/* ---- tokens.css ---- */
/* Design tokens. Colours and sizes come from the approved KISWA design (PDF points x 1.333 = CSS pixels). */
:root {
  /* Brand colours */
  --navy: #102a43;          /* header bar, hero, footer, headings */
  --teal: #087f8c;          /* button backgrounds */
  --teal-hover: #066a75;
  --teal-text: #07737f;     /* teal text on white or light grey; a touch darker than --teal so small text passes WCAG AA */
  --teal-on-dark: #76d2d2;  /* small labels on navy */

  /* Text */
  --ink: #102a43;           /* headings */
  --text: #526577;          /* body copy */
  --text-on-dark: #d6e5ed;  /* paragraphs on navy */
  --muted-on-dark: #cbd5e1; /* footer and sidebar copy on navy */

  /* Surfaces */
  --white: #ffffff;
  --surface: #f1f5f8;       /* cards, panels, form fields */
  --surface-hover: #e6edf2;
  --border: #dce5eb;
  --border-strong: #b9c7d2;

  /* Feedback */
  --error: #b42318;
  --error-surface: #fef3f2;
  --success: #067647;
  --success-surface: #ecfdf3;
  --focus: #087f8c;

  /* Type */
  --font-sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --fs-hero: clamp(2rem, 1.3rem + 2.25vw, 2.75rem);      /* 32-44px: home hero */
  --fs-display: clamp(2rem, 1.25rem + 2.4vw, 2.875rem);  /* 32-46px: page titles */
  --fs-h2: clamp(1.625rem, 1.25rem + 1.25vw, 2.125rem);  /* 26-34px: section titles */
  --fs-h3-lg: clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem);    /* 20-24px: feature card titles */
  --fs-h3: 1.3125rem;                                     /* 21px: card titles */
  --fs-lead: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);   /* 17-20px: intro paragraphs */
  --fs-md: 1.0625rem;                                     /* 17px: section intros */
  --fs-body: 1rem;                                        /* 16px */
  --fs-small: 0.9375rem;                                  /* 15px */
  --fs-xs: 0.8125rem;                                     /* 13px: eyebrows */
  --fs-2xs: 0.6875rem;                                    /* 11px: card eyebrows */
  --lh-tight: 1.15;
  --lh-snug: 1.35;
  --lh-body: 1.55;

  /* Layout */
  --container: 1120px;                                    /* content width */
  --gutter: clamp(1rem, 0.25rem + 3vw, 2.5rem);           /* 16px on phones, 40px on desktop */
  --section-space: clamp(3rem, 2.25rem + 2.5vw, 4.5rem);  /* vertical space between sections */
  --header-height: 5.875rem;
  --radius: 4px;
}

/* Breakpoints are written in em (1em = 16px at the default text size: 40em = 640px, 60em = 960px), so
   layouts switch earlier when a visitor enlarges the browser's text size and nothing gets cut off. */

@media (max-width: 59.99875em) {
  :root {
    --header-height: 4rem;
  }
}

/* ---- base.css ---- */
/* Base element styles and utilities. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  color: var(--ink);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  overflow-wrap: break-word;
}

p,
ul,
ol,
dl,
dd,
figure,
blockquote,
fieldset {
  margin: 0;
}

fieldset {
  padding: 0;
  border: 0;
}

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

img {
  height: auto;
}

.icon {
  display: inline-block;
  flex: none;
  vertical-align: middle;
}

a {
  color: var(--teal-text);
  text-underline-offset: 0.18em;
}

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

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

main:focus {
  outline: none;
}

/* Keep link targets and focused elements clear of the sticky header (the browser only scrolls a
   focused element into the window, so with Shift+Tab it could stop under the header). Elements in
   the header are left out: the header never scrolls away, and a margin there would make the page jump. */
[id],
main *,
.site-footer * {
  scroll-margin-top: calc(var(--header-height) + 1rem);
}

[hidden] {
  display: none !important;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--gutter);
  z-index: 100;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  background: var(--navy);
  color: var(--white);
  font-weight: 700;
  text-decoration: none;
}

.skip-link:focus {
  top: 0.75rem;
  color: var(--white);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ---- layout.css ---- */
/* Page frame: container, sections, site header and footer. */
.container {
  width: 100%;
  max-width: calc(var(--container) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section-title {
  font-size: var(--fs-h2);
  text-wrap: balance; /* avoids a single word on the last line, where supported */
}

.section-lead {
  margin-top: 0.75rem;
  font-size: var(--fs-md);
  max-width: 52rem;
}

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--white);
  border-bottom: 1px solid var(--border);
}

/* The header row is sized in rem; let it grow with the text size so the links and button still fit. */
.site-header .container {
  max-width: calc(70rem + 2 * var(--gutter));
}

.site-header__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 2rem;
  min-height: var(--header-height);
}

.brand {
  justify-self: start;
  color: var(--ink);
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.01em;
  text-decoration: none;
}

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

.site-nav__list {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav__link {
  display: block;
  padding: 0.5rem 0;
  color: var(--text);
  font-size: 1rem;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: inset 0 -2px 0 transparent;
  transition: color 0.15s ease, box-shadow 0.15s ease;
}

.site-nav__link:hover {
  color: var(--ink);
}

/* aria-current is "page" on the page itself and "true" on its section (e.g. Products on a product page). */
.site-nav__link[aria-current] {
  color: var(--ink);
  box-shadow: inset 0 -2px 0 var(--teal);
}

/* Forced colours (Windows contrast themes) remove the box-shadow underline above. */
@media (forced-colors: active) {
  .site-nav__link[aria-current] {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 0.4em;
  }
}

.site-header__cta {
  justify-self: end;
}

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-right: -0.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.nav-toggle:hover {
  background: var(--surface);
}

.nav-toggle__close,
.nav-toggle[aria-expanded="true"] .nav-toggle__open {
  display: none;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__close {
  display: block;
}

.mobile-menu {
  border-top: 1px solid var(--border);
  background: var(--white);
  box-shadow: 0 16px 24px -16px rgba(16, 42, 67, 0.35);
  max-height: calc(100vh - var(--header-height));
  overflow-y: auto;
}

.mobile-menu__list {
  margin: 0;
  padding: 0.25rem 0 0;
  list-style: none;
}

.mobile-menu__link {
  display: block;
  padding: 0.875rem 0;
  border-bottom: 1px solid var(--border);
  color: var(--ink);
  font-size: 1.0625rem;
  font-weight: 700;
  text-decoration: none;
}

/* The current page is marked by more than colour: an underline as well. */
.mobile-menu__link[aria-current] {
  color: var(--teal-text);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}

.mobile-menu__cta {
  margin: 1.25rem 0 1.5rem;
}

@media (min-width: 60em) {
  .mobile-menu {
    display: none !important;
  }
}

@media (max-width: 59.99875em) {
  .site-header__inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
  }

  .brand {
    font-size: 1.75rem;
  }

  /* With JavaScript: brand + menu button. Without it: the links wrap under the brand. */
  .js .site-nav,
  .js .site-header__cta {
    display: none;
  }

  .js .nav-toggle {
    display: inline-flex;
  }

  .no-js .site-header__inner {
    padding-block: 0.75rem;
  }

  .no-js .site-header__cta {
    display: none;
  }

  .no-js .site-nav {
    width: 100%;
  }

  .no-js .site-nav__list {
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
  }
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--navy);
  color: var(--muted-on-dark);
  font-size: var(--fs-small);
}

.site-footer a {
  color: var(--muted-on-dark);
  text-decoration: none;
}

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

.site-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 0.8fr);
  gap: 2rem;
  padding-top: 2.375rem;
}

.site-footer a.site-footer__brand {
  color: var(--white);
  font-size: 1.875rem;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
}

.site-footer__tagline {
  margin-top: 0.375rem;
  text-wrap: balance;
}

.site-footer__heading {
  color: var(--white);
  font-size: 1rem;
  letter-spacing: 0;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  margin: 0.875rem 0 0;
  padding: 0;
  list-style: none;
}

/* The "|" follows each link, so a wrapped line never starts with it; screen readers skip it. */
.site-footer__links li:not(:last-child)::after {
  content: "|";
  content: "|" / "";
  margin: 0 0.625rem;
}

.site-footer__contact {
  margin: 0.875rem 0 0;
  padding: 0;
  list-style: none;
  overflow-wrap: anywhere; /* long email addresses must not widen the page */
}

.site-footer__pending {
  margin-top: 0.875rem;
  text-wrap: balance;
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  margin-top: 2.75rem;
  padding-block: 1.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 0.875rem;
}

/* Tablets: the brand on its own row, the two link columns below it, so no column gets too narrow. */
@media (min-width: 48em) and (max-width: 59.99875em) {
  .site-footer__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .site-footer__about {
    grid-column: 1 / -1;
  }
}

@media (max-width: 47.99875em) {
  .site-footer__grid {
    grid-template-columns: 1fr;
    gap: 1.75rem;
    padding-top: 2.5rem;
  }

  .site-footer__bottom {
    margin-top: 2rem;
  }
}

/* ---- components.css ---- */
/* Shared components: eyebrow, buttons, page intro, card, breadcrumb, panel. */

/* ---------- Eyebrow ---------- */
.eyebrow {
  color: var(--teal-text);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.3;
  text-transform: uppercase;
}

.eyebrow--light {
  color: var(--teal-on-dark);
}

/* ---------- Buttons ---------- */
/* Labels sit on the left of a fixed-minimum-width button, as in the design. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.5rem;
  min-height: 3.25rem;
  min-width: 13rem;
  padding: 0.75rem 1.375rem;
  border: 0;
  border-radius: var(--radius);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.btn--primary {
  background: var(--teal);
  color: var(--white);
}

.btn--primary:hover {
  background: var(--teal-hover);
  color: var(--white);
}

.btn--secondary {
  background: var(--surface);
  color: var(--teal-text);
}

.btn--secondary:hover {
  background: var(--surface-hover);
  color: var(--navy);
}

.btn--block {
  display: flex;
  width: 100%;
  min-width: 0;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

@media (max-width: 39.99875em) {
  .btn-row .btn {
    flex: 1 1 100%;
  }
}

/* Windows contrast themes drop background colours, which are a button's only edge here; a border in
   the forced text colour keeps buttons and button-styled links recognisable. */
@media (forced-colors: active) {
  .btn {
    border: 1px solid;
  }
}

/* ---------- Page intro (top of inner pages) ---------- */
.page-intro {
  padding-block: clamp(2.25rem, 1.5rem + 2vw, 2.75rem) clamp(2.25rem, 1.5rem + 2.5vw, 3.25rem);
}

.page-intro--light {
  background: var(--surface);
  padding-block: clamp(2.5rem, 1.5rem + 3vw, 3.75rem);
}

.page-intro--dark {
  background: var(--navy);
  padding-block: clamp(2.5rem, 1.5rem + 3vw, 3.5rem);
}

.page-intro__title {
  margin-top: clamp(1.25rem, 0.9375rem + 1.25vw, 1.875rem);
  text-wrap: balance; /* avoids a single word on the last line, where supported */
  font-size: var(--fs-display);
  max-width: 24ch;
}

.page-intro__inner > .page-intro__title:first-child {
  margin-top: 0;
}

.page-intro--dark .page-intro__title {
  color: var(--white);
}

.page-intro__lead {
  margin-top: 1rem;
  font-size: var(--fs-md);
  max-width: 52rem;
}

.page-intro--dark .page-intro__lead {
  color: var(--text-on-dark);
}

/* ---------- Card with photo ---------- */
.card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface);
}

.card__media {
  display: block;
  aspect-ratio: 252 / 139;
  overflow: hidden;
  background: var(--surface-hover);
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.35s ease;
}

.card:hover .card__media img {
  transform: scale(1.03);
}

/* Spacing as drawn in the design: 247pt-tall cards with the label, name, summary and link close together. */
.card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  padding: 1rem 1.25rem 0.8125rem;
}

.card__eyebrow {
  color: var(--teal-text);
  font-size: var(--fs-2xs);
  font-weight: 700;
  line-height: 1.3;
  text-transform: uppercase;
}

.card__title {
  margin-top: 0.8125rem;
  font-size: var(--fs-h3);
  line-height: var(--lh-snug);
}

.card__link {
  color: inherit;
  text-decoration: none;
}

.card__link:hover {
  color: var(--teal-text);
  text-decoration: underline;
}

.card__text {
  margin-top: 0.125rem;
  font-size: var(--fs-small);
}

.card__cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: auto;
  padding-top: 0.8125rem;
  color: var(--teal-text);
  font-size: var(--fs-small);
  font-weight: 700;
  text-decoration: none;
}

.card__cta:hover {
  color: var(--navy);
  text-decoration: underline;
}

/* Extends the tap area 8px into the card's bottom padding (to 44px) without moving anything. */
.card__cta::after {
  content: "";
  position: absolute;
  inset: 0 0 -0.5rem;
}

/* Keeps the focus ring clear of the summary line above it and inside the card's rounded edge. */
.card__cta:focus-visible {
  outline-offset: 0;
}

.card__cta .icon {
  transition: transform 0.15s ease;
}

.card__cta:hover .icon {
  transform: translateX(2px);
}

/* ---------- Breadcrumb ---------- */
.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--text);
  font-size: var(--fs-small);
}

/* The "/" follows each item, so a wrapped line never starts with it; screen readers skip it
   (browsers without the alternative-text syntax use the first declaration). */
.breadcrumb__item:not(:last-child)::after {
  content: "/";
  content: "/" / "";
  margin: 0 0.625rem;
}

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

.breadcrumb a:hover {
  color: var(--teal-text);
  text-decoration: underline;
}

/* ---------- Panel ---------- */
.panel {
  padding: 1.5rem;
  border-radius: var(--radius);
  background: var(--surface);
}

/* ---- pages/about.css ---- */
/* About Us page (design: PDF page 2). Desktop sizes come from the design: PDF points x 1.333 = CSS pixels.
   Page styles load after the shared ones, so the about-* rules below can adjust shared defaults (.panel, .btn). */

/* Keeps a hyphenated word on one line (see about.mjs). */
.about-nowrap {
  white-space: nowrap;
}

/* ---------- Intro band ---------- */
/* The design puts the label nearer the top of the band than the shared intro does (40px)
   and leaves more room between the label and the title (30px). */
.page-about .page-intro {
  padding-top: clamp(2rem, 1.6rem + 1vw, 2.5rem);
}

.page-about .page-intro__title {
  max-width: none; /* the line break in the title sets the measure */
}

/* Phones: let the title wrap naturally instead of after "builds". */
@media (max-width: 39.99875em) {
  .about-intro__break {
    display: none;
  }
}

/* ---------- Photo and text ---------- */
.about-story {
  padding-block: clamp(2.5rem, 2rem + 1.25vw, 3.0625rem) clamp(2.75rem, 2rem + 2vw, 3.5rem);
}

.about-story__grid {
  display: grid;
  gap: clamp(1.5rem, 1rem + 1.5vw, 2rem);
}

.about-story__photo {
  width: 100%;
  aspect-ratio: 395 / 280; /* photo box in the design */
  object-fit: cover;
  border-radius: var(--radius);
}

.about-story__title {
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); /* 24-32px */
}

.about-story__lead {
  margin-top: 1.375rem;
  font-size: var(--fs-lead);
  line-height: 1.5;
}

.about-story__text {
  margin-top: clamp(1.25rem, 0.75rem + 1.5vw, 2.0625rem);
  font-size: clamp(1rem, 0.9rem + 0.4vw, 1.1875rem); /* 16-19px */
  line-height: 1.5;
}

/* Photo on the left, text on the right, both aligned to the top. */
@media (min-width: 60em) {
  .about-story__grid {
    grid-template-columns: minmax(0, 395fr) minmax(0, 390fr); /* photo and text column widths in the design */
    align-items: start;
    column-gap: 3.75rem;
  }

  /* In the design the heading starts a little below the top edge of the photo. */
  .about-story__body {
    padding-top: 0.625rem;
  }
}

/* ---------- Values ---------- */
.about-values {
  padding-bottom: clamp(2.5rem, 2rem + 1.25vw, 3.125rem);
}

.about-values__list {
  display: grid;
  gap: 1.25rem;
  margin: clamp(1.25rem, 0.9375rem + 1.25vw, 1.875rem) 0 0;
  padding: 0;
  list-style: none; /* role="list" in the markup keeps the list semantics in Safari */
}

.about-value {
  padding: 1.75rem 1.5rem;
}

.about-value__title {
  font-size: var(--fs-h3-lg);
}

.about-value__text {
  margin-top: 1.25rem;
  font-size: clamp(1rem, 0.95rem + 0.2vw, 1.0625rem); /* 16-17px: never larger than the story text */
  line-height: 1.5;
}

.about-values__actions {
  margin-top: clamp(2rem, 1.5rem + 1.25vw, 2.5625rem);
}

/* The design's button is wider than the shared minimum. */
.about-values__cta {
  min-width: 16rem;
}

@media (max-width: 39.99875em) {
  .about-value {
    padding: 1.5rem 1.25rem;
  }
}

@media (min-width: 60em) {
  .about-values__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2.0625rem;
  }

  .about-value {
    min-height: 12rem; /* panel height in the design */
  }
}

/* ---------- Stacked layout (tablets and phones) ---------- */
/* Below 960px the photo, the text, the value panels and the button form one column with one right edge.
   The source photo is small, so the column stops at 35rem rather than enlarging the photo further. */
@media (max-width: 59.99875em) {
  .about-story__photo,
  .about-story__body,
  .about-values__list,
  .about-values__actions {
    max-width: 35rem;
  }
}

/* ---- pages/contact.css ---- */
/* Contact / Request a Quote page (design: PDF page 6; phones: PDF page 7, right).
   Desktop sizes come from the design: PDF points x 1.35 = CSS pixels (the 830pt column is the 1120px container).
   Phones and tablets stack the "Business inquiries" panel above the form, in the same order as the markup. */

/* ---------- Intro ---------- */
/* The design's title is larger than other page titles (48px) and sits further below the label. */
.page-contact .page-intro {
  padding-bottom: clamp(2rem, 1rem + 2.75vw, 3.25rem);
}

.page-contact .page-intro__title {
  margin-top: clamp(1.25rem, 0.25rem + 2.5vw, 2.0625rem);
  font-size: clamp(2rem, 1.25rem + 2.4vw, 3rem); /* 32-48px */
}

.page-contact .page-intro__lead {
  margin-top: 0.6875rem;
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.1875rem); /* 17-19px */
  text-wrap: pretty; /* avoids a last line with a single word where supported */
}

/* ---------- Layout ---------- */
.contact-quote {
  padding-bottom: clamp(3rem, 2.5rem + 1.5vw, 3.5rem);
}

.contact-quote__grid {
  display: grid;
  gap: 2.5rem;
}

/* ---------- "Business inquiries" panel ---------- */
.contact-info {
  --value-gap: 0.375rem; /* between a label and its value */
  --link-pad: 0.25rem; /* above and below each contact link, see .contact-info__line */
  padding: 1.75rem 1.25rem 2rem;
  border-radius: var(--radius);
  background: var(--navy);
  color: var(--muted-on-dark);
}

.contact-info__title {
  color: var(--white);
  font-size: 1.5rem;
}

.contact-info__text {
  margin-top: 0.75rem;
  font-size: var(--fs-body);
  line-height: 1.5;
}

.contact-info__list {
  display: grid;
  gap: 1.25rem 2rem;
  margin-top: 1.5rem;
}

.contact-info__label {
  color: var(--white);
  font-size: var(--fs-body);
  font-weight: 700;
  line-height: 1.3;
}

.contact-info__value {
  margin-top: var(--value-gap);
  font-size: var(--fs-small);
  line-height: 1.5;
  white-space: pre-line; /* keeps the line breaks of a multi-line address or opening hours */
  overflow-wrap: anywhere; /* long email addresses wrap instead of overflowing */
}

.contact-info a {
  color: var(--white);
}

.contact-info a:hover {
  color: var(--teal-on-dark);
}

.contact-info a:focus-visible {
  outline-color: var(--teal-on-dark); /* the default teal ring is hard to see on navy */
}

/* The email, phone and WhatsApp links, one per line, with padding that makes them easier to hit
   (30px tall, 44px on touch screens). The negative margins keep the text where it would be without
   the padding, except that the first link stops at its label instead of covering it. */
.contact-info__line {
  display: block;
  padding-block: var(--link-pad);
}

.contact-info__line:first-child {
  margin-top: calc(-1 * min(var(--link-pad), var(--value-gap)));
}

.contact-info__line:last-child {
  margin-bottom: calc(-1 * var(--link-pad));
}

@media (pointer: coarse) {
  .contact-info {
    --link-pad: 0.6875rem;
  }
}

/* ---------- Form ---------- */
.contact-form__note,
.contact-form__consent {
  font-size: 0.84375rem; /* 13.5px */
  line-height: 1.5;
}

.contact-form__note {
  margin-bottom: 1rem;
}

.contact-form__fields {
  display: grid;
  gap: 1.5rem;
}

.contact-field {
  min-width: 0;
}

.contact-field__label {
  display: block;
  margin-bottom: 0.625rem;
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.3;
}

.contact-field__control {
  display: block;
  width: 100%;
  height: 3.625rem;
  margin: 0;
  padding: 0 1rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-size: 1rem; /* 16px or more stops phones from zooming into the field */
  line-height: 1.5;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.contact-field__control::placeholder {
  color: var(--text);
  opacity: 1;
}

.contact-field__control:hover {
  border-color: var(--border-strong);
}

.contact-field__control:focus {
  border-color: var(--border-strong);
  background: var(--white);
}

.contact-field__control[aria-invalid="true"] {
  border-color: var(--error);
  background: var(--error-surface);
}

.contact-field__control--textarea {
  height: 5.625rem; /* the design's box; visitors can drag it taller */
  min-height: 5.625rem;
  padding-block: 1.25rem 0.75rem;
  resize: vertical;
}

/* Select lists: flat like the text fields, with a chevron instead of the browser's arrow. */
.contact-select {
  position: relative;
}

.contact-select__control {
  padding-right: 2.75rem;
  -webkit-appearance: none;
  appearance: none;
  text-overflow: ellipsis;
  cursor: pointer;
}

/* Until a choice is made, "Select a ..." looks like the text fields' placeholders. */
.contact-select__control:invalid,
.contact-select__control option[value=""] {
  color: var(--text);
}

.contact-select__control option {
  color: var(--ink);
}

.contact-select .icon {
  position: absolute;
  top: 50%;
  right: 1.125rem;
  color: var(--ink);
  transform: translateY(-50%) rotate(90deg);
  pointer-events: none;
}

/* Error message under a field (added by quote-form.js). */
.contact-field__error {
  display: flex;
  gap: 0.375rem;
  margin-top: 0.5rem;
  color: var(--error);
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.4;
}

.contact-field__error .icon {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.0625rem;
}

/* Spam trap: out of sight, out of the tab order (tabindex="-1") and hidden from screen readers (aria-hidden). */
.contact-form__trap {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.contact-form__consent {
  margin-top: 1rem;
}

.contact-form__consent a {
  color: inherit;
  /* On Shift+Tab, keeps the message field above this link clear of the sticky header
     (header, 1rem gap, the 5.625rem field and the 1rem above the consent line). */
  scroll-margin-top: calc(var(--header-height) + 1rem + 5.625rem + 1rem);
}

.contact-form__consent a:hover {
  color: var(--ink);
}

.contact-form__submit {
  width: 100%;
  margin-top: 1.75rem;
}

/* While the inquiry is being sent (quote-form.js). */
.contact-form__submit[aria-disabled="true"] {
  background: var(--teal-hover);
  cursor: progress;
}

/* Messages from quote-form.js. Empty, the area takes no space but stays in place for screen readers. */
.contact-form__status:not(:empty) {
  display: flex;
  gap: 0.625rem;
  margin-top: 1.25rem;
  padding: 0.875rem 1rem;
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-small);
  line-height: 1.5;
}

.contact-form__status--error:not(:empty) {
  background: var(--error-surface);
  color: var(--error);
  font-weight: 700;
}

.contact-form__status .icon,
.contact-success .icon {
  margin-top: 0.0625rem;
}

/* Replaces the form once the inquiry has been sent. */
.contact-success {
  display: flex;
  gap: 0.75rem;
  padding: 1.5rem;
  border-radius: var(--radius);
  background: var(--success-surface);
  color: var(--ink);
  font-size: var(--fs-md);
  line-height: 1.5;
}

.contact-success .icon {
  color: var(--success);
}

/* ---------- Tablets: the details in two columns, two fields per row ---------- */
@media (min-width: 40em) {
  .contact-info {
    padding: 2rem 1.75rem 2.25rem;
  }

  .contact-info__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Two columns, each at least half the form or 16rem: with enlarged text the fields drop to one
     column instead of cutting off their text. At the default size this is always two columns. */
  .contact-form__fields {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(16rem, (100% - 2.125rem) / 2)), 1fr));
    gap: 2rem 2.125rem;
  }

  .contact-field--wide {
    grid-column: 1 / -1;
  }

  .contact-form__submit {
    width: auto;
    min-width: 15.625rem; /* the design's 250px button */
    margin-top: 2.5rem;
  }
}

/* ---------- Desktop: panel on the left, form on the right ---------- */
@media (min-width: 60em) {
  .contact-quote {
    padding-bottom: 2.25rem;
  }

  .contact-quote__grid {
    grid-template-columns: minmax(0, 250fr) minmax(0, 545fr); /* column widths in the design */
    align-items: start;
    column-gap: 2.9375rem;
  }

  /* As in the design, the panel reaches down to the privacy line under the message field
     (772px in the design, plus the height of the required-fields note above the form). */
  .contact-info {
    --value-gap: 0.875rem;
    min-height: 50.125rem;
    padding: 2.5rem 1.6875rem;
  }

  /* 28px as in the design; a little smaller on narrow desktops so the heading stays on one line. */
  .contact-info__title {
    font-size: clamp(1.5rem, 0.5rem + 1.6vw, 1.75rem);
  }

  .contact-info__text {
    margin-top: 1.5rem;
    font-size: 1.09375rem; /* 17.5px */
  }

  /* One detail under the other, widely spaced as in the design. */
  .contact-info__list {
    grid-template-columns: minmax(0, 1fr);
    gap: 3.5rem;
    margin-top: 5.4375rem;
  }

  .contact-form__fields {
    row-gap: 2.28125rem; /* 36.5px: rows 124px apart, as in the design */
  }
}

/* The design's 15px field text, on screens with a mouse (touch screens keep 16px, see above). */
@media (min-width: 60em) and (hover: hover) and (pointer: fine) {
  .contact-field__control {
    font-size: 0.9375rem;
  }
}

/* ---- pages/home.css ---- */
/* Home page (index.html). Desktop sizes follow PDF page 1 (points x 1.333 = px);
   the phone layout follows the left phone on PDF page 7. */

/* ---------- Hero: navy text panel with a full-height photo on the right ---------- */
.home-hero {
  display: flex;
  background: var(--navy);
}

.home-hero__body {
  flex: 1 1 56%;
  min-width: 0;
  /* The left padding puts the text on the .container edge (the header logo's left edge).
     Percentages on a flex item resolve against the hero, which is as wide as the page. */
  padding: 2.25rem 1.5rem 1.875rem max(var(--gutter), (100% - var(--container)) / 2);
}

.home-hero__title {
  margin-top: 2.5rem;
  color: var(--white);
  /* var(--fs-hero), except below about 390px where it follows the screen width so the longest line
     ("in Industrial Chemicals", about 11em) still fits; never smaller than the 26px section titles. */
  font-size: clamp(1.625rem, (100vw - 2 * var(--gutter)) / 11.25, var(--fs-hero));
  line-height: 1.24;
}

/* Keeps the design's line breaks: "Your Trusted Partner / in Industrial Chemicals / & Bulk Supplies". */
.home-hero__line {
  display: block;
}

.home-hero__lead {
  max-width: 34rem;
  margin-top: 0.75rem;
  color: var(--text-on-dark);
  font-size: var(--fs-md);
}

.home-hero__actions {
  gap: 1.25rem;
  margin-top: 3.25rem;
}

.home-hero__actions .btn {
  min-width: 14.25rem;
}

/* The photo is small (about 370px wide), so on very wide screens it stops growing at 40rem
   and the navy panel takes the extra width. */
.home-hero__media {
  position: relative;
  flex: 0 1 44%;
  min-width: 0;
  max-width: 40rem;
  background: var(--surface-hover);
}

.home-hero__image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Tablets: a narrower photo leaves room for the three heading lines. */
@media (max-width: 59.99875em) {
  .home-hero__body {
    flex-basis: 62%;
  }

  .home-hero__media {
    flex-basis: 38%;
  }
}

/* Phones and small tablets: a navy block with the text only, as in the mobile design.
   The photo is left out: there is no room beside the heading, a full-width band would blow the
   small photo up to twice its size, and the first category card just below shows the same picture. */
@media (max-width: 47.99875em) {
  .home-hero {
    display: block;
  }

  .home-hero__body {
    padding: 2rem var(--gutter) 3rem;
  }

  .home-hero__media {
    display: none;
  }
}

@media (max-width: 39.99875em) {
  .home-hero__title {
    margin-top: 2rem;
  }

  .home-hero__lead {
    margin-top: 1rem;
  }

  .home-hero__actions {
    gap: 0.75rem;
    margin-top: 2.5rem;
  }
}

/* ---------- Portfolio: category cards and highlights ---------- */
.home-portfolio {
  padding-block: 2.25rem 3.25rem;
}

.home-portfolio__lead {
  margin-top: 0.5rem;
}

.home-categories {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* 48px as in the design from 1200px up, narrowing evenly to 24px at 1024px so the card titles stay on one line. */
  gap: clamp(1.5rem, 13.64vw - 7.23rem, 3rem);
  margin: 2.25rem 0 0;
  padding: 0;
  list-style: none;
}

/* The list item stretches to the row height; the card fills it so all cards line up. */
.home-categories__item {
  display: flex;
  min-width: 0;
}

.home-categories__item > .card {
  flex: 1;
}

.home-highlights {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
  margin: 2.0625rem 0 0;
  padding: 1.5rem 1.6875rem 2.25rem;
  border-radius: var(--radius);
  background: var(--surface);
  list-style: none;
}

.home-highlights__title {
  display: block;
  color: var(--ink);
  font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.5625rem);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
}

.home-highlights__text {
  display: block;
  margin-top: 0.6875rem;
}

/* Small tablets (640-767px) */
@media (min-width: 40em) and (max-width: 47.99875em) {
  /* Two cards per row. The grid has four tracks and each card spans two, so a last card left alone
     on its row moves to the middle two tracks: centred and exactly as wide as the others. */
  .home-categories {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .home-categories__item {
    grid-column: span 2;
  }

  .home-categories__item:last-child:nth-child(odd) {
    grid-column: 2 / span 2;
  }

  /* Tighter inner spacing keeps "Diverse Portfolio" and "Across three categories" on one line down to 640px. */
  .home-highlights {
    column-gap: 1rem;
    padding-inline: 1.25rem;
  }
}

@media (max-width: 39.99875em) {
  .home-categories {
    grid-template-columns: minmax(0, 1fr);
  }

  .home-highlights {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
    padding: 1.5rem 1.25rem;
  }
}

/* ---- pages/industries.css ---- */
/* Industries page (industries.html). Desktop sizes follow PDF page 5 (points x 1.35 = px, so the
   830pt content column is the 1120px container). How the edited design page was interpreted is
   explained at the top of src/pages/industries.mjs. */

/* ---------- Intro band ---------- */
/* Positions as drawn: the label baseline 57px below the top of the band, title lines 59px apart,
   the lead 40px under the title and a 292px band at desktop widths. */
.industries-intro {
  padding-top: clamp(2rem, 1.625rem + 1.5vw, 2.75rem);
  padding-bottom: clamp(2rem, 1.85rem + 0.62vw, 2.3125rem);
}

.industries-intro .page-intro__title {
  margin-top: clamp(1.5rem, 1rem + 2.1vw, 2.5625rem);
  line-height: 1.29;
}

.industries-intro .page-intro__lead {
  margin-top: 0.5rem;
}

/* ---------- Segment cards ---------- */
/* Spacing between sections reaches the design's values (46px above the cards, 94px between the
   cards and the wholesale band, 77px above the footer) at 1200px, where the container is full width. */
.industries-segments {
  padding-top: clamp(2rem, 1.58rem + 1.73vw, 2.875rem);
}

.industries-cards {
  display: grid;
  gap: 1.6875rem; /* 27px between cards, as in the design */
  margin: 0;
  padding: 0;
  list-style: none; /* role="list" in the markup keeps the list semantics in Safari */
}

/* Photo on the left in a portrait box (182 x 227px in the design), text on the right.
   On narrow cards the photo takes a third of the width, as in the design. */
.industries-card {
  position: relative; /* anchors the stretched link below */
  display: grid;
  grid-template-columns: min(33.333%, 11.375rem) minmax(0, 1fr);
  border-radius: var(--radius);
  background: var(--surface);
  transition: background-color 0.15s ease;
}

/* The design's 135:168 ratio sets the smallest card height (227px beside a 182px photo);
   the box stretches when the text needs more room. Stretching in both directions keeps the
   column width (with the ratio alone, a taller card would widen the photo). */
.industries-card__media {
  position: relative;
  place-self: stretch;
  aspect-ratio: 135 / 168;
  overflow: hidden;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--surface-hover);
}

/* Positioned so the photo fills the box at any card height without setting that height itself. */
.industries-card__media img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.35s ease;
}

.industries-card__body {
  min-width: 0;
  padding: 1.5rem 1.375rem 1.375rem;
}

.industries-card__title {
  font-size: 1.4375rem;
  line-height: var(--lh-snug);
}

.industries-card__text {
  margin-top: 1.8125rem;
  font-size: var(--fs-md);
  line-height: 1.5;
}

.industries-card__link {
  color: inherit;
  text-decoration: none;
  /* The browser scrolls a focused link only into the viewport, so with Shift+Tab a card could
     stop under the sticky header. This keeps the whole card and its focus ring clear of the
     header: 3rem covers the card's top padding, the ring and a 1rem gap. */
  scroll-margin-top: calc(var(--header-height) + 3rem);
}

/* Stretched link: the title link covers the whole card, so the photo and text are clickable too. */
.industries-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
}

/* Keyboard focus: the ring goes around the whole card (the area the link covers) instead of
   around the title text, with the same style as the global :focus-visible outline. */
.industries-card__link:focus-visible {
  outline: none;
}

.industries-card__link:focus-visible::after {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.industries-card:hover {
  background: var(--surface-hover);
}

.industries-card:hover .industries-card__link {
  color: var(--teal-text);
  text-decoration: underline;
}

.industries-card:hover .industries-card__media img {
  transform: scale(1.03);
}

/* Wide screens: the three cards side by side once the container's content is 70rem wide (1120px at
   the default text size, from a 1200px window). Narrower, or with enlarged text, a third of the row
   leaves too little room beside the photo, so the cards stack. */
.industries-segments > .container {
  container-type: inline-size;
}

@container (min-width: 70rem) {
  .industries-cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---------- Wholesale band ---------- */
.industries-wholesale {
  padding-top: clamp(3rem, 1.6rem + 5.7vw, 5.875rem);
  padding-bottom: clamp(3.5rem, 2.87rem + 2.6vw, 4.8125rem);
}

/* The text sits near the top of the 142px band and the button is centred vertically, as drawn. */
.industries-wholesale__panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem 2rem;
  min-height: 8.875rem;
  padding: 0 1.75rem 0 1.6875rem;
  border-radius: var(--radius);
  background: var(--surface);
}

.industries-wholesale__body {
  align-self: flex-start;
  min-width: 0;
  padding-block: 1.4375rem;
}

.industries-wholesale__title {
  font-size: clamp(1.625rem, 1.475rem + 0.62vw, 1.9375rem); /* 26-31px */
}

.industries-wholesale__text {
  margin-top: 0.6875rem;
  font-size: var(--fs-md);
  text-wrap: pretty; /* avoids a lone "KISWA." on the last line where the text wraps */
}

/* The design's button is a little narrower than the shared minimum. Like the card links, it
   stays clear of the sticky header when it receives focus. */
.industries-wholesale__cta {
  flex: none;
  min-width: 12.5625rem;
  scroll-margin-top: calc(var(--header-height) + 1rem);
}

/* ---------- Phones ---------- */
@media (max-width: 39.99875em) {
  .industries-cards {
    gap: 1rem;
  }

  .industries-card__body {
    padding: 1.25rem 1.125rem 1.375rem;
  }

  .industries-card__title {
    font-size: 1.25rem;
  }

  .industries-card__text {
    margin-top: 0.875rem;
    font-size: var(--fs-body);
  }

  /* The button goes under the text at full width. */
  .industries-wholesale__panel {
    flex-direction: column;
    align-items: stretch;
    padding: 1.5rem 1.25rem;
  }

  .industries-wholesale__body {
    align-self: auto;
    padding-block: 0;
  }

  .industries-wholesale__cta {
    min-width: 0;
  }
}

/* Very narrow phones: the photo goes on top (in the photo box of the site's other cards)
   so the text keeps a readable line length. */
@media (max-width: 22.49875em) {
  .industries-card {
    grid-template-columns: minmax(0, 1fr);
  }

  .industries-card__media {
    aspect-ratio: 252 / 139;
    border-radius: var(--radius) var(--radius) 0 0;
  }

  /* The photo is now above the title, so the focus scroll margin also clears its height
     (the card spans the container: the viewport width minus the gutters). */
  .industries-card__link {
    scroll-margin-top: calc(var(--header-height) + 3rem + (100vw - 2 * var(--gutter)) * 139 / 252);
  }
}

/* ---- pages/legal.css ---- */
/* Privacy Policy (.page-legal) and Not Found (.page-error): short pages with a title and a little content. */

/* Keep the footer at the bottom of the window even though these pages are short. */
.page-legal,
.page-error {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh; /* excludes the mobile browser bars where supported */
}

.page-legal main,
.page-error main {
  flex: 1 0 auto;
}

/* The content follows the title directly, so the intro needs no bottom padding of its own. */
.page-legal .page-intro,
.page-error .page-intro {
  padding-bottom: 0;
}

/* ---------- Privacy Policy ---------- */
.legal-body {
  padding-block: clamp(1.25rem, 0.75rem + 1.5vw, 1.75rem) var(--section-space);
}

.legal-body__text {
  max-width: 46rem;
  font-size: var(--fs-md);
}

.legal-body__text p + p {
  margin-top: 1rem;
}

/* ---------- Not Found ---------- */
.error-actions {
  padding-block: clamp(1.75rem, 1.25rem + 1.5vw, 2.25rem) var(--section-space);
}

/* ---- pages/product.css ---- */
/* Product detail pages (products/<slug>.html). Design: PDF page 4 (Cumin).
   Desktop sizes are the design's points x 1.35, the scale at which the 830pt design column
   fills the 1120px container. Vertical spacing is set so text baselines land where the design has them. */

.product-page {
  padding-top: clamp(1.25rem, 1rem + 1vw, 1.75rem);
  padding-bottom: clamp(3.5rem, 2rem + 4.5vw, 5.25rem);
}

/* ---------- Summary: photo beside name, description, information panel and button ---------- */
.product-summary {
  display: grid;
  /* 400pt photo, 40pt gap, 390pt text column, as in the design */
  grid-template-columns: minmax(0, 400fr) minmax(0, 390fr);
  column-gap: 4.82%;
  align-items: start;
  margin-top: clamp(1.5rem, 0.75rem + 2.75vw, 2.75rem);
}

.product-summary__image {
  width: 100%;
  aspect-ratio: 400 / 346;
  object-fit: cover;
  background: var(--surface);
}

/* Sets the category label just below the top edge of the photo. */
.product-summary__body {
  padding-top: 0.5625rem;
}

.product-summary__title {
  margin-top: 2.3125rem;
  font-size: clamp(2.25rem, 1.6rem + 2.4vw, 3.4375rem); /* 36-55px */
}

.product-summary__lead {
  margin-top: 1.1875rem;
  max-width: 30rem;
  font-size: var(--fs-lead);
  line-height: 1.5;
  text-wrap: pretty; /* avoids a lone last word with longer product names */
}

.product-info {
  margin-top: 3.125rem;
  padding: 1.1875rem 1.5rem 1.0625rem;
}

.product-info__title {
  font-size: 1rem;
  line-height: var(--lh-body);
  letter-spacing: 0;
}

.product-info p {
  margin-top: 0.8125rem;
}

.product-summary__cta {
  margin-top: 2.125rem;
  min-width: 17.5rem;
}

/* Tablets and phones: photo first, then the text. The page becomes one 540px column with one right
   edge (as on About), narrow enough that the photo is not shown much larger than its natural size. */
@media (max-width: 59.99875em) {
  .product-summary {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 1.75rem;
    max-width: 33.75rem;
  }

  .product-summary__body {
    padding-top: 0;
  }

  .product-summary__title {
    margin-top: 0.75rem;
  }

  .product-summary__lead {
    margin-top: 1rem;
  }

  .product-info {
    margin-top: 1.75rem;
  }

  .product-summary__cta {
    margin-top: 1.5rem;
  }
}

@media (max-width: 39.99875em) {
  .product-summary__cta {
    display: flex;
    width: 100%;
    min-width: 0;
  }
}

/* ---------- How an inquiry works ---------- */
.product-process {
  margin-top: clamp(3rem, 2rem + 2.6vw, 4.25rem);
}

.product-process__lead {
  margin-top: 0.8125rem;
  max-width: 66rem;
  font-size: var(--fs-lead);
  line-height: 1.5;
  text-wrap: pretty;
}

.product-steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 0.2rem + 2.2vw, 2.125rem);
  margin-top: 2.3125rem;
  padding: 0;
  list-style: none;
}

.product-step {
  padding: 2.0625rem 1.375rem 2.125rem;
  border-radius: var(--radius);
  background: var(--surface);
}

.product-step__title {
  font-size: var(--fs-h3);
}

.product-step__text {
  margin-top: 1.375rem;
  font-size: var(--fs-md);
  text-wrap: pretty;
}

/* Below 960px the steps stack and the rest of the page keeps the 540px column of the summary. */
@media (max-width: 59.99875em) {
  .product-process,
  .product-related {
    max-width: 33.75rem;
  }

  .product-steps {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    margin-top: 1.75rem;
  }

  .product-step {
    padding: 1.5rem 1.375rem 1.625rem;
  }

  .product-step__text {
    margin-top: 0.75rem;
  }
}

/* ---------- Related products ---------- */
.product-related {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.3em;
  margin-top: clamp(2.5rem, 1.5rem + 3.5vw, 4.3125rem);
  color: var(--teal-text);
  font-size: var(--fs-md);
  font-weight: 700;
}

.product-related__list {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* "|" between the links. The second declaration gives it empty alternative text so screen
   readers skip it; browsers without that syntax keep the first one. */
.product-related__list li:not(:last-child)::after {
  content: "|";
  content: "|" / "";
  margin-inline: 0.55em;
}

.product-related a {
  color: inherit;
  text-decoration: none;
}

.product-related a:hover {
  color: var(--navy);
  text-decoration: underline;
}

/* Touch screens and the stacked layouts: tap targets of at least 44x44px. An invisible layer
   around each link enlarges the area that responds to a tap: the 19px-tall text box plus
   2 x 0.75em is 44.5px, and "Yarn" becomes 45px wide. The layout and the focus outline stay as
   they are. When the links wrap onto a second row, the row gap keeps the rows 45px apart so
   neighbouring tap areas never overlap. */
@media (max-width: 59.99875em), (pointer: coarse) {
  .product-related__list {
    row-gap: 1.1em;
  }

  .product-related a {
    position: relative;
  }

  .product-related a::before {
    content: "";
    position: absolute;
    inset: -0.75em -0.25em;
  }
}

/* ---- pages/products.css ---- */
/* Products page (products.html): search, category filters and the product grid.
   Behaviour lives in src/scripts/products.js. Sizes follow PDF page 3 (points x 1.333 = px);
   phones follow the middle phone on PDF page 7. */

/* ---------- Intro ---------- */
/* A smaller one-line title (29pt). The search field follows straight after the intro, so the
   catalogue section sets the space between them. */
.products-intro {
  padding-bottom: 0;
}

.products-intro .page-intro__title {
  max-width: none;
  margin-top: 1.6875rem;
  font-size: clamp(1.875rem, 1.6rem + 1vw, 2.4375rem);
}

/* ---------- Catalogue ---------- */
.products-catalogue {
  padding-top: clamp(1.75rem, 1.25rem + 1.5vw, 2.375rem);
  padding-bottom: clamp(2.5rem, 1.5rem + 2.5vw, 3.75rem);
}

/* Searching and filtering need JavaScript; without it every product is simply listed. */
.no-js .products-tools {
  display: none;
}

.no-js .products-results {
  margin-top: 0;
}

/* ---------- Search field ---------- */
.products-search {
  position: relative;
}

.products-search__input {
  display: block;
  width: 100%;
  min-height: 4.0625rem;
  padding: 0.5rem 4.5rem 0.5rem 1.4375rem;
  border: 1px solid transparent; /* becomes visible in Windows high contrast mode */
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-size: 1.1875rem;
  line-height: 1.3;
  -webkit-appearance: none;
  appearance: none;
}

.products-search__input::placeholder {
  color: var(--text);
  opacity: 1;
}

.products-search__input::-webkit-search-decoration {
  -webkit-appearance: none;
}

.products-search .icon {
  position: absolute;
  top: 50%;
  right: 2.25rem;
  color: var(--teal-text);
  transform: translateY(-50%);
  pointer-events: none;
}

@media (max-width: 39.99875em) {
  .products-search__input {
    min-height: 3.25rem;
    padding-right: 3.5rem;
    padding-left: 1.0625rem;
    font-size: 1rem;
  }

  .products-search .icon {
    right: 1.125rem;
  }
}

/* ---------- Category filters ---------- */
/* Built on .btn (bold left-aligned labels, 52px tall): pressed = teal, the others light grey.
   Desktop: one row sized like the design. 768-1023px: one compact row. 520-767px: two equal
   filters per row. Phones: the filters share each row and fill it (two per row on most
   phones, one per row on the narrowest). */
.products-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.0625rem;
  margin-top: 1.4375rem;
}

.products-filter {
  min-width: 9.625rem;
  padding-right: 4rem;
  background: var(--surface);
  color: var(--teal-text);
}

.products-filter:hover {
  background: var(--surface-hover);
  color: var(--navy);
}

.products-filter[aria-pressed="true"] {
  background: var(--teal);
  color: var(--white);
}

.products-filter[aria-pressed="true"]:hover {
  background: var(--teal-hover);
  color: var(--white);
}

@media (max-width: 63.99875em) {
  .products-filters {
    gap: 0.625rem;
  }

  .products-filter {
    min-width: 0;
    padding-inline: 1rem;
  }
}

@media (max-width: 47.99875em) {
  .products-filters {
    gap: 0.5rem;
  }
}

@media (min-width: 32.5em) and (max-width: 47.99875em) {
  .products-filters {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 32.49875em) {
  .products-filter {
    flex: 1 1 auto;
    font-size: 0.9375rem;
  }
}

/* Windows high contrast mode replaces the colours that mark the pressed filter. */
@media (forced-colors: active) {
  .products-filter {
    border: 1px solid ButtonText;
  }

  .products-filter[aria-pressed="true"] {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }
}

/* ---------- Results line and grid ---------- */
.products-results {
  margin-top: 1rem;
  font-size: 0.875rem;
  line-height: 1.4;
  overflow-wrap: anywhere; /* repeats the visitor's query, which may be one long word */
}

.products-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  margin-top: 0.5rem;
}

/* Two columns from 520px, so small tablets do not get one screen-wide card at a time. */
@media (min-width: 32.5em) {
  .products-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.75rem;
  }
}

/* Desktop: three columns (cards 252pt wide, 37pt apart across and 22pt down). */
@media (min-width: 60em) {
  .products-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.875rem clamp(2rem, -0.357rem + 4.643vw, 3.125rem);
  }
}

/* ---------- Product cards ---------- */
/* Phones, as in the mobile design: a taller photo, the product name with its category under
   it (visual order only; the markup stays shared) and a full-width teal "Enquire Now" button. */
@media (max-width: 39.99875em) {
  .products-card .card__media {
    aspect-ratio: 4 / 3;
  }

  .products-card .card__body {
    padding: 1rem 1.25rem 1.25rem;
  }

  .products-card .card__title {
    order: -1;
    margin-top: 0;
  }

  .products-card .card__eyebrow,
  .products-card .card__text {
    margin-top: 0.375rem;
  }

  /* Keeps the gap above the button; the button's auto margin lines buttons up across a row. */
  .products-card .card__text {
    margin-bottom: 1.25rem;
  }

  .products-card .card__cta {
    align-self: stretch;
    min-height: 3.25rem;
    margin-top: auto;
    padding: 0.75rem 1.375rem;
    border-radius: var(--radius);
    background: var(--teal);
    color: var(--white);
    font-size: 1rem;
  }

  .products-card .card__cta:hover {
    background: var(--teal-hover);
    color: var(--white);
    text-decoration: none;
  }

  .products-card .card__cta .icon {
    display: none;
  }

  /* The button is already 52px tall, so it needs no extra tap area below it. */
  .products-card .card__cta::after {
    content: none;
  }

  /* The shared ring sits flush (offset 0); on a teal button it needs a gap to be visible. */
  .products-card .card__cta:focus-visible {
    outline-offset: 2px;
  }
}

/* ---------- Nothing found ---------- */
.products-empty {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-top: 0.5rem;
  padding: 1.75rem 2rem;
}

.products-empty__text {
  color: var(--ink);
  font-size: var(--fs-md);
  font-weight: 700;
}

@media (max-width: 39.99875em) {
  .products-empty {
    padding: 1.5rem;
  }

  .products-empty__reset {
    flex: 1 1 100%;
  }
}
