/* ---------- Typefaces ----------
   Self-hosted. The design has always named Archivo, Inter, IBM Plex Mono and
   Caveat, but nothing ever loaded them, so every visitor saw the system
   fallbacks — the CEO signature included. These are the real faces, served
   from our own origin.

   Self-hosting rather than linking Google's CDN keeps the visitor's IP away
   from a third party, which is what the Munich Google Fonts ruling was about,
   and it is what the privacy policies now state in all three languages.

   Archivo and Inter are variable fonts: one file spans the whole weight range
   the design uses, which is smaller than shipping each weight separately.
   IBM Plex Mono has no variable build on Google Fonts, so 400 and 500 are
   static. Caveat is only ever used by the signature, so a browser on any
   other page never downloads it — a face is fetched only when something on
   the page actually renders in it.

   latin covers Finnish, Swedish and German; latin-ext adds the Central and
   Eastern European letters that turn up in consignee names. Licensed under
   the SIL Open Font License 1.1. Regenerate with tools/fetch-fonts.sh. */

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

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

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

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

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

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

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

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

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

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

/* ============================================================
   Nordic Swift — Design System
   Thesis: "Blue hour." The brand violet (#7A63FF) is the colour
   of the Nordic sky over a container port at dusk. Colour is
   earned from photography, never from decorative gradients.
   ============================================================ */


/* ---------- Tokens ---------- */
:root {
  /* Surfaces — near-black with a blue cast, matching dusk */
  --ink:        #08080D;
  --ink-2:      #0E0E16;
  --ink-3:      #15151F;
  --ink-4:      #1E1E2B;

  /* Brand violet, sampled from the logo mark */
  --violet:      #7A63FF;  /* accents, links on dark — 4.75:1 on --ink */
  --violet-lift: #9B8AFF;  /* hover */
  --violet-btn:  #6B52F0;  /* button fill w/ white text — 5.1:1 */
  --violet-deep: #3D2E8A;

  /* Text */
  --paper:  #F5F5FA;
  --muted:  #A6A6BC;   /* 8.1:1 on --ink */
  --faint:  #82829C;   /* 4.9:1 on --ink-2 — the smallest labels still pass AA */

  --border:      rgba(255,255,255,.10);
  --border-lift: rgba(255,255,255,.20);

  /* Type */
  --display: 'Archivo', system-ui, sans-serif;
  --body:    'Inter', system-ui, sans-serif;
  --mono:    'IBM Plex Mono', ui-monospace, monospace;
  --script:  'Caveat', 'Segoe Script', cursive;

  /* Spacing — 8pt rhythm */
  --s-1: 8px;  --s-2: 16px; --s-3: 24px; --s-4: 32px;
  --s-5: 48px; --s-6: 64px; --s-7: 96px; --s-8: 128px;

  --wrap: 1280px;
  --radius: 4px;   /* restrained — engineered, not soft */

  --ease: cubic-bezier(.22,.61,.36,1);
  --dur: 240ms;

  --z-nav: 100; --z-menu: 200;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--s-3); }
@media (min-width: 768px) { .wrap { padding-inline: var(--s-5); } }

.section { padding-block: var(--s-7); position: relative; }
@media (min-width: 1024px) { .section { padding-block: var(--s-8); } }

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--violet-btn); color: #fff;
  padding: var(--s-2) var(--s-3); z-index: 999;
}
.skip:focus { left: var(--s-2); top: var(--s-2); }

:focus-visible {
  outline: 2px solid var(--violet-lift);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- Type ---------- */
.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--violet);
  display: flex; align-items: center; gap: var(--s-2);
  margin: 0 0 var(--s-3);
}
.eyebrow::before {
  content: ''; width: 28px; height: 1px;
  background: var(--violet); flex: none;
}

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -.025em;
  margin: 0 0 var(--s-3);
  text-wrap: balance;
}
h1 { font-size: clamp(2.75rem, 8.5vw, 6.5rem); font-weight: 900; letter-spacing: -.035em; }
h2 { font-size: clamp(2rem, 5vw, 3.75rem); }
h3 { font-size: clamp(1.25rem, 2.2vw, 1.75rem); letter-spacing: -.015em; }

p { margin: 0 0 var(--s-3); max-width: 68ch; }
.lead { font-size: clamp(1.0625rem, 1.6vw, 1.3125rem); color: var(--muted); line-height: 1.6; }
.muted { color: var(--muted); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-1);
  min-height: 52px; padding: 0 var(--s-4);
  border-radius: var(--radius);
  font-family: var(--body); font-weight: 600; font-size: 16px;
  border: 1px solid transparent;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
  text-align: center;
}
.btn:active { transform: scale(.985); }
.btn--primary { background: var(--violet-btn); color: #fff; }
.btn--primary:hover { background: var(--violet-lift); color: var(--ink); }
.btn--ghost { border-color: var(--border-lift); color: var(--paper); background: transparent; }
.btn--ghost:hover { border-color: var(--violet); color: var(--violet-lift); }
.btn--block { width: 100%; }

/* ---------- Header ----------
   Matches the original nordicswift.fi chrome: stacked logo left, centred nav
   with wide tracking, violet language pill right. */
.hdr {
  position: fixed; inset: 0 0 auto 0; z-index: var(--z-nav);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
  border-bottom: 1px solid transparent;
  background: rgba(8,8,13,.72);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.hdr--solid {
  background: rgba(8,8,13,.88);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--border);
}
.hdr__in { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); min-height: 84px; }
@media (min-width: 1024px) { .hdr__in { min-height: 104px; } }

/* Stacked lockup: mark above wordmark + tagline, as on the original site */
.hdr__logo--stack { flex-direction: column; align-items: flex-start; gap: 4px; }
.hdr__logo--stack img { height: 34px; }
@media (min-width: 1024px) { .hdr__logo--stack img { height: 40px; } }
.hdr__logo--stack .hdr__word { font-size: 18px; line-height: 1; }
@media (min-width: 1024px) { .hdr__logo--stack .hdr__word { font-size: 21px; } }
.hdr__tag {
  font-family: var(--body); font-size: 8.5px; font-weight: 500;
  letter-spacing: .07em; color: var(--muted); line-height: 1; white-space: nowrap;
}
@media (min-width: 1024px) { .hdr__tag { font-size: 9.5px; } }
/* Horizontal lockup: the cropped plane mark + the wordmark set in type.
   The supplied logo is a stacked lockup — at header size its wordmark
   and tagline become illegible, so we rebuild it horizontally. */
.hdr__logo { display: flex; align-items: center; gap: 11px; flex: none; min-height: 44px; }
.hdr__logo img { height: 30px; width: auto; }
.hdr__word {
  font-family: var(--display); font-weight: 800; font-size: 20px;
  letter-spacing: -.035em; color: var(--paper); white-space: nowrap;
}
@media (max-width: 420px) { .hdr__word { font-size: 17px; } }
.hdr__nav { display: none; gap: var(--s-4); align-items: center; }
@media (min-width: 1024px) { .hdr__nav { display: flex; } }
.hdr__nav > a, .hdr__nav .hasmenu > a {
  font-size: 15px; font-weight: 400; color: var(--muted);
  letter-spacing: .04em;                 /* wide tracking, as on the original */
  padding: var(--s-1) 0; position: relative;
  display: inline-flex; align-items: center; gap: 5px;
  transition: color var(--dur) var(--ease);
}
.hdr__nav a[aria-current="page"] { color: var(--violet); }
.hdr__nav a {
  font-size: 15px; font-weight: 400; color: var(--muted);
  padding: var(--s-1) 0; position: relative;
  transition: color var(--dur) var(--ease);
}

/* Services dropdown */
.hasmenu { position: relative; }
.hasmenu__panel {
  position: absolute; left: 50%; top: calc(100% + 14px); transform: translateX(-50%);
  background: var(--ink-3); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 8px; min-width: 460px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
  box-shadow: 0 24px 60px rgba(0,0,0,.6);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur);
}
.hasmenu__panel::before { content: ''; position: absolute; inset: -14px 0 auto 0; height: 14px; }
.hasmenu:hover .hasmenu__panel,
.hasmenu:focus-within .hasmenu__panel {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.hasmenu__panel a {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px var(--s-2); border-radius: 3px; min-height: 44px; justify-content: center;
  transition: background var(--dur) var(--ease);
}
.hasmenu__panel a:hover { background: var(--ink-4); }
.hasmenu__panel strong { font-size: 14.5px; font-weight: 600; color: var(--paper); letter-spacing: 0; }
.hasmenu__panel span { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: var(--faint); text-transform: uppercase; }
.hasmenu__panel a:hover span { color: var(--violet); }
.hasmenu__caret { transition: transform var(--dur) var(--ease); }
.hasmenu:hover .hasmenu__caret { transform: rotate(180deg); }
.hdr__nav a::after {
  content: ''; position: absolute; left: 0; bottom: 0; height: 1px; width: 0;
  background: var(--violet); transition: width var(--dur) var(--ease);
}
.hdr__nav a:hover { color: var(--paper); }
.hdr__nav a:hover::after { width: 100%; }
.hdr__right { display: flex; align-items: center; gap: var(--s-2); }
/* Below the desktop breakpoint the burger owns the header: the quote CTA
   lives in the drawer, so showing it here too overflows 375px.
   The language switcher STAYS — pages without a burger (privacy, thank-you)
   would otherwise have no way to change language on a phone. */
@media (max-width: 1023px) {
  .hdr__right .btn { display: none; }
}

/* Language switcher */
.lang { position: relative; }
.lang__btn {
  display: flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 var(--s-2);
  background: transparent; border: 1px solid var(--border);
  border-radius: var(--radius); color: var(--paper);
  font-family: var(--mono); font-size: 12px; letter-spacing: .1em;
  transition: border-color var(--dur) var(--ease);
}
.lang__btn:hover { border-color: var(--border-lift); }
.lang__menu {
  position: absolute; right: 0; top: calc(100% + 8px);
  background: var(--ink-3); border: 1px solid var(--border);
  border-radius: var(--radius); min-width: 168px; padding: 6px;
  display: none; z-index: var(--z-menu);
  box-shadow: 0 18px 40px rgba(0,0,0,.5);
}
.lang[data-open="true"] .lang__menu { display: block; }
.lang__menu a {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-2); min-height: 44px; padding: 0 var(--s-2);
  border-radius: 2px; font-size: 14px; color: var(--muted);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.lang__menu a:hover { background: var(--ink-4); color: var(--paper); }
.lang__menu a[aria-current="true"] { color: var(--violet); }
.lang__menu code { font-family: var(--mono); font-size: 11px; color: var(--faint); }

/* Mobile menu */
.burger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; background: transparent;
  border: 1px solid var(--border); border-radius: var(--radius); color: var(--paper);
}
@media (min-width: 1024px) { .burger { display: none; } }
.drawer {
  position: fixed; inset: 0; z-index: var(--z-menu);
  background: var(--ink); padding: var(--s-3);
  display: none; flex-direction: column;
  overflow-y: auto;
}
.drawer[data-open="true"] { display: flex; }
.drawer__top { display: flex; justify-content: space-between; align-items: center; min-height: 76px; }
.drawer nav { display: flex; flex-direction: column; margin-top: var(--s-4); }
.drawer nav a {
  font-family: var(--display); font-weight: 700; font-size: 1.75rem;
  padding: var(--s-2) 0; border-bottom: 1px solid var(--border);
  letter-spacing: -.02em;
}

/* ---------- Hero ---------- */
.hero { position: relative; min-height: 100svh; display: flex; align-items: flex-end; overflow: hidden; }
/* On narrow screens the hero copy is taller than the viewport, so the
   block must be allowed to grow and clear the fixed header rather than
   bottom-align and slide underneath it. */
@media (max-width: 767px) { .hero { min-height: 0; align-items: stretch; } }
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.hero__scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(8,8,13,.82) 0%, rgba(8,8,13,.30) 34%, rgba(8,8,13,.72) 76%, var(--ink) 100%),
    linear-gradient(90deg, rgba(8,8,13,.74) 0%, rgba(8,8,13,.10) 62%);
}
.hero__in { position: relative; z-index: 2; width: 100%; padding-block: 116px var(--s-6); }
@media (min-width: 768px) { .hero__in { padding-block: var(--s-7) var(--s-6); } }
.hero h1 { margin-bottom: var(--s-3); max-width: 16ch; }
.hero__sub { font-size: clamp(1.0625rem, 2vw, 1.4375rem); color: var(--paper); opacity: .92; max-width: 46ch; margin-bottom: var(--s-4); }
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-bottom: var(--s-5); }

/* Manifest strip — the site's signature device.
   Reads like a shipping manifest / customs reference line. */
.manifest {
  display: grid; gap: 1px;
  grid-template-columns: repeat(2, 1fr);
  background: var(--border);
  border-block: 1px solid var(--border);
}
@media (min-width: 768px) { .manifest { grid-template-columns: repeat(4, 1fr); } }
.manifest__cell { background: var(--ink); padding: var(--s-3) var(--s-2); }
.hero .manifest__cell { background: rgba(8,8,13,.72); backdrop-filter: blur(6px); }
.manifest__k {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint); margin: 0 0 6px;
}
.manifest__v {
  font-family: var(--display); font-weight: 800; font-size: clamp(1.5rem, 3vw, 2.25rem);
  letter-spacing: -.03em; margin: 0; line-height: 1; color: var(--paper);
  font-variant-numeric: tabular-nums; /* stops width jitter while counting */
}
.manifest__v em { font-style: normal; color: var(--violet); }

.scrollcue {
  position: absolute; left: 50%; bottom: var(--s-3); transform: translateX(-50%);
  z-index: 2; font-family: var(--mono); font-size: 10px; letter-spacing: .2em;
  color: var(--faint); text-transform: uppercase;
  display: none;
}
@media (min-width: 1024px) { .scrollcue { display: block; } }

/* ---------- Split (story / CEO) ---------- */
.split { display: grid; gap: var(--s-5); align-items: center; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; gap: var(--s-6); } }
.split--wide { grid-template-columns: 1fr; }
@media (min-width: 900px) { .split--wide { grid-template-columns: 1.05fr .95fr; } }
.split__media { position: relative; }
/* height:auto is required — the img carries width/height attributes (good for
   CLS), but those act as presentational hints that override aspect-ratio.
   Without this the image renders at its full intrinsic height (1500px) and
   leaves a huge empty column beside the text. */
.split__media img {
  width: 100%; height: auto; aspect-ratio: 3/2;
  object-fit: cover; border-radius: var(--radius);
}
.split__media--tall img { aspect-ratio: 3/4; }
.portrait img { height: auto; }

/* ---------- Full-bleed band ----------
   For the network map: a panoramic asset earns the full width rather than
   being cropped into a side column. */
.band { position: relative; overflow: hidden; border-block: 1px solid var(--border); }
.band__media { position: absolute; inset: 0; z-index: 0; }
.band__media img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
.band__scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(90deg, var(--ink) 0%, rgba(8,8,13,.90) 38%, rgba(8,8,13,.45) 68%, rgba(8,8,13,.72) 100%),
    linear-gradient(180deg, var(--ink) 0%, rgba(8,8,13,0) 22%, rgba(8,8,13,0) 78%, var(--ink) 100%);
}
.band__in { position: relative; z-index: 2; padding-block: var(--s-7); }
@media (min-width: 1024px) { .band__in { padding-block: var(--s-8); } }
.band__copy { max-width: 60ch; }
@media (min-width: 900px) { .band__copy { max-width: 46ch; } }

/* ---------- Services ---------- */
.svc-grid { display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); }
@media (min-width: 640px)  { .svc-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .svc-grid { grid-template-columns: repeat(4, 1fr); } }

.svc {
  background: var(--ink); padding: var(--s-4) var(--s-3) var(--s-5);
  position: relative; display: flex; flex-direction: column;
  min-height: 300px;
  overflow: hidden;
  /* Cards are links now — lift slightly on hover. transform + box-shadow only,
     so neighbouring cards never reflow. */
  transition: background var(--dur) var(--ease),
              transform 320ms var(--ease),
              box-shadow 320ms var(--ease);
  will-change: transform;
}
.svc:hover, .svc:focus-visible {
  transform: translateY(-6px);
  box-shadow: 0 22px 48px rgba(0,0,0,.55);
  z-index: 2;
}
.svc:active { transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) {
  .svc:hover, .svc:focus-visible { transform: none; }
}
.svc__go {
  margin-top: auto; padding-top: var(--s-3);
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--violet);
  opacity: 0; transform: translateX(-6px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.svc:hover .svc__go, .svc:focus-visible .svc__go { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .svc__go { opacity: 1; transform: none; } }
.svc__go svg { width: 14px; height: 14px; }
.svc::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 2px;
  background: var(--violet); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.svc:hover { background: var(--ink-2); }
.svc:hover::after { transform: scaleX(1); }
.svc__no {
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  color: var(--faint); margin-bottom: var(--s-3);
}
.svc:hover .svc__no { color: var(--violet); }
.svc h3 { margin-bottom: var(--s-2); }
.svc p { font-size: 15px; color: var(--muted); margin: 0; line-height: 1.6; }
.svc__img {
  position: absolute; inset: 0; z-index: 0; opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.svc__img img { width: 100%; height: 100%; object-fit: cover; }
.svc__img::after { content: ''; position: absolute; inset: 0; background: rgba(8,8,13,.86); }
.svc:hover .svc__img { opacity: 1; }
/* Lift only the CONTENT above the hover image. Excluding .svc__img is
   essential: a bare `.svc > *` would override its position:absolute back
   to relative, dropping the image into flow and pushing the text down. */
.svc > *:not(.svc__img) { position: relative; z-index: 1; }

/* ---------- Trust / credentials ---------- */
/* Text first, then the videos full width — squeezed into a side column they
   were too small to notice. */
.trust { display: grid; gap: var(--s-5); }
@media (min-width: 900px) { .trust { gap: var(--s-6); } }
.badges { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; margin-top: var(--s-4); }
.badge {
  display: flex; align-items: center; gap: var(--s-2);
  background: var(--ink-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--s-2) var(--s-3);
}
.badge img { height: 76px; width: auto; }
a.badge { transition: border-color var(--dur) var(--ease); }
a.badge:hover { border-color: var(--violet); }

/* The GLA asset is a full certificate document, not a logo. At badge size the
   text is unreadable, so it scales up on hover/focus to be legible. */
.badge--doc { overflow: visible; }
.badge--doc img {
  height: 124px; border: 1px solid var(--border); background: #fff;
  transform-origin: left center; position: relative; z-index: 1;
  transition: transform 320ms var(--ease), box-shadow 320ms var(--ease);
}
/* The certificate opens in the shared lightbox, centred in the viewport.
   Scaling it in place pushed it off the right edge — it sits near the margin,
   so there was never room to grow into. */
.badge--doc { cursor: zoom-in; }
.badge--doc:hover img, .badge--doc:focus-visible img { transform: scale(1.04); }
.badge--doc:hover { border-color: var(--violet); }
.badge--doc .badge__zoom {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--violet); margin-top: 6px;
}
.badge--doc .badge__zoom svg { width: 12px; height: 12px; }

/* image variant of the lightbox */
.lb__box img {
  width: 100%; height: auto; max-height: 84vh; object-fit: contain;
  background: #fff; border-radius: var(--radius);
  border: 1px solid var(--border-lift);
}
.lb__box--img { width: min(92vw, 620px); }
@media (prefers-reduced-motion: reduce) {
  .badge--doc:hover img, .badge--doc:focus-visible img { transition: none; }
}
/* the scaled certificate must not be clipped by its section */
#credentials, .trust, .badges { overflow: visible; }
.badge span { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

/* One video per page. Centred rather than left-aligned — off to one side it
   left a large empty field beside it. */
.vidgrid {
  display: grid; gap: var(--s-3); grid-template-columns: 1fr;
  /* min(), not a bare 420px: `.credrow .vidgrid` sets `flex: 0 0 auto`, so on a
     412px phone this held its full 420px and pushed the page 4px wide. On any
     screen wider than 420px the min() resolves to 420px, so desktop is
     unchanged. */
  max-width: min(420px, 100%); margin-inline: auto;
}

/* ---------- Credential row: badge | video | badge ---------- */
.credrow {
  display: flex; align-items: center; justify-content: center;
  gap: var(--s-4); flex-wrap: wrap;
}
@media (min-width: 980px) { .credrow { gap: var(--s-5); flex-wrap: nowrap; } }
.credrow .vidgrid { margin: 0; flex: 0 0 auto; }
.credrow .badge { flex: 0 0 auto; flex-direction: column; text-align: center; gap: var(--s-2); }
@media (min-width: 980px) { .credrow .badge { min-width: 200px; } }

/* ---------- Slider (partners, team) ----------
   Scroll-snap does the work, so touch swipe and keyboard both come free;
   the buttons just nudge scrollLeft. */
.slider { position: relative; }
.slider__track {
  display: flex; gap: var(--s-3);
  /* `safe center` centres the cards when they fit, but falls back to
     flex-start the moment they overflow. Plain `center` would make the
     first card unreachable on narrow screens, because you cannot scroll
     back past the start of an overflowing centred flex container. */
  justify-content: safe center;
  overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-behavior: smooth; padding-bottom: var(--s-2);
  scrollbar-width: none; -ms-overflow-style: none;
}
.slider__track::-webkit-scrollbar { display: none; }
.slider__track > * { scroll-snap-align: start; flex: 0 0 auto; }
.slider__nav { display: flex; gap: var(--s-1); justify-content: flex-end; margin-top: var(--s-2); }
.slider__btn {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--ink-2); border: 1px solid var(--border);
  color: var(--paper); display: grid; place-items: center;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease),
              opacity var(--dur) var(--ease);
}
.slider__btn:hover:not(:disabled) { border-color: var(--violet); color: var(--violet); }
.slider__btn:disabled { opacity: .35; cursor: default; }
.slider__btn svg { width: 19px; height: 19px; }

/* Partner logo wall.
   Four marks, so a wrapping row beats the slider: nothing to reach for, and
   it centres itself at every width. The logos are real brand marks in brand
   colours, so each sits on its own white plate rather than being knocked out
   to white — recolouring somebody else's logo is not ours to do. Every plate
   is exported at the same 3:1 so the row reads as one shape. */
.plogos {
  display: flex; flex-wrap: wrap; gap: var(--s-3);
  justify-content: center; align-items: stretch;
}
.pcard {
  /* A single row of five caps how large each mark can be, because the card
     width is what the logo scales to. So the row breaks 3+2 and the cards
     take that width back: 3x288 + 2x24 = 912 inside the 1184px content box.
     Each mark lands ~60% taller than it was five-across. */
  position: relative;
  width: clamp(160px, 40vw, 288px);
  background: var(--ink-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px;
  transition: border-color var(--dur) var(--ease), transform 320ms var(--ease);
}
.pcard:hover {
  border-color: var(--violet);
  transform: translateY(-6px) scale(1.06);
  z-index: 1;           /* the grown card sits over its neighbours, not under */
}
/* height:auto is load-bearing. The width/height attributes on the <img> are
   presentational hints that outrank aspect-ratio, and without this the plate
   renders 220px tall. Same trap as .split__media img. */
.pcard img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 1; object-fit: contain;
  border-radius: 2px; opacity: .88;
  transition: opacity var(--dur) var(--ease);
}
.pcard:hover img { opacity: 1; }
/* The lift and the grow are decoration; the border and the opacity still
   answer the hover without them. */
@media (prefers-reduced-motion: reduce) { .pcard:hover { transform: none; } }

/* Team card */
.tcard {
  width: 290px;
  background: var(--ink-2); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  transition: border-color var(--dur) var(--ease), transform 320ms var(--ease);
}
.tcard:hover { border-color: var(--violet); transform: translateY(-4px); }
.tcard img { width: 100%; aspect-ratio: 4/5; object-fit: cover; display: block; }
.tcard__body { padding: var(--s-3); }
.tcard__body strong {
  display: block; font-family: var(--display); font-weight: 700;
  font-size: 17px; letter-spacing: -.01em; margin-bottom: 3px;
}
.tcard__role {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--violet); display: block; margin-bottom: 10px;
}
.tcard__body p { font-size: 14px; color: var(--muted); margin: 0; line-height: 1.55; }
.tcard__contact {
  display: inline-flex; align-items: center; min-height: 34px;
  font-size: 13.5px; color: var(--muted); margin-top: 10px;
}
.tcard__contact:hover { color: var(--violet-lift); }

/* ---------- Partner cards ----------
   Same 4:5 portrait as .tcard, but the name is set as a signature rather
   than a heading — these are people who back the company, not staff, and
   the signature reads as a personal endorsement instead of a job title. */
.advcard {
  /* 4 cards + 3 gaps must fit the 1169px track, or `safe center` gives up and
     left-aligns with one card half off the edge. 290px overflowed by 63px.
     clamp keeps the phone size sensible while letting desktop shrink to fit. */
  width: clamp(260px, 23vw, 274px);
  background: var(--ink-2); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  transition: border-color var(--dur) var(--ease), transform 320ms var(--ease);
}
.advcard:hover { border-color: var(--violet); transform: translateY(-4px); }
.advcard__img { position: relative; }
.advcard__img img {
  /* height:auto is required. The <img> carries width/height attributes, which
     are presentational hints that override aspect-ratio — without this the
     portrait renders at its full 1125px intrinsic height. Same trap as
     .split__media img. */
  width: 100%; height: auto; aspect-ratio: 4/5; object-fit: cover; display: block;
}
/* the portraits fade into the card so there is no hard photo edge */
.advcard__img::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 38%;
  background: linear-gradient(180deg, rgba(18,18,26,0) 0%, var(--ink-2) 96%);
  pointer-events: none;
}
.advcard__body { padding: 0 var(--s-3) var(--s-3); margin-top: -34px; position: relative; z-index: 1; }
/* p.advcard__sign, not .advcard__sign: `.advcard__body p` below is
   (0,1,1) and would otherwise win, rendering the signature as body text. */
.advcard__body p.advcard__sign {
  font-family: var(--script); font-weight: 700;
  font-size: 2rem; line-height: 1; color: var(--violet-lift);
  margin: 0 0 2px;
}
.advcard__role {
  display: block; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  margin-bottom: 10px;
}
.advcard__body p { font-size: 14px; color: var(--muted); margin: 0; line-height: 1.6; }

/* Visible marker so placeholder content can't be mistaken for real */
.ph-note {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink);
  background: #E8B84B; border-radius: 3px; padding: 5px 10px;
  margin-bottom: var(--s-3);
}

/* ---------- Textured section background ----------
   Fills the space around centred content instead of flat black. The image is
   heavily dimmed and edge-faded so it never competes with the text.
   url() resolves relative to this stylesheet, so it works at every page depth. */
.tex-bg { position: relative; overflow: hidden; isolation: isolate; }
.tex-bg::before {
  content: ''; position: absolute; inset: 0; z-index: -2;
  background-image: url('../img/tex-container.webp');
  background-size: cover; background-position: center;
  opacity: .16; filter: grayscale(.45) contrast(1.05);
}
.tex-bg::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(ellipse 70% 60% at 50% 50%, transparent 0%, var(--ink) 78%),
    linear-gradient(180deg, var(--ink) 0%, transparent 22%, transparent 78%, var(--ink) 100%);
}
.tex-bg--pallets::before { background-image: url('../img/tex-pallets.webp'); }
.tex-bg--map::before     { background-image: url('../img/tex-map.webp'); opacity: .22; }

/* Slow violet aurora drifting behind the texture. Deliberately faint and very
   slow (28s) — enough to feel alive on a dark page without reading as flashy.
   Injected by main.js so it needs no markup changes. */
/* Aurora clipping layer.
   The aurora is inset -25%, so it is always 150% of its section's width and
   always extended past the viewport. `body { overflow-x: hidden }` masked that
   on desktop, but mobile browsers ignore body-level clipping for pinch-zoom, so
   on a phone the page became ~98px wider than the screen and the right edge was
   unreachable.

   It could not simply be clipped on the parent: the aurora lives in
   #credentials, which carries `overflow: visible` (line ~491) so the GLA
   certificate badge can escape its box. An ID selector also outranks
   `.tex-bg { overflow: hidden }`, which is why that rule was not already doing
   the job.

   So the glow gets its own clipping wrapper instead. #credentials keeps
   overflow:visible and the badge is untouched. No visual change anywhere: the
   section is full-bleed, so its edge is the viewport edge, which is exactly
   where body was already cutting the glow. */
.aurora__clip {
  position: absolute; inset: 0; overflow: hidden;
  z-index: -1; pointer-events: none;
}

.aurora {
  position: absolute; inset: -25%; z-index: -1; pointer-events: none;
  background:
    radial-gradient(circle at 28% 32%, rgba(122,99,255,.20), transparent 55%),
    radial-gradient(circle at 74% 68%, rgba(122,99,255,.13), transparent 55%),
    radial-gradient(circle at 55% 12%, rgba(155,138,255,.10), transparent 50%);
  filter: blur(50px);
  animation: aurora-drift 28s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes aurora-drift {
  from { transform: translate3d(-2.5%, -1.5%, 0) scale(1); }
  to   { transform: translate3d(2.5%,  1.5%, 0) scale(1.09); }
}
@media (prefers-reduced-motion: reduce) { .aurora { animation: none; } }
.vid {
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; background: var(--ink-2); position: relative;
  transition: border-color var(--dur) var(--ease), transform 320ms var(--ease);
}
.vid:hover { border-color: var(--violet); transform: translateY(-4px); }
.vid video { width: 100%; aspect-ratio: 1/1; object-fit: cover; background: var(--ink-3); display: block; }
.vid figcaption {
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  color: var(--faint); padding: var(--s-2); text-transform: uppercase;
}

/* Click-to-enlarge button, laid over the video */
.vid__open {
  position: absolute; inset: 0; z-index: 2;
  background: transparent; border: 0; cursor: pointer;
  display: grid; place-items: center;
  transition: background var(--dur) var(--ease);
}
.vid__open:hover, .vid__open:focus-visible { background: rgba(8,8,13,.42); }
.vid__open span {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 18px; border-radius: 100px;
  background: rgba(8,8,13,.82); border: 1px solid var(--border-lift);
  color: var(--paper); font-family: var(--mono); font-size: 11px;
  letter-spacing: .12em; text-transform: uppercase;
  transform: scale(.94); opacity: .9;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.vid__open:hover span, .vid__open:focus-visible span {
  transform: scale(1); opacity: 1; border-color: var(--violet);
}
.vid__open svg { width: 15px; height: 15px; }
@media (prefers-reduced-motion: reduce) {
  .vid:hover { transform: none; }
  .vid__open span { transform: none; opacity: 1; }
}

/* ---------- Video lightbox ---------- */
.lb {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(4,4,8,.92);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  display: none; place-items: center; padding: var(--s-3);
  opacity: 0; transition: opacity .28s var(--ease);
}
.lb[data-open="true"] { display: grid; opacity: 1; }
.lb__box { width: min(88vw, 78vh); max-width: 720px; }
.lb__box video {
  width: 100%; aspect-ratio: 1/1; object-fit: contain;
  background: #000; border-radius: var(--radius);
  border: 1px solid var(--border-lift);
}
.lb__cap {
  font-family: var(--mono); font-size: 12px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
  margin-top: var(--s-2); text-align: center;
}
.lb__close {
  position: absolute; top: var(--s-3); right: var(--s-3);
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--ink-3); border: 1px solid var(--border-lift);
  color: var(--paper); display: grid; place-items: center;
}
.lb__close:hover { border-color: var(--violet); color: var(--violet); }
.lb__close svg { width: 20px; height: 20px; }

/* ---------- CEO letter ---------- */
.letter { background: var(--ink-2); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--s-4); }
@media (min-width: 900px) { .letter { padding: var(--s-6); } }
.letter blockquote { margin: 0; }
.letter blockquote p { font-size: clamp(1rem, 1.35vw, 1.1875rem); color: var(--paper); opacity: .9; }
.sign { margin-top: var(--s-4); display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.sign img {
  height: 66px; width: auto;
  /* The signature asset is already white ink on a transparent background,
     so it needs no inversion — inverting it would render it black-on-black. */
  opacity: .95;
}
.sign__who strong { display: block; font-family: var(--display); font-weight: 700; font-size: 17px; letter-spacing: -.01em; }
.sign__who span { font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--violet); }
/* The letter column is taller than a 4:5 portrait, which left dead black under
   the photo. Let the portrait fill its column instead so both sides end level. */
.portrait { display: flex; }
.portrait img {
  width: 100%; height: 100%; min-height: 100%;
  aspect-ratio: auto; object-fit: cover; object-position: center 22%;
  border-radius: var(--radius);
}
@media (max-width: 899px) {
  /* stacked on mobile — cap it so the face isn't a full screen of photo */
  .portrait img { height: auto; aspect-ratio: 4/5; }
}

/* ---------- Accordion (Good to know) ---------- */
.acc { border-top: 1px solid var(--border); }
.acc__item { border-bottom: 1px solid var(--border); }
.acc__btn {
  width: 100%; background: transparent; border: 0; color: var(--paper);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-3) 0; min-height: 64px; text-align: left;
  font-family: var(--display); font-weight: 700; font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
  letter-spacing: -.015em;
  transition: color var(--dur) var(--ease);
}
.acc__btn:hover { color: var(--violet-lift); }
.acc__ico { flex: none; width: 22px; height: 22px; position: relative; }
.acc__ico::before, .acc__ico::after {
  content: ''; position: absolute; background: var(--violet);
  left: 50%; top: 50%; transform: translate(-50%,-50%);
}
.acc__ico::before { width: 14px; height: 1.5px; }
.acc__ico::after  { width: 1.5px; height: 14px; transition: transform var(--dur) var(--ease); }
.acc__btn[aria-expanded="true"] .acc__ico::after { transform: translate(-50%,-50%) scaleY(0); }
.acc__panel { display: none; padding-bottom: var(--s-3); }
.acc__panel[data-open="true"] { display: block; }
.terms { display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); }
@media (min-width: 720px) { .terms { grid-template-columns: 1fr 1fr; } }
.term { background: var(--ink); padding: var(--s-3); }
.term dt { font-family: var(--mono); font-size: 12px; letter-spacing: .1em; color: var(--violet); margin-bottom: 6px; }
.term dd { margin: 0; font-size: 14.5px; color: var(--muted); line-height: 1.55; }

/* ---------- Form ---------- */
.form-wrap { display: grid; gap: var(--s-5); }
@media (min-width: 900px) { .form-wrap { grid-template-columns: .9fr 1.1fr; gap: var(--s-6); } }
.form { display: grid; gap: var(--s-3); }
.row { display: grid; gap: var(--s-3); }
@media (min-width: 560px) { .row--2 { grid-template-columns: 1fr 1fr; } }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.field .req { color: var(--violet); }
.field input, .field textarea {
  min-height: 52px; padding: 14px var(--s-2);
  background: var(--ink-2); color: var(--paper);
  border: 1px solid var(--border); border-radius: var(--radius);
  font-family: var(--body); font-size: 16px; /* 16px prevents iOS zoom */
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
  width: 100%;
}
.field textarea { min-height: 152px; resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field input:focus, .field textarea:focus { border-color: var(--violet); background: var(--ink-3); outline: none; }
.field input:user-invalid, .field textarea:user-invalid { border-color: #FF6B6B; }
.field .hint { font-size: 12.5px; color: var(--faint); }
.field .err { font-size: 13px; color: #FF8A8A; display: none; }
.field[data-invalid="true"] .err { display: block; }
.field[data-invalid="true"] input, .field[data-invalid="true"] textarea { border-color: #FF6B6B; }

.consent { display: flex; gap: var(--s-2); align-items: flex-start; font-size: 13.5px; color: var(--muted); }
.consent input { width: 20px; height: 20px; margin-top: 3px; flex: none; accent-color: var(--violet-btn); min-height: 0; }
.consent a { color: var(--violet); text-decoration: underline; text-underline-offset: 3px; }

.contact-card { background: var(--ink-2); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--s-4); }
.contact-card dl { margin: 0; display: grid; gap: var(--s-3); }
.contact-card dt { font-family: var(--mono); font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--faint); margin-bottom: 4px; }
.contact-card dd { margin: 0; font-size: 15.5px; }
/* Phone and e-mail are the primary mobile actions — give them a full
   44px target rather than a 19px line of text. */
.contact-card dd a { display: inline-flex; align-items: center; min-height: 44px; }
.contact-card dd a:hover { color: var(--violet-lift); }

/* ---------- Credential band footer ----------
   Mirrors the original site's compact band: Avainlippu + GLA logos linking
   out, address, phone with WhatsApp, e-mail. */
.fband { border-top: 1px solid var(--border); background: var(--ink-2); padding-block: var(--s-4); }
.fband__in {
  display: grid; gap: var(--s-4); align-items: center; justify-items: center;
  text-align: center;
}
@media (min-width: 900px) {
  .fband__in { grid-template-columns: auto 1fr auto 1fr auto; gap: var(--s-5); text-align: left; justify-items: start; }
}
.fband__mark img { height: 62px; width: auto; transition: opacity var(--dur) var(--ease); }
.fband__mark:hover img { opacity: .78; }
.fband__addr { font-size: 14.5px; color: var(--muted); line-height: 1.6; }
.fband__addr strong { display: block; color: var(--paper); font-weight: 600; }
.fband__contact { display: grid; gap: 6px; }
.fband__contact a {
  display: inline-flex; align-items: center; gap: 9px;
  min-height: 44px;              /* phone + e-mail are primary mobile actions */
  font-size: 14.5px; color: var(--muted);
  transition: color var(--dur) var(--ease);
}
.fband__contact a:hover { color: var(--violet-lift); }
.fband__contact svg { width: 16px; height: 16px; flex: none; color: var(--faint); }
.fband__contact a:hover svg { color: var(--violet); }
/* +358 44 9287161 is a WhatsApp-only number, so it carries the WhatsApp mark
   and links to wa.me rather than tel: */
.fband__contact .wa svg { color: #25D366; }
.fband__contact .wa:hover svg { color: #25D366; }
.fband__contact .tg svg { color: #29A9EB; }
.fband__contact .tg:hover svg { color: #29A9EB; }

/* An inline SVG without width/height attributes expands to fill its container.
   Cap every inline contact icon so a misplaced one can't render page-sized. */
.fband__contact svg,
.infocard svg,
.contact-card svg,
.ftr__links svg { width: 16px; height: 16px; flex: none; }

/* ---------- Footer ---------- */
.ftr { border-top: 1px solid var(--border); padding-block: var(--s-6) var(--s-4); background: var(--ink-2); }
/* Slim variant: one quiet row of links under the credential band */
.ftr--slim { padding-block: var(--s-4); }
.ftr--slim .ftr__links {
  display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-3);
  margin-bottom: var(--s-3);
}
.ftr--slim .ftr__links a { font-size: 13.5px; color: var(--muted); padding-block: 5px; }
.ftr--slim .ftr__links a:hover { color: var(--violet-lift); }
.ftr--slim .ftr__links .sep { color: var(--faint); opacity: .5; }
.ftr__grid { display: grid; gap: var(--s-5); }
@media (min-width: 760px)  { .ftr__grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 1100px) { .ftr__grid { grid-template-columns: 1.6fr 1fr 1fr 1.1fr; } }
.ftr h3 { font-family: var(--mono); font-weight: 500; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--faint); margin-bottom: var(--s-2); }
.ftr ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.ftr li { font-size: 14.5px; color: var(--muted); }
.ftr a { display: inline-block; padding-block: 5px; }
.ftr a:hover { color: var(--violet-lift); }
.ftr__logo img { height: 40px; margin-bottom: var(--s-3); }
.ftr__bottom {
  margin-top: var(--s-5); padding-top: var(--s-3); border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; gap: var(--s-2); justify-content: space-between;
  font-family: var(--mono); font-size: 11.5px; color: var(--faint); letter-spacing: .04em;
}

/* ---------- Route ticker ----------
   A departure-board strip of real trade lanes. Motion with a reason: it is
   the one element on the page that is literally about things moving. */
.ticker {
  position: relative; overflow: hidden;
  border-block: 1px solid var(--border);
  background: var(--ink-2);
  padding-block: var(--s-3);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ticker__track {
  display: flex; width: max-content;
  animation: ticker-slide 48s linear infinite;
  will-change: transform;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
.ticker__group { display: flex; flex: none; }
.ticker__item {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding-inline: var(--s-3);
  font-family: var(--mono); font-size: 13px; letter-spacing: .06em;
  color: var(--muted); white-space: nowrap;
}
.ticker__item svg { width: 14px; height: 14px; color: var(--violet); flex: none; }
.ticker__item b { font-weight: 500; color: var(--faint); text-transform: uppercase; letter-spacing: .1em; font-size: 11px; }
.ticker__item time {
  color: var(--paper); font-weight: 500;
  font-variant-numeric: tabular-nums;   /* stops the strip twitching on each tick */
}
.ticker__dot { width: 3px; height: 3px; border-radius: 50%; background: var(--violet); flex: none; }
@keyframes ticker-slide { from { transform: translate3d(0,0,0); } to { transform: translate3d(-50%,0,0); } }
@media (prefers-reduced-motion: reduce) {
  .ticker__track { animation: none; }
  .ticker { -webkit-mask-image: none; mask-image: none; overflow-x: auto; }
}

/* ---------- Counting numbers ---------- */
.manifest__v[data-count-to] { font-variant-numeric: tabular-nums; }

/* ---------- Line reveal for headings ----------
   Each line is masked and rises into place. Uses transform/opacity only. */
.lines { display: block; }
.lines .line-wrap { display: block; overflow: hidden; }
.lines .line {
  display: block;
  transform: translateY(105%);
  transition: transform .85s cubic-bezier(.16,1,.3,1);
}
.lines.in .line { transform: translateY(0); }
.lines .line:nth-child(1){transition-delay:.02s}
.lines.in .line-wrap:nth-child(2) .line { transition-delay: .10s; }
.lines.in .line-wrap:nth-child(3) .line { transition-delay: .18s; }
.lines.in .line-wrap:nth-child(4) .line { transition-delay: .26s; }
@media (prefers-reduced-motion: reduce) {
  .lines .line { transform: none; transition: none; }
}

/* ---------- Consent banner ---------- */
.cc {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
  background: var(--ink-2); border-top: 1px solid var(--border-lift);
  box-shadow: 0 -20px 60px rgba(0,0,0,.55);
  transform: translateY(110%);
  transition: transform .5s var(--ease);
  padding: var(--s-3) 0 calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
}
.cc[data-show="true"] { transform: translateY(0); }
.cc__in { display: grid; gap: var(--s-3); }
@media (min-width: 900px) {
  .cc__in { grid-template-columns: 1fr auto; align-items: center; gap: var(--s-5); }
}
.cc h2 { font-size: 1.0625rem; margin: 0 0 6px; letter-spacing: -.01em; }
.cc p { font-size: 14px; color: var(--muted); margin: 0; max-width: 72ch; }
.cc p a { color: var(--violet); text-decoration: underline; text-underline-offset: 3px; }
.cc__actions { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.cc__actions .btn { min-height: 46px; padding-inline: var(--s-3); font-size: 15px; flex: 1 1 auto; }
@media (min-width: 900px) { .cc__actions .btn { flex: 0 0 auto; } }

/* Preferences panel */
.cc__prefs { display: none; margin-top: var(--s-3); border-top: 1px solid var(--border); padding-top: var(--s-3); }
.cc[data-prefs="true"] .cc__prefs { display: block; }
.cc__row {
  display: flex; align-items: flex-start; gap: var(--s-2);
  padding-block: var(--s-2); border-bottom: 1px solid var(--border);
}
.cc__row:last-child { border-bottom: 0; }
.cc__row input { width: 20px; height: 20px; margin-top: 3px; flex: none; accent-color: var(--violet-btn); }
.cc__row input:disabled { opacity: .5; }
.cc__row strong { display: block; font-size: 14.5px; font-weight: 600; }
.cc__row span { font-size: 13px; color: var(--faint); }

/* Reopen handle, so consent is revocable — required by GDPR */
.cc-reopen {
  position: fixed; left: var(--s-2); bottom: var(--s-2); z-index: 890;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--ink-3); border: 1px solid var(--border);
  color: var(--muted); display: none; place-items: center;
}
.cc-reopen[data-show="true"] { display: grid; }
.cc-reopen:hover { color: var(--violet); border-color: var(--violet); }
.cc-reopen svg { width: 19px; height: 19px; }

/* ---------- Interactive route map ---------- */
.band__routes { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.band__routes svg { width: 100%; height: 100%; display: block; }
.route {
  fill: none; stroke: var(--violet); stroke-width: 1.2; stroke-linecap: round;
  opacity: .85;
  stroke-dasharray: var(--len); stroke-dashoffset: var(--len);
}
.band__routes.in .route { animation: route-draw 2.2s var(--ease) forwards; }
@keyframes route-draw { to { stroke-dashoffset: 0; } }

/* A bright segment travelling each lane, forever — reads as cargo continuously
   moving through the network rather than a one-off draw that stops. */
.route-pulse {
  fill: none; stroke: var(--violet-lift); stroke-width: 2; stroke-linecap: round;
  opacity: 0;
  stroke-dasharray: 10 999;
}
.band__routes.in .route-pulse {
  animation: route-flow 5.5s linear infinite;
}
@keyframes route-flow {
  0%   { stroke-dashoffset: var(--len); opacity: 0; }
  12%  { opacity: .95; }
  85%  { opacity: .95; }
  100% { stroke-dashoffset: -10; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .route-pulse { display: none; } }
.route-hub, .route-end { fill: var(--violet); }
.route-hub { r: 3.6; }
.band__routes.in .route-hub { animation: hub-pulse 2.6s ease-out infinite; transform-origin: center; }
@keyframes hub-pulse { 0%,100% { opacity: 1 } 50% { opacity: .35 } }
.route-end { r: 2.2; opacity: 0; }
.band__routes.in .route-end { animation: end-in .5s var(--ease) forwards; }
@keyframes end-in { to { opacity: .9 } }
.route-ping { fill: none; stroke: var(--violet); stroke-width: 1; opacity: 0; }
.band__routes.in .route-ping { animation: ping 2.6s ease-out infinite; }
@keyframes ping { 0% { r: 3; opacity: .7 } 100% { r: 16; opacity: 0 } }
@media (prefers-reduced-motion: reduce) {
  .band__routes.in .route { animation: none; stroke-dashoffset: 0; }
  .band__routes.in .route-hub, .band__routes.in .route-ping { animation: none; }
  .band__routes.in .route-end { animation: none; opacity: .9; }
}

/* ---------- Scroll-driven service reveal ---------- */
.svc-grid--scroll .svc {
  opacity: 0; transform: translateY(38px) scale(.97);
  transition: opacity .7s var(--ease), transform .7s var(--ease),
              background var(--dur) var(--ease), box-shadow 320ms var(--ease);
}
.svc-grid--scroll .svc.on { opacity: 1; transform: none; }
.svc-grid--scroll .svc.on:hover { transform: translateY(-6px); }
@media (prefers-reduced-motion: reduce) {
  .svc-grid--scroll .svc { opacity: 1; transform: none; transition: none; }
}

/* ---------- Cursor spotlight ----------
   A soft violet glow tracking the pointer. `screen` only ever lightens, so it
   warms the dark background without washing out or obscuring any text. */
.spot {
  position: fixed; inset: 0; z-index: 60; pointer-events: none;
  mix-blend-mode: screen;
  background: radial-gradient(circle 420px at var(--sx, 50%) var(--sy, 50%),
              rgba(122,99,255,.15), rgba(122,99,255,.05) 38%, transparent 66%);
  opacity: 0; transition: opacity .5s var(--ease);
  will-change: background;
}
body.has-spot .spot { opacity: 1; }
@media (hover: none), (prefers-reduced-motion: reduce) { .spot { display: none; } }

/* ---------- Magnetic buttons ----------
   The custom cursor ring/dot was removed — it obscured the pointer and read as
   confusing. The system cursor is used everywhere; only the magnetic pull on
   buttons remains. */
.btn { will-change: transform; }

/* ---------- Page transitions ---------- */
.pt {
  position: fixed; inset: 0; z-index: 9998; pointer-events: none;
  background: var(--ink); transform: scaleY(0); transform-origin: bottom;
}
.pt.out { animation: pt-out .42s var(--ease) forwards; }
body.pt-in .pt { animation: pt-in .5s var(--ease) forwards; }
@keyframes pt-out { from { transform: scaleY(0); transform-origin: bottom } to { transform: scaleY(1); transform-origin: bottom } }
@keyframes pt-in  { from { transform: scaleY(1); transform-origin: top }    to { transform: scaleY(0); transform-origin: top } }
@media (prefers-reduced-motion: reduce) { .pt { display: none; } }

/* ---------- Scroll reveal ---------- */
.rv { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.rv.in { opacity: 1; transform: none; }
.rv-d1 { transition-delay: .07s; } .rv-d2 { transition-delay: .14s; }
.rv-d3 { transition-delay: .21s; } .rv-d4 { transition-delay: .28s; }
@media (prefers-reduced-motion: reduce) { .rv { opacity: 1; transform: none; } }

/* ---------- Service detail hero ---------- */
.svchero { position: relative; overflow: hidden; min-height: 46svh; display: flex; align-items: flex-end; }
@media (min-width: 900px) { .svchero { min-height: 56svh; } }
.svchero__media { position: absolute; inset: 0; z-index: 0; }
.svchero__media img { width: 100%; height: 100%; object-fit: cover; }
.svchero__scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(8,8,13,.86) 0%, rgba(8,8,13,.45) 45%, rgba(8,8,13,.92) 100%),
    linear-gradient(90deg, rgba(8,8,13,.72) 0%, rgba(8,8,13,.15) 70%);
}
.svchero__in { position: relative; z-index: 2; width: 100%; padding-block: 132px var(--s-5); }
@media (min-width: 1024px) { .svchero__in { padding-block: 176px var(--s-6); } }
.svchero h1 { font-size: clamp(2.25rem, 6vw, 4.5rem); max-width: 16ch; margin: 0; }

/* Compact card used in the "other services" row */
.svc-grid .svc h3 { margin-bottom: 0; }
.svc-grid .svc:not(:has(p)) { min-height: 190px; justify-content: flex-end; }

/* About page headline — sits above the CEO letter */
.about__h1 { font-size: clamp(2rem, 4.5vw, 3.25rem); margin-bottom: var(--s-3); }

/* ---------- Contact + billing cards (About page) ---------- */
.infogrid { display: grid; gap: var(--s-3); }
@media (min-width: 800px) { .infogrid { grid-template-columns: 1fr 1fr; gap: var(--s-4); } }
.infocard {
  background: var(--ink-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--s-4);
}
.infocard dl { margin: 0; display: grid; gap: var(--s-3); }
.infocard dt {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint); margin-bottom: 5px;
}
.infocard dd { margin: 0; font-size: 15px; color: var(--paper); line-height: 1.55; }
.infocard dd + dd { color: var(--muted); }
.infocard dd a:hover { color: var(--violet-lift); }
/* IBANs and reference numbers read better with fixed-width figures */
.infocard dd { font-variant-numeric: tabular-nums; }

/* ---------- Closing CTA band ---------- */
.cta-band { background: var(--ink-2); border-top: 1px solid var(--border); }
.cta-band h2 { max-width: 20ch; margin-inline: auto; }
.cta-band .lead { max-width: 52ch; }

/* ---------- Legal / prose pages ---------- */
.legal { padding-block: calc(76px + var(--s-6)) var(--s-7); }
.legal__head { margin-bottom: var(--s-6); }
.legal__head h1 { font-size: clamp(2.25rem, 5.5vw, 4rem); max-width: 18ch; }
.legal__updated {
  font-family: var(--mono); font-size: 12px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--faint); margin: 0;
}
.legal__grid { display: grid; gap: var(--s-5); }
@media (min-width: 1000px) { .legal__grid { grid-template-columns: 240px 1fr; gap: var(--s-6); align-items: start; } }
/* Grid items default to min-width:auto, so the 540px min-width table inside
   .table-scroll would push the whole column past the viewport instead of
   scrolling inside it. This is what caused horizontal scroll at 375px. */
.legal__grid > * { min-width: 0; }

.legal__toc { position: sticky; top: 96px; display: none; }
@media (min-width: 1000px) { .legal__toc { display: block; } }
.legal__toc ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; counter-reset: toc; }
.legal__toc a {
  display: block; padding: 7px 0; font-size: 13.5px; color: var(--muted);
  border-left: 1px solid var(--border); padding-left: var(--s-2);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.legal__toc a:hover { color: var(--paper); border-left-color: var(--violet); }

.prose { max-width: 74ch; min-width: 0; }
.prose h2 {
  font-size: clamp(1.375rem, 2.4vw, 1.875rem);
  margin-top: var(--s-6); margin-bottom: var(--s-2); scroll-margin-top: 96px;
}
.prose h2:first-child { margin-top: 0; }
.prose h3 { font-size: 1.0625rem; margin-top: var(--s-4); margin-bottom: var(--s-1); }
.prose p, .prose li { color: var(--muted); font-size: 16px; line-height: 1.7; }
.prose strong { color: var(--paper); font-weight: 600; }
.prose a { color: var(--violet); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--violet-lift); }
.prose ul, .prose ol { padding-left: var(--s-3); margin: 0 0 var(--s-3); display: grid; gap: 8px; }
.prose li::marker { color: var(--violet); }
.prose hr { border: 0; border-top: 1px solid var(--border); margin-block: var(--s-5); }

.prose .box {
  background: var(--ink-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--s-3); margin-bottom: var(--s-3);
}
.prose .box p:last-child { margin-bottom: 0; }

.table-scroll { overflow-x: auto; margin-bottom: var(--s-3); border: 1px solid var(--border); border-radius: var(--radius); }
.prose table { border-collapse: collapse; width: 100%; min-width: 540px; font-size: 14.5px; }
.prose th, .prose td { text-align: left; padding: 12px var(--s-2); border-bottom: 1px solid var(--border); vertical-align: top; }
.prose th {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); font-weight: 500; background: var(--ink-2); white-space: nowrap;
}
.prose td { color: var(--muted); }
.prose tr:last-child td { border-bottom: 0; }
.prose code {
  font-family: var(--mono); font-size: .88em; background: var(--ink-3);
  padding: 2px 6px; border-radius: 3px; color: var(--paper);
}

/* ---------- Thank you page ---------- */
.ty { min-height: 100svh; display: grid; place-items: center; text-align: center; position: relative; overflow: hidden; }
.ty__media { position: absolute; inset: 0; z-index: 0; }
.ty__media img { width: 100%; height: 100%; object-fit: cover; }
.ty__media::after { content: ''; position: absolute; inset: 0; background: rgba(8,8,13,.86); }
.ty__in { position: relative; z-index: 1; padding-block: var(--s-7); }
.ty p { margin-inline: auto; }
.ty .tick {
  width: 76px; height: 76px; border-radius: 50%;
  border: 1.5px solid var(--violet); display: grid; place-items: center;
  margin: 0 auto var(--s-4);
}
.ty .tick svg { width: 34px; height: 34px; stroke: var(--violet); }
