@charset "utf-8";
/* =====================================================================================
   NAVIKS — design system
   Hand-written. No framework, no utility classes, no build step.

   Contents
     01  Fonts
     02  Tokens
     03  Reset & base
     04  Typography
     05  Layout primitives
     06  Buttons & links
     07  Header / nav
     08  Hero (3D stage)
     09  Cards & sections
     10  Process rail (3D)
     11  FAQ
     12  Form
     13  Footer & cookie bar
     14  Motion, reduced-motion, print
   ===================================================================================== */


/* 01  Fonts ------------------------------------------------------------------------ */
/* Self-hosted: fonts.gstatic.com would expose every visitor's IP to Google, which EU
   courts have held to be a GDPR violation. These are also one less connection to open. */

/* Montserrat — the NAVIKS logo font, used for the entire site so the page and the
   printed identity read as one brand. One variable file per subset covers 100–900. */

@font-face {
  font-family: "Montserrat";
  src: url("../fonts/montserrat-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* True italics, loaded only when something is actually set in italic. */
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/montserrat-italic-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/montserrat-italic-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/montserrat-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  /* Slovene c/s/z with carons live here — without this subset the copy breaks. */
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* 02  Tokens ----------------------------------------------------------------------- */

:root {
  /* Brand. Yellow is an accent, deliberately rationed — it marks actions, indices and
     one word per headline. Flooding a page with it is what makes a brand look cheap. */
  --brand:        #FFDE59;
  --brand-deep:   #E9C230;
  --brand-dim:    #6A5B21;

  /* Canvas */
  --ink:          #0A0A0B;
  --ink-raised:   #101013;
  --ink-card:     #141418;
  --ink-hair:     #26262C;
  --ink-hair-soft:#1B1B20;

  /* Text. Contrast against --ink is measured, not eyeballed: 17.9:1 / 7.8:1 / 5.3:1.
     --fg-faint carries small 12-14px text (form notes, step meta, footer), so it has to
     clear WCAG AA 4.5:1 — an earlier #6E6E79 looked right but measured 3.93:1 and failed. */
  --fg:           #F4F4F2;
  --fg-muted:     #A2A2AC;
  --fg-faint:     #83838E;

  /* Light surfaces (product plates) */
  --plate:        #ECECEC;

  --focus:        #FFDE59;
  --danger:       #FF6B5A;
  --ok:           #6FE3A6;

  /* Type — one family, two roles. Montserrat is geometric and runs wide, so display
     sizes are a notch smaller than a grotesque would need and tracking is tighter. */
  --f-display: "Montserrat", "Segoe UI", system-ui, sans-serif;
  --f-text:    "Montserrat", "Segoe UI", system-ui, sans-serif;

  /* Fluid scale — 1.25 ratio, clamped so it never gets silly on ultrawide */
  --t-hero:  clamp(2.5rem, 1.1rem + 5.9vw, 6.4rem);
  --t-h2:    clamp(2rem,   1.25rem + 3.1vw, 4rem);
  --t-h3:    clamp(1.28rem, 1.1rem + 0.75vw, 1.75rem);
  --t-lead:  clamp(1.06rem, 0.99rem + 0.34vw, 1.3rem);
  --t-body:  clamp(0.98rem, 0.95rem + 0.16vw, 1.06rem);
  --t-small: 0.87rem;
  --t-micro: 0.75rem;

  /* Space — 4px base */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 3rem;     --s-8: 4rem;
  --s-9: 6rem;     --s-10: 8rem;

  /* Was up to 10rem top AND bottom — 320px of empty dark between blocks, which read as
     unfinished gaps rather than breathing room. */
  --section-y: clamp(3.75rem, 2rem + 5.5vw, 7rem);
  --shell:     1320px;
  --gutter:    clamp(1.25rem, 0.6rem + 2.6vw, 3.5rem);

  --r-sm: 6px;  --r-md: 12px;  --r-lg: 20px;  --r-xl: 28px;

  /* Expo-out: covers most of the distance immediately, then settles. This is the single
     change that makes motion read as considered rather than mechanical, and unlike the
     pinned-scroll experiment it costs nothing in layout. */
  --ease:        cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft:   cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-in-out: cubic-bezier(0.45, 0, 0.2, 1);

  color-scheme: dark;
}


/* 03  Reset & base ----------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
}

body {
  background: var(--ink);
  color: var(--fg);
  font-family: var(--f-text);
  font-size: var(--t-body);
  font-weight: 400;
  /* Montserrat needs a touch more leading than a text-first face to stay comfortable
     at paragraph length. */
  line-height: 1.68;
  letter-spacing: -0.003em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* A very fine grain over the whole canvas. Flat black reads as "unfinished dark mode";
   a little noise reads as a considered surface. Pure CSS, no image request. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

img, svg, video { display: block; max-width: 100%; height: auto; }

button, input, select, textarea { font: inherit; color: inherit; }

:where(a) { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--brand); color: #000; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px; left: var(--s-4);
  z-index: 999;
  background: var(--brand);
  color: #000;
  padding: var(--s-3) var(--s-5);
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  font-weight: 600;
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 0; }


/* 04  Typography ------------------------------------------------------------------- */

/* Montserrat's caps are tall and its default spacing is generous. Headings therefore
   want heavier weight and noticeably tighter tracking than a neutral grotesque, or they
   read as loose and soft. */
h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

h2 { font-size: var(--t-h2); letter-spacing: -0.028em; }
h3 { font-size: var(--t-h3); line-height: 1.2; letter-spacing: -0.018em; }

p { text-wrap: pretty; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--f-text);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand);
}
.eyebrow::before {
  content: "";
  width: 1.6rem;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  color: var(--fg-muted);
  max-width: 54ch;
}

/* Section heads.
   Previously every section was the same left-aligned stack — eyebrow, heading, lead,
   grid — repeated six times, which reads like a document rather than a designed page.
   The heading and the lead now sit side by side on a split grid, with the lead dropped
   to a lower baseline and indented. That single change gives the page a horizontal
   rhythm and a second column of interest. */
/* Structured two-column head: eyebrow and heading anchored left, the lead in a second
   column on a shared baseline. Restored because the plain stack let each block find its
   own width, so nothing lined up down the page. This locks every section to the same
   two-column grid, which is what makes a page read as designed rather than typed. */
.section-head {
  margin-bottom: clamp(2.25rem, 1rem + 3.5vw, 4rem);
  display: grid;
  gap: var(--s-4) clamp(2rem, 5vw, 5rem);
}
.section-head h2 { margin: var(--s-4) 0 0; max-width: 18ch; }
.section-head .lead { max-width: 46ch; }

@media (min-width: 900px) {
  .section-head {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    align-items: end;
  }
  .section-head .eyebrow { grid-column: 1; grid-row: 1; }
  .section-head h2       { grid-column: 1; grid-row: 2; }
  .section-head .lead    { grid-column: 2; grid-row: 2; padding-bottom: 0.35em; }
}

/* Card text sits on the same grid: fixed measure so descriptions do not each wrap to a
   different width, which is what made the row look ragged. */
.product-body p, .card p { max-width: 34ch; }

/* Yellow is applied to a single word, never a whole heading. Italic as well, so the
   accent reads as emphasis rather than only as a colour change — which also means it
   still carries meaning for anyone who cannot distinguish the colour. Real italics,
   not a synthesised slant: see the italic @font-face above. */
.hl {
  color: var(--brand);
  font-style: italic;
  /* Italics lean into the following word; a hair of space keeps them from touching. */
  padding-right: 0.04em;
}

.index {
  font-family: var(--f-display);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--brand);
  font-variant-numeric: tabular-nums;
}


/* 05  Layout primitives ------------------------------------------------------------ */

.shell {
  width: min(100% - (var(--gutter) * 2), var(--shell));
  margin-inline: auto;
}

main { position: relative; z-index: 1; }

section { position: relative; }

.section { padding-block: var(--section-y); }

/* A hairline that fades at both ends — a quieter divider than a full-width border. */
.rule {
  height: 1px;
  border: 0;
  background: linear-gradient(90deg, transparent, var(--ink-hair) 12%, var(--ink-hair) 88%, transparent);
}

.grid { display: grid; gap: var(--s-6); }

@media (min-width: 900px) {
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  /* Asymmetric split — a 50/50 hero is the most generic layout there is. */
  .split { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: clamp(2rem, 5vw, 5rem); }
}

/* Five product categories (hoodies, t-shirts, polos, jackets, workwear). Three across
   on desktop gives 3 + 2 and keeps each garment image large; four across would leave a
   single orphan on the second row. */
.grid-products { grid-template-columns: 1fr; }
@media (min-width: 620px)  { .grid-products { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .grid-products { grid-template-columns: repeat(3, 1fr); } }


/* 06  Buttons & links -------------------------------------------------------------- */

.btn {
  --btn-bg: var(--brand);
  --btn-fg: #08080A;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7em;
  padding: 1.05em 1.7em;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--f-text);
  font-size: var(--t-small);
  font-weight: 650;
  letter-spacing: 0.01em;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease), background-color 0.25s;
  will-change: transform;
}
.btn::after {
  /* Sheen sweep on hover. Subtle — it should register as material, not as a casino. */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(110deg, transparent 20%, rgba(255, 255, 255, 0.55) 50%, transparent 80%);
  transform: translateX(-120%);
  transition: transform 0.7s var(--ease);
}
.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 30px -12px rgba(255, 222, 89, 0.55);
}
.btn:hover::after { transform: translateX(120%); }
.btn:active { transform: translateY(0); }

.btn .arrow { transition: transform 0.35s var(--ease); }
.btn:hover .arrow { transform: translateX(4px); }

.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--fg);
  border-color: var(--ink-hair);
}
.btn-ghost:hover {
  border-color: var(--brand);
  color: var(--brand);
  box-shadow: none;
}
.btn-ghost::after { display: none; }

/* Inline link with an underline that grows from the left */
.link {
  color: var(--fg);
  background-image: linear-gradient(var(--brand), var(--brand));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 1px;
  transition: background-size 0.4s var(--ease), color 0.25s;
  padding-bottom: 1px;
}
.link:hover { background-size: 100% 1px; color: var(--brand); }

.link-brand { color: var(--brand); background-image: linear-gradient(var(--brand), var(--brand)); }


/* 07  Header / nav ----------------------------------------------------------------- */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  padding-block: var(--s-4);
  transition: background-color 0.35s var(--ease), border-color 0.35s, backdrop-filter 0.35s;
  border-bottom: 1px solid transparent;
}
.site-header[data-stuck="true"] {
  background: color-mix(in srgb, var(--ink) 82%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--ink-hair-soft);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}

.brand { display: inline-flex; align-items: center; }
/* Same guard as the footer mark: fix the width, never let max-width squash it. */
.brand img { width: 150px; height: auto; max-width: none; object-fit: contain; }

.nav-links {
  display: none;
  align-items: center;
  gap: clamp(1rem, 2.2vw, 2.2rem);
  list-style: none;
  padding: 0;
}
@media (min-width: 1060px) { .nav-links { display: flex; } }

.nav-links a {
  font-size: var(--t-small);
  color: var(--fg-muted);
  position: relative;
  padding-block: 0.4em;
  transition: color 0.25s;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}
.nav-links a:hover { color: var(--fg); }
.nav-links a:hover::after { transform: scaleX(1); }

.nav-actions { display: flex; align-items: center; gap: var(--s-3); }

.lang-switch {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--ink-hair);
  border-radius: 999px;
  overflow: hidden;
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.06em;
}
.lang-switch a, .lang-switch span {
  padding: 0.5em 0.85em;
  color: var(--fg-faint);
  transition: color 0.25s, background-color 0.25s;
}
.lang-switch [aria-current="true"] { background: var(--brand); color: #000; }
.lang-switch a:hover { color: var(--fg); }

.nav-cta { display: none; }
@media (min-width: 640px) { .nav-cta { display: inline-flex; padding: 0.8em 1.35em; } }

/* Mobile menu */
.burger {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px; height: 44px;
  padding: 0 10px;
  background: none;
  border: 1px solid var(--ink-hair);
  border-radius: 999px;
  cursor: pointer;
}
@media (min-width: 1060px) { .burger { display: none; } }
.burger span {
  display: block;
  height: 1.5px;
  background: var(--fg);
  border-radius: 2px;
  transition: transform 0.35s var(--ease), opacity 0.2s;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: var(--ink);
  padding: 7rem var(--gutter) var(--s-7);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform 0.5s var(--ease), visibility 0.5s;
  overflow-y: auto;
}
.mobile-menu[data-open="true"] { transform: translateY(0); visibility: visible; }
.mobile-menu a {
  font-family: var(--f-display);
  font-size: clamp(1.8rem, 8vw, 2.6rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  padding-block: var(--s-3);
  border-bottom: 1px solid var(--ink-hair-soft);
  transition: color 0.25s, padding-left 0.35s var(--ease);
}
.mobile-menu a:hover { color: var(--brand); padding-left: var(--s-3); }
.mobile-menu .btn { margin-top: var(--s-5); }


/* 08  Hero (3D stage) -------------------------------------------------------------- */

.hero {
  position: relative;
  /* max() floor stops the flex centring from pushing the headline up under the fixed
     header on short or landscape windows — that was the overlap in the screenshot. */
  min-height: max(680px, min(100svh, 1000px));
  display: flex;
  align-items: center;
  padding-top: clamp(8.5rem, 14vh, 11rem);
  padding-bottom: clamp(4rem, 8vh, 7rem);
  overflow: hidden;
  text-align: center;
}

/* A single wide glow anchored behind the deck. One light source, not five blurred blobs. */
.hero::after {
  content: "";
  position: absolute;
  top: 12%; right: -10%;
  width: 60vw; height: 60vw;
  max-width: 900px; max-height: 900px;
  background: radial-gradient(circle, rgba(255, 222, 89, 0.13), transparent 62%);
  pointer-events: none;
  z-index: 0;
}

.hero .shell { position: relative; z-index: 2; }

/* Centred title-slide layout: the copy sits in the middle, the product imagery sits
   behind it at depth. Reads like the opening frame of a presentation rather than the
   left-text/right-picture arrangement every template ships with. */
.hero-grid { position: relative; z-index: 3; }

.hero-copy {
  max-width: 20ch;
  margin-inline: auto;
}

.hero h1 {
  font-size: var(--t-hero);
  /* Weight 600, not 700. Studio-grade sites set huge display type LIGHT and tight —
     the reference runs 66px at weight 400 with -0.04em. Montserrat is geometric so it
     cannot go as tight without its round letterforms colliding, but dropping a step in
     weight and pulling tracking in buys most of that refinement. Heavy + loose is what
     makes a headline look like a template. */
  font-weight: 600;
  letter-spacing: -0.035em;
  /* 1.12, not 0.98. Two things caused "logotipom." to be cut off: the .line wrapper had
     overflow:hidden, and the leading was trimmed below Montserrat's own descender depth
     (its vertical metrics run ~1.2em). The wrapper no longer clips, and this leaves
     room for the g/p descenders with margin to spare. */
  line-height: 1.12;
  /* Belt and braces: .hero needs overflow:hidden to contain the backdrop panels, so the
     headline carries its own descender room rather than relying on an ancestor not to
     clip it. */
  padding-bottom: 0.08em;
  margin: var(--s-5) auto var(--s-6);
  max-width: 15ch;
}
.hero h1 .line { display: block; }

/* Rotating object of the headline. The wrapper's width is animated to the measured
   width of the next phrase, so the full stop glides across instead of jumping — that
   settling motion is most of what makes a word rotator feel finished. */
/* The possessive is static markup outside the animated wrapper; it only cross-fades on
   the transitions where the grammar changes it. */
.rot-p {
  display: inline-block;
  transition: opacity 0.22s var(--ease);
}
.rot-p.is-fading { opacity: 0; }

.rot {
  display: inline-block;
  /* Clipping is what lets the word slide in from below, but it was shaving the tail off
     the italic. Note `overflow-x: visible` does NOT work here — CSS forces `visible` to
     compute as `auto` whenever the other axis is hidden, so the box still clipped (and
     became scrollable). The fix is content-box sizing: the width JS sets then applies to
     the text alone, and the horizontal padding is extra room the italic overhang can
     lean into. Negative margins keep the surrounding words where they were. */
  box-sizing: content-box;
  overflow: hidden;
  padding: 0.14em 0.1em 0.18em;
  margin: -0.14em -0.1em -0.18em;
  vertical-align: top;
  transition: width 0.62s var(--ease);
  will-change: width;
}
.rot-in {
  display: inline-block;
  white-space: nowrap;
  transition: transform 0.42s var(--ease), opacity 0.28s var(--ease);
  will-change: transform, opacity;
}
/* Outgoing word lifts away; the incoming one is placed below and rises into view. */
.rot.is-out .rot-in { transform: translateY(-105%); opacity: 0; }
.rot.is-in  .rot-in { transform: translateY(105%);  opacity: 0; transition: none; }

.rot-dot { display: inline-block; }

/* Reduced-motion variant: the words still change, they just cross-fade in place with
   no vertical travel and no width glide. */
.rot.rot-plain { transition: none; }
.rot.rot-plain .rot-in { transition: opacity 0.2s linear; }
.rot.rot-plain.is-out .rot-in { transform: none; opacity: 0; }
.rot.rot-plain.is-in  .rot-in { transform: none; opacity: 0; }

/* Hidden ruler used to measure a phrase before swapping to it. */
.rot-measure {
  position: absolute !important;
  visibility: hidden;
  white-space: nowrap;
  pointer-events: none;
  left: -9999px;
  top: 0;
}

.hero-lead { max-width: 52ch; margin-inline: auto; }

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-3);
  margin-top: var(--s-7);
}

.hero-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s-5) var(--s-6);
  max-width: 760px;
  margin: clamp(3.5rem, 7vw, 5rem) auto 0;
  padding-top: var(--s-5);
  border-top: 1px solid var(--ink-hair-soft);
}
.hero-facts dt {
  font-family: var(--f-display);
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.9rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--brand);
}
.hero-facts dd {
  margin: 0.35em 0 0;
  font-size: var(--t-small);
  color: var(--fg-faint);
  line-height: 1.35;
}

/* --- hero composition ------------------------------------------------------------
   Rewritten. The previous version floated three product cards at three different
   angles plus a fake-extruded monogram; scattered objects at odd rotations read as
   clip-art, not as craft.

   This is one composed image pair on a shared grid: a large primary frame and one
   smaller frame anchored to its lower-left corner, both square to the page at rest.
   The only motion is a whisper of shared tilt on pointer — under 4 degrees, applied to
   the group so the two frames move together as one object rather than drifting apart.
   Restraint is the point.                                                            */

/* Woven-thread canvas. Generated in js/weave.js — warp and weft crossing, which is
   literally what the business makes. Nothing photographic here: the product shots live
   further down, and reusing them at the top made the hero a contents list of itself. */
.hero-weave {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  display: block;
  pointer-events: none;
}

/* Vignette over the canvas so the headline always has a contrast bed and the threads
   fade out at the edges rather than stopping at a hard line. */
.hero-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 54% 46% at 50% 48%, rgba(10, 10, 11, 0.88) 26%, rgba(10, 10, 11, 0.42) 64%, transparent 100%),
    linear-gradient(180deg, var(--ink) 0%, transparent 16%, transparent 80%, var(--ink) 100%);
}

/* Single fact chip, centred under the actions — replaces the badge that used to sit on
   a floating card. */
.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  margin-top: var(--s-5);
  padding: 0.55em 1.1em;
  border: 1px solid var(--brand-dim);
  border-radius: 999px;
  background: rgba(255, 222, 89, 0.07);
  color: var(--brand);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.hero-badge::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--brand);
}

@media (max-width: 720px) {
  /* At phone width the panels sit behind the text rather than beside it; drop them to
     one, further back, so the headline never fights a busy backdrop. */
  .frame-r { display: none; }
  .frame-l { left: 50%; transform: translate(-50%, -50%) translateZ(-320px) rotateY(0deg); opacity: 0.3; }
}

/* The old bottom-centre "NAPREJ" scroll hint was removed: it collided with the facts
   row, and a scroll cue on a page that obviously scrolls is decoration. */

/* --- opening sequence --------------------------------------------------------------
   The page opens rather than simply appearing. The weave threads itself in first, then
   the headline lines lift out of their own baseline, then the supporting copy and the
   actions. Roughly 1.6s end to end, once, and skipped entirely under reduced motion.

   Each headline line sits in a clipped box and rises out of it — the same idea as a
   masked reveal, but done with the two lines the markup already has instead of
   measuring and rewrapping text at runtime, which is where the previous attempt started
   fighting the layout. */

@keyframes heroRise {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}
@keyframes lineLift {
  from { transform: translateY(110%); }
  to   { transform: none; }
}
@keyframes weaveIn {
  from { opacity: 0; transform: scale(1.06); }
  to   { opacity: 1; transform: none; }
}

/* CRITICAL: the resting state is VISIBLE. The intro only runs when app.js adds
   `.is-intro`, and it is never added under reduced motion or if scripting is off.
   Using animation fill-mode to reveal content is a trap — the previous version left the
   headline parked 114px below its clip box whenever the animation did not complete,
   which meant an invisible headline. Content must never depend on an animation
   finishing in order to be seen. */

.hero h1 .line {
  display: block;
  padding-bottom: 0.08em;
}
.hero h1 .line > span { display: block; }

/* --- intro, opt-in ------------------------------------------------------------- */

.hero.is-intro .hero-weave { animation: weaveIn 1.8s var(--ease) both; }

/* Clipping is applied only while the intro is armed, so a descender can never be cut
   off in the resting state. */
.hero.is-intro h1 .line { overflow: hidden; }
.hero.is-intro h1 .line > span { animation: lineLift 1.05s var(--ease) both; }
.hero.is-intro h1 .line:nth-child(1) > span { animation-delay: 0.28s; }
.hero.is-intro h1 .line:nth-child(2) > span { animation-delay: 0.40s; }

.hero.is-intro .hero-anim > *:not(h1) { animation: heroRise 0.85s var(--ease) both; }
.hero.is-intro .hero-anim > .eyebrow      { animation-delay: 0.14s; }
.hero.is-intro .hero-anim > .hero-lead    { animation-delay: 0.60s; }
.hero.is-intro .hero-anim > .hero-actions { animation-delay: 0.70s; }
.hero.is-intro .hero-anim > *:nth-child(5){ animation-delay: 0.78s; }
.hero.is-intro .hero-anim > .hero-facts   { animation-delay: 0.86s; }

/* Fixed header sits over a transparent hero at the top of the page. Without a scrim,
   large headline text scrolling underneath collides with the nav. This keeps the top
   band readable at all times without making the header look like a solid slab. */
.site-header::before {
  content: "";
  position: absolute;
  inset: -1px 0 auto 0;
  height: 190%;
  background: linear-gradient(180deg, rgba(10, 10, 11, 0.92) 0%, rgba(10, 10, 11, 0.6) 45%, transparent 100%);
  pointer-events: none;
  z-index: -1;
  transition: opacity 0.35s var(--ease);
}
.site-header[data-stuck="true"]::before { opacity: 0; }


/* 09  Cards & sections ------------------------------------------------------------- */

.card {
  position: relative;
  padding: clamp(1.6rem, 1rem + 1.6vw, 2.4rem);
  background: var(--ink-card);
  border: 1px solid var(--ink-hair-soft);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: border-color 0.4s var(--ease), transform 0.5s var(--ease);
}
.card::before {
  /* Pointer-tracked highlight. Set by app.js via --mx/--my; degrades to nothing. */
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 0%),
              rgba(255, 222, 89, 0.09), transparent 68%);
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}
.card:hover { border-color: var(--ink-hair); }
.card:hover::before { opacity: 1; }

.card h3 { margin-bottom: var(--s-3); }
.card p { color: var(--fg-muted); font-size: var(--t-body); }

.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
}

.tags { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-5); list-style: none; padding: 0; }
.tags li {
  font-size: var(--t-micro);
  color: var(--fg-faint);
  border: 1px solid var(--ink-hair);
  border-radius: 999px;
  padding: 0.4em 0.85em;
}

/* Tilt wrapper — real perspective, driven by app.js */
[data-tilt] { perspective: 1000px; }
[data-tilt] > * {
  transform-style: preserve-3d;
  transform: rotateX(var(--tx, 0deg)) rotateY(var(--ty, 0deg)) translateZ(0);
  transition: transform 0.5s var(--ease);
  will-change: transform;
}

/* Product plates on light backgrounds */
.product {
  display: flex;
  flex-direction: column;
  background: var(--ink-card);
  border: 1px solid var(--ink-hair-soft);
  border-radius: var(--r-lg);
  overflow: hidden;
  height: 100%;
}
.product-figure {
  position: relative;
  background: var(--plate);
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.product-figure img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.product:hover .product-figure img { transform: scale(1.045); }
/* Figure area for a category that has no photograph yet. Same light plate and aspect
   ratio as the photographs, so the row reads as one set; the mark sits quietly in the
   middle rather than imitating a garment. */
.product-figure-mark {
  display: grid;
  place-items: center;
  background:
    radial-gradient(ellipse 70% 60% at 50% 45%, #F4F4F4 0%, var(--plate) 55%, #DEDEDE 100%);
}
.product-figure-mark .plate-mark {
  width: clamp(46px, 16%, 72px);
  height: auto;
  opacity: 0.22;
}
/* The mark's own fills are white-on-dark; invert them for the light plate. */
.product-figure-mark .plate-mark path[fill="#fff"],
.product-figure-mark .plate-mark path[stroke="#fff"] {
  fill: #0A0A0B;
  stroke: #0A0A0B;
}

.product-body { padding: clamp(1.3rem, 1rem + 1vw, 1.9rem); }
.product-body h3 { margin-bottom: var(--s-2); }
.product-body p { color: var(--fg-muted); font-size: var(--t-small); }

/* Category index ------------------------------------------------------------------ */
/* Shows the full breadth of what can be customised without inventing a photograph for
   every line. Colour swatches were removed: NAVIKS can source essentially any colour,
   so six dots understated the offer. */

.cat-index {
  margin-top: clamp(3rem, 6vw, 5rem);
  padding-top: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--ink-hair);
}
.cat-head { margin-bottom: clamp(2rem, 4vw, 3rem); max-width: 62ch; }
.cat-head h3 { font-size: var(--t-h3); margin-bottom: var(--s-3); }
.cat-head p { color: var(--fg-muted); }

.cat-grid {
  display: grid;
  gap: var(--s-6) var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.cat-group h3 {
  font-family: var(--f-text);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand);
  padding-bottom: var(--s-3);
  margin-bottom: var(--s-3);
  border-bottom: 1px solid var(--ink-hair);
}
.cat-group ul { list-style: none; padding: 0; display: grid; gap: 0.55em; }
.cat-group li {
  font-size: var(--t-small);
  color: var(--fg-muted);
  display: flex;
  align-items: baseline;
  gap: 0.6em;
}
.cat-group li::before {
  content: "";
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--ink-hair);
  flex: none;
  transform: translateY(-2px);
}

.chip-list { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; padding: 0; }
.chip-list li {
  font-size: var(--t-small);
  color: var(--fg-muted);
  background: var(--ink-raised);
  border: 1px solid var(--ink-hair-soft);
  border-radius: var(--r-sm);
  padding: 0.6em 1em;
  transition: border-color 0.3s, color 0.3s;
}
.chip-list li:hover { border-color: var(--brand-dim); color: var(--fg); }

/* Full-bleed photographic band -------------------------------------------------- */

.band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  /* Deliberately short and wide: this is a rhythm break, not a second hero. */
  height: clamp(260px, 34vw, 460px);
}
.band img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
  z-index: -2;
}
.band::after {
  /* Darken toward the left so the type has a contrast bed, but let the photograph
     actually read on the right. The previous 0.94/0.72/0.35 ramp crushed the whole
     image to near-black, which is why the band looked like an empty gap. */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(10, 10, 11, 0.9) 0%, rgba(10, 10, 11, 0.45) 42%, rgba(10, 10, 11, 0.05) 100%);
}
.band-inner {
  height: 100%;
  display: flex;
  align-items: center;
  width: min(100% - (var(--gutter) * 2), var(--shell));
  margin-inline: auto;
}
.band-line {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 0.9rem + 2.5vw, 3rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.028em;
  color: var(--fg);
  max-width: 16ch;
}
.band-line span { display: block; color: var(--brand); }

/* Technique list — a numbered editorial table rather than another grid of boxes */
.tech-list { list-style: none; padding: 0; border-top: 1px solid var(--ink-hair-soft); }
.tech-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3) var(--s-5);
  padding: clamp(1.4rem, 1rem + 1.4vw, 2.2rem) 0;
  border-bottom: 1px solid var(--ink-hair-soft);
  transition: background-color 0.4s var(--ease);
}
@media (min-width: 820px) {
  .tech-item { grid-template-columns: 4rem minmax(0, 15rem) minmax(0, 1fr) auto; align-items: baseline; }
}
.tech-item:hover { background: linear-gradient(90deg, rgba(255,222,89,0.045), transparent 70%); }
.tech-item h3 { font-size: var(--t-h3); }
.tech-item p { color: var(--fg-muted); font-size: var(--t-body); }
.tech-best {
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand);
  white-space: nowrap;
}

/* Mirrored split: the item grid takes the wide column on the left and the heading sits
   right, so this section reads against the rhythm of the ones around it. On phones the
   heading must still come first, so the DOM order is restored below the breakpoint. */
@media (min-width: 900px) {
  .split-flip { grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); align-items: center; }
  /* The heading column sits on the right, so its text has to be set right as well —
     otherwise it is a right-hand column of left-aligned text with a ragged left edge
     floating in the middle of the page. */
  .split-flip > *:last-child { text-align: right; }
  .split-flip > *:last-child h2,
  .split-flip > *:last-child .lead { margin-left: auto; }
  /* Put the eyebrow's rule on the outside of the text, mirroring the left-hand version. */
  .split-flip > *:last-child .eyebrow { flex-direction: row-reverse; }
}
@media (max-width: 899px) {
  .split-flip { display: flex; flex-direction: column-reverse; }
}

.why-item { padding-top: var(--s-5); border-top: 1px solid var(--ink-hair); }
.why-item h3 { font-size: 1.1rem; margin-bottom: var(--s-2); }
.why-item p { color: var(--fg-muted); font-size: var(--t-small); }


/* 10  Process rail (3D) ------------------------------------------------------------ */

.process { perspective: 1400px; }

.rail {
  display: grid;
  gap: var(--s-5);
  transform-style: preserve-3d;
}
@media (min-width: 900px) { .rail { grid-template-columns: repeat(4, 1fr); gap: var(--s-4); } }

.step {
  position: relative;
  padding: clamp(1.5rem, 1rem + 1.4vw, 2.1rem);
  background: linear-gradient(165deg, var(--ink-card), var(--ink-raised));
  border: 1px solid var(--ink-hair-soft);
  border-radius: var(--r-lg);
  /* Square to the page. The earlier version rotated each card progressively on Y,
     which just made a tidy row look crooked. Depth now comes from a lift on hover
     and from the connecting rule below, not from skewing content. */
  transition: transform 0.45s var(--ease), border-color 0.4s, box-shadow 0.45s var(--ease);
}
.step:hover {
  transform: translateY(-6px);
  border-color: var(--brand-dim);
  box-shadow: 0 26px 50px -26px rgba(0, 0, 0, 0.9);
}

/* A hairline joining the four steps into one sequence. */
@media (min-width: 900px) {
  .rail { position: relative; }
  .rail::before {
    content: "";
    position: absolute;
    top: 3.2rem;
    left: 6%;
    right: 6%;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--ink-hair) 15%, var(--ink-hair) 85%, transparent);
    z-index: -1;
  }
}

.step-n {
  font-family: var(--f-display);
  font-size: clamp(2.4rem, 2rem + 2vw, 3.4rem);
  font-weight: 600;
  letter-spacing: -0.05em;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px var(--brand-dim);
  margin-bottom: var(--s-4);
  transition: color 0.45s var(--ease), -webkit-text-stroke-color 0.45s;
}
.step:hover .step-n { color: var(--brand); -webkit-text-stroke-color: transparent; }

.step h3 { font-size: 1.12rem; margin-bottom: var(--s-3); }
.step p { color: var(--fg-muted); font-size: var(--t-small); }
.step-meta {
  margin-top: var(--s-5);
  padding-top: var(--s-3);
  border-top: 1px solid var(--ink-hair-soft);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-faint);
}


/* 11  FAQ -------------------------------------------------------------------------- */

.faq-list { border-top: 1px solid var(--ink-hair-soft); }

.faq-item { border-bottom: 1px solid var(--ink-hair-soft); }

.faq-q {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-5);
  padding: clamp(1.15rem, 1rem + 0.7vw, 1.6rem) 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--f-display);
  font-size: clamp(1.02rem, 0.97rem + 0.4vw, 1.22rem);
  font-weight: 550;
  letter-spacing: -0.02em;
  line-height: 1.3;
  color: var(--fg);
  transition: color 0.3s;
}
.faq-q:hover { color: var(--brand); }

.faq-icon {
  flex: none;
  position: relative;
  width: 20px; height: 20px;
  margin-top: 0.2em;
}
.faq-icon::before, .faq-icon::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.4s var(--ease);
}
.faq-icon::after { transform: rotate(90deg); }
.faq-q[aria-expanded="true"] .faq-icon::after { transform: rotate(0deg); }
.faq-q[aria-expanded="true"] { color: var(--brand); }

/* Grid-template-rows 0fr -> 1fr animates height without measuring it in JS. */
.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s var(--ease);
}
.faq-a > div { overflow: hidden; }
.faq-a p {
  color: var(--fg-muted);
  font-size: var(--t-body);
  max-width: 68ch;
  padding-bottom: var(--s-5);
}
.faq-q[aria-expanded="true"] + .faq-a { grid-template-rows: 1fr; }


/* 12  Form ------------------------------------------------------------------------- */

.form-wrap {
  position: relative;
  padding: clamp(1.5rem, 1rem + 2.4vw, 3rem);
  background: var(--ink-card);
  border: 1px solid var(--ink-hair);
  border-radius: var(--r-xl);
}

.form-grid { display: grid; gap: var(--s-5); }
@media (min-width: 720px) { .form-grid.cols-2 { grid-template-columns: 1fr 1fr; } }

fieldset { border: 0; padding: 0; margin: 0; }
legend {
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-faint);
  padding: 0 0 var(--s-4);
}

.field { display: flex; flex-direction: column; gap: 0.55em; min-width: 0; }
.field label { font-size: var(--t-small); font-weight: 500; color: var(--fg); }
.field .opt { color: var(--fg-faint); font-weight: 400; }
.req { color: var(--brand); }

.field input, .field select, .field textarea {
  width: 100%;
  padding: 0.95em 1.05em;
  background: var(--ink-raised);
  border: 1px solid var(--ink-hair);
  border-radius: var(--r-md);
  color: var(--fg);
  font-size: var(--t-small);
  transition: border-color 0.3s, background-color 0.3s, box-shadow 0.3s;
  appearance: none;
}
.field textarea { min-height: 8.5rem; resize: vertical; line-height: 1.6; }

.field input::placeholder, .field textarea::placeholder { color: var(--fg-faint); }

.field input:hover, .field select:hover, .field textarea:hover { border-color: #34343C; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--brand);
  background: #17171B;
  box-shadow: 0 0 0 3px rgba(255, 222, 89, 0.13);
}

/* Native select arrow is inconsistent across platforms; draw our own. */
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23A2A2AC' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.05em center;
  padding-right: 2.6em;
  cursor: pointer;
}
.field select option { background: #17171B; color: var(--fg); }

.field[data-invalid="true"] input,
.field[data-invalid="true"] select,
.field[data-invalid="true"] textarea { border-color: var(--danger); }

.field-error {
  font-size: var(--t-micro);
  color: var(--danger);
  min-height: 1em;
}
.field:not([data-invalid="true"]) .field-error { display: none; }

/* Consent checkbox */
.consent {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  align-items: start;
  font-size: var(--t-small);
  color: var(--fg-muted);
}
.consent input[type="checkbox"] {
  appearance: none;
  width: 20px; height: 20px;
  margin-top: 0.15em;
  border: 1px solid var(--ink-hair);
  border-radius: 5px;
  background: var(--ink-raised);
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: background-color 0.2s, border-color 0.2s;
  flex: none;
}
.consent input[type="checkbox"]::after {
  content: "";
  width: 10px; height: 6px;
  border-left: 2px solid #000;
  border-bottom: 2px solid #000;
  transform: rotate(-45deg) scale(0);
  transition: transform 0.2s var(--ease);
}
.consent input[type="checkbox"]:checked { background: var(--brand); border-color: var(--brand); }
.consent input[type="checkbox"]:checked::after { transform: rotate(-45deg) scale(1); }

/* Honeypot — must be reachable by bots but never by humans or screen readers.
   display:none is skipped by some bots, so it is positioned off-canvas instead. */
.hp {
  position: absolute !important;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.form-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  justify-content: space-between;
  margin-top: var(--s-3);
}
.form-note { font-size: var(--t-micro); color: var(--fg-faint); }

.btn[data-busy="true"] { opacity: 0.65; pointer-events: none; }

.spinner {
  width: 14px; height: 14px;
  border: 2px solid rgba(0, 0, 0, 0.25);
  border-top-color: #000;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Result panels */
.form-result {
  display: none;
  padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  border-radius: var(--r-lg);
  border: 1px solid;
}
.form-result[data-show="true"] { display: block; }
.form-result h3 { margin-bottom: var(--s-3); }
.form-result.is-ok { border-color: rgba(111, 227, 166, 0.35); background: rgba(111, 227, 166, 0.06); }
.form-result.is-ok h3 { color: var(--ok); }
.form-result.is-err { border-color: rgba(255, 107, 90, 0.35); background: rgba(255, 107, 90, 0.06); }
.form-result.is-err h3 { color: var(--danger); }
.form-result p { color: var(--fg-muted); }

/* Contact rows: label above value, each separated by a hairline, all flush left so the
   column reads as one aligned stack with the promise block above it. */
.contact-aside { display: flex; flex-direction: column; margin: 0; }
.contact-line {
  display: flex;
  flex-direction: column;
  gap: 0.25em;
  padding: var(--s-4) 0;
  border-top: 1px solid var(--ink-hair-soft);
}
.contact-line:first-child { border-top: 0; }
.contact-line dt {
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.contact-line dd { margin: 0; font-size: var(--t-lead); line-height: 1.35; }


/* 13  Footer & cookie bar ---------------------------------------------------------- */

.site-footer {
  position: relative;
  z-index: 1;
  padding-top: var(--s-9);
  padding-bottom: var(--s-6);
  border-top: 1px solid var(--ink-hair-soft);
  background: var(--ink-raised);
}

.footer-grid { display: grid; gap: var(--s-7); }
@media (min-width: 860px) {
  .footer-grid { grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr)); gap: var(--s-6); }
}
/* The logo is a fixed 500x100 bitmap. The global `img { max-width: 100% }` was
   clamping its width inside the narrow footer column while `height` stayed pinned at
   28px — which squashes it horizontally. Pin the width instead and let height follow,
   with object-fit as a belt-and-braces guard against any future squeeze. */
.footer-brand img {
  width: 140px;
  height: auto;
  max-width: none;
  object-fit: contain;
  margin-bottom: var(--s-4);
}
.footer-brand p { color: var(--fg-faint); font-size: var(--t-small); max-width: 34ch; }

.footer-col h4 {
  font-family: var(--f-text);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: var(--s-4);
}
.footer-col ul { list-style: none; padding: 0; display: grid; gap: var(--s-3); }

/* Icon + label rows. The Instagram handle used to be bare text while LinkedIn was a
   word — now both read as the same kind of thing. */
.social {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  min-height: 28px;
}
.social svg { flex: none; opacity: 0.75; transition: opacity 0.25s, color 0.25s; }
.social:hover svg { opacity: 1; }
.footer-col a, .footer-col span { font-size: var(--t-small); color: var(--fg-muted); transition: color 0.25s; }
.footer-col a:hover { color: var(--brand); }

.footer-legal {
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--ink-hair-soft);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  justify-content: space-between;
  font-size: var(--t-micro);
  color: var(--fg-faint);
}
.footer-legal p { max-width: 70ch; }
.footer-legal button {
  background: none; border: 0; padding: 0;
  color: inherit; cursor: pointer; text-decoration: underline;
  text-underline-offset: 3px;
}
/* The cookie-settings control lives in a link list, so give it the same touch height
   as its neighbours rather than the bare text height a <button> collapses to. */
.footer-col button {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  background: none;
  border: 0;
  padding: 0;
  color: var(--fg-muted);
  font-size: var(--t-small);
  cursor: pointer;
  text-align: left;
  transition: color 0.25s;
}
.footer-col button:hover { color: var(--brand); }
.footer-legal button:hover { color: var(--brand); }

.cookie-bar {
  position: fixed;
  left: var(--gutter); right: var(--gutter);
  bottom: var(--s-4);
  z-index: 200;
  max-width: 640px;
  margin-inline: auto;
  padding: var(--s-5);
  background: color-mix(in srgb, var(--ink-card) 94%, transparent);
  backdrop-filter: blur(16px);
  border: 1px solid var(--ink-hair);
  border-radius: var(--r-lg);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.9);
  transform: translateY(calc(100% + 2rem));
  transition: transform 0.55s var(--ease);
}
.cookie-bar[data-open="true"] { transform: translateY(0); }
.cookie-bar h4 { font-family: var(--f-display); font-size: 1rem; margin-bottom: var(--s-2); }
.cookie-bar p { font-size: var(--t-small); color: var(--fg-muted); margin-bottom: var(--s-4); }
.cookie-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }
/* Keep the 44px comfortable-touch floor even at the smaller cookie-bar type size. */
.cookie-actions .btn { padding: 0.7em 1.4em; font-size: var(--t-micro); min-height: 44px; }

@media (max-width: 767px) {
  /* Bottom sheet, flush to the edge. Floating it with side gutters above the sticky
     CTA stacked two bars over the content and ate a third of the screen. */
  .cookie-bar {
    left: 0; right: 0; bottom: 0;
    max-width: none;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    padding: var(--s-4) var(--gutter);
    padding-bottom: calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
  }
  .cookie-bar h4 { font-size: 0.95rem; }
  .cookie-bar p { font-size: var(--t-micro); margin-bottom: var(--s-3); }
  /* Two equal buttons on one row — wrapping made it look broken. */
  .cookie-actions { flex-wrap: nowrap; gap: var(--s-2); }
  .cookie-actions .btn { flex: 1; padding: 0.7em 0.8em; }
  /* The sticky CTA is suppressed by app.js while this is open, so no double stack. */
}


/* Sticky mobile CTA --------------------------------------------------------------- */
/* Phones only. On desktop the header CTA is always visible, so a bar would just be
   chrome stealing viewport. */

.sticky-cta {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3) var(--gutter);
  /* Clear the iOS home indicator. */
  padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--ink-card) 94%, transparent);
  backdrop-filter: blur(16px);
  border-top: 1px solid var(--ink-hair);
  transform: translateY(110%);
  transition: transform 0.4s var(--ease);
}
@media (max-width: 767px) { .sticky-cta { display: flex; } }
.sticky-cta[data-show="true"] { transform: translateY(0); }
.sticky-label {
  font-size: var(--t-micro);
  color: var(--fg-muted);
  line-height: 1.25;
  max-width: 15ch;
}
.sticky-cta .btn { padding: 0.85em 1.3em; font-size: var(--t-micro); min-height: 44px; flex: none; }

/* Keep the cookie bar clear of the sticky CTA when both are on screen. */
@media (max-width: 767px) {
  .cookie-bar { bottom: calc(var(--s-4) + 68px); }
}

/* Response-time promise ------------------------------------------------------------ */

/* Accent sits on TOP, not on the side. A left bar forced a 24px text indent that broke
   alignment with the contact details stacked beneath it — visible as a ragged left edge.
   A top rule keeps every block in this column on the same left edge. */
.promise {
  position: relative;
  padding: var(--s-5) 0 0;
  border-top: 2px solid var(--brand);
  background: none;
}
.promise h3 { font-size: 1.05rem; margin-bottom: var(--s-2); }
.promise p { color: var(--fg-muted); font-size: var(--t-small); }

/* Link lists (internal linking blocks) --------------------------------------------- */

.link-list { list-style: none; padding: 0; display: grid; gap: var(--s-3); }
.link-list a { font-size: var(--t-small); }

/* Thank-you page ------------------------------------------------------------------- */

.thanks-steps { list-style: none; padding: 0; display: grid; gap: var(--s-5); }
.thanks-step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--ink-hair-soft);
}
.thanks-step h3 { font-size: 1.02rem; margin-bottom: var(--s-2); }
.thanks-step p { color: var(--fg-muted); font-size: var(--t-small); }

/* Proof / sponsorship ------------------------------------------------------------- */

.proof-grid { align-items: center; }

.proof-figure {
  margin: 0;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--ink-hair);
  background: var(--ink-card);
}
.proof-figure img {
  width: 100%;
  /* A phone snapshot is portrait; crop it to a calm landscape band so it sits on the
     grid instead of towering over the column beside it. */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 62%;
  display: block;
}
.proof-figure figcaption {
  padding: var(--s-4) var(--s-5);
  font-size: var(--t-micro);
  color: var(--fg-faint);
  border-top: 1px solid var(--ink-hair-soft);
}

.proof-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--s-5);
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid var(--ink-hair-soft);
}
.proof-stats dt {
  font-family: var(--f-display);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--brand);
}
.proof-stats dd { margin: 0.3em 0 0; font-size: var(--t-small); color: var(--fg-faint); }

/* References ----------------------------------------------------------------------- */

.ref-figure {
  margin: calc(-1 * clamp(1.6rem, 1rem + 1.6vw, 2.4rem));
  margin-bottom: var(--s-5);
  background: var(--plate);
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.ref-figure img { width: 100%; height: 100%; object-fit: cover; }
.ref-client {
  font-family: var(--f-display);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--brand);
  margin-bottom: var(--s-3);
}
.ref-quote {
  margin: var(--s-5) 0 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--ink-hair-soft);
}
.ref-quote p { font-size: var(--t-small); color: var(--fg); font-style: italic; }
.ref-quote cite {
  display: block;
  margin-top: var(--s-2);
  font-size: var(--t-micro);
  font-style: normal;
  color: var(--fg-faint);
}

/* Legal / long-form pages */
.prose { max-width: 72ch; }
.prose h2 { font-size: clamp(1.4rem, 1.2rem + 1vw, 1.9rem); margin: var(--s-8) 0 var(--s-4); }
.prose h3 { font-size: 1.1rem; margin: var(--s-6) 0 var(--s-3); }
.prose p, .prose li { color: var(--fg-muted); margin-bottom: var(--s-4); }
.prose ul { padding-left: 1.2rem; }
.prose li { margin-bottom: var(--s-2); }
.prose a { color: var(--brand); text-decoration: underline; text-underline-offset: 3px; }
.prose table { width: 100%; border-collapse: collapse; margin: var(--s-5) 0; font-size: var(--t-small); }
.prose th, .prose td { text-align: left; padding: var(--s-3); border-bottom: 1px solid var(--ink-hair-soft); }
.prose th { color: var(--fg); font-weight: 600; }
.prose td { color: var(--fg-muted); }

.page-head { padding-top: clamp(8rem, 16vh, 11rem); padding-bottom: var(--s-6); }
.page-head h1 {
  font-size: clamp(2.2rem, 1.5rem + 3.2vw, 4.2rem);
  margin: var(--s-4) 0 var(--s-5);
}
.crumb {
  display: flex;
  align-items: center;
  gap: 0.55em;
  font-size: var(--t-micro);
  color: var(--fg-faint);
  letter-spacing: 0.08em;
}
.crumb a:hover { color: var(--brand); }
.crumb [aria-current="page"] { color: var(--fg-muted); }


/* 14  Motion ----------------------------------------------------------------------- */

/* Entrance reveal. Applied only once the element is observed, so nothing is hidden
   if JS fails — the .reveal class is added by app.js, not present in the HTML. */
.reveal { opacity: 0; transform: translateY(22px); }
.reveal.in {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--delay, 0ms);
}

/* =====================================================================================
   Mobile pass
   Everything below targets phones specifically. The desktop layout scaled down
   mechanically but read as cramped: type too large for the measure, sections too tall,
   cards too padded, and the sticky bar overlapping content at the bottom of the page.
   ===================================================================================== */

@media (max-width: 767px) {
  :root {
    /* Tighter rhythm — the desktop scale left phone screens mostly empty space. */
    --section-y: clamp(3rem, 7vw, 4rem);
    --gutter: 1.25rem;
    --t-hero: clamp(2.1rem, 1rem + 7.2vw, 3rem);
    --t-h2: clamp(1.6rem, 1.1rem + 4vw, 2.2rem);
    --t-lead: 1rem;
  }

  .hero {
    min-height: auto;
    padding-top: 7.5rem;
    padding-bottom: var(--s-8);
  }
  .hero h1 { max-width: 100%; }
  .hero-lead { max-width: 100%; }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; }

  /* Three facts stacked in one column wastes the width; two up reads better. */
  .hero-facts { grid-template-columns: repeat(2, 1fr); gap: var(--s-4); text-align: left; }
  .hero-facts > div:last-child:nth-child(odd) { grid-column: 1 / -1; }

  .section-head { margin-bottom: var(--s-6); }
  .section-head h2 { max-width: 100%; }

  .card, .form-wrap { padding: var(--s-5); }
  .product-body { padding: var(--s-5); }

  /* Long-form legal tables overflow at phone width; let them scroll on their own. */
  .prose table { display: block; overflow-x: auto; white-space: nowrap; }

  /* Give the sticky CTA room so it never covers the last element on the page. */
  .site-footer { padding-bottom: 6.5rem; }

  .form-foot { flex-direction: column; align-items: stretch; gap: var(--s-4); }
  .form-foot .btn { width: 100%; }
  .form-note { order: 2; text-align: center; }

  .footer-legal { flex-direction: column; gap: var(--s-3); }

  .band { height: clamp(210px, 46vw, 300px); }
  .band-line { max-width: 12ch; }

  .proof-figure img { aspect-ratio: 3 / 2; }

  .thanks-step { grid-template-columns: 1fr; gap: var(--s-2); }

  /* 16px minimum on every control, or iOS Safari zooms the page on focus. */
  input, select, textarea { font-size: 16px; }

  /* WCAG 2.5.8 wants a 24px minimum target; the checkbox was 20px. */
  .consent input[type="checkbox"] { width: 24px; height: 24px; }
  .consent input[type="checkbox"]::after { width: 11px; height: 7px; }

  /* The badge repeats the first fact ("od 25 kosov") verbatim — on a phone that is a
     wasted line above the fold. */
  .hero-badge { display: none; }
  .hero h1 { margin-block: var(--s-4) var(--s-5); }
  .hero-facts { margin-top: var(--s-6); }

  .brand img { width: 132px; }
  .brand { padding-block: var(--s-2); }
}

@media (max-width: 420px) {
  .hero-facts { grid-template-columns: 1fr; }
  .chip-list li { font-size: var(--t-micro); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  /* Frames keep their static composition — that is layout, not motion. Only the
     pointer-driven tilt and hover lifts are suppressed. */
  .deck, .step, [data-tilt] > * { transform: none !important; }
  .scroll-hint .bar { animation: none; }
}

@media print {
  body::before, .site-header, .cookie-bar, .scroll-hint, .mark3d, .stage { display: none !important; }
  body { background: #fff; color: #000; }
  .card, .step, .form-wrap { border-color: #ccc; }
}
