/* variyasinc.com. Colours are taken from the Variyas logo. System fonts only:
   no third-party requests, which the Content-Security-Policy also forbids.

   Every colour is a variable so dark mode (prefers-color-scheme) is one block.
   Each text/background pair below was checked against WCAG AA (4.5:1 for body
   text) in both schemes; tests/contrast.test.js recomputes them from this
   file. Motion is progressive: with JavaScript off nothing is hidden, and
   prefers-reduced-motion switches every animation off at the bottom of the file. */
:root {
  color-scheme: light dark;
  --blue: #036e9c;
  --blue-dark: #024e70;
  --cyan: #06b2e2;
  --ink: #16242c;
  --ink-2: #44545d;
  --muted: #5d6d76;
  --line: #dde5ea;
  --bg: #ffffff;
  --surface: #ffffff;
  --tint: #f2f7fa;
  --link: var(--blue);
  --link-hover: var(--blue-dark);
  --btn-bg: var(--blue);
  --btn-ink: #ffffff;
  --btn-bg-hover: var(--blue-dark);
  --header-bg: rgba(255, 255, 255, .92);
  --logo-bg: transparent;
  --callout-bg: var(--tint);
  --callout-line: #cfe2ec;
  --tick-ring: #d6f2fb;
  --tile: #ffffff;
  /* Light mode: a hairline and a soft shadow make the tile a deliberate
     rounded plate; without them the renders' #fefefe showed as a faint grey
     square on white and tinted bands (design review, 1 Oct 2026). */
  --tile-shadow: 0 0 0 1px var(--line), 0 4px 12px rgba(3, 110, 156, .08);
  --shadow: 0 10px 28px rgba(3, 110, 156, .12);
  --glow: 0 18px 44px rgba(3, 110, 156, .18), 0 0 0 1px var(--cyan), 0 0 30px rgba(6, 178, 226, .22);
  --field: #ffffff;
  /* 3.61:1 on white and 3.34:1 on the tint; a field border must reach 3:1 against
     what it sits on. #9fb3be was 2.17:1, a form of near-invisible boxes. */
  --field-line: #758a94;
  --ok: #0f7a3e;
  --bad: #b3261e;
  /* Keyboard focus ring. Not the brand cyan in light mode: that is 2.5:1 on
     white, below the 3:1 a focus indicator needs. The hero and the footer set
     their own (see there). */
  --focus: var(--blue);
  --radius: 12px;
  --wrap: 1120px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e7eff3;
    --ink-2: #bccbd3;
    --muted: #9aadb7;
    --line: #23404c;
    --bg: #0b171d;
    --surface: #11222a;
    --tint: #0e1d24;
    --link: #62ccf0;
    --link-hover: #a3e2f7;
    --btn-bg: #3cc2ea;
    --btn-ink: #04202b;
    --btn-bg-hover: #86daf3;
    --header-bg: rgba(11, 23, 29, .92);
    /* The dark header gets a light-on-dark logo (picture/source in the header), so no plate:
       a white box behind the blue logo looked pasted on (Vijay, 30 Sep 2026). */
    --logo-bg: transparent;
    --callout-bg: #10252e;
    --callout-line: #1f4452;
    --tick-ring: #0f3a48;
    /* The 3D icons are rendered on pure white, so in dark mode they sit on a
       light tile rather than showing as stark white squares. */
    --tile: #f4f8fa;
    --tile-shadow: 0 6px 18px rgba(0, 0, 0, .35);
    --shadow: 0 10px 30px rgba(0, 0, 0, .45);
    --glow: 0 18px 44px rgba(0, 0, 0, .5), 0 0 0 1px var(--cyan), 0 0 30px rgba(6, 178, 226, .25);
    --field: #0b171d;
    /* #4d6c7a passed on the field (3.24:1) but not on the form panel
       around it (2.91:1); this is 3.36:1 on --surface. */
    --field-line: #567684;
    --ok: #6fdc9b;
    --bad: #ff9d94;
    --focus: var(--cyan);
  }
}
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; font-family: var(--font); font-size: 17px; line-height: 1.6; color: var(--ink); background: var(--bg); overflow-wrap: break-word;
  /* Short pages (thank-you, 404) keep the footer at the bottom of the window
     instead of leaving a white strip under it. */
  min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
body > main { flex: 1 0 auto; }
/* A phone number never breaks at its hyphens ("1-" on one line, the rest on the next). */
a[href^="tel:"] { white-space: nowrap; }
img { max-width: 100%; height: auto; }
a { color: var(--link); text-underline-offset: 3px; }
a:hover { color: var(--link-hover); }
/* The outline follows each element's own radius, so pill buttons stay pills
   and cards keep their corners when focused. */
a:focus-visible, summary:focus-visible, button:focus-visible, canvas:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
h1, h2, h3 { line-height: 1.2; margin: 0 0 .5em; color: var(--ink); }
h1 { font-size: clamp(2rem, 4.5vw, 3rem); letter-spacing: -.01em; }
h2, .h2 { font-size: clamp(1.5rem, 3vw, 2rem); }
h3, .h3 { font-size: 1.2rem; }
p { margin: 0 0 1em; }
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }
.narrow { max-width: 760px; }
.skip { position: absolute; left: -9999px; }
.skip:focus { left: 16px; top: 16px; z-index: 10; background: var(--surface); padding: 8px 12px; }
.muted { color: var(--muted); }
.vh { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Header */
.top { position: sticky; top: 0; z-index: 5; background: var(--header-bg); border-bottom: 1px solid var(--line); -webkit-backdrop-filter: saturate(1.4) blur(8px); backdrop-filter: saturate(1.4) blur(8px); }
.top__row { display: flex; align-items: center; justify-content: space-between; min-height: 72px; gap: 16px; }
.brand { display: block; background: var(--logo-bg); border-radius: 10px; padding: 4px 6px; }
.brand img { display: block; width: 160px; }
.nav ul, .menu ul { list-style: none; margin: 0; padding: 0; }
.nav ul { display: flex; gap: 8px; }
.nav a, .menu a, .nav .subnav__toggle { display: block; padding: 10px 14px; border-radius: 8px; color: var(--ink); text-decoration: none; font-weight: 600; }
.nav a:hover, .menu a:hover, .nav .subnav__toggle:hover { background: var(--tint); color: var(--link); }
.nav a[aria-current="page"], .menu a[aria-current="page"] { color: var(--link); box-shadow: inset 0 -3px 0 var(--cyan); }
.menu { display: none; position: relative; }
.menu > summary { list-style: none; cursor: pointer; width: 48px; height: 48px; display: grid; place-content: center; gap: 5px; border-radius: 8px; }
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary span { display: block; width: 24px; height: 2px; background: var(--ink); }
.menu ul { position: absolute; right: 0; top: 56px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 8px; min-width: 200px; box-shadow: 0 12px 30px rgba(0,0,0,.18); }
/* The two doors: Hire talent / Find a job, a highlighted pair after the links. */
.nav .door a, .menu .door a { white-space: nowrap; border: 2px solid var(--btn-bg); color: var(--link); padding: 8px 14px; border-radius: 999px; }
.nav .door:last-child a, .menu .door:last-child a { background: var(--btn-bg); color: var(--btn-ink); }
.nav .door a:hover, .menu .door a:hover { background: var(--btn-bg-hover); border-color: var(--btn-bg-hover); color: var(--btn-ink); }
.nav .door a[aria-current="page"] { box-shadow: 0 0 0 3px var(--tick-ring); }
.nav .door:first-of-type { margin-left: 8px; }
.menu .door { margin-top: 6px; }
@media (max-width: 920px) { .nav { display: none; } .menu { display: block; } .brand img { width: 128px; } }

/* Hero. Three layers, all CSS: the brand gradient (slowly shifting), a soft
   moving light, and the 3D art. The art is an <img> the build only emits when
   hero.jpg exists, so a missing file leaves the gradient and nothing broken.
   Desktop: full-bleed behind the text, weighted right. Phones: below the text. */
.hero { --focus: #ffffff; position: relative; overflow: hidden; isolation: isolate; color: #fff;
  background: linear-gradient(120deg, #01344d, var(--blue-dark) 35%, var(--blue) 70%, #0891c4);
  background-size: 180% 180%; animation: hero-shift 26s ease-in-out infinite alternate; }
.hero__light { position: absolute; z-index: -1; width: 70vmax; height: 70vmax; left: -20vmax; top: -35vmax; border-radius: 50%;
  background: radial-gradient(circle, rgba(6, 178, 226, .38), rgba(6, 178, 226, 0) 62%);
  animation: hero-light 19s ease-in-out infinite alternate; pointer-events: none; }
.hero__inner { position: relative; padding: clamp(56px, 9vw, 116px) 20px; max-width: var(--wrap); margin: 0 auto; }
.hero h1 { max-width: 640px; color: #fff; }
.hero__sub { margin: 0 0 8px; color: #fff; font-size: 1.3rem; font-weight: 600; max-width: 580px; }
.hero__proof { margin: 16px 0 0; font-size: .88rem; color: #bcd9e6; }
.hero .lead { color: #dff3fb; font-size: 1.2rem; max-width: 580px; }
/* 861-1100: the picture reaches left under the text column, so the lead stays in the navy (15 Oct 2026). */
@media (min-width: 861px) and (max-width: 1100px) {
  .hero .lead { max-width: 400px; }
}
.hero__art img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: right center; }
@media (min-width: 861px) {
  .hero__art { position: absolute; inset: 0; z-index: -2; }
  /* Keeps white text at AA over the art: solid brand navy under the text column,
     fading out before the network graphic. */
  .hero__art::after { content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, rgba(1, 45, 66, .94) 0%, rgba(1, 52, 77, .82) 36%, rgba(2, 58, 85, .25) 62%, rgba(2, 58, 85, 0) 78%); }
}
@media (max-width: 860px) {
  .hero__inner { padding-bottom: 28px; }
  .hero__art { margin: 0 auto; max-width: var(--wrap); padding: 0 20px 40px; }
  .hero__art img { aspect-ratio: 16 / 9; height: auto; object-position: 85% center; border-radius: 16px;
    box-shadow: 0 18px 40px rgba(0, 0, 0, .3); }
}
@keyframes hero-shift { from { background-position: 0% 40%; } to { background-position: 100% 60%; } }
@keyframes hero-light { from { transform: translate(0, 0); } to { transform: translate(28vmax, 18vmax); } }
/* Hero motion (15 Oct 2026), all CSS. The picture, its glow dots and its
   connector lines share one frame cut to the picture's own 1600 x 895 shape and
   pinned right, which is what object-fit: cover did, so the dots stay on the
   people icons at any width. The frame floats; the pointer nudges it through
   the separate "translate" property, so the two never fight over transform. */
.hero__frame { position: relative; }
.hero__frame img { display: block; width: 100%; height: auto; }
.hero__net { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.hero__link { stroke: #7fe3ff; stroke-width: 2; stroke-linecap: round; stroke-dasharray: 10 14; opacity: .55;
  animation: hero-flow 3.2s linear infinite; }
.hero__dot { fill: #bff3ff; filter: drop-shadow(0 0 6px #06b2e2); animation: hero-pulse 3.6s ease-in-out infinite; }
.hero__dot--core { animation-duration: 4.4s; }
.hero__ring { fill: none; stroke: #7fe3ff; stroke-width: 2; transform-box: fill-box; transform-origin: center; opacity: 0;
  animation: hero-ring 3.6s ease-out infinite; }
.hero__node:nth-of-type(2) .hero__ring, .hero__node:nth-of-type(2) .hero__dot, .hero__link:nth-of-type(2) { animation-delay: .9s; }
.hero__node:nth-of-type(3) .hero__ring, .hero__node:nth-of-type(3) .hero__dot, .hero__link:nth-of-type(3) { animation-delay: 1.8s; }
.hero__node:nth-of-type(4) .hero__ring, .hero__node:nth-of-type(4) .hero__dot, .hero__link:nth-of-type(4) { animation-delay: 2.7s; }
.hero__glow { position: absolute; z-index: 0; width: 60vmax; height: 60vmax; right: -12vmax; top: 50%; margin-top: -30vmax; border-radius: 50%;
  background: radial-gradient(circle, rgba(6, 178, 226, .30), rgba(6, 178, 226, 0) 60%); pointer-events: none;
  animation: hero-glow 11s ease-in-out infinite alternate; }
.hero__frame { z-index: 1; animation: hero-float 7s ease-in-out infinite alternate; }
@media (min-width: 861px) {
  .hero__frame { position: absolute; right: 0; top: 50%; width: max(100cqw, 100cqh * 1.788); translate: var(--px, 0px) calc(-50% + var(--py, 0px)); }
  /* The ease is switched on by the first pointer move, never at load: a transition
     from "none" to the centring offset made the picture start (and in a headless
     screenshot, stay) half a screen low. */
  .hero__frame.is-live { transition: translate .5s ease-out; }
  .hero__art { container-type: size; }
}
/* 861-1100: the picture is pushed off the right edge so its big cube sits clear of the headline and subhead,
   which ran 20-600px at 1024 straight over it. The outer cards are cropped; the cube and two cards stay. */
@media (min-width: 861px) and (max-width: 1100px) { .hero__frame { right: -200px; } }
@media (max-width: 860px) { .hero__frame img { border-radius: 16px; box-shadow: 0 18px 40px rgba(0, 0, 0, .3); } .hero__glow { right: -30vmax; } }
@keyframes hero-float { from { transform: translateY(0); } to { transform: translateY(-9px); } }
@keyframes hero-glow { from { opacity: .55; transform: scale(.9); } to { opacity: 1; transform: scale(1.1); } }
@keyframes hero-flow { to { stroke-dashoffset: -48; } }
@keyframes hero-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes hero-ring { 0% { opacity: .7; transform: scale(.4); } 70%, 100% { opacity: 0; transform: scale(1.5); } }

/* The rotating phrase. Every phrase sits in one grid cell, so the line is as
   tall and wide as the longest and nothing shifts when they swap. Gradient is
   the site's own cyan to a pale teal; the plain colour under it is what shows
   in forced-colors and if background-clip is unsupported. */
.hero.is-paused, .hero.is-paused *, .hero.is-paused *::before, .hero.is-paused *::after { animation-play-state: paused !important; }
/* A round icon over the picture, bottom-right of the hero. It was a text link under the buttons; on a phone that
   pushed the buttons down. The fixed "Ask our AI assistant" button owns the viewport's bottom-right 16px + ~48px,
   so this sits 80px up to stay clear of it when the hero's foot is on screen. On a phone there is no picture beside the text, so it takes the empty bottom-right corner,
   beside the last row of buttons and never over them or the words. */
.hero__pause { position: absolute; z-index: 3; right: 16px; bottom: 80px; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: rgba(1, 30, 45, .6); color: #fff; cursor: pointer; }
.hero__pause svg { width: 22px; height: 22px; fill: currentColor; }
.hero__pause:hover { background: rgba(1, 30, 45, .85); }
@media (max-width: 860px) { .hero__pause { right: 12px; bottom: 56px; } }
/* "for your" flows with the headline; the phrase always takes its own single
   line beneath, a little smaller so the longest ("fleet and logistics
   operations") fits that line at every width. One fixed line means no gap under
   a short phrase and no shift when the phrase changes. 6.6vw is what keeps it
   inside a 320-390px phone; .94em is what keeps it inside the 640px column. */
.rotor { display: grid; font-size: min(.94em, 6.6vw); white-space: nowrap; }
.rotor__word { grid-area: 1 / 1; color: #7fe3ff; opacity: 0; transform: translateY(.35em); visibility: hidden;
  transition: opacity .5s, transform .5s, visibility 0s .5s; }
.rotor__word.is-on { opacity: 1; transform: none; visibility: visible; transition-delay: 0s; }
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .rotor__word { background: linear-gradient(90deg, #5fd8f5, #06b2e2 45%, #7ff0d8); background-size: 200% 100%;
    -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
    animation: rotor-shift 6s linear infinite alternate; }
}
@media (forced-colors: active) { .rotor__word { -webkit-text-fill-color: currentColor; background: none; } }
@keyframes rotor-shift { to { background-position: 100% 0; } }

/* Non-IT landing hero (16 Oct 2026): the same dark hero, rotating line and pause
   button as Home, with the seven industry icons as the picture. Text left, icon
   cluster right; on a phone the cluster drops below the text. The icons are
   decorative and aria-hidden; the industry cards below are the links. */
.hero--nonit .hero__inner { display: grid; gap: 32px 48px; align-items: center; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
.hero--nonit .hero__for { margin: 0 0 1em; font-size: clamp(1.25rem, 2.6vw, 1.7rem); font-weight: 700; line-height: 1.25; color: #fff; }
.hero--nonit .rotor { margin-top: .1em; }
/* Eight columns, each tile two wide: the second row starts one column in, so the
   seven icons sit as a staggered 4 + 3 and not a grid with a hole in it. */
.hero__tiles { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: clamp(10px, 1.6vw, 18px); max-width: 520px; width: 100%; justify-self: center; }
.hero__tiles .tile { grid-column: span 2; width: 100%; height: auto; aspect-ratio: 1; margin: 0; border-radius: 22px; box-shadow: 0 14px 30px rgba(0, 0, 0, .28);
  animation: hero-float 6s ease-in-out infinite alternate; }
.hero__tiles .tile:nth-child(5) { grid-column: 2 / span 2; }
.hero__tiles .tile:nth-child(even) { animation-delay: -2.2s; animation-duration: 7.4s; }
.hero__tiles .tile:nth-child(3n) { animation-delay: -4s; }
@media (max-width: 860px) {
  .hero--nonit .hero__inner { grid-template-columns: minmax(0, 1fr); padding-bottom: 76px; }
  .hero--nonit .hero__pause { right: 20px; bottom: 16px; }
  .hero__tiles { max-width: 360px; justify-self: start; }
  .hero__tiles .tile { border-radius: 16px; }
}
/* Industry cards: pills sit right under the blurb, "See roles" rides the bottom, so
   cards in a row line up whatever their pill count. Three across, the last row
   filled by the "Another industry?" card spanning two. */
.card.card--ind p { flex: none; }
.card.card--ind .chips { flex: 1; align-content: flex-start; }
.grid--ind { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--ind .card--talk { grid-column: span 2; }
@media (max-width: 62em) { .grid--ind { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid--ind .card--talk { grid-column: auto; } }
@media (max-width: 40em) { .grid--ind { grid-template-columns: minmax(0, 1fr); } .grid--ind .card--talk { grid-column: auto; } }
.grid--ind .card.card--talk { justify-content: center; }
.grid--ind .card.card--talk p { flex: none; }
.slides-band--nonit .carousel__bar button { flex: none; }
@media (max-width: 30em) { .slides-band--nonit .carousel__bar { gap: 2px; padding: 10px 8px; } }
@media (max-width: 40em) { .card--ind { padding: 20px; } .card--ind .tile { width: 64px; height: 64px; border-radius: 16px; margin-bottom: 12px; } }
.slides-band--nonit { padding-bottom: clamp(28px, 4vw, 48px); }
.faqs { max-width: 820px; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0 0 16px; padding: 0; }
.chips li { padding: 4px 10px; border-radius: 999px; background: var(--tint); border: 1px solid var(--line); color: var(--ink-2); font-size: .85rem; line-height: 1.3; }
.chips .chips__more { background: none; border-style: dashed; }

/* Service pages: a slideshow under the page head. Slide 1 only without
   JavaScript; the rest sit in the same grid cell, hidden. */
.slides-band { padding: clamp(20px, 3vw, 32px) 0 0; }
.carousel__view { display: grid; background: #02405f; border-radius: 16px; overflow: hidden; }
.slide { grid-area: 1 / 1; display: flex; align-items: center; gap: clamp(16px, 4vw, 40px); min-height: 240px; padding: clamp(18px, 3vw, 32px) clamp(18px, 3vw, 32px) 68px;
  color: #fff; background: linear-gradient(120deg, #01344d, var(--blue-dark) 45%, var(--blue)); visibility: hidden; opacity: 0; transition: opacity .3s, visibility 0s .3s; }
.slide:first-child { visibility: visible; opacity: 1; }
.is-ready .slide:first-child:not(.is-on) { visibility: hidden; opacity: 0; }
.slide.is-on { visibility: visible; opacity: 1; transition: opacity .45s .3s, visibility 0s; } /* outgoing fades first, so two lines never overprint */
.slide--2 { background: linear-gradient(120deg, #01344d, #035a80 50%, #0891c4); }
.slide--3 { background: linear-gradient(240deg, #01344d, var(--blue-dark) 50%, #0a7ea8); }
.slide--4 { background: linear-gradient(160deg, #02283a, #036e9c 70%, #06b2e2); }
.slide__img { flex: none; width: clamp(96px, 16vw, 168px); height: auto; border-radius: 18px; box-shadow: 0 12px 30px rgba(0, 0, 0, .35); }
.slide__line { margin: 0; font-size: clamp(1.15rem, 2.6vw, 1.7rem); font-weight: 700; line-height: 1.3; max-width: 30ch; }
.carousel { --focus: #ffffff; position: relative; }
.carousel__bar { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: 6px; padding: 10px 14px; }
.carousel__bar button { width: 44px; height: 44px; border: 0; border-radius: 50%; background: rgba(1, 36, 54, .65); color: #fff; font: inherit; font-size: 1.1rem; line-height: 1; cursor: pointer; }
.carousel__bar button:hover { background: rgba(1, 36, 54, .9); }
.carousel__dots { display: flex; margin-left: auto; }
.carousel__dots button { background: none; position: relative; }
.carousel__dots button::after { content: ""; position: absolute; left: 50%; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; border: 2px solid #fff; }
.carousel__dots button[aria-current="true"]::after { background: #fff; }
.carousel__dots button:hover { background: none; }

/* Scroll reveal also covers section headings and stats (class .reveal in the
   build); the helper below is the same rise, a little longer for headings. */
h2.reveal.is-in, h3.reveal.is-in { animation-duration: .8s; }

/* Small bold text, so 4.5:1. In the hero no colour alone reaches that: on a
   phone the gradient and the moving light go as light as rgb(4, 127, 170)
   under it, where #9fe3f7 was 3.20:1 (2 Oct 2026). So it sits on its own navy
   plate, 6.39:1 even over the brand cyan, and is paler than before (4.73:1 on
   the brand blue without the plate). */
.eyebrow { text-transform: uppercase; letter-spacing: .12em; font-size: .8rem; font-weight: 700; color: #ccf1fc; }
.hero .eyebrow { display: inline-block; padding: 4px 12px; border-radius: 10px; background: rgba(1, 52, 77, .7); }
.eyebrow--ink { color: var(--link); }
.pagehead { background: var(--tint); border-bottom: 1px solid var(--line); padding: clamp(40px, 6vw, 72px) 0 clamp(28px, 4vw, 44px); }
.pagehead__row { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.lead { font-size: 1.15rem; color: var(--ink-2); max-width: 760px; }
.crumbs ol { list-style: none; margin: 0 0 .6em; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 0; font-weight: 600; font-size: .95rem; }
.crumbs li + li::before { content: "\203A"; margin: 0 8px; color: var(--muted); }
.crumbs a { text-decoration: none; display: inline-block; padding: 12px 0; margin: -12px 0; }
.crumbs [aria-current] { color: var(--muted); }
.jobfacts { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 24px; color: var(--ink-2); }
.jobfacts strong { color: var(--ink); }

/* Buttons */
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.actions--center { justify-content: center; }
.btn { display: inline-block; background: var(--btn-bg); color: var(--btn-ink); padding: 12px 22px; border-radius: 999px; font: inherit; font-weight: 700; text-decoration: none; border: 2px solid var(--btn-bg); overflow-wrap: anywhere; cursor: pointer; transition: background-color .15s, border-color .15s, transform .15s; }
.btn:hover { background: var(--btn-bg-hover); border-color: var(--btn-bg-hover); color: var(--btn-ink); }
.btn:disabled { opacity: .6; cursor: progress; }
.btn--outline { background: transparent; color: var(--link); border-color: var(--link); }
.btn--outline:hover { background: var(--tint); color: var(--link-hover); border-color: var(--link-hover); }
.hero .btn { background: #fff; color: var(--blue-dark); border-color: #fff; }
.hero .btn:hover { background: #dff3fb; border-color: #dff3fb; color: var(--blue-dark); }
/* Was ".hero .btn--ghost, .btn--ghost": white text on a transparent button,
   unreadable anywhere but the hero. Scoped to the hero, where it is used. */
.hero .btn--ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.75); }
.hero .btn--ghost:hover { background: rgba(255,255,255,.12); color: #fff; }

/* Sections */
.band { padding: clamp(48px, 7vw, 84px) 0; }
.band--tint { background: var(--tint); }
/* Two tinted bands in a row read as one; without this they also stacked two
   full paddings (about 170px of empty tint on Home and Non-IT Recruiting). */
.band--tint + .band--tint { padding-top: 0; }
.sub { color: var(--ink-2); margin-top: -.2em; margin-bottom: 28px; }
.grid { display: grid; gap: 20px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); margin: 0 0 20px; padding: 0; list-style: none; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); }
/* Nine technology cards (eight services and "Something else?") fill three
   rows of three. Auto-fill went four across at 1440 and two at 768, leaving
   the ninth alone on its row; one column on phones, never two (1 Oct 2026). */
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 720px) { .grid--3 { grid-template-columns: minmax(0, 1fr); } }
.card--talk { border-style: dashed; }
.split { display: grid; gap: clamp(28px, 5vw, 64px); grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); align-items: start; }
.stack { display: grid; gap: 20px; }
.band__next { margin-top: clamp(36px, 5vw, 56px); }
.ticks--roles { columns: 2 280px; column-gap: 40px; }
.ticks--roles li { break-inside: avoid; }
/* Careers: on wide screens the short intro stays beside the long list of
   notices; on phones the notices come first, since they are why people came. */
@media (min-width: 861px) { .split--jobs > :first-child { position: sticky; top: 104px; } }
@media (max-width: 860px) { .split--jobs > :last-child { order: -1; } }
@media (max-width: 860px) { .split { grid-template-columns: minmax(0, 1fr); } }

/* 3D icon tiles: a light rounded plate in both modes (see --tile and
   --tile-shadow). */
.tile { display: grid; place-items: center; width: 84px; height: 84px; margin-bottom: 16px; border-radius: 20px; overflow: hidden; background: var(--tile); box-shadow: var(--tile-shadow); flex: none; }
.tile img { display: block; width: 100%; height: 100%; transition: transform .35s cubic-bezier(.2, .7, .2, 1); }
.tile--lg { width: 104px; height: 104px; border-radius: 24px; }
.tile--head { width: 132px; height: 132px; border-radius: 28px; margin: 0; }
@media (max-width: 600px) { .tile--head { display: none; } }

.card { display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; text-decoration: none; color: var(--ink);
  transition: border-color .25s, box-shadow .25s, transform .35s cubic-bezier(.2, .7, .2, 1); }
/* A lift, not a tilt: the 3D rotation read as a gimmick next to the calm hero. */
a.card:hover, a.card:focus-visible { border-color: var(--cyan); box-shadow: var(--glow); transform: translateY(-4px); color: var(--ink); }
a.card:hover .tile img, a.card:focus-visible .tile img { transform: scale(1.07) translateY(-2px); }
a.card:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.card h3 { color: var(--link); }
.card p { color: var(--ink-2); flex: 1; }
.card__more { font-weight: 700; color: var(--link); }
.card__more::after { content: " \2192"; }
.card--static h3 { color: var(--ink); }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px 24px; margin-bottom: 16px; }
.callout { background: var(--callout-bg); border: 1px solid var(--callout-line); border-left: 5px solid var(--cyan); border-radius: var(--radius); padding: 26px; }
.callout > :last-child, .panel > :last-child, .card--static > :last-child { margin-bottom: 0; }
.band--tint .callout { background: var(--surface); }
.cta { text-align: center; }
.cta h2 { margin-bottom: .8em; }

/* IT Recruiting and Non-IT Recruiting, side by side with equal weight */
.pillars { display: grid; gap: 24px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); }
.pillar { display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--line); border-radius: 18px; padding: clamp(22px, 3vw, 34px); box-shadow: var(--shadow); }
.pillar .ticks { flex: 1; margin-bottom: 20px; }
.pillar__lead { color: var(--ink-2); font-size: 1.05rem; }
.pillar p:last-child { margin: 0; }

/* Count-up stats */
.stats { background: var(--surface); border-bottom: 1px solid var(--line); padding: clamp(28px, 4vw, 44px) 0; }
.stats__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px 32px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
.stat { display: flex; flex-direction: column; gap: 4px; }
.stat__figure { font-size: clamp(2rem, 4.4vw, 2.8rem); font-weight: 800; line-height: 1.1; color: var(--link); letter-spacing: -.01em; }
.stat__num { font-variant-numeric: tabular-nums; }
/* Word facts sit beside the count-up; set them to the size of "Since" + year so the row reads as one line of type. */
.stat__figure--text { font-size: clamp(1.45rem, 3vw, 1.9rem); padding-top: .25em; }
.stat__word { font-size: .55em; font-weight: 700; color: var(--ink); letter-spacing: 0; }
.stat__label { color: var(--muted); font-size: .95rem; }

/* Case studies, partners, leaders: rendered only when build.py has entries */
.case { margin: 0; background: var(--surface); border: 1px solid var(--line); border-left: 5px solid var(--cyan); border-radius: var(--radius); padding: 22px 24px; }
.case__sector { font-weight: 800; text-transform: uppercase; letter-spacing: .1em; font-size: .8rem; color: var(--link); margin-bottom: 8px; }
.case p { color: var(--ink-2); margin: 0; }
.partners { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 16px; }
.partner { display: grid; place-items: center; min-height: 84px; padding: 12px 20px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius); }
.partner img { max-height: 60px; width: auto; }
.partner--text { color: #16242c; font-weight: 700; }
.leader { text-align: center; }
.leader__photo { width: 120px; height: 120px; border-radius: 50%; object-fit: cover; margin: 0 auto 12px; display: block; }

/* How we work */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); counter-reset: step; }
.step { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px 24px 20px 24px; counter-increment: step; }
.step::before { content: counter(step); display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 14px; border-radius: 50%; background: var(--btn-bg); color: var(--btn-ink); font-weight: 800; }
.step p { color: var(--ink-2); margin: 0; }

/* Office globe. The flat map is the default; globe.js adds .globe--live only
   once the WebGL globe has drawn, and never when motion is reduced. */
.globe-split { display: grid; gap: clamp(24px, 4vw, 56px); grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); align-items: center; }
@media (max-width: 860px) { .globe-split { grid-template-columns: minmax(0, 1fr); } }
.globe { position: relative; aspect-ratio: 4 / 3; width: 100%; max-width: 620px; margin: 0 auto; }
.globe__fallback, .globe__fallback img { display: block; width: 100%; height: 100%; object-fit: contain; }
.globe__fallback { transition: opacity .6s; }
.globe__stage { position: absolute; top: 0; bottom: 0; left: 50%; aspect-ratio: 1; transform: translateX(-50%); max-width: 100%; opacity: 0; pointer-events: none; transition: opacity .8s; }
.globe__canvas { display: block; width: 100%; height: 100%; cursor: grab; touch-action: pan-y; }
.globe__canvas:active { cursor: grabbing; }
.globe--live .globe__stage { opacity: 1; pointer-events: auto; }
.globe--live .globe__fallback { opacity: 0; }
.office-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.office-list li { display: flex; align-items: center; gap: 12px; font-weight: 600; }
/* Every pin gets the same 16px slot so the names line up; only the HQ's dot
   is drawn larger (design review, 1 Oct 2026). */
.office-list__pin { width: 16px; height: 16px; flex: none; display: grid; place-items: center; }
.office-list__pin::before { content: ""; width: 12px; height: 12px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 0 4px var(--tick-ring); }
.office-list__pin--hq::before { width: 16px; height: 16px; }

.ticks { list-style: none; padding: 0; margin: 0; }
.ticks li { position: relative; padding-left: 28px; margin-bottom: 10px; }
.ticks li::before { content: ""; position: absolute; left: 4px; top: .55em; width: 10px; height: 10px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 0 3px var(--tick-ring); }
.prose p, .prose li { color: var(--ink-2); }
.prose h2, .prose h3 { margin-top: 1.4em; }

/* Contact form */
.form { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: clamp(18px, 3vw, 30px); box-shadow: var(--shadow); min-width: 0; }
.form__row { margin-bottom: 16px; }
.form label { display: block; font-weight: 700; margin-bottom: 6px; }
.form input, .form textarea { display: block; width: 100%; font: inherit; color: var(--ink); background: var(--field); border: 1.5px solid var(--field-line); border-radius: 10px; padding: 11px 13px; }
.form textarea { resize: vertical; min-height: 140px; }
.form input:focus-visible, .form textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 1px; border-color: var(--link); }
.form .cf-turnstile { margin: 4px 0 16px; max-width: 100%; }
.form__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 16px; }
.form__row { grid-column: 1 / -1; min-width: 0; }
.form__row--half { grid-column: auto; }
@media (max-width: 520px) { .form__row--half { grid-column: 1 / -1; } }
.form select { min-height: 48px; display: block; width: 100%; font: inherit; color: var(--ink); background: var(--field); border: 1.5px solid var(--field-line); border-radius: 10px; padding: 11px 13px; }
.form select:focus-visible, .filter input:focus-visible, .filter select:focus-visible { outline: 3px solid var(--focus); outline-offset: 1px; }
.form__hint { font-size: .88rem; color: var(--muted); margin: 6px 0 0; }
.form__status { min-height: 1.6em; font-weight: 700; margin: 0; }
/* The result of sending is a boxed note, not a line of coloured text that is
   easy to miss under a long form. */
.form__status--ok, .form__status--bad { padding: 12px 14px; border-radius: 10px; background: var(--tint); border: 1px solid var(--line); border-left: 5px solid; }
.form__status--ok { color: var(--ok); border-left-color: var(--ok); }
.form__status--bad { color: var(--bad); border-left-color: var(--bad); }
.form__note { background: var(--tint); border-radius: 10px; padding: 12px 14px; }
.form__small { font-size: .9rem; margin: 12px 0 0; }
/* Honeypot: off-screen for people, still in the form for bots. */
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
/* Turnstile's iframe is at least 300px wide whatever its container says (it
   sits in a closed shadow root and overhung a 278px box by 22px at 320px wide,
   30 Sep 2026). Below 360px the form goes flat, with 10px page margins, so a
   320px screen has exactly 300px for it and no horizontal scroll. */
@media (max-width: 360px) {
  /* Sides only: the shorthand also zeroed the top and bottom padding of
     .hero__inner and .foot__legal, which share the .wrap class. */
  .wrap { padding-left: 10px; padding-right: 10px; }
  .form { padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
}

/* Careers */
.jobs { display: grid; gap: 10px; list-style: none; margin: 0; padding: 0; }
.job a { display: block; padding: 16px 18px; border: 1px solid var(--line); border-radius: 10px; text-decoration: none; background: var(--surface); transition: border-color .2s, transform .2s; }
.job a:hover { border-color: var(--cyan); transform: translateX(3px); }
.filter { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 12px; margin: 0 0 12px; }
.filter__field { flex: 1 1 180px; min-width: 0; }
.filter label { display: block; font-weight: 700; font-size: .92rem; margin-bottom: 4px; }
.filter input, .filter select { display: block; width: 100%; min-height: 48px; font: inherit; color: var(--ink); background: var(--field); border: 1.5px solid var(--field-line); border-radius: 10px; padding: 9px 12px; }
.filter .btn { min-height: 48px; padding: 8px 20px; }
.filter__count { min-height: 1.4em; margin: 0 0 8px; color: var(--ink-2); font-weight: 600; }
/* The job search sits above both job lists; a full-width keyword box reads as a page search. */
.jobsearch { max-width: 760px; }
/* A past notice's page (only if PUBLISH_ARCHIVED_NOTICES is on): closed is the first thing read. */
.notice-closed { margin: 0 0 16px; padding: 12px 16px; border: 1px solid var(--line); border-left: 4px solid var(--ink-2); border-radius: 10px; background: var(--surface); }
.faq { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); margin-bottom: 12px; }
/* The marker is drawn inside the box: the browser's own triangle, positioned
   "outside", hung past the left edge on phones (design review, 1 Oct 2026). */
.faq summary { cursor: pointer; padding: 16px 20px 16px 48px; font-weight: 700; list-style: none; position: relative; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::before { content: ""; position: absolute; left: 20px; top: 1.75em; width: 8px; height: 8px; border-right: 2px solid var(--link); border-bottom: 2px solid var(--link); transform: translateY(-50%) rotate(-45deg); transition: transform .15s; }
.faq[open] summary::before { transform: translateY(-75%) rotate(45deg); }
.faq summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.faq p { padding: 0 20px 16px; margin: 0; color: var(--ink-2); }
.job__title { display: block; font-weight: 700; color: var(--link); }
.job__meta { display: block; font-size: .92rem; color: var(--muted); }
.job-notice strong { color: var(--ink); }

/* Footer: dark in both schemes */
.foot { --focus: #06b2e2; background: #0f2530; color: #c8d6dd; padding: 48px 0 24px; margin-top: 0; }
@media (prefers-color-scheme: dark) { .foot { background: #07131a; border-top: 1px solid var(--line); } }
.foot a { color: #e4f4fb; }
/* The address column is wider so it doesn't wrap badly at 1024. */
.foot__grid { display: grid; gap: 28px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
@media (min-width: 900px) { .foot__grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
.foot ul { list-style: none; padding: 0; margin: 0; }
.foot li { margin-bottom: 6px; }
/* Touch screens: each footer link gets a 44px-high target. */
@media (max-width: 920px), (pointer: coarse) {
  .foot li { margin-bottom: 0; }
  .foot li a, .foot p a { display: inline-block; padding: 9px 0; }
  .panel a[href^="tel:"] { display: inline-block; padding: 9px 0; }
}
.foot__name, .foot__head { color: #fff; font-weight: 700; }
.foot__legal { border-top: 1px solid #25414d; margin-top: 28px; padding-top: 18px; font-size: .9rem; color: #9fb3bd; }

/* Scroll reveal. site.js marks only elements that start below the fold as
   .is-pending, so nothing on screen at load ever blinks out, and without
   JavaScript nothing is hidden at all. */
.is-pending { opacity: 0; }
.is-in { animation: rise .7s cubic-bezier(.2, .7, .2, 1) var(--reveal-delay, 0ms) backwards; }
@keyframes rise { from { opacity: 0; transform: translateY(26px); } }

/* Chat assistant (built by chat.js; absent without JavaScript) */
.chat-launcher { position: fixed; right: 16px; bottom: 16px; z-index: 20; display: inline-flex; align-items: center; gap: 8px; padding: 12px 18px; border: 0; border-radius: 999px; background: var(--btn-bg); color: var(--btn-ink); font: inherit; font-weight: 700; cursor: pointer; box-shadow: 0 10px 30px rgba(2, 40, 58, .35); transition: transform .2s, background-color .2s; }
.chat-launcher:hover { background: var(--btn-bg-hover); transform: translateY(-2px); }
.chat-launcher svg { width: 20px; height: 20px; flex: none; }
.chat { position: fixed; inset: auto 16px 16px auto; margin: 0; padding: 0; max-width: none; max-height: none; width: min(390px, calc(100vw - 32px)); height: min(580px, calc(100dvh - 32px)); border: 1px solid var(--line); border-radius: 18px; background: var(--surface); color: var(--ink); box-shadow: 0 24px 60px rgba(0, 0, 0, .3); overflow: hidden; }
.chat[open] { display: flex; flex-direction: column; }
.chat::backdrop { background: rgba(6, 20, 27, .25); }
.chat__head { display: flex; align-items: flex-start; gap: 12px; padding: 16px 16px 12px; border-bottom: 1px solid var(--line); background: var(--tint); }
.chat__head h2 { font-size: 1.05rem; margin: 0 0 4px; }
.chat__badge { display: inline-block; vertical-align: 2px; margin-left: 4px; padding: 1px 8px; border-radius: 999px; background: var(--btn-bg); color: var(--btn-ink); font-size: .72rem; font-weight: 800; letter-spacing: .02em; }
.chat__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chat__chip { font: inherit; font-size: .88rem; min-height: 44px; padding: 7px 14px; border-radius: 999px; border: 1.5px solid var(--link); background: var(--surface); color: var(--link); cursor: pointer; }
.chat__chip:hover { background: var(--tint); }
.chat__head p { font-size: .82rem; color: var(--muted); margin: 0; line-height: 1.4; }
.chat__close { margin-left: auto; flex: none; width: 44px; height: 44px; border: 1px solid var(--line); border-radius: 50%; background: var(--surface); color: var(--ink); font: inherit; font-size: 1.3rem; line-height: 1; cursor: pointer; }
.chat__log { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; overscroll-behavior: contain; }
.msg { max-width: 88%; padding: 10px 13px; border-radius: 14px; white-space: pre-wrap; font-size: .95rem; line-height: 1.5; }
.msg--bot { align-self: flex-start; background: var(--tint); border: 1px solid var(--line); border-bottom-left-radius: 4px; }
.msg--user { align-self: flex-end; background: var(--btn-bg); color: var(--btn-ink); border-bottom-right-radius: 4px; }
.msg--note { align-self: center; background: none; color: var(--muted); font-size: .85rem; text-align: center; padding: 4px; }
.msg--wait { color: var(--muted); }
.chat__privacy { font-size: .78rem; color: var(--muted); line-height: 1.4; margin: 0; padding: 8px 12px 0; }
.chat__form { display: flex; gap: 8px; align-items: flex-end; padding: 12px; border-top: 1px solid var(--line); }
.chat__form textarea { flex: 1; min-width: 0; font: inherit; font-size: .95rem; color: var(--ink); background: var(--field); border: 1.5px solid var(--field-line); border-radius: 12px; padding: 9px 11px; resize: none; max-height: 120px; }
.chat__form textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 1px; }
.chat__form .btn { padding: 10px 16px; }
@media (max-width: 480px) { .chat { inset: auto 8px 8px auto; width: calc(100vw - 16px); height: calc(100dvh - 16px); } .chat-launcher { right: 12px; bottom: 12px; padding: 12px 14px; } }
/* Phones: the launcher is a 56px round button; its words stay as the
   accessible name. As a 200px pill it sat over the hero picture, form fields
   and the footer on every screen of a 320-375px phone. */
@media (max-width: 600px) {
  .chat-launcher { width: 56px; height: 56px; padding: 0; justify-content: center; }
  .chat-launcher svg { width: 24px; height: 24px; }
  .chat-launcher span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .is-pending { opacity: 1; }
  .hero__frame { translate: none !important; }
  .hero__link, .hero__ring { animation: none; }
  .hero__ring { opacity: 0; }
  .rotor__word { transition: none !important; }
  a.card:hover, a.card:focus-visible, .job a:hover, .chat-launcher:hover { transform: none; }
  a.card:hover .tile img { transform: none; }
  a.entry__tile:hover .entry__arrow, a.entry__tile:focus-visible .entry__arrow { transform: none; }
}

/* Headquarters map on /contact/: committed OpenStreetMap tiles in a grid,
   moved so the office sits at the centre of the box whatever its width. The
   279px / 158px are the office's position inside the tiles and 556px the
   widest box the tiles can fill around it; build.py map_layout() computes all
   three and tests/test_build.py fails if these drift from it. */
.panel--hq { display: grid; gap: 20px 32px; align-items: start; }
@media (min-width: 760px) { .panel--hq { grid-template-columns: minmax(0, 1fr) minmax(0, 556px); } }
.map { margin: 0; }
.map__view { position: relative; width: 100%; max-width: 556px; height: 300px; overflow: hidden; border-radius: 10px; border: 1px solid var(--line); background: #f2efe9; }
.map__tiles { position: absolute; left: calc(50% - 279px); top: calc(50% - 158px); display: grid; grid-template-columns: repeat(3, 256px); width: 768px; }
.map__tiles img { display: block; width: 256px; height: 256px; max-width: none; }
/* A teardrop in the brand colour whose tip is the office: a rounded square
   turned 45 degrees, lifted by half its diagonal so the corner meets the point. */
.map__pin { position: absolute; left: 50%; top: 50%; box-sizing: border-box; width: 24px; height: 24px; margin: -29px 0 0 -12px; border: 3px solid #fff; border-radius: 50% 50% 50% 0; background: #036e9c; transform: rotate(-45deg); box-shadow: 0 2px 6px rgba(0, 0, 0, .35); }
.map__credit { margin-top: 6px; font-size: .8rem; color: var(--muted); }
/* Dark mode: the tiles are a light map, so they sit in a light frame and are
   dimmed a little rather than glaring out of a dark page. */
@media (prefers-color-scheme: dark) {
  .map__view { border: 6px solid #d7e1e6; filter: brightness(.9); }
}

/* Chat on phones (only present when CHAT_ENABLED built chat.js in): the
   launcher never covers the last lines of the page, and steps aside while a
   form field has focus. */
@media (max-width: 760px) {
  .has-chat main, .has-chat .foot__legal { padding-bottom: 88px; }
  .is-typing .chat-launcher { display: none; }
}
.msg a { overflow-wrap: normal; }

/* A small link standing on its own gets a 44px tap target (WCAG 2.5.8 asks
   24; 44 is the platform guidance), without looking like a button. */
.tap { display: inline-flex; align-items: center; min-height: 44px; }
.cta__aside { margin-top: 12px; color: var(--ink-2); }
.contact-email { font-weight: 700; font-size: 1.05rem; }
.map__link { display: block; border-radius: 10px; }
.map__link:hover .map__view { border-color: var(--link); }
/* 404: the one band fills the space down to the footer. */
body > main:has(> .band--fill) { display: flex; flex-direction: column; }
body > main > .band--fill { flex: 1 0 auto; }

/* "Talk to us" (a tel: link): the number itself on wide screens, the words on
   phones. Hidden parts are clipped, not removed, and the link's aria-label
   carries both. In the header it shows only from 1024px, where it fits beside
   the two doors without crowding; the phone menu lists it too. */
.call__number { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (min-width: 761px) {
  .call__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .call__number { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
}
.nav .door--call { display: none; }
/* Phone pill only from 1200: between 921 and 1100 the row of links, the pill
   and the two doors did not fit, and "Hire talent" / "Find a job" wrapped onto
   two lines (15 Oct 2026). Nav spacing is tighter in that range too. */
@media (min-width: 1024px) { .nav .door--call { display: block; } }
@media (min-width: 1024px) and (max-width: 1199px) { .nav .door--call { display: none; } }
@media (min-width: 921px) and (max-width: 1100px) {
  .nav ul { gap: 2px; }
  .nav a, .nav .subnav__toggle { padding: 10px 9px; }
  .nav .door a { padding: 8px 11px; }
}
.nav .door--call a, .menu .door--call a { border-color: var(--line); color: var(--ink); }
.menu .door--call .call__label { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
.menu .door--call .call__number { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* Hiring resources */
.checklist { list-style: none; counter-reset: step; padding: 0; margin: 0; display: grid; gap: 14px; }
.checklist .step { counter-increment: step; position: relative; padding: 18px 20px 18px 64px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.checklist .step::before { content: counter(step); position: absolute; left: 20px; top: 18px; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: var(--btn-bg); color: var(--btn-ink); font-weight: 700; }
.checklist h3 { margin: 0 0 4px; font-size: 1.05rem; }
.checklist p { margin: 0; color: var(--ink-2); }
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
/* The comparison needs 640px as a table; at 390 it scrolled sideways with no
   sign that three columns were off screen. Narrow screens get the same rows
   as cards (build.py writes both) and the table is hidden, not squeezed. */
.compare-cards { display: none; gap: 12px; }
.compare-cards .panel { margin: 0; }
.compare-cards dl { margin: 0; }
.compare-cards dt { font-weight: 700; margin-top: 10px; }
.compare-cards dt:first-child { margin-top: 0; }
.compare-cards dd { margin: 2px 0 0; color: var(--ink-2); }
@media (max-width: 700px) { .compare-table { display: none; } .compare-cards { display: grid; } }
.compare { width: 100%; border-collapse: collapse; min-width: 640px; background: var(--surface); }
.compare th, .compare td { padding: 14px 16px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
.compare thead th { background: var(--tint); }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }
.calc input { display: block; width: 100%; min-height: 48px; font: inherit; color: var(--ink); background: var(--field); border: 1.5px solid var(--field-line); border-radius: 10px; padding: 9px 12px; }
.calc__result { min-height: 3em; margin: 8px 0 0; font-weight: 700; }
.calc__line { display: block; }

/* "What we do": Services opens a two-column panel (tcs.com review, 1 Oct
   2026). The build writes a link to /services/ and a hidden panel; site.js
   swaps the link for a button of the same box (font, line-height, padding
   inherited from the links' rule above), so nothing moves when it does, and
   without JavaScript "Services" stays a plain link. The panel is absolute,
   so opening it shifts nothing either. Phones get the same groups as two
   <details> inside the existing menu, collapsed, so About, Contact and the
   doors stay in view at 375px; the hamburger's rules above are scoped to
   ".menu > summary" so they do not draw these headings as 48px squares. */
.nav > ul { position: relative; }
.nav [data-sub-link], .nav .subnav__toggle { display: flex; align-items: center; gap: 7px; }
.nav .subnav__toggle { font: inherit; font-weight: 600; line-height: inherit; color: var(--ink); border: 0; background: none; margin: 0; cursor: pointer; -webkit-appearance: none; appearance: none; }
.nav .subnav__toggle.is-current { color: var(--link); box-shadow: inset 0 -3px 0 var(--cyan); }
.subnav__chev { width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s; }
.subnav__toggle[aria-expanded="true"] .subnav__chev { transform: translateY(2px) rotate(-135deg); }
.subnav { position: absolute; top: calc(100% + 12px); right: 0; z-index: 6; width: min(640px, calc(100vw - 40px)); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 18px 40px rgba(0, 0, 0, .18); padding: 18px 22px 12px; }
.subnav__cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 32px; }
.subnav__head { margin: 0 0 4px; font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.nav .subnav ul { display: block; }
.nav .subnav a { padding: 7px 10px; margin: 0 -10px; font-weight: 500; }
.subnav__foot { display: flex; flex-wrap: wrap; gap: 0 20px; margin: 10px 0 0; padding-top: 8px; border-top: 1px solid var(--line); }
.nav .subnav__foot a { font-weight: 700; color: var(--link); }
.menu > ul { max-height: calc(100dvh - 96px); overflow-y: auto; min-width: 270px; }
.menu ul ul { position: static; min-width: 0; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; max-height: none; overflow: visible; }
.menu__group > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border-radius: 8px; font-weight: 600; color: var(--ink); }
.menu__group > summary::-webkit-details-marker { display: none; }
.menu__group > summary::after { content: ""; flex: none; width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s; }
.menu__group[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
.menu__group > summary:hover { background: var(--tint); color: var(--link); }
.menu__group ul { padding: 0 0 6px 14px; }
.menu__group a { padding: 9px 14px; font-weight: 500; }
@media (prefers-reduced-motion: reduce) { .menu__group > summary::after { transition: none; } }

/* Home: three entry tiles under the hero. The whole tile is the link. */
.band:has(> .wrap > .entry) { padding: clamp(28px, 4vw, 44px) 0; }
.entry { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.entry > li { display: flex; }
.entry__tile { flex: 1; position: relative; padding-right: 60px; }
.entry__tile h2 { color: var(--link); margin-bottom: .3em; }
.entry__tile p { margin: 0; }
.entry__arrow { position: absolute; right: 24px; bottom: 22px; font-size: 1.4rem; font-weight: 700; line-height: 1; color: var(--link); transition: transform .25s; }
a.entry__tile:hover .entry__arrow, a.entry__tile:focus-visible .entry__arrow { transform: translateX(4px); }

/* Home: Latest. Three across on wide screens; on phones a row that scrolls
   sideways and snaps to each card. Never moves by itself. */
.latest__group + .latest__group { margin-top: clamp(28px, 4vw, 40px); }
.latest__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 16px; margin-bottom: 8px; }
.latest__head h3 { margin: 0; }
.latest__head .tap { gap: 6px; }
.latest__row { list-style: none; margin: 0 -6px; padding: 6px; display: grid; gap: 20px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.latest__row > li { display: flex; min-width: 0; scroll-snap-align: start; }
.latest__row .card { flex: 1; }
@media (max-width: 760px) {
  .latest__row { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 82%; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding: 0 6px; overscroll-behavior-x: contain; padding-bottom: 14px; }
}

/* News and blog */
.post-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 10px; font-size: .9rem; color: var(--muted); }
.kind { display: inline-block; padding: 1px 10px; border-radius: 999px; background: var(--tint); border: 1px solid var(--callout-line); color: var(--link); font-size: .78rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.card__title { font-size: 1.2rem; color: var(--link); margin: 0 0 .5em; }
.post-card__img { display: block; width: calc(100% + 48px); max-width: none; height: auto; margin: -24px -24px 18px; border-radius: var(--radius) var(--radius) 0 0; }
.newsfilter ul { list-style: none; margin: 0 0 24px; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.newsfilter a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 8px 16px; border: 1.5px solid var(--line); border-radius: 999px; color: var(--ink); font-weight: 700; text-decoration: none; }
.newsfilter a:hover { border-color: var(--link); color: var(--link); }
.newsfilter a[aria-current="page"] { background: var(--btn-bg); border-color: var(--btn-bg); color: var(--btn-ink); }
.newsfilter__n { font-weight: 500; }
.post-body h2 { font-size: 1.4rem; margin: 1.6em 0 .5em; }
.post-body ul { padding-left: 1.3em; margin: 0 0 1em; }
.post-body li { margin-bottom: .4em; }
.post-back { margin-top: 2em; font-weight: 700; }

/* Home's closing band: the brand gradient, so the page ends on one clear ask. */
.band--close { --focus: #ffffff; color: #fff; background: linear-gradient(120deg, #01344d, var(--blue-dark) 45%, var(--blue)); }
.band--close h2 { color: #fff; }
.band--close .btn { background: #fff; color: var(--blue-dark); border-color: #fff; }
.band--close .btn:hover { background: #dff3fb; border-color: #dff3fb; color: var(--blue-dark); }
.band--close .cta__aside { color: #dff3fb; }
.band--close .cta__aside a { color: #fff; }
