/* -- VARIABLES -- */
:root {
  --header-logo-height: 22px;
  /* Derived from the header's own parts (padding-25 top and bottom plus
     the logo) rather than a fixed number, so it stays accurate when the
     spacing scale changes at breakpoints. */
  --header-height: calc((var(--global-spacing-25) * 2) + var(--header-logo-height));

  /* Project fonts. @font-face lives in assets/fonts-local/fonts-local.css
     for now (local only, pending web licences). SchoolBook comes from the
     Adobe Fonts web project enqueued in functions/enqueue_assets.php. */
  --font-family-display: "Benton Mod Disp ExCond", "Times New Roman", serif;
  --font-family-display-cond: "Benton Mod Disp Cond", "Times New Roman", serif;
  --font-family-sans: "Akzidenz Grotesk Pro", "Helvetica Neue", Helvetica,
    Arial, sans-serif;
  --font-family-serif: "schoolbook", Georgia, serif;
  --font-family-base: var(--font-family-sans);

  /* Fluid type scale from the Figma type styles (1440px artboards). The
     max is the Figma size; the vw value hits it at 1440; the min is the
     mobile floor. Checked at 900px: h1 56 > h2 44 > h3 36 > h4 28 >
     h5 22 > h6 20 > body 16 - every step still steps up. H5 has no Figma
     style yet, so it sits between H4 and H6. */
  --font-size-h1: clamp(3.5rem, 6.25vw, 5.625rem); /* 90 */
  --font-size-h2: clamp(2.75rem, 4.444vw, 4rem); /* 64 */
  --font-size-h3: clamp(2.25rem, 3.333vw, 3rem); /* 48 */
  --font-size-h4: clamp(1.75rem, 2.222vw, 2rem); /* 32 */
  --font-size-h5: clamp(1.375rem, 1.944vw, 1.75rem); /* 28 */
  --font-size-h6: clamp(1.25rem, 1.667vw, 1.5rem); /* 24 */
  --font-size-body: clamp(1rem, 1.25vw, 1.125rem); /* 18 */
  --font-size-link: 0.75rem; /* 12 - eyebrows, links, buttons */
  --font-size-nav: 0.875rem; /* 14 - header nav, header button, hero eyebrow */

  /* Older utility names, kept pointing at the scale above. */
  --font-size-xxl: var(--font-size-h1);
  --font-size-xl: var(--font-size-h2);
  --font-size-large: var(--font-size-h3);
  --font-size-medium: var(--font-size-h4);
  --font-size-small: var(--font-size-h6);
  --font-size-xsmall: var(--font-size-link);

  /* Page gutter (40px at 1440) and the gap between cards in a grid. */
  --gutter: clamp(20px, 2.778vw, 40px);
  /* Both small cards - the promotional popup and the buy panel - are this
     wide and square, so they read as the same object in two places. */
  --popup-size: 21rem;
  --grid-gap: 20px;
  /* Vertical drop on every second card in the staggered feeds. */
  --stagger: clamp(0px, 13.889vw, 200px);

  /* Brand colours - the "After" palette in the Figma Colour section.
     Off White, Moss Green and Black are named Figma styles; the other
     names are ours. Keep in sync with functions/text_colour.php (which
     backgrounds are dark) and functions/acf_colour_picker_palette.php. */
  /* Dark - light text sits on these */
  --moss-green: #403c28;
  --rust: #88331f;
  --brown: #3b1b0d;
  --black: #000406;
  --navy: #1c2b44;
  /* Light - dark text sits on these */
  --off-white: #fcfaed;
  --cream: #fbf5e2;
  --sand: #e4dabc;
  --yellow: #ead96f;
  --pale-blue: #d2d7df;
  /* Not in the Figma palette. Added for the success notice, which the
     brand colours have no green for. */
  --green-pale: #e3ecdd;
  --green-deep: #2f4a2a;

  /* Contrast pair: default page ground and text. */
  --dark: var(--black);
  --light: var(--off-white);

  --global-spacing-3: 3px;
  --global-spacing-6: 6px;
  --global-spacing-12: 12px;
  --global-spacing-25: 25px;
  --global-spacing-50: 50px;
  --global-spacing-75: 75px;
  --global-spacing-100: 100px;
  --global-spacing-150: 150px;
  --global-spacing-200: 200px;
}
/* Above 1800px the clamp()s have all hit their ceiling and the type stops
   growing, which on a full-bleed section leaves it looking small against
   the images. These continue the same curve: each value is the current
   cap expressed as a vw, so 1800px renders identically either way. */
@media (min-width: 1800px) {
  :root {
    --font-size-h1: 5vw; /* was capped at 5.625rem */
    --font-size-h2: 3.556vw; /* 4rem */
    --font-size-h3: 2.667vw; /* 3rem */
    --font-size-h4: 1.778vw; /* 2rem */
    --font-size-h5: 1.556vw; /* 1.75rem */
    --font-size-h6: 1.333vw; /* 1.5rem */
    --font-size-body: 1vw; /* 1.125rem */
  }
}
@media (max-width: 992px) {
  :root {
    --global-spacing-25: 12px;
    --global-spacing-100: 75px;
  }
}
@media (max-width: 768px) {
  :root {
    --global-spacing-100: 50px;
  }
}
@media (max-width: 548px) {
  :root {
    --global-spacing-100: 25px;
  }
}
/* -- VARIABLES END -- */

/* -- FONTS -- */
/* reset.css sets div { hyphens: auto }, which breaks words mid-line in
   narrow card text ("tem-por"). The design never hyphenates. */
div {
  hyphens: manual;
}
.no-hyphen {
  hyphens: none;
}

body {
  font-family: var(--font-family-base);
  font-size: var(--font-size-body);
  font-weight: 500;
}

.font-light {
  font-weight: 300 !important;
}
.font-regular {
  font-weight: 400 !important;
}
.font-medium {
  font-weight: 500 !important;
}
.font-semibold {
  font-weight: 600 !important;
}
.font-bold {
  font-weight: 700 !important;
}

/* Type styles - one class per Figma text style. Each sets family, size,
   line height and weight together, so any element can take a style
   regardless of its tag (a component title is an h2 for document order
   but may look like H1 or H3). The heading tags default to their own
   style for headings that arrive without a class, e.g. from a WYSIWYG. */
h1,
.type-h1 {
  font-family: var(--font-family-display);
  font-size: var(--font-size-h1);
  font-weight: 400;
  line-height: 0.8;
  letter-spacing: 1px;
  text-transform: uppercase;
}
h2,
.type-h2 {
  font-family: var(--font-family-display);
  font-size: var(--font-size-h2);
  font-weight: 400;
  line-height: 0.86;
  text-transform: uppercase;
}
h3,
.type-h3 {
  font-family: var(--font-family-display-cond);
  font-size: var(--font-size-h3);
  font-weight: 400;
  line-height: 0.9;
  text-transform: none;
}
h4,
.type-h4 {
  font-family: var(--font-family-display-cond);
  font-size: var(--font-size-h4);
  font-weight: 400;
  line-height: 1;
  text-transform: none;
}
h5,
.type-h5 {
  font-family: var(--font-family-sans);
  font-size: var(--font-size-h5);
  font-weight: 500;
  line-height: 1.2;
  text-transform: none;
}
h6,
.type-h6 {
  font-family: var(--font-family-sans);
  font-size: var(--font-size-h6);
  font-weight: 500;
  line-height: 1.2;
  text-transform: none;
}
p,
.type-body,
.font-size-body {
  font-size: var(--font-size-body);
}
.type-body {
  font-family: var(--font-family-sans);
  font-weight: 500;
  line-height: 1.3;
}
.type-body-serif {
  font-family: var(--font-family-serif);
  font-size: var(--font-size-body);
  font-weight: 400;
  line-height: 1.3;
}
/* Eyebrows, arrow links and button labels. */
.type-link {
  font-family: var(--font-family-sans);
  font-size: var(--font-size-link);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
/* A type style on a wrapper has to reach the <p> tags a WYSIWYG puts
   inside it. line-height needs !important because reset.css sets
   p { line-height: 1.3 !important }. */
.type-h1 p,
.type-h2 p,
.type-h3 p,
.type-h4 p,
.type-h5 p,
.type-h6 p,
.type-body p,
.type-body-serif p {
  font-size: inherit;
  line-height: inherit !important;
}
/* Space between paragraphs from a WYSIWYG (reset.css zeroes p margins
   with !important). */
.wysiwyg p + p {
  margin-top: 1em !important;
}
/* Typefaces an editor can apply to part of the text from the Formats menu
   (functions/editor_formats.php). Family only - size, weight and spacing
   still come from wherever the text sits. Must win over the text style of
   the surrounding block, hence the specificity. */
.wysiwyg .font-serif,
.font-serif {
  font-family: var(--font-family-serif);
  font-weight: 400;
}
.wysiwyg .font-sans,
.font-sans {
  font-family: var(--font-family-sans);
  font-weight: 500;
}
.wysiwyg .font-display,
.font-display {
  font-family: var(--font-family-display);
  font-weight: 400;
}
.wysiwyg .font-display-cond,
.font-display-cond {
  font-family: var(--font-family-display-cond);
  font-weight: 400;
}

/* A heading typed into the editor is a sub-heading: sans, above its
   paragraph, whatever the surrounding text style is. */
.wysiwyg h2,
.wysiwyg h3,
.wysiwyg h4,
.wysiwyg h5,
.wysiwyg h6 {
  font-family: var(--font-family-sans);
  font-size: var(--font-size-h6);
  font-weight: 500;
  line-height: 1.2;
  text-transform: none;
  margin-top: 2em;
  margin-bottom: 0.4em;
}
.wysiwyg > :first-child {
  margin-top: 0;
}

.font-size-xxl {
  font-size: var(--font-size-xxl);
}
.font-size-xl {
  font-size: var(--font-size-xl);
}
.font-size-large {
  font-size: var(--font-size-large);
}
/* A size utility on a wrapper has to reach the <p> tags inside it -
   otherwise the rule above wins and editor content ignores the class.
   line-height needs !important because reset.css sets
   p { line-height: 1.3 !important }, which beats specificity alone. */
.font-size-xxl > p,
.font-size-xl > p,
.font-size-large > p,
.font-size-medium > p,
.font-size-small > p,
.font-size-body > p,
.font-size-xsmall > p {
  font-size: inherit;
  line-height: inherit !important;
}
.font-size-medium {
  font-size: var(--font-size-medium);
}
.font-size-small {
  font-size: var(--font-size-small);
}
.font-size-xsmall {
  font-size: var(--font-size-xsmall);
}

/* -- FONTS END -- */

/* -- SECTION STACK -- */
/* Each section pins to the window and the next slides up over it, like
   cards being dealt onto a pile. Plain position: sticky - no animation -
   so later sections simply paint over earlier ones.
   --stack-top is 0 for a section that fits the window. A taller section
   gets a negative offset from js/script.js (window height minus its own
   height), so it scrolls normally until its last line is on screen and
   only then holds - otherwise the next section would cover content that
   had not been reached yet.
   Enabled by the .section-stack body class at every width
   (functions/section_stack.php) - on a phone nearly every section is
   taller than the window, so the negative --stack-top does most of the
   work. */
/* <main> gives no box of its own here, so the sections and the footer
   share one container - otherwise the last section would stop pinning
   where <main> ends and the footer could not slide over it. */
.section-stack main {
  display: contents;
}
.section-stack main > article,
.section-stack .site-footer {
  position: sticky;
  top: var(--stack-top, 0px);
}
/* Solid, so the section underneath never shows through one that has no
   background colour of its own - it takes the page's. The footer is left
   out: it has its own colour. */
.section-stack main > article {
  background-color: var(--section-bg);
}
/* A section js/script.js has decided should not pin (the colour-change
   and hero-only variations). Relative rather than static: a positioned
   element always paints above unpositioned ones, so a static section
   would scroll up underneath the pinned section instead of over it. */
.section-stack main > article.stack-free,
.section-stack .site-footer.stack-free {
  position: relative;
  top: auto;
}
/* -- SECTION STACK END -- */

/* -- SHUTTER REVEAL -- */
/* An image already in place is revealed by an expanding crop opening from
   the top downwards - no fade, no slide, just the crop. clip-path rather
   than a mask or overflow, so it works inside transformed parents (the
   staggered card grids, Splide).
   The clipped start state is scoped to .has-js (set by the inline script
   in header.php before first paint), so without JS the images just show.
   js/script.js adds .is-in when each image scrolls in. */
@media (prefers-reduced-motion: no-preference) {
  .has-js .shutter-reveal {
    clip-path: inset(0 0 100% 0); /* clipped to nothing at the top */
    /* Slow and even. The earlier curve reached most of its travel in the
       first third, which read as fast however long the duration was, so
       this one eases more gently. */
    transition: clip-path 1.5s cubic-bezier(0.33, 0.1, 0.25, 1);
    /* Images in the same grid follow one another (--reveal-i, set in
       script.js from the image's position in its grid). */
    transition-delay: calc(var(--reveal-i, 0) * 0.18s);
    will-change: clip-path;
  }
  .has-js .shutter-reveal.is-in {
    clip-path: inset(0 0 0 0);
  }
  /* Opening upwards instead: the crop edge starts at the bottom and rises,
     travelling the same way the stacked sections slide (body class from
     functions/section_stack.php). */
  .has-js .shutter-up .shutter-reveal {
    clip-path: inset(100% 0 0 0);
  }
  .has-js .shutter-up .shutter-reveal.is-in {
    clip-path: inset(0 0 0 0);
  }

  /* Text under an image drops into place on the same curve. Each piece
     goes separately, top first: --text-i is its position within its own
     block (set in the templates), --card-i the card's position in its
     grid (set in script.js), so a card's text follows its image. */
  .has-js .text-reveal {
    opacity: 0;
    transform: translateY(-0.6em);
    transition: opacity 1.5s cubic-bezier(0.33, 0.1, 0.25, 1),
      transform 1.5s cubic-bezier(0.33, 0.1, 0.25, 1);
    /* Kept short - a long wait on the later cards reads as lag rather
       than as a stagger. */
    transition-delay: calc(var(--card-i, 0) * 0.1s + var(--text-i, 0) * 0.07s);
    will-change: opacity, transform;
  }
  .has-js .text-reveal.is-in {
    opacity: 1;
    transform: none;
  }

  /* The header drops in the same way when the page loads - it is on
     screen from the start, so there is nothing to scroll into. Order:
     wordmark, each nav item, then the button. Indexes are set here rather
     than in the markup because the nav items come from a menu. */
  .has-js .site-header .site-logo,
  .has-js .site-header .menu > li,
  .has-js .site-header .site-header-icons > *,
  .has-js .site-header .site-header-button {
    opacity: 0;
    transform: translateY(-0.6em);
    transition: opacity 1.5s cubic-bezier(0.33, 0.1, 0.25, 1),
      transform 1.5s cubic-bezier(0.33, 0.1, 0.25, 1);
    transition-delay: calc(var(--text-i, 0) * 0.09s);
  }
  .has-js .site-header .menu > li:nth-child(1) {
    --text-i: 1;
  }
  .has-js .site-header .menu > li:nth-child(2) {
    --text-i: 2;
  }
  .has-js .site-header .menu > li:nth-child(3) {
    --text-i: 3;
  }
  .has-js .site-header .menu > li:nth-child(4) {
    --text-i: 4;
  }
  .has-js .site-header .menu > li:nth-child(5) {
    --text-i: 5;
  }
  .has-js .site-header .menu > li:nth-child(6) {
    --text-i: 6;
  }
  .has-js .site-header .menu > li:nth-child(7) {
    --text-i: 7;
  }
  .has-js .site-header .menu > li:nth-child(8) {
    --text-i: 8;
  }
  /* The bag and the account follow the last nav item and lead the
     button, which is the order they sit in across the bar. */
  .has-js .site-header .site-header-icons > *:nth-child(1) {
    --text-i: 6;
  }
  .has-js .site-header .site-header-icons > *:nth-child(2) {
    --text-i: 7;
  }
  .has-js .site-header .site-header-button {
    --text-i: 9;
  }
  .has-js .site-header.is-revealed .site-logo,
  .has-js .site-header.is-revealed .menu > li,
  .has-js .site-header.is-revealed .site-header-icons > *,
  .has-js .site-header.is-revealed .site-header-button {
    opacity: 1;
    transform: none;
  }
}
/* -- SHUTTER REVEAL END -- */

/* -- LINKS -- */
/* Links take the colour of whatever section they sit in rather than the
   browser/Bootstrap blue. Underlined by
   default, underline removed on hover.
   Bootstrap loads after reset.css and re-colours links, so the colour rule
   lives here (this sheet loads after Bootstrap). reset.css sets
   text-decoration: none !important, so the underline needs !important. */
a {
  color: inherit;
  text-decoration: underline !important;
}
a:hover,
a:focus {
  text-decoration: none !important;
}

/* Arrow link - "LABEL ->" in the link type style, no underline. The arrow
   nudges right on hover. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  text-decoration: none !important;
}
.arrow-link svg {
  width: 1.1em;
  height: 1.1em;
  flex: none;
  transition: transform 0.2s ease;
}
.arrow-link:hover svg,
.arrow-link:focus svg {
  transform: translateX(3px);
}

/* Pill button - filled with the section's text colour, label in the
   section's background colour, so it sits correctly on any ground.
   --section-bg / --section-text come from the page (body) or from a
   component's own background colour.
   The two colours are held in --pill-bg / --pill-fg so hover can simply
   swap them, and so anything that needs a different pair (the header
   button over a dark section) only has to set those two. */
.pill-button {
  --pill-bg: var(--section-text, var(--dark));
  --pill-fg: var(--section-bg, var(--light));
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 1.1em 2.2em;
  border: 0;
  border-radius: 999px;
  background-color: var(--pill-bg);
  color: var(--pill-fg);
  /* An inset outline rather than a border, so the button does not change
     size - it is what keeps the shape visible once inverted. */
  box-shadow: inset 0 0 0 1px var(--pill-bg);
  text-decoration: none !important;
  transition: background-color 0.25s ease, color 0.25s ease;
}
/* Inverts on hover: the fill drops away and the label takes the fill's
   colour, outline holding the shape. */
.pill-button:hover,
.pill-button:focus-visible {
  background-color: var(--pill-fg);
  color: var(--pill-bg);
}
.pill-button svg {
  width: 1.1em;
  height: 1.1em;
  flex: none;
}
/* -- LINKS END -- */

/* -- HEADER -- */
/* Sits over the page rather than pushing it down, so the hero image runs
   under it. No background of its own - the design has the wordmark and
   nav straight on the page/photo. Pages that do not open with a hero are
   offset by --header-height instead (see .main-offset below). */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  color: var(--dark);
  background-color: transparent;
}
/* The header is a solid bar at all times, so whatever scrolls past goes
   behind it rather than through the wordmark. Because the bar is always
   the same colour, its contents are too: they no longer take a colour
   from the section underneath, which is what made items flicker between
   black and white as the page moved. */
.site-header {
  /* The bar takes the page's own ground rather than a fixed cream, so on
     a pale blue trip page or a yellow section page the header reads as
     part of the page instead of a strip laid over it. --section-bg comes
     from the page's Background Colour (functions/section_style.php) and
     is set on <body>; the fallback is the default page ground. */
  background-color: var(--section-bg, var(--off-white));
  color: var(--section-text, var(--dark));
}
/* Except on a page that opens with a full-screen photograph, where the
   design wants the wordmark sitting on the picture. There the bar starts
   invisible and fades in as the hero title comes up to meet it, so the
   two never collide (js/script.js adds .is-solid). Everything below the
   hero is behind a solid bar as usual. */
.has-transparent-header .site-header {
  background-color: transparent;
  transition: background-color 0.3s ease, color 0.3s ease;
}
.has-transparent-header .site-header.is-solid {
  background-color: var(--section-bg, var(--off-white));
  color: var(--section-text, var(--dark));
}
/* Over a dark photograph the header has to be light, and the pill swaps
   its pair or a black button disappears into the picture. Which it needs
   is measured from the photograph in PHP (functions/header_offset.php),
   so it is right on the first paint rather than corrected afterwards. */
.transparent-header-light .site-header:not(.is-solid) {
  color: var(--light);
}
.transparent-header-light .site-header:not(.is-solid) .pill-button {
  --pill-bg: var(--light);
  --pill-fg: var(--dark);
}
.transparent-header-light .site-header:not(.is-solid) .site-header-cart {
  --count-ink: var(--dark);
}
.site-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--global-spacing-25);
}
/* The wordmark is an inline SVG using currentColor, so it takes the
   header's colour. Width follows the logo's own proportions. */
.site-logo svg {
  display: block;
  width: auto;
  height: var(--header-logo-height);
}
.site-header-nav {
  display: flex;
  align-items: center;
  gap: var(--global-spacing-25);
}
.site-header .menu {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--global-spacing-25);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-header .menu a {
  font-size: var(--font-size-nav);
}
/* Navigation is not body copy - it keeps the global link colour but not
   the underline. */
.site-header a {
  text-decoration: none !important;
}
.site-header-button {
  padding: 0.7em 1.9em;
  font-size: var(--font-size-nav);
  white-space: nowrap;
}
/* The burger. Hidden on desktop, where the nav is laid out in full. */
.site-header-toggle {
  display: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  transition: color 0.25s ease;
}
.site-header-toggle-bars {
  display: block;
  position: relative;
  width: 26px;
  height: 16px;
}
.site-header-toggle-bars span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background-color: currentColor;
  transition: transform 0.3s ease, opacity 0.2s ease;
}
.site-header-toggle-bars span:nth-child(1) {
  top: 0;
}
.site-header-toggle-bars span:nth-child(2) {
  top: 7px;
}
.site-header-toggle-bars span:nth-child(3) {
  top: 14px;
}
/* Open: the middle bar goes, the outer two cross into an X. They rotate
   about the centre, so both first travel to the middle line. */
.site-header.is-menu-open .site-header-toggle-bars span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.site-header.is-menu-open .site-header-toggle-bars span:nth-child(2) {
  opacity: 0;
}
.site-header.is-menu-open .site-header-toggle-bars span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Below the breakpoint the full nav does not fit, so it becomes a full
   screen panel that slides up from the bottom. The wordmark and the
   burger stay where they are the whole time: the panel is a child of the
   header with z-index -1, which puts it under those two but over the
   page (the header itself is the stacking context, at z-index 100). */
@media (max-width: 1300px) {
  .site-header-toggle {
    display: block;
  }
  .site-header-nav {
    position: fixed;
    inset: 0;
    z-index: -1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--global-spacing-50);
    padding: calc(var(--header-height) + var(--global-spacing-50)) var(--gutter);
    background-color: var(--moss-green);
    color: var(--off-white);
    transform: translateY(100%);
    /* Nothing in a closed panel can be tabbed to or clicked. Visibility
       is delayed until the slide has finished so it still animates. */
    visibility: hidden;
    transition: transform 0.6s cubic-bezier(0.33, 0.1, 0.25, 1),
      visibility 0s linear 0.6s;
  }
  .site-header.is-menu-open .site-header-nav {
    transform: none;
    visibility: visible;
    transition: transform 0.6s cubic-bezier(0.33, 0.1, 0.25, 1),
      visibility 0s;
  }
  .site-header .menu {
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-50);
    text-align: center;
  }
  /* The panel is moss green, so everything over it is off-white - the
     one place the header's contents are not the bar's dark. */
  .site-header.is-menu-open .site-logo,
  .site-header.is-menu-open .site-header-toggle,
  .site-header.is-menu-open .menu a,
  .site-header.is-menu-open .site-header-icon {
    color: var(--off-white);
  }
  .site-header.is-menu-open .pill-button {
    --pill-bg: var(--light);
    --pill-fg: var(--dark);
  }
}
/* The page behind the open menu does not scroll. */
.site-menu-lock,
.site-menu-lock body {
  overflow: hidden;
}
/* On a phone the wordmark and button together overrun the screen, so both
   step down. */
@media (max-width: 576px) {
  :root {
    --header-logo-height: 18px;
  }
  .site-header-button {
    padding: 0.7em 1.2em;
    font-size: var(--font-size-link);
  }
}
/* Pages that do not open with a hero banner start below the header
   rather than underneath it (see functions/header_offset.php). The
   header's height alone only just clears it - the first component needs
   room to breathe under the wordmark, so the offset carries a gap of its
   own on top of that. */
.has-header-offset main > article:first-of-type {
  padding-top: calc(var(--header-height) + var(--global-spacing-50));
}
/* Development only. With the admin toolbar showing, WordPress puts a
   32px fixed bar at the top of the viewport, which our own fixed header
   would sit underneath. WordPress marks the page with .admin-bar, so
   drop the header (and the offset that follows it) clear of the bar.
   Below 782px the toolbar is absolute rather than fixed - it scrolls
   away with the page - so it is left alone there. */
body.admin-bar .site-header {
  top: 32px;
}
body.admin-bar.has-header-offset main > article:first-of-type {
  padding-top: calc(var(--header-height) + var(--global-spacing-50) + 32px);
}
@media (max-width: 782px) {
  body.admin-bar .site-header {
    top: 0;
  }
  body.admin-bar.has-header-offset main > article:first-of-type {
    padding-top: calc(var(--header-height) + var(--global-spacing-50));
  }
}
/* -- HEADER END -- */

/* -- CHECKOUT -- */
/* The classic checkout, laid out by woocommerce/checkout/form-checkout.php
   and review-order.php. WooCommerce's own stylesheets are off on this page
   (functions/woocommerce.php), so everything it needs is here. */
.screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.shop-page-title {
  padding: var(--global-spacing-50) var(--gutter) var(--global-spacing-75);
  text-align: center;
}
.checkout-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  column-gap: clamp(40px, 9.4vw, 135px);
  align-items: start;
}
.checkout-section ~ .checkout-section {
  margin-top: var(--global-spacing-75);
}
.checkout-section h2,
.checkout-summary h2 {
  margin-bottom: var(--global-spacing-12);
}
.checkout-billing-address h3 {
  margin-top: var(--global-spacing-50);
}
.checkout-summary {
  position: sticky;
  top: calc(var(--header-height) + var(--global-spacing-25));
}

/* Fields: a rule under each, the label as an uppercase placeholder.
   First / last name share a line. */
.checkout-fields {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--global-spacing-25);
}
.checkout-grid .form-row {
  position: relative;
  flex: 1 1 100%;
  margin: 0;
  padding: 0;
}
.checkout-grid .form-row-first,
.checkout-grid .form-row-last {
  flex: 1 1 0;
}
.checkout-grid .input-text,
.checkout-grid select {
  display: block;
  width: 100%;
  height: auto;
  padding: 1.35rem 0 0.7rem;
  border: 0;
  border-bottom: 1px solid var(--dark);
  border-radius: 0;
  background: transparent;
  color: var(--dark);
  font-family: var(--font-family-sans);
  font-size: var(--font-size-link);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  appearance: none;
}
.checkout-grid input[type="email"] {
  text-transform: none;
}
.checkout-grid .input-text::placeholder {
  color: rgba(0, 4, 6, 0.45);
  opacity: 1;
  text-transform: uppercase;
}
.checkout-grid .input-text:focus,
.checkout-grid select:focus {
  outline: 0;
  border-bottom-width: 2px;
  padding-bottom: calc(0.7rem - 1px);
}
.checkout-grid select {
  padding-right: 1.5rem;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23000406' stroke-width='1.3'/%3E%3C/svg%3E") no-repeat right 0.2rem bottom 1rem / 10px 7px;
  cursor: pointer;
}
/* A field WooCommerce has flagged after a failed validation. */
.checkout-grid .woocommerce-invalid .input-text,
.checkout-grid .woocommerce-invalid select {
  border-bottom-color: var(--rust);
}
.checkout-grid .form-row .checkout-inline-error-message,
.checkout-grid .form-row .woocommerce-error {
  margin-top: var(--global-spacing-6) !important;
  color: var(--rust);
  font-size: var(--font-size-link);
}
/* A country with only one choice prints as text rather than a select. */
.checkout-grid .woocommerce-input-wrapper > strong {
  display: block;
  padding: 1.35rem 0 0.7rem;
  border-bottom: 1px solid var(--dark);
  font-size: var(--font-size-link);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Checkboxes: a small square box. */
.checkout-checkbox {
  margin-top: var(--global-spacing-25) !important;
}
.checkout-checkbox label {
  display: inline-flex;
  align-items: center;
  gap: 0.75em;
  font-size: var(--font-size-link);
  font-weight: 500;
  cursor: pointer;
}
.checkout-grid input[type="checkbox"] {
  flex: none;
  width: 12px;
  height: 12px;
  margin: 0;
  border: 1px solid var(--dark);
  border-radius: 2px;
  background: transparent;
  appearance: none;
  cursor: pointer;
}
.checkout-grid input[type="checkbox"]:checked {
  background: var(--dark) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.2l2.3 2.3 4.7-5' fill='none' stroke='%23fcfaed' stroke-width='1.5'/%3E%3C/svg%3E") center / 100% no-repeat;
}
.checkout-grid input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--dark);
  outline-offset: 2px;
}

/* Payment: each method a pill tab, the chosen one outlined; its fields
   sit underneath the row of tabs. */
.checkout-grid .wc_payment_methods {
  display: flex;
  flex-wrap: wrap;
  gap: var(--global-spacing-12);
  margin: var(--global-spacing-12) 0 0;
  padding: 0;
  list-style: none;
}
.checkout-grid .wc_payment_method {
  display: contents;
}
.checkout-grid .wc_payment_method > input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.checkout-grid .wc_payment_method > label {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 1.25em 1.8em;
  border-radius: 999px;
  background: rgba(0, 4, 6, 0.05);
  box-shadow: inset 0 0 0 1px transparent;
  font-size: var(--font-size-link);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: box-shadow 0.25s ease;
}
.checkout-grid .wc_payment_method > label img {
  max-height: 1.4em;
  width: auto;
}
.checkout-grid .wc_payment_method > input:checked + label {
  box-shadow: inset 0 0 0 1px var(--dark);
}
.checkout-grid .wc_payment_method > input:focus-visible + label {
  outline: 2px solid var(--dark);
  outline-offset: 2px;
}
.checkout-grid .payment_box {
  order: 1;
  flex: 1 1 100%;
  font-size: var(--font-size-link);
  font-weight: 500;
}
.checkout-grid .payment_box p,
.checkout-grid .woocommerce-privacy-policy-text p {
  font-size: inherit;
  line-height: inherit !important;
}
.checkout-grid .payment_box p {
  margin-top: var(--global-spacing-25) !important;
}
.checkout-grid .payment_box fieldset {
  margin: 0;
  padding: 0;
  border: 0;
}
.checkout-grid .place-order {
  margin-top: var(--global-spacing-50);
}
.checkout-grid .woocommerce-privacy-policy-text {
  max-width: 22rem;
  font-size: var(--font-size-link);
  font-weight: 500;
  line-height: 1.35;
}
.checkout-grid .woocommerce-privacy-policy-text a {
  text-decoration: underline !important;
}
.checkout-place-order {
  --pill-bg: var(--dark);
  --pill-fg: var(--light);
  margin-top: var(--global-spacing-25);
  cursor: pointer;
}
.checkout-place-order::after {
  content: "";
  width: 1.1em;
  height: 1.1em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.3'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.3'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* WooCommerce greys the form out while it talks to the server. */
.checkout-grid .blockUI.blockOverlay {
  background: var(--section-bg, var(--light)) !important;
  opacity: 0.5 !important;
}

/* Your Order. */
.checkout-order {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-body);
  font-weight: 500;
}
.checkout-order th {
  font-weight: inherit;
  text-align: left;
}
.checkout-order td:last-child {
  text-align: right;
  white-space: nowrap;
}
.checkout-order tbody td {
  padding: var(--global-spacing-12) 0 0;
  vertical-align: top;
}
.checkout-order tbody tr:first-child td {
  padding-top: var(--global-spacing-25);
}
.checkout-order tbody tr:last-child td {
  padding-bottom: var(--global-spacing-25);
}
.checkout-order-name .type-link {
  display: block;
  margin-bottom: 0.25em;
}
/* The name takes whatever the price does not: the price never wraps, so
   this keeps it hard against the right edge. */
.checkout-order-name {
  width: 100%;
  padding-right: var(--global-spacing-25);
}
/* Quantity reads as part of the name rather than a column of its own.
   The rule above makes a .type-link in here a block, which would put it
   on a line by itself, so it is put back inline. */
.checkout-order-name .checkout-order-qty {
  display: inline;
  margin-bottom: 0;
  opacity: 0.6;
  white-space: nowrap;
}
.checkout-order tfoot th,
.checkout-order tfoot td {
  padding: var(--global-spacing-6) 0;
}
.checkout-order .checkout-order-first th,
.checkout-order .checkout-order-first td {
  padding-top: var(--global-spacing-25);
  border-top: 1px solid var(--dark);
}
.checkout-order .order-total th,
.checkout-order .order-total td {
  padding-top: var(--global-spacing-25);
  border-top: 1px solid var(--dark);
  font-size: var(--font-size-h6);
}
.checkout-order tfoot tr:nth-last-child(2) th,
.checkout-order tfoot tr:nth-last-child(2) td {
  padding-bottom: var(--global-spacing-25);
}
/* What will be charged after today. The rows come from the theme's own
   woocommerce/checkout/recurring-totals.php, so they carry the same three
   columns as everything else in this table and need nothing but the rule
   above them that the other sections get. */
.checkout-order .recurring-total th,
.checkout-order .recurring-total td {
  padding-top: var(--global-spacing-6);
}

.checkout-order-note {
  font-size: var(--font-size-link);
  opacity: 0.6;
}
.checkout-shipping-methods {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Notices WooCommerce prints above the form (errors after Place order). */
.woocommerce-NoticeGroup,
.woocommerce-notices-wrapper:not(:empty) {
  margin-bottom: var(--global-spacing-50);
}
.woocommerce-error,
.woocommerce-message,
.woocommerce-info {
  margin: 0;
  padding: var(--global-spacing-25);
  border-radius: 16px;
  background: var(--yellow);
  color: var(--dark);
  font-weight: 500;
  list-style: none;
}
.woocommerce-error li + li {
  margin-top: var(--global-spacing-6);
}

@media (max-width: 991px) {
  .checkout-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  /* Order summary first on a phone - what you're paying for, then how. */
  .checkout-summary {
    position: static;
    order: -1;
    margin-bottom: var(--global-spacing-75);
  }
}
@media (max-width: 576px) {
  .checkout-grid .form-row-first,
  .checkout-grid .form-row-last {
    flex-basis: 100%;
  }
}
/* -- CHECKOUT END -- */

/* -- CART PANEL -- */
/* Slides in from the right over a dimmed page (functions/cart_panel.php,
   js/script.js). Moss Green with light text; full screen on a phone. */
.cart-panel-lock,
.cart-panel-lock body {
  overflow: hidden;
}
.cart-panel-backdrop {
  position: fixed;
  inset: 0;
  z-index: 190;
  /* The design leaves the page undimmed - this only catches the click
     that closes the panel. */
  background: transparent;
  opacity: 0;
  transition: opacity 0.6s cubic-bezier(0.33, 0.1, 0.25, 1);
}
.cart-panel-backdrop.is-open {
  opacity: 1;
}
.cart-panel {
  --section-bg: var(--moss-green);
  --section-text: var(--off-white);
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  width: min(33rem, 100%);
  background-color: var(--section-bg);
  color: var(--section-text);
  transform: translateX(100%);
  transition: transform 0.6s cubic-bezier(0.33, 0.1, 0.25, 1);
}
.cart-panel.is-open {
  transform: none;
}
.cart-panel-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--global-spacing-25);
  overflow-y: auto;
}
.cart-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--global-spacing-25);
}
.cart-panel-close {
  width: 36px;
  height: 36px;
  margin-right: -6px;
  padding: 6px;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.cart-panel-close svg {
  display: block;
  width: 100%;
  height: 100%;
}
.cart-panel-items {
  display: flex;
  flex-direction: column;
  gap: var(--global-spacing-50);
  margin: 0;
  padding: 0;
  list-style: none;
}
.cart-panel-item {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr) auto;
  gap: var(--global-spacing-25);
  align-items: start;
  transition: opacity 0.2s;
}
.cart-panel-item.is-busy {
  opacity: 0.5;
}
.cart-panel-image {
  width: 100%;
  height: auto;
  aspect-ratio: 670 / 806;
  object-fit: cover;
  box-shadow: 0 6px 14px rgba(0, 4, 6, 0.25);
}
.cart-panel-details {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--global-spacing-3);
}
.cart-panel-title {
  font-family: var(--font-family-serif);
  font-size: var(--font-size-h6);
  font-weight: 400;
  line-height: 1.2;
  text-decoration: none !important;
}
.cart-panel-price {
  font-size: var(--font-size-body);
}
.cart-panel-upsell {
  margin-top: var(--global-spacing-6);
  font-size: 0.6875rem;
  opacity: 0.85;
  text-decoration: none !important;
}
.cart-panel-upsell span {
  text-decoration: underline;
  text-underline-offset: 2px;
}
.cart-panel-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--global-spacing-12);
}
.cart-panel-qty {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  padding: 0.6em 0.9em;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: var(--font-size-link);
}
.cart-panel-qty button,
.cart-panel-remove {
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.cart-panel-qty button {
  width: 1.8em;
  padding: 0.2em 0;
  font: inherit;
  line-height: 1;
}
.cart-panel-qty button:disabled {
  opacity: 0.35;
  cursor: default;
}
.cart-panel-qty span {
  min-width: 1.2em;
  text-align: center;
}
/* Suggested product - the subscription, alongside what is already in the
   cart (functions/cart_panel.php). */
/* "You might also like" sits at the foot of the panel, directly above the
   subtotal, however few items the cart holds: margin-top: auto takes up
   the slack, which leaves the space after the last item rather than
   between the suggestion and the total. The cart items keep a gap of
   their own so a long cart never runs straight into it. */
.cart-panel-items {
  margin-bottom: var(--global-spacing-50);
}
.cart-panel-suggestions {
  margin-top: auto;
  padding-top: var(--global-spacing-25);
  border-top: 1px solid rgba(252, 250, 237, 0.35);
}
.cart-panel-suggestions-title {
  margin-bottom: var(--global-spacing-12);
}
.cart-panel-suggestion {
  display: flex;
  align-items: center;
  gap: var(--global-spacing-12);
}
/* The foot's own margin-top: auto would split the slack with the
   suggestion above it; with a suggestion there, the foot just follows. */
.cart-panel-suggestions + .cart-panel-foot {
  margin-top: var(--global-spacing-25);
}
.cart-panel-suggestion-text {
  display: flex;
  flex-direction: column;
  gap: var(--global-spacing-3);
  margin-right: auto;
}
.cart-panel-suggestion-add {
  flex: none;
  padding: 0.7em 1.4em;
}
.cart-panel-foot {
  margin-top: auto;
  padding-top: var(--global-spacing-25);
  border-top: 1px solid rgba(252, 250, 237, 0.35);
}
.cart-panel-subtotal {
  display: flex;
  justify-content: space-between;
  gap: var(--global-spacing-25);
}
.cart-panel-foot > p {
  margin-top: var(--global-spacing-6) !important;
  font-size: var(--font-size-body);
}
.cart-panel-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--global-spacing-12);
  margin-top: var(--global-spacing-50);
}
.cart-panel-foot .cart-panel-buttons > * {
  flex: 1 1 0;
  justify-content: center;
}
.cart-panel-empty {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.cart-panel-empty .cart-panel-buttons {
  justify-content: center;
  margin-top: var(--global-spacing-25);
}
/* Outline pill - the pill's colours without the fill (View cart). */
.pill-button-outline {
  background-color: transparent;
  color: var(--pill-bg);
}
.pill-button-outline:hover,
.pill-button-outline:focus-visible {
  background-color: var(--pill-bg);
  color: var(--pill-fg);
}
@media (max-width: 576px) {
  .cart-panel-item {
    grid-template-columns: 4.5rem minmax(0, 1fr);
  }
  .cart-panel-actions {
    grid-column: 2;
    flex-direction: row;
    justify-content: flex-start;
  }
}
@media (prefers-reduced-motion: reduce) {
  .cart-panel,
  .cart-panel-backdrop {
    transition: none;
  }
}
/* -- CART PANEL END -- */

/* -- POPUP -- */
/* The promotional card (functions/popup.php): lower left, on the page
   gutter, below the header in the stacking order. Drops in a moment after
   the page loads, on the site's reveal curve. */
.site-popup {
  position: fixed;
  left: var(--gutter);
  bottom: var(--gutter);
  z-index: 90;
  /* Square, and narrower than it was. At 42rem this covered nearly half a
     laptop screen; at 28rem it was still a wide banner. --popup-size is
     shared with the buy panel so the two cards match. aspect-ratio sets
     the height it wants rather than the height it must have, so a longer
     title still grows the card instead of spilling out of it. */
  width: min(var(--popup-size), calc(100% - (var(--gutter) * 2)));
  aspect-ratio: 1 / 1;
  padding: var(--global-spacing-25);
  border-radius: 16px;
  background-color: var(--yellow);
  color: var(--dark);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--global-spacing-12);
  opacity: 0;
  transform: translateY(-0.6em);
  transition: opacity 1.5s cubic-bezier(0.33, 0.1, 0.25, 1),
    transform 1.5s cubic-bezier(0.33, 0.1, 0.25, 1);
}
.site-popup.is-open {
  opacity: 1;
  transform: none;
}
.site-popup.is-closing {
  opacity: 0;
  transition-duration: 0.3s;
}
.site-popup-text {
  margin-bottom: var(--global-spacing-6) !important;
}
.site-popup-close {
  position: absolute;
  top: var(--global-spacing-12);
  right: var(--global-spacing-12);
  width: 36px;
  height: 36px;
  padding: 6px;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.site-popup-close svg {
  display: block;
  width: 100%;
  height: 100%;
}
@media (prefers-reduced-motion: reduce) {
  .site-popup {
    transition: none;
  }
}
/* -- POPUP END -- */

/* -- FOOTER -- */
/* Link columns on the right, then the wordmark across the foot. A column
   so the wordmark can be pinned to the bottom however tall the columns
   above it run. */
.site-footer {
  display: flex;
  flex-direction: column;
  background-color: var(--moss-green);
  color: var(--off-white);
  /* So the wordmark and the columns are never cramped on a short page. */
  padding-top: var(--global-spacing-25);
}
.site-footer-bottom {
  margin-top: auto;
  padding-top: var(--global-spacing-150);
}
/* The three columns are as wide as their own text and sit as a group
   against the right gutter, so the longest line (the email address) ends
   exactly on it - in line with the header button and the wordmark. A
   fixed-width grid would leave the text stopping short inside its column. */
.site-footer-columns {
  display: flex;
  flex-wrap: wrap;
  /* The block starts at the middle of the page and spreads across the
     right half, so the first column begins on the halfway point and the
     last line ends on the gutter. */
  margin-left: 50%;
  justify-content: space-between;
  gap: var(--global-spacing-50);
}
.site-footer-column {
  flex: 0 1 auto;
}
.site-footer-heading {
  margin-bottom: var(--global-spacing-12);
  opacity: 0.75;
}
.site-footer-menu {
  display: flex;
  flex-direction: column;
  gap: var(--global-spacing-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-footer-menu a {
  text-decoration: none !important;
}
/* The wordmark is an inline SVG on currentColor, set to the full width of
   the page between the gutters. */
.site-footer-logo {
  display: block;
}
.site-footer-logo svg {
  display: block;
  width: 100%;
  height: auto;
}
@media (max-width: 768px) {
  .site-footer-bottom {
    padding-top: var(--global-spacing-75);
  }
  /* Stacked and left-aligned on a phone, where a right-aligned group of
     one-per-row columns would read oddly. */
  .site-footer-columns {
    flex-direction: column;
    justify-content: flex-start;
    margin-left: 0;
    gap: var(--global-spacing-25);
  }
}
/* -- FOOTER END -- */

/* -- BASE COLOUR -- */
/* --section-bg / --section-text are the ground and text colour of wherever
   an element sits. body sets them from the page's Background Colour field
   (header.php, falling back to --light / --dark here); a component with
   its own Background Colour sets them again on its <article> (see
   functions/section_style.php). Components without one are transparent
   and inherit the page's. */
body {
  --section-bg: var(--light);
  --section-text: var(--dark);
  background-color: var(--section-bg);
  color: var(--section-text);
  /* reset.css makes body a flex column with footer { margin-top: auto };
     without a floor the footer stops short of the window on a page with
     little content. */
  min-height: 100vh;
}
/* -- BASE COLOUR END -- */

/* -- SPACING -- */
/* The page's side margin - every component's content lines up on it. */
.padding-inline-gutter {
  padding-inline: var(--gutter);
}

.padding-3 {
  padding: var(--global-spacing-3);
}
.padding-6 {
  padding: var(--global-spacing-6);
}
.padding-12 {
  padding: var(--global-spacing-12);
}
.padding-25 {
  padding: var(--global-spacing-25);
}
.padding-50 {
  padding: var(--global-spacing-50);
}
.padding-75 {
  padding: var(--global-spacing-75);
}
.padding-100 {
  padding: var(--global-spacing-100);
}

.padding-left-3 {
  padding-left: var(--global-spacing-3);
}
.padding-left-6 {
  padding-left: var(--global-spacing-6);
}
.padding-left-12 {
  padding-left: var(--global-spacing-12);
}
.padding-left-25 {
  padding-left: var(--global-spacing-25);
}
.padding-left-50 {
  padding-left: var(--global-spacing-50);
}
.padding-left-75 {
  padding-left: var(--global-spacing-75);
}
.padding-left-100 {
  padding-left: var(--global-spacing-100);
}

.padding-right-3 {
  padding-right: var(--global-spacing-3);
}
.padding-right-6 {
  padding-right: var(--global-spacing-6);
}
.padding-right-12 {
  padding-right: var(--global-spacing-12);
}
.padding-right-25 {
  padding-right: var(--global-spacing-25);
}
.padding-right-50 {
  padding-right: var(--global-spacing-50);
}
.padding-right-75 {
  padding-right: var(--global-spacing-75);
}
.padding-right-100 {
  padding-right: var(--global-spacing-100);
}

.padding-top-3 {
  padding-top: var(--global-spacing-3);
}
.padding-top-6 {
  padding-top: var(--global-spacing-6);
}
.padding-top-12 {
  padding-top: var(--global-spacing-12);
}
.padding-top-25 {
  padding-top: var(--global-spacing-25);
}
.padding-top-50 {
  padding-top: var(--global-spacing-50);
}
.padding-top-75 {
  padding-top: var(--global-spacing-75);
}
.padding-top-100 {
  padding-top: var(--global-spacing-100);
}
.padding-top-150 {
  padding-top: var(--global-spacing-150);
}
.padding-top-200 {
  padding-top: var(--global-spacing-200);
}

.padding-bottom-3 {
  padding-bottom: var(--global-spacing-3);
}
.padding-bottom-6 {
  padding-bottom: var(--global-spacing-6);
}
.padding-bottom-12 {
  padding-bottom: var(--global-spacing-12);
}
.padding-bottom-25 {
  padding-bottom: var(--global-spacing-25);
}
.padding-bottom-50 {
  padding-bottom: var(--global-spacing-50);
}
.padding-bottom-75 {
  padding-bottom: var(--global-spacing-75);
}
.padding-bottom-100 {
  padding-bottom: var(--global-spacing-100);
}
.padding-bottom-150 {
  padding-bottom: var(--global-spacing-150);
}

.padding-block-3 {
  padding-block: var(--global-spacing-3);
}
.padding-block-6 {
  padding-block: var(--global-spacing-6);
}
.padding-block-12 {
  padding-block: var(--global-spacing-12);
}
.padding-block-25 {
  padding-block: var(--global-spacing-25);
}
.padding-block-50 {
  padding-block: var(--global-spacing-50);
}
.padding-block-75 {
  padding-block: var(--global-spacing-75);
}
.padding-block-100 {
  padding-block: var(--global-spacing-100);
}
.padding-block-150 {
  padding-block: var(--global-spacing-150);
}

/* On a phone the components stack into a single column, so the space at
   the foot of one is all that separates it from the next - 50px more
   than the scale gives. Bottom only: the top keeps its own rhythm.
   This matches the breakpoint where the spacing scale already steps
   down (--global-spacing-100 becomes 75px). */
.padding-block-100,
.padding-bottom-100 {
  padding-bottom: calc(var(--global-spacing-100) + 50px);
}

/* A full-bleed image component ends at the edges of the screen with no
   padding of its own, so the component after it has only its own top
   padding between the two - which reads as almost touching on a phone.
   The space goes on the top of the component that follows rather than
   under the image, so a section with its own background colour still
   meets the image flush.
   Extend the list if another full-bleed component is added. */
.hero-banner + article .padding-block-100,
.featured-image-text + article .padding-block-100,
.call-to-action + article .padding-block-100 {
  padding-top: calc(var(--global-spacing-100) + 50px);
}
.hero-banner + article .padding-block-50,
.featured-image-text + article .padding-block-50,
.call-to-action + article .padding-block-50 {
  padding-top: calc(var(--global-spacing-50) + 50px);
}

.padding-inline-3 {
  padding-inline: var(--global-spacing-3);
}
.padding-inline-6 {
  padding-inline: var(--global-spacing-6);
}
.padding-inline-12 {
  padding-inline: var(--global-spacing-12);
}
.padding-inline-25 {
  padding-inline: var(--global-spacing-25);
}
.padding-inline-50 {
  padding-inline: var(--global-spacing-50);
}
.padding-inline-75 {
  padding-inline: var(--global-spacing-75);
}
.padding-inline-100 {
  padding-inline: var(--global-spacing-100);
}
.padding-inline-150 {
  padding-inline: var(--global-spacing-150);
}

.margin-3 {
  margin: var(--global-spacing-3);
}
.margin-6 {
  margin: var(--global-spacing-6);
}
.margin-12 {
  margin: var(--global-spacing-12);
}
.margin-25 {
  margin: var(--global-spacing-25);
}
.margin-50 {
  margin: var(--global-spacing-50);
}
.margin-75 {
  margin: var(--global-spacing-75);
}
.margin-100 {
  margin: var(--global-spacing-100);
}
.margin-150 {
  margin: var(--global-spacing-150);
}
.margin-200 {
  margin: var(--global-spacing-200);
}

.margin-left-3 {
  margin-left: var(--global-spacing-3);
}
.margin-left-6 {
  margin-left: var(--global-spacing-6);
}
.margin-left-12 {
  margin-left: var(--global-spacing-12);
}
.margin-left-25 {
  margin-left: var(--global-spacing-25);
}
.margin-left-50 {
  margin-left: var(--global-spacing-50);
}
.margin-left-75 {
  margin-left: var(--global-spacing-75);
}
.margin-left-100 {
  margin-left: var(--global-spacing-100);
}
.margin-left-150 {
  margin-left: var(--global-spacing-150);
}
.margin-left-200 {
  margin-left: var(--global-spacing-200);
}

.margin-right-3 {
  margin-right: var(--global-spacing-3);
}
.margin-right-6 {
  margin-right: var(--global-spacing-6);
}
.margin-right-12 {
  margin-right: var(--global-spacing-12);
}
.margin-right-25 {
  margin-right: var(--global-spacing-25);
}
.margin-right-50 {
  margin-right: var(--global-spacing-50);
}
.margin-right-75 {
  margin-right: var(--global-spacing-75);
}
.margin-right-100 {
  margin-right: var(--global-spacing-100);
}
.margin-right-150 {
  margin-right: var(--global-spacing-150);
}
.margin-right-200 {
  margin-right: var(--global-spacing-200);
}

.margin-top-3 {
  margin-top: var(--global-spacing-3);
}
.margin-top-6 {
  margin-top: var(--global-spacing-6);
}
.margin-top-12 {
  margin-top: var(--global-spacing-12);
}
.margin-top-25 {
  margin-top: var(--global-spacing-25);
}
.margin-top-50 {
  margin-top: var(--global-spacing-50);
}
.margin-top-75 {
  margin-top: var(--global-spacing-75);
}
.margin-top-100 {
  margin-top: var(--global-spacing-100);
}
.margin-top-150 {
  margin-top: var(--global-spacing-150);
}
.margin-top-200 {
  margin-top: var(--global-spacing-200);
}

.margin-bottom-3 {
  margin-bottom: var(--global-spacing-3);
}
.margin-bottom-6 {
  margin-bottom: var(--global-spacing-6);
}
.margin-bottom-12 {
  margin-bottom: var(--global-spacing-12);
}
.margin-bottom-25 {
  margin-bottom: var(--global-spacing-25);
}
.margin-bottom-50 {
  margin-bottom: var(--global-spacing-50);
}
.margin-bottom-75 {
  margin-bottom: var(--global-spacing-75);
}
.margin-bottom-100 {
  margin-bottom: var(--global-spacing-100);
}
.margin-bottom-150 {
  margin-bottom: var(--global-spacing-150);
}
.margin-bottom-200 {
  margin-bottom: var(--global-spacing-200);
}
@media (max-width: 767px) {
  .margin-bottom-200 {
    margin-bottom: 25px !important;
  }
}

.margin-block-3 {
  margin-block: var(--global-spacing-3);
}
.margin-block-6 {
  margin-block: var(--global-spacing-6);
}
.margin-block-12 {
  margin-block: var(--global-spacing-12);
}
.margin-block-25 {
  margin-block: var(--global-spacing-25);
}
.margin-block-50 {
  margin-block: var(--global-spacing-50);
}
.margin-block-75 {
  margin-block: var(--global-spacing-75);
}
.margin-block-100 {
  margin-block: var(--global-spacing-100);
}
.margin-block-150 {
  margin-block: var(--global-spacing-150);
}
.margin-block-200 {
  margin-block: var(--global-spacing-200);
}

.margin-inline-3 {
  margin-inline: var(--global-spacing-3);
}
.margin-inline-6 {
  margin-inline: var(--global-spacing-6);
}
.margin-inline-12 {
  margin-inline: var(--global-spacing-12);
}
.margin-inline-25 {
  margin-inline: var(--global-spacing-25);
}
.margin-inline-50 {
  margin-inline: var(--global-spacing-50);
}
.margin-inline-75 {
  margin-inline: var(--global-spacing-75);
}
.margin-inline-100 {
  margin-inline: var(--global-spacing-100);
}
.margin-inline-150 {
  margin-inline: var(--global-spacing-150);
}
.margin-inline-200 {
  margin-inline: var(--global-spacing-200);
}
/* -- SPACING END -- */

/* -- POSITION -- */
.position-fixed {
  position: fixed !important;
}
/* -- POSITION END -- */

/* -- SIZING -- */
.vh-100 {
  height: auto !important;
  min-height: 100vh !important;
}

.object-contain {
  object-fit: contain !important;
}

.object-cover {
  object-fit: cover !important;
}
/* -- SIZING END -- */

/* -- BORDER -- */
.border-radius-12 {
  border-radius: var(--global-spacing-12);
}
.border-radius-25 {
  border-radius: var(--global-spacing-25);
}
.border-radius-100 {
  border-radius: var(--global-spacing-100);
}
/* -- BORDER END -- */

/* -- GENERAL -- */
.hidden {
  opacity: 0;
}
.ml-auto {
  margin-left: auto !important;
}
.mr-auto {
  margin-right: auto !important;
}
/* -- GENERAL END -- */

/* -- RESIZE GUARD -- */
/* While the window is being dragged, the mobile menu panel must not
   animate. Crossing the burger breakpoint changes its transform from none
   to off-the-bottom, and without this the browser transitions between the
   two and the panel visibly drops down the screen. js/script.js adds the
   class and removes it once the window stops moving. */
.is-resizing .site-header-nav,
.is-resizing .site-header,
.is-resizing .site-header * {
  transition: none !important;
}
/* -- RESIZE GUARD END -- */

/* -- HEADER ICONS -- */
/* Cart and account, replacing the word "Cart" in the menu. They sit in the
   nav so the colour switching treats them like any other header item. */
.site-header-icons {
  display: flex;
  align-items: center;
  gap: var(--global-spacing-25);
}
.site-header-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  color: inherit;
  transition: opacity 0.2s ease;
}
.site-header-icon svg {
  display: block;
  width: 22px;
  height: 22px;
}
.site-header-icon:hover,
.site-header-icon:focus-visible {
  opacity: 0.6;
}
/* The count rides on the corner of the bag: a filled pill in the page's
   ink with the number knocked out of it in the page's ground, so it
   inverts correctly whatever colour the header has taken.
   It used to take `background-color: currentColor`, but currentColor
   resolves against the colour set on this same element, so the pill and
   the number came out identical and the badge was invisible on every
   page. Both colours are now named outright. */
.site-header-cart-count {
  position: absolute;
  top: -7px;
  right: -9px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background-color: var(--section-text, var(--dark));
  color: var(--section-bg, var(--off-white));
  -webkit-text-fill-color: var(--section-bg, var(--off-white));
  font-size: 11px;
  letter-spacing: 0;
  line-height: 18px;
  text-align: center;
}
/* Over a photograph the header goes light, so the pill has to swap too or
   it is a dark blob on a dark picture. */
.transparent-header-light .site-header:not(.is-solid) .site-header-cart-count {
  background-color: var(--light);
  color: var(--dark);
  -webkit-text-fill-color: var(--dark);
}
@media (max-width: 1300px) {
  /* In the slide-up panel the icons sit with the links rather than in a
     row of their own. */
  .site-header-icons {
    justify-content: center;
  }
}
/* -- HEADER ICONS END -- */

/* -- ACCOUNT MENU -- */
/* My account and Log out, hanging from the person icon. */
.site-header-account-menu {
  position: relative;
  display: inline-flex;
}
.site-header-account-menu .site-header-icon {
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  font: inherit;
}
.account-menu {
  position: absolute;
  top: calc(100% + var(--global-spacing-12));
  right: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  min-width: 11rem;
  padding: var(--global-spacing-12);
  border-radius: 16px;
  background-color: var(--off-white);
  color: var(--dark);
  box-shadow: 0 10px 30px rgba(0, 4, 6, 0.12);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.account-menu.is-open {
  opacity: 1;
  transform: none;
}
.account-menu-item {
  padding: var(--global-spacing-12);
  border-radius: 8px;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.account-menu-item:hover,
.account-menu-item:focus-visible {
  background-color: var(--sand);
}
/* In the slide-up panel the header has its own ground, so the menu sits
   in the flow rather than floating over it. */
@media (max-width: 1300px) {
  .account-menu {
    right: auto;
    left: 50%;
    transform: translateX(-50%) translateY(-4px);
  }
  .account-menu.is-open {
    transform: translateX(-50%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .account-menu {
    transition: none;
  }
}
/* -- ACCOUNT MENU END -- */
