/* Small, additive layer on top of the real ported styles.css. Every rule
   here is either (a) a class that genuinely doesn't exist in the original
   site (the SEO-only category grid), or (b) a static-site substitute for
   something the original did with JS (marquee auto-scroll). Nothing in
   this file should redeclare a class that styles.css already owns —
   site.css loads after styles.css, so any duplicate here would silently
   win and drift the design away from the original. */

/* ---------- contact form fields: left border edge looked cut off ----------
   .form-field input/select/textarea in styles.css sets a uniform 1px
   border on all sides, then overrides just border-left to 2px (for the
   orange accent stripe that appears on focus/filled/error). Two different
   border widths on the same rounded box (border-radius:2px) makes the
   corners render inconsistently — the thicker left edge doesn't sweep into
   the corner arc the same way the thinner top/bottom edges do, so the left
   side can look clipped/discontinuous right where it meets the rounded
   corners. Making every side 2px removes the mismatch; the accent still
   works exactly the same way since it's driven by border-left-COLOR
   (transparent/orange/red), not width. */
.form-field input,
.form-field select,
.form-field textarea {
  border-width: 2px;
}

/* The original nav is `position:fixed` and pages compensate with an inline
   `padding-top:140px` on their first .section (ported as-is on every
   rebuilt page). The one exception is the home hero, which is `height:100vh`
   and intentionally sits behind the fixed nav exactly like the original. */

/* ---------- .btn-secondary was rendering as an underlined link ----------
   .btn-primary explicitly sets text-decoration:none in styles.css, but
   .btn-secondary never got the same reset (the original only ever used it
   as a <button>, never a link). This rebuild uses <a class="btn-secondary">
   in a few places ("Explore Products", "Request Any Report"), which picks
   up the browser's default underline. Same fix pattern as .prod-card /
   .filter-btn / .app-nav-card above. */
.btn-secondary,
.btn-secondary:link,
.btn-secondary:visited,
.btn-secondary:hover,
.btn-secondary:active,
.btn-secondary:focus {
  text-decoration: none;
}

/* ---------- category browse grid (SEO-only addition, not in the original) ---------- */
.cat-grid-inner {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
  margin: 24px 0 40px;
}
.cat-card {
  background: var(--surface);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 3px;
  padding: 20px;
  color: var(--white) !important;
  font-family: 'Barlow Condensed', sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: border-color 0.25s;
}
.cat-card,
.cat-card:hover,
.cat-card:visited,
.cat-card:active,
.cat-card:focus { text-decoration: none; }
.cat-card:hover { border-color: var(--orange); }
.cat-card em { color: var(--mist); font-style: normal; margin-left: 4px; }
.cat-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }

/* ---------- marquee auto-scroll ----------
   The original scrolls .marquee-track via a JS rAF loop keyed to a pixel
   speed; this is a CSS-only equivalent so the ticker still moves without
   that script. */
.marquee-track {
  width: max-content;
  animation: marquee-scroll 90s linear infinite;
}
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ---------- static hero title ----------
   line2 in the original is an SVG stroke-draw of "FOR THE"; we approximate
   the same outlined look with a CSS text-stroke instead of an SVG path. */
.line2-stroke {
  color: transparent;
  -webkit-text-stroke: 1.5px var(--ember);
  text-stroke: 1.5px var(--ember);
}

/* line3 knockout block.
   Replaces the looping gradient shimmer that used to run here. The shimmer
   read as a soft glow against an already-dark hero; a solid orange slab with
   the type knocked out of it is the loudest thing the hero can do and reads
   at any distance. Dark text is hardcoded rather than a token because the
   slab is orange in both themes, so it must not follow --pure (which inverts).
   Negative margin-left cancels the left padding so the block's *text* still
   lines up with PETRIZ and FOR THE above it, not the padding edge. */
/* .line3 was overflow:hidden to mask a reveal animation that no longer runs;
   left as-is it clips the slab's left padding (which sits at a negative
   margin) and shaves the block flush against the D. */
.hero-title .line3 { overflow: visible; }

.line3-inner.line3-knockout {
  background: var(--orange);
  color: #0A0C0F;
  padding: 0 0.14em 0 0.1em;
  margin-left: -0.1em;
}

/* The original reveals .hero-sub/.hero-btns/.hero-eyebrow-seg/.about-para/
   .cf-anim/.detail-info-item/.about-item-from-left/.about-item-from-right/
   .contact-info-item via scroll- or load-triggered JS that adds a
   "visible"/"anim"/"ci-visible" class. Without that script these would stay
   at their pre-animation opacity:0, so show the final state by default. */
.hero-sub,
.hero-btns,
.about-para,
.about-item-from-left,
.about-item-from-right,
.contact-details-row .contact-info-item {
  opacity: 1 !important;
  transform: none !important;
  border-left-color: var(--orange);
}

/* ---------- technical data table: product name link ----------
   The original Product cell (.tds-name) is plain text, not a link — this
   rebuild makes it clickable to the product page, but a bare <a> falls
   back to default browser blue/underline/bold since nothing in styles.css
   targets a link inside this table. Make it inherit the cell's real
   typography and only pick up color on hover/focus. */
.tds-name-link {
  color: inherit;
  font-weight: inherit;
  text-decoration: none;
}
.tds-name-link:hover,
.tds-name-link:focus-visible {
  color: var(--orange);
  text-decoration: underline;
}

/* ---------- technical data table: keep every column boxed in ----------
   .tds-table is table-layout:fixed with equal 14.2857% column widths in
   styles.css, but a couple of cell contents can still render wider than
   their column and visually spill into the next one: the category badge
   is nowrap by design, and free-text TDS fields (form/application/
   compatibility) can contain long unbroken phrases. Clip/wrap everything
   to its own column so nothing bleeds across the vertical dividers. */
.tds-table td {
  overflow: hidden;
}
.tds-cat-badge {
  max-width: 100%;
  overflow: hidden;
}
.tds-cat-badge .tds-cat-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tds-table td:not(.tds-name):not(.tds-mono) {
  word-break: break-word;
}

/* ---------- product cards were invisible ----------
   .prod-card is opacity:0 by default in styles.css — the original only
   ever shows it once JS adds .card-entering or .card-animating (its
   card-build function stamps card-animating on every card as it's
   created). Nothing here adds that class, so every card was stuck
   permanently invisible on home, /products/, every category page, and
   the related-products grid on product detail pages. Force it visible. */
.prod-card {
  opacity: 1;
  transform: none;
}

/* ---------- product card text was rendering as a blue underlined link ----------
   The original card is a plain <article> with an onclick handler, not an
   <a> — so none of its text ever touched the browser's default link
   styling. This rebuild wraps the whole card in <a class="prod-card"> so
   it works without JS, but that means every text node inside (name, desc,
   tags, badge) inherits the UA-default blue color and underline unless
   explicitly reset, since .prod-name/.prod-desc/etc only ever set color in
   styles.css, not text-decoration. Reset both at the card level so nothing
   the original component classes forgot to override leaks through. */
.prod-card,
.prod-card:link,
.prod-card:visited,
.prod-card:hover,
.prod-card:active,
.prod-card:focus {
  color: inherit;
  text-decoration: none;
}
.prod-card * {
  text-decoration: none;
}

/* ---------- filter bar buttons + app-nav cards were rendering as links ----------
   Both .filter-btn and .app-nav-card are <button> elements in the original
   (onclick=setFilter(...)), never <a> tags, so styles.css only ever sets
   color/background/border on them — never text-decoration. This rebuild
   turns them into real <a href> links for JS-free category navigation,
   which brought back the browser's default blue/underline. Same fix
   pattern as .prod-card and .tds-name-link above. */
.filter-btn,
.filter-btn:link,
.filter-btn:visited,
.filter-btn:hover,
.filter-btn:active,
.filter-btn:focus,
.app-nav-card,
.app-nav-card:link,
.app-nav-card:visited,
.app-nav-card:hover,
.app-nav-card:active,
.app-nav-card:focus {
  text-decoration: none;
}
.app-nav-card,
.app-nav-card:visited {
  color: inherit;
}

/* ---------- manufacturing partner cards: add hover state (requested enhancement) ----------
   The original never gave .mfr-card a hover treatment (only padding/background
   are set in styles.css) — this is a deliberate deviation from the original,
   not a parity fix, matching the border-left + tint hover already used on
   .about-basin-item just below it on the same page. */
.mfr-card {
  border-left: 3px solid transparent;
  transition: border-color 0.2s, background 0.2s;
}
.mfr-card:hover {
  border-left-color: var(--orange);
  background: rgba(212, 84, 26, 0.05);
}

/* ---------- technical data table: Request TDS button underline ----------
   .tds-req-btn is a <button> in the original (never a link), so styles.css
   only ever sets its background/border/color — never text-decoration. This
   rebuild renders it as <a class="tds-req-btn"> for JS-free navigation to
   the contact page, which brings back the browser's default underline.
   Same fix pattern as .filter-btn/.app-nav-card above. */
.tds-req-btn,
.tds-req-btn:link,
.tds-req-btn:visited,
.tds-req-btn:hover,
.tds-req-btn:active,
.tds-req-btn:focus {
  text-decoration: none;
}

/* ---------- breadcrumb links were picking up the browser's visited-link color ----------
   The original breadcrumb items are plain elements with an onclick handler,
   not <a> tags, so .bc-link in styles.css only ever sets color on :hover —
   never a base color or a :visited override, since neither was ever needed.
   This rebuild uses real <a href> breadcrumbs for static navigation, so a
   visited /products/ or /products/[category]/ link was falling back to the
   browser's default purple "visited" color instead of the intended --mist
   gray. Pin both states explicitly. */
.bc-link,
.bc-link:visited {
  color: var(--mist);
}
.bc-link:hover {
  color: var(--orange);
}

/* ---------- footer social icons: LinkedIn made larger (requested) ----------
   Twitter/X was removed from the footer entirely (was a "#" placeholder
   link with no real account behind it); LinkedIn is now the only icon, so
   it's sized up from the shared .social-icon default (32px box / 14px
   glyph) to stand out on its own rather than sitting at "one of a row"
   size. */
.social-icon-linkedin {
  width: 44px;
  height: 44px;
}
.social-icon-linkedin svg {
  width: 20px;
  height: 20px;
}

/* ---------- header "Request TDS" hover text color ----------
   .nav-cta:hover already sets color:#0A0C0F (dark) in styles.css, but
   .nav-links a:hover{color:var(--ember)} has higher specificity (one more
   element selector) and wins instead, so the button's hover text was
   staying the light ember color on the orange background rather than
   turning dark. Scope a selector specific enough to actually win. */
.nav-links a.nav-cta:hover {
  color: #0A0C0F;
}

/* ---------- about page: visual panel replaced with a real photo ----------
   The Three.js Earth cross-section (then briefly a Pinterest embed) was
   swapped for an actual photo (oil-trade.jpeg, 464x832 native — a tall
   phone-camera portrait shot). .about-visual-photo reshapes the panel to
   that exact ratio on this page only (.about-visual isn't used elsewhere)
   so the image displays at its true proportions with no cropping, and
   .about-grid's gap is pulled in from the original 80px since the narrower
   photo column leaves a much bigger gap to the text than the original
   500px-square canvas did.

   Vertical sizing: the photo is taken out of grid flow with
   position:absolute so .about-grid's height collapses to match .about-text
   alone, then top:0 and bottom:0 stretch the photo to exactly that height.
   The text column therefore drives the photo, not the other way round — it
   stays full-height whatever the copy does, which matters because this page's
   text grows every time the catalogue does (it went from three paragraphs and
   four feature boxes to four and six when the equipment and screen lines were
   added, and the previously bottom-anchored fixed-ratio photo stopped
   reaching the top).

   height:auto is required: .about-visual in styles.css sets height:500px, and
   on an absolutely positioned box an explicit height beats bottom, so the
   stretch would silently do nothing. Likewise the old aspect-ratio is gone —
   a fixed ratio and a stretched height are contradictory instructions.

   left/right span the full right-hand column rather than centring a narrower
   fixed-width photo inside it: at full text height a 340px column would be an
   awkwardly thin vertical sliver. object-fit:cover on the img handles the
   resulting crop. */
.about-grid {
  gap: 48px;
  position: relative;
}
.about-visual-photo {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(50% + 24px); /* start of the right-hand column: half the grid minus half the 48px gap, plus the gap */
  right: 0;
  width: auto;
  height: auto;
  margin: 0;
  overflow: hidden;
  background: var(--bg);
  border-radius: 4px;
}
.about-visual-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (max-width: 900px) {
  /* .about-grid drops to a single column here (see styles.css), so the
     absolute/anchored-to-column-2 positioning no longer applies — revert
     to a normal, centered block that flows below the text. */
  .about-visual-photo {
    position: static;
    width: auto;
    height: auto;
    max-width: 280px;
    margin: 32px auto 0;
    /* Single column here, so there is no text column to match: the photo goes
       back to its native proportions rather than stretching to nothing. */
    aspect-ratio: 464 / 832;
  }
}

/* ---------- language switcher (EN/ES/PT) ----------
   Uses the original's own .lang-toggle/.lang-btn markup and CSS from
   styles.css (it existed fully styled — .lang-active, .lang-soon, focus
   states, light-theme borders — just never wired to real routes). Only
   fix needed: .lang-btn is a <button> in the original CSS's implicit
   assumptions, but this rebuild renders the non-active entries as real
   <a> links for JS-free navigation between /,/es/,/pt/, which brings back
   the browser's default link underline/color that styles.css never had to
   reset (same pattern as .prod-card, .filter-btn, .app-nav-card above). */
.lang-btn,
.lang-btn:link,
.lang-btn:visited,
.lang-btn:hover,
.lang-btn:active,
.lang-btn:focus {
  text-decoration: none;
  color: var(--mist);
}
.lang-btn.lang-active,
.lang-btn.lang-active:visited {
  color: var(--pure);
}

/* ---------- how-to-order: top section quick-facts sidebar (requested enhancement) ----------
   The original's top section is just a tag + h1 + one line of sub-copy —
   confirmed against index.html, not a dropped element. This is a new
   addition (not original parity): a two-column layout that runs the
   5-step timeline alongside a vertical strip of facts already stated
   elsewhere on the page (24hr response, 5-step process, 48hr qualification
   package, trilingual docs), using the site's existing type system (Bebas
   Neue numerals, JetBrains Mono labels) so it reads as native to the
   design. Sidebar sits to the right of .order-steps and stays pinned
   alongside it as the steps scroll past. */
.order-top-grid {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 56px;
  align-items: start;
  margin-top: 48px;
}
.order-top-grid .order-steps {
  margin-top: 0;
}
.order-quickfacts {
  position: sticky;
  top: 160px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: rgba(212, 84, 26, 0.14);
}
.oqf-item {
  background: var(--bg);
  padding: 20px 22px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.oqf-icon-wrap {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border: 1px solid rgba(212, 84, 26, 0.4);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.oqf-icon-wrap svg {
  width: 18px;
  height: 18px;
  stroke: var(--orange);
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.oqf-num {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 26px;
  letter-spacing: 0.03em;
  color: var(--pure);
  line-height: 1;
  margin-bottom: 4px;
}
.oqf-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--mist);
}
@media (max-width: 900px) {
  .order-top-grid {
    grid-template-columns: 1fr;
  }
  .order-quickfacts {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
  }
  .oqf-item {
    flex: 1 1 45%;
  }
}

/* ---------- product prev/next navigator: text rendering underlined ----------
   .prod-nav-btn in styles.css sets text-decoration:none on the base
   selector only — same category of bug fixed above for .btn-secondary and
   .bc-link (a :visited or other pseudo-class state falls back to the
   browser default underline because the base rule doesn't cover every
   state). Pin text-decoration:none across every link state so the
   Previous/Next product name and hint text never show an underline. */
.prod-nav-btn,
.prod-nav-btn:link,
.prod-nav-btn:visited,
.prod-nav-btn:hover,
.prod-nav-btn:active,
.prod-nav-btn:focus {
  text-decoration: none;
}

/* ---------- contact page: conditional Report Name / Product "Other" fields ----------
   Both hidden by default; revealed via inline script when Request Type is
   "Report" (EN) / "Reporte" (ES) / "Relatório" (PT), or when Product
   Interest is "Other" (EN) / "Otro" (ES) / "Outro" (PT). display:none is
   set inline on the elements too so they never flash visible before the
   script runs, these rules just document/reinforce the default state. */
#report-name-field,
#product-other-field {
  display: none;
}


/* ============================================================
   EMAIL CAPTURE
   Low-friction, single-field signup used at the end of insight
   articles, on the technical-data page, and in the footer. Kept
   visually distinct from the contact form so it doesn't read as
   the same (much heavier) commitment.

   Border/background values follow the existing conventions in
   styles.css rather than inventing tokens: panels use
   rgba(168,184,200,0.15), form inputs use rgba(255,255,255,0.08)
   with an orange focus ring, and light theme overrides them with
   rgba(0,0,0,0.1) / #EAE4DC exactly like .form-field does.
   (Note for future edits: --ba is NOT a colour — it's a rotation
   angle used by the prodBorderSpin conic-gradient keyframe.)
   ============================================================ */

/* Visually-hidden label. The input has a placeholder, but a
   placeholder is not an accessible name — screen readers need a
   real <label>, so it's rendered and clipped rather than omitted. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.email-capture {
  margin-top: 40px;
  padding: 28px;
  background: var(--surface);
  border: 1px solid rgba(168, 184, 200, 0.15);
  border-left: 2px solid var(--orange);
  border-radius: 2px;
}

.email-capture-heading {
  font-family: 'Bebas Neue', sans-serif;
  font-size: clamp(19px, 2vw, 24px);
  letter-spacing: .04em;
  color: var(--pure);
  margin-bottom: 8px;
}

.email-capture-sub {
  font-family: 'Barlow', sans-serif;
  font-size: 14px;
  color: var(--mist);
  line-height: 1.7;
  max-width: 560px;
  margin-bottom: 18px;
}

.email-capture-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: stretch;
}

.email-capture-input {
  font-family: 'Barlow', sans-serif;
  font-size: 14px;
  flex: 1 1 260px;
  min-width: 0;
  padding: 12px 16px;
  background: var(--bg);
  color: var(--white);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 2px;
  outline: none;
  transition: border-color .3s, box-shadow .3s, background .3s;
}

.email-capture-input::placeholder { color: var(--mist); opacity: .8; }

.email-capture-input:focus {
  border-color: rgba(212, 84, 26, 0.3);
  box-shadow: 0 0 0 3px rgba(212, 84, 26, 0.15);
}

/* Match .btn-primary's height to the input rather than relying on its
   default vertical padding, so the two never sit misaligned. */
.email-capture-btn {
  flex: 0 0 auto;
  padding: 13px 26px;
  line-height: 1.2;
}

.email-capture-privacy {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: .08em;
  color: var(--mist);
  margin-top: 12px;
}

/* Footer variant: sits inside the existing footer grid, inherits
   .footer-col-title for its heading, and stays compact. */
.email-capture-footer { margin-top: 4px; }

.email-capture-form-compact { gap: 0; flex-wrap: nowrap; max-width: 260px; }

.email-capture-form-compact .email-capture-input {
  flex: 1 1 auto;
  padding: 10px 12px;
  font-size: 13px;
  border-right: none;
  border-radius: 2px 0 0 2px;
}

.email-capture-btn-compact {
  flex: 0 0 auto;
  padding: 0 14px;
  background: var(--orange);
  color: #fff;
  border: none;
  border-radius: 0 2px 2px 0;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  transition: background .3s;
}
.email-capture-btn-compact:hover { background: var(--ember); }
.email-capture-btn-compact:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

/* Light theme: mirrors the .form-field light overrides in styles.css. */
[data-theme="light"] .email-capture {
  border-color: rgba(212, 84, 26, 0.15);
}
[data-theme="light"] .email-capture-input {
  background: #EAE4DC;
  color: var(--pure);
  border-color: rgba(0, 0, 0, 0.1);
}
[data-theme="light"] .email-capture-input:focus {
  background: #E2DBD2;
  border-color: rgba(212, 84, 26, 0.3);
}

@media (max-width: 600px) {
  .email-capture { padding: 20px; }
  .email-capture-btn { width: 100%; }
}

/* ============================================================
   LEGAL DOCUMENT PAGES (privacy policy, and any terms page
   added later). Long-form prose, so it gets a readable measure
   and generous line-height rather than the tighter rhythm used
   for marketing copy.
   ============================================================ */

.legal-doc { max-width: 760px; margin-top: 8px; }

.legal-updated {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mist);
  margin: 0 0 36px 0;
}

.legal-section { margin-bottom: 34px; }

.legal-h2 {
  font-family: 'Bebas Neue', sans-serif;
  font-size: clamp(20px, 2vw, 27px);
  letter-spacing: .04em;
  color: var(--pure);
  margin: 0 0 12px 0;
}

.legal-p,
.legal-list li {
  font-family: 'Barlow', sans-serif;
  font-size: 15px;
  line-height: 1.8;
  color: var(--mist);
}

.legal-p { margin: 0 0 14px 0; }
.legal-p:last-child { margin-bottom: 0; }

.legal-list {
  margin: 0 0 14px 0;
  padding-left: 20px;
}

.legal-list li { margin-bottom: 12px; }
.legal-list li:last-child { margin-bottom: 0; }

.legal-doc strong { color: var(--cloud); font-weight: 600; }

.legal-doc a {
  color: var(--orange);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.legal-doc a:hover { color: var(--ember); }

.legal-doc code {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--cloud);
  background: var(--surface);
  padding: 1px 5px;
  border-radius: 2px;
}

/* Consent checkbox on the contact form. Sits between the message
   field and the submit button; deliberately unchecked by default
   and NOT required, so declining marketing never blocks a genuine
   sales enquiry. */
.consent-row {
  margin: 4px 0 20px 0;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.consent-row input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 3px 0 0 0;
  accent-color: var(--orange);
  cursor: pointer;
}

.consent-row label {
  font-family: 'Barlow', sans-serif;
  font-size: 13px;
  line-height: 1.6;
  color: var(--mist);
  cursor: pointer;
}

.consent-row a { color: var(--orange); text-decoration: underline; }

.form-privacy-note {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: .07em;
  line-height: 1.7;
  color: var(--mist);
  margin-top: 14px;
}
.form-privacy-note a { color: var(--orange); text-decoration: underline; }

.email-capture-privacy a {
  color: var(--orange);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============================================================
   PDF BRIEF DOWNLOAD
   Sits at the end of an insight article, above the email capture.
   Deliberately quieter than a .btn-primary: the article itself is
   the main content, and the PDF is a convenience format for
   circulating internally, not the page's primary CTA.
   ============================================================ */

.brief-download { margin-top: 34px; }

.brief-download-link {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid rgba(168, 184, 200, 0.15);
  border-left: 2px solid var(--teal);
  border-radius: 2px;
  text-decoration: none;
  transition: border-color .25s, background .25s;
}

.brief-download-link:hover {
  background: var(--bg);
  border-color: rgba(12, 122, 106, 0.4);
}

.brief-download-icon {
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: .08em;
  color: var(--pure);
  background: var(--teal);
  padding: 5px 8px;
  border-radius: 2px;
}

.brief-download-label {
  display: block;
  font-family: 'Barlow', sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--pure);
  margin-bottom: 2px;
}

.brief-download-note {
  display: block;
  font-family: 'Barlow', sans-serif;
  font-size: 12px;
  line-height: 1.5;
  color: var(--mist);
}

[data-theme="light"] .brief-download-link {
  border-color: rgba(12, 122, 106, 0.2);
}

@media (max-width: 520px) {
  .brief-download-link { align-items: flex-start; }
}

/* Note inside the contact form's Report field, pointing at the instant
   PDF download so the form isn't the only way to get a brief. */
.report-download-note {
  font-family: 'Barlow', sans-serif;
  font-size: 12px;
  line-height: 1.6;
  color: var(--mist);
  margin-top: 8px;
}
.report-download-note a { color: var(--orange); text-decoration: underline; }

/* ============================================================
   RELATED INSIGHTS + ARTICLE ATTRIBUTION
   Sits between the PDF download and the email capture, so a
   reader gets an onward path before being asked for an address.
   ============================================================ */

.related-insights { margin-top: 40px; }

.related-insights-heading {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 14px;
}

.related-insights-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.related-insight-card {
  display: block;
  padding: 16px;
  background: var(--surface);
  border: 1px solid rgba(168, 184, 200, 0.15);
  border-top: 2px solid rgba(212, 84, 26, 0.35);
  border-radius: 2px;
  text-decoration: none;
  transition: border-top-color .25s, background .25s, transform .25s;
}

.related-insight-card:hover {
  background: var(--bg);
  border-top-color: var(--orange);
  transform: translateY(-2px);
}

.related-insight-title {
  display: block;
  font-family: 'Barlow Condensed', sans-serif;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.35;
  color: var(--pure);
  margin-bottom: 6px;
}

.related-insight-desc {
  display: block;
  font-family: 'Barlow', sans-serif;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--mist);
}

.article-attribution {
  margin-top: 32px;
  padding-top: 16px;
  border-top: 1px solid rgba(168, 184, 200, 0.15);
}

.article-attribution-by {
  display: block;
  font-family: 'Barlow', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--cloud);
  margin-bottom: 5px;
}

.article-attribution-note {
  display: block;
  font-family: 'Barlow', sans-serif;
  font-size: 12px;
  line-height: 1.7;
  color: var(--mist);
  max-width: 680px;
}

[data-theme="light"] .related-insight-card {
  border-color: rgba(212, 84, 26, 0.15);
}

/* Footer signup is a link to the canonical signup block on the technical-data
   page, not a second form. A single-line input in a narrow footer column was the
   weakest of the three placements, and duplicating the form meant duplicating
   whatever submission mechanism it uses — one canonical signup is easier to keep
   working than three. */
.email-capture-footer-link {
  display: block;
  text-decoration: none;
  margin-top: 4px;
}

.email-capture-footer-link .footer-col-title { margin-bottom: 6px; }

.email-capture-footer-cta {
  display: inline-block;
  font-family: 'Barlow', sans-serif;
  font-size: 13px;
  line-height: 1.5;
  color: var(--orange);
  transition: color .25s;
}

.email-capture-footer-link:hover .email-capture-footer-cta { color: var(--ember); }
.email-capture-footer-link:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}

/* ══════════════════════════════════════════════════════════════════════════
   PRODUCTS LANDING — GROUP SHOWCASE + PREVIEWS
   ══════════════════════════════════════════════════════════════════════════
   Used by /products/. The showcase is a CSS scroll-snap track: the browser
   handles snapping and touch swiping natively, so the strip still works as a
   plain scrollable row if the enhancement script never runs. */

.cat-showcase { margin: 40px 0 0; }

/* Homepage variant of the group showcase.
   /products/ presents these three as a swipeable strip because that page also
   carries a filter bar and a full product grid below it, so horizontal space is
   contested. On the homepage they are the main event and there is nothing to
   compete with, so the same .cat-panel cards are laid out as a plain three-up
   grid — no carousel, no arrows, everything visible at once. Reusing the panel
   class means both pages stay in step if the card design changes. */
.group-panels { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.group-panels .cat-panel {
  min-width: 0;
  scroll-snap-align: none;
  /* Tall portrait columns rather than the 340px landscape boxes /products/
     uses. At a third of the page width, 340px reads as a squat card; ~62vh
     makes each one a distinct vertical column, which is what carries the eye
     down the page instead of across it. Clamped so it can't dominate a short
     laptop screen or shrink to nothing on a tall one. */
  min-height: clamp(420px, 62vh, 620px);
}
/* Copy sits at the bottom of a tall column, so the space above it does the
   work — the index numeral and accent rule fill it rather than dead air. */
.group-panels .cat-panel-index { font-size: clamp(90px, 9vw, 150px); }
/* Two-up before one-up: three columns get too narrow for the label to sit on
   one line much below this. */
@media (max-width: 1100px) {
  .group-panels { grid-template-columns: 1fr 1fr; }
  .group-panels .cat-panel { min-height: 420px; }
}
@media (max-width: 760px) {
  .group-panels { grid-template-columns: 1fr; }
  /* Stacked, they are rows again by definition — so drop the forced height
     and let each panel be only as tall as its content needs. */
  .group-panels .cat-panel { min-height: 0; }
}

.cat-strip {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Hide the native bar — the dots and arrows below carry the affordance,
     and a scrollbar under a full-bleed panel reads as a rendering artefact. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.cat-strip::-webkit-scrollbar { display: none; }

.cat-panel {
  scroll-snap-align: center;
  scroll-snap-stop: always;
  position: relative;
  overflow: hidden;
  min-height: 340px;
  display: flex;
  align-items: flex-end;
  padding: 32px;
  border-radius: 3px;
  background: var(--surface);
  border: 1px solid rgba(212, 84, 26, 0.12);
  border-left: 3px solid var(--accent, var(--orange));
  transition: border-color .25s, background .25s;
}
.cat-panel::after {
  /* Accent wash, anchored to the panel's own colour. */
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 90% at 100% 0%, color-mix(in srgb, var(--accent, #D4541A) 14%, transparent), transparent 70%);
  pointer-events: none;
}
.cat-panel:hover { background: rgba(212, 84, 26, 0.04); border-color: rgba(212, 84, 26, 0.3); }

.cat-panel-inner { position: relative; z-index: 1; max-width: 46ch; }

.cat-panel-code {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: .2em;
  color: var(--accent, var(--orange));
  margin-bottom: 10px;
}
.cat-panel-label {
  font-family: 'Bebas Neue', sans-serif;
  font-size: clamp(28px, 1.4rem + 2vw, 44px);
  letter-spacing: .05em;
  line-height: 1;
  color: var(--pure);
  margin: 0 0 12px;
}
.cat-panel-count { display: flex; align-items: baseline; gap: 8px; margin-bottom: 14px; }
.cat-panel-num {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 30px;
  line-height: 1;
  color: var(--accent, var(--orange));
}
.cat-panel-unit {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--mist);
}
.cat-panel-sub {
  font-family: 'Barlow', sans-serif;
  font-size: 13px;
  line-height: 1.6;
  color: var(--cloud);
  margin: 0 0 20px;
}
.cat-panel-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--accent, var(--orange));
  transition: gap .25s;
}
.cat-panel-cta:hover { gap: 14px; }

.cat-panel-index {
  position: absolute;
  right: 20px;
  top: 12px;
  font-family: 'Bebas Neue', sans-serif;
  font-size: 96px;
  line-height: 1;
  color: var(--accent, var(--orange));
  opacity: .1;
  pointer-events: none;
}

/* ── Strip controls ─────────────────────────────────────────────────────── */

.cat-strip-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 20px;
}

.cat-nav-btn {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid rgba(212, 84, 26, 0.2);
  cursor: pointer;
  transition: border-color .25s, background .25s, opacity .25s;
}
.cat-nav-btn svg {
  width: 16px; height: 16px;
  fill: none;
  stroke: var(--orange);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.cat-nav-btn:hover:not(:disabled) { border-color: var(--orange); background: rgba(212, 84, 26, 0.08); }
.cat-nav-btn:disabled { opacity: .3; cursor: default; }

.cat-dots { display: flex; align-items: center; gap: 8px; }
.cat-nav-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--mist);
  opacity: .4;
  cursor: pointer;
  transition: opacity .25s, background .25s, width .25s;
}
.cat-nav-dot.is-active { background: var(--orange); opacity: 1; width: 22px; border-radius: 4px; }

/* ── Per-group preview rows ─────────────────────────────────────────────── */

.grp-preview { margin-top: 64px; }

.grp-preview-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  padding-bottom: 14px;
  margin-bottom: 24px;
  border-bottom: 1px solid rgba(212, 84, 26, 0.14);
}
.grp-preview-code {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: .2em;
  color: var(--orange);
  margin-bottom: 6px;
}
.grp-preview-title {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 28px;
  letter-spacing: .05em;
  line-height: 1;
  color: var(--pure);
  margin: 0;
}
.grp-preview-all {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--orange);
  transition: gap .25s;
}
.grp-preview-all:hover { gap: 14px; }

.grp-preview-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.grp-preview-note {
  font-family: 'Barlow', sans-serif;
  font-size: 13px;
  line-height: 1.6;
  color: var(--cloud);
  margin: 0 0 20px;
  max-width: 70ch;
}

.screen-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.screen-chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: .04em;
  color: var(--cloud);
  background: var(--surface);
  border: 1px solid rgba(212, 84, 26, 0.14);
  border-radius: 3px;
  padding: 8px 12px;
  transition: border-color .25s, color .25s, background .25s;
}
.screen-chip:hover { border-color: var(--orange); color: var(--pure); background: rgba(212, 84, 26, 0.06); }

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1000px) {
  .grp-preview-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
  /* One panel per screen, so the snap points line up with what the user sees. */
  .cat-strip { grid-auto-columns: 88%; gap: 12px; }
  .cat-panel { min-height: 300px; padding: 24px; }
  .cat-panel-index { font-size: 64px; }
  .grp-preview-grid { grid-template-columns: 1fr; }
  .grp-preview-head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .grp-preview { margin-top: 48px; }
}

/* ── Accessibility ──────────────────────────────────────────────────────── */

.cat-strip:focus-visible,
.cat-nav-btn:focus-visible,
.cat-nav-dot:focus-visible,
.cat-panel-cta:focus-visible,
.grp-preview-all:focus-visible,
.screen-chip:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .cat-strip { scroll-behavior: auto; }
  .cat-panel,
  .cat-nav-btn,
  .cat-nav-dot,
  .cat-panel-cta,
  .grp-preview-all,
  .screen-chip { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   MUD LAB EQUIPMENT — PRODUCT PHOTOGRAPHY
   ══════════════════════════════════════════════════════════════════════════
   The source images are transparent 1000x1000 PNGs of instruments shot on
   white. Against the dark theme a transparent cut-out would leave dark metal
   on a dark panel, so every surface below sits the photo on a light plate.
   object-fit: contain guarantees no instrument is ever cropped — a mud balance
   is long and thin, a retort is tall, and letterboxing the odd one is far
   better than slicing the beam off the balance. */

/* ── Detail page figure ─────────────────────────────────────────────────── */

.eq-figure {
  margin: 0 0 28px;
  background: #F5F7FA;
  border: 1px solid rgba(212, 84, 26, 0.15);
  border-radius: 4px;
  overflow: hidden;
}
.eq-figure-img {
  display: block;
  width: 100%;
  height: 380px;
  object-fit: contain;
  /* Breathing room so the instrument never touches the plate edge. */
  padding: 24px;
  box-sizing: border-box;
}

/* ── Group index cards ──────────────────────────────────────────────────── */

.eq-card-media {
  background: #F5F7FA;
  border-radius: 3px;
  margin-bottom: 16px;
  overflow: hidden;
}
.eq-card-img {
  display: block;
  width: 100%;
  height: 180px;
  object-fit: contain;
  padding: 14px;
  box-sizing: border-box;
  transition: transform .35s cubic-bezier(0.16, 1, 0.3, 1);
}
.eq-card:hover .eq-card-img { transform: scale(1.04); }

/* ── Preview cards on /products/ ────────────────────────────────────────── */

/* Replaces the typographic code plate, so it inherits the plate's box and
   only overrides what the photo needs. */
.prod-plate-photo {
  background: #F5F7FA;
  display: block;
  padding: 0;
}
.prod-plate-img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 180px;
  object-fit: contain;
  padding: 16px;
  box-sizing: border-box;
  transition: transform .35s cubic-bezier(0.16, 1, 0.3, 1);
}
.prod-card:hover .prod-plate-img { transform: scale(1.04); }

@media (max-width: 760px) {
  .eq-figure-img { height: 280px; padding: 16px; }
  .eq-card-img { height: 160px; }
}

@media (prefers-reduced-motion: reduce) {
  .eq-card-img,
  .prod-plate-img { transition: none; }
  .eq-card:hover .eq-card-img,
  .prod-card:hover .prod-plate-img { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   SHAKER TABLES — LEGIBILITY
   ══════════════════════════════════════════════════════════════════════════
   Both shaker tables share one type scale. The compatibility matrix was sized
   up first; the panel configuration table followed once the 'Fits' column was
   dropped, which freed the width that had been forcing small type on it.

   The !important flags match those on the base .ss-name / .ss-mono rules;
   the two-class selector is what wins, not the flag. */

.ss-table th,
.ss-matrix th {
  font-size: 11px;
  letter-spacing: .16em;
  padding: 16px 22px;
}

.ss-table td,
.ss-matrix td {
  font-size: 15px;
  line-height: 1.6;
  padding: 18px 22px;
  color: var(--cloud);
}

/* Lead cell — shaker model in the matrix, configuration name in the panel
   table. Either way it is the row's lookup key, so it leads. */
.ss-table .ss-name,
.ss-matrix .ss-name {
  font-size: 19px !important;
  line-height: 1.3;
}

/* Mesh series codes. Monospace runs visually smaller than Barlow at the same
   px, so this sits slightly under the body size rather than matching it. */
.ss-table .ss-mono,
.ss-matrix .ss-mono {
  font-size: 14px !important;
  letter-spacing: .02em;
}

@media (max-width: 760px) {
  .ss-table th,
  .ss-matrix th { font-size: 10px; padding: 14px 16px; }
  .ss-table td,
  .ss-matrix td { font-size: 14px; padding: 16px; }
  .ss-table .ss-name,
  .ss-matrix .ss-name { font-size: 17px !important; }
  .ss-table .ss-mono,
  .ss-matrix .ss-mono { font-size: 13px !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   SHAKER PANEL — EXPANDABLE ROWS
   ══════════════════════════════════════════════════════════════════════════
   Each summary row in the Panel Configurations table toggles a detail row
   holding the panel photograph and the specification fields that don't earn a
   column of their own. The detail row is in the HTML from the start and only
   `hidden` is toggled, so the content is indexable and survives no-JS. */

.ss-row-toggle { cursor: pointer; }

/* Chevron marking the row as expandable. Rotates to point down when open. */
.ss-chev {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 10px;
  border-right: 2px solid var(--orange);
  border-bottom: 2px solid var(--orange);
  transform: rotate(-45deg) translateY(-2px);
  transition: transform .25s cubic-bezier(0.16, 1, 0.3, 1);
  vertical-align: middle;
}
.ss-row-toggle.is-open .ss-chev { transform: rotate(45deg) translateY(-2px); }

.ss-row-toggle.is-open {
  background: rgba(212, 84, 26, 0.08);
  /* Suppress the row's own bottom rule so the summary and its detail read as
     one block rather than two stacked rows. */
  border-bottom-color: transparent;
}

/* ── Detail row ─────────────────────────────────────────────────────────── */

.ss-detail-row > .ss-detail-cell {
  /* Overrides .tds-table td's fixed width and padding — this cell spans the
     full table and manages its own spacing. */
  width: auto !important;
  padding: 0 !important;
  background: rgba(212, 84, 26, 0.04);
  border-bottom: 2px solid rgba(212, 84, 26, 0.25);
}

.ss-detail {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 32px;
  padding: 28px 24px 30px;
  align-items: start;
}

.ss-detail-media {
  background: #F5F7FA;
  border: 1px solid rgba(212, 84, 26, 0.15);
  border-radius: 4px;
  overflow: hidden;
}
.ss-detail-img {
  display: block;
  width: 100%;
  height: 240px;
  object-fit: contain;
  padding: 14px;
  box-sizing: border-box;
}
.ss-detail-media-empty {
  height: 240px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border-style: dashed;
}
.ss-detail-noimg {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(168, 184, 200, 0.35);
}

.ss-detail-title {
  font-family: 'Barlow Condensed', sans-serif;
  font-weight: 700;
  font-size: 26px;
  letter-spacing: .02em;
  line-height: 1.1;
  color: var(--pure);
  margin-bottom: 6px;
}
.ss-detail-sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: .1em;
  color: var(--ember);
  margin-bottom: 22px;
}

/* ── Spec pairs ─────────────────────────────────────────────────────────── */

.ss-detail-specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 16px 28px;
  margin: 0 0 24px;
}
.ss-detail-spec dt {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--orange);
  margin-bottom: 5px;
}
.ss-detail-spec dd {
  font-family: 'Barlow', sans-serif;
  font-size: 15px;
  line-height: 1.5;
  color: var(--cloud);
  margin: 0;
}

.ss-detail-actions {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 18px;
  border-top: 1px solid rgba(212, 84, 26, 0.15);
}
.ss-detail-cta { flex-shrink: 0; }
.ss-detail-pack {
  font-family: 'Barlow', sans-serif;
  font-size: 13px;
  color: var(--mist);
}

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 860px) {
  .ss-detail { grid-template-columns: 1fr; gap: 22px; padding: 22px 18px 24px; }
  .ss-detail-img, .ss-detail-media-empty { height: 200px; }
  .ss-detail-title { font-size: 22px; }
  .ss-detail-specs { grid-template-columns: 1fr 1fr; gap: 14px 20px; }
}
@media (max-width: 560px) {
  .ss-detail-specs { grid-template-columns: 1fr; }
}

/* ── Accessibility ──────────────────────────────────────────────────────── */

.ss-row-toggle:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
  .ss-chev { transition: none; }
}

/* ── Equal column widths ────────────────────────────────────────────────────
   Both shaker tables were on table-layout:auto, so each column sized to its
   own content: 'Packaging' took a third of the width on the strength of one
   long repeated string while 'API RP 13C' was squeezed, and the two tables
   sat on the page with visibly different rhythms.

   Fixed layout with an explicit per-column fraction divides the width evenly
   instead. The fraction has to be stated per table because it depends on the
   column count — 6 in the panel table, 3 in the compatibility matrix. */

.ss-table, .ss-matrix { table-layout: fixed; }

.ss-table th, .ss-table td { width: 16.6667%; }      /* 6 columns */
.ss-matrix th, .ss-matrix td { width: 33.3333%; }    /* 3 columns */

/* Fixed columns can't grow to fit an unbreakable string, so the mono cells
   drop the global nowrap here — 'API 120 – API 400' would otherwise spill
   past its column edge at narrow widths rather than wrapping inside it. */
.ss-table .ss-mono, .ss-matrix .ss-mono {
  white-space: normal !important;
  word-break: break-word;
}

/* Long values (packaging text, mesh material) wrap rather than overflow. */
.ss-table td, .ss-matrix td {
  overflow-wrap: break-word;
  word-wrap: break-word;
}

/* The detail row spans every column, so it must opt out of the fixed width
   or it inherits a single column's share and collapses. */
.ss-detail-row > .ss-detail-cell { width: auto !important; }

/* ── Compatibility matrix: centred value columns ────────────────────────────
   Screen Type and Mesh Series hold short codes ('PWP', 'DX · DF · HP') in
   equal-width columns, so left-aligned they sat against the left edge with a
   long empty run after them. Centring puts the value under the middle of its
   own column. Shaker Model stays left-aligned — it is the lookup key the eye
   runs down, and a ragged left edge is harder to scan.

   Headers are centred with their cells so the column reads as one unit; this
   also overrides .tds-table's th:last-child rule, which the base stylesheet
   had already flipped back to left for these tables. */

.ss-matrix th:nth-child(2),
.ss-matrix th:nth-child(3),
.ss-matrix td:nth-child(2),
.ss-matrix td:nth-child(3) {
  text-align: center;
}
