/* ==========================================================================
   RLM Carrier Group — design system v2
   Composition and motion language adapted from unitedcarriers.com (master ref),
   over the brand palette sampled from the RLM logo artwork.
   ========================================================================== */

/* --------------------------------------------------------------------------
   TESTE DE TIPOGRAFIA: os titulos voltaram para Archivo, a fonte da v1.
   A BBH Bogle continua auto-hospedada abaixo, desligada apenas pela variavel
   --display. Para voltar a ela: troque --display para "BBH Bogle", devolva
   font-weight 400 / line-height 1.3 / letter-spacing 0 / sem font-stretch nos
   titulos, e troque o link do Google Fonts pelo preload da Bogle no <head>.

   Body e rotulos usam Helvetica Neue, que nao precisa de webfont: e fonte de
   sistema na Apple e cai para Helvetica/Arial no resto.
-------------------------------------------------------------------------- */
@font-face {
  font-family: "BBH Bogle";
  src: url("../fonts/BBHBogle-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Brand — sampled from the logo artwork */
  --navy: #053a6c;
  --navy-deep: #032443;
  --navy-ink: #01182c;
  --orange: #e26b1b;
  --orange-bright: #f07f2a;
  --orange-deep: #be5116;

  /* Surfaces */
  --paper: #ffffff;
  --panel: #f4f2ee;
  --ink: #111111;

  /* Text + hairlines, alpha-based like the master reference */
  --ink-soft: rgba(17, 17, 17, 0.72);
  --ink-faint: rgba(17, 17, 17, 0.38);
  --line: rgba(17, 17, 17, 0.16);
  --line-dark: rgba(255, 255, 255, 0.18);
  --on-dark-soft: rgba(255, 255, 255, 0.64);
  --dim: 0.24; /* opacity of the "setup" half of a two-tone headline */

  /* Type */
  --display: "Archivo", "Arial Black", sans-serif;
  --body: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --label: "Helvetica Neue", Helvetica, Arial, sans-serif;
  /* TESTE: o mono da v1, hoje so nos botoes e na navegacao do header */
  --label-mono: "IBM Plex Mono", ui-monospace, monospace;

  /* Motion */
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --ease-out: cubic-bezier(0.05, 0.7, 0.1, 1);
  --t-quick: 160ms;
  --t-base: 280ms;
  --t-slow: 400ms;

  /* Layout */
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --maxw: 1440px;
  --header-h: 84px;
  --rhythm: clamp(4.5rem, 3rem + 7vw, 9rem);
  --rhythm-tight: clamp(3rem, 2rem + 4vw, 5.5rem);
  --rhythm-xs: clamp(2rem, 1.5rem + 2vw, 3.25rem);
}

/* ---------- Reset ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html {
  color-scheme: light;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 24px);
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img,
svg { display: block; max-width: 100%; }

/* an explicit display wins over the hidden attribute without this */
[hidden] { display: none !important; }

a { color: inherit; text-decoration: none; }

button,
input,
select,
textarea { font: inherit; color: inherit; }

a,
button,
input,
select,
textarea,
summary {
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(226, 107, 27, 0.2);
}

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

:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
}

/* ---------- Typography ---------- */
h1, h2, h3, h4 {
  font-family: var(--display);
  /* Archivo is variable and ships a real 800, so no synthesis is involved */
  font-weight: 800;
  font-synthesis: none;
  font-stretch: 112%;
  line-height: 1.06;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  text-wrap: balance;
}

h1 { font-size: clamp(2.5rem, 1.5rem + 4.4vw, 5.25rem); }
h2 { font-size: clamp(2rem, 1.375rem + 2.8vw, 3.75rem); }
h3 { font-size: clamp(1.125rem, 1rem + 0.5vw, 1.5rem); line-height: 1.25; }

p { text-wrap: pretty; }

.lede {
  font-size: clamp(1.125rem, 1rem + 0.4vw, 1.375rem);
  line-height: 1.5;
  color: var(--ink-soft);
}

/* Two-tone headline: the setup reads at full strength and the payoff carries the
   brand orange. The heading itself is coloured and .dim pulls its half back to
   the surface colour, so no extra span is needed around the payoff. */
.dim { opacity: 1; color: var(--ink); }

.on-dark .dim,
.hero .dim,
.banner .dim,
.cta .dim { color: var(--paper); }

h1:has(.dim),
h2:has(.dim) { color: var(--orange); }

.on-dark h1:has(.dim),
.on-dark h2:has(.dim),
.hero h1:has(.dim),
.banner h1:has(.dim) { color: var(--orange-bright); }

/* Label */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--label);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--orange-deep);
}

.kicker::before {
  content: "";
  width: 26px;
  height: 1px;
  background: currentColor;
}

.on-dark .kicker,
.hero .kicker,
.banner .kicker { color: var(--orange-bright); }

/* ---------- Layout ---------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--rhythm); }
.section--tight { padding-block: var(--rhythm-tight); }
.section--panel { background: var(--panel); }

.section-head {
  display: grid;
  gap: 1.5rem;
  margin-bottom: clamp(2.5rem, 2rem + 2vw, 4.5rem);
}

.section-head p.lede { max-width: 58ch; }

.section-head--split { gap: 2rem; }

@media (min-width: 960px) {
  .section-head--split {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    align-items: end;
    gap: 4rem;
  }
}

.on-dark {
  background: var(--navy-deep);
  color: var(--paper);
}

.on-dark .lede { color: var(--on-dark-soft); }

/* back-to-back dark sections read as one panel, so the doubled padding between
   them is just an empty gap */
.on-dark + .on-dark { padding-top: 0; }

/* ---------- Buttons ---------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  /* v1's button box was 17px/28px with no border. This variant carries a 1px
     border for the ghost outline, so the padding drops by that 1px on each side
     to land on the same rendered size. */
  padding: 1rem 1.6875rem;
  border: 1px solid transparent;
  background: var(--orange);
  color: #fff;
  font-family: var(--label-mono);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  overflow: hidden;
  transition: transform var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease),
              color var(--t-base) var(--ease);
}

/* v1 hover: a lighter wash sweeps across from the left, under the label */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--orange-bright);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-base) var(--ease);
}

/* label and arrow ride above the wash */
.btn > * { position: relative; z-index: 1; }

.btn .arrow { transition: transform var(--t-base) var(--ease); }

.btn--ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--ink);
}

.btn--ghost::before { background: var(--ink); }

.on-dark .btn--ghost,
.hero .btn--ghost,
.banner .btn--ghost {
  border-color: rgba(255, 255, 255, 0.45);
  color: var(--paper);
}

.on-dark .btn--ghost::before,
.hero .btn--ghost::before,
.banner .btn--ghost::before { background: var(--paper); }

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

/* Text link */
.link {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange-deep);
  padding-bottom: 4px;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size var(--t-base) var(--ease);
}

.link .arrow { transition: transform var(--t-base) var(--ease); }
.on-dark .link { color: var(--orange-bright); }

/* ---------- Header ---------- */
/* Fixed rather than sticky: sticky still occupies a row in the flow, which would
   push the hero down instead of letting it run under the bar. */
.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease);
}

.header.is-stuck {
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border-bottom-color: var(--line);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  height: var(--header-h);
}

/* Two marks stacked: the reversed one reads over the dark hero, the navy one
   over the white bar. Swapping opacity avoids the flash a src swap would give. */
.brand { position: relative; display: block; line-height: 0; }

.brand__mark {
  height: 54px;
  width: auto;
  transition: opacity var(--t-base) var(--ease);
}

.brand__mark--dark { position: absolute; inset: 0; opacity: 0; }
.header.is-stuck .brand__mark--light { opacity: 0; }
.header.is-stuck .brand__mark--dark { opacity: 1; }

.nav { display: none; gap: clamp(1.5rem, 2.4vw, 2.75rem); }

@media (min-width: 1060px) { .nav { display: flex; align-items: center; } }

.nav a {
  position: relative;
  font-family: var(--label-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-block: 0.5rem;
  transition: color var(--t-quick) linear;
}

.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--t-base) var(--ease);
}

/* over the hero the bar is transparent, so its content runs light */
.nav a,
.header__phone { color: var(--paper); }

.header.is-stuck .nav a,
.header.is-stuck .header__phone { color: var(--ink); }

.nav a[aria-current="page"] { color: var(--orange-bright); }
.header.is-stuck .nav a[aria-current="page"] { color: var(--orange-deep); }
.nav a[aria-current="page"]::after { transform: scaleX(1); }

.header__actions { display: flex; align-items: center; gap: 1.25rem; }

.header__phone {
  display: none;
  font-family: var(--label-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.08em;
}

@media (min-width: 760px) { .header__phone { display: block; } }

.header .btn { display: none; padding: 0.875rem 1.375rem; }
@media (min-width: 640px) { .header .btn { display: inline-flex; } }

.burger {
  display: grid;
  place-content: center;
  gap: 5px;
  width: 46px;
  height: 46px;
  background: none;
  border: 1px solid var(--line);
  cursor: pointer;
}

@media (min-width: 1060px) { .burger { display: none; } }

.header:not(.is-stuck) .burger { border-color: rgba(255, 255, 255, 0.4); }
.header:not(.is-stuck) .burger span { background: var(--paper); }

.burger span {
  display: block;
  width: 18px;
  height: 1px;
  background: var(--ink);
  transition: transform var(--t-base) var(--ease), opacity var(--t-quick) linear;
}

.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.drawer {
  position: fixed;
  inset: var(--header-h) 0 auto 0;
  z-index: 99;
  background: var(--navy-deep);
  color: var(--paper);
  padding: 2rem var(--gutter) calc(2.5rem + env(safe-area-inset-bottom));
  display: grid;
  gap: 0.25rem;
  transform: translateY(-101%);
  /* hidden outright when closed: it sits just above the bar, and a transparent
     header let its last item show through in the top corner */
  visibility: hidden;
  transition: transform var(--t-slow) var(--ease),
              visibility 0s linear var(--t-slow);
  overscroll-behavior: contain;
}

.drawer.is-open {
  transform: translateY(0);
  visibility: visible;
  transition: transform var(--t-slow) var(--ease), visibility 0s;
}

.drawer a {
  font-family: var(--display);
  font-size: 1.25rem;
  text-transform: uppercase;
  padding-block: 0.75rem;
  border-bottom: 1px solid var(--line-dark);
  transition: color var(--t-quick) linear, transform var(--t-base) var(--ease);
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(560px, 88vh, 900px);
  padding-block: var(--rhythm) var(--rhythm-tight);
  background: var(--navy-ink);
  color: var(--paper);
  overflow: hidden;
  isolation: isolate;
}

.hero__media { position: absolute; inset: 0; z-index: -2; }

.hero__media img,
.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* No opacity gate any more. The poster is frame zero of this very video, so the
   element can be visible from the start: the loop takes over on the identical
   frame and the handover is invisible. Hiding it until "playing" fired meant a
   blank navy hero for as long as the file took to arrive -- and forever when
   autoplay was refused, which phones do in low power mode. */
.hero__video {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Every stop is the old value times 0.85: the video reads 15% stronger through
     the scrim without changing where the gradient turns, so the copy keeps the
     same shape of cover it was designed against. */
  background:
    linear-gradient(180deg, rgba(1, 24, 44, 0.7) 0%, rgba(1, 24, 44, 0.36) 38%, rgba(1, 24, 44, 0.81) 100%),
    linear-gradient(90deg, rgba(5, 58, 108, 0.63) 0%, rgba(5, 58, 108, 0.085) 68%);
}

/* TESTE DE DIAGRAMACAO: o conteudo do hero ignora a centralizacao do container
   e encosta na borda esquerda da tela. O bloco continua limitado em 72rem para a
   linha de texto nao esticar em monitor largo, mas nasce no gutter da esquerda em
   vez de no centro do grid de 1440.
   Para voltar ao centralizado: remova o margin-inline: 0. */
.hero__inner {
  max-width: 72rem;
  width: 100%;
  margin-inline: 0;
}
.hero h1 { margin-block: 1.5rem 2rem; }
/* subheadline da hero fecha em duas linhas: a medida abre o suficiente e o
   balance divide o texto por igual entre elas */
.hero .lede {
  max-width: 72ch;
  color: rgba(255, 255, 255, 0.78);
  text-wrap: balance;
}

/* Circle wipe that opens the hero, echoing the master's transition circles */
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 50%;
  width: 180vmax;
  height: 180vmax;
  border-radius: 50%;
  background: var(--navy-ink);
  transform: translate(-50%, -50%) scale(1);
  animation: circle-open 1100ms var(--ease-out) 120ms forwards;
  pointer-events: none;
}

@keyframes circle-open {
  to { transform: translate(-50%, -50%) scale(0); }
}

/* ---------- Page banner ---------- */
.banner {
  position: relative;
  padding-block: calc(var(--rhythm) + var(--header-h)) var(--rhythm-tight);
  background: var(--navy-deep);
  color: var(--paper);
  overflow: hidden;
  isolation: isolate;
}

.banner__media { position: absolute; inset: 0; z-index: -2; }

.banner__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.banner__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(3, 36, 67, 0.95) 14%, rgba(3, 36, 67, 0.7) 62%, rgba(5, 58, 108, 0.46));
}

.banner h1 { margin-block: 1.25rem 1.25rem; text-wrap: pretty; }
.banner .lede { max-width: 54ch; color: rgba(255, 255, 255, 0.78); }

.crumbs {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}

/* ---------- Marquee ---------- */
.ticker {
  background: var(--orange);
  color: #fff;
  padding-block: 1rem;
  overflow: hidden;
}

.ticker__track { display: flex; width: max-content; animation: ticker 42s linear infinite; }

.ticker__group {
  display: flex;
  align-items: center;
  gap: 3rem;
  padding-right: 3rem;
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  white-space: nowrap;
}

.ticker__group span { display: flex; align-items: center; gap: 3rem; }

.ticker__group span::after {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.8);
}

@keyframes ticker {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ---------- Media with corner brackets ---------- */
.media {
  position: relative;
  overflow: hidden;
  background: var(--navy-deep);
}

.media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms var(--ease);
}

.media--4x3 { aspect-ratio: 4 / 3; }
.media--3x2 { aspect-ratio: 3 / 2; }
.media--16x9 { aspect-ratio: 16 / 9; }
.media--tall { aspect-ratio: 3 / 4; }

.framed { position: relative; }

.framed::before,
.framed::after {
  content: "";
  position: absolute;
  width: 22px;
  height: 22px;
  border: 1px solid rgba(255, 255, 255, 0.85);
  z-index: 2;
  pointer-events: none;
  transition: inset var(--t-slow) var(--ease);
}

.framed::before { top: 14px; left: 14px; border-right: 0; border-bottom: 0; }
.framed::after { bottom: 14px; right: 14px; border-left: 0; border-top: 0; }

/* ---------- Hero fact strip (as in v1: blocks sitting inside the hero) ---------- */
.facts {
  display: grid;
  /* fixed tracks instead of auto-fit: 4 items never leave an orphan row */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin-top: clamp(3rem, 2rem + 4vw, 4.5rem);
  background: var(--line-dark);
  border-block: 1px solid var(--line-dark);
}

.facts div {
  background: var(--navy-ink);
  /* The left inset used to bottom out at 0, so on a phone the copy sat flush
     against the cell edge with 4px of air. A real minimum instead. */
  padding: 1.5rem;
  padding-left: clamp(1.25rem, 1.5vw, 2rem);
}

.facts dt {
  font-family: var(--label-mono);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--orange-bright);
  margin-bottom: 0.5rem;
}

.facts dd {
  font-family: var(--display);
  font-size: 1.125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

@media (min-width: 1000px) {
  .facts { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ---------- Service rows (master) ---------- */
.rows { display: grid; }

.row {
  position: relative;
  display: grid;
  gap: 0.75rem 2rem;
  padding-block: clamp(1.75rem, 1.25rem + 2vw, 2.75rem);
  /* a permanent inset, cancelled by the negative margin, so the hover tint has
     room to breathe around the text without ever shifting the layout */
  padding-inline: 1.25rem;
  margin-inline: -1.25rem;
  border-top: 1px solid var(--line);
  transition: background-color var(--t-base) var(--ease);
}

/* only the content glides; animating padding reflowed the row and felt abrupt */
.row__num,
.row h3,
.row p { transition: transform var(--t-slow) var(--ease); }

.rows .row:last-child { border-bottom: 1px solid var(--line); }

/* A photograph per equipment row. Scoped to .rows--media on purpose: the same
   .row component runs on the home page and on services without a thumbnail, and
   widening the track list globally would push their text into the wrong column. */
.row__thumb {
  position: relative;
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--navy-deep);
  max-width: 20rem;
}

.row__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}

@media (min-width: 900px) {
  .rows--media .row {
    grid-template-columns: 4.5rem 12rem minmax(0, 0.8fr) minmax(0, 1.1fr) 3rem;
    align-items: start;
  }
  .row__thumb { max-width: none; }
}

@media (hover: hover) and (pointer: fine) {
  .rows--media .row:hover .row__thumb img { transform: scale(1.05); }
}

.on-dark .row { border-color: var(--line-dark); }
.on-dark .rows .row:last-child { border-bottom-color: var(--line-dark); }

@media (min-width: 900px) {
  .row {
    grid-template-columns: 5rem minmax(0, 0.9fr) minmax(0, 1.2fr) 3rem;
    align-items: start;
  }
}

.row__num {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  color: var(--orange-deep);
  padding-top: 0.5rem;
}

.row p {
  color: var(--ink-soft);
  font-size: 1rem;
  max-width: 54ch;
}

.on-dark .row__num { color: var(--orange-bright); }
.on-dark .row h3 { color: var(--paper); }
.on-dark .row p { color: var(--on-dark-soft); }

.row__tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }

.tag {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  padding: 0.3rem 0.75rem;
}

.on-dark .tag { color: var(--on-dark-soft); border-color: var(--line-dark); }

.row__go {
  display: grid;
  place-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  justify-self: end;
  transition: background-color var(--t-slow) var(--ease),
              border-color var(--t-slow) var(--ease),
              transform var(--t-slow) var(--ease);
}

.on-dark .row__go { border-color: var(--line-dark); }

/* ---------- Light feature rows / split ---------- */
.split { display: grid; gap: clamp(2rem, 1.5rem + 3vw, 4.5rem); align-items: center; }

@media (min-width: 960px) {
  .split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split--reverse .split__media { order: -1; }

  /* The split centres its columns, which left the picture floating 44px short of
     the list it sits beside. Anchoring it to the end of the grid row lines the
     two bottom edges up without resizing or recropping the photograph. */
  .split--media-bottom { align-items: end; }
}

.split__body { display: grid; gap: 1.5rem; align-content: start; }

/* ---------- Cards ---------- */
.cards {
  display: grid;
  gap: clamp(1.25rem, 1rem + 1vw, 2rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}

.card {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  transition: transform var(--t-slow) var(--ease);
}

.card__body { display: grid; gap: 0.75rem; }

.card__num {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  color: var(--orange-deep);
}

.card p { color: var(--ink-soft); }
.on-dark .card p { color: var(--on-dark-soft); }
.on-dark .card h3 { color: var(--paper); }
.on-dark .card__num { color: var(--orange-bright); }

/* ---------- Numbered reason list ---------- */
.reasons { display: grid; gap: 0; }

.reason {
  display: grid;
  gap: 0.5rem 2.5rem;
  padding-block: clamp(1.5rem, 1.25rem + 1.5vw, 2.25rem);
  border-top: 1px solid var(--line);
}

.reasons .reason:last-child { border-bottom: 1px solid var(--line); }

@media (min-width: 860px) {
  .reason { grid-template-columns: 4rem minmax(0, 0.8fr) minmax(0, 1.2fr); align-items: start; }

  /* The three-track layout assumes the full page width. Inside a split the list
     only gets about 600px, which left the heading track around 185px -- too
     narrow for a word like "International", so it spilled over the paragraph.
     Here the heading and the copy stack in one track instead, and the number
     keeps its own column. */
  .split__body .reason {
    grid-template-columns: 4rem minmax(0, 1fr);
    gap: 0.6rem 2.5rem;
  }

  /* :not() matters here -- the row number is a <p> too, and without it the
     number was dragged into the second column and its own track left empty. */
  .split__body .reason__num { grid-column: 1; grid-row: 1; }

  .split__body .reason h3,
  .split__body .reason p:not(.reason__num) { grid-column: 2; }
}

.reason__num {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  color: var(--orange-deep);
  padding-top: 0.375rem;
}

.reason p { color: var(--ink-soft); max-width: 56ch; }

/* ---------- Steps ---------- */
.steps {
  display: grid;
  gap: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
}

.step { padding-top: 2rem; border-top: 1px solid var(--line); }
.on-dark .step { border-color: var(--line-dark); }

.step__num {
  display: block;
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  color: var(--orange-deep);
  margin-bottom: 1rem;
}

.on-dark .step__num { color: var(--orange-bright); }
.step h3 { margin-bottom: 0.75rem; }
.step p { color: var(--ink-soft); }
.on-dark .step p { color: var(--on-dark-soft); }

/* ---------- Checklist ---------- */
.checks { display: grid; gap: 0; list-style: none; padding: 0; }

.checks li {
  display: grid;
  grid-template-columns: 1.25rem 1fr;
  gap: 1rem;
  align-items: start;
  padding-block: 0.875rem;
  border-bottom: 1px solid var(--line);
}

.on-dark .checks li { border-color: var(--line-dark); }

.checks li::before {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: 0.6rem;
  border-radius: 50%;
  background: var(--orange);
}

/* Ticked-box checklist laid out across the page. Deliberately not the .step
   component: these are guarantees, not a sequence — the home page owns the
   step-by-step and repeating it here made the process look like two processes. */
.checklist {
  display: grid;
  gap: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  list-style: none;
  padding: 0;
  margin: 0;
}

.checklist__item { padding-top: 2rem; border-top: 1px solid var(--line); }
.on-dark .checklist__item { border-color: var(--line-dark); }

.checklist__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  margin-bottom: 1rem;
  border: 1px solid currentColor;
  color: var(--orange-deep);
}

.on-dark .checklist__mark { color: var(--orange-bright); }
.checklist__item h3 { margin-bottom: 0.75rem; }
.checklist__item p { color: var(--ink-soft); }
.on-dark .checklist__item p { color: var(--on-dark-soft); }

/* ---------- CTA ---------- */
/* After a dark section the orange block butts straight against it: the dark
   band's padding reads as part of the CTA, not as air. Light sections already
   give that air through their own padding, so only the dark adjacency needs it. */
.on-dark + .cta { margin-top: var(--rhythm-tight); }

.cta {
  /* boxed rather than full-bleed, with air before the footer. On phones it keeps
     the page gutter: a proportional inset there would squeeze the copy. */
  margin-inline: var(--gutter);
  margin-bottom: var(--rhythm-tight);
  background: var(--orange);
  color: #fff;
  position: relative;
  overflow: hidden;
  /* own stacking context so the wordmark below can sit at z-index -1: above the
     orange fill, behind the copy */
  isolation: isolate;
}

/* oversized RLM bleeding off the bottom-right corner, same anchoring as v1 */
.cta::after {
  content: "RLM";
  position: absolute;
  right: -2%;
  bottom: -32%;
  z-index: -1;
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(11rem, 26vw, 24rem);
  line-height: 1;
  color: rgba(255, 255, 255, 0.09);
  pointer-events: none;
}

.cta .wrap {
  display: grid;
  gap: 2rem;
  align-items: center;
  padding-block: clamp(3.5rem, 3rem + 4vw, 6.5rem);
  /* the box already carries the outer inset, so the inner gutter is smaller —
     otherwise the two stack up and the content sits far from its own edge */
  padding-inline: clamp(1.5rem, 4vw, 3.5rem);
}

@media (min-width: 900px) {
  .cta { margin-inline: clamp(2rem, 10vw, 140px); }
}

/* The button only earns its own column once the text column can still hold the
   sentence in two lines. At 960 it squeezed the copy to ~420px, just under the
   434px two-line threshold, and the paragraph broke three ways. */
@media (min-width: 1040px) {
  .cta .wrap { grid-template-columns: minmax(0, 1fr) auto; gap: 4rem; }
}

.cta h2 { max-width: 18ch; }
/* Two lines, evenly split. At 46ch the sentence broke three ways and left a
   76px orphan on the last one. 50ch is the two-line threshold, so 52ch clears it
   with room for font fallback, and balance splits the pair evenly instead of
   leaving one long line and one short. */
.cta p {
  color: rgba(255, 255, 255, 0.86);
  max-width: 52ch;
  margin-top: 1.25rem;
  text-wrap: balance;
}

.cta .btn { background: #fff; color: var(--orange-deep); border-color: #fff; }
.cta .btn::before { background: var(--navy-deep); }

/* ---------- Forms ---------- */
.form { display: grid; gap: 1.25rem; }
.field { display: grid; gap: 0.5rem; }

.field label {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 1rem 1.125rem;
  background-color: #fff;
  color: var(--ink);
  border: 1px solid var(--line);
  transition: border-color var(--t-quick) var(--ease),
              box-shadow var(--t-quick) var(--ease);
}

.field textarea { min-height: 150px; resize: vertical; }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(226, 107, 27, 0.16);
}

.field--error input,
.field--error select,
.field--error textarea { border-color: #c0392b; }

.field__error {
  font-family: var(--label);
  font-size: 0.75rem;
  color: #c0392b;
  display: none;
}

.field--error .field__error { display: block; }

.form__grid { display: grid; gap: 1.25rem; }

@media (min-width: 680px) {
  .form__grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.form__note {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.form__status {
  display: none;
  padding: 1rem 1.25rem;
  border-left: 2px solid var(--orange);
  background: rgba(226, 107, 27, 0.08);
}

.form__status.is-visible { display: block; }

/* Contact details */
.contact-list { display: grid; }

.contact-list > div {
  padding-block: 1.25rem;
  border-top: 1px solid var(--line);
}

.contact-list > div:last-child { border-bottom: 1px solid var(--line); }

.contact-list dt {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.5rem;
}

.contact-list dd {
  font-family: var(--display);
  font-size: 1.125rem;
  text-transform: uppercase;
  line-height: 1.35;
}

.map {
  width: 100%;
  height: 340px;
  border: 1px solid var(--line);
  filter: grayscale(1);
  transition: filter var(--t-slow) var(--ease);
}

/* An address like customerservice@rlmcarriergroup.com is one unbreakable token
   432px wide. On a 375px phone the column is about 335px, so without this the
   link would push the whole page sideways -- the same horizontal overflow that
   bit the globe labels. 'anywhere' also keeps it out of min-content sizing. */
a[href^="mailto:"] { overflow-wrap: anywhere; }

/* ---------- Legal / long-form prose ----------
   The display h2 runs up to 3.75rem, which is right for a landing section and
   absurd over a paragraph of policy. Scoped here so the legal page keeps the
   family and the uppercase treatment at a size that reads as a subheading. */
.legal { max-width: 68ch; }

.legal__meta {
  font-family: var(--label-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 2.5rem;
}

.legal__lead { font-size: 1.125rem; }

.legal h2 {
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);
  line-height: 1.2;
  margin-top: 3rem;
  margin-bottom: 0.75rem;
}

.legal p {
  color: var(--ink-soft);
  margin-bottom: 1rem;
}

.legal__lead { color: var(--ink); }

.legal .checks { margin-block: 1.25rem 1.75rem; }

.legal a {
  color: var(--orange-deep);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.footer__bottom a {
  color: inherit;
  text-decoration: none;
  transition: color var(--t-base) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .footer__bottom a:hover { color: var(--paper); }
}

/* ---------- Footer ---------- */
.footer {
  background: var(--navy-ink);
  color: var(--on-dark-soft);
  padding-block: var(--rhythm-tight) 2rem;
}

.footer__top {
  display: grid;
  gap: 2.5rem;
  padding-bottom: 3rem;
  border-bottom: 1px solid var(--line-dark);
}

@media (min-width: 880px) {
  .footer__top { grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr)); gap: 3rem; }
}

.footer img { height: 60px; width: auto; margin-bottom: 1.25rem; }
.footer p { max-width: 40ch; }

.footer h4 {
  font-family: var(--label);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--orange-bright);
  margin-bottom: 1.25rem;
  text-transform: uppercase;
}

.footer ul { list-style: none; padding: 0; display: grid; gap: 0.75rem; }
.footer ul a, .footer address a { display: inline-block; transition: color var(--t-quick) linear, transform var(--t-base) var(--ease); }
.footer address { font-style: normal; line-height: 1.9; }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 2rem;
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
}

/* ---------- Reveal ---------- */
/* Progressive enhancement, same rule as the split headlines: the hidden state
   only applies once the script is running, so a JS failure can never leave a
   section permanently invisible. */
html.js-reveal .reveal {
  opacity: 0;
  transform: translateY(24px);
}

/* entrada por animation, nao por transition: assim nao sequestra a transition
   dos componentes que tambem tem estado de hover */
.reveal.in {
  animation: reveal-in 700ms var(--ease-out) var(--delay, 0ms) forwards;
}

@keyframes reveal-in {
  to { opacity: 1; transform: none; }
}

/* Word-by-word headline reveal (SplitText equivalent) */
/* Padding buys room for BBH Bogle's tall ascenders inside the clip; the matching
   negative margin keeps the line box exactly where it was. */
.split-line {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding: 0.14em 0.04em 0.1em;
  margin: -0.14em -0.04em -0.1em;
}

/* Progressive enhancement: words only hide once the script has taken over, so a
   JS failure can never leave a headline permanently invisible inside the clip. */
.split-word {
  display: inline-block;
  transition: transform 800ms var(--ease-out);
  transition-delay: var(--delay, 0ms);
}

html.js-split .split-word { transform: translateY(105%); }
html.js-split .is-revealed .split-word { transform: none; }

/* ---------- Back to top ---------- */
.totop {
  position: fixed;
  right: calc(clamp(1rem, 2vw, 2rem) + env(safe-area-inset-right));
  bottom: calc(clamp(1rem, 2vw, 2rem) + env(safe-area-inset-bottom));
  z-index: 90;
  display: grid;
  place-content: center;
  width: 48px;
  height: 48px;
  border: 0;
  background: var(--navy);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              background-color var(--t-quick) linear;
}

.totop.is-visible { opacity: 1; transform: none; pointer-events: auto; }

/* ---------- Accessibility ---------- */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--orange);
  color: #fff;
  padding: 0.875rem 1.25rem;
  font-family: var(--label);
  font-size: 0.75rem;
}

.skip:focus { left: 0; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ---------- How it works: steps on the left, a sticky image on the right ----------
   The image column pins while the steps scroll past it; the step nearest the
   middle of the screen becomes active, filling its connector and crossfading
   the matching photograph. */
.process {
  display: grid;
  gap: clamp(2.5rem, 2rem + 4vw, 5rem);
  align-items: start;
}

@media (min-width: 900px) {
  .process { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

  /* Each step owns a screenful of scroll. Without this the three short steps
     only span ~580px, which leaves the sticky image pinned for barely 180px
     before it releases — the pinning has to outlast the list, not the reverse. */
  .pstep { min-height: 46vh; }
}

.process__steps {
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 2rem + 2vw, 3.5rem);
}

.pstep {
  position: relative;
  display: flex;
  gap: clamp(1rem, 0.5rem + 1.5vw, 1.5rem);
}

/* connector running from one number down to the next */
.pstep:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 31px;
  top: 64px;
  bottom: calc(clamp(2.5rem, 2rem + 2vw, 3.5rem) * -1);
  width: 2px;
  background: var(--line);
  transition: background-color 600ms var(--ease);
}

.pstep.is-active:not(:last-child)::before { background: var(--orange); }

.pstep__num {
  flex: 0 0 auto;
  display: grid;
  place-content: center;
  width: 64px;
  height: 64px;
  background: rgba(17, 17, 17, 0.07);
  color: var(--ink-faint);
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1;
  transition: background-color 500ms var(--ease), color 500ms var(--ease);
}

.pstep.is-active .pstep__num {
  background: var(--orange);
  color: #fff;
}

.pstep__body { display: grid; gap: 0.75rem; align-content: start; padding-top: 0.5rem; }

.pstep__label {
  font-family: var(--label-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color 500ms var(--ease);
}

.pstep.is-active .pstep__label { color: var(--orange-deep); }

/* :not() keeps this off the label, whose own colour states would otherwise
   lose to this rule on specificity */
.pstep__body p:not(.pstep__label) { color: var(--ink-soft); max-width: 38ch; }

/* ---- sticky image column ---- */
.process__visual { display: none; }

@media (min-width: 900px) {
  .process__visual { display: block; height: 100%; }
}

.process__sticky {
  position: sticky;
  top: calc(var(--header-h) + 2rem);
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--navy-deep);
}

.process__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 1s cubic-bezier(0.4, 0, 0.2, 1),
              transform 1.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.process__img.is-active { opacity: 1; transform: scale(1); }

/* on phones the sticky column is dropped, so each step carries its own photo */
.pstep__media { margin-top: 1.25rem; }

@media (min-width: 900px) {
  .pstep__media { display: none; }
}

/* ---------- Two ways in: freight buyers and moving customers ---------- */
.paths { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }

@media (min-width: 900px) {
  .paths { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.path {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  background: var(--paper);
  padding: clamp(1.75rem, 1.25rem + 2vw, 3rem);
  transition: background-color var(--t-base) var(--ease);
}

.path__eyebrow {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange-deep);
}

.path p { color: var(--ink-soft); }

/* The two paths are different journeys, not two flavours of the same one, so
   they are skinned apart: the business route sits on navy, the home route stays
   on paper. Structure stays parallel — only the surface changes. */
.path--dark {
  background: var(--navy-deep);
  color: var(--paper);
}

.path--dark .path__eyebrow { color: var(--orange-bright); }
.path--dark p { color: var(--on-dark-soft); }
.path--dark .checks li { border-color: var(--line-dark); }
.path .checks { margin-top: auto; }
.path .btn-row { margin-top: 1.5rem; }

/* ---------- Two-column detail block (moving solutions) ---------- */
.cols { display: grid; gap: clamp(2rem, 1.5rem + 2vw, 4rem); }

@media (min-width: 860px) {
  .cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.col > h3 { margin-bottom: 0.5rem; }

.col__eyebrow {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange-deep);
  margin-bottom: 0.875rem;
}

.col p { color: var(--ink-soft); margin-bottom: 0.5rem; }


/* ---------- Reach globe ----------
   Adapted from the standalone prototype: same animation, re-skinned to the site
   palette and typography. The wrapper is square instead of full-viewport so it
   sits in the media column where the photograph used to be. */
#globe-wrap {
  position: relative;
  /* Square box, so its width is also its height: without the vh ceiling a phone
     held sideways gets a globe taller than the screen. */
  /* Edge to edge on a phone. The column is inset by the page gutter on each
     side, which was costing the globe about 11% of its diameter for margin it
     does not need -- nothing sits beside it at this width. Adding both gutters
     back is the whole remaining budget: past this the sphere would leave the
     screen. margin-left:50% with the translate keeps it centred whether the
     width comes from the column or from the 78vh ceiling (landscape). */
  width: min(calc(100% + var(--gutter) * 2), 78vh);
  margin-left: 50%;
  transform: translateX(-50%);
  aspect-ratio: 1 / 1;
  cursor: grab;
  /* No solid fill: a flat colour here painted a visible square against the
     section. The radials fade to transparent, so they add atmosphere without an
     edge.
     Clipped, though: the place labels are nowrap and the longest is 166px inside
     a 320px box on a phone, so one sitting near the right limb escaped the box,
     escaped the screen and widened the page. Desktop turns clipping back off,
     where the box has room to spare. */
  background:
    radial-gradient(ellipse 55% 45% at 40% 45%, rgba(226, 107, 27, 0.14), transparent 72%),
    radial-gradient(ellipse 45% 45% at 68% 78%, rgba(5, 58, 108, 0.38), transparent 72%);
  overflow: clip;
}

/* The globe grows by taking column width, not by pulling the camera in — moving
   the camera closer would crop the sphere again. It bleeds only to the right, out
   to the viewport edge, so every pixel gained moves it away from the copy rather
   than towards it. */
@media (min-width: 960px) {
  .split--globe {
    /* The heading needs 486px to stay in three lines, measured. A proportional
       track kept handing the copy far more than that as the screen grew -- 548px
       at 1440, 545px at 1920 -- and the surplus was width the globe could have
       had. Capping the track at 496px hands every pixel above the measured floor
       to the globe instead, and the 42% keeps the old proportional behaviour on
       the narrow end where there is no surplus to give. */
    grid-template-columns: clamp(440px, 20vw + 190px, 496px) minmax(0, 1fr);
    /* named because the globe has to subtract it to work out how far left it may
       reach before it is 60px from the copy */
    --col-gap: clamp(3rem, 2rem + 4vw, 6rem);
    gap: var(--col-gap);
  }

  /* flex-end rather than a margin: when the globe is wider than its column the
     overflow then goes left, into the gutter between the columns, instead of off
     the right edge of the window. An auto margin cannot go negative, so it would
     have pushed the globe off-screen the moment it outgrew the column. */
  .split--globe .split__media {
    display: flex;
    justify-content: flex-end;
  }

  #globe-wrap {
    /* Three limits, smallest wins.
       1. Left: the globe may cross the column gutter and stop 60px from the copy.
       2. Right: past 1440px the page keeps an outer margin either side of the
          wrap; that space was empty, so the globe runs out into it. The -1rem
          keeps the scrollbar out of the sum.
       3. The window: the box is square, so its width is also its height. A full
          100vh + 5rem lets the globe stand a little taller than the screen: it
          passes under the fixed header, which is blurred and translucent once
          stuck, and the overflow is split between that band and the fold. On a
          short laptop window this ceiling was what held the globe back, and it
          is why the same page showed a bigger globe at 90% browser zoom.
       4. A hard 900px. Without it a 24in screen gave the globe half again as
          much as a laptop did, and the section read as a different design on
          each machine. */
    overflow: visible;
    transform: none;
    --bleed: calc(var(--gutter) + max(0px, (100vw - var(--maxw)) / 2 - 1rem));
    flex: 0 0 auto;
    width: min(
      calc(100% + var(--bleed) + var(--col-gap) - 60px),
      calc(100vh + 5rem),
      900px
    );
    margin-left: 0;
    margin-right: calc(var(--bleed) * -1);
  }
}

/* On a phone the globe leads and the copy follows: stacked, a column of text
   ending in a picture buries the one thing that earns attention in this section.
   Only below the two-column breakpoint -- on desktop the order is horizontal. */
@media (max-width: 959.98px) {
  .split--globe .split__media,
  .split--media-bottom .split__media { order: -1; }

  .split--globe .split__body,
  .split--media-bottom .split__body { order: 0; }
}

/* Why this heading is sized apart from every other h2: it is the only one with a
   globe competing for the same row. The globe's width is whatever the copy does
   not take, so on a laptop the heading's own size decides how big the globe can
   be. Easing the vw coefficient lets the text column drop from 484px to ~446px
   at 1280 while the heading holds its three lines. Both clamps top out at
   3.75rem, so from about 1540px up this is the site-wide size, unchanged.
   To revert: delete this rule. */
.split--globe h2 { font-size: clamp(2rem, 1.25rem + 2.6vw, 3.75rem); }

#globe-wrap:active { cursor: grabbing; }

#globe-wrap canvas { position: absolute; inset: 0; display: block; }
#globe-wrap #leaders { pointer-events: none; }
#globe-wrap #labels { position: absolute; inset: 0; pointer-events: none; }

.lbl {
  position: absolute;
  left: 0;
  top: 0;
  padding: 5px 8px 4px;
  font-family: var(--label-mono);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper);
  background: rgba(1, 24, 44, 0.92);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.35s ease;
  will-change: transform, opacity;
}

.lbl.show { opacity: 1; }

.lbl.hub {
  background: var(--orange);
  color: #fff;
  padding: 6px 10px 5px;
}

.lbl.region {
  background: none;
  color: rgba(255, 255, 255, 0.5);
  letter-spacing: 0.24em;
  font-weight: 400;
}

.lbl small {
  display: block;
  font-weight: 400;
  font-size: 0.625rem;
  opacity: 0.7;
  margin-top: 3px;
  letter-spacing: 0.06em;
}

@media (max-width: 640px) {
  .lbl { font-size: 0.625rem; padding: 4px 6px 3px; }
  .lbl small { display: none; }
  /* The two region captions are scene-setting, not routes, and on a 350px globe
     'Southern Ontario' ran straight through the Mississauga and US Northeast
     pins. The hub and the lanes carry the meaning; these two are the ones to
     drop when there is no room. */
  .lbl.region { display: none; }
}

/* sem WebGL ou com movimento reduzido, o bloco continua sendo um painel legivel */
@media (prefers-reduced-motion: reduce) {
  #globe-wrap { display: grid; place-content: center; }
}

/* ---------- Hover ----------
   Gated so a first tap on touch does not land on a hover state instead of the
   action. Kept near the end of the sheet so these win on equal specificity. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 28px -12px rgba(190, 81, 22, 0.75);
  }

  .btn:hover::before { transform: scaleX(1); }
  .btn:hover .arrow { transform: translateX(5px); }

  .btn--ghost:hover { border-color: var(--ink); color: #fff; box-shadow: none; }

  .on-dark .btn--ghost:hover,
  .hero .btn--ghost:hover,
  .banner .btn--ghost:hover { border-color: var(--paper); color: var(--navy-deep); box-shadow: none; }

  .cta .btn:hover { color: #fff; box-shadow: 0 14px 30px -14px rgba(1, 24, 44, 0.6); }

  .nav a:hover { color: var(--orange-deep); }
  .header:not(.is-stuck) .nav a:hover,
  .header:not(.is-stuck) .header__phone:hover { color: var(--orange-bright); }
  .nav a:hover::after { transform: scaleX(1); transform-origin: left; }

  .header__phone:hover { color: var(--orange-deep); }

  .drawer a:hover { color: var(--orange-bright); transform: translateX(0.6rem); }

  .link:hover { background-size: 100% 1px; }
  .link:hover .arrow { transform: translateX(4px); }

  .ticker:hover .ticker__track { animation-play-state: paused; }

  .media-hover:hover .media img,
  .card:hover .media img { transform: scale(1.05); }

  .framed:hover::before { top: 8px; left: 8px; }
  .framed:hover::after { bottom: 8px; right: 8px; }

  .path:hover { background: var(--panel); }
  .path--dark:hover { background: var(--navy); }

  .row:hover { background-color: rgba(17, 17, 17, 0.035); }
  .on-dark .row:hover { background-color: rgba(255, 255, 255, 0.045); }

  .row:hover .row__num,
  .row:hover h3,
  .row:hover p { transform: translateX(10px); }

  .row:hover .row__go {
    background: var(--orange);
    border-color: var(--orange);
    transform: translateX(6px);
  }

  .footer ul a:hover,
  .footer address a:hover { color: var(--orange-bright); transform: translateX(0.35rem); }

  .map:hover { filter: grayscale(0); }

  .totop:hover { background: var(--orange); }

  .field input:hover,
  .field select:hover,
  .field textarea:hover { border-color: rgba(17, 17, 17, 0.4); }
}

/* press feedback stays outside the hover gate — it must work on touch */
.btn:active { transform: translateY(0); transition-duration: var(--t-quick); }

@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;
  }

  .reveal { opacity: 1; transform: none; }
  .process__img { transition: none; transform: none; }
  .split-word { transform: none; }
  .hero::before { display: none; }
  .hero__video { display: none; }
  .ticker__track { animation: none; }
}
