/* ================================================================
   Stonehelm — Main Stylesheet
   ================================================================
   Mobile-first, brand-compliant CSS for the Stonehelm 11ty site.
   3-column layout: left sidebar | main content | right aside.
   Organised in layers: reset, base typography, layout, components,
   utilities, and responsive breakpoints.
   ================================================================ */

@import url('variables.css');
@import url('search.css');


/* ================================================================
   1. RESET & BASE
   ================================================================ */

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

html {
  font-size: 100%;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  line-height: var(--line-height-body);
  color: var(--color-charcoal);
  background-color: var(--color-page, var(--color-off-white));
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.sidebar-open {
  overflow: hidden;
}

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

ul,
ol {
  list-style: none;
}

a {
  color: var(--color-link);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  transition: color 0.2s ease;
}

a:hover {
  color: var(--color-link-hover);
}

a:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--border-radius-sm);
}

button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}


/* ================================================================
   2. TYPOGRAPHY
   ================================================================ */

h1, h2, h3 {
  font-family: var(--font-heading);
  line-height: var(--line-height-heading);
  color: var(--color-forest-green);
}

h1 {
  font-size: var(--font-size-h1);
  font-weight: 700;
  margin-block-end: var(--space-md);
}

h2 {
  font-size: var(--font-size-h2);
  font-weight: 600;
  margin-block-end: var(--space-sm);
}

h3 {
  font-size: var(--font-size-h3);
  font-weight: 500;
  margin-block-end: var(--space-sm);
}

.display-heading {
  font-family: var(--font-heading);
  font-size: var(--font-size-display);
  font-weight: 900;
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--color-forest-green);
}

p {
  margin-block-end: var(--space-md);
}

small,
.caption {
  font-size: var(--font-size-caption);
}

.accent-text {
  font-family: var(--font-accent);
}


/* ================================================================
   3. LAYOUT — 3-Column Grid System
   ================================================================ */

.container {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--container-padding);
}

.site-layout {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "topbar"
    "main-area"
    "footer";
  min-height: 100vh;
}

.site-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.main-content {
  flex: 1;
  padding-block: var(--space-xl);
}

.site-main-area {
  grid-area: main-area;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.site-content {
  flex: 1;
  /* Tighter top padding so the breadcrumb sits closer to the topbar.
     The breadcrumb supplies its own padding-block, so the visible gap
     above it is `space-md` (here) + `space-sm` (breadcrumb) ≈ 24px,
     down from the previous ~40px. Bottom + horizontal padding kept
     at the original `space-xl` for normal page breathing room. */
  padding: var(--space-md) var(--container-padding) var(--space-xl);
}

.site-aside {
  padding: var(--space-lg) var(--container-padding);
  border-top: 1px solid rgba(122, 122, 122, 0.15);
}


/* ================================================================
   4. SKIP LINK
   ================================================================ */

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-md);
  background-color: var(--color-crimson);
  color: var(--color-white);
  padding: var(--space-sm) var(--space-md);
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 var(--border-radius-sm) var(--border-radius-sm);
  z-index: 1000;
}

.skip-link:focus {
  top: 0;
}


/* ================================================================
   5. TOPBAR (formerly site-header)
   ================================================================ */

.site-topbar {
  grid-area: topbar;
  position: sticky;
  top: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  height: var(--topbar-height);
  padding-inline: var(--container-padding);
  background-color: var(--topbar-bg);
  color: var(--topbar-text);
  /* R4 V1: the cream band closes with a solid green baseline. On
     desktop this border goes transparent and a single ::before paints
     the line across bar + stonewords cell instead (see the ≥768px
     block) — two separate borders snap to different device pixels at
     fractional display scaling and show a step at the seam. */
  border-bottom: var(--topbar-baseline) solid var(--color-forest-green);
}

/* Right-aligned actions cluster: spyglass (mobile), basket, helmet home-link. */
.site-topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.site-topbar__icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--topbar-text);
  cursor: pointer;
}

.site-topbar__icon-btn:hover,
.site-topbar__icon-btn:focus-visible {
  background-color: var(--topbar-hover-bg);
}

/* Back button ships disabled and only wakes up when history.back()
   would stay on this site (see back-button.js). */
.site-topbar__icon-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.site-topbar__icon-btn:disabled:hover {
  background-color: transparent;
}

.site-topbar__icon-btn svg {
  width: 24px;
  height: 24px;
  display: block;
}

/* Tooltips: small charcoal flags under the topbar icon buttons, fed by
   data-tip. Hover is gated on (hover: hover) so a tap on touch screens
   doesn't leave one stuck open; keyboard focus shows them everywhere.
   The elements carry aria-labels, so the pseudo-element text never
   joins the accessible name. */
.site-topbar [data-tip] {
  position: relative;
}

.site-topbar [data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 7px);
  left: 50%;
  translate: -50% 0;
  z-index: 130;
  padding: 0.25rem 0.55rem;
  border-radius: 6px;
  background-color: var(--color-charcoal);
  color: var(--color-white);
  font-family: var(--font-heading);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease, visibility 0.15s;
  pointer-events: none;
}

.site-topbar [data-tip]::before {
  content: '';
  position: absolute;
  top: calc(100% - 1px);
  left: 50%;
  translate: -50% 0;
  z-index: 130;
  border: 4px solid transparent;
  border-bottom-color: var(--color-charcoal);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease, visibility 0.15s;
  pointer-events: none;
}

@media (hover: hover) {
  .site-topbar [data-tip]:hover::after,
  .site-topbar [data-tip]:hover::before {
    opacity: 1;
    visibility: visible;
    transition-delay: 0.35s;
  }
}

.site-topbar [data-tip]:focus-visible::after,
.site-topbar [data-tip]:focus-visible::before {
  opacity: 1;
  visibility: visible;
}

/* The account tooltip would sit on top of the opened dropdown menu —
   drop it while the menu is expanded. */
.site-topbar [data-tip][aria-expanded="true"]::after,
.site-topbar [data-tip][aria-expanded="true"]::before {
  opacity: 0;
  visibility: hidden;
  transition-delay: 0s;
}

/* Account slot: a single user-icon button that opens a dropdown context menu.
   The menu holds "Sign in" (signed out) or "My orders" + "Sign out" (signed
   in); account.js toggles which items are visible. The icon button reuses the
   shared .site-topbar__icon-btn 44px pill affordance. */
.site-topbar__account {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.site-topbar__account-menu {
  position: absolute;
  top: calc(100% + var(--space-xs));
  right: 0;
  z-index: 60;
  min-width: 11rem;
  padding: var(--space-xs);
  display: flex;
  flex-direction: column;
  background-color: var(--color-white);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.15));
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}

.site-topbar__account-menu[hidden] {
  display: none;
}

/* Sign-out confirmation — a <dialog> built by account.js when signing out
   would empty a basket that has items in it. */
.signout-dialog {
  width: min(26rem, calc(100vw - 2 * var(--space-md)));
  /* The global margin reset un-centres a modal <dialog>; put it back. */
  margin: auto;
  padding: 0;
  border: 0;
  border-top: 4px solid var(--color-forest-green);
  border-radius: var(--border-radius);
  background-color: var(--color-white);
  color: var(--color-charcoal);
  box-shadow: var(--shadow-elevated);
}

.signout-dialog::backdrop {
  background: rgba(43, 43, 43, 0.5);
}

.signout-dialog__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-lg);
}

.signout-dialog__title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--font-size-h2);
  line-height: var(--line-height-heading);
  color: var(--color-forest-green);
}

.signout-dialog__text {
  margin: 0;
}

.signout-dialog__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.signout-dialog__cancel {
  align-self: center;
  margin-block-start: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  background: none;
  border: 0;
  font: inherit;
  color: var(--color-forest-green);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.signout-dialog__cancel:hover {
  color: var(--color-crimson);
}

.signout-dialog button:disabled {
  opacity: 0.55;
  cursor: default;
}

.signout-dialog__status {
  margin: 0;
  min-height: 1.5em;
  text-align: center;
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.signout-dialog__status:empty {
  display: none;
}

/* Scoped under the menu so the colour beats the broad `.site-topbar a`
   (white-on-green topbar) rule — these items sit on a white dropdown. */
.site-topbar__account-menu .site-topbar__account-item {
  display: block;
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--color-charcoal);
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.site-topbar__account-menu .site-topbar__account-item[hidden] {
  display: none;
}

.site-topbar__account-menu .site-topbar__account-item:hover,
.site-topbar__account-menu .site-topbar__account-item:focus-visible {
  background-color: var(--color-off-white);
  color: var(--color-forest-green);
}

.site-topbar a {
  color: var(--topbar-text);
  text-decoration: none;
}

/* Cart icon: anchor the live item-count bubble to its top-right corner. */
.site-topbar__cart {
  position: relative;
}

.site-topbar__cart-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-crimson);
  color: var(--color-white);
  border-radius: 999px;
  font-family: var(--font-heading);
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
  pointer-events: none;
}

.site-topbar__cart-badge[hidden] {
  display: none;
}

.site-topbar__leading {
  display: flex;
  align-items: center;
  min-width: 52px;
}

.site-topbar__logo {
  width: 40px;
  height: auto;
}

.site-topbar__home-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
}

.site-topbar__search-placeholder {
  flex: 1;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-width: 0;
  min-height: 48px;
  padding: 0 var(--space-md);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.08));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.78);
}

.site-topbar__search-icon {
  font-size: 0;
  width: 1rem;
  height: 1rem;
  border: 2px solid currentColor;
  border-radius: 50%;
  position: relative;
  flex: 0 0 auto;
}

.site-topbar__search-icon::after {
  content: '';
  position: absolute;
  right: -0.28rem;
  bottom: -0.3rem;
  width: 0.45rem;
  height: 2px;
  background: currentColor;
  transform: rotate(45deg);
  transform-origin: center;
}

.site-topbar__search-copy {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-base);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.site-topbar__search-status {
  padding: 0.25rem 0.55rem;
  border-radius: 999px;
  background-color: rgba(0, 0, 0, 0.16);
  color: rgba(255, 255, 255, 0.9);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Legacy compat — keeps .site-header in CSS for test checks */
.site-header {
  background-color: var(--color-forest-green);
  color: var(--color-white);
  padding-block: var(--space-md);
}

.site-header a {
  color: var(--color-white);
  text-decoration: none;
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
}

.site-header__brand {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.site-header__logo {
  width: 48px;
  height: auto;
}

.site-header__wordmark {
  height: 28px;
  width: auto;
}


/* ================================================================
   6. SIDEBAR NAVIGATION
   ================================================================ */

/* Mobile: off-canvas drawer */
.site-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--sidebar-width);
  background-color: var(--sidebar-bg);
  color: var(--sidebar-text);
  z-index: 200;
  transform: translateX(-100%);
  /* visibility takes the closed drawer out of the tab order and the a11y
     tree (a transform alone does not); the delayed switch keeps the
     slide-out animation visible. */
  visibility: hidden;
  transition: transform 0.3s ease, visibility 0s linear 0.3s;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.site-sidebar.is-open {
  transform: translateX(0);
  visibility: visible;
  transition: transform 0.3s ease, visibility 0s;
}

.site-sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 150;
}

.site-sidebar-overlay.is-visible {
  display: block;
}

.sidebar-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-lg) var(--space-md);
  border-bottom: 1px solid var(--sidebar-border);
  text-align: center;
}

.sidebar-brand__logo {
  width: 48px;
  height: auto;
}

.sidebar-brand__wordmark {
  max-width: 160px;
  height: auto;
}

.sidebar-brand__strapline {
  font-family: var(--font-accent);
  font-size: var(--font-size-base);
  color: var(--color-off-white);
}

.sidebar-nav {
  flex: 1;
  padding: 0;
}

/* R4 V1: the stonewords cell shares the bar's cream with no divider —
   the band reads as one piece. The desktop block gives it the same
   transparent 3px baseline slot as the bar so both bottoms stay 47px. */
.sidebar-nav__item--wordmark {
  border-bottom: 0;
  background-color: var(--topbar-bg);
}

.sidebar-nav__wordmark-link {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 46px;
  padding: 0.3rem var(--space-md);
  border-left: 0;
  text-decoration: none;
  background: transparent;
}

.sidebar-nav__wordmark-link:hover {
  background-color: transparent;
}

.sidebar-nav__wordmark {
  display: block;
  width: 100%;
  max-width: 220px;
  height: auto;
  /* The dark-green stone letters sit straight on the cream — no
     brighten filter (that was for the old charcoal ground). */
  filter: none;
}

.sidebar-nav__item {
  border-bottom: 0;
  background-color: transparent;
}

.sidebar-nav__item > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link) {
  display: flex;
  align-items: center;
  padding: 0.42rem var(--space-md) 0.42rem calc(var(--space-md) + 0.5rem);
  min-height: 1.75rem;
  line-height: 1.25;
  color: var(--sidebar-link);
  text-decoration: none;
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: 500;
  transition: color 0.2s ease, background-color 0.2s ease;
  border-left: 3px solid transparent;
}

/* Hover is a colour change only — a full-row tint block leaves an
   empty highlighted strip left of the indented text that reads as a
   stray shadow (client feedback, round 4). */
.sidebar-nav__item > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link):hover {
  background-color: transparent;
  color: var(--sidebar-link-hover);
}

/* The current page keeps its quiet tint + crimson edge as a marker. */
.sidebar-nav__item > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link)[aria-current="page"] {
  background-color: var(--sidebar-active-bg);
  border-left-color: var(--color-crimson);
  color: var(--color-forest-green);
}

.sidebar-nav__item--heading {
  border-bottom: 0;
  background-color: transparent;
}

.sidebar-nav__item--heading > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link) {
  display: block;
  min-height: 0;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--sidebar-heading);
  border-left: none;
  padding: 0.85rem var(--space-md) 0.25rem;
  line-height: 1.1;
  pointer-events: none;
  cursor: default;
}

.sidebar-nav__item--heading > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link):hover {
  background-color: transparent;
  color: var(--sidebar-heading);
}

/* Compact sidebar for short viewports (e.g. 1080p at 140% display scaling).
   Triggers when viewport height ≤ 800px so the full menu stays visible. */
@media (max-height: 800px) {
  .sidebar-nav__wordmark-link {
    min-height: 38px;
    padding: 0.2rem var(--space-md);
  }

  .sidebar-nav__item > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link) {
    padding: 0.25rem var(--space-md) 0.25rem calc(var(--space-md) + 0.5rem);
    min-height: 1.5rem;
    line-height: 1.2;
  }

  .sidebar-nav__item--heading > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link) {
    min-height: 0;
    padding: 0.12rem var(--space-md) 0.08rem;
  }
}

.sidebar-footer {
  padding: var(--space-md);
  border-top: 1px solid var(--sidebar-rule);
  font-size: var(--font-size-caption);
  color: var(--sidebar-footer-text);
}

.sidebar-footer a {
  color: var(--sidebar-link);
  text-decoration: none;
}

.sidebar-footer a:hover {
  color: var(--sidebar-link-hover);
  text-decoration: underline;
}

/* Legacy compat — keeps .site-nav and .nav-toggle in CSS for test checks */
.site-nav {
  position: relative;
}

.nav-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 2px solid var(--color-white);
  border-radius: var(--border-radius-sm);
  color: var(--color-white);
  cursor: pointer;
  font-size: 1.5rem;
  line-height: 1;
}

.nav-toggle:hover {
  background-color: rgba(255, 255, 255, 0.15);
}

/* Mobile: nav list hidden by default */
.nav-list {
  height: 0;
  overflow: hidden;
  transition: height 0.3s ease;
  position: absolute;
  top: 100%;
  right: 0;
  background-color: var(--color-forest-green);
  min-width: 220px;
  border-radius: 0 0 var(--border-radius) var(--border-radius);
  box-shadow: var(--shadow-elevated);
  z-index: 100;
}

.nav-list.is-open {
  height: auto;
  padding-block: var(--space-sm);
}

.nav-list__item a {
  display: block;
  padding: var(--space-sm) var(--space-md);
  color: var(--color-white);
  text-decoration: none;
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 500;
  transition: background-color 0.2s ease;
}

.nav-list__item a:hover,
.nav-list__item a[aria-current="page"] {
  background-color: rgba(255, 255, 255, 0.15);
}

/* Sidebar hamburger (in topbar) */
.sidebar-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: none;
  border: none;
  color: var(--topbar-text);
  cursor: pointer;
  font-size: 1.4rem;
  line-height: 1;
  padding: 0;
}

.sidebar-toggle:hover {
  opacity: 0.8;
}


/* ================================================================
   6b. RIGHT SIDEBAR / ASIDE WIDGETS
   ================================================================ */

.aside-widget {
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  padding: var(--space-md);
  box-shadow: var(--shadow-card);
  margin-block-end: var(--space-lg);
}

.aside-widget__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--color-forest-green);
  margin-block-end: var(--space-sm);
  padding-block-end: var(--space-xs);
  border-bottom: 2px solid var(--color-forest-green);
}

.aside-widget__list {
  font-size: var(--font-size-caption);
}

.aside-widget__list li {
  padding: var(--space-xs) 0;
  border-bottom: 1px solid rgba(122, 122, 122, 0.1);
}

.aside-widget__list li:last-child {
  border-bottom: none;
}

.aside-widget__list a {
  color: var(--color-link);
  text-decoration: none;
}

.aside-widget__list a:hover {
  color: var(--color-link-hover);
  text-decoration: underline;
}

.aside-widget__more {
  display: block;
  margin-block-start: var(--space-sm);
  font-size: var(--font-size-caption);
  color: var(--color-link);
}

.aside-widget__more:hover {
  color: var(--color-link-hover);
  text-decoration: underline;
}

.aside-seasonal__body {
  font-size: var(--font-size-caption);
  line-height: 1.5;
  color: var(--color-charcoal);
  margin: 0 0 var(--space-sm);
}

/* Tool promo card (page-dependent context slot) */
.aside-tool-promo {
  background-color: var(--color-warm-cream);
}

.aside-tool-promo__image {
  display: block;
  width: 120px;
  height: 120px;
  margin: 0 auto var(--space-sm);
}

.aside-tool-promo__image img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

.aside-tool-promo__kicker {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-size-caption);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-stone-grey);
  margin: 0 0 var(--space-xs);
}

.aside-tool-promo__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--color-forest-green);
  margin: 0 0 var(--space-xs);
}

.aside-tool-promo__blurb {
  font-size: var(--font-size-caption);
  line-height: 1.5;
  color: var(--color-charcoal);
  margin: 0 0 var(--space-md);
}

.aside-start-here .aside-tool-promo__blurb {
  margin-block-end: var(--space-sm);
}

.aside-start-here .aside-widget__list li {
  border-bottom-color: rgba(45, 90, 39, 0.15);
}

/* Doubled class beats the later shared .button-secondary rule. */
.aside-tool-promo__cta.aside-tool-promo__cta {
  width: 100%;
  padding-inline: var(--space-sm);
  font-size: var(--font-size-caption);
}

.aside-widget blockquote {
  font-family: var(--font-body);
  font-size: var(--font-size-caption);
  font-style: italic;
  line-height: 1.6;
  color: var(--color-stone-grey);
  margin: 0;
}

.aside-widget blockquote footer {
  font-family: var(--font-accent);
  font-size: var(--font-size-caption);
  font-style: normal;
  margin-block-start: var(--space-xs);
  color: var(--color-forest-green);
}


/* ================================================================
   7. BREADCRUMBS
   ================================================================ */

.breadcrumb {
  padding-block: var(--space-sm);
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
}

.breadcrumb__item {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.breadcrumb__separator {
  color: var(--color-stone-grey);
  user-select: none;
}

.breadcrumb__link {
  color: var(--color-stone-grey);
  text-decoration: none;
}

.breadcrumb__link:hover {
  color: var(--color-link-hover);
  text-decoration: underline;
}

.breadcrumb__current {
  color: var(--color-charcoal);
  font-weight: 600;
}


/* ================================================================
   8. PRODUCT CARDS & GRID
   ================================================================ */

.price--original {
  text-decoration: line-through;
  color: var(--color-stone-grey);
  font-weight: 400;
  font-size: var(--font-size-base);
  margin-inline-end: var(--space-xs);
}

.price--offer {
  color: var(--color-crimson);
  font-weight: 700;
}

.offer-badge {
  display: inline-block;
  background-color: var(--color-crimson);
  color: var(--color-white);
  font-family: var(--font-heading);
  font-size: 0.75rem;
  font-weight: 700;
  padding: var(--space-xs) var(--space-sm);
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  position: absolute;
  top: var(--space-sm);
  right: var(--space-sm);
}

.offer-badge--unavailable {
  background-color: var(--color-stone-grey);
}


/* ================================================================
   8b. PRODUCT LIST
   ================================================================ */

.product-list {
  display: flex;
  flex-direction: column;
}

.product-list__section {
  display: flex;
  flex-direction: column;
}

.product-list__section + .product-list__section {
  margin-top: var(--space-xl);
}

.product-list__section-heading {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 600;
  color: var(--color-forest-green);
  margin: 0 0 var(--space-sm);
  padding-bottom: var(--space-xs);
  border-bottom: 2px solid var(--color-forest-green);
}

/* Optional one-liner under a section heading saying what the range is
   for (e.g. the wine kit brands). Sits between the rule and the tiles. */
.product-list__section-blurb {
  margin: 0 0 var(--space-sm);
  font-size: var(--font-size-caption);
  line-height: 1.5;
  color: var(--color-stone-grey);
}

/* Tag filter row on a genre landing page (e.g. Wine Kits: All / Red /
   White / Rosé). Buttons are toggles; listing-filter.js hides tiles that
   lack the chosen tag and empties out any range section left bare. */
.listing-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-sm);
  margin: 0 0 var(--space-lg);
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--color-parchment);
}

.listing-filter__label {
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-stone-grey);
  margin-right: var(--space-xs);
}

.listing-filter__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font: inherit;
  font-size: var(--font-size-caption);
  line-height: 1.2;
  padding: 0.3rem 0.85rem;
  border-radius: 999px;
  border: 1px solid var(--color-parchment);
  background: var(--color-white);
  color: var(--color-charcoal);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.listing-filter__btn:hover,
.listing-filter__btn:focus-visible {
  border-color: var(--color-forest-green);
  color: var(--color-forest-green);
}

.listing-filter__btn--active {
  background: var(--color-forest-green);
  border-color: var(--color-forest-green);
  color: var(--color-white);
}

.listing-filter__swatch {
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  background: var(--swatch, currentColor);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
}

/* Tiles and sections are display:flex, which would defeat the [hidden]
   default the filter script relies on. */
.product-list-item[hidden],
.product-list__section[hidden] {
  display: none;
}

/* Split tile: the link wraps image + text only; the actions column beside
   it holds real controls (details pill, add pill, stepper), so hover and
   striping live on the article rather than the link. */
.product-list-item {
  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  border-bottom: 1px solid rgba(122, 122, 122, 0.15);
  border-left: 3px solid transparent;
  border-radius: var(--border-radius-sm);
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.product-list-item:last-child {
  border-bottom: none;
}

.product-list-item:nth-of-type(even) {
  background-color: rgba(250, 247, 240, 0.5);
}

.product-list-item:hover {
  background-color: var(--color-warm-cream);
  border-left-color: var(--color-forest-green);
}

.product-list-item__link {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md);
  padding-right: var(--space-sm);
  text-decoration: none;
  color: inherit;
}

.product-list-item:has(.stock-status--out-of-stock) .product-list-item__link {
  opacity: 0.6;
}

.product-list-item:has(.stock-status--out-of-stock) .product-list-item__link:hover {
  opacity: 0.85;
}

.product-list-item__image {
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  background-color: var(--color-warm-cream);
  padding: var(--space-xs);
  box-sizing: border-box;
  background-color: var(--color-white);
  border: 1px solid rgba(122, 122, 122, 0.2);
  border-radius: var(--border-radius-sm);
  overflow: hidden;
}

.product-list-item__image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.product-list-item__content {
  flex: 1;
  min-width: 0;
}

.product-list-item__brand {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 400;
  color: var(--color-stone-grey);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.3;
  margin: 0 0 var(--space-xxs, 2px);
}

.product-list-item__brand .product-list-item__make,
.product-list-item__brand .product-list-item__range {
  white-space: nowrap;
}

@media (max-width: 480px) {
  /* Long make names ("Brupaks Vacuum Packed Hops…") can't hold the
     no-mid-name-break guarantee on a phone without pushing the page wide. */
  .product-list-item__brand .product-list-item__make,
  .product-list-item__brand .product-list-item__range {
    white-space: normal;
  }
}


.product-list-item__brand .product-list-item__range::before {
  content: "·";
  margin: 0 0.35em;
  opacity: 0.55;
}

@media (min-width: 768px) {
  .product-list-item__brand {
    font-size: var(--font-size-caption);
    letter-spacing: 0.05em;
  }
}

.product-list-item__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-base);
  font-weight: 500;
  color: var(--color-forest-green);
  margin: 0;
}

.product-list-item__desc {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
  margin: var(--space-xs) 0 0;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.product-list-item__actions {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md) var(--space-sm) 0;
  text-align: right;
}

@media (max-width: 639px) {
  .product-list-item__link {
    flex: 1 1 100%;
    padding-bottom: var(--space-xs);
  }

  /* Actions drop to their own full-width row, indented past the thumbnail
     so price and pills align with the text column. */
  .product-list-item__actions {
    flex: 1 1 100%;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    padding: 0 var(--space-md) var(--space-sm)
      calc(var(--space-md) + 72px + var(--space-md));
  }
}

@media (max-width: 420px) {
  /* The thumbnail indent no longer fits alongside price + pills (worst on
     /Offers/ where was- and now-price sit together), so the row goes
     full width instead of scrolling the page sideways. */
  .product-list-item__actions {
    padding-left: var(--space-md);
  }
}

.product-list-item__price {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 700;
  color: var(--color-forest-green);
}

/* Quiet twin pills: matching outline pills — [Details] [+ Add] — in the
   site's pill idiom. The add pill carries a faint green tint; after an add
   listing-add.js swaps it for the stepper. */
/* Timed stock verdict on a listing tile (listing-add.js). */
.product-list-item__note {
  font-size: var(--font-size-caption);
  font-weight: 600;
  color: var(--color-crimson);
}

.product-list-item__note[hidden] {
  display: none;
}

.product-list-item__pills {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.product-list-item__pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-radius: 999px;
  padding: 0.4rem 0.85rem;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease,
    border-color 0.15s ease;
}

.product-list-item__details {
  color: var(--color-forest-green);
  background: transparent;
  border: 1px solid rgba(45, 90, 39, 0.35);
}

.product-list-item__details:hover {
  background: var(--color-forest-green);
  color: var(--color-warm-cream);
}

.product-list-item__add {
  color: var(--color-forest-green);
  background: rgba(45, 90, 39, 0.08);
  border: 1px solid rgba(45, 90, 39, 0.45);
}

.product-list-item__add:hover {
  background: var(--color-forest-green);
  color: var(--color-white);
}

/* In-basket stepper: green pill with −/qty/+ replacing the add pill. The
   display rules must not defeat the hidden attribute. */
.product-list-item__add[hidden],
.product-list-item__stepper[hidden] {
  display: none;
}

.product-list-item__stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--color-forest-green);
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-forest-green);
}

.product-list-item__stepper button {
  width: 2.1rem;
  height: 2.2rem;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-white);
  font-size: 1.05rem;
  line-height: 1;
  font-family: var(--font-heading);
  font-weight: 700;
}

.product-list-item__stepper button:hover {
  background: rgba(255, 255, 255, 0.2);
}

.product-list-item__stepper button:disabled {
  opacity: 0.5;
  cursor: default;
}

.product-list-item__stepper [data-tile-qty] {
  min-width: 1.7em;
  text-align: center;
  color: var(--color-white);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--font-size-caption);
}

@media (max-width: 639px) {
  .product-list-item__pill {
    padding: 0.55rem 1rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .product-list-item__pill {
    transition: none;
  }
}

.product-list-item__meta {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-block-start: var(--space-xs);
  font-size: var(--font-size-caption);
}


/* ================================================================
   9. STOCK STATUS
   ================================================================ */

.stock-status {
  font-size: var(--font-size-caption);
  font-weight: 700;
  margin: 0;
  text-transform: capitalize;
  display: inline-flex;
  align-items: center;
  width: fit-content;
  padding: var(--space-xs) var(--space-sm);
  border-radius: 999px;
}

.stock-status--in-stock {
  color: var(--color-success);
  background-color: rgba(46, 125, 50, 0.1);
  border: 1px solid rgba(46, 125, 50, 0.18);
}

.stock-status--low-stock {
  color: #8a5a00;
  background-color: #fff1c7;
  border: 1px solid rgba(196, 146, 10, 0.35);
}

.stock-status--out-of-stock {
  color: var(--color-stone-grey);
  background-color: rgba(122, 122, 122, 0.08);
  border: 1px solid rgba(122, 122, 122, 0.18);
}

.stock-status--unavailable {
  color: var(--color-stone-grey);
  font-style: italic;
  background-color: rgba(122, 122, 122, 0.08);
  border: 1px solid rgba(122, 122, 122, 0.18);
}


/* ================================================================
   10. PRODUCT DETAIL
   ================================================================ */

.product-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.product-detail__gallery {
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  padding: var(--space-lg);
  text-align: center;
  min-height: 250px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(122, 122, 122, 0.12);
  box-shadow: var(--shadow-card);
}

.product-detail__gallery img {
  max-height: 400px;
  min-width: 180px;
  min-height: 180px;
  width: auto;
  margin-inline: auto;
  object-fit: contain;
}

/* Click-to-zoom main image area — a real <button> (state control), so
   reset all native button chrome and let the contained <picture> drive
   sizing via .product-detail__gallery img rules above.
   Positioned so the magnifier badge can sit in the corner. */
.product-detail__gallery-zoom {
  position: relative;
  display: block;
  width: 100%;
  border: 0;
  padding: 0;
  margin: 0;
  background: transparent;
  cursor: zoom-in;
  font: inherit;
  color: inherit;
}

.product-detail__gallery-zoom:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 4px;
}

/* Static main view (no image large enough to zoom) and the disabled
   button (active image too small while a sibling qualifies) read as a
   plain picture: no magnifier, no zoom-in cursor. */
.product-detail__gallery-main {
  position: relative;
  display: block;
  width: 100%;
}

.product-detail__gallery-zoom:disabled {
  cursor: default;
}

.product-detail__gallery-zoom:disabled::after {
  display: none;
}

/* Magnifier badge — visible affordance so users see the image is
   interactive. URL-encoded SVG data URI for maximum browser compatibility
   (some older Chromium builds choke on unencoded <, >, '). */
.product-detail__gallery-zoom::after {
  content: '';
  position: absolute;
  bottom: 0.75rem;
  right: 0.75rem;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background-color: rgba(45, 90, 39, 0.92);
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27%23fff%27%20stroke-width%3D%272.4%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Ccircle%20cx%3D%2710.5%27%20cy%3D%2710.5%27%20r%3D%276.5%27%2F%3E%3Cpath%20d%3D%27m20%2020-4.5-4.5%27%2F%3E%3Cpath%20d%3D%27M10.5%207.5v6M7.5%2010.5h6%27%2F%3E%3C%2Fsvg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 62%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s ease, background-color 0.15s ease;
  pointer-events: none;
}

.product-detail__gallery-zoom:hover::after,
.product-detail__gallery-zoom:focus-visible::after {
  background-color: var(--color-crimson);
  transform: scale(1.08);
}

/* Thumbnail strip — only renders when >1 image is published. Horizontal
   scroll on overflow keeps narrow viewports working without wrapping
   the thumbs into multiple rows. */
.product-detail__gallery-thumbs {
  display: flex;
  gap: var(--space-sm);
  margin-top: var(--space-md);
  justify-content: center;
  flex-wrap: wrap;
  overflow-x: auto;
}

.product-detail__gallery-thumb {
  display: block;
  width: 80px;
  height: 80px;
  flex: 0 0 80px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--border-radius-sm);
  background: var(--color-white);
  cursor: pointer;
  overflow: hidden;
}

.product-detail__gallery-thumb:hover,
.product-detail__gallery-thumb:focus-visible {
  border-color: var(--color-stone-grey);
  outline: none;
}

.product-detail__gallery-thumb.is-active {
  border-color: var(--color-forest-green);
}

.product-detail__gallery-thumb img,
.product-detail__gallery-thumb picture {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* Override the .product-detail__gallery img min-width/-height — those
     are for the main view; thumbs are intentionally smaller. */
  min-width: 0;
  min-height: 0;
  max-height: none;
}

/* Lightbox dialog — full-viewport overlay, image centred and scaled to
   fit while preserving aspect ratio. */
.product-detail__lightbox {
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-charcoal);
}

/* showModal() traps focus but does NOT lock page scroll — without this the
   document scrollbar stays live at the edge of the full-viewport lightbox. */
body:has(.product-detail__lightbox[open]) {
  overflow: hidden;
}

.product-detail__lightbox::backdrop {
  /* Light warm-cream wash — keeps the brand palette and lets product
     details read on a calm background rather than a void of black. */
  background: rgba(250, 247, 240, 0.96);
}

.product-detail__lightbox-inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.product-detail__lightbox-picture {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  /* touch-action: none — we own all touch gestures here (swipe to
     navigate, pinch to zoom, drag to pan). The dialog is full-viewport
     so there's no page scroll to preserve. */
  touch-action: none;
  cursor: zoom-in;
  overflow: hidden;
}

.product-detail__lightbox-picture.is-zoomed {
  cursor: grab;
}

.product-detail__lightbox-picture.is-zoomed:active {
  cursor: grabbing;
}

.product-detail__lightbox-picture img {
  /* Leave breathing room around the fitted image so it doesn't crowd the
     close/prev/next controls or the viewport edges. The padding scales
     up at wider viewports — small phones get a tighter inset so the
     product still fills usefully on a narrow screen. */
  --lightbox-pad: 2rem;
  max-width: calc(100vw - var(--lightbox-pad) * 2);
  max-height: calc(100vh - var(--lightbox-pad) * 2);
  width: auto;
  height: auto;
  object-fit: contain;
  /* Transform origin at centre matches the maths in createZoomViewer
     (focal-point formula uses image-centre offsets). user-select disabled
     so a drag-to-pan doesn't try to start a selection on desktop. */
  transform-origin: center center;
  user-select: none;
  -webkit-user-drag: none;
  will-change: transform;
}

@media (min-width: 768px) {
  .product-detail__lightbox-picture img {
    --lightbox-pad: 4rem;
  }
}

@media (min-width: 1200px) {
  .product-detail__lightbox-picture img {
    --lightbox-pad: 5.5rem;
  }
}

.product-detail__lightbox-close,
.product-detail__lightbox-prev,
.product-detail__lightbox-next {
  position: absolute;
  /* z-index ensures the controls sit above the picture container even if
     the user agent decides to promote the transformed image to its own
     layer (will-change: transform). */
  z-index: 10;
  background: var(--color-forest-green);
  color: var(--color-white);
  border: 0;
  font-size: 2rem;
  line-height: 1;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}

.product-detail__lightbox-close {
  font-size: 1.75rem;
  font-weight: 300;
}

.product-detail__lightbox-close:hover,
.product-detail__lightbox-prev:hover,
.product-detail__lightbox-next:hover,
.product-detail__lightbox-close:focus-visible,
.product-detail__lightbox-prev:focus-visible,
.product-detail__lightbox-next:focus-visible {
  background: var(--color-crimson);
  outline: 2px solid var(--color-forest-green);
  outline-offset: 2px;
}

.product-detail__lightbox-close {
  top: 1rem;
  right: 1rem;
}

.product-detail__lightbox-prev {
  top: 50%;
  left: 1rem;
  transform: translateY(-50%);
}

.product-detail__lightbox-next {
  top: 50%;
  right: 1rem;
  transform: translateY(-50%);
}

/* Belt-and-braces: the template adds `hidden` to nav buttons when
   there's only one image, but if anyone removes that attr at runtime
   we still want the buttons gone in single-image mode. */
.product-detail__lightbox-prev[hidden],
.product-detail__lightbox-next[hidden] {
  display: none;
}

.product-detail__extras {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* The money moment: price and CTA stacked plainly in the rail — the 2026-08
   redesign dropped the framed panel in favour of open typography. */
.product-detail__purchase {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-sm);
}

/* Eyebrow above the title: the product's facet data (make · ilk). */
.product-detail__eyebrow {
  margin: 0 0 var(--space-xs);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-size-caption);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #7E6310;
}

.product-detail__head {
  margin-block-end: var(--space-sm);
}

.product-detail__title {
  /* clamp scales from a comfortable mobile size (≈22px) up to the desktop
     display size (≈42px). The previous min of 1.9rem and 14ch max-width
     made long product names wrap into four-line walls on phones. */
  font-size: clamp(1.4rem, 1.2vw + 1.1rem, 2.65rem);
  line-height: 1.18;
  margin-block: 0;
  color: var(--color-forest-green);
}

/* Mobile-first flow: gallery → purchase + specs → description. The ≥1200px
   grid below moves the side rail into a sticky right column. */
.product-detail__cols {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.product-detail__side {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.product-detail__description {
  max-width: 70ch;
  line-height: 1.7;
  margin-block-start: 0;
  padding-block-start: 0;
  border-top: none;
}

.product-detail__description p {
  margin-block-end: var(--space-sm);
}

/* The ABV note inside the description data renders as a solid green pill. */
.product-detail__description i {
  display: inline-block;
  margin-block-start: var(--space-md);
  font-style: normal;
  font-weight: 700;
  font-family: var(--font-heading);
  color: var(--color-white);
  font-size: var(--font-size-base);
  background-color: var(--color-forest-green);
  padding: var(--space-xs) var(--space-md);
  border-radius: 999px;
}

.product-detail__price-block {
  font-family: var(--font-heading);
  font-weight: 700;
  display: flex;
  align-items: baseline;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.product-detail__price-block .price {
  font-size: 2.6rem;
  line-height: 1;
  color: var(--color-forest-green);
}

.product-detail__price-block .caption {
  margin-block-end: 0;
  color: var(--color-stone-grey);
  font-family: var(--font-body);
  font-weight: 400;
}

/* Product tags. Only tags the back office marks `visible` are rendered;
   `--tag-colour` is the optional per-tag colour from the tag manager.
   Normal tags are solid chips that link to a tag-filtered search; badges
   (visible but not a search term, e.g. "Bulk") are outlined so they read
   as a label rather than a topic. */
.product-detail__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-sm);
  margin-block-start: var(--space-md);
}

.product-tag {
  --tag-colour: var(--color-forest-green);
  display: inline-block;
  padding: var(--space-xs) var(--space-sm);
  background: var(--tag-colour);
  color: var(--color-white);
  border: 1px solid var(--tag-colour);
  border-radius: 999px;
  font-size: var(--font-size-caption);
  font-family: var(--font-body);
  line-height: 1.2;
  text-decoration: none;
  transition: filter 0.15s ease, background-color 0.15s ease;
}

a.product-tag:hover,
a.product-tag:focus-visible {
  filter: brightness(1.15);
  text-decoration: none;
  color: var(--color-white);
}

.product-tag--badge {
  background: transparent;
  color: var(--tag-colour);
  border-style: dashed;
}

a.product-tag--badge:hover,
a.product-tag--badge:focus-visible {
  background: var(--tag-colour);
  color: var(--color-white);
}

.product-detail__specs-heading {
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--color-stone-grey);
  margin-block-end: var(--space-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Specifications: quiet dot-leader ledger rows. */
.product-detail__specs dl {
  margin: 0;
}

.product-detail__spec-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  padding: var(--space-xs) 0;
}

.product-detail__spec-row dt {
  font-weight: 600;
  color: var(--color-charcoal);
  white-space: nowrap;
}

.product-detail__spec-lead {
  flex: 1;
  border-bottom: 2px dotted rgba(122, 122, 122, 0.45);
  transform: translateY(-4px);
}

.product-detail__spec-row dd {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--color-charcoal);
  white-space: nowrap;
}

.product-detail__actions {
  width: 100%;
  margin-block-start: var(--space-xs);
}

/* Visible verdict when the basket API refuses an add (stock ran out after
   the last build). Timed by add-to-basket.js. */
.product-detail__stock-note {
  margin: var(--space-sm) 0 0;
  font-weight: 600;
  color: var(--color-crimson);
}

.product-detail__stock-note[hidden] {
  display: none;
}

.product-detail__add-btn {
  font-size: 1.1rem;
  padding: 0.75rem var(--space-2xl, 3rem);
  width: 100%;
  max-width: none;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Morphing add control: once the basket holds this product,
   add-to-basket.js swaps the red CTA in place for a green bar —
   [−  ✓ n in basket  +] — with a quiet view-basket link beneath.
   Decrementing to zero brings the CTA back. The display rules here must
   not defeat the hidden attribute. */
.product-detail__add-btn[hidden],
.product-detail__basket-bar[hidden],
.product-detail__basket-view[hidden] {
  display: none;
}

.product-detail__basket-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  width: 100%;
  background: var(--color-forest-green);
  color: var(--color-white);
  border-radius: var(--border-radius-sm);
  padding: 0.4rem 0.5rem;
}

.product-detail__basket-label {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: 0.05em;
}

.product-detail__basket-label b {
  font-size: 1.15em;
}

.product-detail__basket-bar button {
  width: 2.6rem;
  height: 2.6rem;
  flex: none;
  font-size: 1.25rem;
  line-height: 1;
  background: rgba(255, 255, 255, 0.12);
  color: var(--color-white);
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: var(--border-radius-sm);
  cursor: pointer;
}

.product-detail__basket-bar button:hover {
  background: rgba(255, 255, 255, 0.25);
}

.product-detail__basket-bar button:disabled {
  opacity: 0.5;
  cursor: default;
}

.product-detail__basket-view {
  margin: var(--space-sm) 0 0;
  font-size: var(--font-size-caption);
}

.product-detail__basket-view a {
  color: var(--color-forest-green);
}

.product-detail__back {
  margin-block-start: var(--space-2xl, 3rem);
  padding-block-start: var(--space-lg);
  border-top: 1px solid rgba(122, 122, 122, 0.1);
}

/* ── Product strip (sibling tiles + "View all") ─────────
   One horizontal row at the foot of the detail page. It never wraps:
   on narrow screens it scrolls sideways with snap points so the final
   "View all" tile is always the last thing in the row. */

.product-strip {
  margin-block-start: var(--space-2xl, 3rem);
  padding-block-start: var(--space-lg);
  border-top: 1px solid rgba(122, 122, 122, 0.1);
}

.product-strip__heading {
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--color-stone-grey);
  margin: 0 0 var(--space-md);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.product-strip__row {
  list-style: none;
  margin: 0;
  padding: 0 0 var(--space-sm);
  display: flex;
  gap: var(--space-md);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

/* Tiles share the column width when it fits (4 tiles + "View all" in a
   ~700px main column); below the 120px floor they stop shrinking and the
   row scrolls instead. */
.product-strip__tile,
.product-strip__more {
  flex: 1 1 0;
  min-width: 120px;
  max-width: 200px;
  scroll-snap-align: start;
  display: flex;
}

.product-strip__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  width: 100%;
  padding: var(--space-sm);
  border: 1px solid rgba(122, 122, 122, 0.2);
  border-radius: var(--border-radius-sm);
  background: var(--color-white);
  color: inherit;
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.product-strip__link:hover,
.product-strip__link:focus-visible {
  background: var(--color-warm-cream);
  border-color: var(--color-forest-green);
  box-shadow: var(--shadow-card);
}

.product-strip__image {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  padding: var(--space-xs);
  box-sizing: border-box;
  background: var(--color-white);
  overflow: hidden;
}

.product-strip__image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.product-strip__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  font-size: var(--font-size-caption);
  line-height: 1.35;
  color: var(--color-charcoal);
}

.product-strip__price {
  margin-top: auto;
  font-size: var(--font-size-caption);
  font-weight: 600;
}

.product-strip__price .price--original {
  font-weight: 400;
}

.product-strip__price .offer-badge__desc {
  display: none;
}

.product-strip__more {
  align-items: center;
  justify-content: center;
}

.product-strip__more .product-strip__view-all {
  width: 100%;
  text-align: center;
  white-space: normal;
}


/* ================================================================
   11. GENRE / CATEGORY LANDING PAGES
   ================================================================ */

.genre-landing {
  /* No vertical padding here — `.site-content` already supplies the
     outer page padding. Stacking another `space-xl` block above and
     below pushed the breadcrumb/hero further from the topbar than it
     needed to be. */
  padding-block: 0;
}

.genre-landing__header {
  margin-block-end: var(--space-xl);
}

.genre-landing__description {
  max-width: 70ch;
  color: var(--color-charcoal);
}

.genre-landing__header h1:last-child {
  margin-block-end: var(--space-md);
}

/* ── Listing topper (L2 intro block) ──────────────────── */

.listing-topper {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-lg);
  background: var(--color-warm-cream);
  border-radius: var(--border-radius);
  padding: var(--space-lg);
  margin-block-end: var(--space-xl);
  box-shadow: var(--shadow-card);
}

@media (min-width: 720px) {
  .listing-topper {
    grid-template-columns: 220px minmax(0, 1fr);
    align-items: start;
  }
}

.listing-topper__media img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--border-radius-sm);
}

.listing-topper__body > * + * {
  margin-block-start: var(--space-sm);
}

.listing-topper__eyebrow {
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-stone-grey);
  margin-block-end: var(--space-xs);
}

.listing-topper__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h2);
  font-weight: 600;
  color: var(--color-forest-green);
  line-height: 1.15;
  margin: 0;
}

.listing-topper__hallmarks {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
  color: var(--color-charcoal);
}

.listing-topper__hallmarks li::before {
  content: '✦ ';
  color: var(--color-forest-green);
}

.listing-topper__lede {
  font-style: italic;
  color: var(--color-charcoal);
  max-width: 60ch;
}

.listing-topper__note {
  grid-column: 1 / -1;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  padding-block-start: var(--space-md);
  margin-block-start: var(--space-sm);
  color: var(--color-charcoal);
}

.listing-topper__note-eyebrow {
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-forest-green);
  margin-block-end: var(--space-xs);
}

.make-menu-grid,
.ilk-menu-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
  margin-block-end: var(--space-xl);
}

.make-menu-card,
.ilk-menu-card {
  background-color: var(--color-warm-cream);
  border-radius: var(--border-radius);
  padding: var(--space-md);
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.2s ease;
}

.make-menu-card:hover,
.ilk-menu-card:hover {
  box-shadow: var(--shadow-elevated);
}

.make-menu-card__title,
.ilk-menu-card__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 500;
  color: var(--color-forest-green);
}

.make-menu-card__title a,
.ilk-menu-card__title a {
  color: inherit;
  text-decoration: none;
}

.make-menu-card__title a:hover,
.ilk-menu-card__title a:hover {
  color: var(--color-link-hover);
}

.make-menu-card__count,
.ilk-menu-card__count {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.make-menu-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
.make-menu-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
.make-menu-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
.make-menu-grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
.make-menu-grid--cols-6 { grid-template-columns: repeat(6, 1fr); }
.ilk-menu-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
.ilk-menu-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
.ilk-menu-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
.ilk-menu-grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
.ilk-menu-grid--cols-6 { grid-template-columns: repeat(6, 1fr); }


/* ================================================================
   11b. MENU LIST
   ================================================================ */

.menu-list {
  display: flex;
  flex-direction: column;
  list-style: none;
  padding: 0;
  margin: 0;
}

.menu-list__item {
  border-bottom: 1px solid rgba(122, 122, 122, 0.15);
}

.menu-list__item:last-child {
  border-bottom: none;
}

.menu-list__link {
  display: block;
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 500;
  color: var(--color-forest-green);
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease;
  border-radius: var(--border-radius-sm);
}

.menu-list__link:hover {
  background-color: var(--color-warm-cream);
  color: var(--color-link-hover);
}


/* ================================================================
   12. ARTICLES
   ================================================================ */

.article-content {
  line-height: 1.7;
}

/* Editorial measure — cap running text at a book-like line length.
   Only direct text children are capped: figures, the process track,
   galleries, and legacy fixed-width blocks keep the full column. */
.article-content > p,
.article-content > ul,
.article-content > ol,
.article-content > blockquote,
.article-content > h1,
.article-content > h2,
.article-content > h3,
.article-content > h4 {
  max-width: 72ch;
}

/* Inline figures centre within the text column (lead figures still float
   into the right margin like marginalia). */
.article-content > .article-figure:not(.article-figure--lead) {
  max-width: 72ch;
}

.article-content h1 {
  margin-block-end: var(--space-md);
  padding-block-end: var(--space-sm);
  border-bottom: 2px solid var(--color-forest-green, #2d5a27);
}

.article-content h2 {
  margin-block-start: var(--space-2xl);
}

.article-content h3 {
  margin-block-start: var(--space-xl);
}

.article-content p,
.article-content ul,
.article-content ol {
  margin-block-end: var(--space-md);
}

.article-content ul,
.article-content ol {
  padding-inline-start: var(--space-xl);
}

.article-content ul {
  list-style: disc;
}

.article-content ol {
  list-style: decimal;
}

.article-content blockquote {
  border-inline-start: 4px solid var(--color-forest-green);
  padding-inline-start: var(--space-md);
  margin-block: var(--space-md);
  color: var(--color-stone-grey);
  font-style: italic;
}

.article-content h3.article {
  display: none;
}

.article-content > div[style] {
  background-image: none !important;
}

/* Article figure — image + caption, used for hero/inline illustrations */
.article-content .article-figure {
  margin: 0 0 var(--space-lg);
}

.article-content .article-figure img {
  display: block;
  width: 100%;
  height: auto;
  /* Cap inline figures at a comfortable reading size — full detail is
     one click away via the lightbox, so the in-flow copy shouldn't be
     dominated by the image. The --lead variant's parent already
     constrains it tighter, so this max-width is a no-op there. */
  max-width: 32rem;
  margin-inline: auto;
  border-radius: var(--border-radius-sm);
  box-shadow: var(--shadow-hero);
}

.article-content .article-figure figcaption {
  margin-top: var(--space-sm);
  padding-inline: var(--space-sm);
  font-size: var(--font-size-caption);
  line-height: 1.4;
  color: var(--color-stone-grey);
  text-align: center;
}

/* Lead figure floats alongside the opening text on wider screens */
.article-content .article-figure--lead {
  float: right;
  width: clamp(220px, 38%, 320px);
  margin: 0 0 var(--space-md) var(--space-lg);
  shape-margin: var(--space-md);
}

@media (max-width: 720px) {
  .article-content .article-figure--lead {
    float: none;
    width: 100%;
    max-width: 380px;
    margin: 0 auto var(--space-lg);
  }
}

/* Pull-quote treatment — richer than the default blockquote */
.article-content .article-quote {
  position: relative;
  margin: var(--space-lg) 0;
  padding: var(--space-md) var(--space-lg) var(--space-md) var(--space-xl);
  background: var(--color-warm-cream);
  border-inline-start: 4px solid var(--color-forest-green);
  border-radius: 0 var(--border-radius-sm) var(--border-radius-sm) 0;
  font-style: italic;
  color: var(--color-charcoal);
}

.article-content .article-quote::before {
  content: "\201C";
  position: absolute;
  top: -0.25rem;
  left: 0.25rem;
  font-family: var(--font-heading);
  font-size: 3.5rem;
  line-height: 1;
  color: var(--color-forest-green);
  opacity: 0.35;
}

.article-content .article-quote p {
  margin: 0;
  font-size: 1.05rem;
}

.article-content .article-quote cite {
  display: block;
  margin-top: var(--space-sm);
  font-style: normal;
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

/* Stepped definition list — used for temperature rests and similar
   "label + description" sequences inside articles. */
.article-content .mash-rests {
  margin: var(--space-lg) 0;
  display: grid;
  gap: var(--space-sm);
}

.article-content .mash-rests__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-warm-cream);
  border-inline-start: 4px solid var(--color-forest-green);
  border-radius: 0 var(--border-radius-sm) var(--border-radius-sm) 0;
}

.article-content .mash-rests dt {
  margin: 0;
  font-weight: 700;
  color: var(--color-forest-green);
  font-family: var(--font-heading);
}

.article-content .mash-rests dd {
  margin: 0;
  color: var(--color-charcoal);
}

.article-content .mash-rests__temp {
  display: inline-block;
  margin-inline-end: var(--space-sm);
  padding: 0.1rem 0.5rem;
  background: var(--color-forest-green);
  color: var(--color-white);
  border-radius: var(--border-radius-sm);
  font-size: var(--font-size-caption);
  font-weight: 700;
  letter-spacing: 0.02em;
  vertical-align: 1px;
}

@media (max-width: 560px) {
  .article-content .mash-rests__row {
    grid-template-columns: 1fr;
    gap: var(--space-xs);
  }
}

/* Closing tagline — centred kicker line for the end of an article. */
.article-content .article-tagline {
  margin-block-start: var(--space-xl);
  text-align: center;
  font-family: var(--font-heading);
  font-size: 1.15rem;
  color: var(--color-forest-green);
}

/* Zoomable image affordance — applied by article-gallery.js after init.
   The class is JS-added so a no-JS pageview gets a static <img> with no
   misleading zoom cursor. */
.article-content img.is-zoomable {
  cursor: zoom-in;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.article-content img.is-zoomable:hover,
.article-content img.is-zoomable:focus-visible {
  transform: scale(1.015);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.2);
}

.article-content img.is-zoomable:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 4px;
}

/* Article lightbox — full-viewport <dialog> built by article-gallery.js.
   Mirrors the product lightbox styling so the experience is consistent. */
.article-lightbox {
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-charcoal);
}

.article-lightbox::backdrop {
  background: rgba(43, 43, 43, 0.92);
}

.article-lightbox__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.article-lightbox__picture {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: zoom-in;
  overflow: hidden;
}

.article-lightbox__picture.is-zoomed {
  cursor: grab;
}

.article-lightbox__picture.is-zoomed:active {
  cursor: grabbing;
}

.article-lightbox__picture img {
  --lightbox-pad: 2rem;
  max-width: calc(100vw - var(--lightbox-pad) * 2);
  max-height: calc(100vh - var(--lightbox-pad) * 2);
  width: auto;
  height: auto;
  object-fit: contain;
  transform-origin: center center;
  user-select: none;
  -webkit-user-drag: none;
  will-change: transform;
  border-radius: var(--border-radius-sm);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
}

@media (min-width: 768px) {
  .article-lightbox__picture img {
    --lightbox-pad: 4rem;
  }
}

@media (min-width: 1200px) {
  .article-lightbox__picture img {
    --lightbox-pad: 5.5rem;
  }
}

.article-lightbox__close,
.article-lightbox__prev,
.article-lightbox__next {
  position: absolute;
  z-index: 10;
  background: var(--color-forest-green);
  color: var(--color-white);
  border: 0;
  font-size: 2rem;
  line-height: 1;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
}

.article-lightbox__close {
  font-size: 1.75rem;
  font-weight: 300;
}

.article-lightbox__close:hover,
.article-lightbox__prev:hover,
.article-lightbox__next:hover,
.article-lightbox__close:focus-visible,
.article-lightbox__prev:focus-visible,
.article-lightbox__next:focus-visible {
  background: var(--color-crimson);
  outline: 2px solid var(--color-white);
  outline-offset: 2px;
}

.article-lightbox__close {
  top: 1rem;
  right: 1rem;
}

.article-lightbox__prev {
  top: 50%;
  left: 1rem;
  transform: translateY(-50%);
}

.article-lightbox__next {
  top: 50%;
  right: 1rem;
  transform: translateY(-50%);
}

.article-lightbox__prev[hidden],
.article-lightbox__next[hidden] {
  display: none;
}

.article-content ul li,
.article-content ol li {
  margin-block-end: var(--space-xs);
}

.article-content img[border] {
  border: none;
}

/* How-to lesson images — override legacy fixed width/height */
.article-content img.lesson {
  width: auto;
  height: auto;
  max-width: 180px;
  float: right;
  margin: 0 0 var(--space-md) var(--space-md);
  padding: 8px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 6px;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
  shape-margin: var(--space-sm);
  clear: right;
}

@media (max-width: 480px) {
  .article-content img.lesson {
    float: none;
    display: block;
    margin: var(--space-md) auto;
    max-width: 200px;
  }
}

/* Airlock-type image gallery — side-by-side figures */
.airlock-types {
  clear: both;
  margin-block: var(--space-lg);
}

.airlock-types__gallery {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: var(--space-lg);
  flex-wrap: wrap;
}

.airlock-types__gallery figure {
  text-align: center;
  max-width: 140px;
}

.airlock-types__gallery img.lesson {
  float: none;
  display: block;
  margin: 0 auto var(--space-xs);
  clear: none;
}

.airlock-types__gallery figcaption {
  font-size: var(--font-size-sm, 0.8rem);
  color: var(--color-stone-grey);
  line-height: 1.3;
}



/* ================================================================
   12b. GENRE INTRO PAGES
   ================================================================ */

/* ── Shared ─────────────────────────────────────────────── */

.gi-page-title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h1);
  color: var(--color-forest-green);
  margin-block-end: var(--space-sm);
}

.gi-page-intro {
  max-width: 70ch;
  margin-block-end: var(--space-xl);
  color: var(--color-charcoal);
  line-height: var(--line-height-body);
}

.gi-section {
  margin-block: var(--space-2xl);
}

.gi-section__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h2);
  font-weight: 600;
  color: var(--color-forest-green);
  padding-block-end: var(--space-sm);
  border-bottom: 2px solid var(--color-forest-green);
  margin-block-end: var(--space-lg);
}

.gi-section__subtitle {
  font-size: var(--font-size-caption);
  font-weight: 400;
  color: var(--color-stone-grey);
}

/* ── Hero banner (Beers) ────────────────────────────────── */

.gi-hero {
  background-size: cover;
  background-position: center;
  border-radius: var(--border-radius);
  overflow: hidden;
  margin-block-end: var(--space-2xl);
  /* Flex column so an overlay with `align-self: flex-start` can pin
     to the top of the hero instead of stretching to fill its height. */
  display: flex;
  flex-direction: column;
}

/* Beers hero — pub-scene photo. The focal point (two pints on a wooden
   table) sits at the bottom-centre of the source image, so we anchor
   the background there with `background-position: center bottom` and
   let `cover` crop from the top as the container changes shape. As
   the hero gets taller, more of the sky/field/pub appears ABOVE the
   glasses; the glasses themselves are always in frame. */
.gi-hero--beers {
  background-image: image-set(
    url('/assets/images/beerkits-page-header.avif') type('image/avif'),
    url('/assets/images/beerkits-page-header.webp') type('image/webp'),
    url('/assets/images/beerkits-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  /* Fluid sizing: scales with viewport width so wider screens reveal
     more of the image, with a floor on mobile and a cap on huge
     desktop monitors. */
  min-height: clamp(300px, 38vw, 560px);
  /* Padding here (rather than margin on the glass card) guarantees the
     card has equal spacing on all four sides regardless of whether
     the hero has any free space. `margin-top: auto` only works when
     there's free space to absorb — on a constrained mobile hero the
     auto resolves to 0 and the top edge touches. Padding doesn't
     collapse, so spacing is preserved even when the card content
     fills the hero. */
  padding: var(--space-md);
  /* When there IS free space (taller heroes), push the card to the
     bottom of the padded box. A no-op when free space is zero. */
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--beers {
    background-image: image-set(
      url('/assets/images/beerkits-page-header-800.avif') type('image/avif'),
      url('/assets/images/beerkits-page-header-800.webp') type('image/webp'),
      url('/assets/images/beerkits-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Wines hero — Tuscan vineyard scene cropped to a 3.9:1 banner.
   The wine bottles + glasses sit at the bottom-left of the source,
   barrel + path leading to vineyards run along the bottom-right.
   Anchoring to `center bottom` keeps the wooden-table strip in
   frame at every viewport; the very wide aspect means the top
   of the image (sky/trees) always crops out cleanly. */
.gi-hero--wines {
  background-image: image-set(
    url('/assets/images/winekits-page-header.avif') type('image/avif'),
    url('/assets/images/winekits-page-header.webp') type('image/webp'),
    url('/assets/images/winekits-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  /* Shorter minimum than Beers because the cropped source is much
     wider (3.9:1 vs 3:2) — letting the hero grow taller would just
     stretch a banner-shaped image. */
  min-height: clamp(260px, 32vw, 480px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--wines {
    background-image: image-set(
      url('/assets/images/winekits-page-header-800.avif') type('image/avif'),
      url('/assets/images/winekits-page-header-800.webp') type('image/webp'),
      url('/assets/images/winekits-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Liqueurs hero — four jewel-coloured liqueur bottles on a wooden
   table with berries, citrus and elderflower in the foreground,
   sunset hills behind. Focal point sits along the bottom strip
   (bottles + ingredients); the sky/hills above are atmospheric
   bokeh that crops out cleanly on wider viewports. The image's
   1.96:1 aspect is closer to Beers than Wines, so we mirror the
   Beers sizing scale. */
.gi-hero--liqueurs {
  background-image: image-set(
    url('/assets/images/liqueurs-page-header.avif') type('image/avif'),
    url('/assets/images/liqueurs-page-header.webp') type('image/webp'),
    url('/assets/images/liqueurs-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  min-height: clamp(300px, 38vw, 560px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--liqueurs {
    background-image: image-set(
      url('/assets/images/liqueurs-page-header-800.avif') type('image/avif'),
      url('/assets/images/liqueurs-page-header-800.webp') type('image/webp'),
      url('/assets/images/liqueurs-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Starter Kits hero — first-brew still-life: glass demijohn with
   airlock at centre, hydrometer in a trial jar, wine glass, beer
   pint, small liqueur decanter and scattered ingredients across the
   bottom of a rustic kitchen worktop. Designed to read "this kit
   covers every discipline" at a glance. Same 1.96:1 aspect as the
   Liqueurs image so it reuses the Beers/Liqueurs sizing scale. */
.gi-hero--starterkits {
  background-image: image-set(
    url('/assets/images/starterkits-page-header.avif') type('image/avif'),
    url('/assets/images/starterkits-page-header.webp') type('image/webp'),
    url('/assets/images/starterkits-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  min-height: clamp(300px, 38vw, 560px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--starterkits {
    background-image: image-set(
      url('/assets/images/starterkits-page-header-800.avif') type('image/avif'),
      url('/assets/images/starterkits-page-header-800.webp') type('image/webp'),
      url('/assets/images/starterkits-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Grains hero — row of hessian sacks brimming with malts and grains
   (pale through to roasted-black, left to right), wheat ears and a
   cast-iron grain mill on a rustic wooden table. The sacks + scoops
   are the subject and sit across the centre-bottom of the source, so
   we anchor to `center bottom`; the dark shelving above crops out
   cleanly as the hero widens. Same 1.96:1 aspect as the Liqueurs and
   Starter Kits images, so it reuses the Beers sizing scale. */
.gi-hero--grains {
  background-image: image-set(
    url('/assets/images/grains-page-header.avif') type('image/avif'),
    url('/assets/images/grains-page-header.webp') type('image/webp'),
    url('/assets/images/grains-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  min-height: clamp(300px, 38vw, 560px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--grains {
    background-image: image-set(
      url('/assets/images/grains-page-header-800.avif') type('image/avif'),
      url('/assets/images/grains-page-header-800.webp') type('image/webp'),
      url('/assets/images/grains-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Chemicals hero — a warm apothecary / dispensary bench: a graduated glass
   cylinder with a hydrometer in amber wine, brass balance scales, stoppered
   apothecary bottles, ceramic dishes of white crystalline powder + Campden
   tablets, an acid-test strip, and a demijohn of bright cleared wine, on a
   rustic worktop backed by shelves of glass bottles. The bench cluster sits
   across the centre-bottom, so we anchor to `center bottom`; the shelving
   above crops out as the hero widens. Same 1.96:1 aspect as Grains, so it
   reuses the Beers sizing scale. */
.gi-hero--chemicals {
  background-image: image-set(
    url('/assets/images/chemicals-page-header.avif') type('image/avif'),
    url('/assets/images/chemicals-page-header.webp') type('image/webp'),
    url('/assets/images/chemicals-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  min-height: clamp(300px, 38vw, 560px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--chemicals {
    background-image: image-set(
      url('/assets/images/chemicals-page-header-800.avif') type('image/avif'),
      url('/assets/images/chemicals-page-header-800.webp') type('image/webp'),
      url('/assets/images/chemicals-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Hops hero — late-summer hop-harvest still-life: a spill of fresh green
   whole-leaf cones tumbling from a wicker basket, a bowl of golden-green
   pellets, a trailing bine and a glass of pale ale, backed by a hop yard at
   golden-hour. The cone spill + basket sit across the centre-bottom, so we
   anchor to `center bottom`; the sky and climbing bines up top crop out as
   the hero widens. Same 1.96:1 aspect as the other recent heroes, so it
   reuses the Beers sizing scale. The one green hero — kept warm by the
   golden-hour light. */
.gi-hero--hops {
  background-image: image-set(
    url('/assets/images/hops-page-header.avif') type('image/avif'),
    url('/assets/images/hops-page-header.webp') type('image/webp'),
    url('/assets/images/hops-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  min-height: clamp(300px, 38vw, 560px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--hops {
    background-image: image-set(
      url('/assets/images/hops-page-header-800.avif') type('image/avif'),
      url('/assets/images/hops-page-header-800.webp') type('image/webp'),
      url('/assets/images/hops-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Equipment hero — a well-stocked brewer's workshop: an oak barrel, copper
   boiler, glass demijohns, a pressure barrel and bottles in the foreground,
   a coiled syphon and funnels on the bench, backed by shelves of kit in warm
   workshop light. The showpiece cluster sits across the centre-bottom, so we
   anchor to `center bottom`; the laden shelving up top crops out as the hero
   widens. Same 1.96:1 aspect as the other recent heroes, so it reuses the
   Beers sizing scale. */
.gi-hero--equipment {
  background-image: image-set(
    url('/assets/images/equipment-page-header.avif') type('image/avif'),
    url('/assets/images/equipment-page-header.webp') type('image/webp'),
    url('/assets/images/equipment-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  min-height: clamp(300px, 38vw, 560px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--equipment {
    background-image: image-set(
      url('/assets/images/equipment-page-header-800.avif') type('image/avif'),
      url('/assets/images/equipment-page-header-800.webp') type('image/webp'),
      url('/assets/images/equipment-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Sugars hero — a warm pantry sugar still-life: an open kilner jar / scoop of
   fine white brewing sugar spilling on the wood, a dish of jewel-like amber
   Belgian candi rock-sugar, a jar of golden syrup mid-pour, loose crystals
   glinting, backed by pantry shelves of jars. The sugar cluster sits across
   the centre-bottom, so we anchor to `center bottom`; the shelving up top
   crops out as the hero widens. Same 1.96:1 aspect as the other recent
   heroes, so it reuses the Beers sizing scale. */
.gi-hero--sugars {
  background-image: image-set(
    url('/assets/images/sugars-page-header.avif') type('image/avif'),
    url('/assets/images/sugars-page-header.webp') type('image/webp'),
    url('/assets/images/sugars-page-header.jpg') type('image/jpeg')
  );
  background-position: center bottom;
  min-height: clamp(300px, 38vw, 560px);
  padding: var(--space-md);
  justify-content: flex-end;
}

@media (max-width: 800px) {
  .gi-hero--sugars {
    background-image: image-set(
      url('/assets/images/sugars-page-header-800.avif') type('image/avif'),
      url('/assets/images/sugars-page-header-800.webp') type('image/webp'),
      url('/assets/images/sugars-page-header-800.jpg') type('image/jpeg')
    );
  }
}

/* Homepage hero — "the stone threshold". Inside a Cotswold-stone
   brewhouse, the beer → equipment → wine → liqueur still-life runs
   along an oak bench beneath a mullioned window, golden barley
   fields beyond (the layout mirrors the Brewing & Vinting banner:
   hops on the left, grapes on the right). The 2.33:1 source keeps
   everything important in the bottom band, weighted to the right, so
   `right bottom` anchoring holds the still-life in frame while the
   stone wall and beam above crop away on wide viewports. Bottom-left is quiet
   stone/bench shadow — that's where the glass card sits. */
.gi-hero--home {
  background-image: image-set(
    url('/assets/images/home-page-header.avif') type('image/avif'),
    url('/assets/images/home-page-header.webp') type('image/webp'),
    url('/assets/images/home-page-header.jpg') type('image/jpeg')
  );
  background-position: right bottom;
  min-height: clamp(340px, 40vw, 600px);
  padding: var(--space-md);
  justify-content: flex-end;
  /* Tighter than the category-hero default (2xl): the callout strip
     below carries its own padding, and the combined gap was pushing
     the strip and the first section heading below the fold. */
  margin-block-end: var(--space-md);
}

@media (max-width: 800px) {
  .gi-hero--home {
    background-image: image-set(
      url('/assets/images/home-page-header-800.avif') type('image/avif'),
      url('/assets/images/home-page-header-800.webp') type('image/webp'),
      url('/assets/images/home-page-header-800.jpg') type('image/jpeg')
    );
    /* The homepage card (title + strapline + stacked CTAs) is tall on
       small screens — without a taller floor it fills the hero and the
       photo vanishes. 480px leaves a visible strip of the scene above
       the card. */
    min-height: 480px;
  }
}

.gi-hero__overlay {
  background: linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.7) 100%);
  padding: var(--space-3xl) var(--space-xl) var(--space-2xl);
  color: var(--color-white);
}

/* Glass-card overlay — anchored to the bottom-left of the hero with
   a frosted-glass appearance: dark tint for legibility, rounded
   corners, and a backdrop blur that softens the photo behind the
   text without hiding it. Sits inside the hero with margin on the
   bottom and sides so the photo remains visible around it.

   Note on flex axes: the hero is `flex-direction: column`, so
   `align-self` controls horizontal placement and `margin-top: auto`
   does the vertical "push to bottom". `align-self: flex-start` →
   left edge of the cross-axis. */
.gi-hero__overlay--glass {
  align-self: flex-start;
  /* the 100% cap stops the card's fit-content width (CTA row, long
     title word) escaping the hero on the narrowest phones */
  max-width: min(50ch, 100%);
  padding: var(--space-md) var(--space-lg);
  border-radius: var(--border-radius);
  /* Override the base overlay's full-bleed gradient with a single
     translucent tint — the gradient direction makes no sense once
     we're inside a small card. */
  background: rgba(0, 0, 0, 0.4);
  /* Backdrop blur produces the "frosted glass" effect; saturate
     bumps colour back up since the blur tends to wash it out. The
     -webkit- prefix keeps Safari < 18 working. */
  backdrop-filter: blur(6px) saturate(1.1);
  -webkit-backdrop-filter: blur(6px) saturate(1.1);
}

/* Fallback for browsers without backdrop-filter support — use a
   more opaque background so legibility doesn't depend on the blur. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .gi-hero__overlay--glass {
    background: rgba(0, 0, 0, 0.6);
  }
}

.gi-hero__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-display);
  margin-block-end: var(--space-md);
  /* Override the global h1 forest-green colour — over a dark photo
     overlay the brand green is unreadable. White matches the body
     copy in the overlay and gives consistent contrast. */
  color: var(--color-white);
}

.gi-hero__text {
  max-width: 65ch;
  line-height: var(--line-height-body);
  font-size: var(--font-size-base);
}

/* The homepage card carries more than the category ones (display
   title + strapline + two CTA buttons), so it gets a touch more
   width; the category default of 50ch wraps the uppercase display
   title awkwardly. */
.gi-hero__overlay--home {
  max-width: 56ch;
}

/* ── Kit cards (Beers) ──────────────────────────────────── */

.gi-kit-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.gi-kit {
  display: flex;
  gap: var(--space-lg);
  align-items: flex-start;
  background: var(--color-warm-cream);
  border-radius: var(--border-radius);
  padding: var(--space-lg);
  box-shadow: var(--shadow-card);
  /* Anchor for the stretched-link pseudo-element below. */
  position: relative;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.gi-kit:hover {
  box-shadow: var(--shadow-elevated);
  transform: translateY(-2px);
}

.gi-kit:focus-within {
  box-shadow: var(--shadow-elevated);
}

.gi-kit__image {
  width: 100px;
  height: auto;
  border-radius: var(--border-radius-sm);
  flex-shrink: 0;
}

.gi-kit__name {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 600;
  color: var(--color-forest-green);
  margin-block-end: var(--space-xs);
}

.gi-kit__body p {
  line-height: var(--line-height-body);
  margin-block-end: var(--space-sm);
}

.gi-kit__link {
  font-family: var(--font-heading);
  font-weight: 500;
  color: var(--color-link);
  text-decoration: none;
}

.gi-kit__link:hover {
  color: var(--color-link-hover);
}

/* Stretched-link pattern: the anchor's ::after layer covers the whole
   card, so any click on the tile activates the link. Single <a> keeps
   the markup semantic — one link in the AT tree, SEO crawlers see one
   target. The tradeoff is that text under the overlay isn't drag-
   selectable (the click layer catches the pointer); users can still
   double-click words and the touch experience is unaffected. */
.gi-kit__link::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* ── Tile grid (Equipment, Beer single-tins) ────────────── */

.gi-tile-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  margin-block-end: var(--space-xl);
}

.gi-tile-grid--3col {
  grid-template-columns: repeat(2, 1fr);
}

/* Vintage bottle-label frame: a hairline green border plus an inset
   second rule (outline-offset), matching the product purchase panel and
   category cards. The frame deepens to solid forest-green on hover. */
.gi-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  background: var(--color-warm-cream);
  border: 1px solid rgba(45, 90, 39, 0.28);
  outline: 1px solid rgba(45, 90, 39, 0.14);
  outline-offset: -6px;
  border-radius: var(--border-radius);
  padding: var(--space-md);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: var(--color-charcoal);
  transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}

.gi-tile:hover {
  box-shadow: var(--shadow-elevated);
  transform: translateY(-3px);
  border-color: var(--color-forest-green);
}

.gi-tile img {
  width: 100%;
  max-width: 120px;
  height: 120px;
  object-fit: contain;
  border-radius: var(--border-radius-sm);
  margin-block-end: var(--space-sm);
  background: var(--color-white);
}

.gi-tile__label {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-size-caption);
  color: var(--color-forest-green);
  margin-block-start: auto;
}

/* ── Photo tiles (Equipment) ────────────────────────────────
   Frameless full-bleed photo tiles for the brewer's-bench landing.
   The still-life photograph IS the tile — no border chrome, no
   padding, no white product cut-out. The category name sits on a
   charcoal scrim along the bottom edge; hover lifts the card and
   eases the photo into a slow zoom. */
.gi-photo-tile {
  position: relative;
  display: block;
  border-radius: var(--border-radius);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  text-decoration: none;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.gi-photo-tile picture,
.gi-photo-tile img {
  display: block;
  width: 100%;
  height: 100%;
}

.gi-photo-tile img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.gi-photo-tile:hover,
.gi-photo-tile:focus-visible {
  box-shadow: var(--shadow-elevated);
  transform: translateY(-3px);
}

.gi-photo-tile:hover img,
.gi-photo-tile:focus-visible img {
  transform: scale(1.05);
}

.gi-photo-tile__label {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  padding: var(--space-xl) var(--space-sm) var(--space-sm);
  background: linear-gradient(180deg, rgba(43, 43, 43, 0) 0%, rgba(43, 43, 43, 0.78) 75%);
  color: var(--color-warm-cream);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-size-caption);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Optional second line on wide (feature/duo) tiles — a short
   plain-case strapline under the category name. */
.gi-photo-tile__sub {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--font-size-caption);
  letter-spacing: normal;
  text-transform: none;
  color: rgba(250, 247, 240, 0.85);
  margin-block-start: 2px;
}

/* Bench grid: the Equipment photo-tile layout. 2-up on mobile,
   3-up from tablet — it deliberately does NOT widen to the 4-up
   desktop grid, so the photography keeps its size. Each group
   leads with a --feature tile spanning two tracks (5 tiles fill
   2+1 / 1+1+1 cleanly); a 4-tile group closes with a --wide tile
   so the second row mirrors the first (2+1 / 1+2) instead of
   leaving an empty cell. */
.gi-photo-tile--feature,
.gi-photo-tile--wide {
  grid-column: span 2;
}

.gi-photo-tile--feature img,
.gi-photo-tile--wide img {
  aspect-ratio: 2 / 1;
}

/* Duo rows: a two-tile group reads as a pair of wide landscape
   tiles instead of leaving half a grid row empty. Single column
   on mobile (see responsive sections for the 2-up layout). */
.gi-tile-grid--duo {
  grid-template-columns: 1fr;
}

.gi-tile-grid--duo .gi-photo-tile img {
  aspect-ratio: 5 / 3;
}

/* ── Grouped "brewer's bench" landing (Equipment) ───────── */

/* Editorial lead beneath the hero — sets the "sorted by the job it does"
   framing in the brand voice, closed by a single hop-sprig ornament. */
.gi-bench-intro {
  margin-block: var(--space-xl) var(--space-2xl);
}

/* A themed stage of the brew journey: a centred chapter heading with a
   short description, followed by its tile grid. */
.gi-group {
  margin-block-end: var(--space-2xl);
}

.gi-group__head {
  text-align: center;
  max-width: 60ch;
  margin-inline: auto;
  margin-block-end: var(--space-lg);
}

.gi-group__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h2);
  font-weight: 600;
  color: var(--color-forest-green);
  margin-block-end: 0;
}

/* Short double rule under the title — a quiet echo of the bottle-label
   frame that runs through the cards. */
.gi-group__title::after {
  content: "";
  display: block;
  width: 3rem;
  height: 4px;
  margin: var(--space-sm) auto var(--space-md);
  border-block: 1px solid var(--color-forest-green);
}

.gi-group__desc {
  color: var(--color-stone-grey);
  line-height: var(--line-height-body);
  margin-block-end: 0;
}

/* Sub-categories without a photo tile, offered as pills beneath the grid.
   Reuses .pill-list styling but left-aligns and drops the centring cap. */
.gi-group__more {
  justify-content: flex-start;
  align-items: baseline;
  max-width: none;
  margin-block-start: var(--space-md);
}

.gi-group__more-label {
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  color: var(--color-stone-grey);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ── Reference list (Chemicals) ─────────────────────────── */

.gi-reference-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.gi-reference {
  display: flex;
  gap: var(--space-xl);
  padding-block-end: var(--space-xl);
  border-bottom: 1px solid rgba(122, 122, 122, 0.15);
}

.gi-reference:last-child {
  border-bottom: none;
}

.gi-reference__body {
  flex: 1;
}

.gi-reference__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 600;
  color: var(--color-forest-green);
  margin-block-end: var(--space-sm);
}

.gi-reference__body p {
  line-height: var(--line-height-body);
  margin-block-end: var(--space-sm);
}

.gi-reference__links {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  flex-shrink: 0;
  min-width: 160px;
  padding-block-start: var(--space-xl);
}

.gi-reference__links a {
  font-family: var(--font-heading);
  font-weight: 500;
  color: var(--color-link);
  text-decoration: none;
  padding: var(--space-xs) 0;
}

.gi-reference__links a:hover {
  color: var(--color-link-hover);
}

/* "All …" link: sits at the foot of a section's link list and leads to the
   full ilk listing (every product in the above sub-categories). */
.gi-reference__links a.gi-reference__all {
  margin-block-start: var(--space-xs);
  padding-block-start: var(--space-sm);
  border-block-start: 1px solid var(--color-border, rgba(0, 0, 0, 0.15));
  font-weight: 700;
}

.gi-reference__links a.gi-reference__all::after {
  content: " \2192"; /* → */
}

/* ── Grain list (Grains) ────────────────────────────────── */

.gi-grain-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.gi-grain {
  display: flex;
  gap: var(--space-xl);
  padding: var(--space-lg);
  background: var(--color-warm-cream);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-card);
  /* Whole card is a single link to the category listing (the stretched
     `.gi-grain__all` anchor below). `position: relative` anchors that
     anchor's `::after` overlay; the pointer cursor signals clickability. */
  position: relative;
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.gi-grain:hover {
  box-shadow: var(--shadow-elevated);
  transform: translateY(-2px);
}

.gi-grain__body {
  flex: 1;
}

.gi-grain__title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 600;
  color: var(--color-forest-green);
  margin-block-end: var(--space-xs);
}

/* The varieties are now plain text (a "what's inside" summary), not links —
   the whole card links to the category listing. Slightly muted, medium
   weight so the line reads as a contents list above the description. */
.gi-grain__varieties {
  margin-block-end: var(--space-sm);
  font-weight: 500;
  color: var(--color-stone-grey);
}

.gi-grain__body p {
  line-height: var(--line-height-body);
  margin-block-end: var(--space-sm);
}

.gi-grain__aside {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  flex-shrink: 0;
  /* Fixed width (not min-width) so every aside is identical regardless of its
     "All …" label length — the centred images then share one vertical
     centreline down the column, even though the illustrations differ in
     width and aspect. */
  width: 130px;
  text-align: center;
}

/* Tall botanical grain illustrations — render as a slim stalk beside the
   text. Capped by height so a long ear (e.g. rye) doesn't tower over the
   card; width follows the aspect ratio. */
.gi-grain__image {
  width: auto;
  max-width: 90px;
  max-height: 160px;
  height: auto;
}

/* The single real link for the card. Its `::after` overlay stretches across
   the whole `.gi-grain` (which is `position: relative`), so a click or tap
   anywhere on the card follows this link — while keyboard users still get one
   focusable, descriptively-labelled target ("All Pale Malts" etc.). */
.gi-grain__all {
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 500;
  color: var(--color-link);
  text-decoration: none;
}

.gi-grain__all::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--border-radius);
}

.gi-grain:hover .gi-grain__all {
  color: var(--color-link-hover);
  text-decoration: underline;
}

/* Keyboard focus draws a ring around the whole card (the stretched overlay). */
.gi-grain__all:focus-visible::after {
  outline: 2px solid var(--color-link);
  outline-offset: 2px;
}


/* ================================================================
   13. BUTTONS
   ================================================================ */

.button-primary,
.button-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  font-family: var(--font-heading);
  font-size: var(--font-size-base);
  font-weight: 700;
  /* `<button>` defaults to line-height: normal but `<a>` inherits the body's
     1.6 — without this, anchor buttons sit taller than real buttons when the
     two appear side by side (e.g. the checkout success actions). */
  line-height: 1.2;
  padding: var(--space-sm) var(--space-lg);
  border-radius: var(--border-radius-sm);
  border: 2px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.button-primary {
  background-color: var(--color-crimson);
  color: var(--color-white);
  border-color: var(--color-crimson);
}

.button-primary:hover {
  background-color: var(--color-crimson-dark);
  border-color: var(--color-crimson-dark);
  color: var(--color-white);
}

.button-primary:active {
  transform: scale(0.97);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}

.button-secondary {
  background-color: transparent;
  color: var(--color-forest-green);
  border-color: var(--color-forest-green);
}

.button-secondary:hover {
  background-color: var(--color-forest-green);
  color: var(--color-white);
}

.button-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  align-items: center;
}

/* Controllers toggle `hidden` on whole button groups (e.g. the checkout
   success nav variants); the flex display above would otherwise win over
   the UA's [hidden] rule and show both variants at once. */
.button-group[hidden] {
  display: none;
}

.button-group--center {
  justify-content: center;
}

/* Inverse (ghost) secondary — for dark green surfaces like the hero. */
.button-secondary--inverse {
  color: var(--color-white);
  border-color: var(--color-white);
}

.button-secondary--inverse:hover {
  background-color: var(--color-white);
  color: var(--color-forest-green);
}


/* ================================================================
   14. SITE FOOTER
   ================================================================ */

.site-footer {
  grid-area: footer;
  background-color: var(--color-charcoal);
  color: var(--color-off-white);
  padding-block: var(--space-2xl) var(--space-xl);
  border-top: 4px solid var(--color-forest-green);
}

.site-footer a {
  color: var(--color-off-white);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--color-white);
  text-decoration: underline;
}

.site-footer__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-xl);
  padding-inline: var(--container-padding);
}

.site-footer__section-title {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 600;
  color: var(--color-white);
  margin-block-end: var(--space-sm);
}

.site-footer__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  font-size: var(--font-size-caption);
}

.site-footer__inner > div + div {
  padding-block-start: var(--space-lg);
  border-block-start: 1px solid rgba(255, 255, 255, 0.1);
}

.site-footer__copyright {
  border-block-start: 1px solid rgba(255, 255, 255, 0.15);
  padding-block-start: var(--space-md);
  margin-block-start: var(--space-xl);
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
  text-align: center;
  padding-inline: var(--container-padding);
}


/* ================================================================
   15. OFFERS
   ================================================================ */

.offer-banner {
  background-color: var(--color-crimson);
  color: var(--color-white);
  text-align: center;
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--font-size-caption);
}

.offer-banner a {
  color: var(--color-white);
  text-decoration: underline;
}


/* ================================================================
   15b. EMPTY STATE
   ================================================================ */

.empty-state {
  text-align: center;
  padding: var(--space-3xl) var(--space-xl);
}

.empty-state__icon {
  font-size: 4rem;
  margin-block-end: var(--space-md);
  opacity: 0.3;
}

.empty-state__message {
  font-family: var(--font-heading);
  font-size: var(--font-size-h2);
  color: var(--color-charcoal);
  margin-block-end: var(--space-sm);
}

.empty-state__hint {
  font-size: var(--font-size-base);
  color: var(--color-stone-grey);
  margin-block-end: var(--space-lg);
}


/* ================================================================
   15b. BASKET PAGE + ASIDE MINI-BASKET
   ================================================================ */

/* V6 "refined sheet" (2026-08): ledger-style line sheet + order-summary
   card. Breakpoints are CONTAINER queries — the sidebar (>=768px viewport)
   and right aside (>=1024px) make the content column NON-monotonic in
   viewport width (a 1024px viewport has less content width than a 640px
   one), so viewport media queries would misfire. Rows stack below 480cqw,
   the column-header grid appears at 480cqw, the sticky summary rail at
   800cqw; below that the summary joins the sheet as one tile. */
.basket-page {
  container: basket / inline-size;
}

.basket-page [hidden] {
  display: none !important;
}

/* Heading row: title + continue-shopping pill on one line. */
.basket-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-block-end: var(--space-lg);
}

.basket-head h1 {
  margin: 0;
}

.basket-continue {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-forest-green);
  border: 1px solid rgba(45, 90, 39, 0.35);
  border-radius: 999px;
  padding: 0.4rem 0.85rem;
  text-decoration: none;
  white-space: nowrap;
}

.basket-continue:hover {
  background: var(--color-forest-green);
  color: var(--color-warm-cream);
}

.basket-page__loading,
.basket-page__error {
  padding: var(--space-lg);
  text-align: center;
  color: var(--color-stone-grey);
}

/* Reassure rather than alarm: warm panel in a crimson-tinted label frame,
   plain charcoal text, and an escape hatch back into the shop. */
.basket-page__error {
  background-color: var(--color-warm-cream);
  border: 1px solid rgba(204, 34, 34, 0.4);
  outline: 1px solid rgba(204, 34, 34, 0.18);
  outline-offset: -6px;
  border-radius: var(--border-radius);
  color: var(--color-charcoal);
}

.basket-page__error p {
  margin-block-end: var(--space-sm);
}

.basket-page__error-hint {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.basket-page__error .button-group {
  margin-block-start: var(--space-md);
}

/* ── Two-column shell: mobile-first the summary joins the sheet as one
   tile; at 800cqw it detaches into a sticky rail. ── */
.basket-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  align-items: start;
}

/* Item-count tally: single-column only — the rail shows the count on
   desktop, and removing it lets the sheet top align with the summary top. */
.basket-tally {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--color-stone-grey);
  font-size: var(--font-size-caption);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.basket-tally b {
  color: var(--color-forest-green);
  font-size: 1.15em;
}

/* Twin CTA: slim bar above the sheet; basket-page.js shows it only when
   the summary is not sticky AND the main CTA sits below the fold. */
.basket-topcta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  background: var(--color-white);
  border-radius: var(--border-radius-sm);
  box-shadow: var(--shadow-card);
  padding: var(--space-sm) var(--space-md);
  margin-block-end: var(--space-md);
}

.basket-topcta span {
  font-family: var(--font-heading);
  font-weight: 600;
}

.basket-topcta b {
  color: var(--color-forest-green);
  font-size: 1.15em;
}

.basket-topcta .button-primary {
  padding: 0.5rem 1.2rem;
  font-size: var(--font-size-caption);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ── The line sheet ── */
.basket-sheet {
  background: var(--color-white);
  border-radius: var(--border-radius) var(--border-radius) 0 0;
  box-shadow: var(--shadow-card);
  padding: var(--space-md);
}

/* Column headers: hidden while rows are stacked (<480cqw). */
.basket-sheet__cols {
  display: none;
}

.basket-lines {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Row: stacked by default (narrow), grid columns from 480cqw. */
.basket-line {
  display: grid;
  gap: var(--space-xs) var(--space-sm);
  align-items: center;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  grid-template-areas:
    "image details zap"
    "image qty     money";
  padding: var(--space-sm);
  border-block-end: 1px solid rgba(122, 122, 122, 0.15);
}

.basket-line:last-child {
  border-block-end: none;
}

.basket-line.is-unavailable {
  opacity: 0.65;
}

.basket-line__image {
  grid-area: image;
  width: 48px;
  height: 48px;
  align-self: start;
  background-color: var(--color-warm-cream);
  border-radius: var(--border-radius-sm);
  padding: 3px;
}

.basket-line__image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.basket-line__details {
  grid-area: details;
  min-width: 0;
}

.basket-line__eyebrow {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #7E6310;
}

.basket-line__name {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--color-forest-green);
  text-decoration: none;
}

.basket-line__name:hover {
  color: var(--color-crimson);
  text-decoration: underline;
}

.basket-line__size {
  display: block;
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.basket-line__unavailable {
  font-size: var(--font-size-caption);
  font-weight: 600;
  color: var(--color-crimson);
}

.basket-line__message {
  margin: var(--space-xs) 0 0;
  font-size: var(--font-size-caption);
  color: var(--color-crimson);
}

/* The row checkout refused for stock: tinted so it's found at a glance. */
.basket-line.is-out-of-stock {
  background-color: rgba(204, 34, 34, 0.06);
  box-shadow: inset 3px 0 0 var(--color-crimson);
}

.basket-line.is-out-of-stock .basket-line__message {
  font-weight: 600;
}

/* De-emphasised stepper: quiet outline, green only on interaction. */
.basket-line__qty {
  grid-area: qty;
  justify-self: start;
}

.basket-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(122, 122, 122, 0.35);
  border-radius: 999px;
  overflow: hidden;
}

.basket-stepper button {
  width: 1.7rem;
  height: 1.8rem;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-stone-grey);
  font-size: 0.95rem;
  line-height: 1;
  font-family: var(--font-heading);
  font-weight: 700;
}

.basket-stepper button:hover:not(:disabled) {
  background: rgba(45, 90, 39, 0.08);
  color: var(--color-forest-green);
}

.basket-stepper button:disabled {
  opacity: 0.5;
  cursor: default;
}

.basket-stepper b {
  min-width: 1.8em;
  text-align: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--font-size-caption);
  color: var(--color-charcoal);
}

.basket-line__money {
  grid-area: money;
  justify-self: end;
  text-align: right;
}

.basket-line__total {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Unit price: shown by basket-page.js only when qty > 1. */
.basket-line__each {
  display: block;
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.basket-line__zap {
  grid-area: zap;
  justify-self: end;
}

.basket-line__remove {
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-stone-grey);
  font-size: 0.85rem;
  line-height: 1;
  padding: 0.3rem;
}

.basket-line__remove:hover {
  color: var(--color-crimson);
}

/* ── Order summary ── */
.basket-summary {
  background: var(--color-white);
  border-radius: 0 0 var(--border-radius) var(--border-radius);
  box-shadow: var(--shadow-card);
  padding: var(--space-md);
  padding-top: 0;
}

/* Joined-tile seam: drawn inside the padding so it spans the same content
   width as the column-header rule at the top of the grid. The summary is
   the later sibling, so its background covers the sheet's bottom shadow. */
.basket-summary::before {
  content: "";
  display: block;
  border-top: 2px solid var(--color-forest-green);
  margin-bottom: var(--space-md);
}

.basket-summary h2 {
  font-size: var(--font-size-h3);
  margin: 0 0 var(--space-sm);
  color: var(--color-forest-green);
}

.basket-summary__rows {
  margin: 0;
}

.basket-summary__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-sm);
  padding: var(--space-xs) 0;
}

.basket-summary__row dd {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.basket-summary__row--grand dd {
  font-size: 1.4rem;
  color: var(--color-forest-green);
}

/* Summary rows are display:flex, which would otherwise defeat the [hidden]
   attribute the basket/checkout scripts toggle on the coupon, gift-token and
   to-pay rows — a "−£0.00" line would still paint. */
.basket-summary__row[hidden],
.checkout-summary__row[hidden],
.checkout-success__totals-row[hidden] {
  display: none;
}

.basket-delivery {
  margin: var(--space-xs) 0;
  padding: var(--space-sm) 0;
  border: none;
  border-top: 1px solid rgba(122, 122, 122, 0.2);
  border-bottom: 1px solid rgba(122, 122, 122, 0.2);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  font-size: var(--font-size-caption);
}

.basket-delivery__option {
  display: flex;
  gap: 0.45em;
  align-items: center;
  cursor: pointer;
}

.basket-delivery__price {
  margin-left: auto;
  font-family: var(--font-heading);
  font-weight: 600;
}

.basket-delivery__option:has(input:disabled) {
  cursor: not-allowed;
  opacity: 0.55;
}

/* Courier weight-ceiling notice (basket API `totals.tooHeavy`). */
.basket-delivery__note {
  margin: 0;
  color: var(--color-error, #a33);
}

.basket-delivery__note[hidden] {
  display: none;
}

/* ── Gift token / coupon entry (V6 stackable flow, discounts spec §5) ──
   A quiet stone-grey dotted-underline text link near the total discloses a
   small inline form; each applied code collapses to a removable
   "✓ CODE −£x ✕" line. Deliberately unemphasised. */
.basket-codes {
  margin: var(--space-xs) 0;
  padding: var(--space-xs) 0;
  border-bottom: 1px solid rgba(122, 122, 122, 0.2);
  font-size: var(--font-size-caption);
}

.basket-codes__link {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--color-stone-grey);
  font-size: var(--font-size-caption);
  text-decoration: underline dotted;
  text-underline-offset: 0.2em;
}

.basket-codes__link:hover {
  color: var(--color-forest-green);
}

.basket-codes__list {
  list-style: none;
  margin: 0 0 var(--space-xs);
  padding: 0;
}

.basket-code {
  display: flex;
  align-items: baseline;
  gap: 0.45em;
  padding: 2px 0;
}

.basket-code__tick {
  color: var(--color-forest-green);
}

.basket-code__ref {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: 0.03em;
}

.basket-code__amount {
  margin-left: auto;
  font-family: var(--font-heading);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-forest-green);
}

.basket-code__remove {
  background: none;
  border: none;
  padding: 0 0 0 0.35em;
  cursor: pointer;
  color: var(--color-stone-grey);
  font-size: 0.85em;
  line-height: 1;
}

.basket-code__remove:hover {
  color: var(--color-error, #a33);
}

.basket-codes__form {
  display: flex;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

.basket-codes__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.35em 0.5em;
  border: 1px solid rgba(122, 122, 122, 0.4);
  border-radius: 4px;
  font: inherit;
  text-transform: uppercase;
}

.basket-codes__apply {
  padding: 0.35em 0.9em;
  border: 1px solid var(--color-forest-green);
  border-radius: 999px;
  background: none;
  color: var(--color-forest-green);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.basket-codes__apply:hover {
  background: var(--color-forest-green);
  color: #fff;
}

.basket-codes__error {
  margin: var(--space-xs) 0 0;
  color: var(--color-error, #a33);
}

/* Codes applied to an empty basket — listed under the empty state so they
   stay visible and removable. */
.basket-empty-codes {
  max-width: 22rem;
  margin: var(--space-lg) auto 0;
  text-align: left;
  font-size: var(--font-size-caption);
}

.basket-empty-codes__hint {
  margin: 0 0 var(--space-xs);
  color: var(--color-stone-grey);
}

.basket-summary__checkout {
  display: block;
  width: 100%;
  margin-block-start: var(--space-sm);
  text-align: center;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.basket-summary__hint {
  margin: var(--space-sm) 0 0;
  text-align: center;
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

/* Inline padlock: an SVG rather than the 🔒 emoji, whose glyph varies by
   platform (some emoji fonts draw a black keyhole face). Sized to the text
   and coloured forest green via currentColor. */
.basket-summary__lock {
  width: 0.85em;
  height: 1.05em;
  vertical-align: -0.12em;
  margin-inline-end: 0.15em;
  color: var(--color-forest-green);
}

/* ── 480cqw: rows take the ledger grid, column headers appear ── */
@container basket (min-width: 480px) {
  .basket-line {
    grid-template-columns: 48px minmax(0, 1fr) auto minmax(90px, auto) 24px;
    grid-template-areas: "image details qty money zap";
    gap: var(--space-md);
  }

  .basket-line__image {
    align-self: center;
  }

  .basket-line__qty {
    justify-self: center;
  }

  .basket-sheet__cols {
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr) auto minmax(90px, auto) 24px;
    gap: var(--space-md);
    padding: 0 var(--space-sm) var(--space-xs);
    border-bottom: 2px solid var(--color-forest-green);
    margin-bottom: 2px;
    font-family: var(--font-heading);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-stone-grey);
  }

  .basket-sheet__c-qty {
    text-align: center;
  }

  .basket-sheet__c-total {
    text-align: right;
  }
}

/* ── 800cqw: the summary detaches into a sticky rail ── */
@container basket (min-width: 800px) {
  .basket-cols {
    grid-template-columns: minmax(0, 1fr) 288px;
    gap: var(--space-xl);
  }

  .basket-tally {
    display: none;
  }

  .basket-sheet {
    border-radius: var(--border-radius);
  }

  .basket-summary {
    position: sticky;
    top: calc(var(--topbar-height) + var(--space-md));
    border-radius: var(--border-radius);
    padding: var(--space-lg);
  }

  .basket-summary::before {
    display: none;
  }
}

/* ── Checkout order summary (goods / delivery / total) ── */
.checkout-summary {
  margin: 0 0 var(--space-md);
  padding: var(--space-md);
  background-color: var(--color-mist, rgba(122, 122, 122, 0.06));
  border-radius: var(--border-radius);
}

.checkout-summary__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  margin: 0;
}

.checkout-summary__row--total {
  margin-block-start: var(--space-xs);
  padding-block-start: var(--space-xs);
  border-block-start: 1px solid rgba(122, 122, 122, 0.2);
  font-weight: 700;
}

.checkout-summary__value {
  margin: 0;
  color: var(--color-forest-green);
  font-weight: 600;
}

/* ── Aside mini-basket (desktop summary widget) ── */
.aside-basket[hidden] {
  display: none;
}

.aside-basket__lines {
  list-style: none;
  margin: 0 0 var(--space-sm);
  padding: 0;
  font-size: var(--font-size-caption);
}

.aside-basket__line {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: var(--space-xs) var(--space-sm);
  padding-block: var(--space-xs);
  border-block-end: 1px solid rgba(122, 122, 122, 0.12);
}

.aside-basket__line-qty {
  font-family: var(--font-heading);
  font-weight: 700;
  color: var(--color-stone-grey);
  font-variant-numeric: tabular-nums;
}

.aside-basket__line-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-link);
  text-decoration: none;
}

.aside-basket__line-name:hover {
  color: var(--color-link-hover);
  text-decoration: underline;
}

.aside-basket__line-total {
  font-weight: 700;
  color: var(--color-charcoal);
  white-space: nowrap;
}

.aside-basket__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-block: var(--space-sm) var(--space-md);
  font-family: var(--font-heading);
}

.aside-basket__total strong {
  font-size: var(--font-size-h3);
  color: var(--color-forest-green);
}

.aside-basket__checkout {
  width: 100%;
}

.aside-basket__view {
  display: block;
  margin-block-start: var(--space-sm);
  text-align: center;
  font-size: var(--font-size-caption);
  color: var(--color-link);
}

/* Desktop-only: below the 3-column breakpoint the aside stacks beneath the
   page content, where a basket summary would be redundant with the topbar
   cart — hide it there regardless of its hydrated state. */
@media (max-width: 1023.98px) {
  .aside-basket {
    display: none !important;
  }
}


/* ================================================================
   15e. BASKET TRAY (bottom micro-basket)
   ================================================================
   Fixed pill at the foot of the viewport, hydrated by basket-tray.js:
   item count, goods total, and view-basket / checkout actions. Hidden
   while the basket is empty and never rendered on the basket, checkout
   or admin pages. */

.basket-tray[hidden] {
  display: none;
}

.basket-tray {
  position: fixed;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: var(--color-forest-green);
  color: var(--color-white);
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  box-shadow: var(--shadow-elevated);
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  animation: basket-tray-up 0.25s ease;
  white-space: nowrap;
}

@keyframes basket-tray-up {
  from {
    opacity: 0;
    transform: translate(-50%, 12px);
  }
}

.basket-tray svg {
  width: 1.25em;
  height: 1.25em;
  flex: none;
}

.basket-tray__count b {
  font-size: 1.1em;
}

.basket-tray__total {
  color: #F0C86A;
  font-weight: 700;
  font-size: 1.05rem;
  padding-left: 0.7rem;
  border-left: 1px solid rgba(255, 255, 255, 0.35);
}

.basket-tray__view,
.basket-tray__checkout {
  font-weight: 600;
  text-decoration: none;
  padding: 0.3rem 0.8rem;
  border-radius: 999px;
}

.basket-tray__view {
  color: var(--color-white);
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.45);
}

.basket-tray__view:hover {
  background: var(--color-white);
  color: var(--color-forest-green);
}

/* Checkout is the stronger action: solid white on the green pill. */
.basket-tray__checkout {
  color: var(--color-forest-green);
  background: var(--color-white);
  border: 1px solid var(--color-white);
}

.basket-tray__checkout:hover {
  background: #F0C86A;
  border-color: #F0C86A;
}

/* Centre the tray on the content column, not the viewport, once the
   sidebar is in play. */
@media (min-width: 768px) {
  .basket-tray {
    left: calc(50% + var(--sidebar-width) / 2);
  }
}

@media (max-width: 639px) {
  .basket-tray {
    left: 0.75rem;
    right: 0.75rem;
    transform: none;
    justify-content: space-between;
    gap: 0.5rem;
  }

  @keyframes basket-tray-up {
    from {
      opacity: 0;
      transform: translateY(12px);
    }
  }

  /* Keep the pill lean on small screens: drop the icon so count, total
     and both actions fit. */
  .basket-tray svg {
    display: none;
  }
}

/* Small phones: one row can't hold count + total + both actions
   ("Checkout →" clipped off-screen at 360). Stack into two rows —
   count and total on top, the action pills sharing the second row. */
@media (max-width: 479.98px) {
  .basket-tray {
    display: grid;
    grid-template-columns: 1fr 1fr;
    row-gap: 0.55rem;
    column-gap: 0.5rem;
    border-radius: 1.1rem;
    padding: 0.7rem 1rem;
  }

  .basket-tray__count {
    justify-self: start;
  }

  .basket-tray__total {
    justify-self: end;
  }

  /* Grid stretches the pills across their cells — centre the labels. */
  .basket-tray__view,
  .basket-tray__checkout {
    text-align: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .basket-tray {
    animation: none;
  }
}


/* ================================================================
   15d. ACCOUNT — ORDER HISTORY
   ================================================================ */

.account-orders {
  max-width: 860px;
}

.account-orders__loading,
.account-orders__error {
  padding: var(--space-lg);
  text-align: center;
  color: var(--color-stone-grey);
}

.account-orders__error {
  background-color: #fdecec;
  border: 1px solid var(--color-crimson);
  border-radius: var(--border-radius);
  color: var(--color-crimson-dark);
}

/* ── Order list: stack of white cards, one per order ── */
.account-orders__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.account-orders__list[hidden] {
  display: none;
}

.order-card {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "summary actions"
    "result  result"
    "detail  detail";
  gap: var(--space-md) var(--space-lg);
  align-items: start;
  /* As a flex item in the list, keep the card from being widened past the
     viewport by its own wide detail table (which scrolls instead). */
  min-width: 0;
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-card);
  padding: var(--space-lg);
}

.order-card__summary {
  grid-area: summary;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
}

.order-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-sm) var(--space-md);
}

.order-card__date {
  font-family: var(--font-heading);
  font-weight: 700;
  color: var(--color-forest-green);
}

.order-card__invoice {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

/* The J-number quoted on the confirmation screen and email. */
.order-card__ref {
  font-family: var(--font-heading);
  font-weight: 700;
  color: var(--color-charcoal);
}

/* The order a link pointed at (`#order-<id>` on load). */
.order-card.is-linked {
  box-shadow: 0 0 0 2px var(--color-forest-green), var(--shadow-card);
  scroll-margin-top: calc(var(--topbar-height) + var(--space-md));
}

.order-card__preview {
  margin: 0;
  color: var(--color-charcoal);
}

.order-card__count {
  margin: 0;
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.order-card__totals {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
  margin-block-start: var(--space-xs);
}

.order-card__total {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--font-size-h3);
  color: var(--color-charcoal);
}

.order-card__total-note {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.order-card__actions {
  grid-area: actions;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-sm);
}

.order-card__reorder-result {
  grid-area: result;
  margin: 0;
  font-size: var(--font-size-caption);
  color: var(--color-forest-green);
}

.order-card__reorder-result[hidden] {
  display: none;
}

.order-card__reorder-result a {
  color: var(--color-link);
  margin-inline-start: var(--space-xs);
}

.order-card__detail {
  grid-area: detail;
  /* Grid items default to min-width:auto; zero it so the wide line-item table
     scrolls within this cell rather than stretching the whole card. */
  min-width: 0;
}

.order-card__detail[hidden] {
  display: none;
}

/* ── Expanded detail: the line-item table ── */
.order-detail {
  border-block-start: 1px solid rgba(122, 122, 122, 0.15);
  padding-block-start: var(--space-md);
}

/* "Paid by Mastercard ending 3690" — quiet meta line above the lines table. */
.order-detail__paid-by {
  margin: 0 0 var(--space-sm);
  font-size: 0.875rem;
  color: var(--color-text-muted, #7a7a7a);
}

/* Scroll wrapper: lets the full-width table scroll horizontally within the
   card on narrow screens (the standard responsive-table pattern). `position:
   relative` contains the header's absolutely-positioned `.visually-hidden`
   label so it can't escape to the viewport and force page-wide overflow. */
.order-detail__scroll {
  overflow-x: auto;
  position: relative;
}

.order-detail__lines {
  width: 100%;
  border-collapse: collapse;
}

.order-detail__lines thead th {
  text-align: left;
  padding: var(--space-xs) var(--space-sm);
  font-size: var(--font-size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-stone-grey);
  border-block-end: 1px solid rgba(122, 122, 122, 0.2);
}

.order-detail__lines tbody td {
  padding: var(--space-sm);
  vertical-align: middle;
  border-block-end: 1px solid rgba(122, 122, 122, 0.1);
}

.order-detail__lines tbody tr:last-child td {
  border-block-end: none;
}

/* Numeric columns (Qty / Price / Line total) right-aligned, header + body. */
.order-detail__lines th:nth-child(2),
.order-detail__lines th:nth-child(3),
.order-detail__lines th:nth-child(4),
.order-detail__qty,
.order-detail__price,
.order-detail__line-total {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.order-detail__item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-width: 0;
}

/* Same treatment as .basket-line__image — keep the two in step. */
.order-detail__thumb {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  background-color: var(--color-warm-cream);
  border-radius: var(--border-radius-sm);
  padding: 3px;
}

.order-detail__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.order-detail__item-name {
  min-width: 0;
  font-weight: 600;
  color: var(--color-charcoal);
}

.order-detail__line-action {
  text-align: right;
  white-space: nowrap;
}

.order-detail__line-action .button-secondary {
  padding: var(--space-xs) var(--space-md);
  font-size: var(--font-size-caption);
}

/* ── Pager ── */
.account-orders__pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  margin-block-start: var(--space-xl);
}

.account-orders__pager[hidden] {
  display: none;
}

.account-orders__page-label {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

/* ── Narrow screens: collapse the card to a single column ── */
@media (max-width: 600px) {
  .order-card {
    grid-template-columns: 1fr;
    grid-template-areas:
      "summary"
      "actions"
      "result"
      "detail";
  }

  .order-card__actions {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .order-card__actions .button-primary,
  .order-card__actions .button-secondary {
    flex: 1 1 auto;
  }
}


/* ================================================================
   15c. ACCOUNT (login / verify) + CHECKOUT
   ================================================================ */

/* Centre the focused single-task pages (auth + checkout) in the content
   column and give their heading a centred treatment to match the card. */
.page-content:has(> .account-login),
.page-content:has(> .account-verify),
.page-content:has(> .checkout-page) {
  text-align: center;
}

/* Shared "task card": a centred, white, elevated panel. */
.account-login,
.account-verify,
.checkout-page {
  max-width: 30rem;
  margin: var(--space-lg) auto 0;
  padding: var(--space-xl);
  background-color: var(--color-white);
  border: 1px solid rgba(122, 122, 122, 0.18);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-card);
  text-align: center;
}

/* Primary/secondary actions inside a task card span its width and stack. */
.account-login .button-primary,
.account-login .button-secondary,
.account-verify .button-primary,
.checkout-details .button-primary,
.checkout-payment .button-primary {
  width: 100%;
}

/* ── Checkout details form ── */
.checkout-details {
  text-align: left;
}

.checkout-details__group {
  margin: 0 0 var(--space-lg);
  padding: 0;
  border: 0;
}

.checkout-details__legend {
  padding: 0;
  margin-block-end: var(--space-sm);
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  font-weight: 600;
  color: var(--color-forest-green);
}

.checkout-field {
  display: block;
  margin-block-end: var(--space-md);
}

/* The author `display:block` above would otherwise defeat the [hidden] default,
   so a field the controller hides (e.g. the details email field, suppressed once
   the email is captured at the email step) must explicitly collapse. */
.checkout-field[hidden] {
  display: none;
}

.checkout-field__label {
  display: block;
  margin-block-end: var(--space-2xs, 0.25rem);
  font-weight: 600;
  color: var(--color-charcoal);
}

.checkout-field__hint {
  display: block;
  margin-block-end: var(--space-2xs, 0.25rem);
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

.checkout-field__optional {
  font-weight: 400;
  color: var(--color-stone-grey);
}

.checkout-field__input {
  width: 100%;
  padding: var(--space-sm);
  font: inherit;
  color: var(--color-charcoal);
  background-color: var(--color-white);
  border: 1px solid rgba(122, 122, 122, 0.4);
  border-radius: var(--border-radius);
}

.checkout-field__input:focus {
  outline: 2px solid var(--color-forest-green);
  outline-offset: 1px;
  border-color: var(--color-forest-green);
}

.checkout-field__input--short {
  max-width: 10rem;
}

.checkout-field__input--textarea {
  resize: vertical;
  min-height: 3.5rem;
}

.checkout-details__collection {
  margin: 0 0 var(--space-lg);
  padding: var(--space-md);
  background-color: var(--color-mist, rgba(122, 122, 122, 0.06));
  border-radius: var(--border-radius);
  color: var(--color-charcoal);
}

/* Delivery-or-collection chooser on the details step (mirrors .basket-delivery,
   card-styled so the selectable options read as a choice, not form noise). */
.checkout-fulfilment__option {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  margin-block-end: var(--space-xs);
  border: 1px solid rgba(122, 122, 122, 0.25);
  border-radius: var(--border-radius);
  cursor: pointer;
}

.checkout-fulfilment__option:has(input:checked) {
  border-color: var(--color-forest-green);
  background-color: var(--color-mist, rgba(122, 122, 122, 0.06));
}

.checkout-fulfilment__option input {
  flex: none;
}

.checkout-fulfilment__option:has(input:disabled) {
  cursor: not-allowed;
  opacity: 0.55;
}

.checkout-fulfilment__name {
  flex: 1 1 auto;
  font-weight: 600;
  color: var(--color-charcoal);
}

.checkout-fulfilment__hint {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
}

/* 3-step progress track: Email → Delivery → Payment. Each step is a
   column (marker over a centred label) so labels never wrap beside the
   marker on a phone; the connecting rail runs through the markers and
   fills green behind every completed step. */
.checkout-steps {
  --steps-marker: 1.85rem;
  --steps-rail: rgba(122, 122, 122, 0.28);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin: 0 0 var(--space-xl);
  padding: 0;
  list-style: none;
  counter-reset: checkout-step;
  /* A step change scrolls the strip back into view (checkout-page.js);
     land it clear of the sticky topbar. */
  scroll-margin-top: calc(var(--topbar-height) + var(--space-md));
}

/* display:grid above would otherwise defeat the [hidden] default. */
.checkout-steps[hidden] {
  display: none;
}

.checkout-steps__step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
  counter-increment: checkout-step;
  text-align: center;
}

/* Each step is a button: completed steps are enabled so the buyer can go
   back and change their email or delivery details (checkout-page.js);
   the current and upcoming ones stay disabled and read as plain text. */
.checkout-steps__go {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  cursor: default;
}

.checkout-steps__go:not(:disabled) {
  cursor: pointer;
}

.checkout-steps__go:not(:disabled):hover .checkout-steps__label,
.checkout-steps__go:focus-visible .checkout-steps__label {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.checkout-steps__go:focus-visible {
  outline: none;
}

.checkout-steps__go:focus-visible .checkout-steps__marker {
  box-shadow: 0 0 0 4px rgba(45, 90, 39, 0.28);
}

.checkout-steps__marker {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--steps-marker);
  block-size: var(--steps-marker);
  border: 2px solid var(--steps-rail);
  border-radius: 50%;
  background: var(--color-white);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.checkout-steps__marker::before {
  content: counter(checkout-step);
}

/* The rail: one segment on each side of the marker, meeting at the
   column edges so neighbours join into a continuous line. */
.checkout-steps__step::before,
.checkout-steps__step::after {
  content: '';
  position: absolute;
  top: calc(var(--steps-marker) / 2 - 1px);
  inline-size: 50%;
  border-block-start: 2px solid var(--steps-rail);
}

.checkout-steps__step::before { left: 0; }
.checkout-steps__step::after { right: 0; }
.checkout-steps__step:first-child::before,
.checkout-steps__step:last-child::after { content: none; }

.checkout-steps__label {
  letter-spacing: 0.02em;
}

/* Current: solid green marker, bold label. */
.checkout-steps__step.is-current {
  color: var(--color-forest-green);
}

.checkout-steps__step.is-current .checkout-steps__label {
  font-weight: 600;
}

.checkout-steps__step.is-current .checkout-steps__marker {
  background: var(--color-forest-green);
  border-color: var(--color-forest-green);
  color: var(--color-white);
  box-shadow: 0 0 0 4px rgba(45, 90, 39, 0.14);
}

.checkout-steps__step.is-current::before {
  border-color: var(--color-forest-green);
}

/* Complete: tick in a green ring, and the rail either side turns green. */
.checkout-steps__step.is-complete {
  color: var(--color-forest-green);
}

.checkout-steps__step.is-complete .checkout-steps__marker {
  border-color: var(--color-forest-green);
  color: var(--color-forest-green);
}

.checkout-steps__step.is-complete .checkout-steps__marker::before {
  content: '\2713';
}

.checkout-steps__step.is-complete::before,
.checkout-steps__step.is-complete::after {
  border-color: var(--color-forest-green);
}

.checkout-details__error {
  margin-block-end: var(--space-md);
  color: var(--color-error, #b3261e);
  font-weight: 600;
}

/* Login card: left-aligned form under a centred envelope + heading
   (design-concepts/login round 2, V6). The verify card keeps the centred
   treatment from the shared task-card rule above. */
.account-login {
  text-align: left;
}

.account-login [hidden] {
  display: none !important;
}

.account-login__mark {
  text-align: center;
  margin: -0.25rem 0 var(--space-md);
}

.account-login__envelope {
  width: 92px;
  height: auto;
  display: inline-block;
}

/* Phones: drop the envelope mark so the form sits above the fold. */
@media (max-width: 600px) {
  .account-login__mark {
    display: none;
  }
}

/* Invalid address: red border to match the inline error beneath it. */
.account-login.has-email-error .account-login__field input[type="email"] {
  border-color: var(--color-crimson);
}

/* In-card page heading (the layout's own <h1> is suppressed via hideHeading). */
.account-login__heading {
  font-family: var(--font-heading);
  font-size: 1.75rem;
  line-height: 1.2;
  color: var(--color-forest-green);
  text-align: center;
  margin: 0 0 var(--space-lg);
}

.account-login__lede,
.account-verify__intro {
  color: #555555;
  line-height: 1.5;
  margin-block-end: var(--space-lg);
}

.account-login__lede {
  text-align: center;
}

.account-login__sent-to {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.3rem 0.6rem;
  color: #555555;
  line-height: 1.4;
  margin: 0 0 var(--space-lg);
}

.account-login__sent-to strong {
  color: var(--color-charcoal);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.account-login__sent-to a,
.account-login__linkbtn {
  color: var(--color-forest-green);
  text-decoration: underline;
  text-underline-offset: 2px;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
}

.account-login__sent-to a:hover,
.account-login__linkbtn:hover {
  color: var(--color-crimson);
}

/* Field group: stacked label + full-width input. */
.account-login__field {
  margin-block-end: var(--space-md);
}

.account-login__field label,
.account-login__field-label {
  display: block;
  text-align: left;
  font-family: var(--font-heading);
  font-weight: 600;
  margin-block-end: var(--space-xs);
}

.account-login__field input[type="email"] {
  width: 100%;
  padding: 0.7rem 0.9rem;
  border: 1px solid rgba(122, 122, 122, 0.38);
  border-radius: var(--border-radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  text-align: left;
  background-color: var(--color-white);
  color: var(--color-charcoal);
}

.account-login input:focus-visible {
  outline: 2px solid var(--color-forest-green);
  outline-offset: 1px;
  border-color: var(--color-forest-green);
}

/* Six digit cells in a 3 + 3 group; the form submits on the sixth digit. */
.account-login__cells {
  display: flex;
  gap: 0.45rem;
}

.account-login__cell {
  flex: 1 1 0;
  min-width: 0;
  height: 3.75rem;
  padding: 0;
  text-align: center;
  font-family: var(--font-heading);
  font-size: 1.75rem;
  font-weight: 600;
  border: 1px solid rgba(122, 122, 122, 0.38);
  border-radius: var(--border-radius-sm);
  background-color: var(--color-white);
  color: var(--color-charcoal);
}

.account-login__cell:nth-child(3) {
  margin-inline-end: 0.7rem;
}

.account-login.has-error .account-login__cell {
  border-color: var(--color-crimson);
}

/* Inline error attached to the cells (role="alert"). */
.account-login__error {
  display: flex;
  gap: 0.45rem;
  align-items: flex-start;
  margin: 0.7rem 0 0;
  color: var(--color-crimson-dark);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.4;
}

.account-login__error svg {
  flex: 0 0 auto;
  width: 1.15em;
  height: 1.15em;
  margin-top: 0.12em;
}

/* Checkbox row with an optional help affordance. Left-aligned on the login
   card; the verify card inherits its centred alignment. */
.account-login__field--check {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  margin-block: var(--space-md) var(--space-lg);
  font-size: 0.95rem;
}

.account-login .account-login__field--check {
  justify-content: flex-start;
}

.account-login__field--check label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  font-family: var(--font-body);
  font-weight: 400;
  margin-block-end: 0;
  cursor: pointer;
}

/* ── Field help: a small "?" with a hover/focus popover ── */
.field-help {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.field-help__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid var(--color-stone-grey);
  border-radius: 50%;
  background: transparent;
  color: var(--color-stone-grey);
  font-family: var(--font-heading);
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.field-help__btn:hover,
.field-help__btn:focus-visible {
  border-color: var(--color-forest-green);
  color: var(--color-forest-green);
}

/* Anchored to the "?"'s RIGHT edge (the "?" always sits at the end of its
   row) so the popover never overflows a phone screen. */
.field-help__popover {
  position: absolute;
  bottom: calc(100% + 8px);
  right: -6px;
  z-index: 30;
  width: 230px;
  max-width: 78vw;
  padding: var(--space-sm) var(--space-md);
  background-color: var(--color-charcoal);
  color: var(--color-white);
  border-radius: var(--border-radius-sm);
  box-shadow: var(--shadow-elevated);
  font-family: var(--font-body);
  font-size: var(--font-size-caption);
  font-weight: 400;
  line-height: 1.4;
  text-align: left;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease, visibility 0.15s ease;
}

/* Little arrow pointing down at the "?". */
.field-help__popover::after {
  content: "";
  position: absolute;
  top: 100%;
  right: 9px;
  border: 6px solid transparent;
  border-top-color: var(--color-charcoal);
}

/* Reveal on hover or when the "?" (or popover) holds focus — works for mouse,
   keyboard, and tap (tap focuses the button). */
.field-help:hover .field-help__popover,
.field-help:focus-within .field-help__popover {
  opacity: 1;
  visibility: visible;
}

.account-login__field--check input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
  margin: 0;
  flex: 0 0 auto;
  accent-color: var(--color-forest-green);
}

/* Secondary copy under the code form: resend countdown, expiry, link hint. */
.account-login__secondary {
  margin-block-start: var(--space-lg);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid rgba(122, 122, 122, 0.2);
  font-size: 0.9rem;
  color: #555555;
  line-height: 1.45;
}

.account-login__secondary p {
  margin: 0 0 0.45rem;
}

.account-login__secondary p:last-child {
  margin-block-end: 0;
}

.account-login__expiry {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--color-charcoal);
}

/* Signed-in moment: green seal, centred. */
.account-login__done {
  text-align: center;
}

.account-login__done .account-login__lede {
  margin-block-end: 0;
}

/* aria-live status regions: collapse when empty, forest green when filled. */
.account-login__status,
.account-verify__status {
  margin: 0;
  min-height: 0;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--color-forest-green);
}

.account-login__status:not(:empty),
.account-verify__status:not(:empty) {
  margin-block-start: var(--space-md);
}

/* Gentle error panel for an expired/used sign-in link — label frame. */
.account-verify__error {
  margin-block-start: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
  border: 1px solid rgba(204, 34, 34, 0.35);
  outline: 1px solid rgba(204, 34, 34, 0.16);
  outline-offset: -6px;
  border-radius: var(--border-radius-sm);
  background-color: rgba(204, 34, 34, 0.06);
  color: var(--color-charcoal);
}

.account-verify__error p {
  margin-block-end: var(--space-sm);
}

.account-verify__error p:last-child {
  margin-block-end: 0;
}

/* ── Checkout page (shares the centred task-card above) ── */
.checkout-page {
  max-width: 34rem;
}

.checkout-page__loading {
  color: var(--color-stone-grey);
  padding-block: var(--space-md);
}

/* The empty / success states already centre their own content; just relax the
   card padding so the big icon + button group breathe. */
.checkout-page .empty-state {
  padding: var(--space-md) 0;
}

/* Error panel — same gentle label-frame treatment as the auth error. */
.checkout-page__error {
  text-align: left;
  padding: var(--space-md) var(--space-lg);
  border: 1px solid rgba(204, 34, 34, 0.35);
  outline: 1px solid rgba(204, 34, 34, 0.16);
  outline-offset: -6px;
  border-radius: var(--border-radius-sm);
  background-color: rgba(204, 34, 34, 0.06);
}

.checkout-page__error-lead {
  font-family: var(--font-heading);
  font-weight: 700;
  margin-block-end: var(--space-xs);
}

.checkout-page__error-message {
  color: var(--color-stone-grey);
  margin-block-end: var(--space-md);
}

/* ── Email + sign-in code steps ──
   Built from the same fragments and classes as /account/login/ so the two
   flows are one design. The checkout page IS the task card, so strip the
   card chrome the .account-login class would otherwise add. */
.checkout-page .account-login {
  max-width: none;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  text-align: left;
}

.checkout-page .account-login .account-login__field-label {
  display: block;
  margin-block-end: var(--space-xs);
}

/* ── Payment step ── */
.checkout-payment__heading {
  font-family: var(--font-heading);
  font-size: var(--font-size-h3);
  color: var(--color-forest-green);
  margin-block-end: var(--space-lg);
}

/* The Stripe Payment Element is a left-aligned form; don't let the centred
   card text-align bleed into it. */
.checkout-payment__element {
  text-align: left;
  margin-block-end: var(--space-lg);
}


.checkout-payment__status:not(:empty) {
  margin-block-start: var(--space-sm);
  color: var(--color-stone-grey);
}

/* ── Success state ── */
.checkout-success__icon {
  font-size: 3rem;
  margin-block-end: var(--space-sm);
}

.checkout-success__heading {
  font-family: var(--font-heading);
  font-size: var(--font-size-h2);
  color: var(--color-forest-green);
  margin-block-end: var(--space-md);
}

.checkout-success__order {
  font-weight: 600;
}

.checkout-success__order span {
  font-family: var(--font-heading);
  word-break: break-all;
}

.checkout-success__note {
  color: var(--color-stone-grey);
  margin-block: var(--space-sm) var(--space-md);
}

.checkout-success__verify-cta {
  color: var(--color-stone-grey);
  font-size: var(--font-size-caption);
  margin-block-end: var(--space-md);
}

/* ── Success: the buyer's details, played back ── */
.checkout-success__details {
  margin-block-start: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
  background-color: var(--color-off-white);
  border: 1px solid rgba(122, 122, 122, 0.15);
  border-radius: var(--border-radius-md);
  text-align: left;
}

.checkout-success__details-heading {
  font-family: var(--font-heading);
  font-size: var(--font-size-h4);
  margin-block-end: var(--space-sm);
}

.checkout-success__details-row {
  display: flex;
  gap: var(--space-md);
  padding-block: var(--space-xs);
  border-top: 1px solid rgba(122, 122, 122, 0.1);
}

.checkout-success__details-row:first-child {
  border-top: 0;
}

/* The billing row toggles via `hidden`; flex above must not win over it. */
.checkout-success__details-row[hidden] {
  display: none;
}

.checkout-success__details-label {
  flex: 0 0 8rem;
  font-weight: 600;
}

.checkout-success__details-value {
  margin: 0;
  overflow-wrap: anywhere;
}

/* ── Success order summary ── */
.checkout-success__summary {
  margin-block: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
  background-color: var(--color-off-white);
  border: 1px solid rgba(122, 122, 122, 0.15);
  border-radius: var(--border-radius-md);
  text-align: left;
}

.checkout-success__summary-heading {
  font-family: var(--font-heading);
  font-size: var(--font-size-h4);
  margin-block-end: var(--space-md);
}

.checkout-success__lines {
  width: 100%;
  border-collapse: collapse;
  margin-block-end: var(--space-md);
}

.checkout-success__th,
.checkout-success__td {
  padding: var(--space-xs) 0;
  border-bottom: 1px solid rgba(122, 122, 122, 0.1);
}

.checkout-success__th {
  font-weight: 600;
  font-size: var(--font-size-caption);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-stone-grey);
}

.checkout-success__th--qty,
.checkout-success__td--qty {
  text-align: center;
  width: 3rem;
}

.checkout-success__th--price,
.checkout-success__td--price {
  text-align: right;
  width: 5rem;
}

.checkout-success__totals {
  border-top: 2px solid rgba(122, 122, 122, 0.15);
  padding-block-start: var(--space-sm);
}

.checkout-success__totals-row {
  display: flex;
  justify-content: space-between;
  padding-block: var(--space-xs);
}

.checkout-success__totals-row--total {
  font-weight: 700;
  font-size: 1.1em;
  border-top: 1px solid rgba(122, 122, 122, 0.1);
  padding-block-start: var(--space-sm);
  margin-block-start: var(--space-xs);
}

/* ── Success actions ── */
.checkout-success__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  justify-content: center;
  align-items: center;
  margin-block-start: var(--space-lg);
}

/* ── Print styles — the success state prints as a clean receipt ── */
@media print {
  /* Hide the process steps, on-screen actions and screen-only copy so only
     the receipt content prints. Site chrome (topbar/sidebar/aside/footer) is
     hidden by the global print section — never hide body > * here: the page
     content lives inside .site-layout and would vanish site-wide. */
  .checkout-steps,
  .checkout-success__actions,
  .checkout-success__icon,
  .checkout-success__note,
  .checkout-success__verify-cta,
  [data-checkout-loading],
  [data-checkout-empty],
  [data-checkout-error],
  [data-checkout-email],
  [data-checkout-otp],
  [data-checkout-details],
  [data-checkout-payment] {
    display: none !important;
  }

  /* The layout's "Checkout" <h1> reads oddly above a receipt — the success
     heading carries the page instead. */
  .page-content:has([data-checkout-page]) > h1 {
    display: none;
  }

  /* Flatten the screen card: full width, no box, left-aligned like a receipt. */
  .checkout-page {
    max-width: none;
    margin: 0;
    padding: 0;
    background: #fff;
    border: none;
    border-radius: 0;
    box-shadow: none;
    text-align: left;
  }

  .checkout-success__heading {
    font-size: 16pt;
    color: #2D5A27;
    margin-block-end: 4pt;
  }

  .checkout-success__order {
    font-size: 9pt;
    font-weight: 400;
    color: #444;
  }

  .checkout-success__order span {
    font-weight: 600;
  }

  /* Cards become ruled sections: no boxes, headings underlined in brand green. */
  .checkout-success__details,
  .checkout-success__summary {
    background: #fff;
    border: none;
    border-radius: 0;
    padding: 0;
    margin-block: 14pt 0;
    break-inside: avoid;
  }

  .checkout-success__details-heading,
  .checkout-success__summary-heading {
    font-size: 12pt;
    color: #2D5A27;
    border-bottom: 1.5pt solid #2D5A27;
    padding-block-end: 3pt;
    margin-block-end: 6pt;
  }

  .checkout-success__details-row {
    border-top: none;
    padding-block: 2pt;
  }

  .checkout-success__details-label {
    flex-basis: 30mm;
  }

  .checkout-success__th,
  .checkout-success__td {
    border-bottom: 0.75pt solid #bbb;
  }

  .checkout-success__th {
    font-size: 8.5pt;
    letter-spacing: 0.06em;
    color: #555;
  }

  .checkout-success__totals {
    border-top: none;
  }

  .checkout-success__totals-row {
    padding-block: 2pt;
  }

  .checkout-success__totals-row--total {
    border-top: 1.5pt solid #2D5A27;
    padding-block-start: 4pt;
  }

  /* Print-only sign-off: contact details for queries about the order. */
  .checkout-success::after {
    content: "Thank you for brewing with Stonehelm. Questions about this order? 01865 343 275 · info@stonehelm.co.uk";
    display: block;
    margin-block-start: 18pt;
    padding-block-start: 6pt;
    border-top: 0.75pt solid #bbb;
    font-size: 9pt;
    color: #555;
  }
}

/* Button groups inside these centred cards: centre + allow stacking. */
.checkout-page .button-group {
  justify-content: center;
}


/* ── Calculator ─────────────────────────────────────── */

.calculator {
  max-width: 400px;
  padding: var(--space-lg);
  background-color: var(--color-off-white);
  border: 1px solid rgba(122, 122, 122, 0.15);
  border-radius: var(--border-radius-md);
}

.calculator__field {
  margin-block-end: var(--space-md);
}

.calculator__field label {
  display: block;
  font-family: var(--font-heading);
  font-weight: 600;
  margin-block-end: var(--space-xs);
}

.calculator__input {
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(122, 122, 122, 0.3);
  border-radius: var(--border-radius-sm);
  font-size: var(--font-size-base);
}

.calculator__result {
  margin-block-start: var(--space-lg);
  padding: var(--space-md);
  background-color: var(--color-white);
  border-radius: var(--border-radius-sm);
  text-align: center;
}

.calculator--wide {
  max-width: 560px;
}

.calculator--wide fieldset {
  border: 1px solid rgba(122, 122, 122, 0.2);
  border-radius: var(--border-radius-sm);
  padding: var(--space-md);
  margin-block-end: var(--space-md);
}

.calculator--wide legend {
  padding: 0 var(--space-xs);
}

.calculator__row {
  display: flex;
  gap: var(--space-sm);
  align-items: flex-end;
  margin-block-end: var(--space-sm);
}

.calculator__field--inline {
  flex: 1;
  margin-block-end: 0;
}

.calculator__input--result {
  background-color: var(--color-white);
  font-weight: 700;
}

.calculator__error {
  margin-block-start: var(--space-md);
  color: var(--color-wine-red, #8b1a1a);
  font-weight: 600;
}

.calculator__warn {
  margin-block-start: var(--space-md);
  color: #8b6914;
  font-weight: 600;
}

/* Wide two-column calculator (water calculator): paired fieldsets on
   big screens, single column when the container can't fit two. */
.calculator--columns {
  max-width: 960px;
}

.calculator__columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  column-gap: var(--space-md);
  align-items: start;
}

/* Fieldsets refuse to shrink below min-content by default, which breaks
   narrow viewports; the grid track is the sizing authority here. */
.calculator--columns fieldset {
  min-inline-size: 0;
  min-width: 0;
}

/* Unit dropdown sharing a row with its input. */
.calculator__row > .calculator__unit-select {
  flex: 0 0 42%;
}

/* Checkbox / radio row: control and label on one line. Wraps so a wide
   trailing control (the CaCl₂ hydrate select) drops to its own line on
   phones instead of pushing the page sideways. */
.calculator__check {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin-block-end: var(--space-sm);
}

.calculator__check label {
  display: inline;
  font-family: var(--font-heading);
  font-weight: 600;
}

.calculator__check input[type='checkbox'],
.calculator__check input[type='radio'] {
  flex-shrink: 0;
}

.calculator__check .calculator__input {
  width: auto;
  flex: 1 1 150px;
  min-width: 0;
}

/* Results tables can exceed narrow viewports — scroll inside the card. */
.calculator__table-scroll {
  overflow-x: auto;
}

/* Results tables: real table styling inside the (large-type, centred)
   result card — base type size, ruled rows, numbers right-aligned. */
.calculator__table {
  width: 100%;
  margin-block-start: var(--space-sm);
  border-collapse: collapse;
  font-size: var(--font-size-base);
}

.calculator__table th,
.calculator__table td {
  padding: var(--space-xs) var(--space-sm);
  text-align: right;
  border-bottom: 1px solid rgba(122, 122, 122, 0.2);
}

.calculator__table th:first-child,
.calculator__table td:first-child {
  text-align: left;
}

.calculator__table thead th {
  border-bottom: 2px solid rgba(122, 122, 122, 0.45);
  font-family: var(--font-heading);
}

.calculator__table tbody tr:nth-child(even) {
  background-color: rgba(122, 122, 122, 0.06);
}

.calculator__status--good {
  color: var(--color-forest-green, #2d5a27);
  font-weight: 600;
  white-space: nowrap;
}

.calculator__status--over,
.calculator__status--under {
  color: #8b6914;
  font-weight: 600;
  white-space: nowrap;
}

.calculator__status--muted {
  color: var(--color-stone-grey, #7a7a7a);
  font-weight: 400;
}

/* Overall verdict line above the achieved-vs-target table. */
.calculator__verdict {
  font-size: var(--font-size-base);
  font-weight: 700;
  margin-block: var(--space-xs) 0;
}

.calculator__verdict--good {
  color: var(--color-forest-green, #2d5a27);
}

.calculator__verdict--partial {
  color: #8b6914;
}

/* Calculator print: keep the entered water, doses and results; drop the
   interactive-only controls. Chrome is hidden by the global print section. */
@media print {
  .calculator,
  .calculator--wide {
    max-width: none;
    padding: 0;
    border: none;
    background: #fff;
  }

  .calculator button,
  #wc-mode,
  #wc-salts,
  #wc-hardness-helper,
  #wc-results > .calculator__field,
  .print-hidden {
    display: none !important;
  }

  .calculator__result {
    background: #fff;
    border: 1px solid #ccc;
    break-inside: avoid;
  }

  .calculator--wide fieldset {
    break-inside: avoid;
  }

  .calculator__table-scroll {
    overflow-x: visible;
  }

  /* Paper is narrower than the 340px two-column threshold — force the
     tap-water/target pair side by side anyway; they fit at print sizes. */
  .calculator__columns {
    grid-template-columns: 1fr 1fr;
  }

  /* A focus ring left on the last-touched input prints as a red box. */
  .calculator :focus,
  .calculator :focus-visible {
    outline: none !important;
  }
}

/* -- Examples accordion -- */

.examples-section {
  margin-block-start: var(--space-xl);
  max-width: 560px;
}

.examples-section h3 {
  margin-block-end: var(--space-md);
}

.example-accordion {
  border: 1px solid rgba(122, 122, 122, 0.2);
  border-radius: var(--border-radius-sm);
  margin-block-end: var(--space-sm);
  background: var(--color-white, #fff);
}

.example-accordion summary {
  padding: var(--space-md);
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-size-base);
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.example-accordion summary::-webkit-details-marker {
  display: none;
}

.example-accordion summary::before {
  content: '\25B6';
  font-size: 0.7em;
  transition: transform 0.2s ease;
  flex-shrink: 0;
}

.example-accordion[open] summary::before {
  transform: rotate(90deg);
}

.example-accordion__body {
  padding: 0 var(--space-md) var(--space-md);
}

.example-accordion__body h4 {
  font-family: var(--font-heading);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-forest-green, #2d5a27);
  margin-block: var(--space-md) var(--space-xs);
}

.example-accordion__body h4:first-child {
  margin-block-start: 0;
}

.example-accordion__body p {
  margin-block-end: var(--space-sm);
}

.example-accordion__body .example-screenshot {
  margin-block: var(--space-md);
  border: 1px solid rgba(122, 122, 122, 0.15);
  border-radius: var(--border-radius-sm);
  max-width: min(100%, 512px);
  height: auto;
}

.example-accordion__body .button-try {
  margin-block-start: var(--space-md);
  background: var(--color-forest-green, #2d5a27);
  color: var(--color-white, #fff);
  border: none;
  border-radius: var(--border-radius-sm);
  padding: var(--space-xs) var(--space-md);
  font-size: var(--font-size-small);
  font-family: var(--font-heading);
  font-weight: 600;
  cursor: pointer;
}

.example-accordion__body .button-try:hover {
  opacity: 0.85;
}

.example-accordion__body .example-note {
  font-size: var(--font-size-small);
  color: var(--color-text-muted, #666);
  font-style: italic;
  margin-block-start: var(--space-sm);
}

/* Side-by-side calculator + examples on wide screens */

.calculator-layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

@media (min-width: 1400px) {
  .calculator-layout {
    flex-direction: row;
    align-items: flex-start;
  }

  .calculator-layout .calculator {
    flex-shrink: 0;
    position: sticky;
    top: var(--space-md);
  }

  .calculator-layout .examples-section {
    flex: 1;
    min-width: 0;
    margin-block-start: 0;
    max-width: none;
  }
}

.button-sm {
  font-size: var(--font-size-small);
  padding: var(--space-xs) var(--space-sm);
}

.button-remove {
  background: none;
  border: 1px solid rgba(122, 122, 122, 0.2);
  border-radius: var(--border-radius-sm);
  cursor: pointer;
  font-size: 1.2rem;
  line-height: 1;
  padding: var(--space-xs) var(--space-sm);
  color: var(--color-text-muted);
}

.button-remove:hover {
  background: rgba(139, 26, 26, 0.1);
  color: var(--color-wine-red, #8b1a1a);
}


/* ================================================================
   16. WINE SECTION VARIANT
   ================================================================ */

.wine-section h1,
.wine-section h2,
.wine-section h3,
.wine-section .make-menu-card__title,
.wine-section .ilk-menu-card__title {
  color: var(--color-grape-purple);
}

.wine-section .button-secondary {
  color: var(--color-grape-purple);
  border-color: var(--color-grape-purple);
}

.wine-section .button-secondary:hover {
  background-color: var(--color-grape-purple);
  color: var(--color-white);
}


/* ================================================================
   TABS (page-level navigation links)
   Shared by Tools / How To / Articles pages via info-tabs.11ty.js.
   Note: the base `.tabs__tab` reserves a 3px transparent bottom
   border so hover/active states only swap colors — never change
   box dimensions — to avoid reflow on pointer-in/out.
   ================================================================ */

.tabs__list {
  display: flex;
  gap: 0;
  border-bottom: 3px solid var(--color-forest-green, #2d5a27);
  margin-bottom: var(--space-lg, 2rem);
}

.tabs__tab {
  display: inline-block;
  padding: 0.65rem 1.4rem;
  border: 2px solid transparent;
  border-bottom-width: 3px;
  border-radius: 6px 6px 0 0;
  text-decoration: none;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--color-text-muted, #666);
  margin-bottom: -3px;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.tabs__tab:hover,
.tabs__tab--active {
  border-color: var(--color-forest-green, #2d5a27);
}

.tabs__tab:hover:not(.tabs__tab--active) {
  color: var(--color-forest-green, #2d5a27);
  background: var(--color-warm-cream, rgba(250, 247, 240, 0.5));
}

.tabs__tab--active {
  color: #fff;
  background: var(--color-forest-green, #2d5a27);
}

/* ── How-to sibling links ─────────────────────────────── */

.howto-links {
  border-top: 2px solid var(--color-forest-green, #2d5a27);
  padding-top: var(--space-lg, 2rem);
  margin-top: var(--space-2xl, 3rem);
}

.howto-links h3 {
  margin-block-end: var(--space-sm, 0.5rem);
  font-size: 1.1rem;
}

.howto-links ul {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm, 0.5rem);
}

.howto-links li a,
.howto-links li strong {
  display: inline-block;
  padding: 0.4rem 1rem;
  border-radius: 4px;
  font-size: 0.9rem;
  text-decoration: none;
}

.howto-links li a {
  background: var(--color-bg-subtle, #f5f5f5);
  color: var(--color-forest-green, #2d5a27);
  border: 1px solid var(--color-border, #ccc);
  transition: background 0.15s;
}

.howto-links li a:hover {
  background: var(--color-forest-green, #2d5a27);
  color: #fff;
  border-color: var(--color-forest-green, #2d5a27);
}

.howto-links__current strong {
  background: var(--color-forest-green, #2d5a27);
  color: #fff;
}

/* ── Index list (How To / Tools landing pages) ─────────── */

.index-list {
  list-style: none;
  padding: 0;
}

.index-list li {
  border-bottom: 1px solid rgba(122, 122, 122, 0.15);
}

.index-list li:first-child {
  border-top: 1px solid rgba(122, 122, 122, 0.15);
}

.index-list li a {
  display: block;
  padding: 0.75rem 0.75rem;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--color-forest-green, #2d5a27);
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: background 0.15s, border-color 0.15s;
}

.index-list li a:hover {
  background: var(--color-warm-cream, rgba(250, 247, 240, 0.5));
  border-left-color: var(--color-forest-green, #2d5a27);
}

.index-list__desc {
  display: block;
  font-family: var(--font-body, sans-serif);
  font-weight: 400;
  font-size: 0.9rem;
  color: var(--color-text, #333);
  margin-top: 0.15rem;
}

/* ── Knowledge Base index (/Articles/) ─────────────────── */

.kb-intro {
  max-width: 60ch;
  color: var(--color-text, #333);
}

.kb-section {
  margin-top: 2.75rem;
}

.kb-section__head {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.kb-section__medallion {
  flex: none;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  box-shadow: 0 1px 4px rgba(45, 90, 39, 0.25);
}

.kb-section__head h3 {
  margin: 0;
  font-family: var(--font-heading);
  color: var(--color-forest-green, #2d5a27);
  font-size: 1.35rem;
}

.kb-section__blurb {
  margin: 0.2rem 0 0;
  font-size: 0.92rem;
  color: var(--color-text, #333);
  max-width: 62ch;
}

.kb-pills {
  list-style: none;
  padding: 0;
  margin: 0.9rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.kb-pills a {
  display: inline-block;
  padding: 0.35rem 0.85rem;
  border: 1px solid rgba(45, 90, 39, 0.25);
  border-radius: 999px;
  background: var(--color-warm-cream, #faf7f0);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--color-forest-green, #2d5a27);
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.kb-pills a:hover {
  background: var(--color-forest-green, #2d5a27);
  border-color: var(--color-forest-green, #2d5a27);
  color: #fff;
}

@media (max-width: 480px) {
  .kb-section__medallion {
    width: 56px;
    height: 56px;
  }
}



/* ================================================================
   TERMS & CONTACT PAGE
   ================================================================ */

.terms-contact-grid {
  display: grid;
  gap: var(--space-lg, 2rem);
  grid-template-columns: 1fr;
}

@media (min-width: 768px) {
  .terms-contact-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.terms-contact-grid dt {
  font-weight: 700;
  margin-top: var(--space-sm, 0.5rem);
}

.terms-contact-grid dd {
  margin-left: 0;
}


/* ================================================================
   17. UTILITIES
   ================================================================ */

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

.flow > * + * {
  margin-block-start: var(--space-md);
}

.flow--lg > * + * {
  margin-block-start: var(--space-xl);
}

.text-center {
  text-align: center;
}

.text-right {
  text-align: right;
}

.mt-sm { margin-block-start: var(--space-sm); }
.mt-md { margin-block-start: var(--space-md); }
.mt-lg { margin-block-start: var(--space-lg); }
.mt-xl { margin-block-start: var(--space-xl); }
.mb-sm { margin-block-end: var(--space-sm); }
.mb-md { margin-block-end: var(--space-md); }
.mb-lg { margin-block-end: var(--space-lg); }
.mb-xl { margin-block-end: var(--space-xl); }


/* ================================================================
   17b. HERO SECTION (legacy — kept for reference)
   ================================================================ */

.hero {
  background: var(--gradient-hero);
  background-size: cover;
  position: relative;
  color: var(--color-white);
  text-align: center;
  padding-block: 5rem 4rem;
  overflow: hidden;
}

.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: url('/assets/images/grass-background.jpg') center / cover no-repeat;
  opacity: 0.15;
  pointer-events: none;
}

.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--gradient-hero-overlay);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
}

.hero__banner {
  max-width: 360px;
  margin-inline: auto;
  margin-block-end: var(--space-lg);
}

.hero h1 {
  color: var(--color-white);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  letter-spacing: 0.02em;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

.hero p {
  color: rgba(255, 255, 255, 0.9);
  font-size: clamp(1.1rem, 2.5vw, 1.5rem);
  max-width: 50ch;
  margin-inline: auto;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-md);
  margin-block-start: var(--space-xl);
}

.hero__actions .button-primary,
.hero__actions .button-secondary {
  min-width: 200px;
  padding: 0.75rem 2rem;
  font-size: 1.1rem;
}

.hero__actions .button-secondary {
  color: var(--color-white);
  border-color: var(--color-white);
}

.hero__actions .button-secondary:hover {
  background-color: var(--color-white);
  color: var(--color-forest-green);
}


/* ================================================================
   17c. CALLOUT STRIP (Trust badges)
   ================================================================ */

.callout-strip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
  padding-block: var(--space-md) var(--space-sm);
  color: var(--color-charcoal);
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.callout-strip__item {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  white-space: nowrap;
}

.callout-strip__item + .callout-strip__item::before {
  content: '\00b7';
  margin-inline-end: var(--space-xs);
  font-size: 1.4em;
  line-height: 1;
}


/* ================================================================
   17d. CATEGORY GRID & CARDS
   ================================================================ */

.category-grid {
  display: grid;
  /* minmax(0,…): a bare 1fr can't shrink below the card's min-content
     (the nbsp-glued "Equipment →" title) and overflows sub-330px phones */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-md);
}

/* Genre colour lives in a full hairline frame + the motif roundel (below),
   not an accent stripe; the frame deepens to the genre colour on hover. */
.category-card {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  padding: var(--space-lg);
  border: 1px solid rgba(45, 90, 39, 0.25);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}

.category-card:hover {
  box-shadow: var(--shadow-elevated);
  transform: translateY(-4px);
  border-color: var(--color-forest-green);
  color: inherit;
}

/* Botanical motif roundel — line-art SVG inherits currentColor so the
   green/purple family tint below recolours the artwork in one place. */
.category-card__motif {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  color: var(--color-forest-green);
  background-color: rgba(45, 90, 39, 0.08);
  transition: background-color 0.2s ease, transform 0.25s ease;
}

.category-card__motif svg {
  width: 42px;
  height: 42px;
}

.category-card:hover .category-card__motif {
  background-color: rgba(45, 90, 39, 0.14);
  transform: rotate(-4deg) scale(1.06);
}

/* Vinting side of the house speaks grape purple (dual brand language). */
.category-card[data-genre="wines"] {
  border-color: rgba(75, 45, 110, 0.25);
}

.category-card[data-genre="wines"]:hover {
  border-color: var(--color-grape-purple);
}

.category-card[data-genre="wines"] .category-card__motif {
  color: var(--color-grape-purple);
  background-color: rgba(75, 45, 110, 0.08);
}

.category-card[data-genre="wines"]:hover .category-card__motif {
  background-color: rgba(75, 45, 110, 0.14);
}

.category-card[data-genre="wines"] .category-card__title {
  color: var(--color-grape-purple);
}

.category-card__body {
  min-width: 0;
}

.category-card__title {
  display: block;
  font-family: var(--font-heading);
  font-size: var(--font-size-h2);
  font-weight: 600;
  color: var(--color-forest-green);
  margin-block-end: var(--space-xs);
}

.category-card__title::after {
  /* no-break space keeps the arrow glued to the last word when wrapping */
  content: '\00a0\2192';
}

@media (max-width: 360px) {
  /* "Equipment →" at full h2 outgrows the card on sub-330px phones. */
  .category-card__title {
    font-size: 1.4rem;
  }
}

.category-card__desc {
  font-size: var(--font-size-caption);
  color: var(--color-stone-grey);
  margin: 0;
}


/* ================================================================
   17e. SECTION VARIANTS
   ================================================================ */

.section {
  padding-block: var(--space-3xl);
}

/* First section after the homepage callout strip — the strip already
   provides breathing room, so the full 3xl top padding just opens a
   hole between the strip and the "Your Expert Partner" heading. */
.section--after-strip {
  padding-block-start: var(--space-sm);
}

.section--cream {
  background-color: var(--color-parchment);
  border-top: 1px solid rgba(45, 90, 39, 0.15);
  border-bottom: 1px solid rgba(45, 90, 39, 0.15);
}

.section--green {
  background-color: var(--color-forest-green);
  color: var(--color-white);
}

.section--green h2,
.section--green h3 {
  color: var(--color-white);
}

/* Centred intro paragraph under a section heading — measure-limited. */
.section-lede {
  max-width: 70ch;
  margin-inline: auto;
}

/* Botanical ornament — a quiet hop-sprig flourish under centred section
   headings. Inherits currentColor; keep it to one or two per page. */
.ornament {
  display: flex;
  justify-content: center;
  color: rgba(45, 90, 39, 0.55);
  margin-block: var(--space-xs) var(--space-md);
}

.ornament svg {
  width: 140px;
  height: 16px;
}

/* Centred pill grid of category links (404, discovery moments). */
.pill-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
  list-style: none;
  padding: 0;
  max-width: 44rem;
  margin-inline: auto;
}

.pill-list a {
  display: inline-block;
  padding: var(--space-xs) var(--space-md);
  border: 1px solid rgba(45, 90, 39, 0.35);
  border-radius: 999px;
  background-color: var(--color-white);
  color: var(--color-forest-green);
  text-decoration: none;
  font-family: var(--font-heading);
  font-size: var(--font-size-caption);
  transition: background-color 0.2s ease, color 0.2s ease;
}

.pill-list a:hover {
  background-color: var(--color-forest-green);
  color: var(--color-white);
}

.not-found__lede {
  max-width: 55ch;
  margin-inline: auto;
}

/* Two-up "Why choose us" layout: prose beside the promise card. The
   min() keeps the 300px floor from overflowing sub-330px viewports. */
.intro-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: var(--space-xl);
  align-items: start;
}

.highlight-card {
  background: rgba(255, 255, 255, 0.1);
  padding: var(--space-lg);
  border-radius: var(--border-radius);
}

.check-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.check-list li {
  position: relative;
  padding-inline-start: var(--space-lg);
  margin-block-end: var(--space-md);
}

.check-list li::before {
  content: '\2713';
  position: absolute;
  inset-inline-start: 0;
}


/* ================================================================
   17f. QUOTE BLOCK
   ================================================================ */

.quote-block {
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-card);
  padding: var(--space-xl) var(--space-2xl);
  font-style: italic;
  font-size: var(--font-size-h2);
  max-width: 60ch;
  margin-inline: auto;
}

.quote-block footer {
  font-style: normal;
  font-size: var(--font-size-base);
  color: var(--color-stone-grey);
  margin-block-start: var(--space-sm);
}

/* Override cursive on quote blocks — use body font for readability */
.quote-block.accent-text {
  font-family: var(--font-body);
}

.quote-block.accent-text footer {
  font-family: var(--font-accent);
  font-style: normal;
}

/* Footer-specific quote block — dark background variant */
.site-footer .quote-block {
  background-color: rgba(255, 255, 255, 0.05);
  border-inline-start-color: rgba(255, 255, 255, 0.25);
  box-shadow: none;
  color: var(--color-off-white);
  padding: var(--space-lg);
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--font-size-base);
}

.site-footer .quote-block footer {
  color: var(--color-stone-grey);
  font-family: var(--font-accent);
  font-style: normal;
}


/* ================================================================
   17g. HEADER & FOOTER ENHANCEMENTS
   ================================================================ */

.site-header__banner {
  display: none;
}

.site-footer__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-sm);
}

.site-footer__brand-logo {
  width: 48px;
  height: auto;
}

/* Dark-green carved wordmark brightened to read on the charcoal footer,
   matching the sidebar wordmark treatment. */
.site-footer__brand-wordmark {
  width: 100%;
  max-width: 200px;
  height: auto;
  filter: brightness(2.3) contrast(1.02);
}

.site-footer__brand-strapline {
  font-family: var(--font-accent);
  font-size: var(--font-size-h2);
  color: var(--color-off-white);
}

.genre-landing__page-desc {
  max-width: 70ch;
  color: var(--color-stone-grey);
  margin-block-end: var(--space-lg);
}


/* ================================================================
   18. REDUCED MOTION
   ================================================================ */

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


/* Mobile: hide topbar utils — info available in sidebar footer */
@media (max-width: 767px) {
  .site-topbar {
    gap: var(--space-sm);
    padding-inline: var(--space-md);
  }

  .site-topbar__leading,
  .site-topbar__home-link {
    min-width: 48px;
    width: 48px;
    height: 48px;
  }

  /* Mobile: collapse the inline search box. Searching is reached via the
     spyglass in the actions cluster, which opens the full-screen overlay. */
  .site-topbar__search {
    display: none;
  }

  /* Genre intro: stack kit cards vertically */
  .gi-kit {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  .gi-kit__image {
    width: 80px;
  }

  /* Genre intro: stack reference sections */
  .gi-reference {
    flex-direction: column;
  }

  .gi-reference__links {
    min-width: auto;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-sm);
    padding-block-start: 0;
  }

  /* Genre intro: stack grain sections */
  .gi-grain {
    flex-direction: column;
  }

  .gi-grain__aside {
    flex-direction: row;
    width: auto;
    justify-content: center;
  }

  .gi-grain__image {
    max-height: 120px;
  }

  /* Product detail: constrain image height on mobile */
  .product-detail__gallery {
    min-height: auto;
    padding: var(--space-sm);
  }

  .product-detail__gallery img {
    max-height: 250px;
    min-height: 120px;
    min-width: auto;
  }

  /* Hide the thumb strip on mobile — the zoom badge opens the lightbox,
     which carries its own prev/next controls for the extra images. */
  .product-detail__gallery-thumbs {
    display: none;
  }

  /* Breadcrumb: truncate long current item on mobile */
  .breadcrumb__current {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 180px;
    display: inline-block;
    vertical-align: bottom;
  }

  /* Product detail: more spacing around CTA and description */
  .product-detail__actions {
    margin-block: var(--space-md);
  }

  .product-detail__purchase {
    max-width: none;
  }

  .product-detail__description {
    margin-block-start: var(--space-lg);
  }
}


/* ================================================================
   19. RESPONSIVE — TABLET (768px+)
   ================================================================ */

@media (min-width: 768px) {
  /* Typography scales up */
  :root {
    --font-size-h1: 2.25rem;
    --font-size-display: 3rem;
    --container-padding: var(--space-lg);
    /* Slim bar: the topbar matches the 47px sidebar wordmark cell
       (46px link + 1px border), so the two bottoms meet exactly. */
    --topbar-height: 47px;
  }

  /* Genre intro tile grid: 3 columns on tablet+ */
  .gi-tile-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .gi-tile-grid--3col {
    grid-template-columns: repeat(3, 1fr);
  }

  .gi-tile-grid--duo {
    grid-template-columns: repeat(2, 1fr);
  }

  /* 2-column layout: sidebar + main */
  .site-layout {
    grid-template-columns: var(--sidebar-width) 1fr;
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
      "sidebar topbar"
      "sidebar main-area"
      "sidebar footer";
  }

  /* Sidebar: sticky, always visible */
  .site-sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    grid-area: sidebar;
    transform: none;
    visibility: visible;
    z-index: auto;
  }

  /* Move brand lockup from sidebar to topbar on desktop */
  .sidebar-brand {
    display: none;
  }

  .site-topbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--aside-width);
    align-items: center;
    height: var(--topbar-height);
    padding-block: 0;
    padding-inline: 0;
    /* One paint source for the green baseline: the bar's own border
       goes transparent (keeping the geometry) and the ::before below
       draws the whole line, stonewords cell included. Two elements
       each drawing a 3px border land on different device pixels at
       125%/140% display scaling — the sticky bar composites on its own
       layer — and the seam shows a step. */
    border-bottom-color: transparent;
  }

  .site-topbar::before {
    content: '';
    position: absolute;
    left: calc(-1 * var(--sidebar-width));
    right: 0;
    bottom: calc(-1 * var(--topbar-baseline));
    height: var(--topbar-baseline);
    background-color: var(--color-forest-green);
    pointer-events: none;
  }

  /* Stonewords cell mirrors the bar: 44px link + 3px baseline slot =
     47px, bottoms level. The slot stays transparent — the bar's
     ::before paints the visible line across it. */
  .sidebar-nav__wordmark-link {
    min-height: calc(var(--topbar-height) - var(--topbar-baseline));
  }

  .sidebar-nav__item--wordmark {
    border-bottom: var(--topbar-baseline) solid transparent;
  }

  .site-topbar__leading {
    display: none;
  }

  .site-topbar__logo {
    width: 28px;
  }

  /* Slim-bar scaling: search field, icon buttons and helmet all sized
     to sit comfortably inside the 47px band. Scoped to the topbar so
     the mobile search overlay keeps its full-size field. */
  .site-topbar .search-box {
    min-height: 33px;
  }

  .site-topbar .search-box__input {
    padding: 0.3rem 0.6rem;
    font-size: 0.95rem;
  }

  .site-topbar .search-box__submit {
    padding: 0.15rem 0.65rem;
    font-size: 0.9rem;
  }

  .site-topbar .search-box__icon {
    width: 0.85rem;
    height: 0.85rem;
  }

  .site-topbar__icon-btn {
    width: 38px;
    height: 38px;
  }

  .site-topbar__icon-btn svg {
    width: 21px;
    height: 21px;
  }

  .site-topbar__home-link {
    width: 38px;
    height: 38px;
  }

  .site-topbar__cart-badge {
    top: 1px;
    right: 1px;
  }

  .site-topbar__search {
    display: flex;
    grid-column: 1;
    justify-self: center;
    /* Keep a touch of breathing room on both sides — without the explicit
       margin the grid track butts up against the sidebar on the left and
       the home-link on the right, making the box look "crashed in". */
    width: min(680px, calc(100% - (2 * var(--container-padding))));
    margin-inline: var(--container-padding);
  }

  .site-topbar__actions {
    grid-column: 2;
    justify-self: end;
    margin-inline-end: var(--container-padding);
  }

  /* On desktop the inline search box covers search, so the spyglass is
     redundant — but the basket (cart) icon stays so the live item count is
     always one click from anywhere. */
  .site-topbar__search-toggle {
    display: none;
  }

  .site-sidebar-overlay {
    display: none !important;
  }

  /* Hide hamburger on tablet+ */
  .sidebar-toggle {
    display: none;
  }

  /* Product list: larger thumbnails */
  .product-list-item__image {
    width: 80px;
    height: 80px;
  }

  /* Genre menu grids: 2 columns */
  .make-menu-grid,
  .ilk-menu-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Product detail desktop layout lives in the ≥1200px block below —
     between 768px and 1199px the centre column is too narrow for two
     columns, so the mobile-first stack carries through. */

  /* Footer: 2-column grid */
  .site-footer__inner {
    grid-template-columns: repeat(2, 1fr);
  }

  .site-footer__inner > div + div {
    padding-block-start: 0;
    border-block-start: none;
  }

  /* Section: more vertical space */
  .section {
    padding-block: 5rem;
  }

  /* Callout strip: row layout. Wrap whole items rather than letting
     text break mid-item when the row runs out of room (tablet). */
  .callout-strip {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-md) var(--space-xl);
  }

  /* Category grid: 2 columns. minmax(0,…) lets tracks shrink below the
     cards' min-content so the grid can't push past the viewport. */
  .category-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-lg);
  }

  /* Fluid title from tablet up: full h2 needs a ~260px card, which the
     2-up tracks only reach on wide screens. */
  .category-card__title {
    font-size: clamp(1.25rem, 0.3rem + 1.7vw, var(--font-size-h2));
  }

  /* Header banner visible */
  .site-header__banner {
    display: block;
    max-width: 400px;
    margin-inline: auto;
    margin-block-start: var(--space-sm);
  }
}


/* ================================================================
   19b. PRODUCT DETAIL — WIDE CENTRE (1200px+)
   ================================================================ */

/* Gallery + prose left, sticky purchase/specs rail right. Enabled only
   where the centre column is wide enough (~700px at a 1200px viewport). */
@media (min-width: 1200px) {
  .product-detail__cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(260px, 320px);
    column-gap: var(--space-xl);
    row-gap: var(--space-xl);
    align-items: start;
  }

  .product-detail__cols > .product-detail__gallery {
    grid-column: 1;
  }

  .product-detail__side {
    grid-column: 2;
    grid-row: 1 / span 2;
    position: sticky;
    top: calc(var(--topbar-height) + var(--space-md));
  }

  .product-detail__body {
    grid-column: 1;
  }
}


/* ================================================================
   20. RESPONSIVE — DESKTOP (1024px+)
   ================================================================ */

@media (min-width: 1024px) {
  :root {
    --container-padding: var(--space-xl);
  }

  /* Genre intro tile grid: 4 columns on desktop for single-tin style;
     bench and duo grids keep their own column counts so the
     photography stays large */
  .gi-tile-grid:not(.gi-tile-grid--3col):not(.gi-tile-grid--duo):not(.gi-tile-grid--bench) {
    grid-template-columns: repeat(4, 1fr);
  }

  .gi-tile-grid--3col {
    grid-template-columns: repeat(4, 1fr);
  }

  /* 3-column layout: sidebar + main + right aside */
  .site-main-area {
    flex-direction: row;
  }

  .site-content {
    flex: 1;
    min-width: 0;
  }

  .site-aside {
    flex: 0 0 var(--aside-width);
    border-top: none;
    border-left: 1px solid rgba(122, 122, 122, 0.15);
    align-self: stretch;
  }

  /* Genre menu grids: 3 columns */
  .make-menu-grid,
  .ilk-menu-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Footer: brand | contact | links | quote */
  .site-footer__inner {
    grid-template-columns: minmax(150px, 0.7fr) 1fr 0.8fr 1.4fr;
  }

}

/* Category grid stays 2-up on desktop: with the 240px sidebar and 260px
   aside in play, a third track squeezes the motif + title cards into
   clipping ("Equipment →" needs ~260px). Two wide cards read better. */

/* In the two squeeze windows — narrow tablet, and just past 1024 where
   the right aside lands — the 2-up tracks drop to ~190-210px, too tight
   for motif + title side by side. Stack the card into a centred tile. */
@media (min-width: 768px) and (max-width: 899.98px),
  (min-width: 1024px) and (max-width: 1279.98px) {
  .category-card {
    flex-direction: column;
    text-align: center;
    gap: var(--space-sm);
  }
}


/* ================================================================
   21. PRINT
   ================================================================ */

@media print {
  @page {
    margin: 15mm;
  }

  /* ── Hide screen-only chrome ── */
  .site-topbar,
  .site-sidebar,
  .site-sidebar-overlay,
  .sidebar-toggle,
  .site-aside,
  .site-footer,
  .howto-links,
  .tabs__list,
  .skip-link,
  .breadcrumb {
    display: none !important;
  }

  /* ── Print header — logo + site name ── */
  body::before {
    content: "Stonehelm — Home Brewing Supplies";
    display: block;
    font-family: var(--font-heading);
    font-size: 14pt;
    font-weight: 700;
    color: #2D5A27;
    border-bottom: 2pt solid #2D5A27;
    padding-bottom: 6pt;
    margin-bottom: 18pt;
  }

  /* ── Reset layout to single column ── */
  .site-layout,
  .site-main-area {
    display: block;
  }

  .site-content {
    padding: 0;
  }

  /* ── Typography for print ── */
  body {
    font-size: 11pt;
    line-height: 1.5;
    color: var(--color-charcoal);
    background: #fff;
  }

  .article-content h1 {
    font-size: 18pt;
    border-bottom-color: #2D5A27;
  }

  .article-content h2 {
    font-size: 14pt;
    margin-top: 16pt;
  }

  .article-content h3 {
    font-size: 12pt;
    margin-top: 12pt;
  }

  /* ── Images — constrain and remove decorative styling ── */
  .article-content img.lesson {
    float: none;
    display: block;
    margin: 8pt auto;
    max-width: 150px;
    box-shadow: none;
    border: 1px solid #ccc;
    break-inside: avoid;
  }

  .airlock-types__gallery {
    gap: 12pt;
  }

  /* ── Page break hints ── */
  h2, h3 {
    break-after: avoid;
  }

  figure, img {
    break-inside: avoid;
  }

  /* ── Links — show URL for external links ── */
  .article-content a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #666;
  }

  .article-content a {
    color: var(--color-charcoal);
    text-decoration: underline;
  }
}

/* ============================================================
   Account area — shared shell (sub-nav) + dashboard hub
   ============================================================ */

/* ── Account sub-navigation ── */
.account-nav {
  margin-block-end: var(--space-lg);
  border-block-end: 1px solid rgba(122, 122, 122, 0.25);
}

.account-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-md);
}

.account-nav__link {
  display: inline-block;
  padding: var(--space-xs) var(--space-sm);
  font-family: var(--font-heading);
  font-size: 0.95rem;
  color: var(--color-stone-grey);
  text-decoration: none;
  border-block-end: 3px solid transparent;
}

.account-nav__link:hover {
  color: var(--color-forest-green);
}

.account-nav__link[aria-current="page"] {
  color: var(--color-forest-green);
  border-block-end-color: var(--color-crimson);
}

/* ── Dashboard hub ── */
.account-hub {
  max-width: 860px;
}

.account-hub__loading,
.account-hub__error {
  padding: var(--space-lg);
  text-align: center;
  color: var(--color-stone-grey);
}

.account-hub__error {
  background-color: #fdecec;
  border: 1px solid var(--color-crimson);
  border-radius: var(--border-radius);
  color: var(--color-crimson-dark);
}

.account-hub__greeting {
  margin-block-end: var(--space-lg);
}

.account-hub__hello {
  margin: 0;
}

.account-hub__panel {
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-card);
  padding: var(--space-lg);
  margin-block-end: var(--space-lg);
}

.account-hub__panel-title {
  margin: 0 0 var(--space-sm);
  font-size: 1.1rem;
  color: var(--color-forest-green);
}

.account-hub__recent-meta {
  display: flex;
  justify-content: space-between;
  gap: var(--space-md);
  color: var(--color-stone-grey);
  font-size: 0.9rem;
}

.account-hub__recent-preview {
  margin: var(--space-sm) 0;
}

.account-hub__recent-total,
.account-hub__card {
  font-family: var(--font-heading);
  color: var(--color-forest-green);
}

.account-hub__recent .account-hub__recent-total {
  margin: 0 0 var(--space-md);
}

/* ── Gift tokens & credit panel (discounts spec §5) ── */
.account-hub__tokens-hint {
  margin: 0 0 var(--space-sm);
  color: var(--color-stone-grey);
  font-size: 0.9rem;
}

.account-tokens {
  list-style: none;
  margin: 0;
  padding: 0;
}

.account-token {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  border-top: 1px solid rgba(122, 122, 122, 0.15);
}

.account-token:first-child {
  border-top: none;
}

.account-token__ref {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.account-token__value {
  font-family: var(--font-heading);
  font-weight: 700;
  color: var(--color-forest-green);
}

.account-token__meta {
  color: var(--color-stone-grey);
  font-size: 0.85rem;
}

.account-token__action {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.account-token__held {
  margin-left: auto;
  color: var(--color-stone-grey);
  font-size: 0.9rem;
}

.account-tokens__message {
  margin: var(--space-sm) 0 0;
  font-size: 0.9rem;
}

/* ── Quick links grid ── */
.account-hub__links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-md);
}

.account-hub__link-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-md);
  background-color: var(--color-warm-cream);
  border-radius: var(--border-radius);
  text-decoration: none;
  border: 1px solid transparent;
}

.account-hub__link-card:hover {
  border-color: var(--color-forest-green);
}

.account-hub__link-title {
  font-family: var(--font-heading);
  color: var(--color-forest-green);
}

.account-hub__link-hint {
  font-size: 0.9rem;
  color: var(--color-stone-grey);
}

/* ── Order status badge (account/orders) ── */
.order-card__status {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background-color: var(--color-warm-cream);
  color: var(--color-stone-grey);
}

.order-card__status--pending {
  background-color: #fff4e0;
  color: #8a5a00;
}

.order-card__status--packing {
  background-color: #eef4ff;
  color: #2d4a8a;
}

.order-card__status--dispatched,
.order-card__status--delivered {
  background-color: #e7f3e8;
  color: var(--color-forest-green);
}

.order-card__status--cancelled {
  background-color: #fdecec;
  color: var(--color-crimson-dark);
}

.order-card__track {
  text-decoration: none;
}

/* ============================================================
   Account settings — details, address book, preferences
   ============================================================ */
.account-settings {
  max-width: 720px;
}

.account-settings__loading,
.account-settings__error {
  padding: var(--space-lg);
  text-align: center;
  color: var(--color-stone-grey);
}

.account-settings__panel {
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-card);
  padding: var(--space-lg);
  margin-block-end: var(--space-lg);
}

.account-settings__panel-title {
  margin: 0 0 var(--space-md);
  font-size: 1.2rem;
  color: var(--color-forest-green);
}

.account-settings__status {
  margin: var(--space-sm) 0 0;
  font-size: 0.9rem;
  color: var(--color-forest-green);
}

.account-settings__status--error {
  color: var(--color-crimson-dark);
}

.account-settings__check {
  display: flex;
  gap: var(--space-sm);
  align-items: flex-start;
  margin-block-end: var(--space-md);
  cursor: pointer;
}

/* Same box as the login page's "remember me"; nudged down so it sits on the
   first line of the (possibly wrapped) label rather than above it. */
.account-settings__check input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
  margin: 0;
  margin-block-start: calc((1em * var(--line-height-body) - 1.1rem) / 2);
  flex: 0 0 auto;
  accent-color: var(--color-forest-green);
}

.account-settings__addresses {
  list-style: none;
  margin: 0 0 var(--space-md);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.address-card {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-md);
  background-color: var(--color-warm-cream);
  border-radius: var(--border-radius);
}

.address-card__label {
  font-family: var(--font-heading);
  color: var(--color-forest-green);
}

.address-card__badges {
  display: block;
  font-size: 0.8rem;
  color: var(--color-stone-grey);
}

.address-card__lines {
  margin: var(--space-xs) 0 0;
}

.address-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: flex-start;
}

.account-settings__address-form {
  margin-block-start: var(--space-md);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid rgba(122, 122, 122, 0.2);
}

.account-settings__form-actions {
  display: flex;
  gap: var(--space-sm);
}

/* ── Account devices (signed-in devices) ── */
.account-devices {
  max-width: 720px;
}

.account-devices__loading,
.account-devices__error {
  padding: var(--space-lg);
  text-align: center;
  color: var(--color-stone-grey);
}

.account-devices__intro {
  color: var(--color-stone-grey);
}

.account-devices__list {
  list-style: none;
  margin: 0 0 var(--space-md);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.device-card {
  padding: var(--space-md);
  background-color: var(--color-white);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-card);
}

.device-card__name {
  font-family: var(--font-heading);
  color: var(--color-forest-green);
}

.device-card__current {
  display: inline-block;
  margin-inline-start: var(--space-sm);
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background-color: #e7f3e8;
  color: var(--color-forest-green);
}

.device-card__meta {
  margin: var(--space-xs) 0 0;
  font-size: 0.85rem;
  color: var(--color-stone-grey);
}

.account-devices__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

/* ── Account settings: delete-account danger zone ── */
.account-settings__danger {
  border: 1px solid rgba(204, 34, 34, 0.35);
}

.account-settings__danger .account-settings__panel-title {
  color: var(--color-crimson-dark);
}

.account-settings__delete-pending {
  font-weight: 600;
  color: var(--color-crimson-dark);
}

/* ============================================================
   Order tiles — fulfilment line + status progress stepper
   (shared by /account/orders/ and the /account/ hub recent order)
   ============================================================ */
.order-card__fulfilment,
.account-hub__recent-fulfilment {
  margin: 0 0 var(--space-sm);
  font-size: 0.9rem;
  color: var(--color-forest-green);
  font-weight: 600;
}

/* Horizontal breadcrumb-style progress: dot + connector per step. */
.order-progress {
  display: flex;
  list-style: none;
  margin: var(--space-sm) 0 var(--space-md);
  padding: 0;
}

.order-progress[hidden] {
  display: none;
}

.order-progress__step {
  flex: 1 1 0;
  position: relative;
  text-align: center;
  padding-block-start: 20px;
  font-size: 0.72rem;
  line-height: 1.25;
  color: var(--color-stone-grey);
}

/* The status dot. */
.order-progress__step::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--color-white);
  border: 2px solid var(--color-stone-grey);
  z-index: 1;
}

/* The connector line entering this step from the previous one. */
.order-progress__step::after {
  content: "";
  position: absolute;
  inset-block-start: 5px;
  inset-inline-end: 50%;
  width: 100%;
  height: 2px;
  background: var(--color-stone-grey);
  z-index: 0;
}

.order-progress__step:first-child::after {
  display: none;
}

/* Reached steps (complete or current) get a green dot + green connector. */
.order-progress__step.is-complete::before,
.order-progress__step.is-current::before {
  background: var(--color-forest-green);
  border-color: var(--color-forest-green);
}

.order-progress__step.is-complete::after,
.order-progress__step.is-current::after {
  background: var(--color-forest-green);
}

/* The current step stands out (crimson ring + emphasised label). */
.order-progress__step.is-current::before {
  background: var(--color-crimson);
  border-color: var(--color-crimson);
}

.order-progress__step.is-current {
  color: var(--color-forest-green);
  font-weight: 700;
}

/* ── Brewing process track ───────────────────────────────────
   Persistent "you-are-here" map shown on principles-of-brewing
   articles. Spine = the wort's journey (horizontal desktop,
   vertical on mobile); fork = packaging; feeders = ingredients.
   See docs/brewing-principles-track.md. */

/* brew-track articles stack as a flex column so the band can be reordered
   to the top when the column is wide while staying at the bottom otherwise
   (one instance). Both that reorder and the map's own horizontal↔vertical
   switch are CONTAINER queries, not media queries — the layout follows the
   space the track actually has, so window resizing (or any column-width
   change) can never strand the wrong layout. */
.article-page {
  display: flex;
  flex-direction: column;
  container: article-page / inline-size;
}

.brew-track {
  margin: var(--space-md) 0 var(--space-lg);
  padding: var(--space-md) var(--space-md) var(--space-sm);
  background-color: var(--color-warm-cream);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
  border-radius: var(--border-radius);
  container: brew-track / inline-size;
}

.brew-track__heading {
  margin: 0 0 var(--space-sm);
  font-family: 'Roboto Slab', Georgia, serif;
  font-size: 0.9rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-forest-green);
}

/* ── Base layout: ONE vertical metro line ─────────────────
   The default (narrow columns, no JS, and any browser without container
   queries): the three lists dissolve (display:contents) and stops,
   ingredient feeders and alternative entries interleave into one column
   in journey order via the inline --bt-order the partial stamps on each
   <li>. A continuous rail runs through the medallion centres; branch
   nodes hang off it on indented elbows. The horizontal map is applied
   on top by the @container block further down when the track is wide
   enough. */
.brew-track__map {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* The main line: a vertical rail through the spine medallion centres,
   from the first stop down to the last packaging endpoint. */
.brew-track__map::before {
  content: "";
  position: absolute;
  left: 25px;
  top: 26px;
  bottom: 26px;
  width: 2px;
  background-color: var(--color-stone-grey);
}

/* SVG wire overlay (drawn by assets/js/brew-track.js on wide tracks). */
.brew-track__wires {
  display: none;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
  z-index: 0;
}

.bt-wire { fill: none; stroke-linecap: round; }
.bt-wire--spine,
.bt-wire--fork { stroke: var(--color-stone-grey); stroke-width: 2; }
.bt-wire--feeder { stroke: var(--color-forest-green); stroke-width: 2; opacity: 0.8; }

/* Entry wires (alternative starting points): dashed = an optional route
   onto the line, with a small "or" sitting in a gap at the midpoint. */
.bt-wire--entry {
  stroke: var(--color-forest-green);
  stroke-width: 2;
  stroke-dasharray: 4 5;
  opacity: 0.8;
}

.bt-wire__or {
  fill: var(--color-forest-green);
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-style: italic;
  text-anchor: middle;
  dominant-baseline: central;
}

/* The three lists dissolve so their items interleave in the map column. */
.brew-track__spine,
.brew-track__feeders,
.brew-track__entries {
  list-style: none;
  margin: 0;
  padding: 0;
  display: contents;
}

.brew-track__stop,
.brew-track__feeder,
.brew-track__entry {
  order: var(--bt-order, 0);
}

.brew-track__stop {
  position: relative;
  flex: none;
  width: 100%;
  display: flex;
  justify-content: flex-start;
}

/* Fork: the spine splits into stacked packaging branches. */
.brew-track__stop--fork { flex: none; }

.brew-track__branches {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* A node: medallion + label, in three states (link / current / todo).
   Base = vertical line, so nodes are rows: medallion beside its label. */
.bt-node {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-sm);
  width: auto;
  text-decoration: none;
  color: var(--color-charcoal);
}

.bt-node__medallion {
  width: 52px;
  height: 52px;
  flex: none;
  border-radius: 50%;
  background-color: var(--color-off-white);
  border: 2px solid var(--color-stone-grey);
  display: grid;
  place-items: center;
  overflow: hidden;
  transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.bt-node__img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.bt-node__label {
  font-size: 0.9rem;
  line-height: 1.1;
  text-align: left;
  overflow-wrap: break-word;
  hyphens: auto;
  color: var(--color-stone-grey);
}

/* Live link — full colour, lifts on hover/focus. */
.bt-node[href]:hover .bt-node__medallion,
.bt-node[href]:focus-visible .bt-node__medallion {
  border-color: var(--color-forest-green);
  transform: translateY(-2px);
}

.bt-node[href]:hover .bt-node__label,
.bt-node[href]:focus-visible .bt-node__label {
  color: var(--color-forest-green);
}

/* Current = "you are here". */
.bt-node--current .bt-node__medallion {
  border-color: var(--color-crimson);
  border-width: 3px;
  box-shadow: 0 0 0 3px rgba(204, 34, 34, 0.18);
}

.bt-node--current .bt-node__label {
  color: var(--color-crimson);
  font-weight: 700;
}

/* Not yet written — dashed border + faded image, non-clickable. The disc stays
   opaque (no opacity on the medallion) so connector wires never show through it. */
.bt-node--todo .bt-node__medallion {
  border-style: dashed;
  border-color: var(--color-stone-grey);
}

.bt-node--todo .bt-node__img {
  filter: grayscale(1);
  opacity: 0.45;
}

.bt-node--todo .bt-node__label {
  opacity: 0.65;
  font-style: italic;
}

/* Branch stops (base vertical line): smaller medallions, indented off the
   rail on an elbow — solid green for ingredient feeders, dashed with an
   "or" for the alternative starting points, matching the wide map's wires. */
.brew-track__feeder,
.brew-track__entry {
  position: relative;
  margin-left: 60px;
}

.brew-track__feeder .bt-node__medallion,
.brew-track__entry .bt-node__medallion {
  width: 44px;
  height: 44px;
}

.brew-track__feeder::before,
.brew-track__entry::before {
  content: "";
  position: absolute;
  top: 21px;            /* branch medallion centre */
  left: -34px;          /* back to the rail at map x≈26 */
  width: 34px;
  height: 2px;
  background-color: var(--color-forest-green);
  opacity: 0.8;
}

.brew-track__entry::before {
  background: none;
  height: 0;
  border-top: 2px dashed var(--color-forest-green);
}

.brew-track__entry::after {
  content: "or";
  position: absolute;
  top: 22px;
  left: -17px;          /* elbow midpoint */
  transform: translate(-50%, -50%);
  padding: 0 3px;
  background-color: var(--color-warm-cream);
  color: var(--color-forest-green);
  font-size: 0.72rem;
  font-style: italic;
  line-height: 1;
}

/* Float the band to the top (above the article, below breadcrumb) only when
   the column is wide enough for the horizontal map — same signal as the
   map's own switch: 560px of track content + 2 × --space-md track padding.
   Classic min-width syntax (not range syntax) so every container-query
   browser parses it, including early Safari 16.
   On how-to pages the tab bar stays first (order 0, first in DOM), and the
   sibling-links nav follows the reordered article. */
@container article-page (min-width: 592px) {
  .article-page .article-content { order: 1; }
  .article-page--howto .howto-links { order: 2; }
}

/* ── Wide layout: the horizontal metro map ────────────────
   Applied when the TRACK ITSELF is at least 560px wide — a container
   query, so a narrow column in a wide window still gets the vertical
   line, and resizing anything simply flips the layout at the right
   moment. 560px leaves headroom for real phones: an iPhone's landscape
   safe-area insets and iOS page zoom both eat into the column, and the
   map still fits (10 spine medallions at 7cqw + fork ≈ 530px). Classic
   min-width syntax (not range syntax) so every container-query browser
   parses it, including early Safari 16. Medallions are sized in cqw
   (track-relative), so the eleven spine stops can never outgrow the row
   the way viewport units could. The 560px threshold must match
   WIDE_MIN_WIDTH in assets/js/brew-track.js, which draws the SVG wires
   only in this state. */
@container brew-track (min-width: 560px) {
  .brew-track__map {
    display: block;
    --bt-med: clamp(36px, 7cqw, 60px);
  }

  .brew-track__map::before { content: none; }

  .brew-track__wires { display: block; }

  .brew-track__spine {
    display: flex;
    align-items: flex-start;
    gap: var(--space-xs);
    padding-bottom: var(--space-xs);
  }

  .brew-track__feeders,
  .brew-track__entries {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    align-items: flex-start;
  }

  .brew-track__stop {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    justify-content: center;
  }

  .brew-track__stop--fork { flex: 0 0 auto; }

  /* Fallback connector between adjacent stops (no-JS; hidden once JS
     draws the SVG wires). Sits behind the medallions. */
  .brew-track__stop + .brew-track__stop::before {
    content: "";
    position: absolute;
    top: calc(var(--bt-med) / 2);
    left: -50%;
    width: 100%;
    height: 2px;
    background-color: var(--color-stone-grey);
    z-index: 0;
  }

  .brew-track.is-enhanced .brew-track__stop + .brew-track__stop::before {
    display: none;
  }

  .bt-node {
    flex-direction: column;
    gap: 4px;
    width: 100%;
  }

  .bt-node__medallion {
    width: var(--bt-med);
    height: var(--bt-med);
  }

  .bt-node__label {
    width: 100%;
    font-size: 0.62rem;
    text-align: center;
  }

  /* Feeders/entries rejoin the flow (rows above/below the spine); the
     connector script then floats each 45° off its join stop and wires it in. */
  .brew-track__feeder,
  .brew-track__entry {
    position: static;
    margin-left: 0;
  }

  .brew-track__feeder .bt-node__medallion,
  .brew-track__entry .bt-node__medallion {
    width: var(--bt-med);
    height: var(--bt-med);
  }

  .brew-track__feeder::before,
  .brew-track__entry::before,
  .brew-track__entry::after {
    content: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bt-node__medallion { transition: none; }
  .bt-node[href]:hover .bt-node__medallion,
  .bt-node[href]:focus-visible .bt-node__medallion { transform: none; }
}

/* Print: the JS-drawn wires and feeder positions are pixel-frozen for the
   screen layout and never redraw for the print reflow, so fall back to the
   static no-JS presentation. !important is required to beat the inline
   styles the connector script leaves on the elements. */
@media print {
  .brew-track { break-inside: avoid; }

  .brew-track__wires { display: none !important; }

  .brew-track__map { min-height: 0 !important; }

  .brew-track__feeder,
  .brew-track__entry {
    position: static !important;
    width: auto !important;
  }

  .brew-track__map { padding-top: 0 !important; }

  /* Restore the CSS fallback connectors that .is-enhanced hides on screen. */
  .brew-track.is-enhanced .brew-track__stop + .brew-track__stop::before {
    display: block;
  }
}

/* ============================================================
   Saved cards — professional credit-card tiles
   ============================================================ */
.account-cards__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.account-cards__list[hidden] {
  display: none;
}

.saved-card-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* The card visual — ISO-7810 aspect ratio, brand-coloured gradient. */
.saved-card {
  position: relative;
  width: 100%;
  max-width: 340px;
  aspect-ratio: 1.586 / 1;
  padding: var(--space-md);
  border-radius: 14px;
  color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  box-shadow: var(--shadow-card);
  font-family: var(--font-heading);
  overflow: hidden;
  /* House (default) tone; brand modifiers override below. */
  background: linear-gradient(135deg, #2d5a27, #1c3b18);
}

/* Subtle sheen across the card. */
.saved-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 80% at 0% 0%, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0) 60%);
  pointer-events: none;
}

.saved-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* EMV chip. */
.saved-card__chip {
  position: relative;
  width: 38px;
  height: 28px;
  border-radius: 6px;
  background: linear-gradient(135deg, #f4e4a3, #c9a227);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}

.saved-card__chip::after {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid rgba(0, 0, 0, 0.22);
  border-radius: 3px;
}

.saved-card__brand {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.saved-card__number {
  font-size: 1.2rem;
  letter-spacing: 0.16em;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

.saved-card__bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}

.saved-card__exp-label {
  display: block;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.75;
}

.saved-card__exp-value {
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}

.saved-card__default {
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-forest-green);
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
}

/* Brand tones. */
.saved-card--visa { background: linear-gradient(135deg, #1a1f71, #2a357f); }
.saved-card--mastercard { background: linear-gradient(135deg, #232526, #414345); }
.saved-card--amex { background: linear-gradient(135deg, #0a6fb5, #0a4f86); }
.saved-card--discover { background: linear-gradient(135deg, #e9730c, #b8560a); }
.saved-card--default { background: linear-gradient(135deg, #2d5a27, #1c3b18); }
.saved-card--token { background: linear-gradient(135deg, #a81c1c, #6e1212); }

/* Gift tokens & credit — token tiles beneath the saved cards. */
.account-cards__tokens {
  margin-block-start: var(--space-xl);
}

.account-cards__tokens-title {
  margin: 0 0 var(--space-sm);
  font-size: 1.1rem;
  color: var(--color-forest-green);
}

/* Keep the "In a basket" badge bottom-right even when there's no expiry. */
.saved-card--token .saved-card__default {
  margin-left: auto;
}

.saved-card__value {
  font-size: 1.4rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.saved-card-item__actions {
  display: flex;
  gap: var(--space-sm);
}

/* Author rules set `.button-{primary,secondary}{display:inline-flex}`, which
   overrides the UA `[hidden]{display:none}` (author beats UA). Restore the hide
   for buttons toggled via the `hidden` attribute (set-default, reorder, etc.). */
.button-primary[hidden],
.button-secondary[hidden] {
  display: none;
}

/* The default card's set-default control as a non-actionable "Default" state:
   muted and visually static — it must NOT react to hover/focus/active the way
   the live `.button-secondary` does (which fills green on hover). */
.saved-card-item__is-default,
.saved-card-item__is-default:hover,
.saved-card-item__is-default:focus,
.saved-card-item__is-default:focus-visible,
.saved-card-item__is-default:active {
  opacity: 0.6;
  cursor: default;
  box-shadow: none;
  transform: none;
  background-color: transparent;
  color: var(--color-stone-grey);
  border-color: rgba(122, 122, 122, 0.4);
}


/* ================================================================
   22. LANDSCAPE PHONES (short viewports, mobile layout)
   ================================================================
   A phone on its side gives ~360-430px of height; the 47px topbar plus
   either a 240px drawer that needs scrolling (small phones) or the
   permanently pinned desktop sidebar (big phones like 844×390 cross the
   768px desktop threshold) waste most of it. In this window the topbar
   becomes a slim icon rail down the left edge, and the menu opens full
   screen with the nav sections flowing into columns. Capped below
   1024px so landscape tablets and short desktop windows keep the
   normal layout; the ≥768px slice restates the mobile layout that the
   desktop blocks above otherwise override. */

@media (max-width: 1023.98px) and (orientation: landscape) and (max-height: 500px) {
  /* Big phones: back out of the desktop grid — single-column layout,
     sidebar returns to being an off-canvas drawer. */
  .site-layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "topbar"
      "main-area"
      "footer";
  }

  .site-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    height: auto;
    transform: translateX(-100%);
    visibility: hidden;
    z-index: 200;
  }

  .site-sidebar.is-open {
    transform: translateX(0);
    visibility: visible;
  }

  /* Desktop hides the click-away overlay with !important; win it back. */
  .site-sidebar-overlay.is-visible {
    display: block !important;
  }

  /* Topbar → fixed left rail: hamburger on top, icon cluster below.
     display/flex + visible hamburger + spyglass restate the mobile bar
     against the ≥768px grid-topbar rules. */
  .site-topbar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    display: flex;
    height: auto;
    width: 52px;
    flex-direction: column;
    justify-content: flex-start;
    gap: var(--space-sm);
    padding: var(--space-sm) 0;
    border-bottom: 0;
    border-right: var(--topbar-baseline) solid var(--color-forest-green);
  }

  /* Desktop paints its green baseline with this pseudo — off in the rail. */
  .site-topbar::before {
    content: none;
  }

  /* Centre the hamburger on the rail axis — the mobile bar gives its
     wrapper a 48px min-width with the button left-aligned inside, which
     reads as misaligned against the centred icon column below. */
  .site-topbar__leading {
    display: flex;
    justify-content: center;
    min-width: 0;
    width: auto;
    height: auto;
  }

  .sidebar-toggle {
    display: flex;
  }

  /* Inline search box has no room in a 52px rail — the spyglass opens
     the overlay instead, as on portrait mobile. */
  .site-topbar__search {
    display: none;
  }

  .site-topbar__search-toggle {
    display: inline-flex;
  }

  .site-topbar__actions {
    flex-direction: column;
    gap: var(--space-sm);
    margin-inline-end: 0;
  }

  /* The rail is out of the flow — push the page past it. */
  .site-layout {
    padding-left: calc(52px + var(--topbar-baseline));
  }

  /* Desktop offsets the tray for the pinned sidebar; recentre it. */
  .basket-tray {
    left: 50%;
  }

  /* Drawer → full screen, nav sections flow into columns so the whole
     menu is visible without scrolling. */
  .site-sidebar {
    width: 100%;
  }

  .sidebar-nav {
    column-width: 220px;
    column-gap: var(--space-lg);
    padding-inline: var(--space-md);
  }

  .sidebar-nav__item {
    break-inside: avoid;
  }

  /* Brand row spans the columns so the list starts level below it. */
  .sidebar-nav__item--wordmark {
    column-span: all;
  }

  /* Slightly tighter rows: on the shortest screens (~320px) the two-
     column menu otherwise runs a little past the fold. */
  .sidebar-nav__item > a:not(.sidebar-nav__brand-link):not(.sidebar-nav__wordmark-link) {
    padding-block: 0.3rem;
  }
}


/* Sub-330px phones (Fold closed): the icon cluster + hamburger only
   clear the viewport with slimmer bar padding; tap targets keep 44px.
   Last in the file so it wins over the ≤767px mobile bar rule. */
@media (max-width: 360px) {
  .site-topbar {
    padding-inline: var(--space-sm);
  }
}


/* Phones: the frosted "lens" card covers most of the hero photo and
   reads poorly at card sizes. Show the photo as a clean band instead,
   with the title/blurb/CTAs on a solid panel below it in standard
   page colours. Tablet+ keeps the glass card. */
@media (max-width: 639.98px) {
  .gi-hero {
    min-height: 0;
    padding: 0;
  }

  /* Fixed-shape photo band now that no text needs to fit on it.
     background: inherit repaints the genre's image inside the band
     itself — otherwise the section-level image anchors its tuned
     focal point (e.g. wines' center-bottom bottles) behind the
     opaque text panel and the band shows the wrong slice. */
  .gi-hero::before {
    content: '';
    display: block;
    aspect-ratio: 2 / 1;
    background: inherit;
  }

  .gi-hero__overlay--glass {
    align-self: stretch;
    max-width: none;
    border-radius: 0;
    background: var(--color-warm-cream);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    color: var(--color-charcoal);
    padding: var(--space-md);
  }

  .gi-hero__title {
    color: var(--color-forest-green);
  }

  /* The white-outline CTA is invisible on the light panel. */
  .gi-hero__overlay--glass .button-secondary--inverse {
    color: var(--color-forest-green);
    border-color: var(--color-forest-green);
  }
}
