/* ============================================================
   Print Affairs — storefront
   Extends styles.css; only the shop-specific pieces live here.
   ============================================================ */

/* --- Shop header ------------------------------------------- */
.shop-head {
  text-align: center;
  padding: 72px 0 0;
}

.shop-head__title { max-width: 900px; margin: 14px auto 0; }

.shop-head__lede {
  max-width: var(--measure);
  margin: 20px auto 0;
  font-size: 20px;
  line-height: 1.55;
  color: var(--graphite);
}

/* Labels that screen readers need but the layout does not. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- Category filter ---------------------------------------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  padding: 36px 0 0;
}

.filter {
  font-size: 15px;
  font-weight: 500;
  padding: 10px 18px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-pill);
  border: 1px solid var(--rule);
  color: var(--ink-soft);
  background: transparent;
  transition: background-color 0.2s ease, color 0.2s ease,
              border-color 0.2s ease;
}

.filter:hover { border-color: var(--ink); color: var(--ink); }

.filter[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

/* --- Product grid ------------------------------------------- */
.shop {
  padding: 40px 0 120px;
}

.shop__group { padding-top: 56px; }

.shop__group-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 26px;
  letter-spacing: -0.02em;
  margin: 0 0 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
}

.shop__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
}

/* --- Product card ------------------------------------------- */
.product {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--white);
  overflow: hidden;
}

.product__media {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--paper-warm);
  position: relative;
}

.product__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.9s cubic-bezier(0.16,1,0.3,1);
}

.product:hover .product__media img { transform: scale(1.04); }

/* --- Second image -------------------------------------------
   Products carry a designed sample first and the bare product
   second. The second image stacks on top and fades in, so the
   card shows the finished job but the plain product is one tap
   or hover away. */
.product__media--stack img {
  position: absolute;
  inset: 0;
}

.product__media--stack img + img {
  opacity: 0;
  transition: opacity 0.35s ease, transform 0.9s cubic-bezier(0.16,1,0.3,1);
}

@media (hover: hover) {
  .product:hover .product__media--stack img + img { opacity: 1; }
}

/* Touch devices get an explicit control instead of hover. */
.product__flip {
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 2;
  min-height: 34px;
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.92);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  box-shadow: 0 2px 10px rgba(29,29,31,0.14);
  display: none;
}

.product__media--stack.is-flipped img + img { opacity: 1; }

@media (hover: none) {
  .product__flip { display: inline-flex; align-items: center; }
}

.product__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 22px 22px 24px;
  flex: 1;
}

.product__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 21px;
  letter-spacing: -0.02em;
  margin: 0;
}

.product__blurb {
  font-size: 15px;
  line-height: 1.55;
  color: var(--graphite);
  margin: 0;
}

/* The "from" price, before a variant is chosen. */
.product__from {
  font-size: 15px;
  color: var(--ink-soft);
}
.product__from strong {
  font-size: 19px;
  font-weight: 600;
  color: var(--ink);
}

/* --- Variant picker ----------------------------------------- */
.product__pick { margin-top: 6px; }

.product__label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--graphite);
  margin-bottom: 8px;
}

.product__select {
  width: 100%;
  min-height: 46px;
  padding: 10px 38px 10px 14px;
  font: inherit;
  font-size: 16px;          /* 16px keeps iOS from zooming on focus */
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 12px;
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--graphite) 50%),
    linear-gradient(135deg, var(--graphite) 50%, transparent 50%);
  background-position:
    calc(100% - 19px) calc(50% + 2px),
    calc(100% - 14px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.product__select:focus-visible {
  outline: 2px solid var(--magenta-txt);
  outline-offset: 2px;
}

/* --- Price + order ------------------------------------------ */
.product__foot {
  margin-top: auto;
  padding-top: 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.product__price {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 26px;
  letter-spacing: -0.02em;
}

.product__price[data-tbd="true"] {
  font-size: 17px;
  font-family: var(--font-sans);
  color: var(--graphite);
}

.product__order {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  padding: 12px 20px;
  border-radius: var(--radius-pill);
  background: var(--magenta-txt);
  color: var(--white);
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color 0.2s ease;
}
.product__order:hover { background: #A80049; }

.product__order svg { width: 17px; height: 17px; flex-shrink: 0; }

.product__note {
  font-size: 13px;
  line-height: 1.5;
  color: var(--graphite);
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  margin-top: 14px;
}

/* --- How ordering works ------------------------------------- */
.how {
  background: var(--paper-warm);
  padding: 72px 0;
}

.how__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  margin-top: 32px;
}

.how__step-n {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  color: var(--magenta-txt);
  display: block;
  margin-bottom: 8px;
}

.how__step-t {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 21px;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
}

.how__step-b {
  font-size: 16px;
  line-height: 1.55;
  color: var(--graphite);
  margin: 0;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1180px) {
  .shop__grid { grid-template-columns: repeat(2, 1fr); }
  .how__grid  { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}

@media (max-width: 820px) {
  .shop__grid { grid-template-columns: repeat(2, 1fr); }
  .how__grid  { grid-template-columns: 1fr; gap: 28px; }
}

@media (max-width: 640px) {
  .shop-head { padding-top: 44px; }
  .shop-head__lede { font-size: 17px; }

  .filters { padding-top: 26px; gap: 8px; }
  .filter { font-size: 14px; padding-inline: 15px; }

  .shop { padding-bottom: 72px; }
  .shop__group { padding-top: 40px; }
  .shop__grid { grid-template-columns: 1fr; gap: 18px; }

  .product__body { padding: 18px 18px 20px; }

  /* Stack price above the button so neither gets squeezed. */
  .product__foot {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .product__order { justify-content: center; }

  .how { padding-block: 56px; }
}

/* ============================================================
   STOREFRONT LAYOUT
   Filter rail on the left, results on the right — the standard
   e-commerce browse pattern.
   ============================================================ */
.browse {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  gap: 40px;
  align-items: start;
  padding: 32px 0 120px;
}

/* --- Filter rail -------------------------------------------- */
.rail {
  position: sticky;
  top: 76px;                /* clears the sticky nav */
  align-self: start;
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  padding-right: 4px;
}

.rail__group { padding-bottom: 26px; }

.rail__legend {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--graphite);
  margin: 0 0 12px;
}

.rail__opt {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;          /* the label is the tap target, not the 18px box */
  font-size: 16px;
  color: var(--ink);
  cursor: pointer;
}

.rail__opt input {
  width: 18px;
  height: 18px;
  accent-color: var(--magenta-txt);
  flex-shrink: 0;
}

.rail__count {
  margin-left: auto;
  font-size: 14px;
  color: var(--graphite);
  font-variant-numeric: tabular-nums;
}

.rail__clear {
  font-size: 15px;
  color: var(--magenta-txt);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.rail__clear:hover { text-decoration: underline; }

/* --- Results header ----------------------------------------- */
.results__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 20px;
  flex-wrap: wrap;
}

.results__count { font-size: 16px; color: var(--graphite); }
.results__count strong { color: var(--ink); font-weight: 600; }

.results__sort {
  min-height: 42px;
  padding: 8px 34px 8px 13px;
  font: inherit;
  font-size: 16px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--white);
  color: var(--ink);
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--graphite) 50%),
    linear-gradient(135deg, var(--graphite) 50%, transparent 50%);
  background-position: calc(100% - 17px) calc(50% + 2px),
                       calc(100% - 12px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.results__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
}

.results__empty {
  padding: 60px 0;
  color: var(--graphite);
  font-size: 17px;
}

/* --- Product card, linked ----------------------------------- */
.card-link { display: flex; flex-direction: column; height: 100%; }
.card-link:hover .product__name { color: var(--magenta-txt); }

.product__price-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: auto;
  padding-top: 14px;
}

.product__from-label { font-size: 14px; color: var(--graphite); }

.product__amount {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  letter-spacing: -0.02em;
}

.product__variants {
  font-size: 14px;
  color: var(--graphite);
  padding-top: 4px;
}

/* --- Mobile filter sheet ------------------------------------ */
.filter-open {
  display: none;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  padding: 11px 20px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--ink);
  font-size: 16px;
  font-weight: 500;
}

/* These only exist while the rail is a mobile sheet. */
.rail__close,
.rail__head,
.rail__scrim { display: none; }

@media (max-width: 1180px) {
  .browse { grid-template-columns: 210px minmax(0, 1fr); gap: 28px; }
  .results__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 820px) {
  .browse { grid-template-columns: 1fr; gap: 0; padding-top: 16px; }
  .filter-open { display: inline-flex; }

  /* The rail becomes a sheet that slides up from the bottom.

     Closed, it must be completely gone: translateY(100%) alone only
     moves it by its own height, and since mobile browser chrome makes
     the visual viewport shorter than the layout viewport, that left a
     strip of filters showing along the bottom edge and eating scroll.
     So it is also hidden from hit-testing and taken out of the
     accessibility tree until opened. */
  .rail {
    position: fixed;
    inset: auto 0 0 0;
    max-height: 88dvh;
    z-index: 60;
    background: var(--paper);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -18px 50px rgba(29, 29, 31, 0.18);
    padding: 0 var(--gutter) calc(20px + env(safe-area-inset-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateY(101%);
    visibility: hidden;
    pointer-events: none;
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                visibility 0s linear 0.3s;
    display: flex;
    flex-direction: column;
  }
  .rail.is-open {
    transform: none;
    visibility: visible;
    pointer-events: auto;
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  }

  /* A scrim, so the sheet reads as a layer over the results and
     tapping away closes it. */
  .rail__scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 59;
    background: rgba(29, 29, 31, 0.32);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
  }
  .rail__scrim.is-open { opacity: 1; pointer-events: auto; }

  /* A sticky header, so closing does not mean scrolling past
     six checkboxes first. */
  .rail__head {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-inline: calc(var(--gutter) * -1);
    padding: 14px var(--gutter) 12px;
    background: var(--paper);
    border-radius: 18px 18px 0 0;
    border-bottom: 1px solid var(--rule);
  }
  /* The grab handle that marks this as a sheet. */
  .rail__head::before {
    content: "";
    position: absolute;
    top: 6px;
    left: 50%;
    translate: -50% 0;
    width: 36px;
    height: 4px;
    border-radius: 2px;
    background: var(--rule);
  }
  .rail__title {
    font-family: var(--font-display);
    font-size: 20px;
    font-weight: 600;
    letter-spacing: -0.02em;
    margin: 0;
  }
  .rail__dismiss {
    width: 44px;
    height: 44px;
    margin-right: -10px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    font-size: 20px;
    line-height: 1;
    color: var(--graphite);
  }
  .rail__group:first-of-type { padding-top: 18px; }

  /* Confirm button, pinned to the bottom of the sheet. */
  .rail__close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 50px;
    margin-top: auto;
    border-radius: var(--radius-pill);
    background: var(--ink);
    color: var(--paper);
    font-size: 16px;
    font-weight: 500;
  }

  /* The rail is gone, so there is room for two across until the
     cards get too narrow to read. */
  .results__grid { grid-template-columns: repeat(2, 1fr); }
}

/* --- Phones -------------------------------------------------
   Most visitors arrive here from Instagram on a phone, so this
   block does the real work: the results bar becomes two rows
   (controls, then count) instead of three items fighting over
   390px, and the filter sheet gets a fixed header so "close" is
   reachable without scrolling past six checkboxes.
   ------------------------------------------------------------ */
@media (max-width: 640px) {
  .shop-head { padding-top: 44px; }
  .shop-head__lede { font-size: 17px; }

  .browse { padding-bottom: 72px; }

  /* Row one: Filters + Sort. Row two: the result count. */
  .results__bar {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px 12px;
    padding-bottom: 16px;
  }
  .filter-open  { grid-column: 1; width: 100%; justify-content: center; }
  .results__sort { grid-column: 2; width: 100%; }
  .results__count { grid-column: 1 / -1; grid-row: 2; font-size: 15px; }

  .results__grid { grid-template-columns: 1fr; gap: 16px; }
}

/* ============================================================
   CART
   No payment: it assembles one itemised WhatsApp message.
   ============================================================ */
.cart-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 38px;
  padding: 8px 16px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--rule);
  font-size: var(--t-fine);
  font-weight: 500;
}
.cart-btn:hover { border-color: var(--ink); }

.cart-btn__n {
  min-width: 20px;
  height: 20px;
  padding-inline: 6px;
  border-radius: 999px;
  background: var(--magenta-txt);
  color: var(--white);
  font-size: 12px;
  font-weight: 600;
  display: none;
  align-items: center;
  justify-content: center;
}
.cart-btn__n[data-n]:not([data-n="0"]) { display: inline-flex; }

/* Tighten the order button so it does not crowd the hamburger. */
@media (max-width: 640px) {
  .cart-btn { padding: 8px 13px; gap: 6px; min-height: 40px; }
}

.drawer {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(420px, 100vw);
  z-index: 70;
  background: var(--paper);
  border-left: 1px solid var(--rule);
  box-shadow: -20px 0 60px rgba(29,29,31,0.14);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.3s cubic-bezier(0.16,1,0.3,1);
}
.drawer.is-open { transform: none; }

.drawer__scrim {
  position: fixed;
  inset: 0;
  z-index: 65;
  background: rgba(29,29,31,0.32);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.drawer__scrim.is-open { opacity: 1; pointer-events: auto; }

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px var(--gutter);
  border-bottom: 1px solid var(--rule);
}

.drawer__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 21px;
  letter-spacing: -0.02em;
  margin: 0;
}

.drawer__close {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-size: 20px;
  line-height: 1;
  color: var(--graphite);
}
.drawer__close:hover { background: rgba(29,29,31,0.06); color: var(--ink); }

.drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: 8px var(--gutter);
}

.drawer__empty {
  padding: 48px 0;
  text-align: center;
  color: var(--graphite);
}

.line {
  display: grid;
  grid-template-columns: 68px minmax(0,1fr) auto;
  gap: 14px;
  align-items: start;
  padding: 18px 0;
  border-bottom: 1px solid var(--rule);
}

.line__thumb {
  width: 68px;
  height: 68px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--paper-warm);
}
.line__thumb img { width: 100%; height: 100%; object-fit: cover; }

.line__name { font-size: 16px; font-weight: 600; display: block; }
.line__variant { font-size: 14px; color: var(--graphite); display: block; }

.line__qty {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-top: 8px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  overflow: hidden;
}

.line__step {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  font-size: 17px;
  line-height: 1;
  color: var(--ink);
}
.line__step:hover { background: rgba(29,29,31,0.06); }

.line__n {
  min-width: 26px;
  text-align: center;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

.line__cost {
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.line__remove {
  display: block;
  margin-top: 8px;
  font-size: 13px;
  color: var(--graphite);
  text-align: right;
  width: 100%;
}
.line__remove:hover { color: var(--magenta-txt); }

/* On touch the drawer controls need real targets: the steppers grow and
   the name/remove links get padded rather than resized, so the line
   itself keeps its compact look. */
@media (hover: none) {
  .line__step { width: 44px; height: 44px; }
  .line__name { padding: 6px 0; }
  .line__remove { padding: 10px 0 6px; }
}

.drawer__foot {
  border-top: 1px solid var(--rule);
  padding: 18px var(--gutter) calc(20px + env(safe-area-inset-bottom));
}

.drawer__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
}
.drawer__total-label { font-size: 16px; }
.drawer__total-amt {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 26px;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.drawer__note {
  font-size: 13px;
  line-height: 1.5;
  color: var(--graphite);
  margin: 0 0 14px;
}

.drawer__send {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  min-height: 52px;
  border-radius: var(--radius-pill);
  background: var(--magenta-txt);
  color: var(--white);
  font-size: 17px;
  font-weight: 500;
}
.drawer__send:hover { background: #A80049; }
.drawer__send[aria-disabled="true"] {
  background: var(--rule);
  color: var(--graphite);
  pointer-events: none;
}
.drawer__send svg { width: 18px; height: 18px; }

@media (max-width: 640px) {
  /* Leave a sliver of scrim so tapping outside still closes the
     drawer, and clear the notch. */
  .drawer {
    width: min(420px, calc(100vw - 44px));
    padding-top: env(safe-area-inset-top);
  }
}

/* ============================================================
   PRODUCT DETAIL PAGE
   ============================================================ */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 26px 0 18px;
  font-size: 15px;
  color: var(--graphite);
}
.crumbs a { color: var(--graphite); }
.crumbs a:hover { color: var(--ink); text-decoration: underline; }
.crumbs span { opacity: 0.5; }

.detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 460px);
  gap: 56px;
  align-items: start;
  padding-bottom: 110px;
}

.detail__main {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--paper-warm);
  aspect-ratio: 4 / 5;
}
.detail__main img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.detail__thumbs {
  display: flex;
  gap: 12px;
  padding-top: 12px;
}

.detail__thumb {
  width: 84px;
  height: 84px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--paper-warm);
  border: 2px solid transparent;
  padding: 0;
  flex-shrink: 0;
}
.detail__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.detail__thumb.is-on { border-color: var(--ink); }

.detail__buy { padding-top: 4px; }

.detail__name { margin: 6px 0 14px; }

.detail__blurb {
  font-size: 18px;
  line-height: 1.6;
  color: var(--graphite);
  margin: 0 0 22px;
}

/* A true min–max range reads as more honest than "from £X" when
   the spread is real. Single-price products just show the one. */
.detail__from {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 14px;
}

/* Lead time is the top pre-purchase question on made-to-order
   goods, and the UK site never answers it in the buy box. */
.detail__turn {
  font-size: 15px;
  color: var(--graphite);
  margin: 0 0 22px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--rule);
}
.detail__turn strong {
  color: var(--ink);
  font-weight: 600;
  margin-right: 6px;
}

.detail__qty {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 0 4px;
}

.detail__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 22px 0 0;
}
.detail__add { flex: 1 1 200px; justify-content: center; }
.detail__actions .btn--quiet { flex: 0 1 auto; }

.detail__note {
  font-size: 14px;
  line-height: 1.55;
  color: var(--graphite);
  margin: 18px 0 0;
  padding: 14px 16px;
  border-radius: 12px;
  background: var(--paper-warm);
}

/* --- Full size table ---------------------------------------- */
.spec {
  width: 100%;
  border-collapse: collapse;
  margin-top: 34px;
}

.spec__cap {
  text-align: left;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--graphite);
  padding-bottom: 10px;
}

.spec td {
  padding: 12px 0;
  border-top: 1px solid var(--rule);
  font-size: 16px;
}

.spec__price {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .detail { grid-template-columns: 1fr; gap: 28px; padding-bottom: 80px; }
  .detail__main { aspect-ratio: 1 / 1; }
  .detail__add { flex: 1 1 100%; }
  .detail__actions .btn--quiet { flex: 1 1 100%; justify-content: center; }
}

/* ============================================================
   PERSONALISATION FIELDS
   Captured at the point of sale so an order arrives complete
   and printable rather than starting a conversation.
   ============================================================ */
.pf {
  border: 1px solid var(--rule);
  border-radius: 14px;
  padding: 20px 18px 6px;
  margin: 24px 0 4px;
  min-width: 0;                /* fieldset defaults would overflow */
}

.pf__legend {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--graphite);
  padding-inline: 8px;
}

.pf__row { padding-bottom: 18px; }

.pf__label {
  display: block;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 6px;
}

.req {
  color: var(--magenta-txt);
  text-decoration: none;
  border: 0;
  margin-left: 2px;
}

.pf__hint {
  display: block;
  font-size: 13px;
  line-height: 1.5;
  color: var(--graphite);
  margin: -2px 0 8px;
}

.pf__input {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  font: inherit;
  font-size: 16px;             /* 16px stops iOS zooming on focus */
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: 10px;
}
.pf__input:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
  border-color: transparent;
}
.pf__input--note { min-height: 88px; resize: vertical; }

.pf__file {
  width: 100%;
  font-size: 15px;
  padding: 10px 0;
}
.pf__file::file-selector-button {
  font: inherit;
  font-size: 15px;
  margin-right: 12px;
  padding: 10px 16px;
  min-height: 44px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--rule);
  background: var(--paper-warm);
  color: var(--ink);
  cursor: pointer;
}
.pf__file::file-selector-button:hover { border-color: var(--ink); }

.pf__row.is-missing .pf__input { border-color: var(--magenta-txt); }
.pf__row.is-missing .pf__label { color: var(--magenta-txt); }

.pf__error {
  margin: 12px 0 0;
  font-size: 15px;
  color: var(--magenta-txt);
}

/* --- Tag chips ---------------------------------------------- */
.chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-top: 22px;
}

.chips__label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--graphite);
  margin-right: 2px;
}

.chip {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--rule);
  font-size: 14px;
  color: var(--ink-soft);
  background: var(--white);
}
.chip:hover { border-color: var(--ink); color: var(--ink); }

/* ============================================================
   STICKY BUY BAR
   Their site loses the buy button once you scroll into the
   description. This keeps it in reach on long pages.
   ============================================================ */
.buybar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 55;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: saturate(180%) blur(18px);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  border-top: 1px solid var(--rule);
  padding: 10px var(--gutter) calc(10px + env(safe-area-inset-bottom));
}
.buybar[hidden] { display: none; }

.buybar__inner {
  max-width: var(--measure, 1240px);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 16px;
}

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

.buybar__name {
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.buybar__price {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.buybar__add {
  margin-left: auto;
  flex-shrink: 0;
  min-height: 48px;
}

@media (max-width: 640px) {
  .buybar__add { flex: 1 1 auto; justify-content: center; }
  .buybar__name { font-size: 14px; }
}

/* --- Drawer: line detail + secondary action ------------------ */
.line__main { min-width: 0; }

.line__detail {
  display: block;
  font-size: 13px;
  line-height: 1.45;
  color: var(--graphite);
  padding-top: 3px;
}

.line__addon {
  display: block;
  font-size: 13px;
  color: var(--magenta-txt);
  padding-top: 2px;
}

.line__end {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.drawer__alt {
  display: block;
  text-align: center;
  padding: 12px 0 2px;
  font-size: 15px;
  color: var(--graphite);
}
.drawer__alt:hover { color: var(--ink); text-decoration: underline; }
.drawer__alt[aria-disabled="true"] { opacity: 0.4; pointer-events: none; }

/* The checkout button is a <button> now, not a link. */
button.drawer__send { width: 100%; border: 0; cursor: pointer; }
button.drawer__send[aria-disabled="true"] {
  background: var(--rule);
  color: var(--graphite);
  pointer-events: none;
}

/* ============================================================
   COLOUR SWATCHES
   Party decor is chosen by colour before anything else. The UK
   site filters 19 colours with plain checkboxes, which throws
   away the fastest way to scan a colour-led catalogue.
   ============================================================ */
.swatch {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: 16px;
  color: var(--ink);
  cursor: pointer;
}

.swatch input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.swatch__dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(29, 29, 31, 0.18);
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}

.swatch input:checked + .swatch__dot {
  box-shadow: inset 0 0 0 1px rgba(29, 29, 31, 0.18),
              0 0 0 2px var(--paper),
              0 0 0 4px var(--ink);
  transform: scale(1.05);
}

.swatch input:focus-visible + .swatch__dot {
  box-shadow: inset 0 0 0 1px rgba(29, 29, 31, 0.18),
              0 0 0 2px var(--paper),
              0 0 0 4px var(--magenta-txt);
}

.swatch input:checked ~ .swatch__name { font-weight: 600; }

.swatch input:disabled ~ .swatch__name { opacity: 0.4; }
.swatch input:disabled + .swatch__dot { opacity: 0.35; }
.swatch:has(input:disabled) { cursor: default; }

.swatch__name { flex: 1; }

/* ============================================================
   APPLIED FILTERS
   Their site gives no indication of what is narrowing the list.
   ============================================================ */
.applied {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-bottom: 18px;
}
.applied[hidden] { display: none; }

.applied__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
.applied__chip span[aria-hidden] { font-size: 12px; opacity: 0.7; }
.applied__chip:hover span[aria-hidden] { opacity: 1; }

.applied__clear {
  min-height: 36px;
  padding: 7px 4px;
  font-size: 14px;
  color: var(--magenta-txt);
  cursor: pointer;
}
.applied__clear:hover { text-decoration: underline; }

/* ============================================================
   GRID DENSITY
   Two across on phones rather than one. Square-ish cards make
   that readable, and it halves the scrolling on a long category
   — which is how their site handles 465 welcome signs.
   ============================================================ */
@media (max-width: 640px) {
  .results__grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }

  .product__body { padding: 12px 12px 14px; gap: 5px; }
  .product__name { font-size: 16px; }
  .product__amount { font-size: 17px; }

  /* At this width the blurb is noise — the name and price carry
     the card, and the detail page has the full description. */
  .product__blurb { display: none; }
  .product__variants { font-size: 12px; }
  .product__media { aspect-ratio: 1 / 1; }
}

/* Very narrow phones cannot carry two columns legibly. */
@media (max-width: 380px) {
  .results__grid { grid-template-columns: 1fr; }
  .product__blurb { display: block; }
}
