/* ==========================================================================
   Transform8 — subpage sections (/contact-us, /testimonials, /works, /about-us)

   Kept separate from layout.css, which styles the home page only. Everything
   here reuses the same tokens and the same rules the home page follows: no
   border-radius anywhere, Montserrat for display, Manrope for accents, 1450px
   container with 40px gutters (20px below 1280).
   ========================================================================== */

/* Shared subpage intro ------------------------------------------------------
   The home page hero is a 100vh video block; subpages get a plain type intro
   that still clears the fixed header. */

.page-hero {
  padding: 220px 0 90px;
}

.page-hero__title {
  font-family: var(--f-display);
  font-size: 64px;
  font-weight: 500;
  line-height: 1.2em;
  letter-spacing: -0.02em;
  color: var(--c-text);
  max-width: 15em;
  margin-top: 24px;
}

.page-hero__sub {
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  max-width: 40em;
  margin-top: 24px;
}

/* The Clients headline is a full sentence, not a two-word title. At 64px it
   ran to six lines and filled the whole viewport before any content. */
.page-hero__title--long {
  font-size: 44px;
  max-width: 22em;
}

@media (max-width: 1279.98px) {
  .page-hero { padding: 180px 0 70px; }
  .page-hero__title { font-size: 48px; }
  .page-hero__title--long { font-size: 36px; }
}

@media (max-width: 991.98px) {
  .page-hero { padding: 150px 0 60px; }
  .page-hero__title,
  .page-hero__title--long { font-size: 30px; }
  .page-hero__sub { font-size: 16px; }
}

/* /works -------------------------------------------------------------------- */

.works-page { padding: 0 0 130px; }

.works-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 80px 165px;
}

/* The cards reuse .work-card from layout.css; only the fixed 420px media box
   needs relaxing, because these covers vary in aspect far more than the two on
   the home page (Current is portrait). */
.works-grid .work-card__media {
  height: auto;
  aspect-ratio: 3 / 2;
  overflow: hidden;
}

@media (max-width: 1279.98px) {
  .works-grid { gap: 60px 90px; }
}

@media (max-width: 991.98px) {
  .works-page { padding: 0 0 80px; }
  .works-grid { grid-template-columns: 1fr; gap: 60px; }
}

/* /blog ---------------------------------------------------------------------
   Index cards and article typography. Content comes from Supabase and is
   rendered to static HTML at build time (tools/build-blog.js), so everything
   below styles generated markup — keep the class names in step with that file.
   -------------------------------------------------------------------------- */

.blog-index { padding: 0 0 130px; }

.post-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 70px 40px;
}

.post-card__link {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.post-card__media {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  margin-bottom: 24px;
}

.post-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  transition: filter var(--dur-base) var(--ease-site);
}

.post-card__link:hover .post-card__media img { filter: grayscale(0); }

.post-card__meta {
  font-family: var(--f-display);
  font-size: 14px;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--c-accent);
}

.post-card__title {
  font-family: var(--f-display);
  font-size: 22px;
  font-weight: 500;
  line-height: 1.4em;
  color: var(--c-text);
  margin-top: 10px;
}

.post-card__excerpt {
  font-family: var(--f-display);
  font-size: 16px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  margin-top: 12px;
}

.blog-empty {
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 300;
  color: var(--c-text-70);
}

/* Article ------------------------------------------------------------------- */

.article { padding: 220px 0 130px; }

.article__title {
  font-family: var(--f-display);
  font-size: 52px;
  font-weight: 500;
  line-height: 1.2em;
  letter-spacing: -0.02em;
  color: var(--c-text);
  max-width: 18em;
  margin-top: 20px;
}

.article__lead {
  font-family: var(--f-display);
  font-size: 20px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  max-width: 42em;
  margin-top: 24px;
}

.article__media {
  margin-top: 50px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

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

/* Measure caps the line length; long-form is the one place on this site that
   needs it, since every other section is deliberately wide. */
.article__body {
  max-width: 44em;
  margin-top: 50px;
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 300;
  line-height: 1.7em;
  color: var(--c-text);
}

.article__body > * + * { margin-top: 1.2em; }

.article__body h2,
.article__body h3,
.article__body h4 {
  font-weight: 500;
  line-height: 1.3em;
  margin-top: 2em;
}

.article__body h2 { font-size: 30px; }
.article__body h3 { font-size: 24px; }
.article__body h4 { font-size: 20px; }

.article__body a { color: var(--c-accent); }

.article__body ul,
.article__body ol { padding-left: 1.3em; }
.article__body ul { list-style: disc; }
.article__body ol { list-style: decimal; }
.article__body li + li { margin-top: 0.5em; }

.article__body blockquote {
  margin: 2em 0;
  padding-left: 24px;
  border-left: 1px solid var(--c-accent-70);
  color: var(--c-text-70);
}

.article__body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  background: rgba(255, 255, 255, 0.08);
  padding: 0.15em 0.4em;
}

.article__body pre {
  background: rgba(255, 255, 255, 0.06);
  padding: 20px;
  overflow-x: auto;
}

.article__body pre code { background: none; padding: 0; }

.article__back { margin-top: 70px; }

@media (max-width: 1279.98px) {
  .post-grid { grid-template-columns: repeat(2, 1fr); }
  .article__title { font-size: 40px; }
}

@media (max-width: 991.98px) {
  .blog-index { padding: 0 0 80px; }
  .article { padding: 150px 0 80px; }
  .post-grid { grid-template-columns: 1fr; gap: 50px; }
  .article__title { font-size: 30px; }
  .article__lead { font-size: 18px; }
  .article__body { font-size: 17px; }
  .article__body h2 { font-size: 25px; }
  .article__body h3 { font-size: 21px; }
}

/* /testimonials ("Clients") -------------------------------------------------
   Geometry read off the published page at a 1440px viewport, not eyeballed:

     content column   1200px wide (x 120..1320)   -> .container--narrow
     headline         Montserrat 50/60, weight 400, white, full 1200 width
     client wall      3 columns, 200x64 cells, object-fit: contain,
                      row pitch 122px  -> 58px row gap
     quote portrait   370x400, object-fit: cover
     quote text       Manrope 30/36, weight 400, 620px wide
     name             Montserrat 24/28.8, weight 400
     role             Montserrat 16/25.6, weight 500, #bfcfff
     sides            the portrait and the text swap between the two quotes

   The headline reuses the shared .h2 preset from layout.css (50/46/38px,
   -2.5px tracking) rather than redeclaring it — that IS the value measured.
   -------------------------------------------------------------------------- */

/* The rest of the site runs a 1450px container; this page is narrower. */
.container--narrow { max-width: 1280px; }

.clients-hero {
  position: relative;
  width: 100%;
  height: 600px;
  overflow: hidden;
}

.clients-hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Encoded grayscale as well, so the colour channels are not shipped. */
  filter: grayscale(1);
}

/* 60px, so the headline lands at y=660 as measured on the original (the hero
   above it is 600 tall). */
.clients-intro { padding: 60px 0 0; }

/* .h2 caps at its preset size; the original wraps to three lines at 1200px. */
.clients-intro .h2 { max-width: 1200px; }

.clients-wall { padding: 100px 0 130px; }

.client-wall {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  row-gap: 58px;
  align-items: center;
  justify-items: center;
}

.client-wall__cell {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 200px;
  height: 64px;
}

.client-wall__cell img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* Quotes ------------------------------------------------------------------- */

/* The 130px used to sit here as bottom padding, when both quotes shared one
   section. It moved to .quotes--light as a MARGIN: padding would fall inside
   the white band and paint 130px of white below the quote, where a margin
   shows the black page behind it. The rhythm between the two quotes is
   unchanged either way, because each .quote already carries its own 90px. */
.quotes { padding: 0; }

/* Light band, same treatment as .awards on the homepage — the site's only
   other inverted section, so this reuses those tokens rather than inventing
   a second light palette. */
.quotes--light {
  background: var(--c-text);
  color: var(--c-bg);
  margin-bottom: 130px;
}

/* Without these the quote would be white-on-white: .quote__name and
   .quote__text are var(--c-text) further down, and .quote__role is periwinkle,
   which lands at about 1.6:1 on white. --c-grey is what .awards already uses
   for its secondary text on the same background. */
.quotes--light .quote__name,
.quotes--light .quote__text { color: var(--c-bg); }
.quotes--light .quote__role { color: var(--c-grey); }

/* space-between, not a fixed gap: on the original the portrait and the text
   each sit flush against opposite edges of the 1200px column (text 120..740,
   portrait 935..1305), with whatever is left over falling between them. */
.quote {
  display: flex;
  /* Centred, not top-aligned: on the original the quote's midline sits on the
     midline of the portrait+name+role block (measured exactly so on the first
     quote), which reads very differently from tops flush. */
  align-items: center;
  justify-content: space-between;
  gap: 60px;
  padding: 90px 0;
}

/* Second quote mirrors the first: portrait left, text right. */
.quote--left { flex-direction: row; }
.quote--right { flex-direction: row-reverse; }

/* The portrait is inset 15px from the outer edge of the column — the text
   goes fully flush, the portrait does not. */
.quote__portrait { flex: 0 0 370px; }
.quote--right .quote__portrait { margin-right: 15px; }
.quote--left .quote__portrait { margin-left: 15px; }

/* Encoded grayscale rather than filtered here — the published Framer page
   shows these two in colour, so this is a deliberate deviation from the 1:1
   match, requested. Doing it in the encode rather than with a CSS filter keeps
   the dead colour channels off the wire, the same way the hero is handled.
   The colour masters are in images/_originals/ if it needs reverting. */
.quote__img {
  width: 370px;
  height: 400px;
  object-fit: cover;
}

.quote__name {
  font-family: var(--f-display);
  font-size: 24px;
  font-weight: 400;
  line-height: 1.2em;
  color: var(--c-text);
  margin-top: 30px;
}

.quote__role {
  font-family: var(--f-display);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.6em;
  color: var(--c-accent);
  margin-top: 6px;
}

.quote__text {
  flex: 0 1 620px;
  margin: 0;
  font-family: var(--f-accent);
  font-size: 30px;
  font-weight: 400;
  line-height: 1.2em;
  color: var(--c-text);
}

@media (max-width: 1279.98px) {
  .clients-hero { height: 480px; }
  .clients-intro { padding: 80px 0 0; }
  .clients-wall { padding: 80px 0 100px; }
  .quote { gap: 40px; padding: 70px 0; }
  .quote__text { font-size: 26px; }
}

@media (max-width: 991.98px) {
  .clients-hero { height: 320px; }
  .clients-intro { padding: 60px 0 0; }
  .clients-wall { padding: 60px 0 80px; }
  .client-wall { grid-template-columns: repeat(2, 1fr); row-gap: 40px; }
  .client-wall__cell { width: 150px; height: 52px; }
  .quotes { padding: 0 0 80px; }
  /* Stack: portrait above the quote, both quotes the same way round. */
  .quote,
  .quote--right { flex-direction: column; gap: 30px; padding: 50px 0; }
  .quote__portrait { flex: none; width: 100%; }
  .quote__img { width: 100%; height: 320px; }
  .quote__text { flex: none; font-size: 22px; }
}

/* /works/<slug> — case pages -------------------------------------------------
   Generated by tools/build-works.js from the `cases` table. The listing reuses
   .work-card / .works-grid; only the detail page needs its own rules.
   -------------------------------------------------------------------------- */

.case { padding: 220px 0 130px; }

.case__title {
  font-family: var(--f-display);
  font-size: 52px;
  font-weight: 500;
  line-height: 1.2em;
  letter-spacing: -0.02em;
  color: var(--c-text);
  max-width: 18em;
  margin-top: 20px;
}

.case__lead {
  font-family: var(--f-display);
  font-size: 20px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  max-width: 42em;
  margin-top: 24px;
}

.case__media {
  margin-top: 50px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

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

/* Client / Date / Services, as a definition list so the pairing is in the
   markup rather than implied by layout. */
.case__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 50px;
  margin: 50px 0 0;
  padding-top: 30px;
  border-top: 1px solid var(--c-accent-70);
}

.case__meta-row { display: flex; flex-direction: column; gap: 6px; }

.case__meta dt {
  font-family: var(--f-display);
  font-size: 14px;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--c-accent);
}

.case__meta dd {
  margin: 0;
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text);
}

/* Long-form measure, matching the article body on the blog. */
.case__body {
  max-width: 44em;
  margin-top: 50px;
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 300;
  line-height: 1.7em;
  color: var(--c-text);
}

.case__body > * + * { margin-top: 1.2em; }
.case__body h2 { font-size: 30px; font-weight: 500; line-height: 1.3em; margin-top: 2em; }
.case__body h3 { font-size: 24px; font-weight: 500; line-height: 1.3em; margin-top: 2em; }
.case__body a { color: var(--c-accent); }
.case__body ul { list-style: disc; padding-left: 1.3em; }
.case__body ol { list-style: decimal; padding-left: 1.3em; }
.case__body li + li { margin-top: 0.5em; }

.case__back { margin-top: 70px; }

/* The listing cards became links when they moved to the database. */
.work-card__link { display: flex; flex-direction: column; gap: 20px; height: 100%; }

@media (max-width: 1279.98px) {
  .case { padding: 180px 0 100px; }
  .case__title { font-size: 40px; }
}

@media (max-width: 991.98px) {
  .case { padding: 150px 0 80px; }
  .case__title { font-size: 30px; }
  .case__lead { font-size: 18px; }
  .case__meta { gap: 30px; }
  .case__body { font-size: 17px; }
}

/* 404 -------------------------------------------------------------------------
   The "404" is a logo3d panel, so it inherits the label treatment wholesale:
   js/logo3d.js finds it via [data-logo3d], extrudes images/logo3d-404.svg and
   lights it with the same moving spotlight. Nothing here touches the material —
   only the box it sits in.
   -------------------------------------------------------------------------- */

.notfound {
  /* A centred column filling the viewport, minus the small logo bar above it.
     Vertically centred rather than top-aligned: with this little on the page,
     top-alignment leaves it stranded under a large empty area. */
  min-height: calc(100vh - 92px);
  padding: 0 var(--gutter, 40px) 60px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* The panel needs real height: the extruded solid is fitted to the box by
   fitCamera(), so a collapsed box renders a sliver of chrome and nothing else. */
.notfound__panel {
  width: 100%;
  max-width: 660px;
  height: 340px;
}

/* logo3d gives the panel `cursor: grab`; that is wanted here too — the 404 is
   draggable exactly like the label logos. */

.notfound__title {
  font-family: var(--f-display);
  font-size: 38px;
  font-weight: 400;
  line-height: 1.2em;
  letter-spacing: -1.9px;
  color: var(--c-text);
  margin-top: 8px;
}

.notfound__cta { margin-top: 36px; }

@media (max-width: 1279.98px) {
  .notfound__panel { height: 280px; }
  .notfound__title { font-size: 32px; letter-spacing: -1.6px; }
}

@media (max-width: 991.98px) {
  .notfound { min-height: calc(100vh - 80px); }
  .notfound__panel { height: 200px; }
  .notfound__title { font-size: 26px; letter-spacing: -1.2px; }
  .notfound__cta { margin-top: 28px; }
}

/* The stripped header: just the wordmark, on its own line. */
.notfound__head {
  padding: 30px var(--gutter, 40px) 0;
}

.notfound__head .nav__logo img,
.notfound__head .nav__logo picture {
  display: block;
  width: 166px;
  height: 31px;
  object-fit: contain;
}

@media (max-width: 991.98px) {
  .notfound__head { padding-top: 24px; }
  .notfound__head .nav__logo img,
  .notfound__head .nav__logo picture { width: 94px; height: 40px; }
}

/* /vacancies ------------------------------------------------------------------
   A table rather than a stack of cards: openings get scanned, not read. Aligned
   columns let the eye compare role, label, contract and city straight down the
   page — a stacked row makes you re-find each of those on every line.

   The header and the rows share one --v-cols custom property, so the columns
   cannot drift apart: change the track list once and both follow.

   Motion, all on the site's own easing:
     1. Each cell rises out of a clipping mask instead of fading up. --i is the
        cell's place in the row and --row the row's place in the list, so the
        table assembles left to right, top to bottom.
     2. On hover a soft periwinkle glow tracks the cursor across the row
        (js/vacancies.js publishes --mx). With JS off the glow simply centres.

   All of it collapses to nothing under prefers-reduced-motion, at the bottom.
   -------------------------------------------------------------------------- */

.vacancies { padding: 0 0 130px; }

.vacancy-table {
  /* One source of truth for the grid — the header and every row read it. */
  --v-cols: minmax(0, 1fr) 110px 140px 160px 20px;
  --v-gap: 30px;
}

/* The sector index is the same object as the vacancy list: a row of aligned
   columns you click through to a detail page. It reuses these rules by sharing
   selectors rather than by copying them, so a change to the hover, the reveal
   or the hairline lands on both lists at once. Only the column widths and the
   type sizes differ, further down. */
.vacancy-head,
.vacancy__link,
.sector-head,
.sector-row__link {
  display: grid;
  grid-template-columns: var(--v-cols);
  gap: var(--v-gap);
  align-items: center;
}

/* display:contents puts the meta cells in the outer grid on desktop while
   keeping them one element that can regroup onto a single line on mobile. */
.vacancy__meta,
.vacancy-head__meta,
.sector-row__meta,
.sector-head__meta { display: contents; }

.vacancy-head,
.sector-head { padding-bottom: 14px; }

.vacancy-head__cell,
.sector-head__cell {
  font-family: var(--f-display);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.6em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-accent);
}

.vacancy-list,
.sector-list {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The hairline is what makes aligned columns readable — it ties a title to the
   cells sitting on its row. On .vacancy so it stops at the container edge
   rather than following the hover glow's bleed. */
.vacancy,
.sector-row {
  position: relative;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.vacancy:last-child,
.sector-row:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.1); }

.vacancy__link,
.sector-row__link {
  position: relative;
  padding: 26px 0;
  isolation: isolate;
}

/* Cursor-tracked glow. --mx comes from js/vacancies.js; the 50% fallback keeps
   it centred and perfectly usable when that script never runs. Bled past the
   column edge so the wash does not stop hard against the text. */
.vacancy__sheen,
.sector-row__sheen {
  position: absolute;
  inset: 0 -24px;
  z-index: -1;
  opacity: 0;
  background-color: rgba(255, 255, 255, 0.03);
  background-image: radial-gradient(
    420px circle at var(--mx, 50%) 50%,
    rgba(191, 207, 255, 0.13),
    rgba(191, 207, 255, 0.04) 45%,
    transparent 70%
  );
  transition: opacity var(--dur-base) var(--ease-site);
}

.vacancy__link:hover .vacancy__sheen,
.vacancy__link:focus-visible .vacancy__sheen,
.sector-row__link:hover .sector-row__sheen,
.sector-row__link:focus-visible .sector-row__sheen { opacity: 1; }

.vacancy__role,
.sector-row__role { min-width: 0; }

/* Mask + line ---------------------------------------------------------------
   The mask is the parent (overflow hidden); .v-line is the thing that moves.
   Both need to be block-level or the mask collapses to the text baseline and
   clips the descenders. */
.vacancy__title,
.vacancy__summary,
.vacancy__cell,
.sector-row__title,
.sector-row__summary,
.sector-row__cell {
  display: block;
  overflow: hidden;
  /* The mask clips horizontally as well as vertically, so anything that moves
     sideways inside it loses its trailing glyph — the "r" of "Manager" went
     missing on hover. Widen the clip box and pull it back with a matching
     negative margin: more room to move, identical layout. */
  padding-right: 20px;
  margin-right: -20px;
}

.v-line {
  display: block;
  transform: translate3d(0, 110%, 0);
  opacity: 0;
  transition:
    transform var(--dur-reveal) var(--ease-out-intro),
    opacity var(--dur-reveal) var(--ease-site);
  /* Row offset first, then the cell's own position within the row. */
  transition-delay: calc(var(--row, 0) * 60ms + var(--i, 0) * 70ms);
}

.vacancy.is-visible .v-line,
.sector-row.is-visible .v-line {
  transform: translate3d(0, 0, 0);
  opacity: 1;
}

/* Type ---------------------------------------------------------------------- */

.vacancy__title,
.sector-row__title {
  font-family: var(--f-display);
  font-size: 22px;
  font-weight: 500;
  line-height: 1.35em;
  letter-spacing: -0.3px;
  color: var(--c-text);
}

/* The sector index is the page's main content rather than a shelf of links,
   so its rows carry a little more weight than a vacancy row. */
.sector-row__title { font-size: 26px; }

/* Hover lives on .v-shift, a separate element from the .v-line that handles the
   entrance. Both animate `transform`, so sharing one element meant the
   pointer-out inherited the reveal's duration AND its stagger delay — the title
   snapped right and then crawled back. */
.v-shift {
  display: inline-block;
  transition: transform var(--dur-base) var(--ease-site);
}

.vacancy__link:hover .vacancy__title .v-shift,
.sector-row__link:hover .sector-row__title .v-shift { transform: translate3d(10px, 0, 0); }

.vacancy__summary,
.sector-row__summary {
  font-family: var(--f-display);
  font-size: 15px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  max-width: 46em;
  margin-top: 6px;
}

.vacancy__cell,
.sector-row__cell {
  font-family: var(--f-display);
  font-size: 15px;
  font-weight: 300;
  line-height: 1.5em;
  color: var(--c-text-70);
}

/* The label is a brand name, not a property of the job — coloured so you can
   pick out which company is hiring without reading the column. */
.vacancy__cell--label,
.sector-row__cell--label {
  font-weight: 500;
  color: var(--c-accent);
}

.vacancy__go,
.sector-row__go {
  display: flex;
  justify-content: flex-end;
  color: var(--c-text);
}

.vacancy__arrow,
.sector-row__arrow {
  flex: none;
  transition: transform var(--dur-base) var(--ease-out-intro);
}

.vacancy__link:hover .vacancy__arrow,
.sector-row__link:hover .sector-row__arrow { transform: translateX(5px); }

/* Empty state ---------------------------------------------------------------
   Deliberately not a shrug: it says there is nothing open, explains that an
   open application is still read, and gives one route out. */

.vacancy-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  border-top: 1px solid var(--c-accent-70);
  padding-top: 50px;
}

.vacancy-empty__lead {
  font-family: var(--f-display);
  font-size: 30px;
  font-weight: 400;
  line-height: 1.3em;
  letter-spacing: -0.5px;
  color: var(--c-text);
}

.vacancy-empty__text {
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  max-width: 40em;
  margin-top: 16px;
}

.vacancy-empty .btn { margin-top: 40px; }

@media (max-width: 1279.98px) {
  .vacancy-table { --v-cols: minmax(0, 1fr) 100px 120px 140px 20px; --v-gap: 22px; }
  .sector-table  { --v-cols: minmax(0, 1fr) 260px 20px; --v-gap: 22px; }
  .vacancy__title { font-size: 20px; }
  .sector-row__title { font-size: 23px; }
}

@media (max-width: 991.98px) {
  .vacancies { padding: 0 0 80px; }
  /* Columns stop earning their keep once they are narrower than the words in
     them, so the meta regroups onto one line under the title and the header —
     which now labels nothing — goes away. */
  .vacancy-head,
  .sector-head { display: none; }
  .vacancy__link,
  .sector-row__link {
    grid-template-columns: minmax(0, 1fr) 20px;
    grid-template-areas:
      "role go"
      "meta meta";
    row-gap: 12px;
    padding: 22px 0;
    align-items: start;
  }
  .vacancy__role,
  .sector-row__role { grid-area: role; }
  .vacancy__go,
  .sector-row__go { grid-area: go; }
  .vacancy__meta,
  .sector-row__meta {
    grid-area: meta;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 14px;
  }
  /* No sideways movement down here, so the clip allowance is dead weight. */
  .vacancy__cell,
  .sector-row__cell { padding-right: 0; margin-right: 0; }
  .vacancy__title { font-size: 19px; }
  .sector-row__title { font-size: 21px; }
  .vacancy-empty__lead { font-size: 24px; }
  .vacancy-empty__text { font-size: 16px; }
}

/* Reduced motion: keep the hover feedback, drop everything that moves. The
   rows must still be readable, so the masks resolve to their end state rather
   than staying hidden. */
@media (prefers-reduced-motion: reduce) {
  .v-line,
  .v-shift,
  .vacancy__arrow {
    transition: none !important;
    transition-delay: 0s !important;
  }
  .v-shift { transform: none !important; }
  .v-line { transform: none !important; opacity: 1 !important; }
  .vacancy__link:hover .vacancy__title .v-shift { transform: none !important; }
  .vacancy__sheen { display: none; }
}

/* ==========================================================================
   Sectors (/sectors)

   A card per sector, each carrying "chips" naming which labels serve it —
   that mapping is the point of the page: the group's answer to "do you know
   my industry" is which of the four companies already works in it.
   ========================================================================== */

.sectors { padding: 0 0 130px; }

@media (max-width: 1279.98px) { .sectors { padding-bottom: 100px; } }
@media (max-width: 991.98px)  { .sectors { padding-bottom: 80px; } }

/* Two columns of boxed cards became a single column of rules, matching the
   vacancy list. Ten boxed cards read as ten separate offers you have to
   compare one at a time; ten aligned rows read as one list you can scan down,
   and the label column lines up so "who does this" is comparable at a glance
   instead of buried in chips of differing widths.

   The shared behaviour lives with the .vacancy rules above — only the column
   widths belong here. */
.sector-table {
  --v-cols: minmax(0, 1fr) 320px 20px;
  --v-gap: 30px;
}

/* Scroll-margin so the dropdown's old #anchor links do not land under the
   fixed header. */
.sector-row { scroll-margin-top: 120px; }

/* ==========================================================================
   Sector detail (/sectors/<slug>)

   Reuses the site's existing primitives — .page-hero, .h2, .eyebrow, .btn,
   .faq__* from layout.css — and only adds what these pages genuinely need.
   ========================================================================== */

.sector-page .page-hero { padding-bottom: 0; }

.sector-intro { padding: 60px 0 110px; }

@media (max-width: 991.98px) { .sector-intro { padding: 40px 0 70px; } }

.sector-intro__body p {
  font-family: var(--f-display);
  font-size: 19px;
  font-weight: 300;
  line-height: 1.7em;
  color: var(--c-text-70);
}

.sector-intro__body p + p { margin-top: 20px; }

/* Three differentiators, hairline-topped like the "waarom" reasons so the
   two sections read as the same family. */
.sector-angles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  margin-top: 60px;
}

@media (max-width: 991.98px) { .sector-angles { grid-template-columns: 1fr; } }

.angle {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 22px;
  border-top: 1px solid var(--c-accent-70);
}

.angle__title {
  font-family: var(--f-display);
  font-size: 20px;
  font-weight: 400;
  line-height: 1.25em;
  letter-spacing: -0.4px;
  color: var(--c-text);
}

.angle__text {
  font-family: var(--f-display);
  font-size: 15px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
}

/* --- Approach: numbered steps ------------------------------------------- */

.sector-approach { padding: 0 0 110px; }

@media (max-width: 991.98px) { .sector-approach { padding-bottom: 70px; } }

.sector-approach__head,
.sector-labels__head,
.sector-cases__head {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 44px;
}

.steps { display: flex; flex-direction: column; }

.step {
  display: flex;
  gap: 28px;
  padding: 26px 0;
  border-top: 1px solid var(--c-hairline, rgba(255, 255, 255, 0.14));
}

.step:last-child { border-bottom: 1px solid var(--c-hairline, rgba(255, 255, 255, 0.14)); }

.step__num {
  font-family: var(--f-display);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.6em;
  color: var(--c-accent);
  flex: none;
  width: 40px;
}

.step__body { display: flex; flex-direction: column; gap: 8px; }

.step__title {
  font-family: var(--f-display);
  font-size: 20px;
  font-weight: 400;
  line-height: 1.3em;
  color: var(--c-text);
}

.step__text {
  font-family: var(--f-display);
  font-size: 16px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
}

@media (max-width: 599.98px) {
  .step { gap: 16px; }
  .step__num { width: 28px; }
}

/* --- Which labels serve this sector -------------------------------------- */

.sector-labels { padding: 0 0 110px; }
.sector-cases  { padding: 0 0 110px; }

@media (max-width: 991.98px) {
  .sector-labels, .sector-cases { padding-bottom: 70px; }
}

.sector-labels__grid,
.sector-cases__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
}

@media (max-width: 991.98px) {
  .sector-labels__grid,
  .sector-cases__grid { grid-template-columns: 1fr; }
}

.sector-label,
.sector-case {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 30px 28px 26px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--c-hairline, rgba(255, 255, 255, 0.12));
  transition:
    background-color var(--dur-base) var(--ease-site),
    border-color var(--dur-base) var(--ease-site),
    transform var(--dur-base) var(--ease-out-intro);
}

.sector-label:hover,
.sector-case:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.24);
  transform: translateY(-4px);
}

.sector-label__name,
.sector-case__title {
  font-family: var(--f-display);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.2em;
  letter-spacing: -0.5px;
  color: var(--c-text);
}

.sector-label__text,
.sector-case__text {
  font-family: var(--f-display);
  font-size: 15px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  flex: 1;
}

.sector-label__go,
.sector-case__go {
  font-family: var(--f-display);
  font-size: 13px;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--c-accent);
  margin-top: 6px;
}

/* --- FAQ + closing CTA --------------------------------------------------- */

/* Padding and the light treatment both live with .faq in layout.css, so the
   two FAQ sections cannot drift apart. */

.sector-cta {
  padding: 0 0 130px;
  text-align: center;
}

@media (max-width: 991.98px) { .sector-cta { padding-bottom: 80px; } }

.sector-cta__text {
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 300;
  line-height: 1.6em;
  color: var(--c-text-70);
  max-width: 46ch;
  margin: 16px auto 0;
}

.sector-cta__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  margin-top: 34px;
}

@media (max-width: 599.98px) {
  .sector-cta__actions { flex-direction: column; gap: 18px; }
}

.sector-cta__link {
  font-family: var(--f-display);
  font-size: 14px;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--c-accent);
}

.sector-row__link { text-decoration: none; }

/* ==========================================================================
   Office photography

   Shot in colour, shipped in greyscale. The colour masters sit in
   images/_originals/ under the same names, so going back to colour is a
   re-encode rather than a reshoot.

   The greyscale is baked into the files instead of applied with a CSS
   filter: it saves roughly a fifth of the bytes, and it means a reader who
   saves or prints the image gets what the page showed them.

   No border-radius here, per the note at the top of this file.
   ========================================================================== */

.office { padding: 0 0 130px; }

.office__head { margin-bottom: 44px; }

.office__figure {
  margin: 0;
  overflow: hidden;
  background: var(--c-grey);   /* holds the box while the file arrives */
}

.office__figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A wide establishing shot, then two at native proportion beneath it. */
.office__lead { aspect-ratio: 21 / 9; margin-bottom: 20px; }

.office__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.office__pair .office__figure { aspect-ratio: 3 / 2; }

@media (max-width: 767.98px) {
  .office__lead { aspect-ratio: 3 / 2; }
  .office__pair { grid-template-columns: 1fr; }
}

/* Single band, used on /vacancies between the intro and the openings. */
.photo-band { padding: 0 0 90px; }

.photo-band__figure {
  margin: 0;
  aspect-ratio: 21 / 9;
  overflow: hidden;
  background: var(--c-grey);
}

.photo-band__figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 767.98px) {
  .photo-band__figure { aspect-ratio: 3 / 2; }
}
