/* ============================================================
   KD INK — light theme
   Derived from the Datalands system in DESIGN.md, with the surface
   stack inverted: parchment canvas, black type, white elevated cards,
   black used as the contrast block. Geometry, type and accent are
   unchanged — 96px radii, Martian Mono chrome, magenta as the single
   chromatic action colour.

   Font substitutes:
     OZIK Black          -> Anton (condensed ultra-black display)
     Basis Grotesque Pro -> Inter (geometric grotesque)
     Martian Mono        -> Martian Mono (exact, via Google Fonts)
   ============================================================ */

:root {
  /* Colors */
  --color-void: #000000;
  --color-bone: #ffffff;
  --color-charcoal: #1d1a1a;
  --color-ink: #111212;
  --color-graphite: #3d3d3d;
  --color-mist: #d9d9d9;
  --color-parchment: #f3f3ef;
  --color-neon-magenta: #fc74dd;
  --color-ember-dot: #ff4c33;
  --color-deep-violet: #122d8b;

  /* Light-theme semantic roles */
  --canvas: var(--color-parchment);   /* page background */
  --text: var(--color-void);          /* primary type */
  --text-muted: #56544f;              /* de-emphasised type, readable on parchment */
  --text-inverse: var(--color-bone);  /* type on the black contrast blocks */
  --surface-1: var(--color-bone);     /* elevated card */
  --surface-2: var(--color-void);     /* contrast block */
  --line: #dedcd4;                    /* hairline on canvas */
  --line-strong: #c6c3b9;             /* hairline that needs to be seen */
  --line-inverse: #333333;            /* hairline inside a contrast block */

  /* Fonts */
  --font-display: "Anton", "Druk Wide", Impact, ui-sans-serif, system-ui, sans-serif;
  --font-body: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "Martian Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Type scale */
  --text-caption: 12px;    --leading-caption: 1.2;    --tracking-caption: 0.05em;
  --text-body-sm: 14px;    --leading-body-sm: 1.25;   --tracking-body-sm: -0.002em;
  --text-body: 18px;       --leading-body: 1.45;      --tracking-body: -0.008em;
  --text-subheading: 22px; --leading-subheading: 1.2; --tracking-subheading: -0.01em;
  --text-heading-sm: 35px; --leading-heading-sm: 1.1; --tracking-heading-sm: -0.02em;
  --text-heading: 42px;    --leading-heading: 1.1;    --tracking-heading: -0.025em;
  --text-heading-lg: 60px; --leading-heading-lg: 1;   --tracking-heading-lg: -0.03em;
  --text-display: 80px;    --leading-display: 1;      --tracking-display: -0.04em;
  --text-tiny: 11px;       --leading-tiny: 1.3;       --tracking-tiny: 0.06em;
  --text-micro: 10px;      --leading-micro: 1.3;      --tracking-micro: 0.04em;
  --text-badge: 13px;

  /* Weights */
  --fw-xlight: 200; --fw-regular: 400; --fw-semibold: 600;

  /* Spacing */
  --spacing-4: 4px;   --spacing-6: 6px;   --spacing-10: 10px; --spacing-12: 12px;
  --spacing-14: 14px; --spacing-16: 16px; --spacing-18: 18px; --spacing-20: 20px; --spacing-22: 22px;
  --spacing-24: 24px; --spacing-30: 30px; --spacing-36: 36px; --spacing-38: 38px;
  --spacing-40: 40px; --spacing-48: 48px; --spacing-60: 60px; --spacing-80: 80px;

  /* Layout */
  --page-max-width: 1440px;
  --section-gap: 80px;
  --card-padding: 48px;
  --gutter: 40px;

  /* Radii */
  --radius-2xl: 18px; --radius-3xl: 30px; --radius-full-3: 96px; --radius-special: 300px;

  /* Motion */
  --ease-out: cubic-bezier(.2,.7,.2,1);
}

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* text selection/copy is off site-wide; re-enabled explicitly for the
     email, phone and address links so visitors can still copy contact
     details (see .copyable below). -webkit-touch-callout covers iOS
     Safari specifically, where user-select alone doesn't suppress the
     long-press copy/save callout menu. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.copyable, .copyable * {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--color-neon-magenta); color: var(--color-charcoal); }
:focus-visible { outline: 2px solid var(--color-void); outline-offset: 3px; border-radius: 4px; }

.skip-link {
  position: absolute; left: var(--spacing-20); top: -100px; z-index: 100;
  background: var(--color-neon-magenta); color: var(--color-charcoal);
  padding: var(--spacing-10) var(--spacing-22); border-radius: var(--radius-full-3);
}
.skip-link:focus { top: var(--spacing-12); }

/* ---------- scroll progress ---------- */

.progress {
  position: fixed; inset: 0 auto auto 0; z-index: 80;
  height: 2px; width: 100%;
  background: var(--color-neon-magenta);
  transform: scaleX(0); transform-origin: 0 50%;
  will-change: transform;
}

/* ---------- primitives ---------- */

.shell { width: 100%; max-width: var(--page-max-width); margin-inline: auto; padding-inline: var(--gutter); }

.mono {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--fw-xlight);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  line-height: 1.2;
}

.section-label { display: inline-flex; align-items: center; gap: var(--spacing-10); color: var(--text); }
/* only the FAB Tool label -- matches the pink F/A/B badges, not a
   site-wide section-label change. Bold + a soft pink highlight pill
   behind the text, not just a colour swap. */
#fab .section-label {
  color: var(--color-neon-magenta);
  font-weight: var(--fw-semibold);
  background: rgba(252, 116, 221, 0.14);
  padding: var(--spacing-4) var(--spacing-12);
  border-radius: var(--radius-full-3, 999px);
}
.section-label::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--color-ember-dot); flex: none;
}

h1, h2, h3, h4 { font-family: var(--font-body); font-weight: var(--fw-regular); margin: 0; }
h2.display {
  font-size: clamp(35px, 6vw, var(--text-heading-lg));
  line-height: var(--leading-heading-lg);
  letter-spacing: var(--tracking-heading-lg);
  max-width: 20ch;
}
h3.sub { font-size: var(--text-subheading); line-height: var(--leading-subheading); letter-spacing: var(--tracking-subheading); }
p { margin: 0; }
.muted { color: var(--text-muted); }
.small { font-size: var(--text-body-sm); line-height: var(--leading-body-sm); letter-spacing: var(--tracking-body-sm); }

/* ---------- buttons ---------- */

.btn {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: var(--spacing-10);
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: var(--fw-xlight);
  letter-spacing: 0.10em; text-transform: uppercase;
  border-radius: var(--radius-full-3);
  padding: var(--spacing-10) var(--spacing-22);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color .3s var(--ease-out), color .3s var(--ease-out),
              border-color .3s var(--ease-out), transform .25s var(--ease-out);
  white-space: nowrap;
}
.btn > * { position: relative; z-index: 1; }
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--ghost { border-color: var(--line-strong); color: var(--text); background: transparent; }
.btn--ghost:hover { border-color: var(--text); }

.btn--magenta { background: var(--color-neon-magenta); color: var(--color-charcoal); }
.btn--magenta:hover { background: var(--color-void); color: var(--color-bone); }

.btn--solid { background: var(--color-void); color: var(--color-bone); }
.btn--solid:hover { background: var(--color-neon-magenta); color: var(--color-charcoal); }

.btn--onDark { border: 1px solid var(--line-inverse); color: var(--color-bone); background: transparent; }
.btn--onDark:hover { background: var(--color-neon-magenta); color: var(--color-charcoal); border-color: var(--color-neon-magenta); }

.btn__arrow {
  width: 34px; height: 34px; border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--color-void); color: var(--color-bone);
  margin-right: -14px; margin-block: -6px; flex: none;
  transition: transform .3s var(--ease-out), background-color .3s var(--ease-out), color .3s var(--ease-out);
}
.btn:hover .btn__arrow { transform: translateX(3px); }
.btn--magenta .btn__arrow { background: var(--color-charcoal); color: var(--color-neon-magenta); }
.btn--solid .btn__arrow, .btn--onDark .btn__arrow { background: var(--color-bone); color: var(--color-void); }

/* ---------- nav ---------- */

.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  padding-block: var(--spacing-10);
  border-bottom: 1px solid transparent;
  transition: background-color .35s var(--ease-out), border-color .35s var(--ease-out);
}
.nav.is-stuck {
  background: rgba(243,243,239,.88);
  border-bottom-color: var(--line);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.nav__inner { display: flex; align-items: center; gap: var(--spacing-24); justify-content: space-between; }

.nav__brand { display: inline-flex; align-items: center; gap: var(--spacing-10); flex: none; }
.nav__brand-mark { font-family: var(--font-display); font-size: var(--text-subheading); letter-spacing: .02em; text-transform: uppercase; }

.nav__links { display: flex; align-items: center; gap: var(--spacing-24); }
.nav__link { position: relative; color: var(--text-muted); font-weight: var(--fw-semibold); transition: color .3s var(--ease-out); }
.nav__link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -6px; height: 2px;
  background: linear-gradient(90deg, var(--color-neon-magenta), var(--color-lavender, var(--color-neon-magenta)));
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .4s cubic-bezier(.22,.8,.32,1);
}
.nav__link:hover { color: var(--color-neon-magenta); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link.is-active { color: var(--color-neon-magenta); }
.nav__link.is-active::after { transform: scaleX(1); }
.nav__links .nav__cta { display: none; } /* mobile-menu only; shown in the 880px block */

.nav__right { display: inline-flex; align-items: center; gap: var(--spacing-18); flex: none; }
.nav__status { display: inline-flex; align-items: center; gap: var(--spacing-10); color: var(--text); }
.status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-ember-dot); flex: none; animation: pulse 2.4s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .3; transform: scale(.8); } }

.nav__toggle { display: none; }

/* ---------- hero ---------- */

.hero {
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding-block: 140px var(--spacing-60);
  position: relative;
}

.hero__ticker { margin-bottom: var(--spacing-30); color: var(--text); }

.wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  color: var(--text);
  line-height: 0.83;
  letter-spacing: -0.01em;
  font-size: clamp(84px, 24vw, 358px);
  margin: 0;
}
.wordmark em { font-style: normal; color: var(--color-neon-magenta); }

/* per-letter entrance */
.wordmark .ch {
  display: inline-block;
  transform: translateY(0.42em);
  opacity: 0;
  animation: charIn .9s var(--ease-out) forwards;
}
@keyframes charIn { to { transform: translateY(0); opacity: 1; } }

.hero__meta {
  display: flex; flex-wrap: wrap; gap: var(--spacing-30) var(--spacing-48);
  align-items: flex-end; justify-content: space-between;
  margin-top: var(--spacing-40);
}
.hero__since {
  color: var(--text-muted); max-width: 46ch;
  font-size: var(--text-subheading); line-height: var(--leading-subheading); letter-spacing: var(--tracking-subheading);
  font-weight: var(--fw-regular);
}
.hero__since strong { color: inherit; font-weight: inherit; }
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--spacing-12); }

/* elements that fade up once, on load, under the wordmark */
.hero__ticker, .hero__meta { animation: fadeUp .8s var(--ease-out) both; }
.hero__ticker { animation-delay: .05s; }
.hero__meta { animation-delay: 1.05s; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* ---------- sections ---------- */

.section { padding-block: var(--section-gap); }
.section__head { display: flex; flex-direction: column; gap: var(--spacing-20); margin-bottom: var(--spacing-48); }

.manifesto { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-48); }
/* all four paragraphs share one size/weight/colour -- no special
   treatment for the first or last one */
.manifesto p { font-size: var(--text-body); line-height: var(--leading-body); color: var(--text); }
.manifesto ul {
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: var(--spacing-6);
  font-size: var(--text-body); line-height: var(--leading-body); color: var(--text);
}
.manifesto ul li { display: flex; align-items: center; gap: var(--spacing-10); }
.manifesto ul li::before { content: "\2022"; color: var(--color-carbon, var(--text)); font-size: 1.5em; line-height: 1; flex: none; }
.manifesto > div { display: flex; flex-direction: column; gap: var(--spacing-10); }
.manifesto > div p { margin: 0; }

/* solid boxed card around the About manifesto text, matching the same
   card language used for the pillars and capability boxes elsewhere on
   the site (background, border, radius) rather than a decorative frame */
/* shared soft-lift shadow for the outer "block" containers (About text,
   Technical Service group, Contact) -- gives them the same quiet depth
   as a real card instead of sitting perfectly flat against the page */
.manifesto-frame, .capability-frame, .contact-frame {
  box-shadow: 0 1px 3px rgba(24, 25, 37, .07), 0 16px 40px -14px rgba(24, 25, 37, .22);
}

.manifesto-frame {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
}
.manifesto-frame__corner { display: none; }

@media (max-width: 640px) {
  .manifesto-frame { padding: var(--spacing-24); }
}

/* pillars */
.pillars { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--spacing-20); }
.pillar {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: var(--spacing-20);
  min-height: 320px;
  transition: transform .45s var(--ease-out), border-color .45s var(--ease-out);
}
.pillar:hover { transform: translateY(-6px); border-color: var(--line-strong); }
.pillar::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--color-neon-magenta);
  transform: scaleY(0); transform-origin: 50% 0;
  transition: transform .55s var(--ease-out);
}
.pillar.is-in::before { transform: scaleY(1); }
.pillar__n { font-family: var(--font-mono); font-size: var(--text-caption); font-weight: var(--fw-regular); letter-spacing: 0.10em; color: var(--text-muted); }
.pillar h3 { font-size: var(--text-heading-sm); line-height: var(--leading-heading-sm); letter-spacing: var(--tracking-heading-sm); }
.pillar p { color: var(--text-muted); }
.pillar .tagrow { margin-top: auto; }

.tagrow { display: flex; flex-wrap: wrap; gap: var(--spacing-6); }
.tag {
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: var(--fw-regular);
  letter-spacing: 0.05em; text-transform: uppercase;
  background: var(--color-void); color: var(--color-bone);
  border-radius: var(--radius-3xl); padding: var(--spacing-4) var(--spacing-12);
}
.tag--light { background: var(--color-parchment); color: var(--color-void); }

/* products */
.products { display: flex; flex-direction: column; gap: var(--spacing-20); }

.product {
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
  display: grid; grid-template-columns: minmax(0,1.05fr) minmax(0,1fr); gap: var(--spacing-48);
  position: relative; overflow: hidden;
  transition: transform .45s var(--ease-out);
}
.product:hover { transform: translateY(-5px); }

/* white card on the parchment canvas */
.product--light { background: var(--surface-1); color: var(--text); border: 1px solid var(--line); }
.product--light .muted { color: var(--text-muted); }

/* black contrast block — the "inverted" card of the light theme */
.product--dark { background: var(--surface-2); color: var(--color-bone); }
.product--dark .muted { color: var(--color-mist); }
.product--dark .tag { background: var(--color-bone); color: var(--color-void); }

.product__bar { position: absolute; left: 0; top: 0; bottom: 0; width: 6px; }

.product__head { display: flex; flex-direction: column; gap: var(--spacing-20); align-items: flex-start; }
.product__title {
  font-family: var(--font-display); text-transform: uppercase;
  font-size: clamp(42px, 7vw, 92px); line-height: .9; letter-spacing: -0.01em;
}
.product__lede { font-size: var(--text-subheading); line-height: var(--leading-subheading); letter-spacing: var(--tracking-subheading); }
.product__body { display: flex; flex-direction: column; gap: var(--spacing-20); }

.speclist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.speclist li {
  padding-block: var(--spacing-12);
  border-top: 1px solid var(--line);
  display: flex; gap: var(--spacing-12);
  font-size: var(--text-body-sm); line-height: 1.4; letter-spacing: var(--tracking-body-sm);
}
.product--dark .speclist li { border-color: var(--line-inverse); }
.speclist li::before { content: "\2192"; font-family: var(--font-mono); font-size: var(--text-tiny); opacity: .55; flex: none; }

/* flat data-viz artwork */
.artwork { display: grid; place-items: center; }
.artwork svg { width: 100%; height: auto; max-width: 380px; }
.artwork [data-draw] { transition: transform 1s var(--ease-out), opacity 1s ease; transform-origin: 50% 50%; }
.is-in .artwork [data-draw] { transform: none; opacity: 1; }
.artwork [data-draw] { transform: scale(.82); opacity: 0; }

/* ============ FAB TOOL ============ */

.fab {
  background: var(--surface-2);
  color: var(--color-bone);
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
  display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr);
  gap: var(--spacing-48);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* HD background photo, pushed low-contrast so it never competes with the
   form or the figures. Sits behind everything else via z-index; opacity
   and grayscale live on the image layer only, so the panel's own text
   contrast (checked separately) is completely unaffected. */
.fab > * { position: relative; z-index: 1; }
.fab .muted { color: var(--color-mist); }
.fab__intro { display: flex; flex-direction: column; gap: var(--spacing-20); }
.fab__intro h3 {
  font-family: var(--font-display); text-transform: uppercase;
  font-size: clamp(42px, 6vw, 72px); line-height: .9; letter-spacing: -0.01em;
}

.fab__form { display: flex; flex-direction: column; gap: var(--spacing-18); }
.fab__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-12); }

.fab .field { display: flex; flex-direction: column; gap: var(--spacing-6); }
.fab label { color: var(--color-mist); }
/* "Ink used / month (kg)" wraps to two lines while "Present rate (₹/kg)"
   fits on one, which pushed their inputs out of alignment in the grid --
   reserving two lines' height on every field label keeps every input
   starting at the same y regardless of how its own label wraps */
.fab__grid .field label { display: block; min-height: 2.5em; }

.fab .input {
  background: var(--color-parchment);
  border: 1px solid var(--color-ink);
  border-radius: var(--radius-full-3);
  padding: var(--spacing-12) var(--spacing-22);
  font-family: var(--font-mono); font-size: var(--text-body-sm); font-weight: var(--fw-regular);
  color: var(--color-ink);
  width: 100%;
  transition: box-shadow .25s ease;
}
.fab .input:focus { outline: none; box-shadow: 0 0 0 3px var(--color-neon-magenta); }

/* range sliders */
.fab .range { -webkit-appearance: none; appearance: none; width: 100%; height: 2px; background: var(--line-inverse); border-radius: 2px; margin-block: var(--spacing-14); }
.fab .range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--color-neon-magenta); cursor: pointer; border: none;
  transition: transform .2s var(--ease-out);
}
.fab .range::-webkit-slider-thumb:hover { transform: scale(1.25); }
.fab .range::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--color-neon-magenta); cursor: pointer; border: none;
}
.fab .range-label { display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-12); }
.fab .range-value { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--color-neon-magenta); letter-spacing: .05em; }

/* results */
.fab__out { display: flex; flex-direction: column; gap: var(--spacing-20); align-self: start; }

.fab__headline {
  border: 1px solid var(--line-inverse);
  border-radius: var(--radius-3xl);
  padding: var(--spacing-30);
  display: flex; flex-direction: column; gap: var(--spacing-6);
  position: relative; overflow: hidden;
}
.fab__headline::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
  background: var(--color-neon-magenta);
}
.fab__big {
  font-family: var(--font-display);
  font-size: clamp(42px, 6vw, 80px); line-height: 1; letter-spacing: -0.02em;
  color: var(--color-neon-magenta);
  font-variant-numeric: tabular-nums;
}

.fab__rows { display: flex; flex-direction: column; }
.fab__row {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-20);
  padding-block: var(--spacing-14);
  border-top: 1px solid var(--line-inverse);
}
.fab__row dt { color: var(--color-mist); font-size: var(--text-body-sm); letter-spacing: var(--tracking-body-sm); }
.fab__row dd {
  margin: 0; font-family: var(--font-mono); font-size: var(--text-body-sm);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.fab__row dd.pos { color: var(--color-neon-magenta); }
.fab__row dd.neg { color: var(--color-ember-dot); }
/* the calculation still runs on these (a visitor's total saving depends
   on them), they're just not worth a row each in the results list --
   "Ink spend now", "Saving on wastage" and "Total saving" tell the story
   on their own. Placed after .fab__row so it wins the display tie. */
.fab__row--extra { display: none; }

.fab__note { color: var(--color-mist); }

/* the number roll when a result changes */
.fab .flash { animation: flash .5s var(--ease-out); }
@keyframes flash { from { opacity: .25; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* capability strip */
/* outer block wrapping all four cards, so the group reads as one unit
   (matching the FAB Tool card) while each cell stays its own boxed card */
.capability-frame {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
}
.capability { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--spacing-20); }
.capability__cell {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
  display: flex; flex-direction: column; gap: var(--spacing-10);
  transition: transform .45s var(--ease-out), border-color .45s var(--ease-out);
}
.capability__cell:hover { transform: translateY(-6px); border-color: var(--line-strong); }
.capability__cell strong { font-size: var(--text-heading-sm); line-height: var(--leading-heading-sm); letter-spacing: var(--tracking-heading-sm); font-weight: 400; }
.capability__cell span { color: var(--text-muted); }

/* contact */
/* single outer block around the whole Contact section (details + form),
   same nested-card pattern as FAB Tool and Technical Service */
.contact-frame {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
}
.contact { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--spacing-48); align-items: stretch; }
/* the form column is a full-height flex column so it stretches down to the
   same bottom edge as the contact-info list on the left (levelling with
   the Phone row), with the submit button pinned to the bottom instead of
   sitting right under the fields -- and a hairline rule down the middle
   keeps the two columns visually separate instead of touching */
.contact > .form {
  height: 100%;
  padding-left: var(--spacing-48);
  border-left: 1px solid var(--line);
}
.contact > .form .form__actions { margin-top: auto; }
.contact > .form .field:last-of-type { flex: 1; }
.contact > .form .field:last-of-type .textarea { flex: 1; min-height: 132px; }
.contact > .form .field:last-of-type { display: flex; flex-direction: column; }
@media (max-width: 760px) {
  .contact > .form { padding-left: 0; border-left: none; height: auto; }
}

@media (max-width: 640px) {
  .contact-frame { padding: var(--spacing-20); }
}

/* compact desktop spacing so Contact fits closer to one screen, same
   idea as the FAB Tool compaction further down this file */
@media (min-width: 761px) {
  #contact .section__head { gap: var(--spacing-10); margin-bottom: var(--spacing-20); }
  #contact h2.display { font-size: clamp(28px, 3vw, 36px); max-width: 34ch; }
  #contact .contact { gap: var(--spacing-32); }
  #contact .contact__lines { gap: var(--spacing-14); }
  #contact .contact__line { gap: 2px; }
  #contact .form { gap: var(--spacing-8); }
  #contact .field { gap: 2px; }
  #contact .input, #contact .textarea { padding: 8px var(--spacing-16); }
  #contact .textarea { min-height: 90px; }
}
.contact__lines { display: flex; flex-direction: column; }
.contact__line { display: flex; flex-direction: column; gap: var(--spacing-6); }
.contact__line a, .contact__line .value {
  font-size: var(--text-body-sm); line-height: var(--leading-body-sm); letter-spacing: var(--tracking-body-sm);
  font-weight: 500;
  align-self: flex-start;
  color: var(--color-carbon, var(--text));
}
.contact__line a { border-bottom: 1px solid transparent; transition: border-color .25s ease, color .25s ease; }
.contact__line a:hover { border-bottom-color: var(--color-neon-magenta); color: var(--color-neon-magenta); }

.address-link {
  display: inline-flex; align-items: flex-start; gap: var(--spacing-10);
  color: var(--color-carbon, var(--text));
  font-size: var(--text-body-sm); line-height: var(--leading-body-sm); letter-spacing: var(--tracking-body-sm);
  font-weight: 500;
}

/* icon badges: every row in this block (Office, Hours, Email, Phone)
   follows the same icon + label + value pattern -- a big square icon,
   a bold label coloured to match its icon, plain dark text underneath,
   a hairline rule between rows -- so they're quick to tell apart at a
   glance and read as one consistent system rather than mono captions */
.contact__lines .contact__line--icon {
  /* the icon stretches to the full height of its row (address/hours/
     email/phone), instead of staying a fixed 52px square that floats
     small and off-centre next to a taller 3-line block -- so it always
     fills the row it sits in, whatever that row's own content is */
  flex-direction: row; align-items: stretch; gap: var(--spacing-40);
  padding-block: var(--spacing-18);
  border-top: 1px solid var(--line);
}
.contact__lines .contact__line--icon:first-child { border-top: none; padding-top: 0; }
.contact__lines .contact__line--icon:last-child { padding-bottom: 0; }
.contact__icon {
  flex: none;
  width: 52px; min-height: 52px;
  display: grid; place-items: center;
  border-radius: var(--radius-2xl);
}
.contact__icon svg { width: 26px; height: 26px; }
.contact__icon--address { background: var(--color-lavender, var(--brand-red)); }
.contact__icon--hours   { background: var(--color-amber, var(--brand-yellow)); }
.contact__icon--email   { background: var(--color-neon-magenta); }
.contact__icon--phone   { background: var(--color-mint, var(--brand-yellow)); }

.contact__label { display: block; font-weight: var(--fw-semibold); margin-bottom: 2px; }
.contact__label--address { color: var(--color-lavender, var(--brand-red)); }
.contact__label--hours   { color: var(--color-amber, var(--brand-yellow)); }
.contact__label--email   { color: var(--color-neon-magenta); }
.contact__label--phone   { color: var(--color-mint, var(--brand-yellow)); }

.form { display: flex; flex-direction: column; gap: var(--spacing-12); }
.form__hint {
  font-family: var(--font-body);
  color: var(--text-muted);
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  margin: 0 0 var(--spacing-6);
}
.field__optional { font-weight: var(--fw-regular); color: var(--text-muted); text-transform: none; letter-spacing: normal; }
.field { display: flex; flex-direction: column; gap: var(--spacing-6); }
.input, .textarea {
  background: var(--color-bone);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full-3);
  padding: var(--spacing-14) var(--spacing-22);
  font-family: var(--font-mono); font-size: var(--text-body-sm); font-weight: var(--fw-regular);
  color: var(--color-ink);
  width: 100%;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.input:focus, .textarea:focus { outline: none; border-color: var(--color-void); box-shadow: 0 0 0 3px rgba(252,116,221,.5); }

/* the contact form now matches the plain, professional style of the
   Works & Office / Email / Phone rows next to it -- regular sans-serif
   labels and inputs, not the uppercase monospace used for the FAB
   calculator's more technical feel (which keeps its own mono inputs) */
.field__label {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-carbon, var(--text));
  text-transform: none;
  letter-spacing: normal;
}
#contact .input, #contact .textarea { font-family: var(--font-body); }
.textarea { border-radius: var(--radius-2xl); min-height: 132px; resize: vertical; }
.input::placeholder, .textarea::placeholder { color: #9a978f; }
.form__note { color: var(--text-muted); }
.form__note--ok { color: var(--color-mint, #2e9b4f); }
.form__note--error { color: var(--color-ember-dot, #d64545); }
.form__actions { display: flex; align-items: center; gap: var(--spacing-18); flex-wrap: wrap; margin-top: var(--spacing-6); }

/* marquee band */
.band { border-block: 1px solid var(--line); padding-block: var(--spacing-18); overflow: hidden; background: var(--surface-1); }
.band__track { display: flex; gap: var(--spacing-48); width: max-content; animation: slide 42s linear infinite; }
.band:hover .band__track { animation-play-state: paused; }
.band__track span { color: var(--text); white-space: nowrap; font-weight: var(--fw-semibold); }
.band__track span b { color: var(--text); font-weight: var(--fw-semibold); }
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* footer */
.footer { border-top: 1px solid var(--line); padding-block: var(--spacing-48); }
.footer__inner { display: flex; flex-wrap: wrap; gap: var(--spacing-24); justify-content: space-between; align-items: center; }
.footer__links { display: flex; flex-wrap: wrap; gap: var(--spacing-24); }
.footer__links a { color: var(--text-muted); transition: color .25s ease; }
.footer__links a:hover { color: var(--text); }

/* ---------- reveal ----------
   Progressive enhancement: content is visible by default, and only hidden
   once JS has confirmed it can observe and un-hide it again. */
.js-anim .reveal { opacity: 0; transform: translateY(24px); transition: opacity .8s ease, transform .8s var(--ease-out); }
.js-anim .reveal.is-in { opacity: 1; transform: none; }
.js-anim .reveal[data-delay="1"] { transition-delay: .10s; }
.js-anim .reveal[data-delay="2"] { transition-delay: .20s; }
.js-anim .reveal[data-delay="3"] { transition-delay: .30s; }

/* ---------- responsive ---------- */

@media (max-width: 1080px) {
  .capability { grid-template-columns: repeat(2, 1fr); }
  .pillars { grid-template-columns: 1fr; }
  .pillar { min-height: 0; }
}

@media (max-width: 880px) {
  :root { --gutter: 20px; --section-gap: 60px; --card-padding: 30px; }
  .nav__links {
    position: fixed; inset: 0;
    flex-direction: column; justify-content: center; gap: var(--spacing-30);
    background: var(--canvas);
    opacity: 0; pointer-events: none; transition: opacity .35s var(--ease-out);
  }
  .nav__links.is-open { opacity: 1; pointer-events: auto; }
  .nav__toggle { display: inline-flex; }
  .nav__status, .nav__cta { display: none; }
  .nav__links .nav__cta { display: inline-flex; margin-top: var(--spacing-12); }
  /* minmax(0, 1fr), not a bare 1fr -- a plain fr track's minimum width
     defaults to auto (its content's min-content size), so unbreakable
     content (an email row, an address link) could still force the
     track wider than the viewport and overflow the page */
  .manifesto, .product, .contact, .fab { grid-template-columns: minmax(0, 1fr); }
  .hero { min-height: 92svh; padding-block: 120px var(--spacing-40); }
  .artwork { order: -1; }
  /* iOS Safari auto-zooms the page on focus if an input's font-size is
     under 16px; the desktop 14px is kept, this only raises it on phones */
  .input, .textarea { font-size: 16px; }

  /* FAB TOOL — same compaction idea as the desktop rules further down,
     scaled for a phone: the accordion keeps the F/A/B explainer out of
     the way by default, and everything else loses spacing (not content)
     so the card is as short as a phone screen can make it. */
  #fab.section { padding-block: calc(var(--section-gap) * .6); }
  #fab .section__head { gap: var(--spacing-8); margin-bottom: var(--spacing-20); }
  #fab h2.display { font-size: clamp(26px, 7vw, 34px); }
  #fab .fab { gap: var(--spacing-20); padding: calc(var(--card-padding) * .7); }
  #fab .fab__intro { gap: var(--spacing-6); }
  #fab .fab__form { gap: var(--spacing-12); }
  #fab .fab__grid { gap: var(--spacing-10); }
  #fab .fab .input { padding: var(--spacing-10) var(--spacing-16); }
  #fab .fab__out { gap: var(--spacing-12); }
  #fab .fab__headline { padding: var(--spacing-16); }
  #fab .fab__big { font-size: clamp(30px, 9vw, 40px); }
}

@media (max-width: 520px) {
  /* keep the 2x2 grid (01/02 on one row, 03/04 on the next) instead of
     stacking all four into one column, so it reads as two neat frames */
  .capability-frame { padding: var(--spacing-16); }
  .capability { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-14); }
  .capability__cell { padding: var(--spacing-14); min-width: 0; }
  .capability__cell strong { font-size: var(--text-body); line-height: 1.2; }
  .capability__icon { width: 32px; height: auto; }
  .fab__grid { grid-template-columns: 1fr; }
}

/* ============================================================
   INTERACTION LAYER
   Everything below responds to the visitor while they use the
   page — pointer, hover, click, focus. All of it is additive:
   JS attaches it only on a fine pointer with motion allowed, so
   touch and reduced-motion users get the plain static page.
   ============================================================ */

/* ---------- click ripple ---------- */

.ripple {
  position: absolute;
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  background: currentColor;
  opacity: .25;
  pointer-events: none;
  animation: ripple .55s var(--ease-out) forwards;
}
@keyframes ripple { to { transform: translate(-50%, -50%) scale(1); opacity: 0; } }

/* ---------- word-by-word headline reveal ---------- */

/* The clipping box has to reach BELOW the baseline, or overflow:hidden
   shears the descenders off y, p, g, j at line-height 1. The padding
   grows the mask; the negative margin cancels it again so line spacing
   is untouched. The inner span must then travel further than 100% to
   stay hidden behind the enlarged mask. */
.js-anim .word {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-block: 0.16em 0.30em;
  margin-block: -0.16em -0.30em;
}
.js-anim .word > span {
  display: inline-block;
  transform: translateY(150%);
  transition: transform .8s var(--ease-out);
}
.js-anim .is-in .word > span { transform: none; }

/* ---------- tags pop on hover ---------- */

.tag { transition: transform .25s var(--ease-out), background-color .25s ease, color .25s ease; }
.tag:hover { transform: translateY(-2px); background: var(--color-neon-magenta); color: var(--color-charcoal); }

/* ---------- spec rows wipe in on hover ---------- */

.speclist li { position: relative; transition: padding-left .3s var(--ease-out); }
.speclist li::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--color-neon-magenta);
  transform: scaleY(0); transform-origin: 50% 100%;
  transition: transform .3s var(--ease-out);
}
.speclist li:hover { padding-left: var(--spacing-10); }
.speclist li:hover::after { transform: scaleY(1); }

/* ---------- inputs ---------- */

.field > label { transition: color .25s ease, transform .25s var(--ease-out); transform-origin: 0 50%; }
.field:focus-within > label { color: var(--color-neon-magenta); transform: translateX(3px); }

/* range track fills with magenta up to the thumb (set from JS) */
.fab .range { background-image: linear-gradient(var(--color-neon-magenta), var(--color-neon-magenta)); background-repeat: no-repeat; background-size: 0% 100%; }

/* ---------- copy-to-clipboard feedback ---------- */

.contact__line a[data-copy] { position: relative; }
.copied {
  position: absolute; left: 100%; top: 50%;
  transform: translate(8px, -50%);
  white-space: nowrap;
  background: var(--color-void); color: var(--color-bone);
  border-radius: var(--radius-3xl); padding: 3px 12px;
  font-family: var(--font-mono); font-size: var(--text-tiny); letter-spacing: .08em; text-transform: uppercase;
  animation: copied 1.6s var(--ease-out) forwards;
  pointer-events: none;
}
@keyframes copied {
  0% { opacity: 0; transform: translate(0, -50%); }
  15%, 70% { opacity: 1; transform: translate(8px, -50%); }
  100% { opacity: 0; transform: translate(8px, -50%); }
}

/* ---------- back to top ---------- */

.totop {
  position: fixed; right: var(--gutter); bottom: var(--spacing-30); z-index: 70;
  width: 52px; height: 52px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-void); color: var(--color-bone);
  border: none; cursor: pointer;
  opacity: 0; transform: translateY(16px) scale(.85); pointer-events: none;
  transition: opacity .4s var(--ease-out), transform .4s var(--ease-out), background-color .3s ease, color .3s ease;
}
.totop.is-shown { opacity: 1; transform: none; pointer-events: auto; }
.totop:hover { background: var(--color-neon-magenta); color: var(--color-charcoal); transform: translateY(-3px); }

/* the follower and tilt are pointless without a real pointer */

/* ============================================================
   BRAND — sampled from assets/kdink-logo.png
   These three colours are the company's own. They are used with
   intent in the About section, which is the one place on the page
   that is meant to feel like the brand rather than the product.
   The rest of the site keeps the restrained system palette so the
   colour here reads as deliberate.
   ============================================================ */

:root {
  --brand-red: #b63437;
  --brand-red-deep: #8e2528;
  --brand-yellow: #edd22f;
  --brand-yellow-deep: #d9bd18;
  --brand-graphite: #3a3a3a;
}

/* ---------- logo lockup ---------- */

.brandbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-40);
  justify-content: space-between;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-3xl);
  padding: var(--spacing-40) var(--card-padding);
  margin-bottom: var(--spacing-48);
  position: relative; overflow: hidden;
}
/* the brand's own red and yellow, as a rule down the edge */
.brandbar::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 10px;
  background: linear-gradient(var(--brand-red) 0 50%, var(--brand-yellow) 50% 100%);
}
.brandbar__logo { flex: 1 1 340px; max-width: 460px; }
.brandbar__logo img { width: 100%; height: auto; }
.brandbar__meta { display: flex; flex-direction: column; gap: var(--spacing-10); text-align: right; }
.brandbar__meta .mono { color: var(--brand-red); }
.brandbar__meta p { color: var(--text-muted); font-size: var(--text-body-sm); line-height: 1.5; }

/* ---------- stats ---------- */

.stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--spacing-12);
  margin-bottom: var(--spacing-48);
}
.stat {
  border-radius: var(--radius-2xl);
  padding: var(--spacing-30);
  display: flex; flex-direction: column; gap: var(--spacing-6);
  min-height: 150px; justify-content: flex-end;
  transition: transform .45s var(--ease-out);
}
.stat:hover { transform: translateY(-5px); }
.stat__n {
  font-family: var(--font-display);
  font-size: clamp(35px, 4.5vw, 60px); line-height: .95; letter-spacing: -0.02em;
}
.stat__n sup { font-size: .45em; vertical-align: super; }

.stat--red    { background: var(--brand-red);      color: var(--color-bone); }
.stat--yellow { background: var(--brand-yellow);   color: var(--color-void); }
.stat--ink    { background: var(--brand-graphite); color: var(--color-bone); }
.stat--outline{ background: transparent; color: var(--text); border: 1px solid var(--line-strong); }
.stat--outline .stat__n { font-size: clamp(28px, 3.4vw, 44px); }

/* ---------- pillars, in brand colour ----------
   These override the shared .pillar surface. The magenta accent bar
   is replaced by each card's own darker shade of itself. */

.pillar--red    { background: var(--brand-red);      color: var(--color-bone); border-color: transparent; }
.pillar--yellow { background: var(--brand-yellow);   color: var(--color-void); border-color: transparent; }
.pillar--ink    { background: var(--brand-graphite); color: var(--color-bone); border-color: transparent; }

.pillar--red::before    { background: var(--brand-yellow); }
.pillar--yellow::before { background: var(--brand-red); }
.pillar--ink::before    { background: var(--brand-yellow); }

.pillar--red .pillar__n,
.pillar--ink .pillar__n { color: rgba(255,255,255,.88); } /* .72 failed AA on the red */
.pillar--yellow .pillar__n { color: rgba(0,0,0,.6); }

.pillar--red p, .pillar--ink p { color: rgba(255,255,255,.86); }
.pillar--yellow p { color: rgba(0,0,0,.78); }

.pillar--red .tag, .pillar--ink .tag { background: rgba(255,255,255,.14); color: var(--color-bone); }
.pillar--yellow .tag { background: rgba(0,0,0,.1); color: var(--color-void); }

.pillar--red .tag:hover    { background: var(--brand-yellow); color: var(--color-void); }
.pillar--ink .tag:hover    { background: var(--brand-yellow); color: var(--color-void); }
.pillar--yellow .tag:hover { background: var(--brand-red); color: var(--color-bone); }

/* ---------- vision & mission ---------- */

.vm { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-12); margin-top: var(--spacing-48); }
.vm__card {
  border-radius: var(--radius-3xl);
  padding: var(--card-padding);
  display: flex; flex-direction: column; gap: var(--spacing-18);
  position: relative; overflow: hidden;
  transition: transform .45s var(--ease-out);
}
.vm__card:hover { transform: translateY(-5px); }
.vm__card p { font-size: var(--text-subheading); line-height: var(--leading-subheading); letter-spacing: var(--tracking-subheading); }

.vm__card--red { background: var(--brand-red-deep); color: var(--color-bone); }
.vm__card--red .mono { color: var(--brand-yellow); }
.vm__card--yellow { background: var(--brand-yellow); color: var(--color-void); }
.vm__card--yellow .mono { color: var(--brand-red-deep); }

/* the cursor ring has to invert over the dark brand blocks too */

@media (max-width: 1080px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 880px) {
  .vm { grid-template-columns: 1fr; }
  .brandbar { padding: var(--spacing-30); gap: var(--spacing-24); }
  .brandbar__meta { text-align: left; }
}
@media (max-width: 520px) {
  .stats { grid-template-columns: 1fr; }
  .stat { min-height: 0; }
}

/* ============================================================
   HERO LOGO
   The logo image is now the hero, in place of the type wordmark.
   Three things run on it: a wipe-in reveal, a slow float so it
   never sits dead on the page, and a light sweep that crosses the
   artwork on a loop. The sweep is masked by the logo itself, so it
   only lights the red block and the yellow script — never the
   transparent area around them.
   ============================================================ */

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.hero__logo { margin: 0; line-height: 0; }

.hero__logo-frame {
  position: relative;
  display: block;
  width: min(100%, 860px);
  animation: logoWipe 1.25s var(--ease-out) both, logoFloat 7s ease-in-out 1.3s infinite;
}
.hero__logo-frame img { width: 100%; height: auto; }

@keyframes logoWipe {
  from { clip-path: inset(0 100% 0 0); opacity: 0; transform: scale(.985); }
  to   { clip-path: inset(0 0 0 0);    opacity: 1; transform: none; }
}
@keyframes logoFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

/* the travelling highlight, clipped to the logo artwork */
.hero__shine {
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg,
    transparent 42%,
    rgba(255,255,255,.9) 50%,
    transparent 58%);
  background-size: 260% 100%;
  background-repeat: no-repeat;
  -webkit-mask-image: url("assets/kdink-logo-web.png");
          mask-image: url("assets/kdink-logo-web.png");
  -webkit-mask-size: 100% 100%;  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  animation: logoShine 6s ease-in-out 1.6s infinite;
}
@keyframes logoShine {
  0%        { background-position: 190% 0; }
  55%, 100% { background-position: -90% 0; }
}

/* a brand rule that draws itself in under the logo */
.hero__logo::after {
  content: "";
  display: block;
  height: 6px; width: min(100%, 860px);
  margin-top: var(--spacing-24);
  border-radius: 6px;
  background: linear-gradient(90deg, var(--brand-red) 0 50%, var(--brand-yellow) 50% 100%);
  transform-origin: 0 50%;
  animation: ruleIn 1s var(--ease-out) .9s both;
}
@keyframes ruleIn { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* the hero paragraph followed the old letter animation's timing */
.hero__meta { animation-delay: 1.15s; }

@media (prefers-reduced-motion: reduce) {
  .hero__logo-frame { animation: none; }
  .hero__shine { display: none; }
  .hero__logo::after { animation: none; }
}

@media (max-width: 880px) {
  .hero__logo-frame, .hero__logo::after { width: 100%; }
}

/* ============================================================
   TOP STRIP + NAV MARK
   The marquee strip now sits at the very top of the document,
   above the navigation. The nav is sticky rather than fixed, so
   it sits under the strip at rest and takes over the top edge
   once the strip has scrolled away.
   ============================================================ */

.band {
  position: relative;
  z-index: 61;
  background: var(--color-void);
  border-top: none;
  border-bottom: 1px solid var(--color-void);
}
.band__track span { color: var(--color-mist); font-weight: var(--fw-semibold); }
.band__track span b { color: var(--color-mist); font-weight: var(--fw-semibold); }

/* nav sits in the flow now, and sticks once the strip is gone */
.nav {
  position: sticky;
  top: 0;
  inset-inline: auto;
}

/* the logo mark replaces the wordmark text in the bar */
.nav__mark {
  height: 30px;
  width: auto;
  display: block;
}
.nav__brand { gap: var(--spacing-12); }

/* the hero no longer has to clear a fixed bar; --chrome-h is the
   measured height of the strip plus the nav, set from main.js */
.hero {
  padding-block: var(--spacing-60) var(--spacing-60);
  min-height: calc(100svh - var(--chrome-h, 120px));
}

@media (max-width: 880px) {
  .nav__mark { height: 26px; }
  .hero { min-height: calc(88svh - var(--chrome-h, 110px)); }
  /* the full-screen mobile menu must clear the strip and the bar */
  .nav__links { top: var(--chrome-h, 120px); height: auto; bottom: 0; inset-inline: 0; }
}

/* ------------------------------------------------------------
   Nav collapse.
   Seven links plus the clock, the CTA and the logo mark stop
   fitting well before the 880px layout breakpoint, so the menu
   collapses on its own schedule.
   ------------------------------------------------------------ */

@media (max-width: 1100px) {
  .nav__links {
    position: fixed;
    top: var(--chrome-h, 116px); bottom: 0; inset-inline: 0;
    flex-direction: column; justify-content: center; gap: var(--spacing-30);
    background: var(--canvas);
    opacity: 0; pointer-events: none;
    transition: opacity .35s var(--ease-out);
    overflow-y: auto;
  }
  .nav__links.is-open { opacity: 1; pointer-events: auto; }
  .nav__toggle { display: inline-flex; }
  .nav__status, .nav__cta { display: none; }
  .nav__links .nav__cta { display: inline-flex; margin-top: var(--spacing-12); }
}

/* ============================================================
   NAV — horizontal at every width, no hamburger.
   These rules deliberately come last so they beat the earlier
   collapse blocks. The row wraps onto a second line on narrow
   screens instead of hiding behind a button.
   ============================================================ */

.nav__toggle { display: none !important; }

.nav__links,
.nav__links.is-open {
  position: static;
  inset: auto;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--spacing-20);
  background: transparent;
  opacity: 1;
  pointer-events: auto;
  overflow: visible;
  height: auto;
}
.nav__links .nav__cta { display: none !important; }
.nav__links .nav__link { font-size: var(--text-caption); letter-spacing: 0.10em; }

.nav__inner { flex-wrap: wrap; row-gap: var(--spacing-6); }

@media (max-width: 1100px) {
  .nav__status, .nav__right .nav__cta { display: none; }
  .nav__links { gap: var(--spacing-18); }
}

@media (max-width: 820px) {
  /* tighten the row so it holds two lines at most on a phone */
  .nav__links { gap: var(--spacing-12); justify-content: flex-start; }
  .nav__links .nav__link {
    font-size: var(--text-tiny); letter-spacing: 0.06em;
    /* vertical padding grows the tap target toward Apple/Android's
       ~44px touch-target guideline and is left uncompensated so
       wrapped rows push apart instead of overlapping; only the
       horizontal margin cancels out, since side-by-side items on
       the same row don't have that overlap risk */
    padding: 12px 8px; margin: 0 -8px;
    display: inline-block;
  }
  .nav__inner { gap: var(--spacing-10); }
  .nav__mark { height: 24px; }
}

@media (max-width: 420px) {
  .nav__links { gap: var(--spacing-10); }
  .nav__links .nav__link {
    font-size: var(--text-micro); letter-spacing: 0.04em;
    padding: 10px 6px; margin: 0 -6px;
  }
}

/* ============================================================
   FOOTER
   ============================================================ */

.footer {
  border-top: none;
  background: var(--color-void);
  color: var(--color-bone);
  padding-block: var(--spacing-60) var(--spacing-30);
  margin-top: var(--section-gap);
}

.footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr);
  gap: var(--spacing-48);
  align-items: start;
}

.footer__brand { display: flex; flex-direction: column; gap: var(--spacing-24); }
.footer__logo {
  width: min(100%, 300px); height: auto;
  /* the logo is drawn for a light ground; a soft plate keeps the
     red block from vibrating against pure black */
  background: var(--color-bone);
  border-radius: var(--radius-2xl);
  padding: var(--spacing-18) var(--spacing-20);
}
.footer__tag { color: var(--color-mist); font-size: var(--text-body-sm); line-height: 1.6; max-width: 42ch; }

.footer__cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--spacing-30); }
.footer__cols--single { grid-template-columns: minmax(0, 320px); justify-content: end; }
.footer__col { display: flex; flex-direction: column; gap: var(--spacing-12); }
.footer__h { color: var(--brand-yellow); margin-bottom: var(--spacing-4); }
.footer__col a {
  color: var(--color-mist);
  font-size: var(--text-body-sm); line-height: 1.5; letter-spacing: var(--tracking-body-sm);
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition: color .25s ease, border-color .25s ease, transform .25s var(--ease-out);
}
.footer__col a:hover {
  color: var(--color-bone);
  border-bottom-color: var(--brand-yellow);
  transform: translateX(3px);
}

.footer__rule {
  height: 4px; border-radius: 4px;
  margin-block: var(--spacing-48) var(--spacing-24);
  background: linear-gradient(90deg, var(--brand-red) 0 50%, var(--brand-yellow) 50% 100%);
}

.footer__bottom {
  display: flex; flex-wrap: wrap; gap: var(--spacing-12) var(--spacing-24);
  justify-content: space-between; align-items: center;
  color: var(--color-mist);
}
.footer__top-link { color: var(--color-bone); transition: color .25s ease; }
.footer__top-link:hover { color: var(--brand-yellow); }

/* the cursor ring inverts over the black footer */
.footer { --footer-dark: 1; }

@media (max-width: 880px) {
  .footer__top { grid-template-columns: 1fr; gap: var(--spacing-40); }
  .footer__cols { grid-template-columns: 1fr 1fr; gap: var(--spacing-24); }
  .footer__cols--single { grid-template-columns: minmax(0, 1fr); justify-content: start; }
  .footer__bottom { justify-content: flex-start; }
}
@media (max-width: 520px) {
  .footer__cols { grid-template-columns: 1fr; }
}

/* ============================================================
   DARK SURFACES — oxblood instead of black
   Every black or graphite box is replaced by a deep red-brown
   pulled from the logo. It still reads as "ink", it keeps the
   yellow bright on top of it, and it stops the page looking like
   a black-and-white template. Body TYPE stays black; only the
   boxes change.

   A very slow gradient drift runs across the large panels so the
   colour is never flat. 28 seconds per cycle, low contrast: it
   should register as depth, not as movement.
   ============================================================ */

:root {
  --ink-deep: #3f1114;   /* strip, footer, third pillar/stat */
  --ink:      #57181c;   /* product cards, FAB panel, tags, solid buttons */
  --ink-soft: #6d2126;   /* hover lift on the above */

  /* .product--dark and .fab read this token */
  --surface-2: var(--ink);
}

/* ---- large panels: colour + slow wash ---- */

.fab,
.footer,
.product--dark {
  background-color: var(--ink);
  background-image:
    radial-gradient(120% 85% at 8% 0%,   rgba(237,210,47,.13), transparent 62%),
    radial-gradient(110% 80% at 92% 100%, rgba(182,52,55,.42), transparent 62%);
  background-size: 200% 200%;
  background-repeat: no-repeat;
  animation: inkDrift 28s ease-in-out infinite alternate;
}
.footer { background-color: var(--ink-deep); }

@keyframes inkDrift {
  from { background-position:  0%  0%, 100% 100%; }
  to   { background-position: 34% 22%,  66%  78%; }
}

@media (prefers-reduced-motion: reduce) {
  .fab, .footer, .product--dark { animation: none; }
}

/* ---- the strip ---- */

.band {
  background: var(--ink-deep);
  border-bottom-color: var(--ink-deep);
}

/* ---- the formerly graphite pillar and stat ---- */

.pillar--ink { background: var(--ink-deep); }
.stat--ink   { background: var(--ink-deep); }

/* ---- small black elements ---- */

.tag                     { background: var(--ink); }
.btn--solid              { background: var(--ink); }
.btn--solid:hover        { background: var(--brand-yellow); color: var(--color-void); }
.btn__arrow              { background: var(--ink); color: var(--color-bone); }
.btn--magenta            { background: var(--brand-yellow); color: var(--ink); }
.btn--magenta:hover      { background: var(--ink); color: var(--brand-yellow); }
.btn--magenta .btn__arrow{ background: var(--ink); color: var(--brand-yellow); }
.btn--magenta:hover .btn__arrow { background: var(--brand-yellow); color: var(--ink); }

/* the light product card keeps a dark pill, now oxblood */
.product--light .tag { background: var(--ink); color: var(--color-bone); }

/* ---- accents that sat on black ---- */

.pillar--ink::before { background: var(--brand-yellow); }
.vm__card--red       { background: var(--ink); }
.vm__card--red .mono { color: var(--brand-yellow); }

/* ---- hover warms the dark boxes rather than only lifting ---- */

.product--dark, .pillar--ink, .stat--ink, .vm__card--red {
  transition: background-color .5s var(--ease-out), transform .45s var(--ease-out);
}
.pillar--ink:hover, .stat--ink:hover, .vm__card--red:hover { background-color: var(--ink-soft); }

/* ---- scroll progress + status dot read better in brand colour ---- */

.progress { background: var(--brand-yellow); }

/* ---- misc black references ---- */

:focus-visible   { outline-color: var(--ink); }
.input, .textarea{ border-color: var(--ink); }
.totop           { background: var(--ink); }
.totop:hover     { background: var(--brand-yellow); color: var(--ink); }
::selection      { background: var(--brand-yellow); color: var(--ink); }

/* ============================================================
   RETIRING THE MAGENTA
   The magenta was the Datalands accent. Now that the surfaces are
   oxblood and the palette is the company's own red and yellow, it
   is the only colour on the page that belongs to nobody. It is
   replaced contextually, because one colour cannot serve both
   grounds: YELLOW on the dark panels, BRAND RED on the parchment.
   ============================================================ */

/* ---- on the dark panels: yellow ---- */

.fab .input:focus              { box-shadow: 0 0 0 3px var(--brand-yellow); }
.fab .range                    { background-image: linear-gradient(var(--brand-yellow), var(--brand-yellow)); }
.fab .range::-webkit-slider-thumb { background: var(--brand-yellow); }
.fab .range::-moz-range-thumb  { background: var(--brand-yellow); }
.fab .range-value              { color: var(--brand-yellow); }
.fab .field:focus-within > label { color: var(--brand-yellow); }
.fab__headline::after          { background: var(--brand-yellow); }
.fab__big                      { color: var(--brand-yellow); }
.fab__row dd.pos               { color: var(--brand-yellow); }
.btn--onDark:hover             { background: var(--brand-yellow); color: var(--ink); border-color: var(--brand-yellow); }
.product--dark .tag:hover      { background: var(--brand-yellow); color: var(--ink); }

/* ---- on the parchment canvas: brand red ---- */

.skip-link                     { background: var(--brand-red); color: var(--color-bone); }
.nav__link.is-active::after    { background: var(--brand-red); }
.contact__line a:hover         { border-bottom-color: var(--brand-red); color: var(--brand-red); }
.contact .field:focus-within > label { color: var(--brand-red); }
.input:focus, .textarea:focus  { border-color: var(--brand-red); box-shadow: 0 0 0 3px rgba(182,52,55,.30); }
.tag:hover                     { background: var(--brand-red); color: var(--color-bone); }

/* ============================================================
   UGLYCASH PALETTE — BACKGROUNDS ONLY
   Surface colours taken from DESIGN (1).md. Text content, fonts,
   type scale, radii, spacing, layout and animation are untouched.

   Mapping:
     page canvas   -> Paper Cream      #f2f2f2
     white cards   -> Card White       #ffffff  (already)
     dark panels   -> Surface Graphite #3a3a3a
     accent card 1 -> Riot Pink        #fa00ff
     accent card 2 -> Toxic Lime       #adff02
     accent card 3 -> Voltage Cyan     #02bbff
     tinted panel  -> Sticker Khaki    #e7e3bf

   Text colour is changed ONLY where a saturated fill demands it.
   The theme's own rule: "black text on saturated fills, white text
   only on #000100/#3a3a3a panels". White type on lime or pink is
   unreadable, so those cards flip to black type.
   ============================================================ */

:root {
  --color-paper-cream:      #f2f2f2;
  --color-card-white:       #ffffff;
  --color-surface-graphite: #3a3a3a;
  --color-sticker-khaki:    #e7e3bf;
  --color-riot-pink:        #fa00ff;
  --color-voltage-cyan:     #02bbff;
  --color-toxic-lime:       #adff02;

  --canvas:    var(--color-paper-cream);
  --surface-1: var(--color-card-white);
  --surface-2: var(--color-surface-graphite);

  --ink:      var(--color-surface-graphite);
  --ink-deep: var(--color-surface-graphite);
  --ink-soft: #4a4a4a;
}

/* ---- panels ---- */

.band,
.footer,
.fab,
.product--dark { background-color: var(--color-surface-graphite); }

.product--light { background-color: var(--color-card-white); }
.pillar         { background-color: var(--color-card-white); }

/* the drift wash re-mixed for graphite: neutral, so the panel is
   never flat but the colour stays the theme's */
.fab, .footer, .product--dark {
  background-image:
    radial-gradient(120% 85% at 8% 0%,    rgba(255,255,255,.10), transparent 60%),
    radial-gradient(110% 80% at 92% 100%, rgba(0,0,0,.28),       transparent 62%);
}

/* ---- accent cards ---- */

.pillar--red    { background-color: var(--color-riot-pink);        color: #000; }
.pillar--yellow { background-color: var(--color-toxic-lime);       color: #000; }
.pillar--ink    { background-color: var(--color-surface-graphite); color: #fff; }

.stat--red      { background-color: var(--color-riot-pink);        color: #000; }
.stat--yellow   { background-color: var(--color-toxic-lime);       color: #000; }
.stat--ink      { background-color: var(--color-surface-graphite); color: #fff; }

.vm__card--red    { background-color: var(--color-voltage-cyan);  color: #000; }
.vm__card--yellow { background-color: var(--color-sticker-khaki); color: #000; }

/* type that sat on the old dark reds and must now read on a saturated fill */
.pillar--red .pillar__n,
.pillar--yellow .pillar__n { color: rgba(0,0,0,.68); }
.pillar--red p,
.pillar--yellow p          { color: rgba(0,0,0,.80); }
.pillar--ink .pillar__n    { color: rgba(255,255,255,.88); }
.pillar--ink p             { color: rgba(255,255,255,.86); }
.vm__card--red .mono       { color: rgba(0,0,0,.70); }
.vm__card--yellow .mono    { color: rgba(0,0,0,.70); }

/* pills sitting on a saturated card need a solid ground */
.pillar--red .tag,
.pillar--yellow .tag       { background: var(--color-card-white); color: #000; }
.pillar--red .tag:hover,
.pillar--yellow .tag:hover { background: #000; color: var(--color-card-white); }
.pillar--ink .tag          { background: rgba(255,255,255,.16); color: #fff; }
.pillar--ink .tag:hover    { background: var(--color-toxic-lime); color: #000; }

/* ---- accent bars on the product cards ---- */

#coldset  .product__bar { background: var(--color-riot-pink) !important; }
#sheetfed .product__bar { background: var(--color-voltage-cyan) !important; }
#heatset  .product__bar { background: var(--color-toxic-lime) !important; }

/* ---- small surfaces ---- */

.tag                 { background: var(--color-surface-graphite); }
.tag:hover           { background: var(--color-toxic-lime); color: #000; }
.product--light .tag { background: var(--color-surface-graphite); color: #fff; }
.btn--solid          { background: var(--color-surface-graphite); color: #fff; }
.btn--solid:hover    { background: var(--color-toxic-lime); color: #000; }
.btn__arrow          { background: var(--color-surface-graphite); color: #fff; }
.btn--magenta        { background: var(--color-toxic-lime); color: #000; }
.btn--magenta:hover  { background: var(--color-surface-graphite); color: #fff; }
.btn--magenta .btn__arrow { background: #000; color: var(--color-toxic-lime); }
.btn--magenta:hover .btn__arrow { background: var(--color-toxic-lime); color: #000; }
.btn--onDark:hover   { background: var(--color-toxic-lime); color: #000; border-color: var(--color-toxic-lime); }

.skip-link           { background: var(--color-toxic-lime); color: #000; }
.totop               { background: var(--color-surface-graphite); color: #fff; }
.totop:hover         { background: var(--color-toxic-lime); color: #000; }
.progress            { background: var(--color-riot-pink); }
::selection          { background: var(--color-toxic-lime); color: #000; }

/* ---- accents inside the graphite panels ---- */

.fab__big                { color: var(--color-toxic-lime); }
.fab__row dd.pos         { color: var(--color-toxic-lime); }
.fab__headline::after    { background: var(--color-toxic-lime); }
.fab .range-value        { color: var(--color-toxic-lime); }
.fab .range              { background-image: linear-gradient(var(--color-toxic-lime), var(--color-toxic-lime)); }
.fab .range::-webkit-slider-thumb { background: var(--color-toxic-lime); }
.fab .range::-moz-range-thumb     { background: var(--color-toxic-lime); }
.fab .input:focus        { box-shadow: 0 0 0 3px var(--color-toxic-lime); }
.fab .field:focus-within > label { color: var(--color-toxic-lime); }
.footer__h               { color: var(--color-toxic-lime); }
.footer__col a:hover     { border-bottom-color: var(--color-toxic-lime); }
.footer__rule            { background: linear-gradient(90deg, var(--color-riot-pink) 0 50%, var(--color-toxic-lime) 50% 100%); }
.pillar--ink::before     { background: var(--color-toxic-lime); }
.pillar--red::before     { background: #000; }
.pillar--yellow::before  { background: #000; }
.hero__logo::after       { background: linear-gradient(90deg, var(--color-riot-pink) 0 50%, var(--color-voltage-cyan) 50% 100%); }

/* ---- accents on the cream canvas ---- */

.nav.is-stuck              { background: rgba(242,242,242,.90); }
.nav__link.is-active       { color: #000; }
.nav__link.is-active::after{ background: #000; }
.contact__line a:hover     { border-bottom-color: #000; color: #000; }
.contact .field:focus-within > label { color: #000; }
.input:focus, .textarea:focus { border-color: #000; box-shadow: 0 0 0 3px rgba(173,255,2,.55); }

/* Riot Pink is bright enough that 68% black fell just under AA (4.45). */
.pillar--red .pillar__n { color: rgba(0,0,0,.85); }

/* ============================================================
   VISITORS PALETTE — BACKGROUNDS ONLY, NO DARK BOXES
   Surface colours from DESIGN (2).md. Text content, fonts, type
   scale, radii, spacing, layout and animation are untouched.

   This theme has no dark surface at all, so every panel that used
   to be graphite becomes light. That forces the type on those
   panels from white to Carbon/Graphite — not a style choice; the
   old white text would be invisible.

   The theme ships only one pastel (Mint Wash), so the other card
   fills are pale tints mixed from its own accents at the same
   weight, keeping every box light.
   ============================================================ */

:root {
  --color-carbon:      #181925;
  --color-paper-white: #ffffff;
  --color-linen:       #fafafa;
  --color-mist-fill:   #f5f5f5;
  --color-fog:         #e8e8e8;
  --color-ash:         #999999;
  --color-graphite-t:  #666666;
  --color-lavender:    #918df6;
  /* the F/A/B badge sits on this light lavender; white text there
     measures 2.86:1 (fails the 4.5:1 minimum) while dark carbon
     measures ~6:1, so this theme opts the badge into dark text */
  --color-badge-text:  #181925;
  --color-iris:        #9580ff;
  --color-mint:        #33c758;
  --color-mint-wash:   #def6e4;
  --color-amber:       #ffa600;
  --color-sky:         #2c78fc;
  --color-magenta-v:   #d6409f;
  --color-ember-v:     #ff3e00;

  /* pale washes mixed from the palette so no box is dark */
  --wash-lavender: #ebeafe;
  --wash-sky:      #ebf2ff;
  --wash-amber:    #fff3d9;
  --wash-magenta:  #fdeaf6;

  --canvas:    var(--color-paper-white);
  --surface-1: var(--color-paper-white);
  --surface-2: var(--color-linen);

  --line:         var(--color-fog);
  --line-strong:  #d8d8d8;
  --line-inverse: var(--color-fog);

  --ink:      var(--color-mist-fill);
  --ink-deep: var(--color-linen);
  --ink-soft: var(--color-fog);
}

/* ---- panels: all light now ---- */

.band           { background: var(--color-linen); border-bottom-color: var(--color-fog); }
.footer         { background: var(--color-linen); border-top: 1px solid var(--color-fog); }
.fab            { background: var(--color-mist-fill); }
#coldset        { background: var(--wash-lavender); }
#heatset        { background: var(--wash-sky); }
.product--light { background: var(--color-paper-white); border: 1px solid var(--color-fog); }
.pillar         { background: var(--color-paper-white); border-color: var(--color-fog); }

/* the drift wash, barely-there on a light ground */
.fab, .footer, .product--dark {
  background-image:
    radial-gradient(120% 85% at 8% 0%,    rgba(145,141,246,.10), transparent 60%),
    radial-gradient(110% 80% at 92% 100%, rgba(44,120,252,.07),  transparent 62%);
}

/* ---- accent cards, all pale ---- */

.pillar--red    { background: var(--color-mint-wash); border-color: var(--color-fog); }
.pillar--yellow { background: var(--wash-amber);      border-color: var(--color-fog); }
.pillar--ink    { background: var(--wash-lavender);   border-color: var(--color-fog); }
.stat--red      { background: var(--color-mint-wash); }
.stat--yellow   { background: var(--wash-amber); }
.stat--ink      { background: var(--wash-lavender); }
.stat--outline  { background: transparent; border-color: var(--color-fog); }
.vm__card--red    { background: var(--wash-sky); }
.vm__card--yellow { background: var(--wash-magenta); }

/* ---- type that used to sit on dark panels ---- */

.band__track span      { color: var(--color-carbon); font-weight: var(--fw-semibold); }
.band__track span b    { color: var(--color-carbon); font-weight: var(--fw-semibold); }

.footer                { color: var(--color-carbon); }
.footer__tag,
.footer__col a,
.footer__bottom        { color: var(--color-graphite-t); }
.footer__col a:hover   { color: var(--color-carbon); border-bottom-color: var(--color-lavender); }
.footer__h             { color: var(--color-lavender); }
.footer__top-link      { color: var(--color-carbon); }
.footer__top-link:hover{ color: var(--color-lavender); }
.footer__logo          { background: transparent; padding: 0; }

.fab                   { color: var(--color-carbon); }
.fab .muted,
.fab label,
.fab__row dt,
.fab__note             { color: var(--color-graphite-t); }
.fab__row              { border-top-color: var(--color-fog); }
.fab__row dd           { color: var(--color-carbon); }
.fab__headline         { border-color: var(--color-fog); }
.fab__big              { color: var(--color-lavender); }
.fab__row dd.pos       { color: var(--color-mint); }
.fab__row dd.neg       { color: var(--color-ember-v); }
.fab__headline::after  { background: var(--color-lavender); }
.fab .range            { background-color: var(--color-fog);
                         background-image: linear-gradient(var(--color-lavender), var(--color-lavender)); }
.fab .range::-webkit-slider-thumb { background: var(--color-lavender); }
.fab .range::-moz-range-thumb     { background: var(--color-lavender); }
.fab .range-value      { color: var(--color-lavender); }
.fab .input            { background: var(--color-paper-white); border-color: var(--color-fog); }
.fab .input:focus      { box-shadow: 0 0 0 3px rgba(145,141,246,.45); border-color: var(--color-lavender); }
.fab .field:focus-within > label { color: var(--color-lavender); }

.product--dark             { color: var(--color-carbon); }
.product--dark .muted      { color: var(--color-graphite-t); }
.product--dark .speclist li{ border-color: var(--color-fog); }
.product--dark .tag        { background: var(--color-mist-fill); color: var(--color-carbon); }
.product--dark .tag:hover  { background: var(--color-lavender); color: #fff; }

.pillar--red, .pillar--yellow, .pillar--ink { color: var(--color-carbon); }
.pillar--red .pillar__n,
.pillar--yellow .pillar__n,
.pillar--ink .pillar__n    { color: var(--color-ash); }
.pillar--red p,
.pillar--yellow p,
.pillar--ink p             { color: var(--color-graphite-t); }
.pillar--red .tag,
.pillar--yellow .tag,
.pillar--ink .tag          { background: var(--color-paper-white); color: var(--color-carbon); }
.pillar--red .tag:hover,
.pillar--yellow .tag:hover,
.pillar--ink .tag:hover    { background: var(--color-lavender); color: #fff; }

.stat--red, .stat--yellow, .stat--ink, .stat--outline { color: var(--color-carbon); }
.vm__card--red, .vm__card--yellow { color: var(--color-carbon); }
.vm__card--red .mono, .vm__card--yellow .mono { color: var(--color-graphite-t); }

/* ---- controls: Lavender is the one action colour ---- */

.tag                 { background: var(--color-mist-fill); color: var(--color-carbon); }
.tag:hover           { background: var(--color-lavender); color: #fff; }
.product--light .tag { background: var(--color-mist-fill); color: var(--color-carbon); }

.btn--solid          { background: var(--color-lavender); color: #fff; }
.btn--solid:hover    { background: var(--color-iris); color: #fff; }
.btn--magenta        { background: var(--color-lavender); color: #fff; }
.btn--magenta:hover  { background: var(--color-iris); color: #fff; }
.btn--ghost          { border-color: var(--color-fog); color: var(--color-carbon); }
.btn--ghost:hover    { border-color: var(--color-lavender); color: var(--color-lavender); }
.btn--onDark         { border-color: var(--color-fog); color: var(--color-carbon); }
.btn--onDark:hover   { background: var(--color-lavender); color: #fff; border-color: var(--color-lavender); }
.btn__arrow          { background: var(--color-lavender); color: #fff; }
.btn--solid .btn__arrow,
.btn--magenta .btn__arrow { background: #fff; color: var(--color-lavender); }
.btn--magenta:hover .btn__arrow { background: #fff; color: var(--color-iris); }

.skip-link     { background: var(--color-lavender); color: #fff; }
.totop         { background: var(--color-lavender); color: #fff; }
.totop:hover   { background: var(--color-iris); color: #fff; }
.progress      { background: var(--color-lavender); }

::selection    { background: var(--wash-lavender); color: var(--color-carbon); }

/* ---- accent bars, one colour per category ---- */

#coldset  .product__bar { background: var(--color-lavender) !important; }
#sheetfed .product__bar { background: var(--color-sky) !important; }
#heatset  .product__bar { background: var(--color-magenta-v) !important; }
.pillar--red::before    { background: var(--color-mint); }
.pillar--yellow::before { background: var(--color-amber); }
.pillar--ink::before    { background: var(--color-lavender); }
.status-dot             { background: var(--color-ember-v); }
.section-label::before  { background: var(--color-lavender); }
.hero__logo::after      { background: linear-gradient(90deg, var(--color-sky) 0%, var(--color-lavender) 100%); }
.footer__rule           { background: linear-gradient(90deg, var(--color-sky) 0%, var(--color-lavender) 100%); }

/* ---- canvas-level chrome ---- */

.nav.is-stuck              { background: rgba(255,255,255,.90); border-bottom-color: var(--color-fog); }
.nav__link                 { color: var(--color-ash); }
.nav__link:hover           { color: var(--color-lavender); }
.nav__link.is-active       { color: var(--color-lavender); }
.nav__link::after          { background: linear-gradient(90deg, var(--color-lavender), var(--color-magenta-v, var(--color-lavender))); }
.hero__since               { color: var(--color-graphite-t); }
.muted, .capability__cell span { color: var(--color-graphite-t); }
.capability__cell          { border-top-color: var(--color-fog); }
.speclist li               { border-color: var(--color-fog); }
.input, .textarea          { background: var(--color-paper-white); border-color: var(--color-fog); }
.input:focus, .textarea:focus { border-color: var(--color-lavender); box-shadow: 0 0 0 3px rgba(145,141,246,.35); }
.contact .field:focus-within > label { color: var(--color-lavender); }
.contact__line a:hover     { border-bottom-color: var(--color-lavender); color: var(--color-lavender); }
.form__note                { color: var(--color-graphite-t); }
.hero__logo-frame          { background: transparent; padding: 0; }

/* ------------------------------------------------------------
   Accessibility pass on the Visitors palette.

   Lavender, Mint, Amber, Sky and Ember are all light-to-mid
   colours. As TEXT on a white or pastel ground none of them
   reaches 4.5:1 — Lavender lands at 2.7, Mint at 2.0. The theme
   says as much itself: "never for body text", and "never use
   green text on white without the pastel fill".

   So: accents stay as FILLS and BARS. All small text is Carbon
   or Graphite. White-on-Lavender buttons flip to Carbon-on-
   Lavender (5.95:1). Ash #999 is replaced by Graphite #666 for
   nav and eyebrows, which Ash fails at 2.85.
   ------------------------------------------------------------ */

/* filled lavender controls: Carbon type, not white */
.btn--magenta,
.btn--solid,
.btn--magenta:hover,
.btn--solid:hover,
.totop,
.totop:hover,
.skip-link            { color: var(--color-carbon); }
.tag:hover,
.pillar--red .tag:hover,
.pillar--yellow .tag:hover,
.pillar--ink .tag:hover,
.product--dark .tag:hover,
.btn--onDark:hover    { color: var(--color-carbon); }

/* the arrow chip: dark fill, white glyph */
.btn__arrow                     { background: var(--color-carbon); color: #fff; }
.btn--solid .btn__arrow,
.btn--magenta .btn__arrow       { background: #fff; color: var(--color-carbon); }
.btn--magenta:hover .btn__arrow { background: #fff; color: var(--color-carbon); }

/* nav + eyebrows: Ash is too light to read */
.nav__link                 { color: var(--color-graphite-t); }
.pillar--red .pillar__n,
.pillar--yellow .pillar__n,
.pillar--ink .pillar__n,
.pillar__n                 { color: var(--color-graphite-t); }

/* accent text that has to carry meaning gets a darkened tone */
.band__track span b   { color: var(--color-carbon); font-weight: var(--fw-semibold); }
.footer__h            { color: var(--color-carbon); }
.fab .range-value     { color: var(--color-carbon); }
.fab__big             { color: var(--color-sky); }        /* large type, 3.75:1 */
.fab__row dd.pos      { color: #146c2e; }                 /* Mint darkened for text */
.fab__row dd.neg      { color: #cc3200; }                 /* Ember darkened for text */

/* hover and focus states that reached for Lavender as text */
.btn--ghost:hover           { color: var(--color-carbon); border-color: var(--color-lavender); }
.contact__line a:hover      { color: var(--color-carbon); border-bottom-color: var(--color-lavender); }
.footer__top-link:hover     { color: var(--color-carbon); }
.fab .field:focus-within > label,
.contact .field:focus-within > label { color: var(--color-carbon); }

/* ============================================================
   FAB TOOL — added detailing
   Input hints, a formula breakdown, and a spend comparison bar.
   Colours and spacing reuse the page's existing tokens; nothing
   here introduces a new palette.
   ============================================================ */

.fab__intro { display: flex; flex-direction: column; gap: var(--spacing-6); }

.field__hint {
  color: var(--color-graphite-t);
  margin-top: -2px;
}

/* labelled email rows in Contact -- fixed label column so every address
   lines up at the same left edge, whatever the label's own width
   ("Purchase" is wider than "Sales"/"Admin" and was overflowing the old
   68px column, throwing that one row out of alignment). */
.email-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-14);
  font-family: inherit;
}
.email-row__label {
  color: var(--color-carbon, var(--text));
  font-size: var(--text-body-sm);
  font-weight: 500;
  font-family: inherit;
  flex: 0 0 80px;
  width: 80px;
}
.email-row a {
  font-size: var(--text-body-sm);
  font-weight: 500;
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: break-word;
}
/* on a genuinely narrow phone, "purchase@kdink.org" next to an 80px label
   column leaves almost no room and can run right up to (or past) the
   screen edge -- stack the label above its address instead of forcing
   both onto one cramped line */
@media (max-width: 480px) {
  .email-row { flex-direction: column; align-items: flex-start; gap: 2px; }
  .email-row__label { flex: none; width: auto; }
}

/* spend comparison bar — two stacked rows, each independently scaled
   against the larger of the two spends, so neither ever clips */
.fab__compare { display: flex; flex-direction: column; gap: var(--spacing-10); }
.fab__compare-row {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  align-items: center;
  gap: var(--spacing-12);
}
.fab__compare-tag {
  display: inline-flex; align-items: center; gap: var(--spacing-6);
  color: var(--color-graphite-t);
  font-size: var(--text-body-sm);
}
.fab__compare-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.fab__compare-dot--now { background: var(--color-ash, #999999); }
.fab__compare-dot--kd  { background: var(--color-lavender, #918df6); }
.fab__compare-track {
  height: 10px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-fog, #e8e8e8);
}
.fab__compare-bar {
  height: 100%;
  border-radius: 999px;
  transition: width .5s var(--ease-out);
  width: 0%;
}
.fab__compare-bar--now { background: var(--color-ash, #999999); }
.fab__compare-bar--kd  { background: var(--color-lavender, #918df6); }
.fab__compare-figure {
  color: var(--color-carbon, #181925);
  font-size: var(--text-body-sm);
  min-width: 84px;
  text-align: right;
}

/* formula disclosure */
.fab__how {
  border-top: 1px solid var(--color-fog, #e8e8e8);
  padding-top: var(--spacing-16);
}
.fab__how summary {
  cursor: pointer;
  color: var(--color-carbon, #181925);
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--spacing-8);
}
.fab__how summary::-webkit-details-marker { display: none; }
.fab__how summary::before {
  content: "+";
  display: inline-grid;
  place-items: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1px solid var(--color-fog, #e8e8e8);
  font-family: var(--font-body);
  font-size: var(--text-badge);
  transition: transform .25s var(--ease-out);
}
.fab__how[open] summary::before { content: "\2212"; }

.fab__formula {
  margin: var(--spacing-12) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-10);
}
.fab__formula > div {
  display: flex;
  justify-content: space-between;
  gap: var(--spacing-16);
  padding-bottom: var(--spacing-10);
  border-bottom: 1px solid var(--color-fog, #e8e8e8);
}
.fab__formula > div:last-child { border-bottom: none; padding-bottom: 0; }
.fab__formula dt { color: var(--color-graphite-t); flex: none; }
.fab__formula dd {
  margin: 0;
  font-family: var(--font-mono);
  color: var(--color-carbon, #181925);
  text-align: right;
}

@media (max-width: 520px) {
  .fab__formula > div { flex-direction: column; gap: var(--spacing-4); }
  .fab__formula dd { text-align: left; }
}

/* ============================================================
   COLDSET PRESS PHOTOS
   Plain presentation, scoped to the Coldset card only. Sits as a
   third grid child inside .product, spanning the full width above
   the text columns.
   ============================================================ */

.product__gallery {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: var(--spacing-12);
  margin-bottom: var(--spacing-8);
}

/* two equal press-unit photos -- no wide hero slot, so nothing here
   gets stretched past its native resolution */
.product__gallery--units { grid-template-columns: 1fr 1fr; }

/* one full-width photo covering the whole gallery slot, instead of two
   side-by-side units */
.product__gallery--single { grid-template-columns: 1fr; }
.product__gallery--single img {
  max-height: 420px;
  border-radius: var(--radius-xl, 14px);
}

.product__gallery figure { margin: 0; }

.product__gallery img {
  width: 100%;
  height: auto;
  object-fit: cover;
  display: block;
}

.product__gallery--units img {
  max-height: 380px;
  object-position: center 30%;
}
/* every gallery image also gets an explicit aspect-ratio inline (matching
   its width/height attributes -- see index.html) so the browser reserves
   its real box immediately, before the file has actually loaded. Without
   that, a slow connection or a scroll-triggered lazy load can leave the
   image at zero height for a moment with its caption sitting right where
   the photo hasn't painted in yet -- which reads as the caption
   "overlapping" the image below it. */

.product__gallery-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--spacing-12);
}

.product__gallery figcaption {
  margin-top: var(--spacing-10);
  font-size: var(--text-tiny);
  font-weight: var(--fw-semibold);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-carbon, var(--text));
}

@media (max-width: 640px) {
  .product__gallery,
  .product__gallery--units { grid-template-columns: 1fr; }
  .product__gallery--units img { max-height: none; }
}

/* ============================================================
   HEAT-SET PACKAGING PHOTOS
   Real bucket/barrel photography, plain presentation (matching
   the reverted Coldset gallery style — no hover zoom, no overlay).
   ============================================================ */

.product__gallery--pack {
  grid-column: auto;
  grid-template-columns: 1fr 1fr;
  max-width: 320px;
}
.product__gallery--pack img { object-fit: contain; background: transparent; }
.product__gallery--pack figure { text-align: center; }

/* ============================================================
   SUPPORT ICONS
   One HD icon per Technical Service card, taken from the
   brochure's Features & Benefits row.
   ============================================================ */

.capability__icon {
  width: 44px;
  height: auto;
  margin-bottom: var(--spacing-6);
}

/* ============================================================
   TECHNICAL SPECIFICATIONS TABLE — Coldset
   Real HTML table, not an image, so the text stays crisp at any
   size and any zoom level. Spans the full card width, scrolls
   horizontally on narrow screens rather than squeezing columns
   unreadably thin.
   ============================================================ */

.spectable-wrap {
  position: relative;
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-16);
  margin-top: var(--spacing-40);
  padding: var(--spacing-30) var(--spacing-30);
  border-radius: var(--radius-2xl);
  background: var(--color-paper-white, var(--surface-1));
}
.spectable-wrap > .mono {
  color: var(--color-carbon, var(--text));
}

/* mobile-only nudge: the table is genuinely wider than a phone screen, so
   without a visible cue it just looks cut off after the second column --
   this label plus the fade below make "there's more, swipe" obvious rather
   than leaving people to spot the thin scrollbar on their own */
.spectable-hint { display: none; }
@media (max-width: 760px) {
  .spectable-hint {
    display: block;
    color: var(--text-muted);
    font-size: var(--text-tiny);
  }
}

.spectable-scroll {
  overflow-x: auto;
  border-radius: var(--radius-2xl);
  border: 1px solid var(--line-inverse, rgba(255,255,255,.14));
}
/* fade sits on the non-scrolling wrap, pinned to its right edge, so it
   stays put as a "there's more this way" cue while the table underneath
   scrolls -- rather than moving with the scrolled content. */
@media (max-width: 760px) {
  .spectable-wrap::after {
    content: "";
    position: absolute;
    top: var(--spacing-30); bottom: var(--spacing-30); right: var(--spacing-30);
    width: 28px;
    border-radius: 0 var(--radius-2xl) var(--radius-2xl) 0;
    pointer-events: none;
    background: linear-gradient(to right, transparent, rgba(0,0,0,.14));
  }
}

.spectable {
  width: 100%;
  min-width: 760px;
  border-collapse: collapse;
  font-size: var(--text-body-sm);
}

.spectable th,
.spectable td {
  padding: var(--spacing-14) var(--spacing-20);
  text-align: left;
  white-space: nowrap;
  border-right: 1px solid var(--line-strong, rgba(255,255,255,.18));
}
.spectable th:last-child,
.spectable td:last-child { border-right: none; }

.spectable thead th {
  font-family: var(--font-mono);
  font-size: var(--text-tiny);
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: var(--fw-regular);
  background: rgba(0, 0, 0, .10);
  border-bottom: 2px solid var(--line-strong, rgba(255,255,255,.22));
  vertical-align: bottom;
  padding-bottom: var(--spacing-10);
}

.spectable-sub {
  display: block;
  font-size: var(--text-micro);
  opacity: .7;
  text-transform: none;
  letter-spacing: 0;
}

.spectable tbody th {
  font-weight: var(--fw-regular);
  white-space: normal;
}

.spectable tbody tr {
  border-bottom: 1px solid var(--line-inverse, rgba(255,255,255,.10));
}
.spectable tbody tr:last-child { border-bottom: none; }

@media (max-width: 520px) {
  .spectable td, .spectable th { white-space: normal; }
}

/* ============================================================
   FAB — Feature / Advantage / Benefit explainer
   Lives as a closed-by-default accordion inside the calculator's
   own card (spans both grid columns), so visitors who already know
   what FAB means see the calculator immediately, and the card reads
   as one block rather than an explainer plus a separate panel below.
   ============================================================ */

.fab-explain { grid-column: 1 / -1; border-bottom: 1px solid var(--line-inverse); }
.fab-explain summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--spacing-8);
  padding-block: var(--spacing-12);
}
.fab-explain summary::-webkit-details-marker { display: none; }
.fab-explain summary::before {
  content: "+";
  display: inline-grid;
  place-items: center;
  width: 20px; height: 20px;
  border-radius: 50%;
  border: 1px solid currentColor;
  font-family: var(--font-body);
  font-size: var(--text-badge);
  flex: none;
  transition: transform .25s var(--ease-out);
}
.fab-explain[open] summary::before { content: "\2212"; }
.fab-explain[open] summary { padding-bottom: var(--spacing-4); }

.fab-about {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--spacing-14);
  padding-bottom: var(--spacing-16);
}
.fab-about__item {
  display: flex;
  gap: var(--spacing-10);
  align-items: flex-start;
}
.fab-about__letter {
  flex: none;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-neon-magenta, var(--brand-red));
  color: var(--color-badge-text, #fff);
  font-size: var(--text-tiny);
}
.fab-about__item strong {
  display: block;
  margin-bottom: 2px;
  font-size: var(--text-body-sm);
  color: var(--color-carbon, var(--text));
}
.fab-about__item p { font-size: var(--text-tiny); line-height: 1.4; }

@media (max-width: 760px) {
  .fab-about { grid-template-columns: 1fr; gap: var(--spacing-20); margin-top: var(--spacing-24); }
  .fab-about__letter { width: 32px; height: 32px; font-size: var(--text-badge); }
  .fab-about__item strong { font-size: 1em; margin-bottom: var(--spacing-4); }
  .fab-about__item p { font-size: var(--text-body-sm); line-height: inherit; }
}

/* ------------------------------------------------------------
   FAB TOOL — compact desktop layout.
   The heading, F/A/B explainer and calculator together used to run
   well past a laptop's viewport height, forcing two full scrolls to
   see the whole section. Everything here only shrinks type size and
   spacing (never removes content); the ≥761px guard means mobile
   keeps the original, more generous sizing untouched.
   ------------------------------------------------------------ */
@media (min-width: 761px) {
  #fab.section { padding-block: calc(var(--section-gap) * .55); }
  #fab .section__head { gap: var(--spacing-10); margin-bottom: var(--spacing-20); }
  #fab h2.display { font-size: clamp(28px, 3vw, 36px); max-width: 30ch; }
  #fab > .section__head > p.muted { font-size: var(--text-body-sm); margin: 0; }
  #fab .fab { padding: calc(var(--card-padding) * .6); gap: var(--spacing-24); }
  #fab .fab__intro { gap: var(--spacing-10); }
  #fab .fab__form { gap: var(--spacing-10); }
  #fab .fab__grid { gap: var(--spacing-8); }
  #fab .fab .field { gap: 2px; }
  #fab .fab .input { padding: 6px var(--spacing-14); }
  #fab .fab .range { margin-block: var(--spacing-6); }
  #fab .fab__out { gap: var(--spacing-10); }
  #fab .fab__headline { padding: var(--spacing-14); }
  #fab .fab__big { font-size: clamp(32px, 4vw, 44px); }
  #fab .fab__row { padding-block: var(--spacing-6); }
  #fab .fab__compare { gap: var(--spacing-6); }
  #fab .field__hint { font-size: var(--text-tiny); margin-top: 0; }
  #fab .fab__intro span.small { font-size: var(--text-tiny); }
  #fab .fab__note { font-size: var(--text-tiny); }
  #fab .fab__formula { margin-top: var(--spacing-6); gap: var(--spacing-4); }
  #fab .btn { padding-block: var(--spacing-10); }
}

/* ============================================================
   STANDALONE SPEC SECTION
   The Technical Specifications table now lives in its own section
   (moved out of the Coldset card), so its wrapper no longer needs
   the grid-spanning rule written for that context.
   ============================================================ */

#specs .spectable-wrap {
  grid-column: auto;
  margin-top: 0;
}

/* ============================================================
   COLDSET PACKAGING — 4-bucket bunch + barrel
   Auto-fit grid so it stays legible from 5-across on wide
   screens down to 2-across on a phone, without a fixed
   breakpoint count to maintain.
   ============================================================ */

.product__gallery--pack5 {
  grid-column: auto;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--spacing-16) var(--spacing-16);
  row-gap: var(--spacing-30);
  max-width: 100%;
  margin-bottom: var(--spacing-40);
}
.product__gallery--pack5 img { object-fit: contain; background: transparent; }
.product__gallery--pack5 figure { text-align: center; }

/* high-contrast captions: solid text colour against the card, not the
   translucent grey used on the earlier press photos */
.product__gallery--pack5 figcaption {
  color: var(--color-carbon, var(--text));
  font-weight: var(--fw-regular, 500);
  line-height: 1.4;
}

@media (max-width: 880px) {
  .product__gallery--pack5 { grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); }
}


/* ============================================================
   CONTACT — colourful low-contrast backdrop
   Built from the site's own ink brand colours rather than a photo,
   so it stays crisp at any size and ties back to "printing ink"
   rather than being generic decoration. Text sits in its own
   stacking context above it, so contrast is unaffected.
   ============================================================ */

#contact { position: relative; isolation: isolate; }
#contact > * { position: relative; }

/* ============================================================
   PRODUCT ARTWORK — real photos (Sheetfed, Heat-Set)
   Replaces the flat SVG placeholder with genuine HD press
   photography, same slot in the card layout.
   ============================================================ */

.artwork--photo {
  margin: 0;
  width: 100%;
  max-width: 380px;
}
.artwork--photo img {
  width: 100%;
  height: auto;
  max-height: 260px;
  object-fit: cover;
  border-radius: var(--radius-2xl);
  display: block;
}
.artwork--photo figcaption {
  margin-top: var(--spacing-6);
  font-size: var(--text-tiny);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-graphite-t, var(--text-muted));
}

/* FAB Tool trimmed to exactly the fields/rows the client approved --
   these stay in the DOM (so the calculator's math is untouched) but
   are hidden from view. !important because .fab__extra is applied
   across many different base elements (.field, .form__actions, .btn,
   spans, a <p>), each already setting its own display via a rule
   scattered elsewhere in this file -- chasing cascade order for every
   one of those individually is far more fragile than one utility rule. */
.fab__extra { display: none !important; }
