/* ==========================================================================
   Nano Ceramic 9H, shared stylesheet
   Linked from every page's <head> via <link rel="stylesheet" href="styles.css">,
   so it loads once and is cached across all pages.

   Class prefix: nc-
   Hover and focus states are the .nc-hv-* / .nc-fc-* utilities near the bottom
   of this file. They were style-hover="..." attributes compiled at runtime
   until the Design Composer runtime was removed.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts, self-hosted from ./fonts

   Both families were loaded from fonts.googleapis.com on all 31 pages, which
   cost two extra hosts, two TLS handshakes and a serialised dependency: the
   browser could not request a font until Google's stylesheet came back. These
   are the same files Google serves, downloaded and declared here instead.

   Variable, not static: one file per family covers 400-700 rather than four
   files each. That is why every weight the site uses (400, 500, 600, 700)
   works from a single src, and why no @font-face is repeated per weight.

   Split by unicode-range exactly as Google splits them, so the browser fetches
   latin-ext only on a page that needs it. Only one character on the whole site
   does: the rupee sign in the Ceramic Booster pricing. Vietnamese is dropped.

   The arrows and geometric symbols in the carousel buttons and the About Us
   icon pads (U+27F5, U+27F6, U+2248, U+25B3, U+25CB, U+25CE) sit outside every
   subset Google publishes, so they render in a system font. That was already
   true when the fonts came from Google; it is not a regression here.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/archivo-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/archivo-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Host Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(fonts/host-grotesk-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Host Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(fonts/host-grotesk-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --nc-ink: #1A1A1A;
  --nc-muted: #525252;
  --nc-dim: #737373;
  --nc-faint: #A3A3A3;
  --nc-accent: #E02926;
  --nc-accent-dk: #C21E1B;
  --nc-line: #E5E7EB;
  --nc-surface: #F4F4F5;
  --nc-slate: #2A333C;
  --nc-white: #FFFFFF;
  --nc-onDark: #D4D4D8;

  /* Colours that were only ever written as literal hexes inside style="..."
     attributes. Naming them is what stops the next near-duplicate from being
     invented: eight different light greys had already accumulated this way.
     See the design system page for where each one belongs. */
  --nc-tint: #FDEBEB;
  /* accent tint: icon pads, category pills */
  --nc-accent-lt: #FCA5A5;
  /* accent text on a dark row */
  --nc-onSlate: #B9C0C7;
  /* body copy on --nc-slate */
  --nc-slate-line: #3A454F;
  /* hairline on --nc-slate */
  --nc-ink-deep: #14181C;
  /* full-bleed band, one step below --nc-ink */
  --nc-warm: #EDE6E4;
  /* warm backing behind case study cards */
  --nc-fill: #E9E9EC;
  /* image box / skeleton fill */
  --nc-fill-lt: #F1F1F3;
  /* lighter fill, and the bullet hairline */
  --nc-surface-lt: #FAFAFB;
  /* barely-there section tint */
  --nc-wash: #FAF4F4;
  /* warm hero wash: stripe */
  --nc-wash-bg: #F7EFEF;
  /* warm hero wash: base */
  --nc-wash-soft: #FAF4F49A;
  /* the same wash at 60% alpha: tinted page top */

  /* Hover-only surfaces, one step off their resting colour. */
  --nc-slate-hv: #333E49;
  /* .nc-hv-bgslate, one step up from --nc-slate */
  --nc-surface-hv: #EFEFF1;
  /* .nc-hv-bggrey, one step down from --nc-surface */

  --nc-font: 'Archivo', 'Helvetica Neue', Helvetica, sans-serif;
  --nc-font-body: 'Host Grotesk', 'Archivo', sans-serif;
  --nc-maxw: 1440px;

  /* Horizontal page gutter. Shrinks at breakpoints, but only on pages that
     opt in via .nc-rwd (see the responsive section at the end of this file). */
  --nc-gutter: 48px;
}

/* --------------------------------------------------------------------------
   Base / reset  (was duplicated in all 28 pages' <helmet><style>)
   -------------------------------------------------------------------------- */

@view-transition {
  navigation: auto;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--nc-white);
}

body {
  font-family: var(--nc-font);
  color: var(--nc-ink);
  -webkit-font-smoothing: antialiased;
}

p {
  font-family: var(--nc-font-body);
}

input,
select,
textarea {
  font-family: var(--nc-font-body);
}

a {
  color: var(--nc-ink);
  text-decoration: none;
}

a:hover {
  color: var(--nc-accent-dk);
}

::selection {
  background: var(--nc-accent);
  color: var(--nc-white);
}

@keyframes marquee-left {
  from {
    transform: translateX(0);
  }

  to {
    transform: translateX(-50%);
  }
}

/* --------------------------------------------------------------------------
   Page shell
   -------------------------------------------------------------------------- */

.nc-screen {
  min-width: 1200px;
  background: var(--nc-white);
}

/* Centred max-width row used by the utility bar, nav and footer bar.
   Padding differs per usage, hence the -a/-b/-c/-d modifiers.

   Deliberately content-box, matching .nc-wrap/.nc-section/.nc-head below.
   Those three put the 1440 on the content and add the gutter outside it, so
   their outer box is 1536. A border-box bar puts the 1440 on the outer box
   instead, which makes its content 1344 and starts it 48px further in than
   every section on the page. Same max-width, same padding, different box:
   that mismatch is the only reason the logo sat off the body's left edge. */
.nc-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: var(--nc-maxw);
  margin: 0 auto;
}

/* All four carry the gutter. -a/-b used to run at 0, which pinned them to the
   viewport edge instead of the content edge. */
.nc-bar-a {
  padding: 16px 48px;
}

.nc-bar-b {
  padding: 18px 48px;
}

.nc-bar-c {
  padding: 18px 48px;
}

.nc-bar-d {
  padding: 16px 48px;
}

.nc-section {
  max-width: var(--nc-maxw);
  margin: 0 auto;
  padding: 96px 48px;
}

.nc-head {
  max-width: var(--nc-maxw);
  margin: 0 auto;
  padding: 80px 48px 40px;
}

/* Copy column of the full-bleed split hero. The picture runs to the viewport
   edge, so the column itself is half the viewport, but the copy inside it has
   to start on the same line as every .nc-wrap section below it.

   Inside a half-viewport track 100% is vw/2, so (100% - 720px) resolves to
   (vw - 1440)/2: exactly the left offset .nc-wrap lands on. Below 1536 that
   goes negative and the gutter wins, which is again what .nc-wrap does. The
   old rule used margin-left:auto against a 720px cap, which pinned the copy to
   the 50% split instead and drifted further right the wider the screen got.

   A useful side effect: content width settles at 720 - gutter for every width
   at or above 1536, so the measure holds still while the offset tracks the
   viewport. Stacked below 900 the track becomes the full viewport and the
   subtraction would run away, so the breakpoint resets padding-left. */
.nc-herocol {
  min-width: 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 76px var(--nc-gutter) 76px max(var(--nc-gutter), 100% - 720px);
}

/* --------------------------------------------------------------------------
   Utility bar + nav
   -------------------------------------------------------------------------- */

.nc-utilbar {
  background: var(--nc-ink);
  color: var(--nc-onDark);
  font-size: 13px;
}

/* Utility bar entries. All three used to be plain <span>s, so on a phone the
   two most useful things in the header, the number and the address, were not
   tappable at all. They are real links now at every width.

   The icon is a CSS mask rather than inline SVG: it keeps the markup to one
   <a> per entry across 31 pages, and painting with currentColor means the
   icon picks up the hover colour for free. Sized in em so it tracks the
   font-size drops at the two small breakpoints without extra rules. */
.nc-utillink {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}

.nc-utillink::before {
  content: "";
  flex: 0 0 auto;
  width: 1.15em;
  height: 1.15em;
  background: currentColor;
  /* Phosphor Regular is a stroked outline, so it carries less ink than a solid
     glyph and needs to sit a little larger and a little stronger to hold up
     against 11-13px text. */
  opacity: 0.75;
  -webkit-mask: var(--nc-utilicon) center / contain no-repeat;
  mask: var(--nc-utilicon) center / contain no-repeat;
}

.nc-utillink:hover,
.nc-utillink:focus-visible {
  color: var(--nc-white);
}

.nc-utillink:hover::before,
.nc-utillink:focus-visible::before {
  opacity: 1;
}

/* Phosphor Regular, the same set the rest of the site draws from: Phone and
   Envelope are the identical paths the CTA panels use, MapPin is new. The
   complete outlines matter here, because each of these relies on a second,
   counter-wound subpath to punch its interior. Truncating them at the first
   subpath is what turns the handset and the pin into solid blobs. */
.nc-utillink-tel {
  --nc-utilicon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath fill='%23000' d='M222.37,158.46l-47.11-21.11-.13-.06a16,16,0,0,0-15.17,1.4,8.12,8.12,0,0,0-.75.56L134.87,160c-15.42-7.49-31.34-23.29-38.83-38.51l20.78-24.71c.2-.25.39-.5.57-.77a16,16,0,0,0,1.32-15.06l0-.12L97.54,33.64a16,16,0,0,0-16.62-9.52A56.26,56.26,0,0,0,32,80c0,79.4,64.6,144,144,144a56.26,56.26,0,0,0,55.88-48.92A16,16,0,0,0,222.37,158.46ZM176,208A128.14,128.14,0,0,1,48,80,40.2,40.2,0,0,1,82.87,40a.61.61,0,0,0,0,.12l21,47L83.2,111.86a6.13,6.13,0,0,0-.57.77,16,16,0,0,0-1,15.7c9.06,18.53,27.73,37.06,46.46,46.11a16,16,0,0,0,15.75-1.14,8.44,8.44,0,0,0,.74-.56L168.89,152l47,21.05h0s.08,0,.11,0A40.21,40.21,0,0,1,176,208Z'/%3E%3C/svg%3E");
}

.nc-utillink-mail {
  --nc-utilicon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath fill='%23000' d='M224,48H32a8,8,0,0,0-8,8V192a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A8,8,0,0,0,224,48Zm-96,85.15L52.57,64H203.43ZM98.71,128,40,181.81V74.19Zm11.84,10.85,12,11.05a8,8,0,0,0,10.82,0l12-11.05,58,53.15H52.57ZM157.29,128,216,74.18V181.82Z'/%3E%3C/svg%3E");
}

.nc-utillink-map {
  --nc-utilicon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath fill='%23000' d='M128,64a40,40,0,1,0,40,40A40,40,0,0,0,128,64Zm0,64a24,24,0,1,1,24-24A24,24,0,0,1,128,128Zm0-112a88.1,88.1,0,0,0-88,88c0,31.4,14.51,64.68,42,96.25a254.19,254.19,0,0,0,41.45,38.3,8,8,0,0,0,9.18,0A254.19,254.19,0,0,0,174,192.25c27.45-31.57,42-64.85,42-96.25A88.1,88.1,0,0,0,128,16Zm0,206c-16.53-13-72-60.75-72-126a72,72,0,0,1,144,0C200,161.23,144.53,209,128,222Z'/%3E%3C/svg%3E");
}

.nc-nav {
  background: var(--nc-white);
  border-bottom: 1px solid var(--nc-line);
  position: sticky;
  top: 0;
  z-index: 50;
}

.nc-navlinks {
  display: flex;
  gap: 32px;
  font-size: 15px;
  font-weight: 500;
  color: var(--nc-muted);
}

/* Nav item + hover dropdown.
   Lives here rather than as style-hover attributes because a dropdown needs a
   parent:hover -> child selector, which inline attributes cannot express. */
.nc-navitem {
  position: relative;
  display: flex;
  align-items: center;
}

.nc-navlink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: inherit;
  white-space: nowrap;
}

.nc-navlink:hover {
  color: var(--nc-accent);
}

.nc-navlink-active {
  color: var(--nc-accent);
}

.nc-caret {
  font-size: 9px;
  line-height: 1;
  opacity: 0.75;
  transition: transform 0.16s ease;
}

.nc-navitem:hover .nc-caret {
  transform: rotate(180deg);
}

.nc-dropdown {
  position: absolute;
  top: calc(100% + 14px);
  left: -14px;
  min-width: 250px;
  background: var(--nc-white);
  border: 1px solid var(--nc-line);
  border-radius: 12px;
  padding: 8px;
  box-shadow: 0 18px 44px rgba(26, 26, 26, 0.13);
  display: flex;
  flex-direction: column;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
  z-index: 60;
}

/* Invisible bridge so the pointer can cross the gap between the nav link and
   the panel without the dropdown closing. */
.nc-dropdown::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -16px;
  height: 16px;
}

.nc-navitem:hover .nc-dropdown,
.nc-navitem:focus-within .nc-dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.nc-dropitem {
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  color: var(--nc-muted);
  white-space: nowrap;
}

.nc-dropitem:hover {
  background: var(--nc-surface);
  color: var(--nc-accent);
}

/* Nested submenu, one level deeper than nc-dropdown/nc-navitem. Same
   hover-desktop / accordion-mobile split as the parent, but flyouts sideways
   on desktop since it opens from inside an already-open panel. */
.nc-subitem {
  position: relative;
}

.nc-subitem>.nc-dropitem {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.nc-subcaret {
  flex-shrink: 0;
  font-size: 9px;
  line-height: 1;
  opacity: 0.6;
  transform: rotate(-90deg);
}

.nc-subdrop {
  position: absolute;
  top: -8px;
  left: calc(100% + 10px);
  min-width: 220px;
  background: var(--nc-white);
  border: 1px solid var(--nc-line);
  border-radius: 12px;
  padding: 8px;
  box-shadow: 0 18px 44px rgba(26, 26, 26, 0.13);
  display: flex;
  flex-direction: column;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  transform: translateX(6px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
  z-index: 61;
}

/* bridge so the pointer can cross from the parent item into the flyout */
.nc-subdrop::before {
  content: "";
  position: absolute;
  right: 100%;
  top: 0;
  bottom: 0;
  width: 14px;
}

.nc-subitem:hover .nc-subdrop,
.nc-subitem:focus-within .nc-subdrop {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
}

.nc-logolink {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.nc-logo {
  height: 42px;
  width: auto;
  display: block;
}

.nc-breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 500;
  color: var(--nc-muted);
  margin-bottom: 28px;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.nc-btn {
  background: var(--nc-accent);
  color: var(--nc-white);
  padding: 11px 22px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
}

.nc-btn-block {
  display: block;
  text-align: center;
  background: var(--nc-accent);
  color: var(--nc-white);
  padding: 15px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 600;
}

/* the block button is now a real <button>, which does not inherit the
   anchor's box or the page font by default */
button.nc-btn-block {
  width: 100%;
  border: none;
  cursor: pointer;
  font-family: inherit;
  line-height: 1.2;
}

/* --------------------------------------------------------------------------
   Flair button

   A circular fill grows from wherever the pointer entered, follows it around
   the button, then shrinks out towards the edge it left by. Ported from the
   GSAP "magnetic button" demo, but with no GSAP: the whole effect is one
   transform and one transition, so it costs nothing beyond what is already
   here. The pen's power2.out ease is easeOutCubic, written out below.

   Progressive enhancement, in three layers:
     - no CSS at all: a plain link
     - CSS only, no JavaScript: :hover fills the pill the ordinary way
     - nc.js present, fine pointer, motion allowed: the fill tracks the cursor
   nc.js adds .nc-flair-ready to <html>, which is what suppresses the plain
   hover fill so the two never run at once.
   -------------------------------------------------------------------------- */

.nc-btn-flair {
  /* The ring colour, as a pair: --nc-ring at rest, --nc-ring-hv once the fill
     has arrived. Every colourway sets both, and --nc-ring-live is the one the
     ring actually reads, so a state rule only ever has to swap that one. The
     ring has to travel with the fill: left pinned, a red ring stays drawn
     around an ink button and reads as a stray outline. */
  --nc-ring: var(--nc-accent);
  --nc-ring-hv: var(--nc-accent);
  --nc-ring-live: var(--nc-ring);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 20px 34px;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--nc-accent);
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  /* normal, not a number. Every button this class replaced inherited the
     default line-height, and pinning 1.2 made each one 1.8px taller at 14px,
     which pushed everything below it down the page. Keeping it normal makes
     the class a true drop-in for the inline buttons it replaces. */
  line-height: normal;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  /* The label has no colour of its own, it inherits this one, so the label
     recolours from here and the two can never be set from different places. */
  transition: background 0.2s ease, color 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
}

/* The ring is a pseudo-element, not a border, so the fill sweeps underneath it
   rather than being clipped inside it. It goes invisible once the pill is
   fully filled, which is exactly what the original does. */
.nc-btn-flair::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--nc-ring-live);
  border-radius: 999px;
  pointer-events: none;
  /* 0.3s, the same as the fill's drain, so the ring fades back in step with
     it on the way out. The way in is retimed to 0.4s below. */
  transition: border-color 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.nc-btn-flair-fill {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform-origin: 0 0;
  transform: translate(var(--nc-fx, 50%), var(--nc-fy, 50%)) scale(var(--nc-fs, 0));
  transition: transform 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
  will-change: transform;
}

/* Square, pulled back by half its own size, so the circle is centred on the
   box's top-left corner. That corner is what gets moved to the cursor, and
   scaling about transform-origin 0 0 then grows the circle about its own
   centre.

   200%, where the original used 170%. At 170% a pointer entering at the far
   left of a wide pill leaves a sliver of the right end unfilled, and since the
   label turns white as the fill arrives, any label text in that sliver would
   be white on white until the pointer moved. 200% covers the pill from any
   entry point. */
.nc-btn-flair-fill::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: var(--nc-accent);
  transform: translate(-50%, -50%);
}

/* Deliberately NOT a flex container. A flex box takes its height from the
   text's content box and drops the half-leading, which made every button 2px
   shorter than the inline-block it replaced and shifted whole pages up. Left
   as normal flow it generates the same line box the original text did, and the
   space before a trailing icon does the spacing that a gap was doing. */
.nc-btn-flair-label {
  position: relative;
  z-index: 1;
}

/* No-JavaScript fill: an ordinary hover, doing both jobs at once. */
.nc-btn-flair:hover {
  background: var(--nc-accent);
  color: var(--nc-white);
  --nc-ring-live: var(--nc-ring-hv);
}

/* With nc.js the flair does the filling, so the plain hover fill is dropped
   and the label is recoloured by .is-flairing, which the same mouseenter and
   mouseleave handlers set. Driving the fill from JavaScript and the label from
   :hover would let them disagree: :hover ends the instant the pointer leaves,
   while the fill still has 0.3s of draining to do, which would strand accent
   text on an accent fill. */
.nc-flair-ready .nc-btn-flair:hover {
  background: transparent;
  color: var(--nc-accent);
  --nc-ring-live: var(--nc-ring);
}

.nc-flair-ready .nc-btn-flair.is-flairing {
  color: var(--nc-white);
  --nc-ring-live: var(--nc-ring-hv);
}

/* Order matters, not specificity: the two rules above are both (0,3,0), so the
   .is-flairing one wins while the pointer is inside and stops applying the
   moment it leaves, which is exactly when the fill starts draining. */
.nc-flair-ready .nc-btn-flair.is-flairing::after {
  transition-duration: 0.4s;
}

.nc-btn-flair:focus-visible {
  outline: 2px solid var(--nc-accent);
  outline-offset: 3px;
}

/* Squared colourway. The fill is clipped by the button's own overflow, so the
   mechanic is indifferent to the radius; this exists because the hero CTA pairs
   on the two landing pages are 8px boxes rather than pills. */
.nc-btn-flair-sq,
.nc-btn-flair-sq::after {
  border-radius: 8px;
}

/* 14px vertical, where the buttons this replaces used 13px. A flex container
   takes its height from the text's content box and drops the half-leading, so
   at 15px the box came out 2px short and pulled the whole page up with it. The
   extra pixel a side puts it back at the original 44px. Measured, not guessed:
   the 14px buttons elsewhere need no such correction. */
.nc-btn-flair-sq {
  padding: 14px 26px;
}

/* Full-width colourway for form submits: fills the card edge to edge instead
   of sizing to its label. */
.nc-btn-flair-block {
  display: flex;
  width: 100%;
}

/* Solid colourway: an already-filled pill whose flair is the darker accent,
   for use where the button must stay a primary call to action. */
.nc-btn-flair-solid {
  background: var(--nc-accent);
  color: var(--nc-white);
  --nc-ring: var(--nc-accent);
  --nc-ring-hv: var(--nc-accent-dk);
}

.nc-btn-flair-solid .nc-btn-flair-fill::before {
  background: var(--nc-accent-dk);
}

.nc-btn-flair-solid:hover {
  background: var(--nc-accent-dk);
}

/* stays white throughout: the fill only deepens the red underneath it */
.nc-flair-ready .nc-btn-flair-solid:hover {
  background: var(--nc-accent);
  color: var(--nc-white);
}

/* Red button, ink fill. The header CTA: it must stay red at rest because that
   is the one button on every page, and filling to ink rather than to a second
   red reads as a deliberate state change instead of a shade. */
.nc-btn-flair-ink {
  background: var(--nc-accent);
  color: var(--nc-white);
  --nc-ring: var(--nc-accent);
  --nc-ring-hv: var(--nc-ink);
}

.nc-btn-flair-ink .nc-btn-flair-fill::before {
  background: var(--nc-ink);
}

.nc-btn-flair-ink:hover {
  background: var(--nc-ink);
}

/* white throughout: the label sits on red, then on ink, and reads on both */
.nc-flair-ready .nc-btn-flair-ink:hover {
  background: var(--nc-accent);
  color: var(--nc-white);
}

/* The inverse: ink button, red fill. Keeps the existing intent of the section
   CTAs on the solar page, which were ink and turned red on hover. */
.nc-btn-flair-dark {
  background: var(--nc-ink);
  color: var(--nc-white);
  --nc-ring: var(--nc-ink);
  --nc-ring-hv: var(--nc-accent);
}

.nc-btn-flair-dark .nc-btn-flair-fill::before {
  background: var(--nc-accent);
}

.nc-btn-flair-dark:hover {
  background: var(--nc-accent);
}

.nc-flair-ready .nc-btn-flair-dark:hover {
  background: var(--nc-ink);
  color: var(--nc-white);
}

/* Red button, white flair fill: default red bg with white text; on hover white bg with red text & border */
.nc-btn-flair-red-white {
  background: var(--nc-accent);
  color: var(--nc-white);
  --nc-ring: var(--nc-accent);
  --nc-ring-hv: var(--nc-accent);
}

.nc-btn-flair-red-white .nc-btn-flair-fill::before {
  background: var(--nc-white);
}

.nc-btn-flair-red-white:hover {
  background: var(--nc-white);
  color: var(--nc-accent);
}

.nc-flair-ready .nc-btn-flair-red-white:hover {
  background: var(--nc-accent);
  color: var(--nc-white);
}

.nc-flair-ready .nc-btn-flair-red-white.is-flairing {
  color: var(--nc-accent);
  --nc-ring-live: var(--nc-accent);
}


/* The header button keeps .nc-btn so every existing nav rule still finds it,
   including the two responsive ones. .nc-btn-flair is defined after .nc-btn and
   would otherwise win on padding and size, so the nav metrics are restated at a
   specificity that beats it but still loses to .nc-rwd .nc-nav .nc-btn below
   600px, which is what shrinks the button on a phone. */
.nc-nav .nc-btn-flair {
  padding: 11px 22px;
  font-size: 14px;
}

/* The cursor-tracking fill is pointer choreography. With motion reduced there
   is nothing to convey, so it is dropped for the plain hover instead. */
@media (prefers-reduced-motion: reduce) {
  .nc-btn-flair-fill {
    display: none;
  }

  /* Only reachable if the setting is turned on after load, since initFlair
     bails before adding .nc-flair-ready. The ring goes back to following
     :hover here, because with the fill gone :hover is the only state left. */
  .nc-flair-ready .nc-btn-flair:hover {
    background: var(--nc-accent);
    --nc-ring-live: var(--nc-ring-hv);
  }

  .nc-flair-ready .nc-btn-flair-solid:hover {
    background: var(--nc-accent-dk);
  }

  .nc-flair-ready .nc-btn-flair-ink:hover {
    background: var(--nc-ink);
  }

  .nc-flair-ready .nc-btn-flair-dark:hover {
    background: var(--nc-accent);
  }
}


/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */


.nc-cardtitle {
  font-size: 17px;
  font-weight: 700;
  color: var(--nc-ink);
  margin-bottom: 6px;
}

.nc-foothead {
  font-size: 15px;
  font-weight: 700;
  color: var(--nc-white);
  margin-bottom: 16px;
}

.nc-h2-light {
  font-size: 42px;
  line-height: 1.12;
  letter-spacing: -0.02em;
  font-weight: 700;
  margin: 0 0 28px;
  color: var(--nc-white);
}

.nc-bignum {
  font-size: 108px;
  font-weight: 700;
  letter-spacing: -0.05em;
  line-height: 1.02;
  color: var(--nc-ink);
  white-space: nowrap;
}

.nc-fine {
  font-size: 13px;
  line-height: 1.5;
  color: var(--nc-muted);
  font-family: var(--nc-font-body);
}

/* --------------------------------------------------------------------------
   Panels, cards, media
   -------------------------------------------------------------------------- */

.nc-ctapanel {
  display: block;
}


.nc-tile {
  background: var(--nc-surface);
  border-radius: 12px;
  padding: 20px 22px;
}

.nc-media {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  height: 560px;
}

.nc-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(26, 26, 26, 0.45) 0%, rgba(26, 26, 26, 0.92) 100%);
}

.nc-overlay {
  position: absolute;
  left: 44px;
  right: 44px;
  bottom: 44px;
  pointer-events: none;
}

/* Numbered / lettered circular badges */
.nc-num {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--nc-surface);
  border: 1px solid var(--nc-line);
  display: grid;
  place-items: center;
  color: var(--nc-ink);
}

.nc-num-13 {
  font-size: 13px;
  font-weight: 700;
}

.nc-num-14 {
  font-size: 14px;
}

.nc-num-15 {
  font-size: 15px;
  font-weight: 700;
}

/* Circular icon buttons on dark backgrounds */
.nc-icon38 {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.6);
  display: grid;
  place-items: center;
}

.nc-icon38-15 {
  font-size: 15px;
}

.nc-icon38-16 {
  font-size: 16px;
}


/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.nc-footer {
  background: var(--nc-white);
}

/* four columns: brand, Menu, Products, Reach us. Identical on every page. */
.nc-footgrid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1.05fr;
  gap: 56px;
  padding-bottom: 72px;
}

.nc-footbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 40px;
  border-top: 1px solid var(--nc-line);
  font-size: 13px;
  color: var(--nc-dim);
}

.nc-brand {
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--nc-white);
  font-size: 22px;
  font-weight: 700;
}

.nc-linkcol {
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-size: 15px;
}

.nc-socials {
  display: flex;
  gap: 12px;
  margin-top: 28px;
}

/* ==========================================================================
   Icons: Phosphor + Font Awesome brands, inline SVG

   Every icon on the site is pasted in as literal markup. No icon font, no CDN,
   no sprite file: an icon renders with JavaScript off, with the network down
   and from a file:// path, which is the same standard the rest of this
   stylesheet holds to. The Font Awesome kit was deliberately not loaded for
   the four social marks, because pulling in a CDN stylesheet and a webfont to
   draw four logos would undo the same round trips the self-hosted fonts above
   were localised to remove.

   Interface icons are Phosphor at the stock 256x256 viewBox, weight `regular`
   throughout, except the marquee separators and the play triangle, which
   replace solid glyphs and use `fill`.

   The four social marks are Font Awesome Free 6.7.2 brand icons, at their own
   viewBoxes (448x512, 512x512 and 576x512), which is why they do not share
   Phosphor's square 256 box. Font Awesome Free icons are CC BY 4.0:
   https://fontawesome.com/license/free - Copyright 2024 Fonticons, Inc.
   That licence requires attribution, which this comment provides; do not
   delete it while the marks are still in use.

   Sizing is in em, so an icon inherits whatever font-size its container
   already sets and every existing size rule keeps working untouched. Colour
   comes from currentColor, so the .nc-hv-* hover utilities recolour icons for
   free without a single extra rule.
   ========================================================================== */

.nc-i {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
  display: inline-block;
  fill: currentColor;
  /* sits on the text baseline the way the glyphs it replaced did */
  vertical-align: -0.135em;
}

/* Optical sizes, set where a 1em box read too large or too small next to the
   type it sits beside. Measured against the glyphs these replaced. */
.nc-caret .nc-i {
  width: 1.15em;
  height: 1.15em;
  vertical-align: 0;
}

.nc-mq-star .nc-i {
  width: 0.82em;
  height: 0.82em;
}

.nc-mq-sep .nc-i {
  width: 0.9em;
  height: 0.9em;
}

.nc-bullet-mark .nc-i {
  width: 1.05em;
  height: 1.05em;
  vertical-align: 0;
}

/* Inside a grid/place-items:center box the baseline nudge would push the icon
   off centre, so it is cancelled for every circular badge. */
.nc-num .nc-i,
.nc-icon38 .nc-i,
.nc-iconpad .nc-i,
.nc-arrowbtn .nc-i {
  vertical-align: 0;
}

/* The social badges held two-letter text, so .nc-num-13/-14/-15 sized that
   text and the four siblings sat at three different sizes. A logo has no
   x-height to match, so they take one size and the modifiers now only affect
   the rare badge that still holds characters. */
.nc-num .nc-i {
  width: 18px;
  height: 18px;
}

/* --------------------------------------------------------------------------
   Disclosure toggle marks

   These are ::after content, which cannot hold an <svg>, so the Phosphor glyph
   is a mask and the colour comes from background: currentColor. That keeps the
   toggle pure CSS and keeps the colour tokenised, which a data: URI could not
   do because a URI cannot reference currentColor.
   -------------------------------------------------------------------------- */

.nc-faq-icon::after,
.nc-faqrow-sign::after,
.nc-detail-icon::after {
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
  background: currentColor;
  -webkit-mask: var(--nc-mark) center / contain no-repeat;
  mask: var(--nc-mark) center / contain no-repeat;
}

/* Phosphor plus / x / minus, regular. */
:root {
  --nc-mark-plus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z'/%3E%3C/svg%3E");
  --nc-mark-x: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z'/%3E%3C/svg%3E");
  --nc-mark-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128Z'/%3E%3C/svg%3E");
}

/* Open/closed marks. These used to be a straight swap of one mask for another,
   which can only ever cut from one glyph to the next. The mark is now held
   still and transformed instead, so the toggle can tween with the panel. End
   states are unchanged: + reads as x when open, + reads as - when open.

   + to x is a 45 degree rotation of the same plus.
   + to - is built from two minus bars, one laid across the other; the upright
   one rotates flat and fades, leaving the single bar. */
.nc-faq-icon,
.nc-detail-icon {
  --nc-mark: var(--nc-mark-plus);
}

.nc-faqrow-sign {
  --nc-mark: var(--nc-mark-minus);
  position: relative;
}

.nc-faqrow-sign::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1em;
  height: 1em;
  margin: -0.5em 0 0 -0.5em;
  background: currentColor;
  -webkit-mask: var(--nc-mark-minus) center / contain no-repeat;
  mask: var(--nc-mark-minus) center / contain no-repeat;
  transform: rotate(90deg);
}

.nc-faq[open] .nc-faq-icon::after {
  transform: rotate(45deg);
}

.nc-detail[open] .nc-detail-icon::after {
  transform: rotate(45deg);
}

.nc-faqrow[open] .nc-faqrow-sign::before {
  transform: rotate(0deg);
  opacity: 0;
}

/* ==========================================================================
   Components lifted out of repeated inline styles

   Everything below was written as a style="..." attribute, the same
   declarations repeated on every instance across the site: the comparison
   table cell alone appeared 129 times in three orderings. Each class here
   reproduces the declarations exactly, so adding it and deleting the attribute
   renders identically.

   Two things had drifted and are unified here rather than preserved:
     - the marquee ran at 26px on two pages and 24px on two others
     - the section eyebrow appeared with and without an explicit
       font-family: Archivo, which is already the inherited body font
   ========================================================================== */

/* ---- Section furniture ---- */

/* Small uppercase kicker above a section heading. */
.nc-eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--nc-dim);
  margin-bottom: 10px;
}

/* The accent-coloured variant, wider tracking, used above page headings. */
.nc-eyebrow-accent {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nc-accent);
  margin-bottom: 16px;
}

/* font-family is explicit, not inherited. 25 of the 41 instances set Archivo
   inline and 16 relied on inheriting it, which meant the same heading rendered
   in the body font anywhere it sat inside a Host Grotesk container. */
.nc-h4 {
  font-family: var(--nc-font);
  font-size: 20px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--nc-ink);
}

.nc-lede {
  font-size: 18px;
  line-height: 1.75;
  color: var(--nc-muted);
  margin: 0 0 24px;
}

/* ---- Pills, chips and marks ---- */

/* Outlined filter/spec chip. */
.nc-chip {
  background: var(--nc-surface);
  border: 1px solid var(--nc-line);
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--nc-muted);
}

/* Small tinted tag. Two colourways, otherwise identical. */
.nc-tag,
.nc-tag-grey {
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--nc-font-body);
}

.nc-tag {
  background: var(--nc-tint);
  color: var(--nc-accent-dk);
}

.nc-tag-grey {
  background: var(--nc-surface);
  color: var(--nc-muted);
}

/* Full-width pill row: dot + label, used for application lists. */
.nc-pillrow {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--nc-white);
  border: 1px solid var(--nc-line);
  border-radius: 999px;
  padding: 13px 22px;
}

.nc-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--nc-accent);
  flex-shrink: 0;
}

/* Rounded accent pad behind a glyph at the head of a feature card. */
.nc-iconpad {
  width: 50px;
  height: 50px;
  border-radius: 14px;
  background: var(--nc-tint);
  color: var(--nc-accent);
  display: grid;
  place-items: center;
  font-size: 20px;
  margin-bottom: 24px;
}

/* Outlined circular arrow that sits at the end of a card footer. */
.nc-arrowbtn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--nc-line);
  display: grid;
  place-items: center;
  color: var(--nc-accent);
  font-size: 15px;
  flex-shrink: 0;
}

/* ---- Bulleted feature list ---- */

.nc-bullet {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 20px 0;
  border-bottom: 1px solid var(--nc-line);
}

.nc-bullet-mark {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--nc-tint);
  color: var(--nc-accent);
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: 700;
  flex-shrink: 0;
  margin-top: 2px;
}

.nc-bullet-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--nc-ink);
  margin-bottom: 5px;
}

.nc-bullet-text {
  font-size: 14px;
  line-height: 1.6;
  color: var(--nc-muted);
  font-family: var(--nc-font-body);
}

/* ---- Comparison / observation table ---- */
/* The grid itself is .nc-g3-table; these are the parts inside it. */

.nc-thead {
  background: var(--nc-ink);
  color: var(--nc-white);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.nc-trow {
  border-top: 1px solid var(--nc-line);
  font-size: 16px;
  font-family: var(--nc-font-body);
}

.nc-th {
  background: var(--nc-white);
  padding: 24px 26px;
}

.nc-td-key {
  padding: 20px 26px;
  font-weight: 600;
  color: var(--nc-ink);
}

.nc-td-val {
  padding: 20px 26px;
  color: var(--nc-muted);
}

.nc-td-after {
  padding: 18px 26px;
  color: var(--nc-accent-lt);
}

/* Hairline grid: the 1px gaps show the container colour through as dividers. */
.nc-grid-hair {
  gap: 1px;
  background: var(--nc-line);
  border: 1px solid var(--nc-line);
  border-radius: 16px;
  overflow: hidden;
}

/* ---- Cards and media ---- */

.nc-card-outline {
  border: 1px solid var(--nc-line);
  border-radius: 20px;
  overflow: hidden;
  background: var(--nc-white);
}

/* An <img> that fills its positioned parent. */
.nc-imgfill {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Top-and-bottom scrim on a product card, so both the eyebrow at the top and
   the blurb at the bottom stay legible over any artwork. */
.nc-cardscrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg,
      rgba(20, 22, 25, 0.82) 0%, rgba(20, 22, 25, 0.32) 30%, rgba(20, 22, 25, 0) 50%,
      rgba(20, 22, 25, 0.34) 72%, rgba(20, 22, 25, 0.9) 100%);
}

/* Caption band along the bottom of a gallery tile. */
/* Gallery tile. The frame is fixed by the grid and the picture is cropped to
   fill it, so the hover is an inset zoom: the image grows inside a frame that
   does not move, and the overflow clip does the rest. Scaling the picture
   rather than the tile is what keeps the neighbours from being nudged. */
.nc-shot {
  position: relative;
  display: block;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--nc-line);
  background: var(--nc-surface);
  cursor: zoom-in;
}

.nc-shot .nc-imgfill {
  transition: transform 450ms cubic-bezier(0.2, 0.7, 0.3, 1);
  will-change: transform;
}

.nc-shot:hover .nc-imgfill,
.nc-shot:focus-visible .nc-imgfill {
  transform: scale(1.06);
}

/* Lightbox. Built by nc.js on first open and reused after that, so a visitor
   who never opens a picture pays nothing for it. Without the script the tiles
   remain plain links to the full-size files. */
.nc-lb {
  position: fixed;
  inset: 0;
  z-index: 200;
  /* nc.js switches this to flex on open, so the empty overlay can never sit
     invisibly over the page swallowing clicks. */
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(12, 14, 17, 0.92);
  opacity: 0;
  transition: opacity 200ms ease;
}

.nc-lb-open {
  opacity: 1;
}

.nc-lb-fig {
  margin: 0;
  max-width: min(1200px, calc(100vw - 140px));
  max-height: calc(100vh - 150px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.nc-lb-img {
  display: block;
  max-width: 100%;
  /* leaves room for the caption under the picture */
  max-height: calc(100vh - 210px);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 10px;
  background: var(--nc-ink);
}

.nc-lb-cap {
  color: var(--nc-white);
  font-size: 15px;
  font-weight: 600;
  text-align: center;
  text-wrap: pretty;
}

.nc-lb-count {
  position: absolute;
  top: 26px;
  left: 26px;
  color: rgba(255, 255, 255, 0.62);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.nc-lb-btn {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  color: var(--nc-white);
  cursor: pointer;
  transition: background 160ms ease;
}

.nc-lb-btn:hover {
  background: var(--nc-accent);
}

.nc-lb-btn svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.nc-lb-close {
  top: 18px;
  right: 18px;
}

.nc-lb-prev {
  left: 18px;
  top: 50%;
  transform: translateY(-50%);
}

.nc-lb-next {
  right: 18px;
  top: 50%;
  transform: translateY(-50%);
}

/* One picture at a time on a phone: the side buttons would sit on top of the
   image at that width, so they move to a row beneath the caption. */
@media (max-width: 599px) {
  .nc-lb-fig {
    max-width: calc(100vw - 32px);
  }

  .nc-lb-img {
    max-height: calc(100vh - 260px);
  }

  .nc-lb-prev {
    left: calc(50% - 58px);
    top: auto;
    bottom: 26px;
    transform: none;
  }

  .nc-lb-next {
    right: calc(50% - 58px);
    top: auto;
    bottom: 26px;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nc-shot .nc-imgfill {
    transition: none;
  }

  .nc-shot:hover .nc-imgfill,
  .nc-shot:focus-visible .nc-imgfill {
    transform: none;
  }

  .nc-lb {
    transition: none;
  }
}

.nc-tilecap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  padding: 44px 18px 16px;
  background: linear-gradient(180deg, transparent 0%, rgba(16, 19, 23, 0.78) 100%);
  color: var(--nc-white);
  font-size: 14px;
  font-weight: 600;
}

.nc-statnum {
  font-family: var(--nc-font);
  font-size: 28px;
  font-weight: 700;
  color: var(--nc-accent);
  margin-bottom: 4px;
}

/* ---- Marquee ---- */
/* Two designs. -word/-star is the uppercase category band; -name/-sep is the
   product-name band on the about page. The category band ran at 26px on two
   pages and 24px on two others; one size now. */

/* The scrolling track. Duration is per page, passed in as --nc-mq-dur, because
   it was the one thing that genuinely differed (34s / 36s / 38s). It lived in
   an inline `animation:` shorthand, and an inline declaration cannot be
   overridden by a media query, so the marquee was the only motion on the site
   that ignored prefers-reduced-motion. As a class it can be switched off. */
.nc-mq-track {
  display: flex;
  width: max-content;
  animation: marquee-left var(--nc-mq-dur, 36s) linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .nc-mq-track {
    animation: none;
  }
}

.nc-mq-item {
  display: flex;
  align-items: center;
  gap: 34px;
  padding-right: 34px;
}

.nc-mq-word {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--nc-white);
  white-space: nowrap;
}

.nc-mq-star {
  font-size: 16px;
  color: rgba(255, 255, 255, 0.72);
  line-height: 1;
  flex-shrink: 0;
}

.nc-mq-name {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--nc-white);
}

.nc-mq-sep {
  font-size: 14px;
  color: var(--nc-accent);
}

/* --------------------------------------------------------------------------
   Standalone pages  (404, thank-you)
   Centred, chrome-free pages. They deliberately skip .nc-screen, so they never
   inherit its 1200px min-width and need no .nc-rwd; their own clamps carry the
   responsive behaviour. This lived in a page-local <style> block on each page
   until it moved here, which is why the two drifted apart.
   -------------------------------------------------------------------------- */

.nc-err,
.nc-ty {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px 20px;
  box-sizing: border-box;
}

.nc-err img,
.nc-ty img {
  height: 44px;
  margin-bottom: 40px;
}

/* One scale for both. They were clamp(26,4vw,40) and clamp(28,4.4vw,44), which
   made two sibling pages set their headline a step apart for no reason. */
.nc-err h1,
.nc-ty h1 {
  font-size: clamp(28px, 4.4vw, 44px);
  font-weight: 700;
  letter-spacing: -0.03em;
  margin: 0 0 16px;
  color: var(--nc-ink);
}

/* Margins differ on purpose: the 404 has a single paragraph then the links,
   the thank-you has a paragraph, a direct-contact row, then the links. */
.nc-err p,
.nc-ty p {
  font-size: 17px;
  line-height: 1.7;
  color: var(--nc-muted);
}

.nc-err p {
  margin: 0 0 34px;
  max-width: 520px;
}

.nc-ty p {
  margin: 0 0 12px;
  max-width: 540px;
}

.nc-err-code {
  font-size: clamp(64px, 14vw, 132px);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--nc-accent);
  margin: 0 0 12px;
}

.nc-ty-tick {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--nc-tint);
  color: var(--nc-accent);
  display: grid;
  place-items: center;
  font-size: 32px;
  margin-bottom: 28px;
}

.nc-ty-direct {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  justify-content: center;
  margin: 22px 0 34px;
  font-size: 17px;
  font-weight: 700;
}

.nc-ty-direct a {
  color: var(--nc-ink);
}

/* Same pill row on both pages, so one rule rather than two copies. */
.nc-err-links,
.nc-ty-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
}

.nc-err-links a,
.nc-ty-links a {
  padding: 14px 26px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  border: 1px solid var(--nc-line);
  color: var(--nc-ink);
}

.nc-err-links a.is-primary,
.nc-ty-links a.is-primary {
  background: var(--nc-accent);
  border-color: var(--nc-accent);
  color: var(--nc-white);
}

/* --------------------------------------------------------------------------
   Layout utilities
   -------------------------------------------------------------------------- */

.nc-row28 {
  display: flex;
  gap: 28px;
}

.nc-grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.nc-colflex {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.nc-stack14 {
  display: flex;
  flex-direction: column;
  gap: 14px;
  pointer-events: auto;
}

.nc-clip {
  overflow: hidden;
  padding-bottom: 6px;
}

.nc-pad {
  padding: 18px 26px;
}

.nc-mb10 {
  margin-bottom: 10px;
}

.nc-mb12 {
  margin-bottom: 12px;
}

/* --------------------------------------------------------------------------
   Colour utilities
   -------------------------------------------------------------------------- */

.nc-ink {
  color: var(--nc-ink);
}

.nc-muted {
  color: var(--nc-muted);
}

.nc-dim {
  color: var(--nc-dim);
}

.nc-faint {
  color: var(--nc-faint);
}

.nc-accent {
  color: var(--nc-accent);
}

.nc-accent-strong {
  color: var(--nc-accent);
  font-weight: 600;
}

/* ==========================================================================
   Layout classes lifted out of inline styles
   Each reproduces its element's desktop value exactly, so adding the class
   changes nothing on its own. They exist so the breakpoint rules below have
   something to override, because a @media rule cannot beat an inline style.
   ========================================================================== */

.nc-wrap {
  max-width: var(--nc-maxw);
  margin: 0 auto;
  padding-left: var(--nc-gutter);
  padding-right: var(--nc-gutter);
}

/* Fluid type. Each clamp maximum is the element's current desktop value, and
   the vw term is sized so the maximum is reached at the 1440px design width.
   Rendering at 1440 is therefore unchanged; scaling happens below it. */
.nc-h1 {
  font-size: clamp(30px, 4.4vw, 52px);
}

.nc-fs-34 {
  font-size: clamp(24px, 2.4vw, 34px);
}

.nc-fs-36 {
  font-size: clamp(24px, 2.6vw, 36px);
}

.nc-fs-38 {
  font-size: clamp(26px, 3.2vw, 38px);
}

.nc-fs-40 {
  font-size: clamp(24px, 2.8vw, 40px);
}

.nc-fs-42 {
  font-size: clamp(25px, 3.0vw, 42px);
}

.nc-fs-44 {
  font-size: clamp(25px, 3.1vw, 44px);
}

.nc-fs-46 {
  font-size: clamp(26px, 3.2vw, 46px);
}

.nc-fs-48 {
  font-size: clamp(26px, 3.4vw, 48px);
}

.nc-fs-50 {
  font-size: clamp(28px, 4.2vw, 50px);
}

.nc-fs-54 {
  font-size: clamp(28px, 3.8vw, 54px);
}

.nc-fs-56 {
  font-size: clamp(30px, 2.5vw, 56px);
}

.nc-fs-60 {
  font-size: clamp(30px, 4.2vw, 60px);
}

.nc-fs-62 {
  font-size: clamp(32px, 5.1vw, 62px);
}

.nc-fs-64 {
  font-size: clamp(30px, 4.5vw, 64px);
}

.nc-fs-68 {
  font-size: clamp(32px, 4.8vw, 68px);
}

.nc-fs-72 {
  font-size: clamp(32px, 5.1vw, 72px);
}

.nc-fs-74 {
  font-size: clamp(32px, 5.2vw, 74px);
}

/* Named for their exact desktop ratio, so a page always keeps the proportions
   it was designed with. Collapse behaviour is shared, see the breakpoints. */
.nc-g2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.nc-g2-135 {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
}

.nc-g2-115 {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
}

.nc-g2-115r {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
}

.nc-g3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.nc-g4 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.nc-g5 {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

.nc-g4m {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.nc-g3-table {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr;
}

/* two-column variants, named for their exact desktop ratio.
   The ladder is deliberately complete: -105, -110r and -auto have no user yet,
   and .nc-fs-64 above is likewise a spare rung. They stay because a gap in a
   scale is what makes the next person write the ratio inline instead. */
.nc-g2-105 {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
}

.nc-g2-110 {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
}

.nc-g2-120 {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
}

.nc-g2-105r {
  display: grid;
  grid-template-columns: 1fr 1.05fr;
}

.nc-g2-110r {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
}

.nc-g2-125r {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
}

.nc-g2-130r {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
}

.nc-g2-auto {
  display: grid;
  grid-template-columns: 1fr auto;
}

/* fixed-sidebar layouts. The 48px and 64px tracks are icon/number columns
   narrow enough to keep at every width; the wider ones stack. */
.nc-g2-48 {
  display: grid;
  grid-template-columns: 1fr 48px;
}

.nc-gside-64 {
  display: grid;
  grid-template-columns: 64px 1fr;
}

.nc-gside-200 {
  display: grid;
  grid-template-columns: 200px 1fr;
}

.nc-gside-260 {
  display: grid;
  grid-template-columns: 260px 1fr;
}

.nc-gside-260a {
  display: grid;
  grid-template-columns: 260px 1fr auto;
}

.nc-gside-340 {
  display: grid;
  grid-template-columns: 340px 1fr;
}

.nc-gap-40 {
  gap: clamp(20px, 2.8vw, 40px);
}

.nc-gap-44 {
  gap: clamp(20px, 3.1vw, 44px);
}

.nc-gap-48 {
  gap: clamp(40px, 3.4vw, 48px);
}

.nc-gap-lg {
  gap: clamp(24px, 4vw, 56px);
}

.nc-gap-62 {
  gap: clamp(48px, 4.4vw, 62px);
}

.nc-gap-64 {
  gap: clamp(40px, 4.6vw, 64px);
}

.nc-gap-72 {
  gap: clamp(24px, 5.1vw, 72px);
}

.nc-gap-80 {
  gap: clamp(24px, 5.6vw, 80px);
}

.nc-gap-96 {
  gap: clamp(24px, 6.7vw, 96px);
}

/* A horizontal band whose contents must stack on small screens. align-items is
   carried by one of the .nc-ai-* classes rather than inline, so a breakpoint
   can override it; left inline it would win and keep the row crushed. */
.nc-rowstack {
  /* marker only; see the breakpoints */
}

.nc-ai-center {
  align-items: center;
}

.nc-ai-start {
  align-items: flex-start;
}

.nc-ai-end {
  align-items: flex-end;
}

.nc-tablewrap {
  border-radius: 16px;
  overflow: hidden;
}

/* Sticky sidebar: stays static when stacked in single-column, sticky on desktop side-by-side grids. */
.nc-sticky-sidebar {
  position: static;
}

@media (min-width: 900px) {
  .nc-sticky-sidebar {
    position: sticky;
    top: 110px;
  }
}

/* FAQ accordion. Native <details>, so the answers are in the HTML and readable
   with no JavaScript. The shared name attribute makes the group exclusive
   (opening one closes the rest); browsers without it simply allow several open,
   which is a harmless fallback. */
.nc-faq {
  background: var(--nc-white);
  border: 1px solid var(--nc-line);
  border-radius: 12px;
  padding: 26px 30px;
}

.nc-faq>summary {
  display: block;
  cursor: pointer;
  list-style: none;
}

.nc-faq>summary::-webkit-details-marker {
  display: none;
}

/* the + / x mark itself is a Phosphor mask, see the icon section above */

/* Photo tile. Replaces the old <image-slot> custom element, reproducing its
   host box (block, relative, fills the parent, 3:2 only when the parent has no
   height of its own) so the surrounding layout is untouched. Plain markup, so
   the photo loads with no JavaScript and is visible to crawlers. */
.nc-photo {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.04);
}

.nc-photo>img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The .nc-credit attribution pill was removed from every page on request. The
   Unsplash licence does not require attribution, so nothing here depends on it.
   Deleted rather than left dead: if photo credits are ever wanted again, they
   should be reintroduced deliberately rather than found lying around. */

/* Same accordion in the hairline-row style used on the contact page. The
   summary keeps the .nc-g2-48 grid, so no display is set here. */
.nc-faqrow {
  border-bottom: 1px solid var(--nc-line);
}

.nc-faqrow>summary {
  cursor: pointer;
  list-style: none;
  padding: 26px 0;
}

.nc-faqrow>summary::-webkit-details-marker {
  display: none;
}

.nc-faqrow[open]>summary {
  padding-bottom: 0;
}

/* Inline product detail, styled to match the pill button it replaced. Was a
   JS modal, so the copy only existed in the DOM once opened; as <details> it
   ships in the HTML and is readable without JavaScript. */
.nc-detail>summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--nc-accent);
  color: var(--nc-white);
  padding: 13px 24px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.nc-detail>summary::-webkit-details-marker {
  display: none;
}

.nc-detail>summary:hover {
  background: var(--nc-accent-dk);
}

.nc-detail-icon::after {
  font-size: 15px;
  line-height: 1;
}

.nc-detail-body {
  padding-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 30px;
  max-width: 880px;
}

.nc-detail-body h3 {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 12px;
  color: var(--nc-ink);
}

.nc-detail-body p {
  font-size: 16px;
  line-height: 1.75;
  color: var(--nc-muted);
  margin: 0 0 14px;
  text-wrap: pretty;
}

.nc-detail-bullet {
  display: flex;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--nc-fill-lt);
}

.nc-detail-bullet>span {
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--nc-accent);
  margin-top: 9px;
}

.nc-detail-bullet>div {
  font-size: 16px;
  line-height: 1.65;
  color: var(--nc-muted);
  font-family: 'Host Grotesk', 'Archivo', sans-serif;
}

.nc-detail-bullet strong {
  color: var(--nc-ink);
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Accordion motion

   A <details> snaps open because the browser flips its content out of
   display:none, and there is nothing on that to transition. ::details-content
   is the box wrapped around that content, so it will take a height that can be
   animated instead.

   interpolate-size is what lets that height animate to auto. The usual
   max-height trick needs a guessed ceiling, which either clips the long
   answers or spends the tail of the animation travelling through empty space
   on the short ones; with auto every panel takes the same time whatever it
   holds. Browsers without it fall back to opening instantly, exactly as this
   did before, so nothing regresses.

   content-visibility has to transition too, with allow-discrete, or the
   content is dropped on the first frame of the close and the panel collapses
   behind an empty box.
   -------------------------------------------------------------------------- */

@supports (interpolate-size: allow-keywords) {
  :root {
    interpolate-size: allow-keywords;
  }
}

.nc-faq::details-content,
.nc-faqrow::details-content,
.nc-detail::details-content {
  block-size: 0;
  overflow: hidden;
  opacity: 0;
  transition: block-size 340ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 200ms ease-out,
    content-visibility 340ms allow-discrete;
}

/* Opening, the answer fades in a little behind the expansion so the text is
   not sliding and fading at the same time. Closing keeps the shorter fade
   above, which clears the text before the panel has finished collapsing. */
.nc-faq[open]::details-content,
.nc-faqrow[open]::details-content,
.nc-detail[open]::details-content {
  block-size: auto;
  opacity: 1;
  transition: block-size 340ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 260ms ease-in 120ms,
    content-visibility 340ms allow-discrete;
}

.nc-faq-icon::after,
.nc-detail-icon::after,
.nc-faqrow-sign::before {
  transition: transform 340ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 200ms ease-out;
}

@media (prefers-reduced-motion: reduce) {

  .nc-faq::details-content,
  .nc-faqrow::details-content,
  .nc-detail::details-content,
  .nc-faq[open]::details-content,
  .nc-faqrow[open]::details-content,
  .nc-detail[open]::details-content,
  .nc-faq-icon::after,
  .nc-detail-icon::after,
  .nc-faqrow-sign::before {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   Hover / focus utilities
   These replace the style-hover="..." and style-focus="..." attributes the
   Design Composer runtime used to compile into .scpNN:hover rules at load
   time. Only 14 distinct declarations were ever used across the site, so they
   live here as classes and no longer need JavaScript.

   !important is deliberate and matches the old behaviour: nearly every element
   carrying one of these also carries an inline style setting the same property,
   and an inline declaration outranks any selector without it.
   -------------------------------------------------------------------------- */

.nc-hv-red:hover {
  color: var(--nc-accent) !important;
}

.nc-hv-deep:hover {
  color: var(--nc-accent-dk) !important;
}

.nc-hv-ink:hover {
  color: var(--nc-ink) !important;
}

.nc-hv-white:hover {
  color: var(--nc-white) !important;
}

.nc-hv-redline:hover {
  border-color: var(--nc-accent) !important;
  color: var(--nc-accent) !important;
}

.nc-hv-cardred:hover {
  border-color: var(--nc-accent) !important;
  color: var(--nc-white) !important;
}

.nc-hv-inkred:hover {
  border-color: var(--nc-accent) !important;
  color: var(--nc-ink) !important;
}

.nc-hv-btn:hover {
  background: var(--nc-accent-dk) !important;
  color: var(--nc-white) !important;
}

.nc-hv-fillred:hover {
  background: var(--nc-accent) !important;
  color: var(--nc-white) !important;
}

.nc-hv-glass:hover {
  background: rgba(255, 255, 255, 0.20) !important;
  color: var(--nc-white) !important;
}

.nc-hv-bgdeep:hover {
  background: var(--nc-accent-dk) !important;
}

.nc-hv-bgslate:hover {
  background: var(--nc-slate-hv) !important;
}

.nc-hv-bggrey:hover {
  background: var(--nc-surface-hv) !important;
}

.nc-fc-red:focus {
  border-color: var(--nc-accent) !important;
}

/* --------------------------------------------------------------------------
   Product carousel  (solar-solutions, nano-tech-solutions)
   Horizontal scroll track with prev/next buttons. The track itself scrolls
   with no JavaScript at all; nc.js only adds the buttons' smooth step and
   drag-to-scroll. Without it the track is still scrollable by wheel, trackpad
   and touch, so the content is never trapped.
   -------------------------------------------------------------------------- */

.nc-carousel {
  position: relative;
}

/* No scroll-behavior here on purpose: the buttons ask for smooth scrolling
   themselves, so dragging stays 1:1 with the pointer. */
.nc-track {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  cursor: grab;
}

.nc-track::-webkit-scrollbar {
  display: none;
}

.nc-track>* {
  scroll-snap-align: start;
}

.nc-track.nc-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
}

.nc-fade {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 75px;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(250, 250, 251, 0) 0%, rgba(250, 250, 251, 0.72) 70%, var(--nc-surface-lt) 100%);
}

.nc-carobtn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 54px;
  height: 54px;
  border-radius: 999px;
  border: 1px solid var(--nc-line);
  background: var(--nc-white);
  color: var(--nc-ink);
  font-size: 18px;
  cursor: pointer;
  box-shadow: 0 10px 26px rgba(20, 22, 25, 0.14);
}

.nc-carobtn-next {
  right: 18px;
}

.nc-carobtn-prev {
  left: 18px;
}

/* The prev button starts hidden because the track starts at the left edge.
   nc.js clears this the moment the track scrolls; with no JavaScript the
   button simply never appears, which is honest rather than broken. */
.nc-carobtn-prev {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.nc-carousel.nc-scrolled .nc-carobtn-prev {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Product cards inside a carousel. The card count and the card's aspect are
   the same decision: four square cards read fine at 1440, but the same square
   at phone width is barely 120px across and the title and blurb collide. So
   the count drops and the card gets taller as the viewport narrows. The 2.5
   at the bottom is deliberate, a half-visible third card is what tells a
   thumb the row scrolls. */
.nc-procard {
  position: relative;
  flex: 0 0 calc((100% - 48px) / 4);
  aspect-ratio: 1 / 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-radius: 18px;
  overflow: hidden;
  background: var(--nc-fill);
  color: var(--nc-white);
  border: 1px solid var(--nc-line);
}

.nc-procard-top {
  position: relative;
  padding: 22px 20px 0;
  pointer-events: none;
}

.nc-procard-bot {
  position: relative;
  padding: 0 20px 20px;
  pointer-events: none;
}

.nc-procard-eyebrow {
  font-family: 'Host Grotesk', 'Archivo', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.82);
  margin-bottom: 8px;
}

.nc-procard-title {
  font-size: 21px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-wrap: pretty;
  /* the card clips its overflow, so a word wider than the card would be cut
     mid-letter rather than wrapped. "Applicator" does this at 320px. */
  overflow-wrap: break-word;
}

.nc-procard-desc {
  font-size: 14px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.86);
  margin: 0;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   "Open" hover cursor. nc.js positions the dot and toggles .nc-cursor-on;
   everything about how it looks is here.
   -------------------------------------------------------------------------- */

/* Two elements on purpose: the outer one is moved by script every frame, so it
   must not carry a transition, while the inner one animates in and out. */
.nc-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2147483000;
  width: 0;
  height: 0;
  pointer-events: none;
}

.nc-cursor>span {
  position: absolute;
  left: -36px;
  top: -36px;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(20, 22, 25, 0.72);
  color: var(--nc-white);
  font: 600 13px/1 var(--nc-font);
  letter-spacing: 0.02em;
  backdrop-filter: blur(6px);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 140ms ease, transform 140ms ease;
}

.nc-cursor.nc-cursor-on>span {
  opacity: 1;
  transform: scale(1);
}

/* Only hide the real pointer once nc.js has actually drawn the replacement.
   The class comes from the script, so a blocked or failed nc.js leaves the
   normal cursor alone instead of making it invisible. */
.nc-cursor-ready [data-open-cursor]:hover {
  cursor: none;
}

/* Mobile nav controls. Fully inert on desktop: display:none keeps the five
   toggles out of the tab order, so keyboard users never hit phantom controls
   on a viewport where the drawer does not exist. */
.nc-navtoggle,
.nc-sectoggle,
.nc-subtoggle,
.nc-burger,
.nc-navscrim,
.nc-secbtn,
.nc-subbtn,
.nc-drawerlogo {
  display: none;
}

/* ==========================================================================
   Responsive behaviour, scoped to .nc-rwd
   Only pages carrying .nc-rwd on their root div are affected. Every other
   page renders exactly as it did before.
   Breakpoints: 1200 / 900 / 600
   ========================================================================== */

/* Fluid type. Each clamp maximum is the current desktop value, so rendering at
   the 1440px design width is unchanged; scaling starts as the viewport narrows. */
.nc-rwd .nc-bignum {
  font-size: clamp(44px, 9vw, 108px);
}

.nc-rwd .nc-h2-light {
  font-size: clamp(26px, 3.4vw, 42px);
}

/* ---------------------------- 1200 to 1339 ----------------------------- */
@media (min-width: 1200px) and (max-width: 1339px) {

  /* The narrowest band where the full desktop nav is still on show. Seven
     items at a 32px gap spend 192px on gap alone, which at 1200 pushed the
     Contact Us button on top of About Us and wrapped its label to two lines.
     18px hands back 84px, which clears it with room to spare. Below 1200 the
     burger takes over, so this is the only band that needs it. */
  .nc-rwd .nc-navlinks {
    gap: 18px;
  }
}

/* ------------------------------- < 1200 -------------------------------- */
@media (max-width: 1199px) {
  .nc-screen.nc-rwd {
    min-width: 0;
  }

  .nc-rwd {
    --nc-gutter: 32px;
  }

  /* shared containers follow the shrinking gutter */
  .nc-rwd .nc-section,
  .nc-rwd .nc-head,
  .nc-rwd .nc-bar-a,
  .nc-rwd .nc-bar-b,
  .nc-rwd .nc-bar-c,
  .nc-rwd .nc-bar-d {
    padding-left: var(--nc-gutter);
    padding-right: var(--nc-gutter);
  }

  .nc-rwd .nc-g4 {
    grid-template-columns: repeat(2, 1fr);
  }

  .nc-rwd .nc-g5 {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Keep grid items inside their track. A child with aspect-ratio under
     align-items:center resolves its width from its own height rather than
     stretching, which pushed the product hero image 135px past its column.
     min-width:0 also lets tracks shrink below their content's min-content. */
  .nc-rwd .nc-g2>*,
  .nc-rwd .nc-g2-135>*,
  .nc-rwd .nc-g2-115>*,
  .nc-rwd .nc-g2-115r>*,
  .nc-rwd .nc-g2-105>*,
  .nc-rwd .nc-g2-110>*,
  .nc-rwd .nc-g2-120>*,
  .nc-rwd .nc-g2-105r>*,
  .nc-rwd .nc-g2-110r>*,
  .nc-rwd .nc-g2-125r>*,
  .nc-rwd .nc-g2-130r>*,
  .nc-rwd .nc-g2-auto>*,
  .nc-rwd .nc-g2-48>*,
  .nc-rwd .nc-g3>*,
  .nc-rwd .nc-g4>*,
  .nc-rwd .nc-g4m>*,
  .nc-rwd .nc-g5>*,
  .nc-rwd .nc-gside-64>*,
  .nc-rwd .nc-gside-200>*,
  .nc-rwd .nc-gside-260>*,
  .nc-rwd .nc-gside-260a>*,
  .nc-rwd .nc-gside-340>*,
  .nc-rwd .nc-grid2>* {
    min-width: 0;
    max-width: 100%;
  }

  .nc-rwd .nc-g4m {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* four footer columns are too tight on a tablet, pair them up instead */
  .nc-rwd .nc-footgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 48px;
  }

  /* The video tiles rely on an inline grid-template-rows of two tracks, which
     only works at four columns. At two the featured 2x2 tile fills both rows
     on its own and the other four spill onto implicit auto rows that collapse
     to nothing, so every row needs an explicit height from here down. */
  .nc-rwd .nc-tiles {
    grid-template-rows: none !important;
    grid-auto-rows: 220px;
  }

  /* The 5-item facts strip draws its hairline dividers as a grey container
     background showing through a 1px gap, so any unfilled cell renders as an
     empty grey box. Five items divide evenly into neither 3 nor 2 columns, so
     a filler cell squares off the last row. Removed again at 1 column. */
  .nc-rwd .nc-g5::after {
    content: "";
    background: var(--nc-white);
  }

  /* Breadcrumb flows as text rather than as flex items. As a flex row the final
     crumb is one unbreakable box, so it drops to its own line and strands the
     space after "Field Testing /". Inline flow lets it fill that space and wrap
     mid-phrase like a paragraph, while the links themselves stay unbroken. */
  .nc-rwd .nc-breadcrumb {
    display: block;
    line-height: 1.55;
  }

  .nc-rwd .nc-breadcrumb>a,
  .nc-rwd .nc-breadcrumb>span.nc-faint {
    white-space: nowrap;
  }

  .nc-rwd .nc-breadcrumb>span.nc-faint {
    margin: 0 3px;
  }

  /* --- nav turns into a drawer --- */
  /* Toggles become visually hidden but still focusable, so the drawer can be
     operated from the keyboard. The visible +/- and hamburger glyphs are
     decorative labels; the checkbox carries the accessible name. */
  .nc-rwd .nc-navtoggle,
  .nc-rwd .nc-sectoggle {
    display: block;
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .nc-rwd .nc-navtoggle:focus-visible~.nc-burger,
  .nc-rwd .nc-sectoggle:focus-visible~.nc-secbtn {
    outline: 2px solid var(--nc-accent);
    outline-offset: 2px;
  }

  /* logo takes the free space so the CTA and burger pair up on the right,
     instead of space-between stranding the CTA in the middle */
  .nc-rwd .nc-nav .nc-bar {
    gap: 12px;
  }

  .nc-rwd .nc-nav .nc-logolink {
    margin-right: auto;
  }

  .nc-rwd .nc-nav .nc-btn {
    order: 2;
  }

  .nc-rwd .nc-burger {
    display: flex;
    order: 3;
    position: relative;
    z-index: 210;
    /* stays tappable above the open drawer, to close it */
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 36px;
    height: 36px;
    padding: 0 6px;
    box-sizing: border-box;
    border-radius: 8px;
    cursor: pointer;
    flex-shrink: 0;
  }

  .nc-rwd .nc-burger span {
    display: block;
    height: 2px;
    border-radius: 2px;
    background: var(--nc-ink);
    transition: transform 0.22s ease, opacity 0.22s ease;
  }

  .nc-rwd .nc-navtoggle:checked~.nc-burger span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }

  .nc-rwd .nc-navtoggle:checked~.nc-burger span:nth-child(2) {
    opacity: 0;
  }

  .nc-rwd .nc-navtoggle:checked~.nc-burger span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }

  .nc-rwd .nc-navscrim {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(26, 26, 26, 0.44);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease, visibility 0.25s;
    z-index: 190;
  }

  .nc-rwd .nc-navtoggle:checked~.nc-navscrim {
    opacity: 1;
    visibility: visible;
  }

  .nc-rwd .nc-navlinks {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(86vw, 340px);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--nc-white);
    border-left: 1px solid var(--nc-line);
    box-shadow: -22px 0 60px rgba(26, 26, 26, 0.18);
    /* top padding puts the drawer logo row on the same centre line as the
       close button (burger spans 64-108px here, 88-132px below 600) */
    padding: 64px 20px 32px;
    overflow-y: auto;
    transform: translateX(102%);
    /* visibility, not just transform: an off-screen drawer would otherwise keep
       all 22 links in the tab order and the accessibility tree */
    visibility: hidden;
    transition: transform 0.26s ease, visibility 0.26s;
    z-index: 200;
  }

  .nc-rwd .nc-navtoggle:checked~.nc-navlinks {
    transform: translateX(0);
    visibility: visible;
  }

  /* logo inside the drawer, sharing the close button's centre line */
  .nc-rwd .nc-drawerlogo {
    display: flex;
    align-items: center;
    height: 44px;
    margin-bottom: 20px;
    flex-shrink: 0;
  }

  .nc-rwd .nc-drawerlogo img {
    height: 38px;
    width: auto;
    display: block;
  }

  .nc-rwd .nc-navitem {
    display: block;
    position: relative;
    border-bottom: 1px solid var(--nc-line);
  }

  .nc-rwd .nc-navlink {
    display: block;
    padding: 15px 46px 15px 2px;
    font-size: 17px;
  }

  .nc-rwd .nc-caret {
    display: none;
  }

  .nc-rwd .nc-secbtn {
    display: grid;
    place-items: center;
    position: absolute;
    top: 3px;
    right: 0;
    width: 44px;
    height: 46px;
    cursor: pointer;
  }

  .nc-rwd .nc-secbtn::before {
    content: "+";
    font-size: 21px;
    color: var(--nc-muted);
  }

  .nc-rwd .nc-sectoggle:checked~.nc-secbtn::before {
    content: "\2013";
  }

  /* dropdown becomes an accordion panel, gated on display so the desktop
     hover rules (which only touch opacity/visibility) cannot reopen it */
  .nc-rwd .nc-dropdown {
    position: static;
    display: none;
    opacity: 1;
    /* inherit, not visible: an expanded section must still be hidden when the
       drawer itself is closed, or its links stay tabbable off-screen */
    visibility: inherit;
    transform: none;
    min-width: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0 0 12px 12px;
    transition: none;
  }

  .nc-rwd .nc-dropdown::before {
    display: none;
  }

  .nc-rwd .nc-sectoggle:checked~.nc-dropdown {
    display: flex;
  }

  .nc-rwd .nc-dropitem {
    padding: 9px 10px;
  }

  /* second-level accordion, nested inside the drawer panel above */
  .nc-rwd .nc-subitem,
  .nc-rwd .nc-dropdown>.nc-dropitem {
    display: block;
    position: relative;
    border-top: 1px solid var(--nc-line);
  }

  .nc-rwd .nc-subitem:first-child,
  .nc-rwd .nc-dropdown>.nc-dropitem:first-child {
    border-top: 0;
  }

  .nc-rwd .nc-subitem>.nc-dropitem {
    padding-right: 40px;
  }

  .nc-rwd .nc-subcaret {
    display: none;
  }

  .nc-rwd .nc-subtoggle {
    display: block;
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .nc-rwd .nc-subtoggle:focus-visible~.nc-subbtn {
    outline: 2px solid var(--nc-accent);
    outline-offset: 2px;
  }

  .nc-rwd .nc-subbtn {
    display: grid;
    place-items: center;
    position: absolute;
    top: 0;
    right: 0;
    width: 36px;
    height: 36px;
    cursor: pointer;
  }

  .nc-rwd .nc-subbtn::before {
    content: "+";
    font-size: 18px;
    color: var(--nc-muted);
  }

  .nc-rwd .nc-subtoggle:checked~.nc-subbtn::before {
    content: "\2013";
  }

  .nc-rwd .nc-subdrop {
    position: static;
    display: none;
    opacity: 1;
    visibility: inherit;
    transform: none;
    min-width: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0 0 8px 12px;
    transition: none;
  }

  .nc-rwd .nc-subdrop::before {
    display: none;
  }

  .nc-rwd .nc-subtoggle:checked~.nc-subdrop {
    display: flex;
  }
}

/* -------------------------------- < 900 -------------------------------- */
@media (max-width: 899px) {

  .nc-rwd .nc-g2,
  .nc-rwd .nc-g2-135,
  .nc-rwd .nc-g2-115,
  .nc-rwd .nc-g2-115r,
  .nc-rwd .nc-g2-105,
  .nc-rwd .nc-g2-110,
  .nc-rwd .nc-g2-120,
  .nc-rwd .nc-g2-105r,
  .nc-rwd .nc-g2-110r,
  .nc-rwd .nc-g2-125r,
  .nc-rwd .nc-g2-130r,
  .nc-rwd .nc-g2-auto,
  .nc-rwd .nc-gside-200,
  .nc-rwd .nc-gside-260,
  .nc-rwd .nc-gside-260a,
  .nc-rwd .nc-gside-340,
  .nc-rwd .nc-footgrid {
    grid-template-columns: 1fr;
  }

  /* Stacked, the hero copy column is the full viewport rather than half of it,
     so (100% - 720px) would grow into a huge left indent. Back to the gutter. */
  .nc-rwd .nc-herocol {
    padding-left: var(--nc-gutter);
  }

  /* This grid's columns come from a {{ s.cols }} binding, so the runtime
     writes them into the style attribute and only !important can collapse it. */
  .nc-rwd .nc-gbound {
    grid-template-columns: 1fr !important;
  }

  /* Alternating text/image bands. The inline order values drive the zig-zag
     across two columns, but stacked they make the order flip band to band:
     text, image, image, text. Pinning the picture first gives every band the
     same shape going down the page. Inline order needs !important to lose. */
  .nc-rwd .nc-segmedia {
    order: -1 !important;
  }

  .nc-rwd .nc-g5 {
    grid-template-columns: repeat(2, 1fr);
  }

  .nc-rwd .nc-g3 {
    grid-template-columns: repeat(2, 1fr);
  }

  .nc-rwd .nc-footgrid {
    gap: 40px;
    padding-bottom: 48px;
  }

  .nc-rwd .nc-media {
    height: 380px;
  }

  .nc-rwd .nc-overlay {
    left: 24px;
    right: 24px;
    bottom: 24px;
  }

  /* three across, and slightly taller than square to keep the blurb legible */
  .nc-rwd .nc-procard {
    flex-basis: calc((100% - 32px) / 3);
    aspect-ratio: 5 / 6;
  }

  /* Below this the arrows sit on top of a card rather than beside it, and
     everything this size is touch anyway, so the track is swiped. */
  .nc-rwd .nc-carobtn {
    display: none;
  }

  .nc-rwd .nc-fade {
    width: 40px;
  }

  /* Sticky sidebar items must revert to position: static when grid columns stack into a single column */
  .nc-rwd [style*="position: sticky"]:not(.nc-nav),
  .nc-rwd [style*="position:sticky"]:not(.nc-nav),
  .nc-rwd .nc-sticky-sidebar {
    position: static !important;
  }
}

.nc-hero-card {
  padding: 48px 48px 0;
}

/* -------------------------------- < 600 -------------------------------- */
@media (max-width: 599px) {
  .nc-rwd .nc-hero-card {
    padding: 48px 36px 0;
  }

  .nc-rwd {
    --nc-gutter: 20px;
  }

  .nc-rwd .nc-g3,
  .nc-rwd .nc-g4,
  .nc-rwd .nc-g4m,
  .nc-rwd .nc-g5,
  .nc-rwd .nc-grid2 {
    grid-template-columns: 1fr;
  }

  /* single column divides evenly, so the filler cell would be a blank row */
  .nc-rwd .nc-g5::after {
    display: none;
  }

  /* Some tiles carry their placement inline or from a {{ }} binding, e.g.
     "grid-column: span 2". Once the grid is one column wide that span
     invents a second, near-zero implicit column and the tile spills out of
     it, so the placement has to be reset with enough weight to beat the
     inline value. */
  .nc-rwd .nc-g3>*,
  .nc-rwd .nc-g4>*,
  .nc-rwd .nc-g4m>*,
  .nc-rwd .nc-g5>* {
    grid-column: auto !important;
    grid-row: auto !important;
  }

  /* The video tiles take their height from an inline grid-template-rows of
     exactly two tracks. In one column there are five rows, so the last three
     would fall back to auto and collapse; give every row the same height. */
  .nc-rwd .nc-tiles {
    grid-template-rows: none !important;
    grid-auto-rows: 200px;
  }

  /* comparison table keeps all three columns and scrolls sideways */
  .nc-rwd .nc-tablewrap {
    overflow-x: auto;
  }

  .nc-rwd .nc-g3-table {
    min-width: 520px;
  }

  /* 2.5 cards: two whole ones plus a peek, which is the affordance that says
     "swipe". min-height is the real guard, aspect-ratio alone still collapses
     on a 320px screen once the gutters come off. */
  .nc-rwd .nc-procard {
    flex-basis: calc((100% - 32px) / 2.5);
    aspect-ratio: 3 / 4;
    min-height: 200px;
  }

  .nc-rwd .nc-procard-top {
    padding: 16px 14px 0;
  }

  .nc-rwd .nc-procard-bot {
    padding: 0 14px 16px;
  }

  .nc-rwd .nc-procard-eyebrow {
    font-size: 10px;
    margin-bottom: 5px;
  }

  .nc-rwd .nc-procard-title {
    font-size: 15px;
    line-height: 1.2;
  }

  /* Show description on mobile, adjusted font size for small cards */
  .nc-rwd .nc-procard-desc {
    display: block;
    font-size: 12px;
    line-height: 1.4;
    margin-top: 4px;
  }

  /* stack the chrome rows */
  .nc-rwd .nc-utilbar .nc-bar,
  .nc-rwd .nc-footbar {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .nc-rwd .nc-utilbar {
    font-size: 12px;
  }

  /* Phone, email and address cannot share one line on a phone: at 360px the
     three run about 410px of text before any icon or gap. Two rows is the
     floor, so make the two rows deliberate instead of a ragged wrap.

     Row one holds the pair and justifies them to the two gutters, which means
     the gap is whatever is left over rather than a fixed value that can push
     the email onto a third line. Row two carries the address on its own. All
     three stay visible, and all three are tap targets. */
  /* The row gap is 0 and the separation comes from each link's own padding
     instead, so the space between the rows doubles as touch area rather than
     being dead pixels. Trimming the bar's vertical padding to match pays for
     most of the height the taller tap targets cost. */
  .nc-rwd .nc-utilbar .nc-bar {
    align-items: stretch;
    gap: 0;
    flex-direction: row;
    justify-content: space-between;
  }

  .nc-rwd .nc-utilbar .nc-bar-a,
  .nc-rwd .nc-utilbar .nc-bar-d {
    padding-top: 6px;
    padding-bottom: 6px;
  }

  .nc-rwd .nc-utilbar .nc-row28 {
    width: 50%;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 0;
  }

  .nc-rwd .nc-utilbar .nc-row28:last-child {
    align-items: flex-end;
    text-align: right;
  }

  /* Each entry carries its own vertical padding, giving a ~34px touch target
     against a 12px label. Not the full 44px, which two stacked rows cannot
     afford here, but a large improvement on text that was not tappable at all. */
  .nc-rwd .nc-utillink {
    padding: 8px 0;
  }

  /* The email is the one entry that cannot shrink gracefully, so let it clip
     with an ellipsis at the narrowest sizes rather than force a third row. */
  .nc-rwd .nc-utilbar .nc-row28 .nc-utillink-mail {
    min-width: 0;
  }

  .nc-rwd .nc-utilbar .nc-row28 .nc-utillink-mail>span {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* stacked utility bar makes the header taller, so the drawer logo moves down
     to stay level with the close button */
  .nc-rwd .nc-navlinks {
    padding-top: 88px;
  }

  /* text + nowrap button bands stack rather than squeezing the copy to
     one or two words per line */
  .nc-rwd .nc-rowstack {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }

  /* ...but not the FAQ summary. There the second item is the +/x mark, not a
     button, and stacking drops it onto its own line under the question, which
     reads as a stray icon rather than as the control that opens the panel. It
     is 22px wide and never needs the room, so it stays on the question's line
     and keeps the tap target where the eye expects it. */
  .nc-rwd .nc-faq>summary .nc-rowstack {
    flex-direction: row;
    align-items: center;
    gap: 16px;
  }

  .nc-rwd .nc-logo {
    height: 26px;
  }

  .nc-rwd .nc-nav .nc-btn {
    padding: 8px 12px;
    font-size: 13px;
    white-space: nowrap;
  }

  .nc-rwd .nc-section {
    padding-top: 56px;
    padding-bottom: 56px;
  }

  .nc-rwd .nc-media {
    height: 300px;
  }
}

/* -------------------------------- < 380 -------------------------------- */
@media (max-width: 379px) {

  /* a 2.5-up card is ~99px wide here, leaving ~71px of text. "Applicator" and
     "APPLICATORS" both exceed that, so the type drops one more step and long
     words break on a hyphen rather than mid-syllable. */
  .nc-rwd .nc-procard-title {
    font-size: 13px;
    hyphens: auto;
  }

  .nc-rwd .nc-procard-eyebrow {
    font-size: 9px;
    letter-spacing: 0.04em;
  }

  /* One step down keeps the number and the full email side by side at 320,
     where the gutter leaves only 280px. The icons follow, being sized in em. */
  .nc-rwd .nc-utilbar {
    font-size: 11px;
  }
}

/* lenis smooth scroll */
html.lenis,
html.lenis body {
  height: auto;
  width: 100vw;
  overflow-x: hidden;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}