/* =====================================================================
   Eurobond 3 Dimensions: landing page
   Brand blue #013E87 (RGB 1, 62, 135 / HSL 213 99% 27%) on white.
   Layout follows the reference supplied in the brief, with its red
   replaced by Eurobond blue throughout.
   ===================================================================== */

/* ---------- Fonts (self-hosted Poppins, SIL Open Font License) ---------- */
@font-face { font-family: "Poppins"; src: url("../fonts/Poppins-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Poppins"; src: url("../fonts/Poppins-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Poppins"; src: url("../fonts/Poppins-SemiBold.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Poppins"; src: url("../fonts/Poppins-Bold.woff2") format("woff2"); font-weight: 700; font-display: swap; }

/* ---------- Tokens ---------- */
:root {
  --blue: #013E87;          /* primary brand colour from the brief (replaces the reference red) */
  --blue-bright: #0064B6;   /* second blue in the Eurobond logo */
  --navy: #012A5C;
  --charcoal: #2E3238;      /* benefits list background, as in the reference */
  --grey: #55585C;          /* second word of headings, as in the reference */
  --text: #4A4D52;          /* body copy */
  --line: #D5DFEC;
  --mist: #EEF3F9;
  --white: #FFFFFF;
  --accent-on-dark: #F29100;
  --error: #B42318;
  --error-on-dark: #FFD2C9;

  --font: "Poppins", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --container: 1320px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section-space: clamp(3.5rem, 7vw, 6.5rem);
  --header-h: 92px;
  --radius: 6px;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + 8px); }
body { margin: 0; overflow-x: clip; font-family: var(--font); font-size: 1rem; line-height: 1.75; color: var(--text); background: var(--white); -webkit-font-smoothing: antialiased; }
img, svg { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3 { margin: 0; line-height: 1.1; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
a { color: var(--blue-bright); }
ul { margin: 0; padding: 0; list-style: none; }
figure { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--blue-bright); outline-offset: 3px; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.icon { width: 1.25rem; height: 1.25rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.icon--sm { width: 1rem; height: 1rem; }
svg .fill, .icon .fill { fill: currentColor; stroke: none; }

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.page-top { position: absolute; top: 0; left: 0; width: 1px; height: 1px; outline: none; }
.skip-link { position: absolute; left: 1rem; top: -100px; z-index: 100; padding: .75rem 1rem; background: var(--blue); color: var(--white); font-weight: 600; }
.skip-link:focus { top: 1rem; }

/* Two-tone uppercase headings: first word in brand blue, the rest in grey (reference style) */
.title {
  font-weight: 700; text-transform: uppercase; letter-spacing: 0;
  font-size: clamp(1.75rem, 1.15rem + 2.2vw, 2.75rem); line-height: 1.1; color: var(--grey);
  margin-bottom: 1.5rem;
}
.title--center { text-align: center; }
.hl { color: var(--blue); }
.brand { color: var(--blue); font-weight: 600; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 48px; padding: .7rem 1.4rem; border: 2px solid transparent; border-radius: var(--radius);
  font-weight: 600; font-size: 1rem; line-height: 1.2; text-decoration: none; cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.btn--primary { background: var(--blue); color: var(--white); }
.btn--primary:hover { background: var(--blue-bright); }
.btn--light { background: var(--white); color: var(--blue); }
.btn--light:hover { background: var(--mist); }
.btn--outline-light { color: var(--white); border-color: rgba(255, 255, 255, .85); }
.btn--outline-light:hover { background: var(--white); color: var(--blue); }
.btn[disabled] { opacity: .7; cursor: progress; }
/* .btn sets display, which outranks the browser's [hidden] rule, so a button
   that JavaScript hides would otherwise stay on screen. */
.btn[hidden] { display: none; }

/* ---------- Header ---------- */
.site-header { position: sticky; top: 0; z-index: 50; background: var(--white); transition: box-shadow .2s ease; }
.site-header.is-scrolled { box-shadow: 0 4px 18px -8px rgba(1, 42, 92, .35); }
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  min-height: var(--header-h); padding-inline: clamp(1rem, 2.5vw, 2.25rem);
}
.site-header__brand { flex: none; }
.site-header__brand img { width: clamp(200px, 19vw, 270px); }

.site-nav__list { display: flex; align-items: center; gap: clamp(1rem, 2.6vw, 3rem); }
.site-nav a {
  position: relative; display: inline-flex; align-items: center; gap: .35rem; padding: .6rem 0;
  background: none; border: 0; cursor: pointer; text-decoration: none;
  color: #2B2D30; font-weight: 500; font-size: .9375rem; text-transform: uppercase; letter-spacing: .01em;
}
.site-nav a:hover { color: var(--blue-bright); }
/* Current tab: brand blue with a bar underneath, so it reads differently from a hover */
.site-nav .is-active { color: var(--blue); font-weight: 600; }
.site-nav__list > li > .is-active::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: .1rem; height: 3px; border-radius: 2px; background: var(--blue);
}
.nav-toggle { display: none; }

/* ---------- 1. Hero banner ---------- */
.hero {
  position: relative; overflow: hidden; isolation: isolate;
  margin-inline: clamp(0px, 1.3vw, 20px);
  min-height: clamp(520px, calc(100vh - var(--header-h) - 20px), 720px);
  min-height: clamp(520px, calc(100svh - var(--header-h) - 20px), 720px);  /* mobile: ignores the collapsing URL bar */
  display: flex; align-items: flex-end; justify-content: flex-end;
  color: var(--white); background: var(--navy);
}
/* The background picture is a positioned box covering the whole hero, so without
   these two rules it paints over the (unpositioned) content and eats the clicks
   on "Request a quote" and "See the products". */
.hero__bg { z-index: -2; pointer-events: none; }
.hero__bg, .hero__bg img { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero__bg img { object-fit: cover; object-position: 38% 60%; z-index: -2; }
/* Five-photo strip (home page). Replaces the single feature-wall photo: the
   photos sit edge to edge in equal columns, each cropped to fill its column.
   The generic .hero__bg img rule above would stack every photo across the
   whole hero, so the strip resets it. */
.hero__strip { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0; }
.hero__strip .hero__tile { position: relative; display: block; min-width: 0; overflow: hidden; }
.hero__strip img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; z-index: auto; }
/* With photos across the full width there is no empty side to darken, so the
   shade sits along the bottom only, under the headline and controls, plus a
   light wash on the right where the headline is right-aligned. */
.hero.hero--strip::before {
  background:
    linear-gradient(0deg, rgba(1, 30, 66, .93) 0%, rgba(1, 30, 66, .8) 34%, rgba(1, 30, 66, .25) 62%, rgba(1, 30, 66, 0) 76%),
    linear-gradient(270deg, rgba(1, 42, 92, .5) 0%, rgba(1, 42, 92, 0) 50%);
}
/* The restored poolside banner sits over the strip and fades in on slides
   marked data-bg="photo". Its shade is the original one: blue from the
   right, where the headline sits. */
.hero__photo { opacity: 0; transition: opacity .8s ease; }
.hero[data-bg="photo"] .hero__photo { opacity: 1; }
.hero.hero--strip[data-bg="photo"]::before {
  background:
    linear-gradient(270deg, rgba(1, 42, 92, .88) 0%, rgba(1, 42, 92, .62) 34%, rgba(1, 42, 92, 0) 64%),
    linear-gradient(0deg, rgba(1, 30, 66, .55) 0%, rgba(1, 30, 66, 0) 35%);
}
@media (prefers-reduced-motion: reduce) { .hero__photo { transition: none; } }
@media (max-width: 900px) {
  .hero__strip { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hero__strip .hero__tile:nth-child(n+4) { display: none; }
}
@media (max-width: 560px) {
  .hero__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero__strip .hero__tile:nth-child(n+3) { display: none; }
}
.hero::before { /* brand-blue shade so white type stays readable over the photo */
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(270deg, rgba(1, 42, 92, .88) 0%, rgba(1, 42, 92, .62) 34%, rgba(1, 42, 92, 0) 64%),
    linear-gradient(0deg, rgba(1, 30, 66, .55) 0%, rgba(1, 30, 66, 0) 35%);
}
.hero__content {
  position: relative; z-index: 1;
  width: min(100%, 780px); text-align: right;
  padding: 3rem clamp(1.5rem, 5vw, 4.5rem) clamp(6.5rem, 12vh, 8.5rem) 1.5rem;
}
.hero__slides { display: grid; }
.hero__slide { grid-area: 1 / 1; display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; }
.js .hero__slide:not(.is-active) { visibility: hidden; opacity: 0; }
.js .hero__slide { transition: opacity .6s ease, visibility 0s linear .6s; }
.js .hero__slide.is-active { transition-delay: 0s; }
.hero__icon { width: 5.5rem; height: 5.5rem; margin-bottom: 1.25rem; fill: none; stroke: currentColor; stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; }
.hero__title {
  margin: 0; font-weight: 700; text-transform: uppercase; letter-spacing: .01em;
  font-size: clamp(1.85rem, .9rem + 3.1vw, 3.35rem); line-height: 1.12;
  text-wrap: balance; text-shadow: 0 2px 18px rgba(1, 20, 45, .35);
}
.hero__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .75rem; margin-top: 2rem; }

.hero__controls {
  position: absolute; right: clamp(1.5rem, 5vw, 4.5rem); bottom: clamp(1.5rem, 4vh, 2.5rem);
  display: flex; align-items: center; gap: .9rem; font-size: 1.125rem; font-variant-numeric: tabular-nums;
}
.hero__dots { display: flex; }
.hero__dot { width: 44px; height: 32px; padding: 0; border: 0; background: none; cursor: pointer; position: relative; }
.hero__dot::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 3px; margin-top: -1.5px; background: rgba(255, 255, 255, .4); }
.hero__dot.is-active::before, .hero__dot:hover::before { background: var(--white); }
.hero__pause { display: grid; place-items: center; width: 40px; height: 40px; border: 1.5px solid rgba(255, 255, 255, .7); border-radius: 50%; background: none; color: var(--white); cursor: pointer; }
.hero__pause:hover { background: rgba(255, 255, 255, .15); }
.hero__pause .icon { width: 1rem; height: 1rem; }
.hero :focus-visible { outline-color: var(--white); }

.section { padding-block: var(--section-space); }

/* ---------- 2. Introduction ----------
   A centred column between the hero and the product sections. Measure is
   capped at 68ch: the copy is centred, and centred text over a full container
   width makes the reader hunt for the start of every line.

   This block overrides .section on both sides rather than inheriting
   --section-space. Above, the hero already ends in a wide dark band and a full
   section gap under it read as a hole in the page; below, the Shapes section
   opens with its own top border and brings its own gap, so two stacked would
   do the same.

   The copy runs the full container width by request. That is a long measure
   for centred text, so the leading stays a touch open here — tighter than the
   1.75 body default, but not as tight as it would be in a narrow column, or
   the eye loses its place coming back to the start of each line. If the lines
   ever read as too long, put a max-width back on .intro__inner (68ch was the
   previous value) and nothing else needs to change. */
.intro { padding-top: clamp(1.75rem, 3.5vw, 3rem); padding-bottom: clamp(1.25rem, 2.5vw, 2rem); }
.intro__inner { margin-inline: auto; text-align: center; }
.intro .title { margin-bottom: .8rem; }
.intro p { margin: 0 0 .7rem; line-height: 1.65; }
.intro p:last-child { margin-bottom: 0; }
.intro__lede { font-size: clamp(1.0625rem, 1rem + .35vw, 1.25rem); line-height: 1.6; }

/* ---------- 3–5. Product feature sections ---------- */
.feature { border-top: 1px solid #E6E9ED; box-shadow: inset 0 10px 12px -12px rgba(0, 0, 0, .15); }
.feature__inner { display: grid; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.feature--shapes .feature__inner, .feature--fins .feature__inner { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.feature--louvers .feature__inner { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.feature__figure { display: grid; place-items: center; }
/* All three at the same cap now. The old Shapes graphic was a spiky irregular
   outline that needed less width to hold its own; the panel render is a solid
   block, and at 440px it sat visibly smaller than Louvers and Fins below it. */
.feature--shapes .feature__figure img,
.feature--louvers .feature__figure img, .feature--fins .feature__figure img { width: min(100%, 520px); }
/* The Shapes image is now a square photo of tiled panels rather than a cut-out
   render, so it gets a frame of its own instead of floating on the white. */
.feature--shapes .feature__figure img.feature__img--tiles { width: min(100%, 480px); border-radius: var(--radius); box-shadow: 0 18px 40px -22px rgba(1, 42, 92, .55); }
.feature__copy p { text-align: justify; hyphens: auto; }
.feature__copy .btn { margin-top: 1rem; }
.feature--louvers .feature__copy { text-align: right; }
.feature--louvers .feature__copy p { text-align-last: right; }

/* ---------- 5. Our products ----------
   Home page: three numbered cards linking to products.html.
   products.html: the category / design-series catalogue. */
.products { border-top: 1px solid #E6E9ED; }
.products--page { border-top: 0; padding-top: clamp(2rem, 4vw, 3rem); }
.products__more { margin: 2.5rem 0 0; text-align: center; }

.product-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; margin-top: 1rem; }
.product-card {
  position: relative; display: flex; flex-direction: column;
  border: 1px solid #C9D8EC; padding: clamp(1.25rem, 2.5vw, 2rem); min-height: 480px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.product-card:hover, .product-card:focus-within { border-color: var(--blue); box-shadow: 0 12px 28px -18px rgba(1, 42, 92, .5); }
.product-card__num { font-weight: 700; font-size: clamp(2.75rem, 1.8rem + 2.5vw, 4rem); line-height: 1; color: var(--grey); }
.product-card__media { flex: 1; display: grid; place-items: center; width: 82%; margin: 1.5rem auto; min-height: 0; }
.product-card__img { width: 100%; max-height: 230px; object-fit: contain; }
.product-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.product-card__title { font-weight: 700; text-transform: uppercase; font-size: clamp(1.2rem, .9rem + .8vw, 1.6rem); color: var(--grey); }
.product-card__title a { color: inherit; text-decoration: none; }
.product-card__title a::after { content: ""; position: absolute; inset: 0; }   /* whole card is clickable */
.product-card__arrow { width: 2.75rem; height: 2.75rem; padding: .55rem; flex: none; border: 2px solid var(--blue); border-radius: 50%; color: var(--blue); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: background-color .2s ease, color .2s ease; }
.product-card:hover .product-card__arrow { background: var(--blue); color: var(--white); }

.catalogue { display: grid; grid-template-columns: minmax(0, 270px) minmax(0, 1fr); gap: clamp(1.5rem, 3vw, 3rem); align-items: start; }
.catalogue__filters { display: grid; gap: 1.75rem; position: sticky; top: calc(var(--header-h) + 1.25rem); }

.filter { border: 1px solid var(--line); border-radius: var(--radius); padding: 1.1rem 1.25rem 1.25rem; }
.filter__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: .85rem; }
.filter__title { font-size: 1.0625rem; font-weight: 700; color: var(--blue); }
.filter__clear { padding: .35rem 0; background: none; border: 0; cursor: pointer; color: var(--grey); font-size: .875rem; font-weight: 500; text-decoration: underline; text-underline-offset: .2em; }
.filter__clear:hover { color: var(--blue); }
.filter__list { display: grid; gap: .15rem; }

.choice { display: flex; align-items: center; gap: .7rem; min-height: 44px; padding: .25rem .4rem; margin-inline: -.4rem; border-radius: 4px; cursor: pointer; }
.choice:hover { background: var(--mist); }
.choice input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.choice__box { flex: none; width: 19px; height: 19px; border: 2px solid #AFC0D6; border-radius: 3px; background: var(--white); transition: background-color .15s ease, border-color .15s ease; }
.choice input:checked + .choice__box {
  border-color: var(--blue-bright); background: var(--blue-bright) no-repeat center / 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFFFF' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E");
}
.choice input:focus-visible + .choice__box { outline: 3px solid var(--blue-bright); outline-offset: 3px; }
.choice__label { font-size: .9375rem; line-height: 1.4; color: var(--text); }
.choice input:checked ~ .choice__label { color: var(--blue); font-weight: 600; }

.catalogue__count { margin: 0 0 1rem; font-size: .9rem; color: var(--grey); }
.swatches { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.5rem 1.25rem; }
.swatch { text-align: center; }
.swatch__img { width: 100%; aspect-ratio: 257 / 200; object-fit: cover; border: 1px solid var(--line); border-radius: 4px; }
.swatch__name { margin: .75rem 0 .2rem; font-size: .9375rem; font-weight: 600; color: #2B2D30; line-height: 1.3; }
.swatch__code { margin: 0; font-size: .875rem; color: var(--grey); }
.swatch[hidden] { display: none; }

/* Shapes: every design in every family, with the name under each one. Four
   across, like the Louver and Fin swatches (the .swatches breakpoints below
   take it to three on a tablet and two on a phone), eight at a time behind
   "See more". main.js adds .swatches--panels while Shapes is the selected
   category. Tile sizing is in the "Shapes on products.html" block at the end
   of this file. */
.swatches--panels { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* A shape tile is a link: to its design page, or to the larger view. The name
   turning blue on hover, plus the lift, is what says so. */
.swatch__link { display: block; color: inherit; text-decoration: none; }
.swatch__link:hover .swatch__name { color: var(--blue); }

.catalogue__empty { margin: 0; padding: 2rem 1.25rem; text-align: center; background: var(--mist); border-radius: var(--radius); color: var(--grey); }
.link-btn { padding: 0; background: none; border: 0; cursor: pointer; color: var(--blue-bright); font: inherit; text-decoration: underline; }

/* ---------- 5b. Shape tiles (.shape-grid / .shape-tile) ----------
   Used by the Other Designs carousel on the design pages. (The family page
   shapes-marvels.html they were first built for has been retired; every
   design now lives on products.html.)

   The tiles are square, not landscape like the products.html panels, because
   the renders are: eleven Marvels designs are square panels and two are tall
   ones, and a square tile holds both without cropping a single panel. The
   renders are supplied on white, so the tile is white with the same hairline
   border as the finish swatches. The grid is capped and centred so a tile
   never grows past a comfortable reading size on a wide monitor. */
.shape-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(.85rem, 1.5vw, 1.25rem); max-width: 1040px; margin-inline: auto;
}
.shape-tile { text-align: center; }
.shape-tile__img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; background: var(--white); border: 0; border-radius: 4px; }

/* Hover: the panel is lifted off the wall. The whole tile rises 8 px and tips
   back from its top edge at the same time, so the bottom edge ends up about
   19 px higher than where it started and the top edge 8 px higher.

   An earlier version kept the top edge perfectly still and moved only the
   bottom. That is the truer hinge, but on screen it read as the tile shrinking
   rather than rising, because nothing in the frame of reference moved. Lifting
   the whole panel and letting the bottom travel furthest is what actually reads
   as being picked up. The shadow is offset well below the raised edge for the
   same reason: the gap between panel and shadow is what says "off the wall".

   Light and shadow do the rest of the work: a gradient over the panel catches
   the light along the bottom edge, the one now tipped up towards an overhead
   light, and puts the top edge slightly into shade, while the shadow gathers
   under the raised edge. The direction matters — brightening the TOP instead
   fades that edge into the white page, and the tile then reads as shrinking
   from the top and growing downwards, which cancels the movement out entirely.
   Without any light the tilt alone reads as the panel sinking backwards rather
   than being picked up.

   The overlay needs an element of its own, so each render sits inside
   .panel-frame and the frame carries the transform; the image and the light
   tilt together. Only transform, box-shadow and opacity are animated, all three
   composited, so a grid of thirteen stays smooth. Hover styling is confined to
   devices that really hover, because on a touch screen :hover sticks after a
   tap and would leave a tile raised. */
.panel-frame { position: relative; display: block; border-radius: 4px; }
.panel-frame::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0;
  background: linear-gradient(180deg, rgba(1, 42, 92, .12) 0%, rgba(1, 42, 92, .04) 30%, rgba(255, 255, 255, 0) 55%, rgba(255, 255, 255, .3) 100%);
  transition: opacity .35s ease;
}

@media (hover: hover) {
  .panel-frame {
    transform-origin: 50% 0;
    transition: transform .4s cubic-bezier(.2, .7, .3, 1), box-shadow .4s cubic-bezier(.2, .7, .3, 1);
  }
  .shape-tile:hover .panel-frame,
  .shape-tile__link:focus-visible .panel-frame,
  .swatch__link:hover .panel-frame,
  .swatch__link:focus-visible .panel-frame {
    transform: perspective(900px) translateY(-8px) rotateX(-8deg);
    box-shadow: 0 26px 30px -18px rgba(1, 42, 92, .42), 0 10px 16px -12px rgba(1, 42, 92, .3);
  }
  .shape-tile:hover .panel-frame::after,
  .shape-tile__link:focus-visible .panel-frame::after,
  .swatch__link:hover .panel-frame::after,
  .swatch__link:focus-visible .panel-frame::after { opacity: 1; }

  .shape-tile:hover .shape-tile__code { color: var(--blue); }
  .shape-tile__code { transition: color .25s ease; }
}

/* Someone who has asked for less motion still gets the light and the shadow,
   just without the movement. */
@media (prefers-reduced-motion: reduce) {
  .shape-tile:hover .panel-frame,
  .shape-tile__link:focus-visible .panel-frame,
  .swatch__link:hover .panel-frame,
  .swatch__link:focus-visible .panel-frame { transform: none; }
}

/* Eight to start with (two full rows of four), the rest behind the button. The
   collapsed state is CSS so the extra tiles never flash before main.js runs;
   main.js swaps it for the hidden attribute on first run and takes over from
   there. Without JavaScript the whole family is shown and the button is never
   displayed. Keep this number in step with data-reveal-step in the markup. */
.js .shape-grid--collapsed > .shape-tile:nth-child(n+9) { display: none; }
.reveal { display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem; margin: clamp(1.75rem, 3vw, 2.5rem) 0 0; text-align: center; }
.reveal[hidden], html:not(.js) .reveal { display: none; }
.shape-page__cta { margin: clamp(1.75rem, 3vw, 2.5rem) 0 0; text-align: center; }

/* Best sellers: the same tiles as the grid above, so it needs nothing beyond a
   centred lede under the heading. */
.best-sellers { border-top: 1px solid #E6E9ED; padding-top: clamp(2.5rem, 5vw, 4rem); }
.section-lede { max-width: 58ch; margin: -.75rem auto clamp(1.75rem, 3vw, 2.5rem); text-align: center; color: var(--grey); }

/* FAQ: plain <details> elements, so opening and closing works with no
   JavaScript. The marker is drawn as a plus that turns into a minus, because
   the browser default triangle sits oddly against Poppins. */
.faqs { background: var(--mist); border-top: 1px solid var(--line); }
.faq { max-width: 860px; margin-inline: auto; }
.faq__item { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: .75rem; }
.faq__item[open] { border-color: #B9CEE8; box-shadow: 0 12px 28px -22px rgba(1, 42, 92, .5); }
.faq__q {
  position: relative; display: block; padding: 1.05rem 3.25rem 1.05rem 1.25rem; cursor: pointer;
  font-weight: 600; font-size: 1.0625rem; line-height: 1.45; color: var(--blue); list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }   /* Safari draws its own triangle */
.faq__q:hover { color: var(--blue-bright); }
.faq__q:focus-visible { outline: 3px solid var(--blue-bright); outline-offset: -3px; border-radius: var(--radius); }
.faq__q::after,
.faq__q::before {   /* the two strokes of the plus */
  content: ""; position: absolute; right: 1.35rem; top: 50%; width: 15px; height: 2px;
  background: currentColor; border-radius: 2px; transition: transform .2s ease;
}
.faq__q::before { transform: translateY(-50%); }
.faq__q::after { transform: translateY(-50%) rotate(90deg); }
.faq__item[open] .faq__q::after { transform: translateY(-50%) rotate(0deg); }   /* plus becomes minus */
.faq__a { padding: 0 1.25rem 1.25rem; }
.faq__a p { margin: 0; }

/* ---------- 5c. One design per page (shapes-marvels-101.html) ----------
   Banner, then the gallery beside the product's number, description and
   enquiry button, then other designs, FAQ and the closing section. */
/* The gallery column is capped rather than given a fraction: the renders are
   1200 x 800 canvases with the panel floating in the middle on white, so a
   column that grows with the viewport only grows the white margin. Capping it
   keeps the panel at a sensible size and hands the spare width to the copy,
   which shortens the text column at the same time. The cap is min()'d with a
   percentage so that between about 1000px and 1250px, where the container has
   shrunk but the layout has not stacked yet, the gallery gives width back
   instead of squeezing the copy into a 380px column. */
.product-detail__grid { display: grid; grid-template-columns: minmax(0, min(500px, 45%)) minmax(0, 1fr); gap: clamp(1.75rem, 4vw, 3.5rem); align-items: start; }

/* The spec table is a full-width row under both columns. The copy column is
   always shorter than it used to be and the gallery column is fixed, so the
   bottom left of the section was dead space; the table now fills it. */
.spec--wide { grid-column: 1 / -1; margin-top: clamp(1.5rem, 3vw, 2.25rem); }

/* Gallery: a scroll-snap track. It swipes on a phone and scrolls with the
   arrows or thumbnails on a desktop; with no JavaScript it is still a
   scrollable strip, so every image stays reachable. main.js only adds the
   arrows and the thumbnail highlight. */
.gallery__stage { position: relative; }
.gallery__track {
  display: flex; gap: 0; margin: 0; padding: 0; list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; border-radius: var(--radius); background: var(--white);
}
.gallery__track::-webkit-scrollbar { display: none; }
.gallery__track:focus-visible { outline: 3px solid var(--blue-bright); outline-offset: 3px; }
.gallery__slide { flex: 0 0 100%; scroll-snap-align: center; }
.gallery__slide img { width: 100%; aspect-ratio: 3 / 2; object-fit: contain; background: var(--white); }

.gallery__nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px;
  background: rgba(255, 255, 255, .92); border: 1px solid var(--line); border-radius: 50%; cursor: pointer;
  color: var(--blue); box-shadow: 0 8px 20px -14px rgba(1, 42, 92, .6); transition: background .2s ease, color .2s ease;
}
.gallery__nav:hover { background: var(--blue); color: var(--white); border-color: var(--blue); }
.gallery__nav[hidden] { display: none; }
.gallery__nav--prev { left: .5rem; }
.gallery__nav--next { right: .5rem; }

/* The 360 button used to sit on the stage at bottom left. It cannot stay
   there: each render frames the panel differently inside the same 1200 x 800
   canvas (view-1 fills 18.8%-81.2% of the width, view-2 fills 3%-97%, and
   view-2 stops 21% short of the bottom), so any fixed corner is inside the
   panel on some slides and out in the white margin on others. It now sits in
   the row under the stage, where it is on the panel for none of them and past
   the panel for none of them either. If the renders are ever re-exported
   tight-cropped, this can go back to being an overlay. */
.gallery__foot {
  display: flex; flex-direction: column; align-items: center; gap: .75rem; margin-top: .75rem;
}
/* Two buttons now sit in this row. They wrap rather than shrink: "View all
   colours" is too long to squeeze onto one line beside "360° view" on a phone,
   and a truncated label is worse than a second row. */
.gallery__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .6rem; }

.view-360 {
  display: inline-flex; align-items: center; gap: .45rem; padding: .5rem .9rem;
  background: var(--white); border: 1px solid var(--line); border-radius: 999px;
  color: var(--blue); font-size: .875rem; font-weight: 600; text-decoration: none; white-space: nowrap;
  box-shadow: 0 8px 20px -14px rgba(1, 42, 92, .6); transition: background .2s ease, color .2s ease;
}
.view-360:hover { background: var(--blue); color: var(--white); border-color: var(--blue); }
.view-360 .icon { width: 20px; height: 20px; }

/* Centred under the stage, however many thumbnails a design has. justify-content
   is ignored once the strip overflows on a narrow screen, which is the correct
   behaviour: it falls back to scrolling from the left rather than clipping the
   first thumbnail. */
.gallery__thumbs { display: flex; justify-content: safe center; gap: .55rem; margin: 0; padding: 0; list-style: none; overflow-x: auto; max-width: 100%; }
.gallery__thumbs button { flex: 0 0 auto; padding: 0; width: 74px; background: var(--white); border: 1px solid var(--line); border-radius: 4px; cursor: pointer; overflow: hidden; }
.gallery__thumbs img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: contain; }
.gallery__thumbs button[aria-current="true"] { border-color: var(--blue); box-shadow: 0 0 0 1px var(--blue) inset; }

.product-code { margin: 0 0 .6rem; font-size: clamp(1.375rem, 1.05rem + 1.1vw, 1.875rem); font-weight: 700; letter-spacing: .04em; color: var(--blue); }
.product-desc { font-size: .9375rem; line-height: 1.65; }
.product-desc p { margin: 0 0 .85rem; }
.product-detail__cta { margin: clamp(1rem, 2vw, 1.5rem) 0 0; }

.spec { margin: 0; padding: 1.1rem 1.25rem; background: var(--mist); border-radius: var(--radius); }
.spec > div { display: flex; flex-wrap: wrap; gap: .35rem 1rem; padding: .45rem 0; border-bottom: 1px solid #DFE7F1; }
.spec > div:last-child { border-bottom: 0; }
.spec dt { min-width: 10.5rem; font-weight: 600; color: var(--blue); }
.spec dd { margin: 0; }

/* Full width, so the rows run in two columns instead of one long list with a
   half-empty page beside it. The last-child border reset above is wrong in two
   columns (it only clears one of the two bottom cells), so it is re-done here
   for the last row of the pair. An odd number of rows leaves the final cell
   alone in column 1; its border is cleared by the :nth-child rule below. */
@media (min-width: 760px) {
  .spec--wide { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(1.5rem, 3vw, 3rem); padding: 1.25rem 1.5rem; }
  .spec--wide > div { padding: .55rem 0; }
  .spec--wide > div:nth-last-child(-n+2) { border-bottom: 0; }
  .spec--wide > div:nth-last-child(2):nth-child(even) { border-bottom: 1px solid #DFE7F1; }
  .spec--wide dt { min-width: 8.5rem; }
  /* Half the width means a long value (the finishes list) no longer fits beside
     its label at max-content, and flex-wrap drops it onto its own line, which
     reads as a different kind of row. A basis it can shrink from keeps it
     alongside and wraps inside the value instead. The two figures are sized so
     label + gap + value still fits the column at the 760px breakpoint itself,
     which is where the columns are narrowest. */
  .spec--wide dd { flex: 1 1 9rem; min-width: 0; }
}

.other-designs { border-top: 1px solid #E6E9ED; }

/* Other designs: the same tiles as .shape-grid, but the whole family is in the
   track and four are in view at a time, so the arrows are the way through the
   rest. The track is a plain scroll-snap strip: with no JavaScript the arrows
   stay hidden and it is still swipeable, so nothing is unreachable.

   The vertical padding is load-bearing. The tiles lift and tip on hover, and
   overflow-x: auto makes the track a scroll container on BOTH axes, so without
   the padding the raised edge and its shadow are clipped off. */
.shape-carousel {
  --carousel-gap: clamp(.85rem, 1.5vw, 1.25rem);
  --carousel-per-view: 4;
  position: relative; max-width: 1040px; margin-inline: auto;
}
.shape-carousel__track {
  display: flex; gap: var(--carousel-gap); margin: 0; padding: 14px 0 22px; list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; scroll-behavior: smooth;
}
.shape-carousel__track::-webkit-scrollbar { display: none; }
.shape-carousel__track:focus-visible { outline: 3px solid var(--blue-bright); outline-offset: 2px; border-radius: var(--radius); }
.shape-carousel .shape-tile {
  flex: 0 0 calc((100% - (var(--carousel-per-view) - 1) * var(--carousel-gap)) / var(--carousel-per-view));
  scroll-snap-align: start;
}

.carousel__nav {
  position: absolute; top: calc(50% - .8rem); transform: translateY(-50%); z-index: 2;
  display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px;
  background: var(--white); border: 1px solid var(--line); border-radius: 50%; cursor: pointer;
  color: var(--blue); box-shadow: 0 8px 20px -14px rgba(1, 42, 92, .6);
  transition: background .2s ease, color .2s ease, opacity .2s ease;
}
.carousel__nav:hover:not(:disabled) { background: var(--blue); color: var(--white); border-color: var(--blue); }
.carousel__nav:disabled { opacity: .3; cursor: default; }
.carousel__nav[hidden] { display: none; }
.carousel__nav--prev { left: -3.25rem; }
.carousel__nav--next { right: -3.25rem; }

/* Below about 1250px the track is as wide as the container and there is no
   margin left to sit in, so the arrows step onto the end tiles instead of
   overflowing the page. */
@media (max-width: 1250px) {
  .carousel__nav--prev { left: -.5rem; }
  .carousel__nav--next { right: -.5rem; }
}
@media (max-width: 900px) { .shape-carousel { --carousel-per-view: 3; } }
@media (max-width: 600px) {
  .shape-carousel { --carousel-per-view: 2; }
  /* On a phone the arrows have to sit over the end tiles, so they shrink to
     cover less of them. The track is swipeable regardless. */
  .carousel__nav { width: 36px; height: 36px; }
  .carousel__nav--prev { left: -.35rem; }
  .carousel__nav--next { right: -.35rem; }
}

.shape-tile__link { display: block; color: inherit; text-decoration: none; }
.shape-tile__link:hover .shape-tile__code { color: var(--blue); text-decoration: underline; }
.shape-tile__link:focus-visible { outline: 3px solid var(--blue-bright); outline-offset: 4px; border-radius: 4px; }
.shape-tile__link .shape-tile__code { display: block; }

/* Back link sitting above the page title in the photo hero */
.crumb { margin: 0 0 .75rem; font-size: .9375rem; }
.crumb a { display: inline-flex; align-items: center; gap: .4rem; color: var(--white); text-decoration: none; font-weight: 500; }
.crumb a:hover { text-decoration: underline; }

/* ---------- 6. Benefits (tabs on desktop, accordion on mobile) ---------- */
.benefits {
  position: relative; overflow: hidden; color: var(--white);
  background: linear-gradient(90deg, var(--charcoal) 50%, var(--blue) 50%);
  padding-bottom: clamp(2rem, 4vw, 3.5rem);
}
.benefits__title { text-align: center; font-weight: 700; text-transform: uppercase; font-size: clamp(1.75rem, 1.15rem + 2.2vw, 2.75rem); padding: clamp(2rem, 4vw, 3rem) 1rem clamp(2rem, 4vw, 3.5rem); }
.benefits__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  max-width: var(--container); margin-inline: auto;
}
.benefit { display: contents; }
.benefit__tab {
  grid-column: 1; position: relative; z-index: 0;
  display: grid; grid-template-columns: 4.5rem 1fr auto; align-items: center; gap: 1.25rem;
  width: 100%; min-height: 84px; padding: .5rem clamp(1.5rem, 5vw, 4rem) .5rem var(--gutter);
  background: none; border: 0; color: var(--white); cursor: pointer; text-align: left;
}
.benefit__tab::before { /* active row colour runs to the left edge of the screen, as in the reference */
  content: ""; position: absolute; inset: 0 0 0 -100vw; z-index: -1; background: transparent; transition: background-color .2s ease;
}
.benefit__tab:hover::before { background: rgba(255, 255, 255, .06); }
.benefit__tab[aria-expanded="true"]::before { background: var(--blue); }
.benefit__icon { width: 3.25rem; height: 3.25rem; justify-self: center; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.benefit__label { font-size: clamp(1rem, .92rem + .4vw, 1.25rem); padding-left: 1.25rem; border-left: 2px solid rgba(255, 255, 255, .85); line-height: 2.4; }
.benefit__arrow { display: grid; place-items: center; width: 3rem; height: 3rem; border-radius: 50%; background: var(--blue-bright); color: var(--white); transition: background-color .2s ease, color .2s ease, transform .2s ease; }
.benefit__arrow .icon { width: 1.4rem; height: 1.4rem; }
.benefit__tab[aria-expanded="true"] .benefit__arrow { background: var(--white); color: var(--blue); transform: rotate(45deg); }
.benefit__panel {
  grid-column: 2; grid-row: 1 / span 6; align-self: center;
  padding: 1rem var(--gutter) 1rem clamp(2rem, 6vw, 5.5rem);
}
.benefit__panel h3 { font-size: clamp(1.35rem, 1.1rem + .9vw, 1.8rem); font-weight: 700; margin-bottom: 1.25rem; }
.benefit__panel p { text-align: justify; hyphens: auto; color: rgba(255, 255, 255, .92); }
.js .benefit__panel:not([hidden]) { animation: panel-in .35s ease both; }
@keyframes panel-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---------- 7. Applications ---------- */
.app-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(2rem, 3.5vw, 2.75rem) clamp(1rem, 2vw, 2rem); margin-top: 2.5rem; }
.app { display: flex; flex-direction: column; }
.app__link { display: flex; flex-direction: column; gap: 1rem; height: 100%; color: inherit; text-decoration: none; }
.app__link:focus-visible { outline-offset: 5px; }
.app__box {
  display: block; width: 100%; aspect-ratio: 3 / 2; overflow: hidden;
  border-radius: var(--radius); background: var(--mist);
}
.app__photo { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .4s ease; }
.app:hover .app__photo { transform: scale(1.04); }
.app h3 { font-size: clamp(1rem, .92rem + .35vw, 1.2rem); font-weight: 600; color: var(--grey); line-height: 1.35; }

/* ---------- 9. Closing section: about, form, contact, social ---------- */
.site-footer { background: var(--blue); color: var(--white); padding-top: clamp(3rem, 6vw, 4.5rem); }
.site-footer__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 5vw, 3.5rem) clamp(2rem, 6vw, 6rem);
}
.site-footer__logo { width: min(100%, 340px); margin-bottom: 1.25rem; }
.site-footer__about p { color: rgba(255, 255, 255, .92); max-width: 40rem; font-size: .9375rem; line-height: 1.7; }
.site-footer a { color: var(--white); }
.site-footer :focus-visible { outline-color: var(--white); }
/* Form: underlined fields on blue, as in the reference */
.enquiry { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem 1.5rem; align-content: start; }
.enquiry__title { grid-column: 1 / -1; font-size: clamp(1.35rem, 1.1rem + .9vw, 1.8rem); font-weight: 700; text-transform: uppercase; }
.field { display: grid; gap: .15rem; align-content: start; }
.field--wide, .form-status, .enquiry__submit { grid-column: 1 / -1; }
.field label { font-size: .9375rem; font-weight: 500; }
.field input, .field select, .field textarea {
  width: 100%; min-height: 44px; padding: .45rem 0; border: 0; border-bottom: 1.5px solid rgba(255, 255, 255, .8);
  border-radius: 0; background: transparent; color: var(--white); font-size: 1rem;
}
.field textarea { resize: vertical; min-height: 3.5rem; }
.field select {
  appearance: none; -webkit-appearance: none; padding-right: 2rem; cursor: pointer;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFFFF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 9.5l5.5 5.5 5.5-5.5'/%3E%3C/svg%3E") no-repeat right .1rem center / 1.1rem;
}
.field select option { color: #1B1D20; }
.field input::placeholder, .field textarea::placeholder { color: rgba(255, 255, 255, .6); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-bottom-color: var(--white); box-shadow: 0 2px 0 0 var(--white); }
.field.has-error input, .field.has-error select { border-bottom-color: var(--error-on-dark); box-shadow: 0 2px 0 0 var(--error-on-dark); }
.field__error { margin: .3rem 0 0; font-size: .9rem; font-weight: 600; color: var(--error-on-dark); line-height: 1.4; }
.form-status { padding: .85rem 1rem; border-left: 4px solid var(--error); background: #FEF3F2; color: var(--error); font-weight: 500; line-height: 1.5; border-radius: 4px; }
.enquiry__submit { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1.5rem; margin-top: .5rem; }
.enquiry__submit .btn { min-width: 170px; }
.form-note { margin: 0; font-size: .9rem; color: rgba(255, 255, 255, .8); line-height: 1.5; }
.hp { position: absolute !important; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* =====================================================================
   Enquiry pop-up (native <dialog>, opened by main.js on landing)
   The form inside is the same markup as the closing section, so the light
   theme here is an override of the white-on-blue defaults above.
   ===================================================================== */
.modal {
  width: min(960px, calc(100vw - 2rem)); max-width: none;
  max-height: min(92vh, 720px); max-height: min(92svh, 720px);
  padding: 0; overflow: hidden;
  border: 0; border-radius: var(--radius); background: var(--white);
  box-shadow: 0 24px 60px rgba(1, 42, 92, .28);
}
.modal::backdrop { background: rgba(1, 42, 92, .55); }
.modal__inner { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); max-height: inherit; }
.modal__media { position: relative; background: var(--mist); }
.modal__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.modal__close {
  position: absolute; top: .6rem; right: .6rem; z-index: 2;
  display: grid; place-items: center; width: 44px; height: 44px;
  border: 0; border-radius: 50%; background: var(--white); color: var(--charcoal);
  cursor: pointer; box-shadow: 0 2px 10px rgba(1, 42, 92, .2);
}
.modal__close:hover { background: var(--mist); color: var(--blue); }
.modal__title { font-size: clamp(1.35rem, 1.1rem + .9vw, 1.75rem); font-weight: 700; color: var(--blue); }
.modal__lede { margin: .5rem 0 0; color: var(--grey); font-size: .9375rem; line-height: 1.55; }

/* The form column scrolls on its own so the photo stays put on a short screen */
.enquiry--modal {
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  gap: 1rem 1.5rem; padding: clamp(1.5rem, 3vw, 2.25rem);
}
.enquiry--modal .modal__title, .enquiry--modal .modal__lede,
.enquiry--modal .field--wide, .enquiry--modal .form-status,
.enquiry--modal .enquiry__submit { grid-column: 1 / -1; }
.enquiry--modal .modal__lede { margin-bottom: .25rem; }

/* Light-theme overrides for the shared field markup */
.enquiry--modal .field label { color: var(--charcoal); }
.enquiry--modal .field input,
.enquiry--modal .field select,
.enquiry--modal .field textarea { border-bottom-color: var(--line); color: var(--text); }
.enquiry--modal .field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234A4D52' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 9.5l5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
}
.enquiry--modal .field input::placeholder,
.enquiry--modal .field textarea::placeholder { color: #9AA1A9; }
.enquiry--modal .field input:focus,
.enquiry--modal .field select:focus,
.enquiry--modal .field textarea:focus { border-bottom-color: var(--blue); box-shadow: 0 2px 0 0 var(--blue); }
.enquiry--modal .field.has-error input,
.enquiry--modal .field.has-error select { border-bottom-color: var(--error); box-shadow: 0 2px 0 0 var(--error); }
.enquiry--modal .field__error { color: var(--error); }
.enquiry--modal .form-note { color: var(--grey); }
.enquiry--modal .enquiry__submit { margin-top: .25rem; }

/* Opening animation, skipped for anyone who asked for less motion */
.modal[open] { animation: modal-in .25s ease both; }
.modal[open]::backdrop { animation: backdrop-in .25s ease both; }
@keyframes modal-in { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes backdrop-in { from { opacity: 0; } to { opacity: 1; } }

/* main.js sets this while a dialog is open; <dialog> does not lock the page itself */
body.modal-open { overflow: hidden; }

@media (max-width: 760px) {
  .modal { width: calc(100vw - 1.5rem); max-height: 90svh; }
  /* The photo becomes a banner so the fields still get the room they need */
  .modal__inner { grid-template-columns: 1fr; grid-template-rows: 116px minmax(0, 1fr); }
  .modal__media { min-height: 116px; }
  /* Everything below is about getting "Send enquiry" onto the first screen:
     stacked fields make this form tall, and a submit button the visitor has to
     scroll an inner panel to find is a submit button that does not get pressed. */
  .modal__lede { display: none; }
  .enquiry--modal { gap: .5rem 1rem; padding: 1.1rem 1.25rem 1.4rem; }
  .enquiry--modal .field input,
  .enquiry--modal .field select { min-height: 38px; padding-block: .3rem; }
  .enquiry--modal .field textarea { min-height: 2.75rem; }
  .enquiry--modal .form-note { font-size: .8125rem; }
}
@media (max-height: 620px) {
  .modal__inner { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr); }
  .modal__media { display: none; }   /* a landscape phone has no room for it */
}

/* =====================================================================
   Product quote forms (home page "Get a quote" buttons)
   Same dialog shell and light form theme as the enquiry pop-up. The left
   column shows the product on a pale panel instead of a photo, and the form
   adds a City field and a file drop box for the visitor's requirements.
   ===================================================================== */
.modal__media--product { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.5rem; padding: 2rem 1.5rem; background: var(--mist); }
.modal__media--product picture { display: block; width: 100%; }
.modal__media--product img { position: static; width: 100%; height: auto; max-height: 300px; object-fit: contain; }
.modal__product { margin: 0; font-weight: 700; text-transform: uppercase; font-size: 1.35rem; line-height: 1.15; color: var(--grey); text-align: center; }

.field__label { font-size: .9375rem; font-weight: 500; color: var(--charcoal); }
.field__optional { font-weight: 400; color: var(--grey); }
.dropzone {
  display: grid; justify-items: center; gap: .2rem; margin-top: .35rem; padding: 1rem 1rem 1.1rem;
  border: 1.5px dashed #AFC0D6; border-radius: var(--radius); background: #F8FAFD;
  text-align: center; cursor: pointer; transition: border-color .15s ease, background-color .15s ease;
}
.dropzone:hover, .dropzone.is-over { border-color: var(--blue-bright); background: var(--mist); }
.dropzone .icon { width: 1.6rem; height: 1.6rem; color: var(--blue-bright); }
.dropzone__text { font-size: .9375rem; color: var(--text); line-height: 1.4; }
.dropzone__text strong { color: var(--blue); }
.dropzone__hint { font-size: .8125rem; color: var(--grey); line-height: 1.4; }
/* The real input stays in the page (keyboard and screen readers reach it); the
   box above is its visible face. Focus on the input lights up the box. */
.dropzone__input { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.field--files { position: relative; }
.dropzone__input:focus-visible + .dropzone__list, .field--files:focus-within .dropzone { outline: 3px solid var(--blue-bright); outline-offset: 2px; }
.dropzone__list { display: grid; gap: .15rem; margin-top: .35rem; font-size: .875rem; color: var(--text); line-height: 1.4; }
.dropzone__list li { overflow-wrap: anywhere; padding-left: 1.1rem; position: relative; }
.dropzone__list li::before { content: ""; position: absolute; left: .2rem; top: .5em; width: .45rem; height: .45rem; border-radius: 50%; background: var(--blue-bright); }
.field--files.has-error .dropzone { border-color: var(--error); }
.enquiry--quote .form-status { margin: 0; }

@media (max-width: 760px) {
  /* The product image becomes a short banner, as the photo does in the pop-up */
  .modal--quote .modal__inner { grid-template-rows: 96px minmax(0, 1fr); }
  .modal__media--product { flex-direction: row; gap: 1rem; padding: .75rem 3.5rem .75rem 1rem; min-height: 96px; }
  .modal__media--product picture { width: auto; flex: 0 1 45%; }
  .modal__media--product img { max-height: 72px; }
  .modal__product { font-size: 1rem; text-align: left; }
  .dropzone { padding: .75rem; }
}

/* =====================================================================
   Text panel: Terms and Conditions, opened over the page. One scrolling column.
   ===================================================================== */
.modal--text { width: min(760px, calc(100vw - 2rem)); }
.modal__text { position: relative; max-height: inherit; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: clamp(1.5rem, 4vw, 2.75rem); padding-top: clamp(1.75rem, 4vw, 2.75rem); }
.modal__text .modal__title { padding-right: 3rem; }
.modal__text .modal__lede { margin-bottom: 1.5rem; }
.modal__text .modal__close { position: sticky; float: right; top: 0; margin: -.75rem -.75rem 0 0; }
.modal__text .legal__body section + section { margin-top: 1.5rem; padding-top: 1.5rem; }
@media (max-width: 760px) {
  .modal--text { width: calc(100vw - 1.5rem); max-height: 90svh; }
}


/* =====================================================================
   Colours pop-up
   Same dialog shell as the enquiry pop-up, without the photo column: the
   swatches are the picture. Narrower than .modal so fourteen chips read as
   a palette rather than a spreadsheet.
   ===================================================================== */
.modal--colours { width: min(680px, calc(100vw - 2rem)); max-height: min(88vh, 640px); max-height: min(88svh, 640px); }
.colours { position: relative; overflow-y: auto; -webkit-overflow-scrolling: touch; max-height: inherit; padding: clamp(1.5rem, 3vw, 2.25rem); }
.colours__lede { margin: .5rem 0 1.5rem; max-width: 52ch; color: var(--grey); font-size: .9375rem; line-height: 1.55; }
.colours__note { margin: 1.5rem 0 0; padding-top: 1.1rem; border-top: 1px solid var(--line); color: var(--grey); font-size: .875rem; line-height: 1.55; }

.swatch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .6rem; margin: 0; padding: 0; list-style: none; }
.swatch-card {
  display: flex; align-items: center; gap: .7rem; padding: .5rem .75rem .5rem .5rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); font-size: .9375rem; text-decoration: none;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.swatch-card:hover, .swatch-card:focus-visible { border-color: var(--blue); box-shadow: 0 6px 18px -12px rgba(1, 42, 92, .7); }
/* The inset ring keeps Ivory and the other pale finishes from vanishing into
   the white card, without painting a border colour over the finish itself */
.swatch-card__chip { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 6px; box-shadow: inset 0 0 0 1px rgba(1, 42, 92, .22); }
.swatch-card__name { min-width: 0; font-weight: 600; color: var(--blue); }

@media (max-width: 560px) {
  .swatch-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: .5rem; }
  .swatch-card { padding: .4rem .6rem .4rem .4rem; font-size: .875rem; min-height: 44px; }
  .swatch-card__chip { width: 30px; height: 30px; }
  .colours__lede { margin-bottom: 1.1rem; }
}

/* Contact details and social links sit under the about text, sized to fit the
   height of the form column so the section doesn't grow */
.connect { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid rgba(255, 255, 255, .22); }
.connect__heading { font-size: 1rem; font-weight: 600; margin-bottom: .75rem; }
.connect__list { display: grid; grid-template-columns: repeat(2, minmax(0, auto)); justify-content: start; gap: .55rem 2rem; font-size: .875rem; line-height: 1.45; }
.connect__list li { display: flex; gap: .5rem; align-items: center; min-width: 0; }
.connect__address { grid-column: 1 / -1; align-items: start; } /* the street address needs the full row */
.connect__address .icon { margin-top: .15rem; flex: none; }
.connect__list .icon { width: 1rem; height: 1rem; opacity: .9; }
.connect__list strong { font-weight: 600; }
.connect__list a { text-decoration: none; display: inline-block; padding-block: .5rem; margin-block: -.5rem; }
.connect__list a:hover { text-decoration: underline; }
.connect__social { display: flex; align-items: center; gap: 1rem; margin-top: 1rem; }
.connect__label { font-size: .875rem; font-weight: 600; }
.social { display: flex; flex-wrap: wrap; gap: .5rem; }
.social a { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--white); color: var(--blue); transition: transform .15s ease, background-color .15s ease; }
.social a:hover { transform: translateY(-2px); background: var(--mist); }
.social .icon { width: 1.05rem; height: 1.05rem; stroke-width: 1.9; }

.site-footer__legal {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: .5rem 2rem;
  margin-top: clamp(2.5rem, 5vw, 3.5rem); padding-block: 1.25rem; border-top: 1px solid rgba(255, 255, 255, .22);
  font-size: .9rem; color: rgba(255, 255, 255, .85);
}
.site-footer__legal p { margin: 0; }
.site-footer__legal a { display: inline-block; padding-block: .6rem; margin-block: -.6rem; }
.legal-links { display: flex; flex-wrap: wrap; gap: .25rem 1.75rem; }

/* Back to top */
.to-top {
  position: fixed; right: clamp(1rem, 2vw, 1.5rem); bottom: clamp(1rem, 2vw, 1.5rem); z-index: 40;
  display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%;
  background: var(--blue); color: var(--white); border: 2px solid var(--white); /* ring keeps it visible on the blue footer */
  box-shadow: 0 6px 18px -6px rgba(1, 42, 92, .6);
  opacity: 0; visibility: hidden; transform: translateY(8px); transition: opacity .2s ease, transform .2s ease, visibility 0s linear .2s;
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.to-top:hover { background: var(--blue-bright); }

/* ---------- Thank-you page ---------- */
.page-thanks { min-height: 100vh; display: flex; flex-direction: column; }
.page-thanks main { flex: 1; }
.thanks { padding-block: clamp(3rem, 8vw, 6rem); }
.thanks__inner { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: clamp(2rem, 6vw, 5rem); align-items: center; }
.thanks__title { font-weight: 700; text-transform: uppercase; font-size: clamp(2rem, 1.3rem + 3vw, 3.4rem); color: var(--grey); }
.thanks__lede { margin-top: 1.25rem; font-size: 1.25rem; line-height: 1.6; max-width: 34rem; }
.thanks__urgent { margin-top: 1rem; max-width: 34rem; }
.thanks__urgent a { color: var(--blue); font-weight: 600; }
.thanks__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }
.btn--ghost { color: var(--blue); border-color: var(--blue); background: transparent; }
.btn--ghost:hover { background: var(--blue); color: var(--white); }
.thanks__art { overflow: hidden; border-radius: var(--radius); }
.thanks__art img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: 38% 60%; }
.site-footer--slim { padding-top: 0; }
.site-footer--slim .site-footer__legal { margin-top: 0; border-top: 0; }

/* ---------- Terms and Conditions page ---------- */
.page-legal { min-height: 100vh; display: flex; flex-direction: column; }
.page-legal main { flex: 1; }
.legal-hero { background: var(--mist); border-bottom: 1px solid var(--line); padding: clamp(2.5rem, 6vw, 4.5rem) 0 clamp(2rem, 4vw, 3rem); }
.legal-hero .title { margin-bottom: .5rem; }
.legal-hero__meta { margin: 0; color: var(--grey); font-size: .9375rem; }

/* Photo variant (products.html). The blur is baked into the image file, so
   there is no runtime filter and no soft edge to hide. */
.legal-hero--photo {
  position: relative; overflow: hidden; isolation: isolate;
  padding: clamp(3.25rem, 7vw, 5.5rem) 0;
  border-bottom: 0; color: var(--white); background: var(--navy);
}
.legal-hero__bg { z-index: -2; pointer-events: none; }
.legal-hero__bg, .legal-hero__bg img { position: absolute; inset: 0; width: 100%; height: 100%; }
.legal-hero__bg img { object-fit: cover; object-position: 50% 42%; z-index: -2; }
.legal-hero--photo::before {   /* brand-blue shade so white type stays readable over the photo */
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(1, 42, 92, .92) 0%, rgba(1, 42, 92, .78) 48%, rgba(1, 42, 92, .5) 100%);
}
.legal-hero--photo .container { position: relative; z-index: 1; }
.legal-hero--photo .title { color: var(--white); }
.legal-hero--photo .hl { color: #8FC0F0; }
.legal-hero--photo .legal-hero__meta { color: rgba(255, 255, 255, .88); max-width: 62ch; }

/* ---------- contact.html ---------- */
/* ---------- Contact page: reach us ----------
   Details column and map sit side by side. align-items: start keeps the map
   from stretching to the height of the details when one column runs longer. */
.contact-reach__inner { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.contact-reach__lede { margin: .75rem 0 1.75rem; max-width: 46ch; color: var(--grey); line-height: 1.6; }

/* A list with hairlines rather than three boxes: a phone number and a postal
   address do not deserve the same amount of furniture around them. */
.contact-list { margin: 0; padding: 0; list-style: none; }
.contact-item { display: grid; grid-template-columns: 2.75rem minmax(0, 1fr); gap: 1rem; padding: 1.25rem 0; border-top: 1px solid var(--line); }
.contact-item:last-child { border-bottom: 1px solid var(--line); }
.contact-item__icon { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: 50%; background: var(--mist); }
.contact-item__icon .icon { width: 1.35rem; height: 1.35rem; color: var(--blue-bright); }
.contact-item__title { margin-bottom: .3rem; font-size: 1.0625rem; font-weight: 700; color: var(--blue); }
.contact-item__value { margin: 0; font-size: 1.0625rem; line-height: 1.5; overflow-wrap: anywhere; }
.contact-item__value a { text-decoration: none; }
.contact-item__value a:hover { text-decoration: underline; }
.contact-item__note { margin: .4rem 0 0; color: var(--grey); font-size: .9375rem; line-height: 1.5; }

/* ---------- Contact page: map ----------
   A fixed aspect box rather than a fixed height, so the embed keeps its shape
   at every width and the iframe can never push the column around as it loads. */
.map { margin: 0; }
.map__frame { position: relative; aspect-ratio: 4 / 3; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--mist); }
.map__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.map__caption { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .35rem 1.5rem; margin-top: .85rem; color: var(--grey); font-size: .9375rem; }
.map__caption a { font-weight: 600; text-underline-offset: .2em; white-space: nowrap; }
.map__caption a::after { content: " \2197"; }

/* ---------- Contact page: the three enquiry routes ----------
   Cards, not a wall of prose. Each one is a whole route into the business, so
   they get equal weight rather than a heading hierarchy the visitor has to
   read through to find themselves in. The tinted band separates them from the
   details above, so the page reads as three steps: reach us, pick a desk,
   write the message. */
.routes { background: var(--mist); border-top: 1px solid var(--line); }
.routes .title { margin-bottom: .75rem; }
.contact-lede { max-width: 62ch; margin: 0 auto clamp(1.75rem, 3vw, 2.5rem); color: var(--grey); text-align: center; line-height: 1.6; }
.enquiry-types { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem; margin: 0; padding: 0; list-style: none; }
/* Column layout so the link can be pushed to the bottom with margin-top:auto:
   the three bodies are different lengths and a ragged row of links reads as a
   mistake rather than a choice. position: relative anchors the step number. */
.enquiry-type { position: relative; display: flex; flex-direction: column; padding: 1.75rem 1.5rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); }
/* Decorative only, and hidden from assistive tech: it numbers the choices for
   the eye without implying the visitor has to work through all three. */
.enquiry-type__step { position: absolute; top: 1.25rem; right: 1.35rem; font-size: 1.5rem; font-weight: 700; line-height: 1; color: var(--line); }
.enquiry-type .icon { width: 1.75rem; height: 1.75rem; color: var(--blue-bright); margin-bottom: .9rem; }
.enquiry-type__title { margin-bottom: .6rem; font-size: 1.25rem; font-weight: 700; color: var(--blue); }
.enquiry-type p { margin: 0 0 1.25rem; font-size: .9375rem; line-height: 1.6; }
.enquiry-type__link { margin-top: auto; font-weight: 600; text-underline-offset: .2em; }
.enquiry-type__link::after { content: " \2192"; }

.tick-list { display: grid; gap: .6rem; }
.tick-list li { position: relative; padding-left: 1.6rem; line-height: 1.6; }
.tick-list li::before { content: ""; position: absolute; left: 0; top: .62em; width: .5rem; height: .5rem; border-radius: 50%; background: var(--blue-bright); }

.legal { display: grid; grid-template-columns: minmax(0, 17rem) minmax(0, 46rem); gap: clamp(2rem, 5vw, 5rem); padding-block: clamp(2.5rem, 5vw, 4rem) clamp(3.5rem, 7vw, 6rem); }
.legal__toc { position: sticky; top: calc(var(--header-h) + 1.5rem); align-self: start; font-size: .875rem; }
.legal__toc-title { font-size: .8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--grey); margin-bottom: .75rem; }
.legal__toc ol { margin: 0; padding-left: 1.25rem; display: grid; gap: .1rem; }
.legal__toc a { display: inline-block; padding-block: .3rem; color: var(--text); text-decoration: none; line-height: 1.4; }
.legal__toc a:hover { color: var(--blue); text-decoration: underline; }
.legal__body section { scroll-margin-top: calc(var(--header-h) + 1rem); }
.legal__body section + section { margin-top: 2.25rem; padding-top: 2.25rem; border-top: 1px solid var(--line); }
.legal__body h2 { font-size: clamp(1.15rem, 1rem + .5vw, 1.35rem); font-weight: 600; color: var(--blue); margin-bottom: .9rem; }
.legal__body ul { list-style: disc; padding-left: 1.25rem; margin: 0 0 1em; display: grid; gap: .35rem; }
.legal__body a:not(.btn) { color: var(--blue); font-weight: 500; }
.legal__back { margin-top: .5rem; }
.legal-links a[aria-current="page"] { text-decoration: underline; text-underline-offset: .2em; }

/* =====================================================================
   Benefits and Applications pages (benefits.html, applications.html)
   ===================================================================== */

/* Shared: a centred button under a section, and the small variant used inline */
.section-cta { margin: clamp(2rem, 4vw, 3rem) 0 0; text-align: center; }
/* Lines the button up with the open panel rather than letting it straddle the
   charcoal/blue seam that runs down the middle of the band. */
.benefits__cta {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  max-width: var(--container); margin: clamp(1rem, 2vw, 1.75rem) auto 0;
}
.benefits__cta a { grid-column: 2; justify-self: start; margin-left: clamp(2rem, 6vw, 5.5rem); }
.btn--sm { padding: .5rem 1.1rem; font-size: .875rem; }

/* Jump links at the top of benefits.html */
.jump-list {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.jump-list a {
  display: flex; align-items: center; gap: .7rem; height: 100%;
  padding: .8rem 1rem; border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); text-decoration: none; font-size: .9375rem; font-weight: 500; line-height: 1.35;
  transition: border-color .2s ease, color .2s ease, background-color .2s ease;
}
.jump-list a:hover { border-color: var(--blue); color: var(--blue); background: var(--mist); }
.jump-list .icon { width: 1.4rem; height: 1.4rem; color: var(--blue-bright); }

/* One expanded benefit: number and icon on the left, copy on the right */
.benefit-detail {
  display: grid; grid-template-columns: minmax(0, 8rem) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding-block: clamp(2rem, 4vw, 3rem);
  scroll-margin-top: calc(var(--header-h) + 1rem);
}
.benefit-detail + .benefit-detail { border-top: 1px solid var(--line); }
.benefit-detail__aside { display: flex; flex-direction: column; align-items: flex-start; gap: 1rem; }
.benefit-detail__num { font-size: clamp(2.25rem, 1.6rem + 2.4vw, 3.5rem); font-weight: 700; line-height: 1; color: var(--line); }
.benefit-detail__icon {
  width: 3rem; height: 3rem; color: var(--blue);
  fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round;
}
.benefit-detail__title { font-size: clamp(1.35rem, 1.1rem + .9vw, 1.9rem); font-weight: 700; color: var(--blue); margin-bottom: .6rem; }
.benefit-detail__summary { font-size: 1.0625rem; font-weight: 500; color: var(--grey); margin-bottom: 1.25rem; }
.benefit-detail__sub, .use-case__sub {
  margin: 1.5rem 0 .75rem; font-size: .8125rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; color: var(--blue);
}
.benefit-detail__links { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1.5rem 0 0; }

/* One application: photo beside the copy, sides swapping down the page */
.use-case {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.75rem, 4vw, 3.5rem); align-items: center;
  padding-block: clamp(2rem, 4vw, 3.25rem);
  scroll-margin-top: calc(var(--header-h) + 1rem);
}
.use-case + .use-case { border-top: 1px solid var(--line); }
.use-case__media img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  border-radius: var(--radius); background: var(--mist);
}
/* The flipped rows put the photo second in the source but first on screen, so
   the reading order stays photo-then-copy for a screen reader either way. */
.use-case--flip .use-case__media { grid-column: 2; grid-row: 1; }
.use-case__title { font-size: clamp(1.35rem, 1.1rem + .9vw, 1.9rem); font-weight: 700; color: var(--blue); margin-bottom: .9rem; }
.use-case__suits { margin: 1.5rem 0 0; font-size: .9375rem; color: var(--grey); }
.use-case__suits-label {
  display: inline-block; margin-right: .5rem; padding: .15rem .55rem;
  border-radius: 999px; background: var(--mist); color: var(--blue);
  font-size: .75rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
}

/* Closing note and buttons at the foot of both pages */
.note-band {
  margin-top: clamp(2.5rem, 5vw, 4rem); padding: clamp(1.5rem, 3vw, 2.5rem);
  background: var(--mist); border-radius: var(--radius);
}
.note-band__title { font-size: 1.25rem; font-weight: 700; color: var(--blue); margin-bottom: .75rem; }
.note-band p { max-width: 70ch; }
.note-band__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin: 1.5rem 0 0; }

/* =====================================================================
   Responsive
   ===================================================================== */
@media (max-width: 1080px) {
  :root { --header-h: 78px; }
  .site-header__brand img { width: 210px; }

  .nav-toggle {
    display: inline-flex; align-items: center; gap: .6rem; min-height: 44px; padding: .5rem .75rem; margin-right: -.75rem;
    background: none; border: 0; cursor: pointer; color: var(--blue); font-weight: 600; text-transform: uppercase; letter-spacing: .03em;
  }
  .nav-toggle__bars, .nav-toggle__bars::before, .nav-toggle__bars::after { display: block; width: 22px; height: 2px; background: currentColor; transition: transform .2s ease; }
  .nav-toggle__bars { position: relative; }
  .nav-toggle__bars::before, .nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
  .nav-toggle__bars::before { top: -7px; }
  .nav-toggle__bars::after { top: 7px; }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(7px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bars::after { transform: translateY(-7px) rotate(-45deg); }

  .site-nav {
    position: fixed; inset: var(--header-h) 0 auto 0; overflow-y: auto;
    max-height: calc(100vh - var(--header-h));
    max-height: calc(100dvh - var(--header-h));
    background: var(--white); border-top: 1px solid var(--line); box-shadow: 0 0 0 100vmax rgba(1, 42, 92, .45); display: none;
  }
  .site-nav.is-open { display: block; }
  .site-header__brand, .nav-toggle { position: relative; z-index: 2; } /* stay bright above the menu backdrop */
  .site-header { background: var(--white); }
  .site-header__inner { position: relative; }
  .site-header__inner::before { content: ""; position: absolute; inset: 0; background: var(--white); z-index: 1; }
  .site-nav { z-index: 0; }
  .site-nav__list { flex-direction: column; align-items: stretch; gap: 0; padding: .5rem var(--gutter) 1.5rem; }
  .site-nav__list > li { border-bottom: 1px solid var(--line); }
  .site-nav a { width: 100%; justify-content: space-between; padding: 1rem 0; }
  .site-nav__list > li > .is-active::after { left: -.75rem; right: auto; top: .7rem; bottom: .7rem; width: 3px; height: auto; }
  body.nav-open { overflow: hidden; }

  .catalogue { grid-template-columns: minmax(0, 230px) minmax(0, 1fr); }
  .swatches { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .product-cards { grid-template-columns: 1fr 1fr; }
  .product-card:last-child { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
  .hero { margin-inline: 0; min-height: clamp(500px, 82vh, 680px); justify-content: center; }
  .hero { min-height: clamp(500px, 82svh, 680px); }
  .hero::before { background: linear-gradient(0deg, rgba(1, 42, 92, .94) 0%, rgba(1, 42, 92, .78) 34%, rgba(1, 42, 92, .12) 58%, rgba(1, 42, 92, 0) 72%); }
  .hero__bg img { object-position: 30% 50%; }
  .hero__content { text-align: left; width: 100%; padding: 2rem var(--gutter) 6.5rem; }
  .hero__slide { align-items: flex-start; }
  .hero__icon { width: 3.75rem; height: 3.75rem; margin-bottom: 1rem; }
  .hero__actions { justify-content: flex-start; }
  .hero__controls { left: var(--gutter); right: var(--gutter); bottom: 1.5rem; }
  .hero__dots { flex: 1; }
  .hero__dot { flex: 1; width: auto; }

  .feature--shapes .feature__inner, .feature--fins .feature__inner, .feature--louvers .feature__inner { grid-template-columns: 1fr; }
  .feature--louvers .feature__figure { order: -1; }
  .feature--louvers .feature__copy { text-align: left; }
  .feature--louvers .feature__copy p { text-align-last: auto; }
  .feature__copy p { text-align: left; hyphens: manual; }
  .feature--shapes .feature__figure img { width: min(88%, 440px); }

  /* Benefits become an accordion: each panel opens under its own row */
  .benefits { background: var(--charcoal); }
  .benefits__grid { grid-template-columns: 1fr; }
  .benefit__tab { grid-template-columns: 3.25rem 1fr auto; gap: 1rem; min-height: 72px; padding-right: var(--gutter); }
  .benefit__tab::before { inset: 0; }
  .benefit__icon { width: 2.5rem; height: 2.5rem; }
  .benefit__label { padding-left: 1rem; line-height: 2; }
  .benefit__arrow { width: 2.5rem; height: 2.5rem; }
  .benefit__tab[aria-expanded="true"] .benefit__arrow { transform: rotate(135deg); }
  .benefit__panel { grid-column: 1; grid-row: auto; background: var(--blue); padding: .25rem var(--gutter) 1.75rem; }
  .benefit__panel h3 { display: none; } /* the row above already names it */
  .benefit__panel p { text-align: left; hyphens: manual; }
  .benefits__cta { display: block; text-align: center; margin-top: 2rem; padding-inline: var(--gutter); }
  .benefits__cta a { margin-left: 0; }

  .legal-hero--photo::before { background: linear-gradient(90deg, rgba(1, 42, 92, .93) 0%, rgba(1, 42, 92, .86) 100%); }
  .app-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.75rem 1rem; }

  /* Benefits and Applications pages: both two-column layouts stack */
  .jump-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .benefit-detail { grid-template-columns: 1fr; gap: 1.1rem; }
  .benefit-detail__aside { flex-direction: row; align-items: center; gap: 1rem; }
  .benefit-detail__num { font-size: 2.25rem; }
  .use-case { grid-template-columns: 1fr; }
  .use-case--flip .use-case__media { grid-column: 1; grid-row: 1; }

  /* Contact page: the details/map split stacks, and the map keeps a shape
     that is still readable at full width rather than a tall 4:3 box. */
  .contact-reach__inner { grid-template-columns: 1fr; }
  .map__frame { aspect-ratio: 16 / 10; }
  .enquiry-types { grid-template-columns: 1fr; }

  /* Catalogue: filters sit above the grid, each as a row of chips */
  .catalogue { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; }
  .catalogue__filters { position: static; grid-template-columns: minmax(0, 1fr); gap: 1rem; min-width: 0; }
  .filter__list { display: flex; flex-wrap: wrap; gap: .5rem; }
  .choice { min-height: 44px; padding: .4rem .85rem; margin: 0; border: 1px solid var(--line); border-radius: 999px; gap: .55rem; }
  .choice input:checked ~ .choice__label { color: var(--blue); }
  .swatches { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Four square tiles need about 900 px to stay readable, so the shape pages
     step down to three here and to two on phones. */
  .shape-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Gallery and details stack once there is no room for two readable columns. */
  .product-detail__grid { grid-template-columns: minmax(0, 1fr); }
  /* Stacked, the gallery would otherwise run the full width of the container and
     show the panel larger here than on a desktop. Capped and centred instead,
     which also keeps it over the centred thumbnails and 360 button. */
  .gallery { max-width: 560px; margin-inline: auto; }
  .spec--wide { margin-top: 0; }

  .site-footer__grid { grid-template-columns: 1fr; }
  .thanks__inner { grid-template-columns: 1fr; }
  .legal { grid-template-columns: 1fr; }
  .legal__toc { position: static; padding: 1.25rem; background: var(--mist); border-radius: var(--radius); }
}

@media (max-width: 600px) {
  body { font-size: 1rem; }
  .site-header__brand img { width: 178px; }
  .hero__actions .btn { flex: 1 1 100%; }
  .hero__icon { display: none; } /* keeps the headline low so the feature wall stays visible */
  .swatches { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem .85rem; }
  .swatches--panels { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem 1rem; }
  /* Three square tiles across a phone leaves each one about 100px wide, too
     small to read the facets, so the shape pages drop to two. */
  .shape-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem .85rem; }
  .gallery__thumbs button { width: 58px; }
  .spec dt { min-width: 100%; }
  .enquiry-types { gap: 1rem; }
  .enquiry-type { padding: 1.35rem 1.25rem 1.5rem; }
  .enquiry-type__step { top: 1rem; right: 1.1rem; font-size: 1.25rem; }
  .enquiry-type__title { font-size: 1.125rem; }
  .enquiry-type__link { display: inline-flex; align-items: center; min-height: 44px; }
  .jump-list { grid-template-columns: 1fr; }
  .note-band__actions { flex-direction: column; align-items: stretch; }
  /* Phone-sized: tighter rows, a smaller icon well, and every phone, email and
     directions link gets a 44px tap target instead of being a line of inline
     text. The map goes near-square: a wide strip on a narrow screen shows a lot
     of road and not much of where we actually are. */
  .contact-item { grid-template-columns: 2.25rem minmax(0, 1fr); gap: .85rem; padding: 1rem 0; }
  .contact-item__icon { width: 2.25rem; height: 2.25rem; }
  .contact-item__icon .icon { width: 1.15rem; height: 1.15rem; }
  .contact-item__title { font-size: 1rem; }
  .contact-item__value { font-size: 1rem; }
  .contact-item__value a,
  .map__caption a { display: inline-flex; align-items: center; min-height: 44px; }
  .map__frame { aspect-ratio: 5 / 4; }
  .map__caption { gap: .15rem; }
  .product-cards { grid-template-columns: 1fr; }
  .product-card { min-height: 0; }
  .product-card__img { max-height: 190px; }
  .enquiry { grid-template-columns: 1fr; }
  .connect__list { grid-template-columns: 1fr; }
  .enquiry__submit .btn { width: 100%; }
  .thanks__actions .btn { flex: 1 1 100%; }
}

@media (max-width: 400px) {
  :root { --gutter: 1.1rem; }
  .site-header__brand img { width: 158px; }
  .nav-toggle__label {                              /* keeps the bars and the logo clear of each other,
                                                       but stays readable to screen readers */
    position: absolute; width: 1px; height: 1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .hero__title { font-size: 1.7rem; }
  .benefit__tab { grid-template-columns: 2.6rem 1fr auto; gap: .75rem; min-height: 66px; }
  .benefit__icon { width: 2.1rem; height: 2.1rem; }
  .benefit__label { padding-left: .75rem; font-size: .95rem; line-height: 1.35; }
  .benefit__arrow { width: 2.2rem; height: 2.2rem; }
  .benefit__arrow .icon { width: 1.1rem; height: 1.1rem; }
  .app-grid { grid-template-columns: 1fr; gap: 1.5rem; }
  .app__link { gap: .75rem; }
  .choice { padding: .4rem .7rem; }
  .site-header__inner .btn--ghost { padding-inline: .85rem; font-size: .9375rem; } /* logo + CTA overflowed 320px screens */
  .choice__label { font-size: .875rem; }
  .connect__social { flex-wrap: wrap; gap: .6rem 1rem; }
  .site-footer__legal { justify-content: flex-start; }
}

/* Phones held sideways: a 520px-tall hero would fill more than the screen */
/* Phones held sideways: very little height. A slimmer header, and a hero that
   fits the screen under it with the headline, both buttons and the slide
   controls all visible without scrolling. */
@media (max-height: 540px) and (orientation: landscape) {
  :root { --header-h: 62px; }
  .site-header__brand img { width: 150px; }
  .hero { min-height: max(250px, calc(100svh - var(--header-h))); }
  .hero__content { padding-block: 1rem 4.25rem; }
  .hero__icon { display: none; }
  .hero__title { font-size: clamp(1.4rem, 3.8vw, 2rem); }
  .hero__actions { margin-top: 1rem; }
  .hero__actions .btn { flex: 0 0 auto; }
  .hero__controls { bottom: .9rem; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: .01ms !important; animation: none !important; }
}

/* Thank-you pages: notice shown only when the site is opened from disk (file://),
   where PHP cannot run and nothing is actually sent. */
.thanks__preview { margin-bottom: 1.5rem; padding: .85rem 1rem; max-width: 34rem; border-left: 4px solid #b26a00; background: #fff4e0; color: #5a3600; border-radius: 6px; font-size: .95rem; line-height: 1.5; }

/* =====================================================================
   Shapes on products.html: every design, square tiles, and the viewer
   ===================================================================== */
/* The shape renders are exported square (panel cropped tight, the odd tall or
   wide panel centred on white), so the tile is square too and nothing is
   cropped. This replaces the old 4:3 family cards and their height cap. */
.swatch--panel .swatch__img { aspect-ratio: 1 / 1; object-fit: contain; background: var(--white); max-height: none; padding: 0; border: 0; }
.swatch--panel .swatch__name { margin: .6rem 0 0; font-size: .875rem; line-height: 1.35; overflow-wrap: anywhere; }
.swatches--panels { gap: 1.75rem 1.25rem; }

/* A tile reached by a link such as #shape-102 lands clear of the sticky header
   and is briefly marked, so the visitor can see which one they were sent to. */
.swatch--panel { scroll-margin-top: 110px; }
.swatch--panel:target .swatch__name { color: var(--blue); }
.swatch--panel:target .panel-frame { outline: 3px solid var(--blue-bright); outline-offset: 4px; }

.swatch__link:focus-visible { outline: 3px solid var(--blue-bright); outline-offset: 4px; border-radius: 4px; }

/* Viewer dialog */
.modal--viewer { width: min(860px, calc(100vw - 2rem)); max-height: min(94vh, 980px); max-height: min(94svh, 980px); }
.viewer { position: relative; display: flex; flex-direction: column; max-height: inherit; }
.viewer__stage { position: relative; flex: 1 1 auto; min-height: 0; display: grid; place-items: center; padding: clamp(1rem, 3vw, 2rem) clamp(3.25rem, 7vw, 4.5rem); background: var(--white); }
.viewer__img {
  display: block; width: auto; height: auto; max-width: 100%;
  max-height: calc(min(94svh, 980px) - 9.5rem); aspect-ratio: 1 / 1; object-fit: contain;
  transition: filter .25s ease;
}
.viewer__img.is-loading { filter: blur(2px); }
.viewer__nav { top: 50%; transform: translateY(-50%); }
.viewer__nav--prev { left: .75rem; }
.viewer__nav--next { right: .75rem; }
.viewer__bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem 1.25rem;
  padding: 1rem clamp(1.25rem, 3vw, 2rem); border-top: 1px solid var(--line); background: var(--mist);
}
.viewer__name { font-size: clamp(1rem, .95rem + .4vw, 1.25rem); font-weight: 700; color: var(--blue); line-height: 1.3; }
.viewer__count { margin: .15rem 0 0; font-size: .875rem; color: var(--grey); }

@media (max-width: 600px) {
  .swatches--panels { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem .85rem; }
  .swatch--panel .swatch__name { font-size: .8125rem; }
  .viewer__stage { padding: .75rem .75rem 3.75rem; }
  .viewer__img { max-height: calc(90svh - 11rem); }
  .viewer__nav { top: auto; bottom: .6rem; transform: none; }
  .viewer__nav--prev { left: calc(50% - 50px); }
  .viewer__nav--next { right: calc(50% - 50px); }
  .viewer__bar .btn { width: 100%; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) { .viewer__img { transition: none; } }
.viewer__actions { display: flex; flex-wrap: wrap; gap: .6rem; }
@media (max-width: 600px) { .viewer__actions { width: 100%; } .viewer__actions .btn { flex: 1 1 100%; } }

/* "See more" under the shape grid sits clear of the last row */
[data-shapes-more-bar] { margin-top: clamp(2rem, 3.5vw, 2.75rem); }

/* Our Products gets a slightly wider page than the rest of the site, so four
   shape tiles across are large enough to read the facets (about 240px each on
   a 1440px screen, up from 210) while two full rows still fit on one screen
   down to a 1366 x 768 laptop. The Louver and Fin swatches share the grid and
   grow with it. */
@media (min-width: 1081px) {
  .products--page .container { max-width: 1440px; }
}

/* Other Designs carousel on the design pages: same names as the Shapes grid on
   products.html, set the same way. */
.shape-tile__name { display: block; margin: .6rem 0 0; font-size: .875rem; font-weight: 600; line-height: 1.35; color: #2B2D30; overflow-wrap: anywhere; transition: color .25s ease; }
.shape-tile__link:hover .shape-tile__name { color: var(--blue); }
@media (max-width: 600px) { .shape-tile__name { font-size: .8125rem; } }

/* Very narrow phones (320-360px): five thumbnails at 58px plus gaps are wider
   than the column, so they shrink a little rather than scroll. */
@media (max-width: 360px) {
  .gallery__thumbs { gap: .4rem; }
  .gallery__thumbs button { width: 48px; }
}

/* ---------- Responsive polish (products filters) ----------
   Desktop: the filter column is sticky. With the Shape family list it can be
   taller than a short laptop window (1280 x 720), which left the last options
   unreachable while it was stuck, so it scrolls within itself when needed. */
@media (min-width: 901px) {
  .catalogue__filters {
    max-height: calc(100vh - var(--header-h) - 2.5rem);
    max-height: calc(100svh - var(--header-h) - 2.5rem);
    overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
    padding: 2px; margin: -2px;   /* room for the focus ring inside the scroller */
  }
}
/* Phones: each filter list becomes one swipeable row of chips instead of
   wrapping onto three lines, so the first shapes appear about 200px sooner.
   The fade on the right edge says there is more to swipe to. */
@media (max-width: 600px), (max-height: 540px) and (orientation: landscape) {
  .filter { padding: .9rem 1rem 1rem; }
  .filter__head { margin-bottom: .6rem; }
  .filter__list {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: -1rem; padding: 2px 1rem; scroll-padding-inline: 1rem;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent);
            mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent);
  }
  .filter__list::-webkit-scrollbar { display: none; }
  .filter__list > li { flex: 0 0 auto; }
  .choice { white-space: nowrap; }
}
.filter { min-width: 0; }
/* Keeps the visually hidden inputs inside their chip; otherwise they sit at their static position and, in the swipeable phone row, widen the page. */
.choice { position: relative; }

/* Terms panel: keep the effective date visible on phones too (the pop-up form
   hides its lede below 760px to save height; this panel scrolls anyway). */
.modal__text .modal__lede { display: block; }

@media (max-width: 900px) {
  .hero.hero--strip[data-bg="photo"]::before { background: linear-gradient(0deg, rgba(1, 42, 92, .94) 0%, rgba(1, 42, 92, .78) 34%, rgba(1, 42, 92, .12) 58%, rgba(1, 42, 92, 0) 72%); }
}

/* "Call now" line under the product quote forms */
.quote-call {
  grid-column: 1 / -1; display: flex; align-items: center; gap: .75rem; margin: .25rem 0 0;
  padding: .8rem 1rem; border-radius: var(--radius); background: var(--mist); color: var(--charcoal); line-height: 1.45; font-size: .9375rem;
}
.quote-call .icon { width: 1.6rem; height: 1.6rem; flex: none; color: var(--blue); }
.quote-call strong { display: block; color: var(--blue); font-weight: 600; }
.quote-call a { color: var(--blue); font-weight: 600; text-decoration: none; white-space: nowrap; }
.quote-call a:hover { text-decoration: underline; }
@media (max-width: 760px) { .quote-call { padding: .6rem .8rem; font-size: .875rem; } }

/* The headline block (z-index 1) overlapped the progress line and swallowed
   clicks on it; lift the controls above it. */
.hero__controls { z-index: 2; }
