/* ==========================================================================
   REXZEE SPORTS - core stylesheet
   Design read : custom sportswear manufacturer, Sialkot. Gen-Z athletic
                 poster language. Dual theme (dark default + light), locked
                 tokens, one accent (volt), one radius system.
   Dials       : variance 8 / motion 8 / density 4
   Surfaces    : the page alternates black and white blocks on purpose.
                 Add .inv to a section and it flips to the opposite family
                 in whichever theme the visitor has chosen.
   Radius rule : interactive = pill, panels = 22px, inputs = 14px
   ========================================================================== */

/* ---------- 1. TOKENS ---------------------------------------------------- */

/* The page deliberately alternates black and white blocks. A section marked
   .inv flips to the opposite surface family, whichever theme is active:
       dark theme  -> .inv blocks turn paper white
       light theme -> .inv blocks turn near black
   Two palettes, four selectors, nothing else needed. Volt stays volt in
   both, and every ink value below clears WCAG AA on its own background. */

:root,
[data-theme='light'] .inv {
  /* ============ DARK PALETTE ============ */
  --volt: #d6ff3d;
  --volt-deep: #b4e015;
  --volt-ink: #d6ff3d;
  --on-volt: #0a0b0e;
  --c-sport: #ff9f2e;
  --c-team: #5b83ff;
  --c-combat: #ff4230;
  --c-fit: #d6ff3d;
  --c-moto: #b07cff;
  --c-bags: #33d6c0;
  /* accessories: magenta, the last hue the other six lines leave open.
     Sits clear of the bags teal beside it in the nav and on the bento. */
  --c-acc: #ff5fa8;
  /* workwear: a steel blue, the one hue the other five lines leave free.
     Deliberately not the amber a safety range would use - this line carries
     no hi-vis and the colour should not suggest one. */
  --c-work: #4aa8f0;
  --bg: #0a0b0e;
  --bg-2: #0f1116;
  --bg-3: #14171e;
  --surface: #14171e;
  --surface-2: #1a1e26;
  --ink: #f3f5f7;
  --ink-2: #a5adb8;
  --ink-3: #8b939e;
  --line: rgba(255, 255, 255, 0.11);
  --line-strong: rgba(255, 255, 255, 0.2);
  --line-faint: rgba(255, 255, 255, 0.045);
  --shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
  --shadow-sm: 0 8px 24px rgba(0, 0, 0, 0.4);
  --scrim: rgba(6, 7, 9, 0.72);
  --wash-a: rgba(214, 255, 61, 0.11);
  --wash-b: rgba(59, 107, 255, 0.13);
  --wash-c: rgba(255, 66, 48, 0.08);
  --glow: 55%;
  --glow-soft: 30%;
}

[data-theme='light'],
.inv {
  /* ============ LIGHT PALETTE ============ */
  --volt: #d6ff3d;
  --volt-deep: #b4e015;
  --volt-ink: #4f6e00;
  --on-volt: #0a0b0e;
  --c-sport: #a3560a;
  --c-team: #2f52d8;
  --c-combat: #c62817;
  --c-fit: #556e00;
  --c-moto: #6b30c4;
  --c-bags: #006b5e;
  --c-acc: #a81257;
  --c-work: #0b5c93;
  --bg: #f3f2ed;
  --bg-2: #ffffff;
  --bg-3: #eceae2;
  --surface: #ffffff;
  --surface-2: #f7f6f1;
  --ink: #0a0b0e;
  --ink-2: #565d67;
  --ink-3: #5f6670;
  --line: rgba(10, 11, 14, 0.13);
  --line-strong: rgba(10, 11, 14, 0.28);
  --line-faint: rgba(10, 11, 14, 0.06);
  --shadow: 0 24px 60px rgba(24, 26, 33, 0.13);
  --shadow-sm: 0 8px 22px rgba(24, 26, 33, 0.09);
  --scrim: rgba(243, 242, 237, 0.78);
  --wash-a: rgba(180, 224, 21, 0.2);
  --wash-b: rgba(59, 107, 255, 0.11);
  --wash-c: rgba(255, 66, 48, 0.07);
  --glow: 16%;
  --glow-soft: 10%;
}

:root {
  --grain-opacity: 0.05;
  color-scheme: dark;
}
[data-theme='light'] {
  --grain-opacity: 0.035;
  color-scheme: light;
}

/* the inverted block paints itself and everything inside follows the tokens */
.inv {
  background: var(--bg);
  color: var(--ink);
}
.inv.alt {
  background: var(--bg-2);
}

:root {
  /* type
     Archivo for display: an industrial grotesk that reads as engineering
     rather than editorial, which is the register a manufacturer wants in
     front of a buyer. Inter for body because it holds up at the small sizes
     spec tables and product copy actually run at. */
  --f-display: 'Archivo', 'Barlow Condensed', system-ui, sans-serif;
  --f-cond: 'Barlow Condensed', 'Arial Narrow', system-ui, sans-serif;
  --f-body: 'Inter', system-ui, -apple-system, sans-serif;
  --f-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* spacing scale (density 4) */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;
  --s-9: 96px;
  --s-10: 128px;

  --pad-x: clamp(20px, 5vw, 64px);
  --wrap: 1360px;
  --sec-y: clamp(64px, 9vw, 128px);

  /* shape - one system, applied everywhere:
     interactive (buttons, chips, avatars, icon buttons) = pill
     panels, cards, posters, media                       = --r-panel
     inputs and inner elements                           = --r-input */
  --r-panel: 22px;
  --r-input: 14px;
  --r-pill: 999px;

  /* motion */
  --e-out: cubic-bezier(0.16, 1, 0.3, 1);
  --e-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast: 0.18s var(--e-out);
  --t-mid: 0.32s var(--e-out);
  --t-slow: 0.6s var(--e-out);

  /* layers */
  --z-base: 1;
  --z-sticky: 40;
  --z-nav: 60;
  --z-drawer: 70;
  --z-grain: 80;
  --z-loader: 100;
}

/* ---------- 2. RESET ----------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}
* {
  margin: 0;
  padding: 0;
}
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
/* Lenis owns the scroll when it loads, so the native smoothing steps aside */
html.lenis,
html.lenis body {
  height: auto;
}
html.lenis-on {
  scroll-behavior: auto;
}
.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}
.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}
.lenis.lenis-stopped {
  overflow: hidden;
}
/* scroll lock for the drawer and the preloader. It has to sit on the root
   element: <html> is what scrolls, so overflow:hidden on body does nothing.
   The stable gutter keeps the page from jumping sideways as it engages. */
html {
  scrollbar-gutter: stable;
}
html.rx-locked,
html.rx-locked body {
  overflow: hidden;
  touch-action: none;
}
/* Lenis makes body a scroll container (overflow-y: auto), and a body that
   scrolls on one axis no longer propagates its overflow to the viewport. That
   quietly disabled the overflow-x: hidden below and let full bleed decoration
   drag a real horizontal scrollbar onto the page.

   overflow-x: clip on the root does the job instead: it clips without creating
   a scroll container, so sticky headers, Lenis and the scroll timeline all
   keep working.

   THE overflow-x: hidden THIS REPLACED WAS LEFT BEHIND ON body, and it was
   still doing the damage the note above describes. overflow-x: hidden cannot
   stand alone: the spec forces the other axis from visible to auto, so body
   computed to "hidden auto" and became a scroll container. position: sticky
   sticks to its nearest scrolling ancestor, so the header - declared
   sticky, top 0, z-index 60 - was sticking to a box that never scrolls while
   the viewport scrolled past it. Measured at scroll 900 the header sat at
   -859: it left the screen and stayed gone for all 9,500px of the homepage.

   Simply deleting it was not the answer either: the root's clip did not catch
   everything on its own and about 100px of horizontal scroll came back. body
   does need to contain the axis - it just must not become scrollable doing it.

   clip is the difference. hidden means "scrollable but without scrollbars", so
   it makes a scroll container; clip means "cut it off, no scrolling", so it
   does not, and the other axis is left visible instead of being forced to
   auto. Same containment, no scroll container, sticky intact. */
html {
  overflow-x: clip;
}
body {
  font-family: var(--f-body);
  font-size: 16.5px;
  line-height: 1.66;
  letter-spacing: -0.006em;
  color: var(--ink);
  background: var(--bg);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* lining tabular figures so MOQ, gsm and lead times line up in a column */
  font-variant-numeric: tabular-nums lining-nums;
  transition: background-color 0.45s var(--e-out), color 0.45s var(--e-out);
}
img,
svg,
video {
  display: block;
  max-width: 100%;
}
img {
  height: auto;
}
a {
  color: inherit;
  text-decoration: none;
}
button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}
button {
  background: none;
  border: 0;
  cursor: pointer;
}
ul,
ol {
  list-style: none;
}
::selection {
  background: var(--volt);
  color: var(--on-volt);
}
:focus-visible {
  outline: 3px solid var(--volt);
  outline-offset: 3px;
  border-radius: 8px;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.skip-link {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 200;
  background: var(--volt);
  color: var(--on-volt);
  padding: 12px 20px;
  border-radius: var(--r-pill);
  font-family: var(--f-cond);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: top var(--t-mid);
}
.skip-link:focus {
  top: 12px;
}

/* ---------- 3. TYPOGRAPHY ------------------------------------------------ */

/* Archivo carries more x-height than the old face, so the tracking opens up
   and the leading comes off the floor. Display type that is too tight reads
   as a fashion label; a manufacturer wants it to read as a spec sheet. */
h1,
h2,
h3,
h4 {
  font-family: var(--f-display);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.022em;
  text-wrap: balance;
}
h1 {
  font-size: clamp(2.5rem, 5.6vw, 4.6rem);
  font-weight: 800;
  letter-spacing: -0.028em;
}
h2 {
  font-size: clamp(1.85rem, 3.4vw, 3rem);
  font-weight: 700;
}
h3 {
  font-size: clamp(1.22rem, 1.8vw, 1.6rem);
  letter-spacing: -0.018em;
  line-height: 1.14;
}
/* A section head that has to be an h2 for the outline but must not shout at
   the column of copy beside it. Reads at h3, ranks at h2. */
.h-sub {
  font-size: clamp(1.22rem, 1.8vw, 1.6rem);
  letter-spacing: -0.018em;
  line-height: 1.14;
}
h4 {
  font-size: clamp(1.02rem, 1.3vw, 1.18rem);
  letter-spacing: -0.012em;
  line-height: 1.2;
}
p {
  color: var(--ink-2);
  max-width: 66ch;
}
strong {
  color: var(--ink);
  font-weight: 600;
}

.eyebrow {
  font-family: var(--f-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
  margin-bottom: var(--s-4);
}
.lede {
  font-size: clamp(1.02rem, 1.35vw, 1.2rem);
  color: var(--ink-2);
  max-width: 58ch;
}
.hl {
  color: var(--volt-ink);
}
.num {
  font-family: var(--f-mono);
  font-variant-numeric: tabular-nums;
}
.cond {
  font-family: var(--f-cond);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* outline / ghost display type */
.ghost-type {
  font-family: var(--f-display);
  font-weight: 800;
  letter-spacing: -0.05em;
  color: transparent;
  -webkit-text-stroke: 1.4px var(--line-strong);
  line-height: 0.8;
  user-select: none;
  pointer-events: none;
}

/* ---------- 4. LAYOUT ---------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}
.wrap-wide {
  max-width: 1620px;
}
section {
  position: relative;
}
.sec {
  padding-block: var(--sec-y);
}
.sec-tight {
  padding-block: clamp(48px, 6vw, 84px);
}
.alt {
  background: var(--bg-2);
}
.rule {
  height: 1px;
  background: var(--line);
  border: 0;
}

.sec-head {
  margin-bottom: clamp(32px, 4.5vw, 64px);
  max-width: 62ch;
}
.sec-head p {
  margin-top: var(--s-4);
}

/* fine technical grid, both themes */
.grid-bg::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: linear-gradient(var(--line-faint) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-faint) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(ellipse 80% 70% at 50% 40%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 40%, #000 30%, transparent 100%);
}

/* film grain - fixed, never on a scrolling container
   ---------------------------------------------------------------------------
   This used to be mix-blend-mode: overlay, and that one declaration was the
   most expensive thing on the site. A blended layer has to be recomposited
   against whatever is beneath it every time those pixels change, and it is
   fixed at inset 0, so "beneath it" means the entire viewport. The homepage
   has a wordmark turning, a banner cycling, two marquees and a ticker running
   at all times, so the full screen was being re-blended on every single frame,
   forever, whether or not anyone was looking at it.

   At three to five percent opacity the difference between overlay and normal
   compositing is not visible on either palette: the texture still reads, the
   page no longer pays for it. Verified against both themes before removing. */
.grain {
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='4'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- 5. BUTTONS --------------------------------------------------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 26px;
  border-radius: var(--r-pill);
  font-family: var(--f-cond);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--t-fast), background-color var(--t-mid),
    color var(--t-mid), border-color var(--t-mid);
}
.btn svg {
  width: 17px;
  height: 17px;
  flex: none;
}
.btn:active {
  transform: scale(0.975);
}

.btn-primary {
  background: var(--volt);
  color: var(--on-volt);
  border: 1px solid var(--volt);
}
.btn-primary::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--on-volt);
  transform: translateY(101%);
  transition: transform 0.42s var(--e-out);
}
.btn-primary:hover {
  color: var(--volt);
  box-shadow: 0 0 34px color-mix(in srgb, var(--volt) var(--glow), transparent);
}
.btn-primary:hover::after {
  transform: translateY(0);
}

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line-strong);
}
.btn-ghost::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--ink);
  transform: translateY(101%);
  transition: transform 0.42s var(--e-out);
}
.btn-ghost:hover {
  color: var(--bg);
  border-color: var(--ink);
}
.btn-ghost:hover::after {
  transform: translateY(0);
}

.btn-sm {
  min-height: 40px;
  padding: 0 18px;
  font-size: 0.86rem;
}
.btn-block {
  width: 100%;
}
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

/* ---------- 6. CHIPS + TAGS --------------------------------------------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  font-family: var(--f-cond);
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-2);
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast),
    background-color var(--t-fast);
}
.chip:hover {
  color: var(--ink);
  border-color: var(--line-strong);
}
.chip[aria-pressed='true'],
.chip.on {
  background: var(--volt);
  border-color: var(--volt);
  color: var(--on-volt);
  box-shadow: 0 0 24px color-mix(in srgb, var(--volt) var(--glow-soft), transparent);
}
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  font-family: var(--f-mono);
  font-size: 0.63rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.tag-volt {
  background: var(--volt);
  border-color: var(--volt);
  color: var(--on-volt);
  font-weight: 700;
  box-shadow: 0 0 20px color-mix(in srgb, var(--volt) var(--glow-soft), transparent);
}

/* ---------- 7. TICKER (single marquee on the page) ---------------------- */

.ticker {
  position: relative;
  overflow: hidden;
  background: var(--volt);
  color: var(--on-volt);
  border-bottom: 1px solid var(--volt-deep);
}
.ticker-track {
  display: flex;
  width: max-content;
  animation: tick 34s linear infinite;
}
.ticker-track span {
  display: inline-flex;
  align-items: center;
  gap: 34px;
  padding: 9px 17px;
  font-family: var(--f-cond);
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  white-space: nowrap;
}
.ticker-track b {
  font-weight: 700;
  opacity: 0.42;
}
.ticker:hover .ticker-track {
  animation-play-state: paused;
}
@keyframes tick {
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

/* ---------- 8. NAVIGATION ----------------------------------------------- */

.nav {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: var(--scrim);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border-bottom: 1px solid var(--line);
  transition: background-color var(--t-mid), border-color var(--t-mid);
}
.nav-in {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  height: 70px;
}
@media (max-width: 900px) {
  .nav-in {
    height: 62px;
  }
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: none;
}
.brand-mark {
  width: 34px;
  height: 34px;
  flex: none;
}
.brand-text {
  display: flex;
  flex-direction: column;
  line-height: 1;
}
.brand-text b {
  font-family: var(--f-display);
  font-size: 1.24rem;
  font-weight: 800;
  letter-spacing: -0.04em;
}
.brand-text i {
  font-family: var(--f-mono);
  font-style: normal;
  font-size: 0.54rem;
  letter-spacing: 0.28em;
  color: var(--ink-3);
  text-transform: uppercase;
  margin-top: 3px;
}

.nav-links {
  display: flex;
  align-items: center;
  /* the items were touching; a menu needs air between its labels */
  gap: clamp(4px, 1.1vw, 18px);
  margin-left: auto;
}
.nav-links a {
  position: relative;
  padding: 9px 13px;
  font-family: var(--f-cond);
  font-size: 0.97rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-2);
  transition: color var(--t-fast);
}
.nav-links a::after {
  content: '';
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 3px;
  height: 2px;
  background: var(--volt);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid);
}
.nav-links a:hover,
.nav-links a[aria-current='page'] {
  color: var(--ink);
}
.nav-links a:hover::after,
.nav-links a[aria-current='page']::after {
  transform: scaleX(1);
}

/* ---------- primary menu -------------------------------------------------
   One line: Home, Products, Manufacturing, About, Quality, Resources.
   Each dropdown is a split control. The label is a real link to the hub page
   and the chevron beside it opens the panel, so a visitor who knows where
   they are going is never forced through a menu to get there. */

.nav-drop {
  position: relative;
  display: flex;
  align-items: center;
}
.nav-drop-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 9px 4px 9px 13px;
  font-family: var(--f-cond);
  font-size: 0.97rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
  transition: color var(--t-fast);
}
/* Hover opens these, but hover does not exist on a touch screen and cannot be
   reached from a keyboard, so this button is the other way in and has to look
   like a control rather than a decoration beside the word. */
.nav-drop-tog {
  display: grid;
  place-items: center;
  width: 26px;
  height: 30px;
  margin-right: 4px;
  border-radius: 8px;
  color: var(--ink-3);
  cursor: pointer;
  transition: color var(--t-fast), background-color var(--t-fast);
}
.nav-drop-tog:hover {
  color: var(--ink);
  background: var(--surface-2);
}
.nav-drop.open .nav-drop-tog {
  color: var(--on-volt);
  background: var(--volt);
}
.nav-drop-tog svg {
  width: 12px;
  height: 12px;
  transition: transform var(--t-mid);
}
.nav-drop:hover .nav-drop-btn,
.nav-drop:focus-within .nav-drop-btn,
.nav-drop.open .nav-drop-btn,
.nav-drop-btn[aria-current='page'] {
  color: var(--ink);
}
/* the chevron turns over when the panel is actually open, not when the word is
   merely hovered: during the dwell nothing has opened yet, and a chevron that
   had already flipped would be describing a panel that is not there */
.nav-drop.open .nav-drop-tog svg {
  transform: rotate(180deg);
}
/* The underline lives on the button, not on .nav-drop, because the products
   trigger has to become position:static so its full width shelf can resolve
   against the header instead of against the trigger. */
.nav-drop-btn::after {
  content: '';
  position: absolute;
  left: 13px;
  right: 0;
  bottom: 3px;
  height: 2px;
  background: var(--volt);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid);
}
.nav-drop:hover .nav-drop-btn::after,
.nav-drop.open .nav-drop-btn::after,
.nav-drop-btn[aria-current='page']::after {
  transform: scaleX(1);
}

/* ---------- dropdown panels (3D) ---------------------------------------
   The panel hinges down from its top edge rather than fading in. The rotateX
   is what makes it read as a physical surface swinging into the room instead
   of a rectangle appearing, and it is the reason the perspective sits on the
   nav row rather than on the panel itself: a shared vanishing point means all
   six panels tip toward the same eye. */

/* Perspective establishes a containing block for absolutely positioned
   descendants, exactly like a transform does. Left on .nav-links it trapped
   the products shelf inside the nav width, so the list panels get their own
   perspective and the shelf carries its own in its transform function. */
.nav-drop:not([data-drop='products']) {
  perspective: 1500px;
  perspective-origin: top center;
}
.dd-panel {
  position: absolute;
  top: calc(100% + 8px);
  padding: clamp(16px, 1.8vw, 24px);
  display: grid;
  gap: clamp(12px, 1.4vw, 18px);
  border: 1px solid var(--line);
  border-radius: var(--r-panel);
  background: var(--bg-2);
  box-shadow: var(--shadow);
  transform-origin: top center;
  transform: rotateX(-14deg) translateY(-6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.24s var(--e-out), transform 0.42s var(--e-out),
    visibility 0.42s;
  /* a laptop is 800 to 900px tall, so no panel may outgrow the screen */
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Open state is a class, not a :hover selector, and that is the whole point.

   :hover fires the moment the pointer touches the word. Crossing the header on
   the way to anything else was enough to drop a full width panel over the hero
   banner and then whip it away again, which is the behaviour the owner
   reported. wireNav() in app.js still opens these on hover, but only after the
   pointer has stayed put long enough to mean it, and it holds them open for a
   beat after the pointer leaves so the panel can actually be reached. Neither
   of those is expressible in CSS.

   :focus-within is deliberately not here either. It cannot be: the toggle
   button keeps focus after a click, so a focus based rule would hold the panel
   open against the button that is trying to close it. Keyboard access comes
   from the button instead, which is what a disclosure widget is for. */
.nav-drop.open > .dd-panel {
  opacity: 1;
  visibility: visible;
  transform: rotateX(0) translateY(0);
}

/* The page dims behind an open panel. Without it the panel read as a box that
   had landed on the hero banner; with it the panel is obviously a layer and
   the banner is obviously behind it. */
.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-nav) - 1);
  background: var(--bg);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.28s var(--e-out), visibility 0.28s;
}
html.menu-open .nav-scrim {
  opacity: 0.62;
  visibility: visible;
  pointer-events: auto;
}

/* contents lift out of the panel a beat later, which is what stops the whole
   thing arriving as one flat sheet */
.dd-panel > * {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.3s var(--e-out), transform 0.42s var(--e-out);
}
.nav-drop.open > .dd-panel > * {
  opacity: 1;
  transform: none;
}
.dd-panel > :nth-child(1) { transition-delay: 0.05s; }
.dd-panel > :nth-child(2) { transition-delay: 0.1s; }
.dd-panel > :nth-child(3) { transition-delay: 0.15s; }

/* the wide product panel centres on the trigger; the short list panels hang
   from their left edge so they sit under the word that opened them */
/* The products panel is not a floating box, it is the header opening. Made
   static, the trigger stops being the positioning context and the panel
   resolves against the sticky header instead, so it spans the full width and
   reads as part of the chrome rather than as something dropped on the hero. */
.nav-drop[data-drop='products'] {
  position: static;
}
.mega {
  left: 0;
  right: 0;
  top: 100%;
  width: auto;
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  /* centre the contents on the page wrap without an extra wrapper element */
  padding-inline: max(var(--pad-x), calc((100vw - 1620px) / 2));
  /* A dropdown has to cover something; what it must not do is take the page
     over. At its old size this panel stood 594px tall on a 720px laptop, which
     is not a menu opening, it is the page being replaced, and on the homepage
     the thing it replaced was the hero banner.

     Half the viewport is the ceiling. The layout below is tightened to fit
     inside it comfortably at five columns, and the scroll is there for the
     short screens where it still cannot. */
  padding-block: clamp(11px, 1vw, 15px);
  gap: clamp(9px, 0.8vw, 12px);
  max-height: min(56vh, 470px);
  transform: perspective(1800px) rotateX(-7deg);
}
.nav-drop.open > .mega {
  transform: perspective(1800px) rotateX(0);
}
.dd-list {
  left: 0;
  width: 330px;
  gap: 0;
}
.dd-head {
  padding-bottom: 11px;
  margin-bottom: 9px;
  border-bottom: 1px solid var(--line);
}
.dd-head b {
  display: block;
  font-family: var(--f-cond);
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.dd-head i {
  display: block;
  margin-top: 3px;
  font-family: var(--f-mono);
  font-style: normal;
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.dd-links {
  display: flex;
  flex-direction: column;
}
.dd-links a {
  padding: 9px 11px;
  margin: 0 -11px;
  border-radius: var(--r-input);
  transition: background-color var(--t-fast), transform var(--t-fast);
}
.dd-links a:hover,
.dd-links a[aria-current='page'] {
  background: var(--surface-2);
  transform: translateX(3px);
}
.dd-links b {
  display: block;
  font-family: var(--f-cond);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}
.dd-links i {
  display: block;
  margin-top: 1px;
  font-family: var(--f-mono);
  font-style: normal;
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  color: var(--ink-3);
}
.dd-all {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--f-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--volt-ink);
}
.dd-all:hover .mm-arw {
  transform: translateX(5px);
}

/* the panel is a surface, not a slide: honour a reduced-motion request by
   dropping the hinge and keeping only the fade */
@media (prefers-reduced-motion: reduce) {
  .dd-panel,
  .mega {
    transform: none !important;
  }
  .dd-panel > * {
    transform: none;
  }
}
/* a buyer arrives with a garment in mind, so the panel leads with search and
   only then offers the taxonomy.

   The popular searches used to wrap onto a line of their own, which cost the
   panel about fifty pixels of height for six words. They sit beside the field
   now and scroll sideways if the header is narrow. */
.mega-search {
  display: grid;
  grid-template-columns: minmax(240px, 0.9fr) auto minmax(0, 1.1fr);
  gap: 10px;
  align-items: center;
  padding-bottom: clamp(10px, 1.1vw, 14px);
  border-bottom: 1px solid var(--line);
}
.mega-search .search {
  margin: 0;
}
.mega-quick {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.mega-quick::-webkit-scrollbar {
  display: none;
}
.mega-quick a,
.mega-quick span {
  flex: none;
}
@media (max-width: 1100px) {
  .mega-search {
    grid-template-columns: 1fr auto;
  }
  .mega-quick {
    grid-column: 1 / -1;
  }
}
.mega-quick span {
  font-family: var(--f-mono);
  font-size: 0.58rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.mega-quick a {
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-family: var(--f-cond);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
  transition: color var(--t-fast), border-color var(--t-fast);
}
.mega-quick a:hover {
  color: var(--ink);
  border-color: var(--volt);
}

/* One track per product line, counted rather than hard coded.
   repeat(5, 1fr) was fine while there were five lines. Adding Workwear made a
   sixth column wrap onto a second row: the panel's content grew to 772px
   inside a 448px cap, so the new line sat below a scrollbar - the exact
   failure the note further up this file warns about, where a menu you have to
   scroll to see a line is not a menu. It also pushed the panel back over the
   hero banner, from 49% coverage to 58%.

   auto-fit keeps every line on one row and lets a seventh arrive without
   anyone remembering to come back here. The 132px floor is the narrowest a
   column can be and still hold a subcategory name on one line; below that the
   grid drops to fewer tracks on its own, which is what should happen. */
.mega-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: clamp(8px, 1vw, 14px);
}
.mega-foot {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(8px, 1vw, 14px);
  padding-top: clamp(10px, 1.1vw, 14px);
  border-top: 1px solid var(--line);
}
.mega-foot a {
  padding: 8px 13px;
  border-radius: var(--r-input);
  border: 1px solid transparent;
  transition: background-color var(--t-fast), border-color var(--t-fast);
}
.mega-foot a:hover {
  background: var(--surface-2);
  border-color: var(--line);
}
.mega-foot b {
  display: block;
  font-family: var(--f-cond);
  font-size: 0.93rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.mega-foot i {
  display: block;
  margin-top: 2px;
  font-family: var(--f-mono);
  font-style: normal;
  font-size: 0.6rem;
  line-height: 1.25;
  letter-spacing: 0.1em;
  color: var(--ink-3);
}
.mega-foot .mega-cta {
  background: var(--volt);
  border-color: var(--volt);
}
.mega-foot .mega-cta b,
.mega-foot .mega-cta i {
  color: var(--on-volt);
}
.mega-foot .mega-cta:hover {
  background: var(--volt-deep);
  border-color: var(--volt-deep);
}

.mm-col {
  display: flex;
  flex-direction: column;
  padding: 9px 10px;
  border-radius: var(--r-input);
  border: 1px solid transparent;
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.mm-col:hover {
  border-color: color-mix(in srgb, var(--c) 40%, transparent);
  background: var(--surface-2);
}
.mm-head {
  display: block;
  padding-bottom: 7px;
  margin-bottom: 7px;
  border-bottom: 1px solid var(--line);
}
/* The body line height is set for reading paragraphs. Inside a menu it is
   dead space: five columns of it stacked the panel up to 594px, which is what
   put it over the hero banner in the first place. Everything in here is a
   label, and labels set tight. */
.mm-head b {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--f-cond);
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.mm-head b::before {
  content: '';
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: var(--r-pill);
  background: var(--c, var(--volt));
}
.mm-head i {
  display: block;
  margin-top: 3px;
  font-family: var(--f-mono);
  font-style: normal;
  font-size: 0.6rem;
  line-height: 1.3;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.mm-links {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-bottom: 7px;
}
.mm-links a {
  padding: 3px 8px;
  margin-left: -8px;
  border-radius: 8px;
  font-family: var(--f-cond);
  font-size: 0.94rem;
  line-height: 1.3;
  letter-spacing: 0.03em;
  color: var(--ink-2);
  transition: color var(--t-fast), background-color var(--t-fast);
}
.mm-links a:hover,
.mm-links a[aria-current='page'] {
  color: var(--ink);
  background: var(--surface);
}
.mm-all {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--f-mono);
  font-size: 0.62rem;
  line-height: 1.3;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c, var(--volt-ink));
}
.mm-arw {
  display: inline-block;
  transition: transform var(--t-fast);
}
.mm-all:hover .mm-arw,
.sc-card:hover .mm-arw {
  transform: translateX(5px);
}
.mega a[aria-current='true'] {
  color: var(--ink);
}
/* Between 1060px, where the desktop menu gives way to the drawer, and 1240px
   the five columns used to reflow onto three, and the footer onto two. Both
   changes doubled the number of rows, which made the panel about 250px taller
   at exactly the screen sizes with the least height to spare, and a menu that
   has to be scrolled to see two of the six lines is not a menu.

   The columns stay put and the type tightens instead. Five narrow columns are
   still five columns; two rows of them are a page.

   The height clause is for the other awkward shape: a wide, short laptop, the
   1280 by 720 that a lot of buyers are actually sitting in front of. There is
   room across but none to spare downwards, so the same trim applies and the
   one line descriptors under each heading are the first thing to go. They are
   nice to have; seeing all six lines at once is not. */
@media (max-width: 1240px), (max-height: 780px) {
  .mega-cols,
  .mega-foot {
    gap: 7px;
  }
  .mm-col {
    padding: 8px;
  }
  .mm-head b {
    font-size: 0.9rem;
    gap: 6px;
  }
  .mm-head i,
  .mega-foot i {
    display: none;
  }
  .mm-links a {
    font-size: 0.88rem;
  }
  .mega-foot a {
    padding: 8px 10px;
  }
  .mega-foot b {
    font-size: 0.86rem;
  }
}

/* drawer search sits above the collapsible lines on mobile */
.drawer-search {
  margin-bottom: var(--s-5);
}
.drawer-search .search {
  width: 100%;
}
/* The 8px gap between trigger and panel would drop the hover halfway, so it is
   bridged with an invisible strip. Scoped per trigger, not across the header,
   or hovering any part of the nav would hold a panel open. */
.nav-drop::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 12px;
}
/* The products trigger used to need a bridge 440px wider than itself to catch
   a diagonal move toward the outer columns of a floating panel. Now that it is
   position:static its ::after already resolves against the full width header,
   so that override is not only unnecessary, it pushed 440px of scrollable
   overflow past the viewport and gave the whole page a horizontal scrollbar. */
.nav-side {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

/* theme toggle */
.theme-btn {
  position: relative;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  color: var(--ink);
  overflow: hidden;
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.theme-btn:hover {
  border-color: var(--line-strong);
  background: var(--surface);
}
.theme-btn svg {
  width: 19px;
  height: 19px;
  position: absolute;
  transition: transform 0.5s var(--e-out), opacity 0.35s var(--e-out);
}
.theme-btn .i-sun {
  opacity: 0;
  transform: rotate(-90deg) scale(0.4);
}
.theme-btn .i-moon {
  opacity: 1;
  transform: rotate(0) scale(1);
}
[data-theme='light'] .theme-btn .i-sun {
  opacity: 1;
  transform: rotate(0) scale(1);
}
[data-theme='light'] .theme-btn .i-moon {
  opacity: 0;
  transform: rotate(90deg) scale(0.4);
}

.burger {
  display: none;
  width: 46px;
  height: 46px;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.burger span {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--ink);
  transition: transform var(--t-mid), opacity var(--t-fast);
}
.burger span + span {
  margin-top: 5px;
}
.burger[aria-expanded='true'] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.burger[aria-expanded='true'] span:nth-child(2) {
  opacity: 0;
}
.burger[aria-expanded='true'] span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* mobile drawer */
.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: var(--bg);
  padding: 96px var(--pad-x) 40px;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform 0.55s var(--e-out), visibility 0.55s;
  overflow-y: auto;
}
.drawer.open {
  transform: translateY(0);
  visibility: visible;
  overscroll-behavior: contain;
}
/* the drawer covers the full viewport, so the header rides above it while it
   is open. Without this the burger turns into an X the visitor cannot reach,
   and on a phone there is no Escape key to fall back on. */
html.drawer-open .nav {
  z-index: calc(var(--z-drawer) + 1);
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}
html.drawer-open .nav .btn-primary {
  display: none;
}
.drawer a {
  font-family: var(--f-display);
  /* ten items now that the six lines live here, so the scale steps down */
  font-size: clamp(1.5rem, 6vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
  transition: color var(--t-fast), padding-left var(--t-fast);
}
.drawer a:hover {
  color: var(--volt-ink);
  padding-left: 10px;
}
.drawer .btn {
  margin-top: var(--s-5);
}
.drawer-label {
  font-family: var(--f-mono);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-top: var(--s-4);
  margin-bottom: 2px;
}
.drawer-label:first-child {
  margin-top: 0;
}
/* five collapsible lines rather than fifty flat links */
.drawer-group summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  list-style: none;
  font-family: var(--f-display);
  font-size: clamp(1.35rem, 5.4vw, 1.9rem);
  font-weight: 800;
  letter-spacing: -0.04em;
}
.drawer-group summary::-webkit-details-marker {
  display: none;
}
.drawer-group summary::before {
  content: '';
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: var(--r-pill);
  background: var(--c, var(--volt));
}
.drawer-group summary::after {
  content: '+';
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: 1.1rem;
  font-weight: 400;
  color: var(--ink-3);
}
.drawer-group[open] summary::after {
  content: '\2013';
}
.drawer-subs {
  display: flex;
  flex-direction: column;
  padding: 8px 0 12px 21px;
}
.drawer-subs a {
  font-family: var(--f-cond);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 7px 0;
  border-bottom: 0;
}
.drawer-subs a:hover {
  color: var(--volt-ink);
}
.drawer-subs .drawer-all {
  margin-top: 6px;
  font-family: var(--f-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  color: var(--c, var(--volt-ink));
}

@media (max-width: 1060px) {
  .nav-links {
    display: none;
  }
  .burger {
    display: grid;
  }
}

/* On a 375px phone the header ran to 412px: brand, theme toggle, quote button
   and burger do not fit, and the burger was the part hanging off the edge.
   The quote CTA is the one that can go, because the drawer opens with a full
   width "Request a quote" and the contact deck is on screen anyway. Losing a
   menu button is not a trade worth making for a duplicate CTA. */
@media (max-width: 560px) {
  .nav-side .btn {
    display: none;
  }
  .nav-in {
    gap: var(--s-3);
  }
}

/* ---------- 9. FOOTER ---------------------------------------------------- */

.foot {
  background: var(--bg-2);
  border-top: 1px solid var(--line);
  padding-top: clamp(56px, 7vw, 90px);
  position: relative;
  overflow: hidden;
}
.foot-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1.3fr;
  gap: var(--s-7);
}
.foot h2 {
  font-family: var(--f-mono);
  line-height: 1.2;
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s-4);
}
.foot-links {
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.foot-links a {
  font-family: var(--f-cond);
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
  transition: color var(--t-fast), transform var(--t-fast);
}
.foot-links a:hover {
  color: var(--volt-ink);
  transform: translateX(4px);
}
.foot-bot {
  margin-top: clamp(48px, 6vw, 72px);
  border-top: 1px solid var(--line);
  padding: var(--s-5) 0 var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: space-between;
  align-items: center;
  font-family: var(--f-mono);
  font-size: 0.72rem;
  color: var(--ink-3);
}
.foot-word {
  font-family: var(--f-display);
  font-weight: 800;
  font-size: clamp(3.4rem, 16vw, 15rem);
  line-height: 0.72;
  letter-spacing: -0.055em;
  color: transparent;
  -webkit-text-stroke: 1px var(--line);
  text-align: center;
  margin-top: clamp(24px, 4vw, 48px);
  user-select: none;
  overflow: hidden;
}
@media (max-width: 940px) {
  .foot-grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-6);
  }
}
@media (max-width: 560px) {
  .foot-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- 10. SOCIAL + CONTACT ROWS ----------------------------------- */

.soc-row {
  display: flex;
  gap: 9px;
  margin-top: var(--s-5);
}
.soc-row a {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  color: var(--ink-2);
  transition: color var(--t-fast), border-color var(--t-fast),
    background-color var(--t-fast), transform var(--t-fast);
}
.soc-row a:hover {
  color: var(--on-volt);
  background: var(--volt);
  border-color: var(--volt);
  transform: translateY(-3px);
}
.soc-row svg {
  width: 18px;
  height: 18px;
}

.kv {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: var(--s-4);
}
.kv dt {
  font-family: var(--f-mono);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.kv dd {
  font-family: var(--f-cond);
  font-size: 1.06rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.kv dd a:hover {
  color: var(--volt-ink);
}

/* ---------- 11. PRELOADER ----------------------------------------------- */

.loader {
  position: fixed;
  inset: 0;
  z-index: var(--z-loader);
  background: var(--bg);
  display: grid;
  place-items: center;
  transition: opacity 0.5s var(--e-out), visibility 0.5s;
}
.loader.done {
  opacity: 0;
  visibility: hidden;
  /* visibility flips only when the 0.5s fade ends, so without this the
     invisible overlay still swallows the first tap on the hero. */
  pointer-events: none;
}
.loader-in {
  text-align: center;
  width: min(520px, 78vw);
}
.loader-word {
  font-family: var(--f-display);
  font-size: clamp(2.4rem, 9vw, 5rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 1;
  overflow: hidden;
}
.loader-bar {
  margin-top: var(--s-5);
  height: 2px;
  background: var(--line);
  overflow: hidden;
}
.loader-bar i {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--volt);
}
.loader-pct {
  margin-top: 10px;
  font-family: var(--f-mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  color: var(--ink-3);
}

/* ---------- 12. SCROLL PROGRESS ----------------------------------------- */

.progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: var(--volt);
  z-index: calc(var(--z-nav) + 1);
  pointer-events: none;
  display: none;
}
/* driven entirely by the scroll timeline, no scroll listener involved */
@supports (animation-timeline: scroll()) {
  .progress {
    display: block;
    animation: bar-grow linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes bar-grow {
    to {
      transform: scaleX(1);
    }
  }
}

/* ---------- 12b. CURSOR --------------------------------------------------
   An instrument, not an effect.

   THE RULE THIS VERSION IS BUILT ON: the pointer is never behind the mouse.
   Earlier versions gave the ring a long transition on transform so it trailed
   the dot, and that trail is what the owner kept rejecting. It is also
   indefensible on a manufacturing site: a lagging pointer does not read as
   refinement, it reads as a slow page, and it is worst on exactly the cheap
   hardware a lot of these buyers are on. Every part now lands on the pointer
   in the same frame, and the character comes from what the pointer BECOMES
   over each kind of thing rather than from how late it arrives.

   Three states, each one a piece of information a buyer can act on:
     nothing      a thin ring with a centre dot. Precise, quiet, out of the way.
     a link       the ring fills solid. Unmistakably "this does something".
     a garment    the ring squares off into a viewfinder and names the action.
                  The word is the point: it tells a buyer the whole card is a
                  destination, which is otherwise something they have to guess.

   The whole thing is one fixed element carrying one transform, written once
   per pointer event. No animation frame, no glow, no blend mode: the 760px
   halo an older version dragged around under .grain and .nav was the most
   expensive thing on the page.

   The native cursor is hidden only under html.has-cursor, added after the
   replacement has drawn. If the script never runs, the normal pointer stays. */

html.has-cursor,
html.has-cursor *:not(input):not(textarea):not(select):not([contenteditable='true']) {
  cursor: none;
}

.cur {
  --cc: var(--volt);
  position: fixed;
  left: 0;
  top: 0;
  z-index: 300;
  pointer-events: none;
  opacity: 0;
  /* one promoted layer for the whole cursor; the parts inside never move
     relative to each other, so they never need one of their own */
  will-change: transform;
  transition: opacity 0.16s var(--e-out), scale 0.14s var(--e-out);
}
.cur.is-live {
  opacity: 1;
}
.cur.is-out,
.cur.on-text,
.cur.is-off {
  opacity: 0;
}

.cur-dot,
.cur-ring,
.cur-lbl,
.cur-t,
.cur-c {
  position: absolute;
  left: 0;
  top: 0;
}

/* ---------------------------------------------------------------------------
   THE RESTING STATE IS THE ONE THAT HAD TO CHANGE.

   It was a 6px dot inside a 28px ring at 0.62 opacity and a 1px border, and
   that is the cursor every template on the internet ships. All the character
   was hidden behind hover: the solid fill, the viewfinder, the word. A visitor
   spends most of their time not hovering anything, so the impression the site
   actually makes was the generic one.

   What it is now is a registration mark. Four ticks around a centre point is
   what sits on a cut sheet, a panel map and a pattern piece, and it is exactly
   the language the rest of this site already speaks: the product artwork is
   technical line drawings, the copy is tolerances and tech packs, the poster
   blocks have corner ticks on them. The pointer now belongs to the same
   drawing.

   Cost is unchanged. Every part is pinned to the same origin by CSS margins,
   so the wrapper still takes one transform write per pointer move and the
   compositor still gets a single layer.
   --------------------------------------------------------------------------- */

/* Visibility is the thing that kept failing. Volt green reads brilliantly on
   graphite and almost disappears on the paper white .inv sections, and the
   page alternates between the two by design.

   A fixed dark halo solves it in both directions without a blend mode: on a
   light surface the halo is what you see, on a dark one it vanishes into the
   background and the volt carries. The value is hard coded rather than
   tokenised precisely because it must NOT flip with the section. */
.cur-dot {
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: var(--r-pill);
  background: var(--cc);
  box-shadow: 0 0 0 1.25px rgba(9, 10, 13, 0.5), 0 1px 4px rgba(9, 10, 13, 0.3);
  transition: width 0.18s var(--e-out), height 0.18s var(--e-out),
    margin 0.18s var(--e-out), background-color 0.18s var(--e-out);
}

/* The four ticks. --a is the angle; each one is pushed out from the centre
   along it, so one rule places all four and the group scales as a unit. */
.cur-t {
  width: 7px;
  height: 1.5px;
  margin: -0.75px 0 0 0;
  background: var(--cc);
  box-shadow: 0 0 0 0.75px rgba(9, 10, 13, 0.45);
  transform-origin: 0 50%;
  transform: rotate(var(--a)) translateX(9px);
  transition: transform 0.2s var(--e-out), opacity 0.16s var(--e-out);
}

/* THE RING IS A STITCH.
   A register mark says "technical drawing", which is true of the artwork but
   is not what this company sells. A dashed ring says seam, and a seam is the
   one mark that belongs to apparel and to nothing else - it is also the
   vocabulary the rest of the site already speaks, where the copy is flatlock,
   overlock, coverstitch and bar tack.

   It turns slowly, which reads as the stitch being sewn. One rotation on one
   small composited element; the wrapper keeps its single transform write per
   pointer move and this does not touch it. */
.cur-ring {
  width: 27px;
  height: 27px;
  margin: -13.5px 0 0 -13.5px;
  border: 1.75px dashed var(--cc);
  border-radius: var(--r-pill);
  opacity: 0.75;
  filter: drop-shadow(0 0 1px rgba(9, 10, 13, 0.55));
  animation: curStitch 9s linear infinite;
  transition: width 0.2s var(--e-out), height 0.2s var(--e-out),
    margin 0.2s var(--e-out), border-radius 0.2s var(--e-out),
    opacity 0.18s var(--e-out), background-color 0.18s var(--e-out),
    border-color 0.18s var(--e-out), border-style 0.18s var(--e-out);
}
@keyframes curStitch {
  to { transform: rotate(360deg); }
}

/* The four corner brackets of the viewfinder. Hidden until there is something
   worth framing. --x and --y put each one in its own corner and flip the two
   borders that draw it, so a single rule makes all four. */
.cur-c {
  width: 9px;
  height: 9px;
  /* centred on the pointer origin, so --x and --y are a direction and the
     distance below is the half width of the frame */
  margin: -4.5px 0 0 -4.5px;
  opacity: 0;
  border: 1.75px solid var(--cc);
  border-right-color: transparent;
  border-bottom-color: transparent;
  filter: drop-shadow(0 0 0.75px rgba(9, 10, 13, 0.55));
  transform: translate(calc(var(--x) * 13px), calc(var(--y) * 13px)) rotate(var(--r));
  transition: transform 0.22s var(--e-out), opacity 0.16s var(--e-out);
}

/* ---- over a link: the ticks pull in, the ring fills solid and the dot
   inverts inside it. Bold and unmistakable, and it says "clickable" without
   needing a new shape. */
/* over a link the seam closes: the dashes join into a solid bound edge */
.cur.on-link .cur-ring {
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  background: var(--cc);
  border-style: solid;
  border-color: var(--cc);
  box-shadow: 0 0 0 1.25px rgba(9, 10, 13, 0.42), 0 2px 9px rgba(9, 10, 13, 0.26);
  opacity: 1;
  animation-play-state: paused;
}
.cur.on-link .cur-dot {
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  background: var(--on-volt);
  box-shadow: none;
}
.cur.on-link .cur-t {
  transform: rotate(var(--a)) translateX(4px);
  opacity: 0;
}

/* ---- over a garment card: the corners open into a viewfinder and the ring
   gets out of the way. It frames the product rather than covering it, and a
   crop frame is the same mark the cut sheets carry. */
.cur.on-card .cur-ring {
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 10px;
  opacity: 0.3;
  /* a rotating square is a spinning box, not a seam - the corners take over
     the framing here so the stitch simply holds still behind them */
  animation-play-state: paused;
}
.cur.on-card .cur-dot {
  width: 3px;
  height: 3px;
  margin: -1.5px 0 0 -1.5px;
}
.cur.on-card .cur-t {
  transform: rotate(var(--a)) translateX(5px);
  opacity: 0;
}
.cur.on-card .cur-c {
  opacity: 1;
  transform: translate(calc(var(--x) * 21px), calc(var(--y) * 21px)) rotate(var(--r));
}

.cur-lbl {
  padding: 6px 12px;
  margin: 26px 0 0 26px;
  border-radius: var(--r-pill);
  background: var(--cc);
  color: var(--on-volt);
  font-family: var(--f-cond);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(9, 10, 13, 0.28);
  opacity: 0;
  transform-origin: 0 0;
  transition: opacity 0.16s var(--e-out);
}
.cur.has-lbl .cur-lbl {
  opacity: 1;
}

/* ---- press: the whole instrument draws in as one piece.
   scale is its own property, so it composes with the transform JavaScript is
   writing rather than overwriting it. */
.cur.is-down {
  scale: 0.84;
}

@media (prefers-reduced-motion: reduce) {
  .cur,
  .cur-dot,
  .cur-ring,
  .cur-lbl,
  .cur-t,
  .cur-c {
    transition: none;
  }
  .cur-ring {
    animation: none;
  }
}

/* ---------- 13. FLOATING CONTACT DECK -----------------------------------
   Three channels rather than one. A buyer who will not install WhatsApp still
   has a way to reach the floor, and a buyer who lives in it gets one tap.

   The 3D is driven by --fx / --fy / --near, written per button by
   RX.contactDeck from the pointer distance. Everything here is composited,
   so a pointer moving across the page never triggers layout. */

.fab-deck {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: var(--z-sticky);
  display: grid;
  gap: 10px;
  justify-items: end;
  perspective: 620px;
}
.fab {
  --fx: 0;
  --fy: 0;
  --near: 0;
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  height: 52px;
  padding: 0;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
  transform-style: preserve-3d;
  /* tilt toward the pointer, and lift as it gets close */
  transform: rotateY(calc(var(--fx) * 22deg)) rotateX(calc(var(--fy) * -22deg))
    translateZ(calc(var(--near) * 14px));
  transition: transform 0.45s var(--e-out), background-color var(--t-mid),
    border-color var(--t-mid), box-shadow var(--t-mid);
}
.fab-ico {
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  flex: none;
  border-radius: var(--r-pill);
  transform: translateZ(12px);
}
.fab-ico svg {
  width: 23px;
  height: 23px;
}

/* the label is collapsed to zero width and opens on hover, so the deck stays
   out of the way until someone reaches for it */
.fab-lbl {
  display: grid;
  align-content: center;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  transform: translateZ(8px);
  transition: max-width 0.42s var(--e-out), opacity 0.28s var(--e-out),
    padding 0.42s var(--e-out);
}
.fab-lbl b {
  font-family: var(--f-cond);
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.1;
}
.fab-lbl i {
  font-family: var(--f-mono);
  font-style: normal;
  font-size: 0.56rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-top: 2px;
}
.fab:hover .fab-lbl,
.fab:focus-visible .fab-lbl {
  max-width: 190px;
  opacity: 1;
  padding-right: 20px;
}

/* one brand colour per channel, applied on hover and during the nudge */
.fab-wa {
  --fc: #22c55e;
  --fc-ink: #06230f;
}
.fab-ig {
  --fc: #e1306c;
  --fc-ink: #ffffff;
}
.fab-mail {
  --fc: var(--volt);
  --fc-ink: var(--on-volt);
}
.fab:hover,
.fab:focus-visible,
.fab.is-nudge {
  background: var(--fc);
  border-color: var(--fc);
  color: var(--fc-ink);
  box-shadow: 0 12px 34px color-mix(in srgb, var(--fc) 42%, transparent);
}
.fab:hover .fab-lbl i,
.fab.is-nudge .fab-lbl i {
  color: inherit;
  opacity: 0.72;
}

/* the timed nudge: a half turn on the Y axis, once, every few seconds */
.fab.is-nudge {
  animation: fabNudge 1.1s var(--e-inout);
}
@keyframes fabNudge {
  0% {
    transform: rotateY(0) translateZ(0);
  }
  45% {
    transform: rotateY(180deg) translateZ(16px) scale(1.06);
  }
  100% {
    transform: rotateY(360deg) translateZ(0) scale(1);
  }
}

@media (max-width: 620px) {
  .fab-deck {
    right: 12px;
    bottom: 12px;
    gap: 8px;
  }
  .fab {
    height: 46px;
  }
  .fab-ico {
    width: 44px;
    height: 44px;
  }
  .fab-ico svg {
    width: 20px;
    height: 20px;
  }
  /* no hover on a phone, so the labels never open and only the icons show */
  .fab-lbl {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fab {
    transform: none;
  }
  .fab.is-nudge {
    animation: none;
  }
}

/* ---------- 14. REVEAL PRIMITIVES (CSS engine, GSAP layers on top) ------ */

.js-anim [data-rv] {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
}
.js-anim [data-rv].in {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s var(--e-out), transform 0.7s var(--e-out);
  transition-delay: var(--d, 0ms);
}

/* ---------- 14b. LITE MODE ----------------------------------------------
   Set by the inline head script on a save-data, 2G, low memory or low core
   device. The page keeps every pixel of its layout and colour and loses only
   the things that cost a weak GPU real frames.

   backdrop-filter is first out. On budget Android it forces the compositor to
   read back and blur a region every frame the element is on screen, and it is
   the single most expensive property on this site. A solid surface at high
   opacity looks near identical and costs nothing. */

html.rx-lite .nav,
html.rx-lite .dd-panel,
html.rx-lite .mega,
html.rx-lite .modal {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
html.rx-lite .nav {
  background: var(--bg);
}
html.rx-lite .dd-panel,
html.rx-lite .mega {
  background: var(--bg-2);
}

/* four infinite animations across the page is four layers the compositor can
   never retire. On a lite device they are the difference between a smooth
   scroll and a stuttering one. */
html.rx-lite .ticker-track,
html.rx-lite .slant-track,
html.rx-lite .hw-stack,
html.rx-lite .hw-sheen,
html.rx-lite .hb-slide.is-on .hb-art svg,
html.rx-lite .hb-dot.is-on i {
  animation: none !important;
}
html.rx-lite .hw-sheen {
  opacity: 0 !important;
}

/* the grain no longer blends, but it is still a full screen layer the
   compositor has to carry, and on a lite device it buys nothing */
html.rx-lite .grain {
  display: none;
}

/* heavy shadows and glows are cheap to draw once and expensive to redraw on
   every hover, so on a lite device they resolve to a border change instead */
html.rx-lite .pc,
html.rx-lite .sc-card,
html.rx-lite .cat-panel,
html.rx-lite .station,
html.rx-lite .buyer {
  transition: border-color var(--t-fast) !important;
}
html.rx-lite .pc:hover,
html.rx-lite .sc-card:hover,
html.rx-lite .cat-panel:hover,
html.rx-lite .station:hover,
html.rx-lite .buyer:hover {
  transform: none !important;
  box-shadow: none !important;
}

/* ---------- 15. MOTION SAFETY ------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .ticker-track {
    animation: none;
    transform: none;
  }
  .js-anim [data-rv] {
    opacity: 1 !important;
    transform: none !important;
  }
  .loader {
    display: none;
  }
}
