/* ==========================================================================
   Sections — hero carousel, spec module, process, gallery, page headers
   Layout comes from Bootstrap's grid; this file supplies the visual identity.
   ========================================================================== */

/* ---- Home hero -----------------------------------------------------------
   A full-bleed banner that still behaves like a datasheet: the photograph
   runs the full width of the viewport, the copy stays on the page grid, and
   the technical callout sits in the control bar as the constant beneath it.

   The header is fixed and transparent over a light page, so the band starts
   below it rather than under it — the logo and nav keep their light ground
   instead of fighting whatever photograph is showing. */

.hero {
  position: relative;
  padding-top: var(--header-h);
  /* the strip the fixed header sits on stays the page colour, so the logo
     and nav are never asked to hold up over a photograph */
  background: var(--resin);
  overflow: hidden;
}

.hero h1,
.hero .h1 {
  margin-bottom: 1.35rem;
  color: #fff;
  /* a shade tighter than --t-hero: the banner gives the line more width than
     the old half-column did, and four lines of display type is a wall */
  font-size: clamp(2.2rem, 4vw, 3.8rem);
}
.hero h1 em,
.hero .h1 em { font-style: normal; color: #f8a072; }
.hero__lead {
  font-size: var(--t-lead);
  color: rgba(255, 255, 255, 0.84);
  max-width: 52ch;
  line-height: 1.55;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-top: 2rem; }

/* ---- Hero carousel --------------------------------------------------------
   Bootstrap's carousel handles autoplay, pause-on-hover, keyboard and touch.
   Copy and photograph advance together because both live in the same slide. */

.hero .carousel { position: relative; }
.hero .carousel-item { transition-duration: 700ms; }

.hero__frame { position: relative; height: clamp(500px, 72vh, 780px); }
.hero__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Scrim: heavy on the left where the copy sits, with a second wash top and
   bottom so the fixed header and the control bar both stay readable over
   whatever the photograph happens to be doing there. */
.hero__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      90deg,
      rgba(16, 25, 23, 0.88) 0%,
      rgba(16, 25, 23, 0.66) 38%,
      rgba(16, 25, 23, 0.15) 76%,
      rgba(16, 25, 23, 0.05) 100%
    ),
    linear-gradient(
      180deg,
      rgba(16, 25, 23, 0.35) 0%,
      rgba(16, 25, 23, 0) 28%,
      rgba(16, 25, 23, 0.55) 100%
    );
}

.hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  padding-bottom: clamp(5.5rem, 12vh, 8.5rem);
}
.hero__overlay > .container { width: 100%; }
.hero__copy { max-width: min(720px, 62%); }
@media (max-width: 991.98px) {
  .hero__copy { max-width: 100%; }
}
.hero .eyebrow { color: #f8b79a; }

/* Below xl the callout leaves the bar, so the copy needs less room under it. */
@media (max-width: 1199.98px) {
  .hero__overlay { padding-bottom: clamp(4.5rem, 10vh, 6.5rem); }
}

/* Phones. A banner sized in viewport heights turns into a full screen of
   photograph with the copy crushed against the controls, so here the band is
   sized to hold the longest slide's copy and the type steps down to match.
   Every slide is held to the same height so the band never jumps as it
   advances. */
@media (max-width: 767.98px) {
  /* Capped both ways: roughly three-quarters of the screen, but never so
     short (landscape, small phones) that the copy has nowhere to go. */
  .hero__frame { height: clamp(420px, 72vh, 540px); }
  .hero h1,
  .hero .h1 {
    font-size: clamp(1.6rem, 1.15rem + 2.2vw, 2rem);
    line-height: 1.12;
    margin-bottom: 0.8rem;
  }
  .hero__lead {
    font-size: 0.94rem;
    line-height: 1.45;
  }
  .hero__overlay { padding-bottom: 4.25rem; }
  /* A wrapping eyebrow would otherwise centre its rib marker against two
     lines and leave it stranded on its own. */
  .hero .eyebrow,
  .showcase .eyebrow { align-items: flex-start; }
  .hero .eyebrow::before,
  .showcase .eyebrow::before { margin-top: 0.42em; }
  .hero__actions { margin-top: 1.35rem; gap: 0.6rem; }
  .hero__actions .btn { padding: 0.75rem 1.15rem; }
  .hero-controls { bottom: 1rem; }
}

/* Narrow phones: the same copy runs to more lines, so the band gets a little
   more room to keep it clear of the controls. */
@media (max-width: 399.98px) {
  .hero__frame { height: clamp(440px, 78vh, 560px); }
  .hero__lead { font-size: 0.9rem; }
  .hero__overlay { padding-bottom: 3.85rem; }
  .hero__actions { margin-top: 1.1rem; }
}

@media (max-width: 359.98px) {
  .hero__frame { height: clamp(460px, 84vh, 560px); }
  .hero__lead { font-size: 0.86rem; }
}

/* Short screens — an old small phone, or any phone held sideways. There is
   no honest way to fit a headline, a paragraph and two buttons into 500-odd
   pixels, so the supporting line steps aside and the headline and the CTAs
   carry the slide. The same words open the sections below. */
@media (max-width: 767.98px) and (max-height: 620px) {
  .hero__lead { display: none; }
}

/* Copy rises in, one element after another, when a slide becomes active. */
.hero .carousel-item.active .hero__copy > * {
  animation: slide-in 700ms var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 90ms);
}
.hero__copy > :nth-child(2) { --i: 1; }
.hero__copy > :nth-child(3) { --i: 2; }
.hero__copy > :nth-child(4) { --i: 3; }
@keyframes slide-in {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* A slow push on the active photograph. Not a zoom for its own sake — it
   keeps a still product shot from reading as a frozen frame. */
.hero .carousel-item.active .hero__frame img {
  animation: hero-drift 9s var(--ease-out) both;
}
@keyframes hero-drift {
  from { transform: scale(1.07); }
  to   { transform: none; }
}

/* Technical callout — the constant behind every slide, so it sits in the
   control bar rather than on any one photograph. */
.hero__callout {
  width: min(320px, 100%);
  margin: 0;
  background: var(--paper);
  border: 1px solid var(--ink);
  border-radius: var(--radius);
  padding: 1rem 1.1rem 1.1rem;
  box-shadow: var(--shadow-2);
}
.hero__callout .label {
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
  margin-bottom: 0.7rem;
}
.hero__callout .readout {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.7rem;
  font-family: var(--font-data);
  font-size: 0.78rem;
  color: var(--ink-2);
}

/* ---- Carousel controls ---------------------------------------------------- */

.hero-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(1.25rem, 2.6vw, 2.25rem);
  z-index: 5;
  /* The bar spans the full width and, with the callout in it, rises into the
     slide — its empty space must let clicks through to the slide's CTAs. */
  pointer-events: none;
}
.hero-controls__group,
.hero__callout { pointer-events: auto; }
.hero-controls__group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
}

/* Bootstrap positions indicators over the slide; here they belong in the
   control bar below it. */
.hero-controls .carousel-indicators {
  position: static;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* The indicators are ribs. The active one fills across the slide's own
   duration, so the control doubles as the timer. */
/* The rib is 2px of ink, but the button around it is a touch target — hence
   the height, which is empty space either side of the rib. */
.hero-controls .carousel-indicators [data-bs-target] {
  position: relative;
  width: clamp(34px, 6vw, 58px);
  height: 34px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  opacity: 1;
  text-indent: 0;
  transition: none;
}
.hero-controls .carousel-indicators [data-bs-target]::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 16px;
  height: 2px;
  background: rgba(255, 255, 255, 0.34);
  border-radius: var(--radius-pill);
}
.hero-controls .carousel-indicators [data-bs-target]::after {
  content: "";
  position: absolute;
  left: 0;
  top: 16px;
  height: 2px;
  width: 0;
  background: var(--accent);
  border-radius: var(--radius-pill);
}
.hero-controls .carousel-indicators [data-bs-target]:hover::before { background: rgba(255, 255, 255, 0.7); }

.hero-controls .carousel-indicators .active::after {
  animation: rib-fill var(--slide-dur, 7000ms) linear both;
}
/* Paused, the fill has nothing to count down, so it sits full instead —
   otherwise a paused slider shows no current-slide marker at all. */
.is-paused .carousel-indicators .active::after { animation: none; width: 100%; }
@keyframes rib-fill { from { width: 0; } to { width: 100%; } }

.hero-nav { display: flex; align-items: center; gap: 0.5rem; }

.hero-btn {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  background: rgba(16, 25, 23, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.34);
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease);
}
.hero-btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

.hero-btn .ico-play { display: none; }
.is-paused .hero-btn .ico-play { display: block; }
.is-paused .hero-btn .ico-pause { display: none; }

@media (prefers-reduced-motion: reduce) {
  .hero .carousel-item.active .hero__copy > *,
  .hero .carousel-item.active .hero__frame img,
  .hero-controls .carousel-indicators .active::after { animation: none; }
  .hero-controls .carousel-indicators .active::after { width: 100%; }
}

/* ---- Spec ticker ---------------------------------------------------------- */

.ticker {
  border-block: 1px solid var(--flute);
  background: var(--paper);
  overflow: hidden;
  position: relative;
}
.ticker__track { display: flex; width: max-content; animation: ticker 46s linear infinite; }
.ticker:hover .ticker__track { animation-play-state: paused; }
@keyframes ticker { to { transform: translateX(-50%); } }

.ticker__group { display: flex; flex-shrink: 0; }
.ticker__item {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.95rem clamp(1.1rem, 2.4vw, 2rem);
  font-family: var(--font-data);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
}
.ticker__item::after {
  content: "";
  width: 5px;
  height: 5px;
  background: var(--accent);
  transform: rotate(45deg);
  flex-shrink: 0;
}
.ticker__item b { color: var(--ink); font-weight: 600; }

/* ---- Signature: the interactive sheet cross-section ----------------------- */

.flute-stage {
  background: var(--paper);
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
  padding: clamp(1.1rem, 2.4vw, 2rem);
  position: relative;
}
.flute-stage__head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.9rem;
}
.flute-stage__title {
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.flute-readout {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.flute-readout .unit { font-size: 0.5em; color: var(--ink-3); margin-left: 0.2em; letter-spacing: 0; }

.flute-svg { width: 100%; height: auto; display: block; }

.range-row__meta {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.6rem;
}

/* Specify-it controls: heading, then one row per choice, then the drawing. */
.flute-controls { margin-bottom: clamp(2rem, 4vw, 3rem); }
.flute-controls h3 { margin-bottom: 1.5rem; }
.flute-controls .range-row + .range-row { margin-top: 1.75rem; }
.flute-controls .form-select { margin-top: 0.1rem; }

.form-range.flute-range { --bs-form-range-thumb-bg: var(--accent); }
.form-range.flute-range::-webkit-slider-thumb { width: 12px; height: 26px; border-radius: var(--radius-sm); margin-top: -11.5px; }
.form-range.flute-range::-moz-range-thumb { width: 12px; height: 26px; border-radius: var(--radius-sm); }
.form-range.flute-range::-webkit-slider-runnable-track { height: 3px; background: var(--flute); }
.form-range.flute-range::-moz-range-track { height: 3px; background: var(--flute); }

.swatches { display: flex; flex-wrap: wrap; gap: 0.55rem; }
.swatch {
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  border: 1px solid var(--flute);
  cursor: pointer;
  padding: 0;
  position: relative;
  transition: transform var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.swatch:hover { transform: translateY(-2px); }

/* Stock colours. Each button's data-colour carries the same value for
   flute.js, which paints the sheet with it. */
.swatch--white { background: #f4f6f4; }
.swatch--blue { background: #1b57a8; }
.swatch--green { background: #1f7a45; }
.swatch--black { background: #14181a; }
.swatch--orange { background: #e8541f; }
.swatch--red { background: #c0271f; }
.swatch--grey { background: #7c8a89; }
.swatch--silver { background: #b9c2c4; }
.swatch[aria-pressed="true"],
.swatch--any.is-picked { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px var(--ink); }

/* Any-colour picker: a rainbow swatch wrapping a native colour input. */
.swatch--any {
  display: inline-block;
  overflow: hidden;
  background: conic-gradient(#e53935, #fdd835, #43a047, #1e88e5, #8e24aa, #e53935);
}
.swatch--any input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.swatch--any:focus-within { outline: 2px solid var(--ink); outline-offset: 2px; }

.spec-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 0; border-top: 1px solid var(--flute); }
.spec-list li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.15rem 1rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--flute-soft);
  font-size: 0.92rem;
}
.spec-list .k {
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* A long value (“UV · fire retardant · anti-static”) would otherwise be
   squeezed to a few pixels by the label beside it; let it take its own line. */
.spec-list .v {
  font-family: var(--font-data);
  color: var(--ink);
  text-align: right;
  flex: 1 1 auto;
  min-width: 0;
}
@media (max-width: 575.98px) {
  .spec-list .v { flex-basis: 100%; text-align: left; }
}
/* On the contact page these values are the phone number and the email — the
   things a visitor actually taps. */
.spec-list .v a { display: inline-block; padding-block: 0.3rem; }

/* Thickness chart — each row draws the twin-wall section of one gauge. The
   cell grows with --mm, so the thicker sheets read visibly deeper. */
.thickness-chart {
  list-style: none;
  padding: 0;
  margin: 2rem 0 0;
  display: grid;
  gap: 1.1rem;
  max-width: 760px;
}
.thickness-chart li {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  align-items: center;
  gap: 1rem;
}
.thickness-chart__label {
  font-family: var(--font-data);
  font-size: 0.95rem;
  color: #fff;
  white-space: nowrap;
}
.thickness-chart__in { color: rgba(255, 255, 255, 0.62); }
/* Sheet thickness per row, in mm — drives the bar depth below. */
.thickness-chart .mm-2 { --mm: 2; }
.thickness-chart .mm-3 { --mm: 3; }
.thickness-chart .mm-4 { --mm: 4; }
.thickness-chart .mm-5 { --mm: 5; }
.thickness-chart .mm-6 { --mm: 6; }
.thickness-chart .mm-7 { --mm: 7; }
.thickness-chart .mm-8 { --mm: 8; }
.thickness-chart .mm-9 { --mm: 9; }
.thickness-chart .mm-10 { --mm: 10; }
.thickness-chart__bar {
  --cell: calc(0.4rem + var(--mm) * 0.16rem);
  display: block;
  height: var(--cell);
  border: 1.5px solid rgba(255, 255, 255, 0.85);
  background: repeating-linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.85) 0 1.5px,
    transparent 1.5px var(--cell)
  );
  transform-origin: left center;
}
@media (max-width: 575.98px) {
  .thickness-chart li { grid-template-columns: 1fr; gap: 0.4rem; }
}
@media (prefers-reduced-motion: no-preference) {
  .thickness-chart.reveal .thickness-chart__bar {
    transform: scaleX(0);
    transition: transform var(--dur-3) var(--ease-out);
  }
  .thickness-chart.reveal.is-in .thickness-chart__bar { transform: none; }
  .thickness-chart li:nth-child(2) .thickness-chart__bar { transition-delay: 80ms; }
  .thickness-chart li:nth-child(3) .thickness-chart__bar { transition-delay: 160ms; }
  .thickness-chart li:nth-child(4) .thickness-chart__bar { transition-delay: 240ms; }
  .thickness-chart li:nth-child(5) .thickness-chart__bar { transition-delay: 320ms; }
  .thickness-chart li:nth-child(6) .thickness-chart__bar { transition-delay: 400ms; }
}

.spec-list__caption {
  display: block;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.75rem;
}

/* Wide variant: on roomy screens the rows sit side by side as a spec strip. */
@media (min-width: 780px) {
  .spec-list--wide {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
    border-top: 0;
    gap: 0 clamp(1.5rem, 3vw, 3rem);
  }
  .spec-list--wide li {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
    border-top: 1px solid var(--flute);
    border-bottom: 0;
    padding-block: 0.85rem 0;
  }
  .spec-list--wide .v { text-align: left; }
}

/* The drawing itself */
[data-flute] { --sheet: var(--pp-blue); display: block; }
.fl-wall { fill: var(--sheet); }
.fl-fill { fill: var(--sheet); opacity: 0.13; }
.fl-rib { fill: var(--sheet); opacity: 0.5; }

/* Pale stock (white / silver) needs an outline to read on a white card */
[data-flute].is-pale .fl-wall { stroke: var(--ink-3); stroke-width: 1; }
[data-flute].is-pale .fl-rib { opacity: 0.75; stroke: var(--flute); stroke-width: 0.5; }

.fl-ext { stroke: var(--flute); stroke-width: 1; stroke-dasharray: 3 3; }
.fl-dim { stroke: var(--ink-3); stroke-width: 1; }

/* Ribs extrude into place, left to right */
[data-flute] .fl-rib { transform-box: fill-box; transform-origin: center; transform: scaleY(0); }
[data-flute].is-drawn .fl-rib {
  animation: rib-in 460ms var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 38ms);
}
@keyframes rib-in { to { transform: scaleY(1); } }

/* V profile: one zig-zag stroke that draws itself on, left to right */
.fl-rib--v { fill: none; stroke: var(--sheet); stroke-width: 5; stroke-linejoin: miter; }
[data-flute] .fl-rib--v { transform: none; stroke-dasharray: 1; stroke-dashoffset: 1; }
[data-flute].is-drawn .fl-rib--v { animation: v-in 900ms var(--ease-out) forwards; }
[data-flute].is-pale .fl-rib--v { stroke: var(--ink-3); stroke-width: 3; opacity: 0.6; }
.fl-rib--x,
[data-flute].is-pale .fl-rib--x { stroke-width: 3; }
[data-flute-mini] .fl-rib--x { stroke-width: 2; }
@keyframes v-in { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  [data-flute] .fl-rib { transform: none; animation: none; }
  [data-flute] .fl-rib--v { stroke-dashoffset: 0; }
}

/* ---- Process ---------------------------------------------------------------
   Numbering is used here because the content genuinely is an ordered
   sequence: material cannot be printed before it is corona treated. */

.process__step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(1rem, 2.5vw, 2.25rem);
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  align-items: start;
}
.process__step:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.16); }
.process__num {
  font-family: var(--font-data);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: #f08a5d;
  padding-top: 0.35rem;
  min-width: 2.5rem;
}
.process__body h3 { margin-bottom: 0.5rem; }
.process__body p { color: rgba(255, 255, 255, 0.7); font-size: 0.96rem; max-width: 62ch; margin: 0; }
.process__meta {
  margin-top: 0.7rem;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
/* Below 860 the three children fall into a two-column grid, and the meta
   line lands under the number — where its own text widens the `auto` column
   and squeezes the step's body to a ribbon. Pin the number's column and send
   the meta line under the body instead. */
@media (max-width: 859.98px) {
  .process__step { grid-template-columns: 2.75rem 1fr; gap: 0.5rem 0.75rem; }
  .process__num { min-width: 0; }
  .process__meta { grid-column: 2; margin-top: 0.25rem; }
}

@media (min-width: 860px) {
  .process__step { grid-template-columns: 4rem 1fr 15rem; }
  .process__meta { margin-top: 0.35rem; text-align: right; }
}

/* ---- Full-width showcase slider ----------------------------------------------
   The one band on the page that ignores the container: the photograph runs
   edge to edge, while its caption and controls stay on the page grid so the
   type still lines up with everything above and below it. */

.showcase {
  position: relative;
  background: var(--ink);
  overflow: hidden;
}
.showcase .carousel-item { transition-duration: 800ms; }

/* Shorter than the hero band on purpose — it reads as a second, quieter beat
   rather than a repeat of the banner — but not so short that the wide source
   photographs get cropped down to an abstract strip. */
.showcase__frame {
  position: relative;
  height: clamp(420px, 62vh, 680px);
}
.showcase__frame img,
.showcase__frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Scrim: dark at the foot so the caption holds contrast over any photograph,
   and a lighter wash at the head so the image still reads as the subject. */
.showcase__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  /* background:
    linear-gradient(
      180deg,
      rgba(16, 25, 23, 0.4) 0%,
      rgba(16, 25, 23, 0.06) 26%,
      rgba(16, 25, 23, 0.62) 72%,
      rgba(16, 25, 23, 0.92) 100%
    ),
    linear-gradient(90deg, rgba(16, 25, 23, 0.55) 0%, rgba(16, 25, 23, 0) 62%); */
}

/* The same slow push the hero photograph gets — a still frame at this size
   otherwise reads as a stalled slideshow. */
.showcase .carousel-item.active .showcase__frame img {
  animation: showcase-drift 11s var(--ease-out) both;
}
@keyframes showcase-drift {
  from { transform: scale(1.08); }
  to   { transform: none; }
}

.showcase__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(5rem, 9vw, 7rem);
  z-index: 2;
  color: #fff;
}
/* The video band has no control bar under the caption, so it sits lower. */
.showcase--video .showcase__caption { bottom: clamp(3rem, 6vw, 4.5rem); }
.showcase__caption .eyebrow { color: #f8b79a; margin-bottom: 0.8rem; }
.showcase__caption h2 {
  color: #fff;
  max-width: 20ch;
  margin-bottom: 1.35rem;
  text-shadow: 0 2px 24px rgba(16, 25, 23, 0.45);
}
.showcase__caption .link-rib { color: #fff; }
.showcase__caption .link-rib:hover { color: #f8b79a; }

/* Caption copy rises in as its slide becomes active. */
.showcase .carousel-item.active .showcase__caption > .container > * {
  animation: slide-in 700ms var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 90ms);
}
.showcase__caption h2 { --i: 1; }
.showcase__caption .link-rib { --i: 2; }

/* ---- Showcase controls ---- */

.showcase__bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(1.25rem, 2.6vw, 2.25rem);
  z-index: 3;
}
.showcase__count {
  font-size: var(--t-micro);
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}
.showcase__count b { color: #fff; font-weight: 500; }

/* Bootstrap parks indicators over the slide; here they belong in the bar. */
.showcase__bar .carousel-indicators {
  position: static;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex: 1 1 auto;
}
.showcase__dots [data-bs-target] {
  width: clamp(34px, 4vw, 44px);
  height: 32px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  opacity: 1;
  text-indent: 0;
  position: relative;
  transition: none;
}
.showcase__dots [data-bs-target]::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 15px;
  height: 2px;
  background: rgba(255, 255, 255, 0.34);
  border-radius: var(--radius-pill);
}
.showcase__dots [data-bs-target]:hover::before { background: rgba(255, 255, 255, 0.7); }
.showcase__dots .active::before { background: var(--accent); }

.showcase__nav { display: flex; align-items: center; gap: 0.5rem; }
.showcase__btn {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  background: rgba(16, 25, 23, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.34);
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.showcase__btn:hover { background: var(--accent); border-color: var(--accent); }

/* On a phone the caption is four short lines, so the band comes down with it
   rather than leaving two-thirds of the screen as untouched photograph. */
@media (max-width: 767.98px) {
  .showcase__frame { height: clamp(300px, 52vh, 400px); }
  .showcase__caption { bottom: clamp(4.75rem, 14vw, 5.5rem); }
  .showcase__caption h2 { font-size: clamp(1.4rem, 1.1rem + 1.6vw, 1.75rem); max-width: 24ch; }
}

@media (max-width: 575.98px) {
  .showcase__count { display: none; }
  .showcase__btn { width: 38px; height: 38px; }
}

@media (prefers-reduced-motion: reduce) {
  .showcase .carousel-item.active .showcase__frame img,
  .showcase .carousel-item.active .showcase__caption > .container > * { animation: none; }
}

/* ---- Media frame ------------------------------------------------------------ */

.media-frame {
  position: relative;
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--resin-deep);
}
.media-frame img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.media-frame--free img { aspect-ratio: auto; }

/* About "Who we are": the company line is long, so the heading runs a size
   down, and the photo stretches to the height of the copy beside it. */
.about-intro h2 { font-size: clamp(1.75rem, 1.2rem + 1.8vw, 2.6rem); max-width: 24ch; }
.about-intro .lead { font-size: clamp(1.05rem, 1rem + 0.3vw, 1.2rem); }
@media (min-width: 992px) {
  .about-intro .media-frame { height: 100%; }
  .about-intro .media-frame img { height: 100%; min-height: 420px; aspect-ratio: auto; }
}

/* Thumbnail strip under the main product shot. The sources are all different
   shapes, so the crop is fixed here rather than left to each file. */
.media-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6rem; }
.media-thumbs .masonry__item { margin: 0; cursor: pointer; border-radius: var(--radius); }
[data-media-thumb] { aspect-ratio: 4 / 3; }
[data-media-thumb] img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Product gallery slider (built by main.js). The main shot becomes a track
   of slides with arrows and a counter; the thumbs become one scrolling row. */
.media-frame[data-slider] { touch-action: pan-y; user-select: none; }
.media-track {
  display: flex;
  align-items: flex-start;
  transition: transform 450ms var(--ease-out);
  will-change: transform;
}
.media-track.is-dragging { transition: none; }
.media-track .media-slide {
  flex: 0 0 100%;
  min-width: 0;
  height: auto;
  display: block;
  transition: transform 250ms var(--ease-out);
}
.media-track .media-slide.is-zoom { transform: scale(1.8); cursor: zoom-in; transition: none; }
@media (hover: hover) and (pointer: fine) { .media-track .media-slide { cursor: zoom-in; } }

.media-nav {
  position: absolute;
  top: 50%;
  z-index: 3;
  width: 44px;
  height: 44px;
  margin-top: -22px;
  display: grid;
  place-items: center;
  padding: 0 0 3px;
  border: 1px solid var(--flute);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: var(--ink);
  font-size: 1.9rem;
  line-height: 1;
  box-shadow: 0 6px 18px rgba(16, 25, 23, 0.16);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease), color var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease), opacity var(--dur-2) var(--ease);
}
.media-nav--prev { left: 0.75rem; }
.media-nav--next { right: 0.75rem; }
.media-nav:hover,
.media-nav:focus-visible { background: var(--accent); border-color: var(--accent); color: #fff; }
@media (hover: hover) and (pointer: fine) {
  .media-frame[data-slider] .media-nav { opacity: 0; }
  .media-frame[data-slider]:hover .media-nav,
  .media-frame[data-slider] .media-nav:focus-visible { opacity: 1; }
}

.media-count {
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  z-index: 3;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-pill);
  background: rgba(16, 25, 23, 0.7);
  color: #fff;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  pointer-events: none;
}

.media-thumbs-wrap { position: relative; }
.media-thumbs-wrap .media-thumbs {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.media-thumbs-wrap .media-thumbs::-webkit-scrollbar { display: none; }
.media-thumbs-wrap [data-media-thumb] {
  flex: 0 0 calc((100% - 3 * 0.6rem) / 4);
  scroll-snap-align: start;
  cursor: pointer;
  opacity: 0.65;
  transition: opacity var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
@media (max-width: 575.98px) {
  .media-thumbs-wrap [data-media-thumb] { flex-basis: calc((100% - 3 * 0.6rem) / 3.5); }
}
.media-thumbs-wrap [data-media-thumb]:hover { opacity: 1; }
.media-thumbs-wrap [data-media-thumb][aria-pressed="true"] {
  opacity: 1;
  border: 2px solid var(--accent);
}
/* A picker, not a gallery tile: no hover shade or push-in. */
.media-thumbs-wrap [data-media-thumb]::after { display: none; }
.media-thumbs-wrap [data-media-thumb]:hover img { transform: none; }

.media-thumbs-nav {
  position: absolute;
  top: 50%;
  z-index: 2;
  width: 32px;
  height: 32px;
  margin-top: -16px;
  display: grid;
  place-items: center;
  padding: 0 0 2px;
  border: 1px solid var(--flute);
  border-radius: 50%;
  background: #fff;
  color: var(--ink);
  font-size: 1.4rem;
  line-height: 1;
  box-shadow: 0 4px 12px rgba(16, 25, 23, 0.18);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-2) var(--ease), background var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
.media-thumbs-nav.is-shown { opacity: 1; visibility: visible; }
.media-thumbs-nav--prev { left: -0.6rem; }
.media-thumbs-nav--next { right: -0.6rem; }
.media-thumbs-nav:hover,
.media-thumbs-nav:focus-visible { background: var(--accent); border-color: var(--accent); color: #fff; }

.tick-list { list-style: none; padding: 0; display: grid; gap: 0.8rem; margin: 1.5rem 0 0; }
.tick-list li {
  display: grid;
  grid-template-columns: 20px 1fr;
  gap: 0.75rem;
  font-size: 0.97rem;
  color: var(--ink-2);
  align-items: start;
}
.tick-list li::before {
  content: "";
  width: 6px;
  height: 11px;
  margin: 0.3em 0 0 3px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
}
.section--ink .tick-list li,
.section--deep .tick-list li { color: rgba(255, 255, 255, 0.76); }

/* ---- Page header (interior pages) -------------------------------------------- */

.page-head {
  padding-top: calc(var(--header-h) + clamp(2.5rem, 5vw, 4.5rem));
  padding-bottom: clamp(2rem, 4vw, 3.25rem);
  border-bottom: 1px solid var(--flute);
  position: relative;
  overflow: hidden;
}
.page-head::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 9px;
  background-image: repeating-linear-gradient(90deg, var(--flute) 0 1px, transparent 1px 10px);
  opacity: 0.7;
}
.page-head h1 { font-size: var(--t-display); margin-block: 0.9rem 0; }
.page-head p { color: var(--ink-2); font-size: var(--t-lead); line-height: 1.5; margin: 0; }

/* ---- Page header, photographic variant ----------------------------------
   The same header over a full-width photograph: breadcrumb, title and the
   one-line summary sit on the page grid, the picture runs edge to edge
   behind them. Shorter than the home banner — this is a signpost, not a
   headline — and it keeps its proportions by sizing to its own copy rather
   than to the viewport. */

.page-head--media {
  padding-top: calc(var(--header-h) + clamp(2.25rem, 4.5vw, 3.75rem));
  padding-bottom: clamp(2.25rem, 4.5vw, 3.5rem);
  min-height: clamp(280px, 38vh, 420px);
  display: flex;
  align-items: flex-end;
  /* the strip behind the fixed header keeps the page colour, as on the home
     banner — the logo and nav are dark and have to stay legible */
  background: var(--resin);
  border-bottom: 0;
}
.page-head__bg,
.page-head--media::before {
  position: absolute;
  top: var(--header-h);
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 0;
}
.page-head__bg {
  width: 100%;
  height: calc(100% - var(--header-h));
  object-fit: cover;
}
/* Dark enough at the foot for micro type to hold up over any photograph. */
.page-head--media::before {
  content: "";
  z-index: 1;
  background:
    linear-gradient(90deg, rgba(16, 25, 23, 0.9) 0%, rgba(16, 25, 23, 0.68) 45%, rgba(16, 25, 23, 0.34) 100%),
    linear-gradient(180deg, rgba(16, 25, 23, 0.45) 0%, rgba(16, 25, 23, 0.2) 40%, rgba(16, 25, 23, 0.72) 100%);
}
.page-head--media > .container { position: relative; z-index: 2; width: 100%; }

/* Breadcrumb, title and summary read as one block down the left of the
   picture. The two-column split the light header uses would put the summary
   over the brightest part of the photograph. */
.page-head--media .row { display: block; margin: 0; }
.page-head--media .row > [class*="col-"] { width: auto; max-width: none; padding: 0; }
.page-head--media p { max-width: 56ch; margin-top: 1rem; }
.page-head--media h1 { color: #fff; }
.page-head--media p { color: rgba(255, 255, 255, 0.84); }
.page-head--media::after { background-image: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.45) 0 1px, transparent 1px 10px); z-index: 2; }

/* The breadcrumb is the smallest type on the page, so on the photograph it
   gets more weight and contrast than it needs on paper. */
.page-head--media .breadcrumb {
  --bs-breadcrumb-divider-color: rgba(255, 255, 255, 0.5);
  --bs-breadcrumb-item-active-color: rgba(255, 255, 255, 0.9);
  /* the current page's crumb carries no class of its own, so it takes this
     colour by inheritance — without it, it stays near-black on the photo */
  color: rgba(255, 255, 255, 0.8);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
}
.page-head--media .breadcrumb a { color: rgba(255, 255, 255, 0.82); }
.page-head--media .breadcrumb a:hover { color: #fff; }

@media (max-width: 767.98px) {
  .page-head--media {
    min-height: clamp(230px, 32vh, 320px);
    padding-top: calc(var(--header-h) + 1.75rem);
    padding-bottom: 1.75rem;
  }
  .page-head--media h1 { font-size: clamp(1.7rem, 1.2rem + 2.6vw, 2.4rem); }
  .page-head--media p { font-size: 1rem; margin-top: 0.85rem; }
  /* The last crumb can be a whole article title; let it wrap instead of
     pushing the row out of the container. */
  .page-head .breadcrumb { row-gap: 0.15rem; }
  .page-head .breadcrumb-item { max-width: 100%; }
}

/* ---- Gallery ------------------------------------------------------------------ */

.masonry { columns: 1; column-gap: clamp(0.75rem, 1.5vw, 1.25rem); }
@media (min-width: 620px) { .masonry { columns: 2; } }
@media (min-width: 1000px) { .masonry { columns: 3; } }

.masonry__item {
  break-inside: avoid;
  margin-bottom: clamp(0.75rem, 1.5vw, 1.25rem);
  display: block;
  width: 100%;
  position: relative;
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--paper);
  padding: 0;
  cursor: zoom-in;
}
.masonry__item img { width: 100%; height: auto; display: block; transition: transform 700ms var(--ease-out); }
.masonry__item:hover img { transform: scale(1.04); }
.masonry__item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(16, 25, 23, 0.42), transparent 45%);
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease);
}
.masonry__item:hover::after { opacity: 1; }
.masonry__cap {
  position: absolute;
  left: 0.9rem;
  bottom: 0.85rem;
  z-index: 2;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease-out);
}
.masonry__item:hover .masonry__cap { opacity: 1; transform: none; }

/* Lightbox modal */
#lightbox .modal-content { background: transparent; border: 0; }
#lightbox img { max-height: 78vh; width: auto; margin-inline: auto; border-radius: var(--radius-lg); }
#lightbox .lightbox__cap {
  margin-top: 1rem;
  text-align: center;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
#lightbox .btn-close {
  position: absolute;
  top: -3rem;
  right: 0;
  filter: invert(1) grayscale(100%) brightness(200%);
}
.lightbox__nav {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease);
}
.lightbox__nav:hover { background: rgba(255, 255, 255, 0.2); }

/* ---- CTA band ------------------------------------------------------------------ */

.cta-band { position: relative; overflow: hidden; background: var(--ink); color: #fff; }
.cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.09) 0 1px, transparent 1px 12px);
  pointer-events: none;
}
.cta-band > .container { position: relative; padding-block: clamp(3rem, 6vw, 5.5rem); }
.cta-band h2 { color: #fff; max-width: 22ch; }
.cta-band p { color: rgba(255, 255, 255, 0.72); margin-top: 1rem; margin-bottom: 0; max-width: 52ch; }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: 0.85rem; }

/* ---- Filter bar ------------------------------------------------------------------ */

.filters { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: clamp(1.75rem, 3vw, 2.5rem); }
.filter-btn {
  padding: 0.55rem 1rem;
  background: transparent;
  border: 1px solid var(--flute);
  border-radius: var(--radius-pill);
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-2);
  text-decoration: none;
  cursor: pointer;
  transition: all var(--dur-1) var(--ease);
}
.filter-btn:hover { border-color: var(--ink); color: var(--ink); }
.filter-btn[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: #fff; }

/* ---- Certificate card -------------------------------------------------------------- */

.cert {
  display: grid;
  grid-template-columns: 1fr;
  height: 100%;
  background: var(--paper);
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}
.cert:hover { transform: translateY(-3px); border-color: var(--ink); box-shadow: var(--shadow-2); }
@media (min-width: 620px) { .cert { grid-template-columns: 240px 1fr; } }
.cert__thumb { background: var(--resin-deep); border-right: 1px solid var(--flute); }
.cert__thumb img { width: 100%; height: 100%; aspect-ratio: 3 / 4; object-fit: cover; object-position: top; }
.cert__body { padding: clamp(1.25rem, 2.5vw, 1.9rem); display: flex; flex-direction: column; gap: 0.7rem; }
.cert__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.cert__actions { margin-top: auto; padding-top: 0.85rem; display: flex; gap: 0.6rem; flex-wrap: wrap; }

/* ---- Testimonials ------------------------------------------------------------------- */

.testimonial {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  margin: 0;
  padding: clamp(1.5rem, 3vw, 2.5rem);
  background: var(--paper);
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
}
@media (min-width: 768px) {
  .testimonial { grid-template-columns: 96px 1fr; gap: clamp(1.5rem, 3vw, 2.5rem); align-items: start; }
}
.testimonial__img {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--flute);
  background: var(--resin-deep);
}
.testimonial__text { margin: 0 0 1.25rem; }
.testimonial__text p {
  margin: 0;
  font-size: var(--t-lead);
  line-height: 1.55;
  color: var(--ink);
}
.testimonial__text p::before {
  content: "\201C";
  display: block;
  font-family: var(--font-display);
  font-size: 3rem;
  line-height: 0.8;
  color: var(--accent);
}
.testimonial figcaption { display: flex; flex-direction: column; gap: 0.3rem; }
.testimonial__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-h4);
  color: var(--ink);
}
.testimonial__role {
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.testimonials__bar { margin-top: 1.25rem; }
.testimonials__bar .carousel-indicators {
  position: static;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.5rem;
}
.testimonials__dots [data-bs-target] {
  width: clamp(34px, 4vw, 44px);
  height: 32px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  opacity: 1;
  text-indent: 0;
  position: relative;
  transition: none;
}
.testimonials__dots [data-bs-target]::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 15px;
  height: 2px;
  background: var(--flute);
  border-radius: var(--radius-pill);
}
.testimonials__dots [data-bs-target]:hover::before { background: var(--ink-3); }
.testimonials__dots .active::before { background: var(--accent); }

.testimonials__nav { display: flex; align-items: center; gap: 0.5rem; }
.testimonials__btn {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  background: var(--paper);
  border: 1px solid var(--flute);
  border-radius: 50%;
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease);
}
.testimonials__btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ---- Article ------------------------------------------------------------------------ */

.article { max-width: 72ch; }
.article h2 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); margin-block: 2.25rem 0.9rem; }
.article h3 { margin-block: 1.75rem 0.65rem; }
.article p { color: var(--ink-2); }
.article ul { margin: 0 0 1.2rem; padding-left: 0; list-style: none; display: grid; gap: 0.55rem; }
.article ul li { display: grid; grid-template-columns: 16px 1fr; gap: 0.7rem; color: var(--ink-2); }
.article ul li::before {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: 0.62em;
  background: var(--accent);
  transform: rotate(45deg);
}
/* A spec list keeps its own layout inside an article: the bullet grid above
   would otherwise take the marker column for itself and drop each value into
   the next row, 16px wide. */
.article .spec-list li { display: flex; }
.article .spec-list li::before { content: none; }
.article__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 1.25rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--flute);
}

/* ---- Article sidebar ------------------------------------------------------
   The specification and the two calls to action, held beside the reading
   column instead of at the foot of it. Sticky from lg up, where there is a
   column to be sticky in; below that it simply follows the article. */

.article-aside__card {
  background: var(--paper);
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
}
.article-aside__card .eyebrow { margin-bottom: 0.75rem; }
/* A narrower column than the spec list usually gets — "UV · fire retardant ·
   anti-static" needs the smaller size to sit on one line. */
.article-aside__card .spec-list { margin-top: 0; }
.article-aside__card .spec-list li { font-size: 0.86rem; }
.article-aside__actions {
  display: grid;
  gap: 0.6rem;
  margin-top: 1.5rem;
}
.article-aside__note {
  margin: 1rem 0 0;
  font-size: 0.92rem;
  color: var(--ink-3);
}

@media (min-width: 992px) {
  .article-aside {
    position: sticky;
    top: calc(var(--header-h) + 24px);
  }
}

/* ---- Contact ------------------------------------------------------------- */

/* The address runs several lines, so its row stacks label over value. */
.spec-list li.spec-list__item--stack { flex-direction: column; align-items: flex-start; gap: 0.35rem; }
.contact-address { font-size: 1rem; }

.contact-panel {
  background: var(--paper);
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
  padding: clamp(1.25rem, 3vw, 2.25rem);
}
.form-label__note { text-transform: none; letter-spacing: 0; }

.map-frame {
  border: 1px solid var(--flute);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--resin-deep);
}
.map-frame iframe { border: 0; display: block; }

/* ---- Industries jump nav -------------------------------------------------- */

.section.industries-jump { padding-top: clamp(2rem, 4vw, 3rem); padding-bottom: 0; }

/* ---- Plant film ----------------------------------------------------------- */

.video-frame { width: 100%; aspect-ratio: 16 / 9; background: var(--ink); }

/* Product gallery beside a long spec column: keep it in view while the
   copy and spec list scroll past, instead of leaving an empty column. */
@media (min-width: 992px) {
  .media-sticky { position: sticky; top: calc(var(--header-h) + 1.5rem); }
}

/* ---- Report viewer (full-screen PDF modal) -------------------------------------- */

.report-viewer .modal-content { background: var(--ink); color: #fff; border: 0; border-radius: 0; }
.report-viewer__bar {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.75rem clamp(1rem, 2.5vw, 2rem);
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}
.report-viewer__title {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-family: var(--font-data);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.report-viewer .btn-close { filter: invert(1) grayscale(100%) brightness(200%); opacity: 0.8; }
.report-viewer .btn-close:hover { opacity: 1; }
.report-viewer__frame { flex: 1 1 auto; width: 100%; border: 0; background: #525659; }
