/* ========================================================================
   CargoGauge marketing site styles

   Reference points are European B2B logistics platforms (sennder, Forto,
   Shippeo, Transporeon) rather than generic SaaS templates:

     · White ground. Depth comes from hairlines and one navy band, not from
       stacked grey sections or gradients.
     · Navy #0d2744 is the anchor. It is the navy already inside the logo,
       so the brand mark sits in the page instead of on top of it.
     · The product does the selling. Every section that can show a piece of
       real interface does so, captioned honestly.
     · One typeface (Schibsted Grotesk) carrying the whole hierarchy, with a
       mono only inside interface renderings where data needs to line up.
   ======================================================================== */

/* ========== TYPEFACE ==========
   Schibsted Grotesk is served from this origin, not fonts.gstatic.com. A
   Google-hosted webfont makes every visitor's browser call Google before the
   page has asked them anything, which discloses their IP address to a third
   party on every page view. Self-hosting removes that entirely, which is the
   same call already made for React and Leaflet in js/vendor/.

   One variable file per subset covers 400 through 700. Google advertises four
   separate weights but returns the identical variable file for each, so
   splitting them would download the same bytes four times.

   latin-ext is kept because the copy carries European place and company names
   (Malmoe, Gothenburg, Polish and Czech operators) that fall outside latin.
   ======================================================================== */
@font-face {
  font-family: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/schibsted-grotesk-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

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

/* ========== TOKENS ========== */
:root {
  --white: #ffffff;
  --mist: #f4f6f9; /* banded sections */
  --mist-deep: #eaeef4; /* table heads, pressed states */

  --navy: #0d2744; /* from the logo */
  --navy-deep: #081a2e;
  --slate: #4a5a70; /* body copy */
  --slate-light: #5f6d84; /* meta, captions; dark enough for WCAG AA on --mist */

  --line: #dfe5ec;
  --line-soft: #eef2f6;

  --blue: #2563eb; /* from the logo. Links and accents only */
  --blue-deep: #1b4dc4;
  --blue-wash: #eef3fe;

  --green: #12805c;
  --green-wash: #e8f5f0;
  --amber: #a86412;
  --amber-wash: #fbf1e3;

  --font: "Schibsted Grotesk", "Helvetica Neue", Arial, sans-serif;
  /* System stack: the only webfonts loaded are the marketing face and the
     two the design system needs for the product panels. */
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --r-sm: 4px;
  --r: 6px;
  --r-lg: 10px;
  --r-xl: 14px;

  --shadow-xs: 0 1px 2px rgba(13, 39, 68, 0.06);
  --shadow-sm: 0 1px 3px rgba(13, 39, 68, 0.08),
    0 1px 2px rgba(13, 39, 68, 0.04);
  --shadow-panel: 0 24px 60px -28px rgba(13, 39, 68, 0.28),
    0 2px 8px rgba(13, 39, 68, 0.05);

  /* Sticky header (4.5rem) plus the platform page's section nav. */
  --chrome-h: 7.75rem;

  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --sect: clamp(4.5rem, 8vw, 7.5rem);
}

/* ========== RESET ========== */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* Keeps an anchor jump clear of the sticky chrome. */
  scroll-padding-top: calc(var(--chrome-h) + 1rem);
}

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

body {
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--slate);
  background: var(--white);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "ss01" on;
}

img,
svg {
  max-width: 100%;
  display: block;
}
a {
  color: inherit;
  text-decoration: none;
}
ul,
ol {
  list-style: none;
}
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

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

::selection {
  background: var(--navy);
  color: #fff;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--navy);
  color: #fff;
  font-size: 0.875rem;
  font-weight: 600;
  border-radius: 0 0 var(--r) 0;
}
.skip:focus {
  left: 0;
}

/* ========== TYPE ========== */
h1,
h2,
h3,
h4 {
  color: var(--navy);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.021em;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.4rem, 4.6vw, 3.9rem);
  line-height: 1.04;
  letter-spacing: -0.032em;
  font-weight: 700;
}

h2 {
  font-size: clamp(1.75rem, 3vw, 2.6rem);
  letter-spacing: -0.028em;
}

h3 {
  font-size: 1.1875rem;
  letter-spacing: -0.018em;
}

h4 {
  font-size: 1rem;
  letter-spacing: -0.012em;
}

p {
  text-wrap: pretty;
}

strong {
  font-weight: 600;
  color: var(--navy);
}

.lede {
  font-size: clamp(1.0625rem, 1.4vw, 1.1875rem);
  line-height: 1.6;
  color: var(--slate);
  max-width: 56ch;
}

.eyebrow {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 1rem;
}

.muted {
  color: var(--slate-light);
}

.tlink {
  color: var(--blue);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: rgba(37, 99, 235, 0.35);
  transition: text-decoration-color 0.15s ease;
}
.tlink:hover {
  text-decoration-color: currentColor;
}

.arrowlink {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--blue);
}
.arrowlink::after {
  content: "→";
  transition: transform 0.18s ease;
}
.arrowlink:hover::after {
  transform: translateX(3px);
}

.mono {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* ========== LAYOUT ========== */
.wrap {
  /* The explicit width matters inside a flex container: `margin: 0 auto` turns
     off cross-axis stretch, and a wrap whose only in-flow child is a caption
     would otherwise shrink to the caption's width. */
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.wrap--narrow {
  max-width: 880px;
}

.sect {
  padding: var(--sect) 0;
}

.sect--tight {
  padding: clamp(3rem, 5vw, 4.5rem) 0;
}

.sect--mist {
  background: var(--mist);
}

.sect--navy {
  background: var(--navy);
  color: rgba(255, 255, 255, 0.76);
}

.sect--navy h2,
.sect--navy h3,
.sect--navy h4 {
  color: #fff;
}

.sect--navy .lede {
  color: rgba(255, 255, 255, 0.76);
}

.sect--navy .eyebrow {
  color: #7fa9ff;
}

.sect-head {
  max-width: 42rem;
  margin-bottom: clamp(2.5rem, 4vw, 3.5rem);
}

.sect-head h2 {
  margin-bottom: 0.9rem;
}

/* Heading on the left, supporting note on the right, so it reads as a document
   spread rather than a centred marketing block. */
.sect-head--split {
  max-width: none;
  display: grid;
  gap: 1.25rem;
  align-items: end;
}

@media (min-width: 56rem) {
  .sect-head--split {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 3rem;
  }
  .sect-head--split .lede {
    padding-bottom: 0.35rem;
  }
}

/* ========== BUTTONS ========== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 0.78rem 1.3rem;
  border: 1px solid transparent;
  border-radius: var(--r);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease,
    box-shadow 0.15s ease;
}

.btn--primary {
  background: var(--navy);
  color: #fff;
  box-shadow: var(--shadow-xs);
}
.btn--primary:hover {
  background: var(--navy-deep);
}

.btn--blue {
  background: var(--blue);
  color: #fff;
}
.btn--blue:hover {
  background: var(--blue-deep);
}

.btn--outline {
  background: var(--white);
  border-color: var(--line);
  color: var(--navy);
}
.btn--outline:hover {
  border-color: var(--slate-light);
  background: var(--mist);
}

.btn--onnavy {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.26);
  color: #fff;
}
.btn--onnavy:hover {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.45);
}

.btn--white {
  background: #fff;
  color: var(--navy);
}
.btn--white:hover {
  background: #eef2f7;
}

.btn--lg {
  padding: 0.95rem 1.6rem;
  font-size: 1rem;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* ========== HEADER ========== */
.header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line-soft);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  height: 4.5rem;
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--navy);
}

.logo img {
  width: 30px;
  height: 30px;
}

.nav {
  display: none;
  align-items: center;
  gap: 2rem;
  margin-right: auto;
  margin-left: 2.5rem;
}

@media (min-width: 60rem) {
  .nav {
    display: flex;
  }
}

.nav a {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--slate);
  transition: color 0.15s ease;
}
.nav a:hover,
.nav a.active {
  color: var(--navy);
}
.nav a.active {
  font-weight: 600;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.header .btn {
  padding: 0.6rem 1.1rem;
  font-size: 0.875rem;
}

@media (max-width: 59.99rem) {
  .header .btn {
    display: none;
  }
}

.menu-btn {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--white);
  cursor: pointer;
}

@media (min-width: 60rem) {
  .menu-btn {
    display: none;
  }
}

.menu-btn span {
  display: block;
  height: 1.5px;
  border-radius: 2px;
  background: var(--navy);
}

.mobile-menu {
  display: none;
  background: var(--white);
  border-bottom: 1px solid var(--line);
  padding: 0.5rem var(--gutter) 1.25rem;
}

.mobile-menu.open {
  display: block;
}

@media (min-width: 60rem) {
  .mobile-menu.open {
    display: none;
  }
}

.mobile-menu a {
  display: block;
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 1rem;
  font-weight: 500;
  color: var(--navy);
}

.mobile-menu a:last-child {
  border-bottom: 0;
  margin-top: 0.75rem;
  padding: 0.8rem 1.25rem;
  background: var(--navy);
  color: #fff;
  text-align: center;
  border-radius: var(--r);
}

/* ========== PAGE HEAD ========== */
.page-head {
  padding: clamp(3rem, 6vw, 5rem) 0 clamp(2rem, 4vw, 3rem);
}

.page-head h1 {
  max-width: 20ch;
  margin-bottom: 1.25rem;
}

/* ========== PANELS & CARDS ========== */
.panel {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}

.panel--pad {
  padding: clamp(1.5rem, 2.5vw, 2rem);
}

.grid {
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 48rem) {
  .grid--2 {
    grid-template-columns: repeat(2, 1fr);
  }
  .grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ========== FEATURE LIST ========== */
.feature-list {
  display: grid;
  gap: 1.25rem;
  margin-bottom: 1.75rem;
}

.feature-list h4 {
  margin-bottom: 0.2rem;
}

.feature-list p {
  font-size: 0.9375rem;
  max-width: 46ch;
}

.feature-list li {
  padding-left: 1.1rem;
  border-left: 2px solid var(--line);
}

/* The marker rests on the first item until the script takes the list over by
   setting data-beats="on". The :not() keeps this from depending on rule order. */
.feature-list:not([data-beats="on"]) li:first-child {
  border-left-color: var(--blue);
}

/* Reading focus. The script paints opacity, scale and the marker colour on
   every frame from an eased scroll position, so there is deliberately no
   transition here: a CSS transition would fight the easing rather than add to
   it. The class is still set, as a hook and so the marked bullet is findable
   without reading inline styles. */
.feature-list[data-beats="on"] li {
  transform-origin: left center;
  will-change: opacity, transform;
}

.feature-list[data-beats="on"] li.is-focus {
  border-left-color: var(--blue);
}

/* ========== CHIPS & STATUS ========== */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.18rem 0.45rem;
  border-radius: var(--r-sm);
  background: var(--mist-deep);
  color: var(--slate);
  white-space: nowrap;
}

.chip::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}

.chip--live {
  background: var(--green-wash);
  color: var(--green);
}
.chip--hold {
  background: var(--amber-wash);
  color: var(--amber);
}
.chip--done {
  background: var(--mist-deep);
  color: var(--slate-light);
}
.chip--blue {
  background: var(--blue-wash);
  color: var(--blue);
}

.chip--plain::before {
  display: none;
}

/* Outlined tag used in headings and trust rows. */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8125rem;
  font-weight: 600;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 100px;
  color: var(--slate);
  background: var(--white);
}

.tag--live {
  border-color: rgba(18, 128, 92, 0.3);
  color: var(--green);
  background: var(--green-wash);
}

/* ========== TRUST ROW ========== */
.trust {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 2rem;
  padding-top: 1.75rem;
  margin-top: 2.25rem;
  border-top: 1px solid var(--line-soft);
}

.trust li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--slate-light);
}

.trust li::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--blue);
  opacity: 0.5;
}

/* ========== STATS ========== */
.stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

@media (min-width: 48rem) {
  .stats--3 {
    grid-template-columns: repeat(3, 1fr);
  }
  .stats--4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

.stat {
  background: var(--white);
  padding: 1.4rem 1.5rem 1.6rem;
}

.stat-fig {
  font-size: clamp(1.75rem, 2.6vw, 2.25rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.stat-fig span {
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--blue);
  margin-left: 0.15rem;
}

.stat-cap {
  margin-top: 0.55rem;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--slate-light);
}

.sect--navy .stats {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.14);
}
.sect--navy .stat {
  background: var(--navy);
}
.sect--navy .stat-fig {
  color: #fff;
}
.sect--navy .stat-fig span {
  color: #7fa9ff;
}
.sect--navy .stat-cap {
  color: rgba(255, 255, 255, 0.62);
}

/* ========== CHECKLIST ========== */
.checklist {
  display: grid;
  gap: 0.85rem;
}

.checklist li {
  position: relative;
  padding-left: 1.7rem;
  font-size: 0.9375rem;
  line-height: 1.55;
}

.checklist li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--green);
  line-height: 1.75;
}

.checklist--pending li::before {
  content: "○";
  color: var(--slate-light);
  font-weight: 400;
}

.checklist--pending li {
  color: var(--slate-light);
}

.sect--navy .checklist li {
  color: rgba(255, 255, 255, 0.78);
}
.sect--navy .checklist li::before {
  color: #6ee7b7;
}

/* ========== DATA TABLE ========== */
.table-wrap {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

.table th {
  background: var(--mist);
  color: var(--slate-light);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: left;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

.table td {
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--line-soft);
  color: var(--navy);
}

.table tr:last-child td {
  border-bottom: 0;
}

.table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.table .dim {
  color: var(--slate-light);
}

/* ========== Q&A (native details) ========== */
.qa {
  border-top: 1px solid var(--line);
}

.qa details {
  border-bottom: 1px solid var(--line);
}

.qa summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.25rem 0;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--navy);
}

.qa summary::-webkit-details-marker {
  display: none;
}

.qa summary::after {
  content: "+";
  margin-left: auto;
  font-size: 1.25rem;
  font-weight: 400;
  color: var(--slate-light);
  transition: transform 0.18s ease, color 0.15s ease;
}

.qa details[open] summary::after {
  content: "−";
  color: var(--blue);
}

.qa summary:hover {
  color: var(--blue);
}

.qa-a {
  padding: 0 0 1.4rem;
  max-width: 68ch;
  font-size: 0.9375rem;
}

/* ========== STEPS ========== */
.steps {
  display: grid;
  gap: 2rem;
  counter-reset: step;
}

@media (min-width: 52rem) {
  .steps {
    grid-template-columns: repeat(3, 1fr);
    gap: 2.5rem;
  }
}

.steps li {
  counter-increment: step;
  padding-top: 1.25rem;
  border-top: 2px solid var(--line);
}

.steps li:first-child {
  border-top-color: var(--blue);
}

.steps li::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--blue);
  margin-bottom: 0.75rem;
}

.steps h3 {
  margin-bottom: 0.5rem;
}

.steps p {
  font-size: 0.9375rem;
}

/* ========== CLOSER ========== */
.closer {
  background: var(--navy);
  color: rgba(255, 255, 255, 0.76);
  padding: clamp(3.5rem, 7vw, 5.5rem) 0;
}

.closer h2 {
  color: #fff;
  max-width: 18ch;
  margin-bottom: 1rem;
}

.closer p {
  max-width: 50ch;
  margin-bottom: 2rem;
}

.closer-grid {
  display: grid;
  gap: 2.5rem;
}

@media (min-width: 62rem) {
  .closer-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
    gap: 4rem;
    align-items: center;
  }
}

.closer-notes {
  display: grid;
  gap: 0.75rem;
}

.closer-notes li {
  position: relative;
  padding-left: 1.6rem;
  font-size: 0.9375rem;
  color: rgba(255, 255, 255, 0.76);
}

.closer-notes li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: #6ee7b7;
  font-size: 0.8125rem;
  line-height: 1.75;
}

/* ========== FOOTER ========== */
.footer {
  border-top: 1px solid var(--line);
  padding: clamp(3rem, 5vw, 4.5rem) 0 0;
}

.footer-grid {
  display: grid;
  gap: 2.5rem;
  padding-bottom: 3rem;
}

@media (min-width: 48rem) {
  .footer-grid {
    grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
    gap: 2rem;
  }
}

.footer-brand p {
  font-size: 0.875rem;
  line-height: 1.6;
  max-width: 32ch;
  margin: 1rem 0 1.25rem;
  color: var(--slate-light);
}

.footer-col h4 {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slate-light);
  margin-bottom: 0.9rem;
}

.footer-col li a {
  display: block;
  padding: 0.35rem 0;
  font-size: 0.9375rem;
  color: var(--slate);
  transition: color 0.15s ease;
}

.footer-col li a:hover {
  color: var(--blue);
}

.footer-social {
  display: flex;
  gap: 0.5rem;
}

.footer-social a {
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--slate);
  transition: all 0.15s ease;
}

.footer-social a svg {
  width: 16px;
  height: 16px;
}

.footer-social a:hover {
  border-color: var(--navy);
  background: var(--navy);
  color: #fff;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  align-items: center;
  padding: 1.35rem 0;
  border-top: 1px solid var(--line-soft);
  font-size: 0.8125rem;
  color: var(--slate-light);
}

.footer-bottom .end {
  margin-left: auto;
}

/* ========================================================================
   PRODUCT INTERFACE RENDERINGS
   Drawn in markup rather than shipped as screenshots, so they stay sharp and
   stay honest. Every one of them carries a caption saying it is a rendering
   with example data.
   ======================================================================== */
.ui {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-panel);
  overflow: hidden;
}

.ui-bar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 0.95rem;
  border-bottom: 1px solid var(--line);
  background: var(--mist);
}

.ui-title {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--navy);
}

.ui-bar .chip {
  margin-left: auto;
}

.ui-body {
  display: grid;
}

@media (min-width: 40rem) {
  .ui-body--split {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  }
}

.ui-map {
  position: relative;
  min-height: 250px;
  background: #eef2f7;
  background-image: linear-gradient(rgba(13, 39, 68, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(13, 39, 68, 0.05) 1px, transparent 1px);
  background-size: 34px 34px;
  /* Divider follows the layout: beside the list on wide screens, under it
     once the panel stacks. */
  border-bottom: 1px solid var(--line);
}

@media (min-width: 40rem) {
  .ui-body--split .ui-map {
    border-bottom: 0;
    border-right: 1px solid var(--line);
  }
}

.ui-map svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.ui-side {
  display: flex;
  flex-direction: column;
}

.ui-side-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.7rem 0.95rem;
  border-bottom: 1px solid var(--line-soft);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slate-light);
}

.ui-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.2rem 0.75rem;
  padding: 0.7rem 0.95rem;
  border-bottom: 1px solid var(--line-soft);
}

.ui-row:last-child {
  border-bottom: 0;
}

.ui-row--active {
  background: var(--blue-wash);
  box-shadow: inset 2px 0 0 var(--blue);
}

.ui-row-main {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--navy);
}

.ui-row-sub {
  grid-column: 1;
  font-size: 0.75rem;
  color: var(--slate-light);
}

.ui-row-eta {
  grid-row: span 2;
  align-self: center;
  text-align: right;
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.ui-cap {
  padding: 0.6rem 0.95rem;
  border-top: 1px solid var(--line-soft);
  background: var(--mist);
  font-size: 0.75rem;
  color: var(--slate-light);
  line-height: 1.5;
}

/* Figure caption used outside the frame. */
.fig-note {
  margin-top: 0.9rem;
  font-size: 0.8125rem;
  color: var(--slate-light);
  line-height: 1.5;
}

/* ========== PHONE RENDERING ========== */
.phone {
  width: 260px;
  margin: 0 auto;
  border: 1px solid var(--line);
  border-radius: 26px;
  background: var(--white);
  box-shadow: var(--shadow-panel);
  padding: 0.5rem;
}

.phone-screen {
  border-radius: 20px;
  overflow: hidden;
  background: var(--mist);
}

.phone-top {
  background: var(--navy);
  color: #fff;
  padding: 1rem 0.9rem 1.1rem;
}

.phone-top .tiny {
  font-size: 0.6875rem;
  color: rgba(255, 255, 255, 0.6);
}

.phone-top h4 {
  color: #fff;
  font-size: 1rem;
  margin-top: 0.15rem;
}

.phone-progress {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.9rem;
}

.phone-progress span {
  flex: 1;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.22);
}

.phone-progress span.done {
  background: #6ee7b7;
}

.phone-list {
  padding: 0.75rem;
  display: grid;
  gap: 0.5rem;
}

.phone-stop {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 0.6rem 0.7rem;
}

.phone-stop.current {
  border-color: var(--blue);
  box-shadow: 0 0 0 2px var(--blue-wash);
}

.phone-stop-name {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--navy);
}

.phone-stop-sub {
  font-size: 0.6875rem;
  color: var(--slate-light);
  margin-top: 0.1rem;
}

.phone-action {
  margin-top: 0.55rem;
  padding: 0.5rem;
  text-align: center;
  background: var(--blue);
  color: #fff;
  border-radius: var(--r-sm);
  font-size: 0.75rem;
  font-weight: 600;
}

/* ========== FORMS ========== */
.field {
  display: grid;
  gap: 0.4rem;
  margin-bottom: 1.1rem;
}

.field label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--navy);
}

.field .req {
  color: var(--blue);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--white);
  font-size: 0.9375rem;
  color: var(--navy);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field input::placeholder,
.field textarea::placeholder {
  color: #a9b4c4;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-wash);
}

.field textarea {
  min-height: 8rem;
  resize: vertical;
}

.field-row {
  display: grid;
  gap: 0 1rem;
}

@media (min-width: 34rem) {
  .field-row--2 {
    grid-template-columns: repeat(2, 1fr);
  }
}

.consent {
  display: grid;
  grid-template-columns: 1.1rem minmax(0, 1fr);
  gap: 0.65rem;
  align-items: start;
  font-size: 0.8125rem;
  color: var(--slate);
  margin-bottom: 1.35rem;
}

.consent input {
  margin-top: 0.22rem;
  accent-color: var(--blue);
}

.form-note {
  margin-top: 1rem;
  font-size: 0.8125rem;
  color: var(--slate-light);
}

.notice {
  padding: 0.85rem 1rem;
  border: 1px solid rgba(168, 100, 18, 0.3);
  border-left-width: 3px;
  border-radius: var(--r);
  background: var(--amber-wash);
  font-size: 0.875rem;
  color: #6f4207;
  line-height: 1.55;
  margin-bottom: 1.25rem;
}

/* ========================================================================
   PRODUCT SHOTS
   Frames captured from the CargoGauge product film and presented as screens:
   fixed aspect, rounded, one soft shadow. They are pictures of the real
   interface, so they carry a caption saying whose data is on them.
   ======================================================================== */
.shot {
  margin: 0;
}

.shot-frame {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  background: var(--white);
  border: 1px solid var(--line);
  box-shadow: 0 24px 60px -28px rgba(13, 39, 68, 0.3),
    0 2px 8px rgba(13, 39, 68, 0.05);
}

.shot-frame img {
  display: block;
  width: 100%;
  height: auto;
}

/* The driver scenes are portrait, so they get a phone-sized column rather
   than being stretched across a feature panel. */
.shot--phone {
  max-width: 360px;
  margin: 0 auto;
}

/* The phone stills are rendered from the design system's own PhoneFrame, so
   the bezel is already in the picture and is cut out against transparency.
   Drawing a second frame here is what produced the double border. */
.shot--phone .shot-frame {
  border-radius: 0;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  /* The base rule clips; the phone's shadow has to fall outside its box. */
  overflow: visible;
}

/* drop-shadow follows the alpha silhouette, so the shadow hugs the phone
   rather than sitting behind a rectangle. */
.shot--phone .shot-frame img {
  border-radius: 0;
  filter: drop-shadow(0 18px 34px rgba(13, 39, 68, 0.26));
}

.shot-cap {
  margin-top: 0.9rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--slate-light);
}

.shot--phone .shot-cap {
  text-align: center;
}

/* ========================================================================
   FEATURE STEPS
   A wide visual beside a column of copy. On a wide screen the visual is
   pinned: it holds still while the bullets scroll past it, and the script
   moves the marker down the list and points the picture at whatever is being
   read. The bullets are spaced to give that read its length, so the pin lasts
   as long as the copy and no longer. An earlier attempt pinned a fixed 84vh
   and left a screen and a half of dead space wherever the copy ran short.
   ======================================================================== */
.steps-wrap {
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.fstep {
  display: grid;
  gap: clamp(1.75rem, 3vw, 2.5rem);
  padding: clamp(3rem, 5.5vw, 5rem) 0;
  border-top: 1px solid var(--line-soft);
  align-items: center;
}

.fstep:first-child {
  border-top: 0;
  padding-top: clamp(1rem, 2vw, 2rem);
}

.fstep-copy .eyebrow {
  margin-bottom: 0.75rem;
}

.fstep-copy h2 {
  margin-bottom: 1rem;
}

.fstep-copy .lede {
  margin-bottom: 1.75rem;
}

@media (min-width: 66rem) {
  .fstep {
    grid-template-columns: minmax(0, 25rem) minmax(0, 1fr);
    gap: clamp(2.5rem, 4vw, 4rem);
    /* Start, not centre: the copy column is the taller one now, and the
       visual has to sit at the top of it to have anywhere to stick to. */
    align-items: start;
  }

  /* The pin lasts for (step height - visual height), so the visual must stay
     its natural size. Stretching it to the full viewport spent most of the
     pin and released it two thirds of the way down, sliding the picture up
     under the header while the last bullets were still being read. */
  .fstep-visual {
    position: sticky;
    top: calc(var(--chrome-h) + 2.5rem);
  }

  /* The length of the read. Enough scroll per bullet to take one at a time,
     no more: this is what decides how far the reader has to travel. */
  .feature-list[data-beats] > li {
    min-height: max(14rem, 24vh);
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  /* A floor of room below the last bullet, so it can reach the middle of the
     screen while the visual is still pinned. The exact amount depends on how
     tall the pinned element is, which only the script can measure, so it tops
     this up per step. */
  .feature-list[data-beats] {
    padding-bottom: 8vh;
  }

  /* Flipping has to move the column widths too, not just the order. Ordering
     alone put the wide screenshot into the narrow copy column and left every
     other feature with a thumbnail. */
  .fstep--flip {
    grid-template-columns: minmax(0, 1fr) minmax(0, 23rem);
  }

  .fstep--flip .fstep-visual {
    order: 1;
  }

  .fstep--flip .fstep-copy {
    order: 2;
  }
}

/* A live scene that plays an entrance when it scrolls into view. The still
   underneath is what a visitor sees with scripting off or reduced motion on. */
.scene {
  position: relative;
}

/* A portrait scene in the wide visual column would be taller than the screen.
   Cap it the way the phone screenshots are capped. */
.scene--phone .scene-box {
  max-width: 19rem;
  margin-inline: auto;
  border-radius: 0;
  border: 0;
  background: none;
  box-shadow: none;
  /* drop-shadow applies to the element's rendered result, so it falls outside
     the box even though the box still clips its children. That matters: the
     box has to keep clipping, because before the script resizes it the stage
     inside is 1920px wide and would push a horizontal scrollbar onto narrow
     screens. */
  filter: drop-shadow(0 18px 34px rgba(13, 39, 68, 0.26));
}

/* The film draws the phone with a shadow scaled for a 1920x1080 stage, inline
   on the frame itself. At the size the site shows it that reads as a smudge,
   and it is what was being clipped. The site draws its own instead. */
.cg-phone-stage > div {
  box-shadow: none !important;
}

.scene--phone .scene-note {
  text-align: center;
}

.scene-box {
  position: relative;
  width: 100%;
  /* The scenes are authored 16:9. Fixing the box to that ratio means the still
     and the live scene fill the same rectangle, so mounting causes no jump. */
  aspect-ratio: 16 / 9;
  margin-inline: auto;
  overflow: hidden;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: #f5f6f3;
  box-shadow: 0 24px 60px -28px rgba(13, 39, 68, 0.3),
    0 2px 8px rgba(13, 39, 68, 0.05);
}

.scene-box > img {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* This has to beat the rule above. An author `display: block` outranks the
   browser's own `[hidden] { display: none }`, so without this the still stays
   in flow after the live scene mounts and shoves the scene out of the box. */
.scene-box > img[hidden] {
  display: none;
}

/* The scene is authored against a fixed 1920x1080 stage; the script scales it
   to whatever width the box has and sets the box height to match. Layering it
   over the box keeps it put no matter what else is in there. */
.scene-stage {
  position: absolute;
  top: 0;
  left: 0;
  width: 1920px;
  height: 1080px;
  transform-origin: top left;
}

.scene-note {
  margin-top: 0.9rem;
  font-size: 0.8125rem;
  color: var(--slate-light);
}

/* ========================================================================
   LEGAL DOCUMENTS
   The privacy policy and terms were published in 2025 as standalone pages with
   their own inline stylesheet. Their markup is now lifted onto the site's
   chrome unchanged, so these rules dress the tags the original used: plain
   headings and lists, two tables, and the three callout boxes it defined.
   ======================================================================== */
.legal-updated {
  font-size: 0.9375rem;
  color: var(--slate-light);
}

.legal {
  max-width: 68ch;
}

.legal h2 {
  font-size: 1.375rem;
  letter-spacing: -0.018em;
  margin: 3rem 0 0.9rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line-soft);
}

.legal > h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.legal h3 {
  font-size: 1.0625rem;
  margin: 1.75rem 0 0.5rem;
}

.legal p {
  margin-bottom: 1rem;
}

.legal ul {
  margin: 0 0 1.25rem;
  display: grid;
  gap: 0.5rem;
}

/* The marker is positioned rather than a list-style, so a <strong> lead-in
   inside the item cannot become a grid item of its own and stack one word
   per line. */
.legal li {
  position: relative;
  padding-left: 1.4rem;
}

.legal li::before {
  content: "";
  position: absolute;
  left: 0.3rem;
  top: 0.66em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--line);
}

.legal table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.25rem 0 1.75rem;
  font-size: 0.9375rem;
}

.legal th,
.legal td {
  text-align: left;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}

.legal th {
  background: var(--mist);
  color: var(--navy);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  border-bottom-color: var(--line);
}

.legal tbody tr:last-child td {
  border-bottom: 0;
}

/* Wide tables get their own scroller rather than pushing the page sideways. */
.legal table {
  display: block;
  overflow-x: auto;
  white-space: normal;
}

.legal .info-box,
.legal .warning-box,
.legal .contact-section {
  border-radius: var(--r-lg);
  padding: 1.1rem 1.25rem;
  margin: 1.5rem 0;
}

.legal .info-box {
  background: var(--blue-wash);
  border-left: 3px solid var(--blue);
}

.legal .warning-box {
  background: var(--amber-wash);
  border-left: 3px solid var(--amber);
}

.legal .contact-section {
  background: var(--mist);
  border: 1px solid var(--line);
}

.legal .contact-section h3 {
  margin-top: 0;
}

.legal .contact-section p {
  margin-bottom: 0.4rem;
}

.legal .contact-section p:last-child {
  margin-bottom: 0;
}

/* ========================================================================
   COOKIE NOTICE
   A single card in the corner rather than a full-width bar across the bottom:
   it reports a fact and asks for nothing, so it has no business covering the
   page or blocking the footer links directly underneath it.
   ======================================================================== */
.cookie-note {
  position: fixed;
  z-index: 60; /* over the page, under the mobile menu at 100 */
  left: var(--gutter);
  right: var(--gutter);
  bottom: var(--gutter);
  display: flex;
  justify-content: flex-end;
  pointer-events: none; /* the card takes the clicks, not this full-width row */
}

/* This has to beat the rule above. An author `display: flex` outranks the
   browser's own `[hidden] { display: none }`, so without this the notice stays
   on screen after it is dismissed and blocks the footer behind it. */
.cookie-note[hidden] {
  display: none;
}

.cookie-note-inner {
  pointer-events: auto;
  width: min(30rem, 100%);
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.15rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 12px 32px rgba(13, 39, 68, 0.14);

  /* Start low and clear, then slide in. Paired with .is-in from the script. */
  opacity: 0;
  transform: translateY(0.75rem);
  transition: opacity 0.26s ease, transform 0.26s ease;
}

.cookie-note.is-in .cookie-note-inner {
  opacity: 1;
  transform: none;
}

.cookie-note-text {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--slate);
}

.cookie-note-text strong {
  color: var(--navy);
}

.cookie-note-text a {
  color: var(--blue);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* The button must not be squeezed to one word per line by the text beside it. */
.cookie-note-ok {
  flex: none;
  padding: 0.5rem 1rem;
  font-size: 0.8125rem;
}

@media (max-width: 30rem) {
  .cookie-note-inner {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
  }
}

/* Motion is decoration here. The notice still appears, it just arrives. */
@media (prefers-reduced-motion: reduce) {
  .cookie-note-inner {
    transition: none;
    transform: none;
  }
}

/* ========== SCROLL REVEAL ==========
   Sections fade up as they come into view. The pre-state hangs off
   `html.reveal-on`, which an inline script in the head sets before the first
   paint and only when the visitor has not asked for less motion. The selector
   list below is mirrored by REVEAL in the shared footer script; keep them in
   step. Nothing here applies to the hero, which must not animate in. */
.reveal-on .sect-head,
.reveal-on .fstep-copy,
.reveal-on .fstep-visual,
.reveal-on .panel,
.reveal-on .stat,
.reveal-on .fact,
.reveal-on .why-card,
.reveal-on .ea-card,
.reveal-on .state-head,
.reveal-on .qa-mini,
.reveal-on .checklist,
.reveal-on .story,
.reveal-on .who,
.reveal-on .table-wrap,
.reveal-on .deflist,
.reveal-on .closer-grid > *,
.reveal-on .two-col > * {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.65s cubic-bezier(0.22, 0.61, 0.24, 1),
    transform 0.65s cubic-bezier(0.22, 0.61, 0.24, 1);
}

.reveal-on .is-in {
  opacity: 1;
  transform: none;
}

/* ========== PRINT ========== */
@media print {
  .header,
  .mobile-menu,
  .btn {
    display: none;
  }
  body {
    color: #000;
  }
}
