/* ===========================================================================
   landing.css — the home page, and only the home page
   ---------------------------------------------------------------------------
   The home page's hero and the sections under it. Its header is not here: the
   centred-wordmark header this file used to own is now the header every page
   wears, so it lives in components.css and is rendered from one NAV_ITEMS
   list in site.js. This file is loaded nowhere else.

   The teal in the design arrives through the artwork rather than by re-tinting
   the palette. Everything here still runs on the existing tokens — the forest
   greens, the champagne rules, the Playfair and Outfit pairing — which is what
   keeps the home page and the interior pages reading as one site rather than
   two.
   =========================================================================== */

/* ═══════════════════════════════════════════════════════════════════════════
   1. HERO
   ---------------------------------------------------------------------------
   The plate is 1486x720. It used to be a full-bleed backdrop behind the type,
   which meant object-fit: cover had to stretch it to whatever the viewport
   was — on a 1600px screen that is a 1.08x upscale before device pixel ratio,
   and past 2x it fell apart.

   So it is not a backdrop any more. Text and image are two columns of one
   grid, neither overlapping the other, and the image is a plain <img> that
   renders at its own size: width auto, capped by max-width, never told to
   fill anything. The grid tops out at 1400px, so the image column tops out
   near 760px — comfortably under the plate's native 1486px, which means the
   browser is always sampling down. Downsampling is sharp; upsampling is not.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The ground the practices sit on. Barely separated from the page — enough
   that the wave has something to be the edge of, not enough to read as a band. */
:root { --lp-shore: color-mix(in srgb, var(--forest-100) 42%, var(--bg)); }
:root[data-theme="dark"] { --lp-shore: color-mix(in srgb, var(--forest-900) 58%, var(--bg)); }

/* How far the plate is held back from the left edge of the viewport — the one
   dial for how tightly the hero is framed. Larger insets zoom out.

   The right edge stays flush, always: the plate's water runs off that corner
   and a gap there would read as a cut. Only the left is inset, and the left is
   the end the mask has already faded to nothing, so nothing visible is lost.

   The figure carries the plate's own 1486/720 and takes its height from its
   width, so cover never crops and the dial is free to go as wide as you like:
   the whole scene is on screen at every setting, just smaller. Past roughly
   9vw the plate stops reaching the hero's full height and floats, which is why
   all four edges feather rather than only two. */
:root { --lp-plate-inset: clamp(0px, 16vw, 340px); }

.lp-hero {
  position: relative;
  overflow: clip;
  /* The figure is out of flow now, so it contributes no height and the hero
     would collapse to the height of the paragraph — cropping the basin to a
     letterbox. This is the plate's own height, which is also the point past
     which cover would begin upscaling. */
  min-block-size: clamp(560px, 44vw, 720px);
  display: flex;
  align-items: center;
  padding-block: clamp(var(--space-lg), 6vw, var(--space-2xl));
}

.lp-hero__grid {
  inline-size: 100%;
  max-inline-size: 1400px;
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(var(--space-sm), 4vw, var(--space-lg));
  align-items: center;
}

/* The plate paints one continuous scene 1486x720: a ribbon field that sweeps in
   from the left edge, the basin it feeds on the right, and a soft wave band that
   runs the full width along the bottom. Its left third is deliberately empty —
   that is where the type was always meant to sit.

   So the plate is laid across the whole hero rather than cropped to the basin.
   Cropping to the right 756px is what used to make it read as a picture placed
   on the page: the ribbons were discarded, the band survived only on the right,
   and the basin came out over-scaled and clipped at the viewport edge.

     inline-size 100% + object-fit cover means the crop is always vertical, so
     the full painted width — ribbons, basin, band — is on screen at every
     viewport. Only the top and bottom margins of the plate are trimmed, and
     the plate is nearly empty there.
   --------------------------------------------------------------------------- */
.lp-hero__figure {
  position: absolute;
  inset-block: 0;
  inset-inline: var(--lp-plate-inset) 0;
  /* Height from the aspect ratio, then centred in whatever the hero's height
     happens to be. auto margins against two zero insets is what centres it. */
  margin-block: auto;
  block-size: auto;
  aspect-ratio: 1486 / 720;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  /* Two masks, intersected.

     Across: the words sit over the plate's empty third, which is dimmed rather
     than cut, so the ribbons carry on behind them as a whisper instead of
     stopping on a line. The ramp is long and reaches full strength only at 72%,
     which also matters for the plate's one flaw — it carries a faint vertical
     seam at source x=720, i.e. 48.5% across. Held under half opacity there, the
     step has nothing like enough contrast left to read as an edge.

     Down: the band at the plate's foot dissolves into the shore colour that
     .lp-practices carries, so the hero ends in water rather than on the straight
     line where one section stops and the next starts. */
  mask-image:
    linear-gradient(to right,
      transparent 0,
      rgba(0, 0, 0, 0.26) 24%,
      rgba(0, 0, 0, 0.46) 44%,
      rgba(0, 0, 0, 0.78) 58%,
      #000 72%),
    linear-gradient(to bottom,
      transparent 0,
      #000 8%,
      #000 58%,
      rgba(0, 0, 0, 0.55) 84%,
      transparent 100%);
  mask-composite: intersect;
  -webkit-mask-image:
    linear-gradient(to right,
      transparent 0,
      rgba(0, 0, 0, 0.26) 24%,
      rgba(0, 0, 0, 0.46) 44%,
      rgba(0, 0, 0, 0.78) 58%,
      #000 72%),
    linear-gradient(to bottom,
      transparent 0,
      #000 8%,
      #000 58%,
      rgba(0, 0, 0, 0.55) 84%,
      transparent 100%);
  -webkit-mask-composite: source-in;
}

.lp-hero__art {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Slightly above centre: the plate carries more dead space under the band
     than over the basin's crown, so the trim is worth spending downward. */
  object-position: 50% 44%;
  /* The plate is drawn on a cool white, the page is warm cream, so even a
     well-masked edge leaves a faint panel sitting on the ground. multiply
     makes white the identity colour — white x cream = cream — so the plate's
     background disappears into the page completely and only the artwork is
     left. Nothing is faked with opacity, so the basin keeps its full colour. */
  mix-blend-mode: multiply;
}

.lp-hero__col { position: relative; z-index: 2; max-inline-size: 34rem; }

/* The organisation panel, back in the hero. Its backdrop-filter is the reason
   it belongs here rather than anywhere else on the page: sitting over the
   plate's dimmed left third, it frosts the ribbons behind it instead of
   covering them, so it reads as glass laid on the artwork rather than as a
   second card competing with it. Slightly narrower than the column so it
   stops short of the lede's measure. */
.lp-hero__col .locator {
  max-inline-size: 33rem;
  margin-block-start: clamp(var(--space-sm), 2.4vw, var(--space-md));
}

.lp-hero__name {
  font-family: var(--font-display);
  font-size: clamp(3.5rem, 8vw, 6.5rem);
  font-weight: var(--weight-medium);
  line-height: 0.95;
  letter-spacing: 0.01em;
  color: var(--text-strong);
}

.lp-hero__lede {
  margin-block-start: var(--space-sm);
  font-size: var(--step-1);
  line-height: 1.68;
  color: var(--text-muted);
}

.lp-hero__actions {
  margin-block-start: var(--space-md);
  display: flex;
  flex-wrap: wrap;
  gap: 13px;
}

/* --- Hero buttons -------------------------------------------------------- */

.btn--lp {
  border-radius: 11px;
  padding: 14px 24px;
  font-size: var(--step--1);
  letter-spacing: 0.005em;
}

.btn--lp-primary {
  --btn-fg: #ffffff;
  --btn-border: transparent;
  --btn-bg: linear-gradient(178deg,
            color-mix(in srgb, var(--brand-cta) 94%, #ffffff),
            color-mix(in srgb, var(--brand-cta) 84%, #04231a));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    0 12px 26px -14px rgba(9, 40, 30, 0.75);
}

.btn--lp-primary:hover {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.36),
    0 16px 32px -14px rgba(9, 40, 30, 0.8),
    var(--glow-brand);
}

.btn--lp-primary .btn__arrow { transition: transform var(--dur-mid) var(--ease-out); }
.btn--lp-primary:hover .btn__arrow { transform: translateX(3px); }

.btn--lp-ghost {
  --btn-fg: var(--text-strong);
  --btn-border: color-mix(in srgb, var(--border-strong) 72%, transparent);
  --btn-bg: color-mix(in srgb, var(--surface) 86%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), var(--elev-1);
}

.btn--lp-ghost:hover {
  --btn-border: var(--brand-soft-border);
  --btn-fg: var(--brand-text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), var(--elev-2);
}

/* --- Narrow ---------------------------------------------------------------
   One column, image beneath the words. Still never upscaled: below about
   760px the column is narrower than the plate, so it keeps sampling down. */

@media (max-width: 900px) {
  /* Stacked. The desktop min-height exists only to give the out-of-flow figure
     room; in flow it sizes itself, and leaving it on just adds dead space. */
  .lp-hero {
    display: block;
    min-block-size: auto;
    padding-block-start: var(--space-lg);
  }

  .lp-hero__grid { grid-template-columns: minmax(0, 1fr); }
  .lp-hero__col { max-inline-size: none; }

  /* Back in flow and full width, at the plate's own 2.06:1 — the whole scene,
     read as a banner under the words. Both ends feather so it still ends in
     water rather than on a border. */
  .lp-hero__figure {
    position: static;
    order: 2;
    margin: var(--space-md) auto 0;
    inline-size: 100%;
    block-size: auto;
    aspect-ratio: 1486 / 720;
    /* All four edges feather here, not just the sides. Stacked, the plate has
       page above it and page below it, so a hard top and bottom is what turns
       it back into a rectangle sitting on the layout. mask-composite from the
       base rule still applies, so these two intersect. */
    mask-image:
      linear-gradient(to right, transparent 0, #000 10%, #000 91%, transparent 100%),
      linear-gradient(to bottom, transparent 0, #000 13%, #000 82%, transparent 100%);
    -webkit-mask-image:
      linear-gradient(to right, transparent 0, #000 10%, #000 91%, transparent 100%),
      linear-gradient(to bottom, transparent 0, #000 13%, #000 82%, transparent 100%);
  }
}

/* --- Dark -----------------------------------------------------------------
   Inverting and rotating the hue back through 180 degrees returns roughly the
   original greens and teals on a dark field, which this plate survives well
   because it is nearly all mid-tone water and foliage. */

:root[data-theme="dark"] .lp-hero__art {
  /* multiply over an obsidian ground would erase the plate outright */
  mix-blend-mode: normal;
  filter: invert(1) hue-rotate(180deg) brightness(0.94) saturate(1.2);
  opacity: 0.86;
}

/* ═══════════════════════════════════════════════════════════════════════════
   2. SERVICE CARDS
   ═══════════════════════════════════════════════════════════════════════════ */

.lp-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(278px, 1fr));
  gap: var(--space-sm);
}

.lp-card {
  --card-accent: var(--brand);
  position: relative;
  overflow: hidden;
  display: grid;
  align-content: start;
  gap: var(--space-2xs);
  padding: var(--space-sm);
  border-radius: var(--radius-xl);
  border: var(--hairline) solid color-mix(in srgb, var(--border-soft) 88%, transparent);
  background:
    radial-gradient(120% 88% at 0% 0%,
      color-mix(in srgb, var(--card-accent) 5%, transparent), transparent 62%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--surface) 97%, transparent),
      color-mix(in srgb, var(--surface-2) 92%, transparent));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 1px 2px rgba(23, 22, 20, 0.03),
    0 22px 48px -30px rgba(23, 22, 20, 0.35);
  transition: transform var(--dur-mid) var(--ease-out),
              box-shadow var(--dur-mid) var(--ease-out),
              border-color var(--dur-mid) var(--ease-out);
}

.lp-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--card-accent) 26%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 2px 4px rgba(23, 22, 20, 0.04),
    0 32px 64px -30px rgba(23, 22, 20, 0.42);
}

/* The accent bar. Inset rather than full-bleed so it reads as part of the
   rounded card and not as a lid sitting on top of it. */
.lp-card::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 14%;
  block-size: 2.5px;
  border-radius: 0 0 var(--radius-full) var(--radius-full);
  background: linear-gradient(90deg,
    transparent,
    var(--card-accent) 22%,
    var(--card-accent) 78%,
    transparent);
  opacity: 0.85;
}

.lp-card__icon {
  inline-size: 48px;
  block-size: 48px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  color: var(--card-accent);
  background: color-mix(in srgb, var(--card-accent) 9%, transparent);
  border: var(--hairline) solid color-mix(in srgb, var(--card-accent) 20%, transparent);
}

.lp-card__icon svg { inline-size: 25px; block-size: 25px; }

.lp-card__no {
  position: absolute;
  inset-block-start: var(--space-sm);
  inset-inline-end: var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--card-accent) 52%, transparent);
}

.lp-card__title {
  margin-block-start: var(--space-3xs);
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: var(--weight-bold);
  letter-spacing: -0.01em;
  color: var(--text-strong);
}

.lp-card__body {
  font-size: var(--step--1);
  line-height: var(--leading-body);
  color: var(--text-muted);
}

.lp-card__list {
  margin: var(--space-3xs) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 10px;
  border-block-start: var(--rule) solid color-mix(in srgb, var(--border-soft) 80%, transparent);
  padding-block-start: var(--space-2xs);
}

.lp-card__list li {
  position: relative;
  padding-inline-start: 19px;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--text-muted);
}

.lp-card__list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.6em;
  inline-size: 5px;
  block-size: 5px;
  border-radius: var(--radius-full);
  background: var(--card-accent);
  opacity: 0.6;
}

/* --- Per-card accents ---------------------------------------------------- */

.lp-card--research   { --card-accent: var(--brand); }
.lp-card--advisory   { --card-accent: var(--accent); }
.lp-card--innovation { --card-accent: var(--champagne-600, var(--warm)); }


/* --- The practices section, lifted ----------------------------------------
   It used to be a sunk band starting well below the hero, which left a dead
   stripe of page between the artwork and the first card. The band is gone and
   the section is pulled up so the cards rise into the bottom of the wave
   field, which ties the two together the way the reference did.

   The reference put the section heading *after* the cards to make that overlap
   work. That orphans the heading — you meet three cards before being told what
   they are — so the heading stays on top here and the lift is sized to clear
   it: the hero's lower left is empty ground at every width, which is exactly
   where the heading lands. */

.lp-practices {
  position: relative;
  z-index: 2;
  margin-block-start: clamp(-72px, -4vw, -34px);
  padding-block-start: clamp(var(--space-sm), 3vw, var(--space-md));
  /* Not a flat fill. This section is lifted into the hero, and a solid colour
     starting at its own top edge draws exactly the straight line across the
     page that the plate's dissolving foot was meant to avoid — and covers the
     wave besides, since this carries z-index 2. Fading the shore in over its
     first stretch means the water above and the ground below meet in a wash
     instead of a border. The last stop holds, so everything past it is solid. */
  background: linear-gradient(to bottom,
    transparent 0,
    color-mix(in srgb, var(--lp-shore) 55%, transparent) clamp(46px, 5vw, 84px),
    var(--lp-shore) clamp(104px, 11vw, 190px));
}

/* Closes the gap from the other side so the lift does not have to do all of it. */
.lp-hero { padding-block-end: clamp(var(--space-md), 4vw, var(--space-xl)); }

@media (max-width: 900px) {
  /* Stacked, the artwork ends on its own faded edge and there is nothing to
     rise into — the overlap would just crowd the heading. */
  .lp-practices { padding-block-start: var(--space-md); }
}

/* --- The wave band at the hero's foot --------------------------------------
   Two strokes of the same swell, the back one slower and fainter, so the edge
   between the hero and the practices below it is water rather than a margin.
   The cards sit above it — .lp-practices carries z-index 2 — so they read as
   floating on the surface rather than beginning a new section.

   Vector on purpose: this is the one part of the wave field that can be sharp
   at any resolution, which the plate itself never will be. */

.lp-hero__wave {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 0;
  inline-size: 100%;
  block-size: clamp(58px, 7vw, 104px);
  display: block;
  pointer-events: none;
}

.lp-hero__wave-back {
  fill: color-mix(in srgb, var(--lp-shore) 62%, var(--forest-200));
}

.lp-hero__wave-front {
  /* identical to .lp-practices, so the fill runs on unbroken past the svg */
  fill: var(--lp-shore);
}

/* On the dark ground the same two tints would disappear; these sit just above
   the background instead of just below the page white. */
:root[data-theme="dark"] .lp-hero__wave-back {
  fill: color-mix(in srgb, var(--lp-shore) 60%, var(--forest-800));
}

:root[data-theme="dark"] .lp-hero__wave-front {
  fill: var(--lp-shore);
}
