/*
 * Figma home — file OxLdQL2viiyVItpQXhIB0S
 * Hero frame 1:107 (1440x805) and "chosen by" strip 1:128.
 * Vertical rhythm reproduces the frame's absolute tops as flow margins.
 */

.fh {
  margin: 0;
  background: #fff;
  color: #000;
  font-family: Arial, Helvetica, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;

  /* The gap between one section and the next. The design's frame column gap is
     256px, which on a 805px-tall frame is a proportion and on a real page is
     most of a screen of nothing — the client read the bands as cliffhangers and
     asked for less air. 160px keeps the sections plainly separate at a
     desktop's height without the page pausing between them. One number, so the
     rhythm can be retuned in one place. */
  --fh-band: 160px;
  /* The logo bar's share of it — see .fh-chosen. A sibling has to read this,
     so it is declared here rather than on the band itself. */
  --fh-bar-band: calc(var(--fh-band) * 0.75);
  /* The brand's acid green, the one the live site's sticky bubble already
     carries. The page is otherwise black on white, so this is the only colour
     on it and it is spent where something is being asked of the reader. */
  --fh-acid: #bffe00;
}

.fh-shell {
  max-width: 1440px;
  margin: 0 auto;
  box-sizing: border-box;
}

/* ---------- nav — node 1:108 ---------- */

.fh-header { padding-top: 27px; }

.fh-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 55px;
  padding: 0 40px 0 41px;            /* node 1:108 x=41, right edge 1400 */
}

.fh-logo {                            /* node 1:109 — 254x55 */
  display: block;
  position: relative;
  flex-shrink: 0;
  width: 254px;
  height: 55px;
  overflow: hidden;
}

.fh-logo img {
  position: absolute;
  top: -0.06%;
  left: -5.12%;
  width: 105.12%;
  height: 100.11%;
  max-width: none;
  display: block;
}

.fh-nav ul {                          /* node 1:110 */
  display: flex;
  align-items: center;
  gap: 32.667px;
  margin: 0;
  padding: 0;
  list-style: none;
  white-space: nowrap;
}

.fh-nav a {
  display: block;
  position: relative;
  font-size: 18.667px;
  line-height: 28px;
  letter-spacing: -0.1867px;
  color: #000;
  text-decoration: none;
}

/* Nav hover: the line wipes in from the left, and on leave keeps travelling
   the same way — the left edge collapses toward the right, so it exits rather
   than rewinding. One pseudo-element, origin flipped between the two states.
   Positioned with `bottom`, not padding, so the nav's layout is untouched. */
.fh-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;                         /* nav keeps the finer rule */
  background: #000;
  transform: scaleX(0);
  transform-origin: right center;      /* leaving: collapse to the right */
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
  pointer-events: none;
}

.fh-nav a:hover::after,
.fh-nav a:focus-visible::after,
.fh-nav a[aria-current="page"]::after {
  transform: scaleX(1);
  transform-origin: left center;       /* entering: grow to the right */
}

@media (prefers-reduced-motion: reduce) {
  .fh-nav a::after { transition: none; }
}

/* ---------- hero — node 1:107 ---------- */

.fh-hero {
  /* The hero owns the first screen. border-box so the bottom padding counts
     inside the 100vh rather than adding to it. */
  box-sizing: border-box;
  /* The fixed header is paid for by the body's padding-top, so one screen of
     hero is that much less than the viewport. */
  min-height: calc(100vh - var(--fh-header-h, 82px));
  min-height: calc(100svh - var(--fh-header-h, 82px));
  display: flex;
  flex-direction: column;
  padding-bottom: clamp(32px, 5vh, 72px);

  /* Two things share this value. `gap` is the floor — the smallest breathing
     room the strip ever gets above and below. The auto margins below then split
     whatever is left of the screen equally between those same two gaps, so the
     section fills 100vh and the strip stays optically centred no matter how
     tall the viewport is. One number, and the two gaps cannot drift apart. */
  gap: var(--fh-strip-gap);
  --fh-strip-gap: clamp(28px, 4.4vh, 64px);
}

.fh-hero__title {                     /* node 1:127 — top 165, width 668 */
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-weight: 400;
  font-size: 47.636px;
  line-height: 55.762px;
  letter-spacing: -2.3818px;
  text-align: center;
  color: #000;
  width: 668px;
  max-width: calc(100% - 80px);
  /* auto on top here and on the strip below: whatever the screen has left over
     splits evenly between the two gaps, so the headline sits between the
     showreel and the disciplines however tall the viewport is. */
  margin: auto auto 0;
}

/* ---------- marquees ---------- */

.fh-marquee { overflow: hidden; }

.fh-marquee__track {
  display: flex;
  align-items: center;
  will-change: transform;
}

/* card marquee — node 1:116: 437 wide, gap 25.147 */
/* The showreel leads the page and the headline answers it — the client's
   arrangement, not the design's. The <h1> stays first in the document, where a
   screen reader and a crawler want it; only the paint order moves. Being first
   on screen, it takes a fixed offset from the header rather than a share of
   the spare height: the two shares now go to the gaps below it. */
.fh-marquee--cards {
  order: -1;
  margin-top: clamp(24px, 4.5vh, 64px);
}

.fh-marquee--cards .fh-marquee__track { gap: 25.147px; }

.fh-card {
  position: relative;
  flex-shrink: 0;
  /* JS fits exactly 3 across the strip; the vh cap only bites on viewports too
     short to show the strip and the disciplines under it at the design size.
     The width cap also bounds the height of the client's 874x572 films. */
  width: min(var(--fh-item-w, 437px), 72vh);
  /* Match the delivered films so their artwork stays uncropped. */
  aspect-ratio: 874 / 572;
  height: auto;
  background: #d9d9d9;
  opacity: 0.2;                        /* Figma: only the centre card is solid */
  transform: scale(1);
  margin-left: 0;
  margin-right: 0;
  transition: opacity 0.35s ease,
              transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
              margin 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* First paint only: the opening card is already focused, so its scale and the
   margins that reserve its room must not animate into place. */
.fh-marquee--cards.is-init .fh-card { transition: none; }

/* Active card — node 1:573. Inactive cards are 378 wide there and the active
   one 432.46, i.e. 1.1441x, and every gap in that frame stays 25.147 —
   so the layout genuinely reserves the extra room rather than the big card
   overlapping its neighbours. The scale is a transform (cheap, GPU) and the
   matching horizontal margin reserves the space it grows into: the card grows
   0.072x its width past each edge, so that is exactly the margin needed.
   Vertical centring comes from the track's align-items:center. */
.fh-card.is-focus {
  opacity: 1;
  transform: scale(1.1441);
  margin-left: calc(min(var(--fh-item-w, 437px), 72vh) * 0.072);
  margin-right: calc(min(var(--fh-item-w, 437px), 72vh) * 0.072);
}

/* room for the taller active card, and a grab cursor for the drag */
.fh-marquee--cards {
  padding: 26px 0;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
}

.fh-marquee--cards.is-dragging { cursor: grabbing; }

.fh-marquee--cards img { -webkit-user-drag: none; user-drag: none; }

/* Video sits exactly where the still does, so a card can hold either. */
.fh-card img,
.fh-card video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  max-width: none;
  display: block;
}

/* A played video's native poster does not return when it is rewound. Keep the
   selected artwork visible on inactive cards, including films with white intros. */
.fh-card--poster:not(.is-focus) video { opacity: 0; }

/* No hover treatment on the hero cards — both the second-artwork wipe and the
   scale-up were removed on request. */

/* discipline strip — node 1:122, held to the container */
/* Four words thrown to the four corners of a 1440px line read as four separate
   claims. Joined by a plus and set at reading size they read as one — which is
   what they are, and what the client asked for. */
.fh-cats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0 12px;
  width: 100%;
  max-width: 1440px;
  margin: auto auto 0;             /* the matching share — see .fh-hero */
  padding: 0 40px;
  box-sizing: border-box;
  list-style: none;
}

/* The join, drawn rather than written, so the list stays a list of four. */
.fh-cats li + li::before {
  content: "+";
  margin-right: 12px;
}

.fh-cats a {
  color: inherit;
  text-decoration: none;
  position: relative;
  display: inline-block;
}

/* Same wipe as the nav links, at the strip's weight. */
.fh-cats a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
  pointer-events: none;
}

.fh-cats a:hover::after,
.fh-cats a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

@media (prefers-reduced-motion: reduce) {
  .fh-cats a::after { transition: none; }
}

.fh-cats li {
  font-size: 20px;
  line-height: 26px;
  letter-spacing: -1px;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---------- chosen by — node 1:128 ---------- */
/* "Chosen by" — one row of client marks, at the client's request (2026-10-09):
   no lines between them and no name on hover, in their order of priority.
   The row never moves: when the marks do not fit they shrink together, and
   below the desktop they wrap. */
.fh-chosen {
  display: flex;
  align-items: center;
  max-width: 1440px;                   /* held to the container, like the strip above */
  /* Three quarters of the rhythm, top and bottom: given a full section's air
     on both sides the band read as a cliffhanger rather than as proof. */
  margin: var(--fh-bar-band) auto 0;
}

/* Scoped through .fh so it outranks the next section's own margin-top, which is
   declared later in this file at the same weight. */
.fh .fh-chosen + * { margin-top: var(--fh-bar-band); }

.fh-chosen__label {                    /* node 1:139 — left 40 */
  flex: none;
  box-sizing: border-box;
  padding: 0 0 0 40px;
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
  white-space: nowrap;
}

.fh-chosen__row {
  /* --fh-s scales every mark. */
  --fh-s: 1;
  flex: 1 1 0;
  min-width: 0;
  margin-right: 40px;
}

/* The marks spread across the row, at least one gap apart. */
.fh-chosen__track {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 48px;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* An empty first item, so space-between leaves the label the same gap before
   the first mark as the marks leave each other. Without it Lidl sat 41px off
   the label and the rest 130px apart. Only while the label sits beside the
   row. */
@media (min-width: 1024px) {
  .fh-chosen__track::before { content: ''; }
}

/* Too wide for the row, every mark gives up the same share of its width (a
   shrink in proportion to its basis), so they shrink together and keep their
   relative weights. */
.fh-clogo { flex: 0 1 auto; min-width: 0; }

/* Each mark is drawn at its own width, --w, worked out from its file's
   proportions in critical_figma_logo_box() so that a square and a long
   wordmark weigh about the same. The height follows from the file. */
.fh-clogo__mark {
  display: block;
  width: calc(var(--w, 90) * var(--fh-s) * 1px);
  max-width: 100%;
  height: auto;
}

/* Below about 1024px the label sits above and the row runs the full width. */
@media (max-width: 1023px) {
  .fh-chosen { flex-direction: column; align-items: stretch; }
  .fh-chosen__label { flex: none; padding: 0 40px 24px; }
  .fh-chosen__row { flex: none; margin: 0 40px; }
  /* Shrunk to one row they would be crumbs: below the desktop they wrap. */
  .fh-chosen__track { flex-wrap: wrap; justify-content: flex-start; gap: 28px 48px; }
  .fh-clogo { flex: none; }
}

@media (max-width: 640px) {
  .fh-chosen { margin-top: 96px; }
  .fh-chosen__label { padding: 0 20px 20px; }
  .fh-chosen__row { --fh-s: 0.8; margin: 0 20px; }
  /* The same 88px every other section is apart on a phone, not the desktop's
     three quarters of 160. */
  .fh .fh-chosen + * { margin-top: 88px; }
  .fh-chosen__track { column-gap: 36px; }
  /* Centred, with the label over them, and one even gap between marks: the
     wrapped rows read as a group rather than a line with a hole at its end. */
  .fh-chosen__label { text-align: center; }
  /* Two rows of three, each mark centred in a cell of its own with the same
     air on every side, so a square and a long wordmark sit on one grid. Only
     the first six show on a phone, in the client's order of priority. */
  .fh-chosen__track {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
  }
  .fh-clogo {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 72px;
    padding: 12px;
    box-sizing: border-box;
  }
  .fh-clogo:nth-child(n + 7) { display: none; }
  .fh-clogo__mark { max-height: 100%; object-fit: contain; }
}

@media (max-width: 480px) {
  /* The categories above end in their own air: 48px here reads as the same
     gap as the 88px below the marks. */
  .fh-chosen { margin-top: 48px; }
  .fh-chosen__label { font-size: 16px; letter-spacing: -0.8px; }
}

/* ---------- responsive ---------- */

@media (max-width: 1100px) {
  .fh-header__inner { padding: 0 24px; }
  .fh-nav ul { gap: 24px; }
  .fh-cats { padding: 0 24px; }
  .fh-marquee--cards { margin-top: clamp(20px, 3.5vh, 40px); }
}

@media (max-width: 820px) {
  .fh-logo { width: 200px; height: 43px; }
  .fh-nav a { font-size: 16px; line-height: 24px; }
  .fh-nav ul { gap: 18px; }
  .fh-hero__title { font-size: 34px; line-height: 40px; letter-spacing: -1.6px; }
  .fh-hero { --fh-strip-gap: 40px; }
  .fh-cats li { font-size: 18px; letter-spacing: -0.9px; }
  .fh-cats { gap: 0 10px; }
  .fh-cats li + li::before { margin-right: 10px; }
}

@media (max-width: 640px) {
  .fh-marquee--cards .fh-marquee__track { gap: 16px; }
  .fh-marquee--cards .fh-card:not(.is-focus) { opacity: 0.45; }
  .fh-header__inner {
    height: auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 0 20px;
  }
  .fh-nav ul { flex-wrap: wrap; gap: 14px 20px; }
  .fh-hero__title { max-width: calc(100% - 40px); }
  .fh-cats { gap: 0 10px; padding: 0 20px; }
  /* A phone's screen is too tall for three short things: filling it left the
     headline 130px of white above and below. Here the hero is only as tall as
     its content, and the next section shows on the first screen. */
  .fh-hero { min-height: 0; --fh-strip-gap: 56px; }

}

@media (max-width: 480px) {
  .fh-hero__title { font-size: 30px; line-height: 36px; letter-spacing: -1.3px; }
  .fh-cats { gap: 0 8px; }
  .fh-cats li + li::before { margin-right: 8px; }
  .fh-cats li { font-size: 16px; letter-spacing: -0.8px; }
}

/* ---------- challenges — nodes 1:141 / 1:374 / 1:386 ---------- */

.fh-chal {
  margin-top: var(--fh-band);                   /* frame 1:106 column gap */
  background: #fff;
  box-sizing: border-box;
}
/* The panels are absolutely positioned and add no height of their own, so the
   height of the one on show is reserved on .fh-chal__cols from JS. */

.fh-chal__inner {
  max-width: 1440px;
  margin: 0 auto;
  padding: 104px 40px 0;               /* heading at y=104 in frame 1:386 */
  box-sizing: border-box;
}

.fh-chal__heading {                    /* node 1:142 */
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
}

/* The absolutely positioned panel is measured against this full-width column,
   not against the 437px list — otherwise its left/right/width percentages
   resolve against the narrow list and it lands on top of the titles. */
.fh-chal__cols {
  position: relative;
  margin-top: 64.626px;                /* 196 - (104 + 27.374) */
  /* figma-home.js reserves the shown panel's height here. Two of the six
     challenges carry a case image and are five times the height of the others,
     so the section visibly opens and closes as you move down the list — eased
     rather than snapped, over roughly the length of the panel swap itself. */
  transition: min-height 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (prefers-reduced-motion: reduce) {
  .fh-chal__cols { transition: none; }
}

.fh-chal__list {                       /* node 1:143 — width 437, gap 4 */
  width: 437px;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.fh-chal__item { position: static; }

.fh-chal__title {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font-family: Inter, Arial, Helvetica, sans-serif;
  text-align: left;
  cursor: pointer;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-weight: 400;
  font-size: 47.636px;
  line-height: 55.762px;
  letter-spacing: -2.3818px;
  color: #000;
  opacity: 0.2;
  transition: opacity 0.4s ease;
}

.fh-chal__item.is-active .fh-chal__title { opacity: 1; }

/* right column — node 1:395 at x=732, aligned with the list top */
.fh-chal__panel {
  position: absolute;
  left: 692px;                         /* 732 - 40 gutter */
  top: 0;
  width: 668px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  visibility: hidden;
  transition: visibility 0s linear 0.5s;
}

.fh-chal__panel.is-active {
  visibility: visible;
  transition-delay: 0s;
}

/* Panel children are animated from JS (directional slide), so no CSS
   transitions here — they would fight the tween. */
.fh-chal__panel > * { opacity: 0; }

/* tags sit above the description in the markup, so order them explicitly */
.fh-chal__tags { order: 1; }
.fh-chal__desc { order: 2; }
.fh-chal__case { order: 3; }

.fh-chal__tags {                       /* node 1:397 — Inter 16/18, tracking -0.48 */
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  max-width: 412px;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  white-space: nowrap;
}

.fh-chal__desc {                       /* node 1:405 drew 24/33.283; see .fh-cases__copy */
  margin: 0;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.19px;
}

.fh-chal__case {                       /* node 1:161 — gap 32 under the description */
  display: flex;
  flex-direction: column;
  gap: 32px;
  margin-top: 64px;                    /* node 1:150 column gap 96 minus panel gap 32 */
}

.fh-chal__case-label {                 /* node 1:163 — Inter 16/18, tracking -0.48 */
  margin: 0;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
}

.fh-chal__case-media {                 /* node 1:166 — 668x481 */
  position: relative;
  width: 100%;
  aspect-ratio: 668 / 481;
  max-height: 40vh;                    /* keep the panel inside short viewports */
  background: #d9d9d9;
  overflow: hidden;
}

.fh-chal__case-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  max-width: none;
}

/* Node 1:166 carries -scale-y-100, so the design's own export is stored
   flipped; only that artwork gets flipped back. A real case cover doesn't. */
.fh-chal__case-media.is-flipped img { transform: scaleY(-1); }

a.fh-chal__case-media { display: block; }

.fh-chal__case-meta {                  /* node 1:167 — width 322 */
  display: flex;
  flex-direction: column;
  width: 322px;
  margin-top: -16px;                   /* node 1:165 gap is 16, not 32 */
}

.fh-chal__case-title {                 /* node 1:168 — Arial 24/33.283 */
  margin: 0;
  font-size: 24px;
  line-height: 33.283px;
  letter-spacing: -0.24px;
}

.fh-chal__case-tags {                  /* node 1:169 — Inter 16/18, opacity 0.34 */
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  opacity: 0.34;
}

/* fluid halves below the 1440 design width, same as the case grid */
@media (max-width: 1439px) {
  .fh-chal__list,
  .fh-chal__panel { width: calc((100% - 24px) / 2); }
  .fh-chal__panel { left: auto; right: 0; }
}

@media (max-width: 1100px) {
  .fh-chal__inner { padding: 80px 24px 0; }
}

/* stacked layout — no pinning, every panel visible under its own title */
@media (max-width: 820px) {
  .fh-chal { margin-top: 120px; }
  .fh-chal__inner { padding: 64px 20px 0; }
  .fh-chal__cols { margin-top: 40px; }
  .fh-chal__list { width: 100%; gap: 40px; }

  .fh-chal__title { font-size: 32px; line-height: 38px; letter-spacing: -1.6px; opacity: 1; }


  .fh-chal__panel {
    position: static;
    left: auto;
    right: auto;
    width: 100%;
    margin-top: 16px;
    visibility: visible;
    gap: 16px;
  }

  .fh-chal__panel > *,
  .fh-chal__panel.is-active > * {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .fh-chal__case { margin-top: 24px; gap: 16px; }
  .fh-chal__case-media { max-height: none; }
  .fh-chal__case-meta { width: 100%; margin-top: 0; }


  /* stacked, every title is its own heading rather than a jump target */
  .fh-chal__title { cursor: default; }
  .fh-chal__tags { max-width: 100%; white-space: normal; }
}

@media (max-width: 480px) {
  .fh-chal { margin-top: 88px; }
  .fh-chal__inner { padding: 48px 20px 0; }
  .fh-chal__heading { font-size: 16px; letter-spacing: -0.8px; }
  .fh-chal__cols { margin-top: 32px; }
  .fh-chal__list { gap: 32px; }
  .fh-chal__title { font-size: 27px; line-height: 32px; letter-spacing: -1.3px; }
  .fh-chal__case-title { font-size: 19px; line-height: 26px; }
}

/* ---------- solved by critical — node 1:174 ---------- */

.fh-cases { margin-top: var(--fh-band); }       /* frame 1:106 column gap */

/* The margins between sections are all --fh-band, but what the eye measures
   is ink to ink, and most sections end in air of their own: Chosen by's
   wall, the team's photo stack and its "hover here". Those gaps read as about
   260px. These three open straight after content that runs to its box's edge,
   so they read short (190, 139, 202) and are topped up to match. Desktop only:
   the narrower layouts set their own margins below. */
@media (min-width: 1101px) {
  /* Through .fh, to outrank each section's own margin-top further down. */
  .fh .fh-cases { margin-top: calc(var(--fh-band) + 72px); }
  .fh .fh-ideas { margin-top: calc(var(--fh-band) + 120px); }
  .fh .fh-team  { margin-top: calc(var(--fh-band) + 60px); }
}

.fh-cases__inner {                     /* node 1:175 — left 40, width 1360, gap 96 */
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 40px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 96px;
}

.fh-cases__grid {                      /* node 1:176 — gap 48 */
  display: flex;
  flex-direction: column;
  gap: 48px;
}

.fh-cases__row {                       /* nodes 1:177 / 1:195 / 1:213 */
  display: flex;
  justify-content: space-between;
  gap: 24px;
}

.fh-cases__intro {                     /* node 1:178 — 668 wide, gap 64 */
  display: flex;
  flex-direction: column;
  gap: 64px;
  width: 668px;
  flex-shrink: 0;
}

.fh-cases__eyebrow {                   /* node 1:180 — gap 8 */
  display: flex;
  gap: 8px;
  margin: 0;
  font-size: 28px;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
  white-space: nowrap;
}

.fh-mirror {                           /* node 1:182 — rotate(180) + scaleY(-1) */
  display: inline-block;
  transform: scaleX(-1);
}

/* node 1:183 drew this at Arial 28.433/33.283. The client wants every running
   paragraph on the page in one style, the education body's 19/24 (node 1:302),
   so the cases intro, the team copy and the programmes all read as one voice. */
.fh-cases__copy {
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.fh-cases__copy p {
  margin: 0;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.19px;
}

/* A shorter measure than the column the case cards set: at 668px a 19px line
   runs past a hundred characters. Phones keep the full width. */
@media (min-width: 821px) {
  .fh-cases__copy p { max-width: 80%; }
}

/* case card — nodes 1:186 / 1:196 / 1:205 / 1:214 / 1:223 */
.fh-case {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 668px;
  flex-shrink: 0;
}

.fh-case__media {                      /* 668x416 */
  position: relative;
  width: 100%;
  aspect-ratio: 668 / 416;
  background: #d9d9d9;
  overflow: hidden;
}

.fh-case__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  max-width: none;
}

/* A card that links to its case carries the whole card as the anchor. */
a.fh-case {
  color: inherit;
  text-decoration: none;
}

/* Hover artwork cross-fades over the cover — the same treatment the live
   listing gives its cards (app.css `.case-item .hover`). */
.fh-case__hover {
  opacity: 0;
  transition: opacity 0.3s ease-out;
}

a.fh-case:hover .fh-case__hover,
a.fh-case:focus-visible .fh-case__hover { opacity: 1; }

/* Further images of the case, shown one at a time in turn while the card is
   hovered — figma-home.js turns them on and off. They sit over the hover
   image, so one fading in over the last fading out is a cross-fade, and all
   of them off is the hover image again. */
.fh-case__slide {
  opacity: 0;
  transition: opacity 0.3s ease-out;
  pointer-events: none;
}

.fh-case__slide.is-on { opacity: 1; }

/* A clip stands in for the hover artwork where the case has one: same fade,
   with the cover underneath until the first frame is decoded. figma-home.js
   plays and rewinds it. */
.fh-case__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 0.3s ease-out;
  pointer-events: none;
}

a.fh-case:hover .fh-case__video,
a.fh-case:focus-visible .fh-case__video { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .fh-case__hover,
  .fh-case__slide,
  .fh-case__video { transition: none; }
}

.fh-case__meta {                       /* node 1:188 — width 322 */
  display: flex;
  flex-direction: column;
  width: 322px;
}

.fh-case__title {                      /* Arial 24/33.283 */
  margin: 0;
  font-size: 24px;
  line-height: 33.283px;
  letter-spacing: -0.24px;
}

.fh-case__tags {                       /* Inter 16/18, opacity 0.34, single line */
  display: flex;
  flex-wrap: nowrap;
  white-space: nowrap;
  gap: 8px;
  margin: 0;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  opacity: 0.34;
}

.fh-cases__all {                       /* node 1:231 — link-button, underlined */
  margin: 0;
  text-align: center;
}

.fh-cases__all a {
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 18px;
  line-height: 27px;
  letter-spacing: -0.54px;
  text-transform: uppercase;
  color: #000;
}

/* fluid columns below the 1440 design width */
@media (max-width: 1439px) {
  .fh-cases__intro,
  .fh-case { width: calc((100% - 24px) / 2); }
}

@media (max-width: 1100px) {
  .fh-cases__inner { padding: 0 24px; gap: 64px; }
  .fh-cases__intro { gap: 40px; }
}

@media (max-width: 820px) {
  .fh-cases { margin-top: 120px; }
  .fh-cases__inner { padding: 0 20px; gap: 48px; }
  .fh-cases__grid { gap: 40px; }

  .fh-cases__row { flex-direction: column; gap: 40px; }
  .fh-cases__intro,
  .fh-case { width: 100%; }

  .fh-cases__eyebrow { font-size: 18px; letter-spacing: -0.9px; }
  .fh-case { gap: 12px; }
  .fh-case__meta { width: 100%; }
  .fh-case__title { font-size: 19px; line-height: 26px; }
  .fh-case__tags { flex-wrap: wrap; white-space: normal; gap: 6px; }
}

@media (max-width: 480px) {
  .fh-cases { margin-top: 88px; }
  .fh-cases__inner { gap: 40px; }
  .fh-cases__grid { gap: 32px; }
  .fh-cases__row { gap: 32px; }
  .fh-cases__intro { gap: 24px; }
  .fh-cases__copy { gap: 20px; }
  .fh-cases__eyebrow { font-size: 16px; letter-spacing: -0.8px; }
  .fh-cases__all a { font-size: 17px; }
}

/* ---------- ideas — node 1:233 ---------- */

.fh-ideas { margin-top: var(--fh-band); }       /* frame 1:106 column gap */

.fh-ideas__inner {                     /* node 1:233 — left 40, width 1361, gap 64 */
  max-width: 1441px;
  margin: 0 auto;
  padding: 0 40px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 64px;
}

.fh-ideas__head {                      /* node 1:234 */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.fh-ideas__title {                     /* node 1:235 — width 438 */
  width: 438px;
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
}

.fh-ideas__links {                     /* node 1:236 — width 158, gap 16, right aligned */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 16px;
  width: 158px;
  margin: 0;
}

.fh-ideas__links a {
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 18px;
  line-height: 27px;
  letter-spacing: -0.54px;
  text-transform: uppercase;
  color: #000;
  white-space: nowrap;
}

.fh-ideas__grid {                      /* node 1:239 — gap 25 */
  display: flex;
  align-items: stretch;                /* equal-height cards, see __meta below */
  gap: 25px;
}

/* A card that links to its post carries the whole card as the anchor. */
a.fh-idea {
  color: inherit;
  text-decoration: none;
}

.fh-idea {                             /* node 1:240 — width 437, gap 24 */
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 437px;
  flex: 1 1 0;
  min-width: 0;
}

.fh-idea__media {                      /* node 1:242 — 437x303 */
  position: relative;
  width: 100%;
  aspect-ratio: 437 / 303;
  background: #d9d9d9;
  overflow: hidden;
}

.fh-idea__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  max-width: none;
}

.fh-idea__body {                       /* node 1:243 — gap 8 */
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
}

.fh-idea__title {                      /* Arial 24/33.283 */
  margin: 0;
  font-size: 24px;
  line-height: 33.283px;
  letter-spacing: -0.24px;
}

/* The source belongs to the headline above it, so it follows it at the body's
   own 8px step. It used to be pushed to the bottom of the card so the chips
   lined up across the row, but the cards stretch to the tallest title and a
   one-line headline then sat a whole line and a half above its own source —
   an alignment nobody reads, bought with a gap everybody does. */
.fh-idea__meta {                       /* node 1:245 — Inter 16/18, gap 16, opacity 0.7 */
  display: flex;
  gap: 16px;
  margin: 0;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  white-space: nowrap;
}

.fh-idea__meta span { opacity: 0.7; }

@media (max-width: 1100px) {
  .fh-ideas__inner { padding: 0 24px; gap: 48px; }
  .fh-ideas__title { width: auto; max-width: 438px; }
  .fh-ideas__grid { gap: 16px; }
  .fh-idea__title { font-size: 20px; line-height: 27px; }
}

@media (max-width: 820px) {
  .fh-ideas { margin-top: 120px; }
  .fh-ideas__inner { padding: 0 20px; gap: 40px; }
  .fh-ideas__head { flex-direction: column; align-items: flex-start; gap: 24px; }
  .fh-ideas__links { flex-direction: row; align-items: flex-start; width: auto; gap: 24px; }
  .fh-ideas__title { font-size: 18px; letter-spacing: -0.9px; }
  .fh-ideas__grid { flex-direction: column; gap: 40px; }
  .fh-idea { width: 100%; gap: 16px; }
  .fh-idea__title { font-size: 19px; line-height: 26px; }
  .fh-idea__meta { flex-wrap: wrap; gap: 8px 16px; white-space: normal; }
}

@media (max-width: 480px) {
  .fh-ideas { margin-top: 88px; }
  .fh-ideas__inner { gap: 32px; }
  .fh-ideas__title { font-size: 16px; letter-spacing: -0.8px; }
  .fh-ideas__links { gap: 20px; }
  .fh-ideas__links a { font-size: 17px; }
  .fh-ideas__grid { gap: 32px; }
}

/* ---------- a small team, a deep bench — node 1:263 ---------- */

.fh-team { margin-top: var(--fh-band); }        /* frame 1:106 column gap */

.fh-team__inner {                      /* node 1:263 — left 40, width 1361 */
  max-width: 1441px;
  margin: 0 auto;
  padding: 0 40px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
}

.fh-team__col {                        /* node 1:264 — width 554, gap 128 */
  display: flex;
  flex-direction: column;
  gap: 128px;
  width: 554px;
  flex-shrink: 0;
}

.fh-team__intro {                      /* node 1:266 — gap 32 */
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.fh-team__title {                      /* node 1:267 — Arial 28/27.374 */
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
}

.fh-team__copy {                       /* node 1:268 drew 24/33.283; see .fh-cases__copy */
  margin: 0;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.19px;
}

.fh-team__awards {                     /* node 1:269 — gap 64 */
  display: flex;
  flex-direction: column;
  gap: 64px;
}

.fh-team__awards-label {               /* node 1:270 */
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
}

/* The awards run as a strip, the same one the clients run in further up the
   page: the awarding body's mark with what it gave us set underneath, in the
   type the client names use. The design drew three 106px columns 82px apart,
   which fits "Edawards / 2025" and nothing longer — each award now carries a
   sentence, and three of those side by side in a 554px column is four words a
   line. Scrolling gives each one room instead. */
/* No height of its own: the track's tallest item sets it. A number here would
   be a guess at how many lines a claim wraps to, and that guess was already
   wrong once — the strip clips, and the clipped line is content. */
.fh-marquee--awards { width: 100%; }

.fh-marquee--awards .fh-marquee__track {
  gap: 56px;
  align-items: flex-start;
}

/* The mark sits over its words the way a client's name sits under its logo:
   both centred on the same axis, so a wide wordmark and a narrow symbol still
   hang from one line down the strip. */
.fh-award {                            /* node 1:272 */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;                           /* the same step the client names sit at */
  flex-shrink: 0;
  /* The gap between two awards is the track's gap plus whatever each box has
     left over around its centred lines, so an over-wide box reads as a bigger
     gap than the one set. At 260 the longest line of the shortest claim left
     99px spare and the strip looked spaced twice as far apart as it was. 200 is
     where the slack goes without costing a line: measured, every claim wraps to
     the same number of lines at 200 as it did at 260. */
  width: 200px;
  color: inherit;
  text-decoration: none;
  text-align: center;
}

/* Same box as a client's mark, so the two strips read as one family: a height
   with a width cap, which lets a symbol use the full height while a long
   wordmark reads at its length. */
.fh-award__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 31.981px;
}

.fh-award__mark img {
  display: block;
  width: auto;
  height: 100%;
  max-width: 132px;
  object-fit: contain;
}

/* One style for both — the body's name where it has no mark, and the claim —
   which is the client name's style, and that is the point: the two strips are
   the same strip. */
.fh-award__wordmark,
.fh-award__claim {
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.16px;
  text-transform: uppercase;
  text-wrap: balance;
}

/* the strip slows under the pointer; the award being read stays solid */
.fh-marquee--awards.is-hovering .fh-award { opacity: 0.2; transition: opacity 0.3s ease; }
.fh-marquee--awards .fh-award:hover,
.fh-marquee--awards .fh-award:focus-visible { opacity: 1; }

/* card stack — closed 1:287. Every card sits at the same point, which is the
   pile: the design drew them in an open fan (node 1:406) and carried each one
   back with a transform, but the fan no longer opens — figma-home.js shuffles
   the pile and trails the cursor with the cards instead — so the two halves of
   that arithmetic cancelled to one spot. Cards differ by their angle alone,
   which the block sets per card. */
.fh-stack {
  position: relative;
  width: 670px;
  max-width: 100%;
  aspect-ratio: 670 / 599;
  flex-shrink: 1;
}

.fh-stack__card {
  position: absolute;
  left: 33.955%;                       /* where every card in node 1:287 lands */
  top: 33.889%;
  display: block;
  width: 32.687%;                      /* 219 / 670 */
  height: 24.708%;                     /* 148 / 599 */
  max-width: none;
  object-fit: cover;
  will-change: transform;
}
/* No z-index here: source order paints the pile bottom to top before the
   script runs, and figma-home.js writes the order it wants from its first
   frame. One rule per card would otherwise have to grow with the photographs. */

/* cursor trail — one of the card images dropped wherever the pointer has
   travelled far enough (figma-home.js). Card-sized, centred on the pointer by
   its own transform, stacked above the pile and the hint. */
/* The trail is drawn here rather than inside .fh-stack, whose bounds used to
   cut the images off. Absolute at the top of the page, not fixed: the images
   are placed in page coordinates, so they stay where they were dropped and
   scroll away with the block instead of hanging on the screen. overflow-x:
   clip keeps an image at the right edge from widening the document, without
   turning the layer into a scroll box or cutting anything off vertically. */
.fh-stack__trail-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0;
  overflow-x: clip;
  pointer-events: none;
  z-index: 900;                        /* under the header (999) and cursor */
}

.fh-stack__trail {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: var(--fh-trail-w, 219px);     /* JS measures the live cards */
  height: var(--fh-trail-h, 148px);
  max-width: none;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}

.fh-stack__hint {                      /* node 1:291 — Inter 16/18, opacity 0.2 */
  position: absolute;
  left: 50.299%;
  top: 64.774%;
  transform: translateX(-50%);
  margin: 0;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  opacity: 0.2;
  /* Clear of the pile, whose cards are given 1..n inline — n being however many
     photographs the stack is holding. */
  z-index: 50;
  pointer-events: none;
}

@media (max-width: 1200px) {
  .fh-team__col { width: 46%; gap: 80px; }
  .fh-team__awards { gap: 40px; }
}

@media (max-width: 1100px) {
  .fh-team__inner { padding: 0 24px; }
}

@media (max-width: 820px) {
  .fh-team { margin-top: 120px; }
  .fh-team__inner { flex-direction: column; align-items: flex-start; gap: 56px; padding: 0 20px; }
  .fh-team__col { width: 100%; gap: 56px; }
  .fh-team__title,
  .fh-team__awards-label { font-size: 18px; letter-spacing: -0.9px; }

  /* awards share the row evenly instead of a fixed 106px each, so three
     still fit on a 320px screen */
  /* No room for a 128px name column beside the copy, so the two stack. */
  .fh-marquee--awards .fh-marquee__track { gap: 40px; }
  .fh-award { width: 184px; }

  /*
   * Card stack — redesigned for touch. The fan is a hover gesture with no
   * equivalent on a phone, and the 670x599 frame leaves most of a small screen
   * empty, so the five cards become a snap-scrolling strip that bleeds to the
   * right edge. JS leaves the stack alone below 821px (see figma-home.js).
   */
  .fh-stack {
    display: flex;
    gap: 12px;
    width: auto;
    order: -1;
    aspect-ratio: auto;
    align-self: stretch;
    margin-right: -20px;
    padding-right: 20px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  .fh-stack::-webkit-scrollbar { display: none; }

  .fh-stack__card {
    position: static;
    flex: 0 0 62%;
    width: auto;
    height: auto;
    aspect-ratio: 219 / 148;
    scroll-snap-align: start;
  }

  .fh-stack__hint,
  .fh-stack__trail,
  .fh-stack__trail-layer { display: none; }
}

@media (max-width: 480px) {
  .fh-team { margin-top: 88px; }
  .fh-team__inner { gap: 40px; }
  .fh-team__col { gap: 40px; }
  .fh-team__intro { gap: 20px; }
  .fh-team__awards { gap: 28px; }
  .fh-team__title,
  .fh-team__awards-label { font-size: 16px; letter-spacing: -0.8px; }
  .fh-marquee--awards .fh-marquee__track { gap: 32px; }
  .fh-award { width: 168px; gap: 12px; }
  .fh-stack { gap: 10px; }
  .fh-stack__card { flex-basis: 70%; }
}

/* ---------- fostering the ideas of the future — node 1:293 ---------- */

.fh-edu { margin-top: var(--fh-band); }

.fh-edu__inner {                       /* node 1:293 — left 41, width 1360, gap 128 */
  max-width: 1442px;
  margin: 0 auto;
  padding: 0 41px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 128px;
}

.fh-edu__title {                       /* node 1:295 — centred */
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
  text-align: center;
}

.fh-edu__list {                        /* node 1:296 — gap 32 */
  display: flex;
  flex-direction: column;
  gap: 32px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.fh-edu__item {
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding-bottom: 32px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);   /* node 1:303 */
}

.fh-edu__row {                         /* node 1:298 — gap 24 */
  display: flex;
  align-items: flex-start;
  gap: 24px;
}

/* One square for every institution, so a wide wordmark and an upright seal are
   measured against the same box rather than against each other. Nothing is
   drawn here — the square is the cell, and the mark is fitted inside it — but
   it is held even where there is no file, so the programme titles keep one
   left edge all the way down the list. */
.fh-edu__mark {
  display: flex;
  align-items: center;
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  /* The row's own 24px gap is what separates the two copy columns from each
     other. The mark wants more than that: it is artwork rather than another
     column, and at 24px it crowded the programme title. The margin buys it
     the extra on its own, so widening the mark's gap does not widen theirs. */
  margin-right: 40px;
}

/* The mark fills the square rather than sitting at whatever size it was drawn
   at — ISM ships at 90x40 and would otherwise be half the height of KTU's
   299x162 in the same cell. */
.fh-edu__logo {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: left center;
  display: block;
}

.fh-edu__lead {                        /* node 1:299 — gap 11 */
  display: flex;
  flex-direction: column;
  gap: 11px;
  flex: 1 1 0;
  min-width: 0;
}

/* The institution, named in words under the programme as it always was. The
   logo beside it is artwork, not a replacement for this line. */
.fh-edu__org {                         /* Inter 16/18 */
  margin: 0;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  opacity: 0.6;
}

/* The two copy columns shared 1360 evenly; they now share what the mark
   leaves, still evenly, so the row keeps reading as two columns of text. */
.fh-edu__name {                        /* Arial 24/33.283 */
  margin: 0;
  font-size: 24px;
  line-height: 33.283px;
  letter-spacing: -0.24px;
}

.fh-edu__body {                        /* node 1:302 — Arial 19/24 */
  flex: 1 1 0;
  min-width: 0;
  margin: 0;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.19px;
}

/* ---------- ready to get started — node 1:325 ---------- */

.fh-cta {
  /* The white above and below is this section's own breathing room, so it owns
     it as padding rather than as a gap between neighbours: the whole band is
     one invitation, one target, and the cursor reads it as one thing. The
     neighbour's own top gap is dropped in exchange, so nothing moves. */
  position: relative;
  margin-top: 0;
  padding-top: var(--fh-band);
  padding-bottom: var(--fh-band);
}
/* Scoped through .fh so it outranks the neighbour's own margin-top, which is
   declared later in this file at the same weight. */
.fh .fh-cta + * { margin-top: 0; }
/* Last section on the page: there is no neighbour to hand a gap over, and the
   footer already brings 12rem of its own. This is the rest of the 256. */
.fh-cta:last-of-type { padding-bottom: 136px; }

/* The whole band is the invitation, so the whole band is the link. A stretched
   anchor rather than a click handler, and hidden from assistive tech: the real
   "Get in touch" below stays the one link in the accessibility tree. */
.fh-cta__blanket {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.fh-cta__inner {                       /* gap 96, centred */
  position: relative;                  /* painted above the blanket */
  z-index: 1;
  /* Clicks pass straight through the copy to the blanket beneath, so the whole
     band behaves as one button rather than as a live edge around a dead centre.
     The real link takes its own events back below. */
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 96px;
  width: 100%;
  padding: 0 40px;
  box-sizing: border-box;
}

.fh-cta__copy {                        /* node 1:326 — gap 32 */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  max-width: 100%;                     /* the 436px children would otherwise
                                          push the page wider than the phone */
}

.fh-cta__title {                       /* node 1:328 — width 436, centred */
  width: 436px;
  max-width: 100%;
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
  text-align: center;
}

.fh-cta__sub {                         /* node 1:329 — Arial 19/24, width 436 */
  width: 436px;
  max-width: 100%;
  margin: 0;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.19px;
  text-align: center;
  text-wrap: balance;                  /* no word left alone on a phone */
}

.fh-cta__action { margin: 0; }
/* The one part of the copy that stays live: it is the real link, and the only
   one in the accessibility tree. */
.fh-cta__action a { pointer-events: auto; }

/* Every link-button on the Figma pages is Inter 18/27 — the size of the
   capabilities links (node 1:729). The home frames drew theirs at 24.3/27;
   those were brought down to match, so one size reads across the site. */
.fh-cta__action a {
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 18px;
  line-height: 27px;
  letter-spacing: -0.54px;
  text-transform: uppercase;
  color: #000;
}

/* ---------- your questions, answered — node 1:333 ---------- */

.fh-faq {
  margin-top: var(--fh-band);
  padding-bottom: 160px;
}

.fh-faq__inner {                       /* node 1:333 — left 40, width 1361 */
  max-width: 1441px;
  margin: 0 auto;
  padding: 0 40px;
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}

.fh-faq__aside {                       /* node 1:334 — width 437, gap 64 */
  display: flex;
  flex-direction: column;
  gap: 64px;
  width: 437px;
  flex-shrink: 0;
}

.fh-faq__title {                       /* node 1:335 */
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
}

.fh-faq__link { margin: 0; }

.fh-faq__link a {                      /* node 1:336 — link-button, underlined */
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 18px;
  line-height: 27px;
  letter-spacing: -0.54px;
  text-transform: uppercase;
  color: #000;
}

.fh-faq__list {                        /* node 1:337 — width 900, gap 32 */
  display: flex;
  flex-direction: column;
  gap: 32px;
  width: 900px;
  flex-shrink: 1;
  min-width: 0;
}

.fh-faq__item {
  display: flex;
  flex-direction: column;
  gap: 0;                              /* the panel's own padding carries the
                                          spacing, so it animates with the height
                                          instead of snapping when the panel hides */
  padding-bottom: 32px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);   /* node 1:343 */
}

/* The question sits in a heading for the outline, so it arrives bold from the
   UA sheet; the design has no bold anywhere. */
.fh-faq__q { margin: 0; font-weight: 400; }

.fh-faq__q button {                    /* node 1:339 — question + plus, spaced apart */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 400;
  font-size: 24px;
  line-height: 33.283px;
  letter-spacing: -0.24px;
  color: #000;
  text-align: left;
  cursor: pointer;
}

.fh-faq__icon {                        /* node 1:341 — 24x24 */
  display: block;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  color: #000;
}

.fh-faq__icon svg { display: block; }

.fh-faq__panel {
  overflow: hidden;
  will-change: height;
}

.fh-faq__panel p {
  margin: 0;
  padding-top: 32px;                   /* node 1:338 gap, inside the animated box */
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.19px;
  max-width: 668px;
}

/* no-JS fallback: panels are simply open */
.fh-faq__panel[hidden] { display: block; }
.fh-js .fh-faq__panel[hidden] { display: none; }

/* The copy columns share what is left of the row on their own now. The mark
   is the fixed part, so it is the part that has to give as the row narrows. */
@media (max-width: 1200px) {
  .fh-edu__mark { width: 56px; height: 56px; margin-right: 28px; }
}

@media (max-width: 1100px) {
  .fh-edu__inner { padding: 0 24px; gap: 80px; }
  .fh-faq__inner { padding: 0 24px; }
  .fh-faq__aside { width: 34%; }
  .fh-faq__list { width: 62%; }
}

@media (max-width: 820px) {
  .fh-edu { margin-top: 120px; }
  .fh-edu__inner { padding: 0 20px; gap: 48px; }
  .fh-edu__title,
  .fh-cta__title,
  .fh-faq__title { font-size: 18px; letter-spacing: -0.9px; }
  /* stacked: the mark sits above the copy, so it is a line of its own rather
     than a column, and it no longer has to reserve a column's width */
  .fh-edu__row { flex-direction: column; gap: 16px; }
  .fh-edu__mark { width: 48px; height: 48px; margin-right: 0; }
  .fh-edu__name { font-size: 19px; line-height: 26px; }

  /* Bottom padding kept on the last one too: the newsletter card follows it
     now, and without the padding Get in touch sat on the card's top edge. */
  .fh-cta { margin-top: 0; padding-top: 120px; padding-bottom: 120px; }
  .fh-cta:last-of-type { padding-bottom: 120px; }
  .fh-cta__inner { gap: 48px; padding: 0 20px; }
  .fh-cta__copy { gap: 24px; }

  .fh-faq { margin-top: 120px; padding-bottom: 96px; }
  .fh-faq__inner { flex-direction: column; gap: 48px; padding: 0 20px; }
  .fh-faq__aside { width: 100%; gap: 32px; }
  .fh-faq__list { width: 100%; gap: 24px; }
  .fh-faq__item { padding-bottom: 24px; }
  .fh-faq__q button { font-size: 19px; line-height: 26px; gap: 16px; align-items: flex-start; }
  .fh-faq__icon { margin-top: 1px; }
  .fh-faq__panel p { padding-top: 20px; }
}

@media (max-width: 480px) {
  .fh-edu { margin-top: 88px; }
  .fh-edu__inner { gap: 36px; }
  .fh-edu__list { gap: 24px; }
  .fh-edu__item { gap: 24px; padding-bottom: 24px; }
  .fh-edu__body,
  .fh-team__copy,
  .fh-chal__desc,
  .fh-cases__copy p { font-size: 17px; line-height: 23px; }

  .fh-cta { margin-top: 0; padding-top: 88px; padding-bottom: 88px; }
  .fh-cta:last-of-type { padding-bottom: 88px; }
  .fh-cta__inner { gap: 36px; }
  .fh-cta__copy { gap: 20px; }
  .fh-cta__sub { font-size: 17px; line-height: 23px; }
  .fh-cta__action a { font-size: 17px; }

  .fh-faq { margin-top: 88px; padding-bottom: 72px; }
  .fh-faq__inner { gap: 36px; }
  .fh-faq__aside { gap: 24px; }
  .fh-faq__link a { font-size: 17px; }
  .fh-faq__q button { font-size: 18px; line-height: 25px; }
  .fh-faq__panel p { font-size: 17px; line-height: 23px; }

  .fh-edu__title,
  .fh-cta__title,
  .fh-faq__title { font-size: 16px; letter-spacing: -0.8px; }
}


/* ---------- tablet ----------
   Between a phone and the 821px desktop layout there is room for two columns.
   Without this the grids drop straight from three-up to full-width stacking at
   820px, which leaves half the screen empty and the images enormous. */

@media (min-width: 561px) and (max-width: 820px) {
  .fh-cases__row { flex-direction: row; gap: 24px; }
  .fh-cases__intro,
  .fh-case { width: calc((100% - 24px) / 2); }

  .fh-ideas__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px 24px;
  }
  .fh-idea { width: auto; }

  .fh-stack__card { flex-basis: 40%; }
}

/* ---------- reveal on scroll ----------
   Same motion as the live theme (main.js + app.css): 30px rise, fade,
   0.8s ease-out, once. Hidden state is CSS so there is no flash before
   the script runs; ScrollTrigger does the reveal.                     */

.fh-js .fh-hero__title:not(.inviewed),
.fh-js .fh-cats > li:not(.inviewed),
.fh-js .fh-chosen__label:not(.inviewed),
.fh-js .fh-cases__eyebrow:not(.inviewed),
.fh-js .fh-cases__copy > p:not(.inviewed),
.fh-js .fh-case:not(.inviewed),
.fh-js .fh-cases__all:not(.inviewed),
.fh-js .fh-ideas__title:not(.inviewed),
.fh-js .fh-ideas__links:not(.inviewed),
.fh-js .fh-idea:not(.inviewed),
.fh-js .fh-team__title:not(.inviewed),
.fh-js .fh-team__copy:not(.inviewed),
.fh-js .fh-team__awards-label:not(.inviewed),
.fh-js .fh-marquee--awards:not(.inviewed),
.fh-js .fh-edu__title:not(.inviewed),
.fh-js .fh-edu__item:not(.inviewed),
.fh-js .fh-cta__title:not(.inviewed),
.fh-js .fh-cta__sub:not(.inviewed),
.fh-js .fh-cta__action:not(.inviewed),
.fh-js .fh-faq__title:not(.inviewed),
.fh-js .fh-faq__link:not(.inviewed),
.fh-js .fh-faq__item:not(.inviewed),
.fh-js .fs-hero__title:not(.inviewed),
.fh-js .fs-hero__lede:not(.inviewed),
.fh-js .fs-pillar:not(.inviewed),
.fh-js .fs-impact__title:not(.inviewed),
.fh-js .fs-chal__title:not(.inviewed),
.fh-js .fs-chal__nav:not(.inviewed),
.fh-js .fs-chal__card:not(.inviewed),
.fh-js .fs-caps__sticky > *:not(.inviewed),
.fh-js .fs-caps__group:not(.inviewed) {
  opacity: 0;
  transform: translateY(30px);
}

@media (prefers-reduced-motion: reduce) {
.fh-js .fh-hero__title,
.fh-js .fh-cats > li,
.fh-js .fh-chosen__label,
.fh-js .fh-cases__eyebrow,
.fh-js .fh-cases__copy > p,
.fh-js .fh-case,
.fh-js .fh-cases__all,
.fh-js .fh-ideas__title,
.fh-js .fh-ideas__links,
.fh-js .fh-idea,
.fh-js .fh-team__title,
.fh-js .fh-team__copy,
.fh-js .fh-team__awards-label,
.fh-js .fh-marquee--awards,
.fh-js .fh-edu__title,
.fh-js .fh-edu__item,
.fh-js .fh-cta__title,
.fh-js .fh-cta__sub,
.fh-js .fh-cta__action,
.fh-js .fh-faq__title,
.fh-js .fh-faq__link,
.fh-js .fh-faq__item,
.fh-js .fs-hero__title,
.fh-js .fs-hero__lede,
.fh-js .fs-pillar,
.fh-js .fs-impact__title,
.fh-js .fs-chal__title,
.fh-js .fs-chal__nav,
.fh-js .fs-chal__card,
.fh-js .fs-caps__sticky > *,
.fh-js .fs-caps__group {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* challenges heading joins the reveal; the list titles are handled in JS
   (y only) because their opacity encodes the active state. */
.fh-js .fh-chal__heading:not(.inviewed) {
  opacity: 0;
  transform: translateY(30px);
}

@media (prefers-reduced-motion: reduce) {
  .fh-js .fh-chal__heading {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---------- nav behaviour, matched to the live theme ----------
   Live: .header is fixed with a white backdrop; below 767.98px a .menu-trigger
   appears and .main-nav becomes a full-screen overlay toggled by
   body.active-menu, with the burger crossing into an X. Same behaviour here,
   keeping the Figma typography on desktop.                                  */

.fh-header {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  background: #fff;
  z-index: 999;
  transition: transform 0.3s ease-out;
}

/* Covers the strip above the bar so nothing shows through on an overscroll
   bounce. It was a solid (blur-free) box-shadow; a block element does the same
   job without the property. */
.fh-header::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 50px;
  background: #fff;
}

/* Live behaviour: scrolling down past 80px slides the bar away, scrolling
   up brings it back. Stays put while the mobile menu is open. */
.header-up:not(.active-menu) .fh-header {
  transform: translateY(-100%);
}

/* 27 + 55 — the height the header used to occupy before it became fixed. The
   body pads by it, and the hero subtracts it from 100vh, so one value keeps the
   first screen exactly one screen tall. */
.fh {
  --fh-header-h: 82px;
  padding-top: var(--fh-header-h);
}

.fh-menu-trigger { display: none; }

@media (max-width: 767.98px) {
  .fh { --fh-header-h: 70px; }

  /* The same white above the logo as below it: with the desktop's 27px on
     top and none underneath, the lockup sat on the bar's bottom edge. Still
     70px tall in all. */
  .fh-header { padding: 13.5px 0; }

  /* the burger replaces the inline links, so the bar stays a single row */
  .fh-header__inner {
    flex-direction: row;
    align-items: center;
    height: 43px;
    gap: 0;
  }

  .fh-menu-trigger {
    display: block;
    position: relative;
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    margin: 0 -10px 0 0; /* cancel right padding so the bars align with the shell */
    padding: 10px;
    border: 0;
    background: none;
    box-sizing: border-box;
    z-index: 20;
    cursor: pointer;
    user-select: none;
  }

  .fh-menu-trigger span {
    display: block;
    position: absolute;
    left: 10px;
    top: calc(50% - 1.5px);              /* the logo's ink centres half a pixel above the bar's */
    width: 28px;
    height: 2px;
    background: #000;
    transition: transform 0.3s ease-out, width 0.3s ease-out,
                left 0.3s ease-out, opacity 0.15s ease-out;
  }

  /* 11px either side of the middle line: the icon's top and bottom bars
     line up with the top of THE and the foot of CRITICAL beside it, so the two
     read as one row. At 9 it sat inside the lettering and looked low. */
  .fh-menu-trigger span:first-child { transform: translateY(-11px); }
  .fh-menu-trigger span:last-child { transform: translateY(11px); }

  /* Both shapes share the button's centre; opening cannot shift the icon. */
  .active-menu .fh-menu-trigger span { width: 36px; left: 6px; }
  .active-menu .fh-menu-trigger span:nth-child(1) { transform: rotate(45deg); }
  .active-menu .fh-menu-trigger span:nth-child(2) { opacity: 0; }
  .active-menu .fh-menu-trigger span:nth-child(3) { transform: rotate(-45deg); }

  .fh-nav {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    overflow: auto;
    padding: 100px 20px 20px;
    background: #fff;
    z-index: 5;
  }

  .active-menu .fh-nav { display: flex; }

  /* The logo stays on top of the open menu, as the close button does: the
     panel is still this site, and the logo is the way home. */
  .fh-logo { z-index: 6; }

  /* Set by figma-nav.js: .active-menu is dropped the moment you tap close, so
     the burger morphs back immediately, while this keeps the panel on screen
     for its fade-out. */
  .fh-nav.is-closing { display: flex; }

  .fh-nav ul {
    display: block;
    margin-top: auto;
    gap: 0;
  }

  .fh-nav a {
    display: inline-block;
    margin-top: 30px;
    font-size: 42px;
    line-height: 48px;
    letter-spacing: -1px;
  }

  .active-menu { overflow: hidden; }   /* live theme hides .body; locking the
                                          scroll achieves the same thing here */
}

@media (prefers-reduced-motion: reduce) {
  .fh-menu-trigger span { transition: none; }
}

/* WordPress admin bar. It is fixed at top:0 and forces html{margin-top:32px},
   so a fixed header must drop below it — the live theme does the same thing
   in header.php via .customize-support. */
body.admin-bar .fh-header,
.customize-support .fh-header { top: 32px; }

@media screen and (max-width: 782px) {
  body.admin-bar .fh-header,
  .customize-support .fh-header { top: 46px; }
}


/* reveal targets for the insights and how-we-work pages */
.fh-js .fi-title:not(.inviewed),
.fh-js .fi-filters:not(.inviewed),
.fh-js .fi-card:not(.inviewed),
.fh-js .fi-news:not(.inviewed),
.fh-js .fw-title:not(.inviewed),
.fh-js .fw-row:not(.inviewed) {
  opacity: 0;
  transform: translateY(30px);
}

@media (prefers-reduced-motion: reduce) {
.fh-js .fi-title,
.fh-js .fi-filters,
.fh-js .fi-card,
.fh-js .fi-news,
.fh-js .fw-title,
.fh-js .fw-row {
    opacity: 1 !important;
    transform: none !important;
  }
}


/* ---------- animated underline ----------
   The nav's line (.fh-nav a::after): 1px black, wiping in from the left on
   hover and carrying on out to the right on leave. These links add one thing
   the nav does not need: a resting grey rule at the same 1px, since a lone
   "Contact us" or "Subscribe" would otherwise read as plain text.           */

.fh-cases__all a,
.fh-ideas__links a,
.fh-cta__action a,
.fh-faq__link a,
.fs-caps__links a,
.fs-caps__item-link,
.fi-news__form button,
.fh-sub__form button,
.fh-uline {
  position: relative;
  display: inline-block;
  text-decoration: none;
  padding-bottom: 3px;
}

.fh-cases__all a::after,
.fh-ideas__links a::after,
.fh-cta__action a::after,
.fh-faq__link a::after,
.fs-caps__links a::after,
.fs-caps__item-link::after,
.fi-news__form button::after,
.fh-sub__form button::after,
.fh-uline::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: rgba(0, 0, 0, 0.2);
  pointer-events: none;
}

.fh-cases__all a::before,
.fh-ideas__links a::before,
.fh-cta__action a::before,
.fh-faq__link a::before,
.fs-caps__links a::before,
.fs-caps__item-link::before,
.fi-news__form button::before,
.fh-sub__form button::before,
.fh-uline::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: #000;
  transform: scaleX(0);
  transform-origin: right center;      /* leaving: collapse to the right */
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
  pointer-events: none;
}

.fh-cases__all a:hover::before,
.fh-cases__all a:focus-visible::before,
.fh-ideas__links a:hover::before,
.fh-ideas__links a:focus-visible::before,
.fh-cta__action a:hover::before,
.fh-cta__action a:focus-visible::before,
.fh-faq__link a:hover::before,
.fh-faq__link a:focus-visible::before,
.fs-caps__links a:hover::before,
.fs-caps__links a:focus-visible::before,
.fs-caps__item-link:hover::before,
.fs-caps__item-link:focus-visible::before,
.fi-news__form button:hover::before,
.fh-sub__form button:hover::before,
.fi-news__form button:focus-visible::before,
.fh-sub__form button:focus-visible::before,
.fh-uline:hover::before,
.fh-uline:focus-visible::before {
  transform: scaleX(1);
  transform-origin: left center;       /* entering: grow to the right */
}

@media (prefers-reduced-motion: reduce) {
.fh-cases__all a::before,
.fh-ideas__links a::before,
.fh-cta__action a::before,
.fh-faq__link a::before,
.fs-caps__links a::before,
.fs-caps__item-link::before,
.fi-news__form button::before,
.fh-sub__form button::before,
.fh-uline::before {
    transition: none;
  }
}

/* ---------- newsletter band ----------
   Rendered by critical_figma_subscribe() directly above the footer, on every
   Figma page that has not already shown the offer in its own content.

   Acid green, the same as the insights listing's newsletter cell — on a page
   that is otherwise black on white it is the one thing with a colour, which is
   the whole job the client gave it. The copy and form styles repeat that cell's
   rather than share them: .fi-news lives in figma-insights.css, which the home,
   services and how pages never load, and those are exactly the pages the band
   appears on. Keep the two in step by hand. */

/* A card held to the page's 40px margins rather than a band running edge to
   edge, at the client's request: the same square green block as the insights
   listing's newsletter cell, set on the white. */
.fh-sub {
  padding: 0 40px;
}

.fh-sub__inner {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 64px;
  max-width: 1360px;                   /* the 1440 container less its margins */
  margin: 0 auto;
  padding: 56px 48px;
  box-sizing: border-box;
  background: var(--fh-acid);
}

.fh-sub__copy {
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: 560px;
}

.fh-sub__title {                       /* as .fi-news__title */
  margin: 0;
  font-size: 28px;
  line-height: 27.374px;
  letter-spacing: -1.4px;
  text-transform: uppercase;
}

.fh-sub__body {
  margin: 0;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.19px;
}

/* The form and the line its result is read out in. */
.fh-sub__action {
  flex: 0 1 520px;
  min-width: 0;
}

.fh-sub__form {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px;
  box-sizing: border-box;
  /* Darker than the equivalent hairlines on white, where 0.2 black reads as a
     crease; on the green it reads as nothing. */
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
}

.fh-sub__form input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  color: #000;
}

.fh-sub__form input::placeholder { color: rgba(0, 0, 0, 0.6); }
/* Caps are the placeholder's label style; a typed address keeps its own case
   rather than reading as caps lock. */
.fh-sub__form input:not(:placeholder-shown),
.fi-news__form input:not(:placeholder-shown) { text-transform: none; }
.fh-sub__form input:focus { outline: none; }

.fh-sub__form button {
  flex-shrink: 0;
  /* No padding reset: the link-button rules above hand every one of these a hit
     area as padding cancelled by a negative margin. */
  border: 0;
  background: none;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: 18px;
  line-height: 27px;
  letter-spacing: -0.54px;
  text-transform: uppercase;
  color: #000;
  cursor: pointer;
}

/* Shared by both subscribe forms — the footer card here and the insights cell
   (.fi-news), which also loads this sheet. The result line sits under the
   form's rule, lined up with its text, and takes no room until it has
   something to say. */
.fh-news-status {
  margin: 12px 16px 0;
  font-size: 16px;
  line-height: 20px;
  letter-spacing: -0.16px;
  color: #000;
}
.fh-news-status:empty { display: none; }
/* A finger needs more than the 18px line the field is on a desktop. */
@media (hover: none) {
  .fh-sub__form input,
  .fi-news__form input { min-height: 44px; }
}
/* Same type as the success line; the colour alone says it went wrong. A deep
   red rather than a bright one: it has to read on the acid green as well. */
.fh-news-status.is-error { color: #b3001b; }

[data-newsletter].is-busy button { opacity: 0.45; cursor: progress; }

/* The honeypot: in the form for bots to fill in, out of sight for people. */
.fh-hp {
  position: absolute !important;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* The Get in touch bubble rides the bottom-right corner (120px, 36px in), so
   the card keeps that column clear and the button never passes under it. */
@media (min-width: 1024px) {
  .fh-sub__inner { padding-right: 176px; }
}

/* Below the desktop the copy sits over the form. Side by side, with the
   bubble's column held clear as well, the field was 29px wide at 768. */
@media (max-width: 1023.98px) {
  .fh-sub__inner { flex-direction: column; align-items: stretch; gap: 32px; }
  .fh-sub__copy { max-width: none; }
  .fh-sub__action { flex: 0 0 auto; }
}

@media (max-width: 767.98px) {
  .fh-sub { padding: 0 20px; }
  .fh-sub__inner { flex-direction: column; align-items: stretch; gap: 32px; padding: 32px 24px; }
  .fh-sub__copy { max-width: none; }
  .fh-sub__action { flex: 0 0 auto; }

  /* On a phone the form is a field over a button, on the copy's own edge: the
     desktop's 16px inset and the rule under the whole row made the field a
     faint word floating 16px in from everything above it. The rule moves to
     the field itself, the field gets a thumb's height, and focus darkens the
     rule since there is no outline. Both newsletter cards share this, scoped
     through the card so it outranks figma-insights.css, which loads later. */
  .fh-sub .fh-sub__form,
  .fi-news .fi-news__form {
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
    padding: 0;
    border: 0;
  }
  .fh-sub .fh-sub__form input,
  .fi-news .fi-news__form input {
    flex: 0 0 auto;
    width: 100%;
    min-height: 48px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.3);
    border-radius: 0;
    transition: border-color 0.2s ease;
  }
  .fh-sub .fh-sub__form input:focus,
  .fi-news .fi-news__form input:focus { border-bottom-color: #000; }
  /* The field's type: one caps style for the field and its button. */
  .fh-sub .fh-sub__form button,
  .fi-news .fi-news__form button {
    align-self: flex-start;
    font-size: 16px;
    line-height: 18px;
    letter-spacing: -0.48px;
  }
  .fh-news-status { margin: 12px 0 0; }
}

@media (max-width: 479.98px) {
  .fh-sub__title { font-size: 22px; letter-spacing: -1.1px; }
  .fh-sub__body { font-size: 17px; line-height: 23px; }
}

/* The four Figma templates do not load app.css, so the label the band's input
   is named by has nothing to hide it. figma-insights.css carries its own copy
   for the page that loads it first. */
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- smooth scroll — Lenis (figma-scroll.js) ----------
   The stock rules from the Lenis docs; Lenis sets the classes on <html>. */
html.lenis,
html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: clip; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* ---------- click targets ---------- */
/*
 * Text is the smallest thing on the page and the easiest to miss, so every link
 * gets a hit area larger than its own glyphs. Two techniques, because the right
 * one depends on what the element has spare:
 *
 *   nav links   — ::before is free, so an overlay does it. This leaves the
 *                 element's own box measuring the word, which is what the
 *                 underline cursor sizes itself from.
 *   link-buttons — ::before is the hover rule and ::after the static one, both
 *                 spoken for, so padding does the work and an equal negative
 *                 margin cancels it out of the layout. Their two rules are
 *                 offset by the same amount so they stay exactly where they
 *                 were, against the text rather than the padding edge.
 *
 * The cursor decides its state from elementFromPoint().closest(), so this box
 * is also what says how early the cursor reacts — widening it makes the effect
 * start before the pointer is on the word, which is the point.
 *
 * What stops it growing is the next link along: two hit areas must never meet,
 * or a link would take the cursor while the pointer is over its neighbour. So
 * the budget is generous by default — most link-buttons stand alone — and only
 * the crowded rows below rein it back in, each to half the gap it has.
 */
.fh { --fh-hit-x: 32px; --fh-hit-y: 16px; }

.fh-nav          { --fh-hit-x: 16px; }   /* row, 32.667px apart */
.fh-ideas__links { --fh-hit-y: 8px; }    /* column, 16px apart */
.fs-caps__links  { --fh-hit-x: 12px; }   /* row, 24px apart */
.fs-caps__item   { --fh-hit-y: 12px; }   /* rows 24px apart */
.fi-news__form   { --fh-hit-x: 16px; }   /* the form's own inner edge */
.fh-sub__form    { --fh-hit-x: 16px; }   /* same form, in the footer band */

/* These have to sit here rather than with the layout rules that tighten the
   gaps, because they set the same custom property on the same selector: the
   media query does not raise specificity, so anything declared after it wins
   whatever the viewport. Each one halves as the gap it answers to halves. */
/* Below the full desktop the gutter is 24px, and a 32px reach past the edge
   made the page 8px wider than a landscape phone. */
@media (max-width: 1279px) {
  .fh-ideas__links,
  .fs-caps__item { --fh-hit-x: 20px; }
}

@media (max-width: 1100px) {
  .fh-nav { --fh-hit-x: 12px; }          /* gap 24px */
}

@media (max-width: 820px) {
  .fh-nav { --fh-hit-x: 9px; }           /* gap 18px */
  /* the ideas links turn into a row here, so the two ceilings swap over */
  .fh-ideas__links { --fh-hit-x: 12px; --fh-hit-y: 16px; }
}

/* Below this the nav is the full-screen menu, not a row: 42px links stacked
   30px apart with nothing beside them, so the ceiling is vertical only and
   the tap target matters more than the cursor, which does not run on a coarse
   pointer at all. */
@media (max-width: 767.98px) {
  .fh-nav { --fh-hit-x: 20px; --fh-hit-y: 15px; }
  /* The phone form stacks the button on the copy's edge, so it has no inner
     edge to reach into sideways. */
  .fi-news__form,
  .fh-sub__form { --fh-hit-x: 0px; }
}

.fh-nav a::before {
  content: "";
  position: absolute;
  top: calc(var(--fh-hit-y) * -1);
  right: calc(var(--fh-hit-x) * -1);
  bottom: calc(var(--fh-hit-y) * -1);
  left: calc(var(--fh-hit-x) * -1);
}

.fh-cases__all a,
.fh-ideas__links a,
.fh-cta__action a,
.fh-faq__link a,
.fs-caps__links a,
.fs-caps__item-link,
.fi-news__form button,
.fh-sub__form button {
  padding: var(--fh-hit-y) var(--fh-hit-x) calc(var(--fh-hit-y) + 3px);
  margin: calc(var(--fh-hit-y) * -1) calc(var(--fh-hit-x) * -1);
}

.fh-cases__all a::after,
.fh-ideas__links a::after,
.fh-cta__action a::after,
.fh-faq__link a::after,
.fs-caps__links a::after,
.fs-caps__item-link::after,
.fi-news__form button::after,
.fh-sub__form button::after,
.fh-cases__all a::before,
.fh-ideas__links a::before,
.fh-cta__action a::before,
.fh-faq__link a::before,
.fs-caps__links a::before,
.fs-caps__item-link::before,
.fi-news__form button::before,
.fh-sub__form button::before {
  left: var(--fh-hit-x);
  right: var(--fh-hit-x);
  bottom: var(--fh-hit-y);
}

/* ---------- phone pass ----------
   Declared last so it outranks the per-section responsive rules above. */
@media (max-width: 820px) {
  /* The plus trails each discipline rather than leading the next, so a
     wrapped line never starts with "+". */
  .fh .fh-cats li + li::before { content: none; }
  .fh .fh-cats li:not(:last-child)::after { content: "+"; margin-left: 8px; }

  /* No one word alone on the last line of a title or a short paragraph. */
  .fw-row__title,
  .fw-row__sub,
  .fi-card__title,
  .fh-idea__title,
  .fh-case__title,
  .fh-sub__body,
  .fi-news__body,
  .fh-chal__desc,
  .fh-edu__body { text-wrap: pretty; }

  /* Section titles at the newsletter card's title size: at 16px they were the
     same size as the tags and read as chips, not as the heads of sections. */
  .fh .fh-chosen__label,
  .fh .fh-chal__heading,
  .fh .fh-cases__eyebrow,
  .fh .fh-ideas__title,
  .fh .fh-team__title,
  .fh .fh-team__awards-label,
  .fh .fh-edu__title,
  .fh .fh-cta__title,
  .fh .fh-faq__title {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: -1.1px;
    text-wrap: balance;
  }

  /* One small caps style for everything under them. Tags and meta were Inter
     16 at -0.48 beside Arial 16 at -0.8: two caps styles 1px of tracking
     apart, which reads as a mistake rather than a hierarchy. */
  .fh .fh-chal__tags,
  .fh .fh-chal__case-label,
  .fh .fh-chal__case-tags,
  .fh .fh-case__tags,
  .fh .fh-idea__meta,
  .fh .fh-edu__org,
  .fh .fh-award__claim {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 16px;
    line-height: 20px;
    letter-spacing: -0.8px;
    text-wrap: balance;
  }
  /* Names of cases and programmes at the body size: at 19 beside 17 they
     were two styles 2px apart. They lead their blocks by place and ink. */
  .fh .fh-chal__case-title,
  .fh .fh-case__title,
  .fh .fh-edu__name { font-size: 17px; line-height: 23px; letter-spacing: -0.19px; }
  /* Link-buttons at the caps size too. */
  .fh .fh-cases__all a,
  .fh .fh-ideas__links a,
  .fh .fh-cta__action a,
  .fh .fh-faq__link a { font-size: 16px; line-height: 18px; letter-spacing: -0.48px; }

  /* Every other heading on a phone is on the left edge with its content. */
  .fh .fh-edu__title { text-align: left; width: auto; margin-left: 0; }

  /* The section's own top padding stacked on the band's gap: 136px of white
     under the logos against 88 everywhere else. */
  .fh .fh-chal__inner { padding-top: 0; }

  /* Challenges, folded (figma-home.js): six titles with a plus, the first
     open. Fully open they were three screens of copy, and the titles looked
     like buttons that did nothing. Same control as the capabilities list on
     the services page. */
  .fh-chal--folded .fh-chal__list { gap: 0; }
  .fh-chal--folded .fh-chal__item { border-top: 1px solid rgba(0, 0, 0, 0.2); }
  .fh-chal--folded .fh-chal__item:last-child { border-bottom: 1px solid rgba(0, 0, 0, 0.2); }
  .fh-chal--folded .fh-chal__title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    padding: 20px 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .fh-chal--folded .fh-chal__title::after {
    content: "+";
    flex: none;
    font-size: 28px;
    line-height: 1;
    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .fh-chal--folded .fh-chal__item.is-open .fh-chal__title::after { transform: rotate(45deg); }
  .fh-chal--folded .fh-chal__item:not(.is-open) .fh-chal__panel:not(.is-folding) { display: none; }
  .fh-chal--folded .fh-chal__panel { margin-top: 0; padding-bottom: 32px; }

  /* The team strip: an <img> flex item will not shrink below its own width
     unless told, so every card came out at the file's 438px and filled the
     screen with no neighbour peeking in to say it scrolls. */
  .fh-stack__card { min-width: 0; object-fit: cover; }

  /* Under the title and copy it illustrates, not above them: the column is
     unwrapped so the strip can sit between the copy and the awards. */
  .fh .fh-team__col { display: contents; }
  .fh .fh-team__intro { order: 0; }
  .fh .fh-stack { order: 1; }
  .fh .fh-team__awards { order: 2; }

  /* Edge to edge and centred: the photo in the middle with a neighbour
     peeking in on both sides. figma-home.js copies the photos on either side
     so it runs on both ways and opens with a neighbour on the left too. */
  .fh .fh-stack {
    width: calc(100% + 40px);
    max-width: none;
    margin: 0 -20px;
    padding: 0;
  }
  .fh .fh-stack__card { flex: 0 0 70vw; scroll-snap-align: center; }

  /* Awards hold still on a phone (figma-home.js leaves the strip alone): three
     claims crawling past at 168px a column were four lines each and clipped
     mid-word at the edge. A list instead: the mark, and its claim beside it. */
  .fh-marquee--awards .fh-marquee__track { flex-direction: column; gap: 20px; transform: none !important; }
  .fh-marquee--awards .fh-award {
    flex-direction: row;
    align-items: center;
    gap: 20px;
    width: auto;
    text-align: left;
  }
  .fh-marquee--awards .fh-award__mark { flex: 0 0 96px; justify-content: flex-start; }
  .fh-marquee--awards .fh-award__mark img { max-width: 96px; }
  .fh-marquee--awards.is-hovering .fh-award { opacity: 1; }
}

/* A tablet in portrait shows the strip's photos at half the width. */
@media (min-width: 561px) and (max-width: 820px) {
  .fh .fh-stack__card { flex-basis: 44vw; }
}

/* One display style on a phone and a tablet: the hero line, the open menu,
   the challenge and impact titles, the page titles and the How we work rows
   were Inter at 25, 27, 30 and 32, and the menu Arial at 42 - five sizes of
   one voice. Prefixed with .fh so it holds on the pages whose own sheets load
   after this one. */
@media (max-width: 820px) {
  .fh .fh-hero__title,
  .fh .fh-chal__title,
  .fh .fs-hero__title,
  .fh .fs-impact__name,
  .fh .fs-chal__card-title,
  .fh .fi-title,
  .fh .fw-title,
  .fh .fw-row__title {
    font-family: Inter, Arial, Helvetica, sans-serif;
    font-size: 28px;
    line-height: 34px;
    letter-spacing: -1.2px;
  }
}

@media (max-width: 767.98px) {
  .fh .fh-nav a {
    font-family: Inter, Arial, Helvetica, sans-serif;
    font-size: 28px;
    line-height: 34px;
    letter-spacing: -1.2px;
    margin-top: 24px;
  }
}

/* The strip's copies only exist for the phone's loop. */
@media (min-width: 821px) {
  .fh-stack__card.is-clone { display: none; }
}

/* A strip that drifts with the page (figma-scroll.js) has no photo to settle
   on: snapping would tug it back to one face after every swipe. */
.is-drifting { scroll-snap-type: none !important; }
