/* Northest — design system
   Ink canvas, tight grotesque type, media cards, pill buttons.
   Ships in dark and light; the palette follows the device setting.
   Brand palette: navy #3F5B81, ink #090C11, sky #6F9FDD, mist #DAE1EB,
   cream #EADBBE, forest #46684D, orange #F37042. */

/* ---------------------------------------------------------------- tokens */

/* Dark is the base palette. Every colour below is overridden in the
   prefers-color-scheme: light block — nothing else in this file hardcodes
   the canvas colours. */

:root {
  --bg: #090c11;
  --fg: #ffffff;
  --muted: #a3abb8;
  --faint: #7a828f;
  --line: rgba(218, 225, 235, 0.14);
  --line-soft: rgba(218, 225, 235, 0.08);
  --surface: #10151d;
  --surface-2: #18202b;

  /* translucent header once scrolled */
  --header-bg: rgba(9, 12, 17, 0.72);
  /* soft hover wash on ghost buttons and nav pills */
  --hover-soft: rgba(218, 225, 235, 0.08);

  /* reversed pair — primary button, selection, skip link */
  --contrast-bg: #ffffff;
  --contrast-fg: #090c11;
  --contrast-bg-hover: #dae1eb;

  --prose-fg: #e3e7ee;
  --footer-link: #cfd5df;

  /* the mark SVG is white artwork; flip it on a light canvas */
  --logo-filter: none;

  --page: 1440px;
  --gutter: 20px;
  --nav-h: 64px;
  --radius: 10px;
  --radius-lg: 20px;

  --section-y: clamp(56px, 8vw, 104px);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #ffffff;
    --fg: #090c11;
    --muted: #5b6472;
    --faint: #6b7380;
    --line: rgba(9, 12, 17, 0.16);
    --line-soft: rgba(9, 12, 17, 0.09);
    --surface: #f4f6f9;
    --surface-2: #e9edf3;

    --header-bg: rgba(255, 255, 255, 0.72);
    --hover-soft: rgba(9, 12, 17, 0.06);

    --contrast-bg: #090c11;
    --contrast-fg: #ffffff;
    --contrast-bg-hover: #3f5b81;

    --prose-fg: #1a1f27;
    --footer-link: #353d49;

    --logo-filter: invert(1);
  }
}

@media (min-width: 768px) {
  :root { --gutter: 32px; --nav-h: 68px; }
}

@media (min-width: 1280px) {
  :root { --gutter: 48px; }
}

/* ---------------------------------------------------------------- reset */

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

* { margin: 0; padding: 0; }

html {
  background: var(--bg);
  color-scheme: light dark;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: "Inter", ui-sans-serif, -apple-system, BlinkMacSystemFont,
    "Segoe UI", Helvetica, "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  font-feature-settings: "cv05" 1, "cv08" 1, "ss03" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

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

a { color: inherit; }

ul, ol { list-style: none; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

::selection { background: var(--contrast-bg); color: var(--contrast-fg); }

:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 3px;
  border-radius: 4px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--contrast-bg);
  color: var(--contrast-fg);
  transform: translateY(-200%);
}

.skip-link:focus { transform: none; }

/* ---------------------------------------------------------------- layout */

.wrap {
  width: 100%;
  max-width: var(--page);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }

/* anchors clear the sticky bar */
[id] { scroll-margin-top: calc(var(--nav-h) + 20px); }

.section--tight { padding-block: clamp(40px, 5vw, 72px); }

.rule {
  border: 0;
  border-top: 1px solid var(--line-soft);
}

/* ---------------------------------------------------------------- type */

h1, h2, h3, h4 {
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-wrap: balance;
}

.display {
  font-size: clamp(2.125rem, 7.6vw, 4.25rem);
  line-height: 1.06;
  letter-spacing: -0.03em;
}

.h1 {
  font-size: clamp(1.875rem, 6.6vw, 3.25rem);
  line-height: 1.07;
  letter-spacing: -0.03em;
}

.h2 {
  font-size: clamp(1.1875rem, 4.4vw, 1.75rem);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.025em;
}

.h3 {
  font-size: clamp(1.0625rem, 1.8vw, 1.1875rem);
  letter-spacing: -0.022em;
}

.lede {
  font-size: clamp(1rem, 3.7vw, 1.125rem);
  line-height: 1.5;
  letter-spacing: -0.011em;
  color: var(--muted);
  text-wrap: pretty;
}

.eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  font-size: clamp(0.875rem, 3.2vw, 0.9375rem);
  letter-spacing: -0.005em;
  color: var(--faint);
}

.eyebrow strong {
  font-weight: 400;
  color: var(--fg);
}

.center { text-align: center; }

.center .eyebrow { justify-content: center; }

.stack > * + * { margin-top: var(--stack, 24px); }

/* ---------------------------------------------------------------- header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: transparent;
  transition: background 0.25s var(--ease), backdrop-filter 0.25s var(--ease);
}

.site-header.is-stuck {
  background: var(--header-bg);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: var(--nav-h);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: clamp(1.0625rem, 4vw, 1.1875rem);
  font-weight: 700;
  letter-spacing: -0.032em;
  text-decoration: none;
}

.wordmark img {
  width: auto;
  height: 1.05em;
  filter: var(--logo-filter);
}

.nav-links {
  display: none;
  align-items: center;
  gap: 4px;
}

.nav-links a {
  padding: 8px 12px;
  border-radius: 999px;
  font-size: 0.9375rem;
  letter-spacing: -0.008em;
  color: var(--muted);
  text-decoration: none;
  transition: color 0.18s var(--ease), background 0.18s var(--ease);
}

.nav-links a:hover,
.nav-links a[aria-current="page"] {
  color: var(--fg);
  background: var(--hover-soft);
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-right: -10px;
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  color: var(--fg);
  transition: opacity 0.18s var(--ease), background 0.18s var(--ease);
}

.icon-btn:hover { opacity: 0.65; }

.icon-btn svg {
  width: 21px;
  height: 21px;
  stroke: currentColor;
}

@media (min-width: 900px) {
  .nav-links { display: flex; }
}

/* ---- language switch ---- */

/* Sits in the header on every screen size, so it never hides in the menu.
   The current language is plain text; only the other one is a link. */
.lang-switch {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-right: 6px;
  font-size: 0.875rem;
  letter-spacing: 0.01em;
}

.lang-switch a,
.lang-switch [aria-current] {
  padding: 8px 4px;
}

.lang-switch a {
  color: var(--muted);
  text-decoration: none;
  transition: color 0.18s var(--ease);
}

.lang-switch a:hover { color: var(--fg); }

.lang-switch [aria-current] { color: var(--fg); }

.lang-switch__sep { color: var(--faint); }

/* ---- slide-over menu ---- */

.menu {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: grid;
  grid-template-rows: var(--nav-h) 1fr;
  background: var(--bg);
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.22s var(--ease), visibility 0.22s var(--ease);
}

.menu[data-open="true"] {
  visibility: visible;
  opacity: 1;
}

/* The panel fades in over a page of the same colour, so on its own the fade
   is invisible and opening reads as an instant jump. The groups carry the
   motion instead: they rise and settle in sequence, which is the part the eye
   actually registers. The delays apply only while opening, so closing
   collapses at once rather than unwinding. */

.menu__group {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}

.menu[data-open="true"] .menu__group {
  opacity: 1;
  transform: none;
}

.menu[data-open="true"] .menu__group:nth-child(1) { transition-delay: 0.05s; }
.menu[data-open="true"] .menu__group:nth-child(2) { transition-delay: 0.1s; }
.menu[data-open="true"] .menu__group:nth-child(3) { transition-delay: 0.15s; }
.menu[data-open="true"] .menu__group:nth-child(4) { transition-delay: 0.2s; }

@media (prefers-reduced-motion: reduce) {
  .menu__group { opacity: 1; transform: none; }
  .menu[data-open="true"] .menu__group { transition-delay: 0s; }
}

.menu__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: var(--page);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.menu__body {
  overflow-y: auto;
  padding: 24px var(--gutter) 64px;
  width: 100%;
  max-width: var(--page);
  margin: 0 auto;
}

.menu__group + .menu__group {
  margin-top: 32px;
  padding-top: 32px;
  border-top: 1px solid var(--line-soft);
}

.menu__label {
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 12px;
}

.menu__body a {
  display: block;
  padding: 9px 0;
  font-size: 1.1875rem;
  font-weight: 500;
  letter-spacing: -0.026em;
  text-decoration: none;
}

.menu__body a:hover { color: var(--muted); }

body.is-locked { overflow: hidden; }

/* ---- search overlay ---- */

.search {
  position: fixed;
  inset: 0;
  z-index: 160;
  background: var(--bg);
  display: grid;
  grid-template-rows: auto 1fr;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.18s var(--ease), visibility 0.18s var(--ease);
}

.search[data-open="true"] {
  visibility: visible;
  opacity: 1;
}

.search__bar {
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--nav-h);
  border-bottom: 1px solid var(--line-soft);
}

.search__bar svg {
  flex: none;
  width: 22px;
  height: 22px;
  stroke: var(--muted);
}

.search__bar input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: 0;
  background: none;
  color: var(--fg);
  font: inherit;
  font-size: 1rem;
  letter-spacing: -0.01em;
  outline: none;
}

.search__bar input::placeholder { color: var(--faint); }

.search__results {
  overflow-y: auto;
  padding: 12px var(--gutter) 64px;
}

.search__results a {
  display: block;
  padding: 18px 0;
  border-bottom: 1px solid var(--line-soft);
  text-decoration: none;
}

.search__results a:hover { opacity: 0.7; }

.search__results h2 {
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: -0.018em;
}

.search__results p {
  margin-top: 4px;
  font-size: 0.9375rem;
  color: var(--faint);
}

.search__empty {
  padding: 24px 0;
  color: var(--faint);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 46px;
  padding: 0 22px;
  border-radius: 999px;
  font-size: clamp(0.875rem, 3.3vw, 0.9375rem);
  font-weight: 500;
  letter-spacing: -0.012em;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.18s var(--ease), color 0.18s var(--ease),
    border-color 0.18s var(--ease), transform 0.18s var(--ease);
}

.btn:active { transform: scale(0.985); }

.btn--primary {
  background: var(--contrast-bg);
  color: var(--contrast-fg);
}

.btn--primary:hover { background: var(--contrast-bg-hover); }

.btn--ghost {
  border: 1px solid var(--line);
  color: var(--fg);
}

.btn--ghost:hover {
  background: var(--hover-soft);
  border-color: transparent;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.hero .btn-row { flex-wrap: nowrap; }

@media (max-width: 420px) {
  .hero .btn { padding: 0 18px; }
}

.center .btn-row { justify-content: center; }

/* ---------------------------------------------------------------- section head */

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: clamp(24px, 3vw, 40px);
}

.view-all {
  flex: none;
  align-self: center;
  font-size: 0.875rem;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--faint);
  text-decoration: none;
  transition: color 0.18s var(--ease);
}

.view-all:hover { color: var(--muted); }

/* ---------------------------------------------------------------- rails & grids */

.rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 72%;
  gap: 16px;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  padding-inline: var(--gutter);
  margin-inline: calc(-1 * var(--gutter));
  scrollbar-width: none;
}

.rail::-webkit-scrollbar { display: none; }

.rail > * { scroll-snap-align: start; }

@media (min-width: 600px) {
  .rail { grid-auto-columns: 46%; }
}

@media (min-width: 1024px) {
  .rail {
    grid-auto-flow: row;
    grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
    gap: 24px 24px;
    overflow: visible;
    padding-inline: 0;
    margin-inline: 0;
  }
}

.grid {
  display: grid;
  gap: 24px;
}

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

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

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

/* ---------------------------------------------------------------- cards */

.card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  color: inherit;
  text-decoration: none;
}

.card__media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 1 / 1;
  background: var(--surface-2);
}

.card__media--wide { aspect-ratio: 16 / 10; }

.card__media > * {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease);
}

.card:hover .card__media > * { transform: scale(1.03); }

.card__title {
  font-size: clamp(1.0625rem, 4.2vw, 1.1875rem);
  font-weight: 400;
  line-height: 1.22;
  letter-spacing: -0.02em;
  text-wrap: pretty;
}

.card:hover .card__title { color: var(--muted); }

.card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin-top: auto;
  padding-top: 4px;
  font-size: clamp(0.8125rem, 3.1vw, 0.875rem);
  letter-spacing: -0.005em;
  color: var(--faint);
}

.card__meta span:first-child { color: var(--fg); }

.card__body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}

/* ---- panel card (text only, bordered) ---- */

.panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 22px 20px 24px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: inherit;
  text-decoration: none;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease);
}

a.panel:hover {
  background: var(--surface-2);
  border-color: var(--line);
}

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

.panel p {
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--muted);
  letter-spacing: -0.008em;
  text-wrap: pretty;
}

/* ---------------------------------------------------------------- product cards */

/* One card per product, each carrying its own palette. These are the only
   blocks on the site that do not follow the light/dark tokens: a product's
   colour is the offer's, not the page's, so the pair is set locally and
   holds in both schemes. Every derived value (dimmed copy, rules, button
   wash) is mixed from that pair, so a new product needs two hex codes and
   nothing else. Every pair is taken from the Northest palette. */

/* The same mechanics as .rail, kept separate because this one never collapses
   into rows: a product card is tall and the artwork bleeds off its bottom
   edge, so a stacked grid of them turns the section into a wall. It stays a
   horizontal scroller at every width, and the track is always cut off before
   the last card so the scroll is visible without a scrollbar. */
.products {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 86%;
  gap: 16px;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  padding-inline: var(--gutter);
  margin-inline: calc(-1 * var(--gutter));
  scrollbar-width: none;
}

.products::-webkit-scrollbar { display: none; }

.products > * { scroll-snap-align: start; }

@media (min-width: 600px) {
  .products { grid-auto-columns: 62%; }
}

@media (min-width: 1024px) {
  .products {
    grid-auto-columns: 46%;
    gap: 24px;
  }
}

.product {
  --pc-bg: var(--surface);
  --pc-fg: var(--fg);
  /* 74% keeps the secondary copy above 4.5:1 on every card below. */
  --pc-dim: color-mix(in srgb, var(--pc-fg) 74%, var(--pc-bg));
  --pc-line: color-mix(in srgb, var(--pc-fg) 20%, transparent);
  --pc-wash: color-mix(in srgb, var(--pc-fg) 9%, transparent);
  --pc-wash-hover: color-mix(in srgb, var(--pc-fg) 16%, transparent);

  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border-radius: 26px;
  background: var(--pc-bg);
  color: var(--pc-fg);
}

.product--workshops { --pc-bg: #dae1eb; --pc-fg: #090c11; }
.product--projects  { --pc-bg: #3f5b81; --pc-fg: #ffffff; --pc-dim: color-mix(in srgb, #ffffff 82%, #3f5b81); }
.product--agents    { --pc-bg: #eadbbe; --pc-fg: #090c11; }
.product--next      { --pc-bg: #46684d; --pc-fg: #ffffff; --pc-dim: color-mix(in srgb, #ffffff 82%, #46684d); }

.product__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
  padding: clamp(24px, 3.4vw, 34px) clamp(22px, 3.2vw, 34px) 0;
}

.product__lockup {
  display: flex;
  align-items: center;
  gap: 12px;
}

.product__icon {
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: 23%;
  box-shadow: inset 0 0 0 1px var(--pc-line);
}

/* The offer name stands in for a wordmark, so it is set like the Northest
   one: same weight and tracking, scaled up. */
.product__name {
  font-size: clamp(1.75rem, 5.6vw, 2.375rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.038em;
}

.product__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: clamp(0.9375rem, 3.4vw, 1rem);
  letter-spacing: -0.012em;
}

.product__meta svg {
  flex: none;
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
}

/* The facts read as a short timeline: a rule down the left, a ring per item. */
.product__facts {
  display: grid;
  gap: 12px;
  margin-left: 8px;
  padding-left: 26px;
  border-left: 1px solid var(--pc-line);
}

.product__facts li {
  position: relative;
  font-size: clamp(0.9375rem, 3.4vw, 1rem);
  line-height: 1.4;
  letter-spacing: -0.012em;
  color: var(--pc-dim);
  text-wrap: pretty;
}

.product__facts li::before {
  content: "";
  position: absolute;
  left: -29px;
  top: 0.5em;
  width: 6px;
  height: 6px;
  border: 1px solid currentColor;
  border-radius: 50%;
}

.product__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  margin-top: 4px;
  padding: 0 20px;
  border-radius: 999px;
  background: var(--pc-wash);
  color: inherit;
  font-size: clamp(0.875rem, 3.3vw, 0.9375rem);
  font-weight: 500;
  letter-spacing: -0.012em;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.18s var(--ease), transform 0.18s var(--ease);
}

.product__cta:hover { background: var(--pc-wash-hover); }

.product__cta:active { transform: scale(0.985); }

.product__cta svg {
  width: 13px;
  height: 13px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The artwork runs off the bottom edge of the card the way a screenshot
   would, so the card reads as a window onto the product rather than a box
   with a picture in it. */
.product__shot {
  position: relative;
  margin-top: auto;
  height: clamp(160px, 21vw, 200px);
  /* Decoration only, and the glow below reaches up over the button on any
     card whose facts wrap to a third line. Nothing in here takes a tap. */
  pointer-events: none;
}

.product__shot::before {
  content: "";
  position: absolute;
  inset: -40% -12% 0 20%;
  background: radial-gradient(58% 74% at 72% 96%, var(--pc-wash-hover), transparent 72%);
}

.product__shot > img {
  position: absolute;
  right: clamp(20px, 3vw, 40px);
  bottom: -13%;
  width: clamp(160px, 23vw, 232px);
  height: auto;
  border-radius: 23%;
  box-shadow: 0 24px 54px rgba(0, 0, 0, 0.2), inset 0 0 0 1px var(--pc-line);
}

/* A line of work has no icon of its own, so it gets the Northest mark on a
   tile, in the same box and at the same size on every card. The artwork is
   white, so the tile has to stay dark. */
.product__tile {
  position: absolute;
  right: clamp(20px, 3vw, 40px);
  bottom: -13%;
  display: grid;
  place-items: center;
  width: clamp(160px, 23vw, 232px);
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 23%;
  background:
    radial-gradient(88% 78% at 26% 16%, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 58%),
    linear-gradient(150deg, #6f9fdd 0%, #3f5b81 52%, #090c11 100%);
  box-shadow: 0 24px 54px rgba(0, 0, 0, 0.2), inset 0 0 0 1px var(--pc-line);
}

/* The mark fills its square, so it is inset to sit like an app icon
   rather than touching the corners. */
.product__tile > img { width: 76%; height: auto; }

/* The last card has nothing to show yet, so the Northest mark sits in the
   same place as a watermark. The mark is white artwork on a dark card. */
.product__shot--mark > img {
  width: auto;
  height: clamp(150px, 19vw, 190px);
  right: clamp(24px, 4vw, 60px);
  bottom: 4%;
  border-radius: 0;
  box-shadow: none;
  opacity: 0.12;
}

/* ---------------------------------------------------------------- hero */

.hero {
  padding-top: clamp(48px, 9vw, 108px);
  padding-bottom: clamp(40px, 6vw, 72px);
}

/* The opening screen, headline and gradient banner together, fills exactly
   the viewport below the sticky bar: the banner stretches to take whatever
   height the headline block leaves, and keeps a floor on short screens. */
.intro {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--nav-h));
  min-height: calc(100svh - var(--nav-h));
}

.intro > .section--tight {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-top: 0;
  padding-bottom: var(--gutter);
}

.intro > .hero {
  padding-top: clamp(32px, 9svh, 108px);
  padding-bottom: clamp(28px, 6svh, 72px);
}

.intro .banner {
  flex: 1;
  min-height: 180px;
  aspect-ratio: auto;
}

.hero__inner {
  max-width: 920px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(20px, 3vw, 32px);
}

.hero .lede { max-width: 640px; }

.page-hero {
  padding-top: clamp(40px, 7vw, 88px);
  padding-bottom: clamp(28px, 4vw, 48px);
}

.page-hero__inner {
  max-width: 860px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(16px, 2.4vw, 24px);
}

.page-hero .eyebrow { justify-content: center; }

.page-hero .lede { max-width: 680px; }

/* ---------------------------------------------------------------- gradient art */

/* Six gradients, all mixed from the brand palette. */

.art {
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.art--1 {
  background:
    radial-gradient(120% 90% at 18% 12%, #9fc2ee 0%, rgba(159, 194, 238, 0) 58%),
    radial-gradient(100% 100% at 82% 26%, #dae1eb 0%, rgba(218, 225, 235, 0) 46%),
    linear-gradient(148deg, #6f9fdd 0%, #3f5b81 46%, #1a2638 100%);
}

.art--2 {
  background:
    radial-gradient(90% 80% at 78% 18%, #eadbbe 0%, rgba(234, 219, 190, 0) 60%),
    radial-gradient(80% 80% at 12% 84%, #f79a78 0%, rgba(247, 154, 120, 0) 62%),
    linear-gradient(160deg, #f0b98a 0%, #f37042 58%, #7a2f1c 100%);
}

.art--3 {
  background:
    radial-gradient(100% 90% at 24% 78%, #6f9fdd 0%, rgba(111, 159, 221, 0) 60%),
    radial-gradient(80% 70% at 80% 20%, #ffffff 0%, rgba(255, 255, 255, 0) 52%),
    linear-gradient(140deg, #dae1eb 0%, #6f9fdd 52%, #3f5b81 100%);
}

.art--4 {
  background:
    radial-gradient(90% 90% at 20% 22%, #eadbbe 0%, rgba(234, 219, 190, 0) 58%),
    radial-gradient(90% 80% at 84% 82%, #2c4431 0%, rgba(44, 68, 49, 0) 62%),
    linear-gradient(152deg, #8fa98f 0%, #46684d 54%, #18261b 100%);
}

.art--5 {
  background:
    radial-gradient(100% 80% at 76% 24%, #f79a78 0%, rgba(247, 154, 120, 0) 58%),
    radial-gradient(80% 80% at 16% 80%, #3f5b81 0%, rgba(63, 91, 129, 0) 60%),
    linear-gradient(146deg, #f37042 0%, #8a5a6a 52%, #1a2638 100%);
}

.art--6 {
  background:
    radial-gradient(110% 90% at 30% 20%, #dae1eb 0%, rgba(218, 225, 235, 0) 56%),
    radial-gradient(90% 80% at 84% 78%, #3f5b81 0%, rgba(63, 91, 129, 0) 60%),
    linear-gradient(150deg, #b9c4d4 0%, #5d6b80 50%, #090c11 100%);
}

.art--grain::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.16;
  background-image: radial-gradient(rgba(255, 255, 255, 0.45) 0.5px, transparent 0.6px);
  background-size: 4px 4px;
}

.banner {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 16 / 9;
}

@media (min-width: 900px) {
  .banner { aspect-ratio: 21 / 8; }
}

/* ---------------------------------------------------------------- feature split */

.feature {
  display: grid;
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}

@media (min-width: 900px) {
  .feature { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
  .feature--flip .feature__media { order: 2; }
}

.feature__media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 4 / 5;
  max-height: 560px;
}

.feature__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
}

.feature__body {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: flex-start;
}

/* ---------------------------------------------------------------- spec list */

.specs {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line-soft);
}

.specs > div {
  display: grid;
  gap: 4px 32px;
  padding: 18px 0;
  border-bottom: 1px solid var(--line-soft);
}

@media (min-width: 700px) {
  .specs > div { grid-template-columns: minmax(0, 180px) minmax(0, 1fr); }
}

.specs dt {
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  padding-top: 2px;
}

.specs dd {
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
}

.specs dd a { text-decoration: none; border-bottom: 1px solid var(--line); }

.specs dd a:hover { color: var(--muted); }

/* ---------------------------------------------------------------- prose */

.prose {
  max-width: 44rem;
  margin-inline: auto;
  font-size: 1rem;
  line-height: 1.65;
  letter-spacing: -0.011em;
  color: var(--prose-fg);
}

@media (min-width: 768px) {
  .prose { font-size: 1.0625rem; }
}

.prose > * + * { margin-top: 1.35em; }

.prose + .prose { margin-top: clamp(40px, 5vw, 64px); }

.prose p { text-wrap: pretty; }

.prose h2 {
  font-size: clamp(1.1875rem, 2.2vw, 1.375rem);
  letter-spacing: -0.026em;
  color: var(--fg);
  margin-top: 2.2em;
  margin-bottom: 0.1em;
}

.prose h3 {
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: -0.018em;
  color: var(--fg);
  margin-top: 1.9em;
  margin-bottom: -0.35em;
}

.prose h2:first-child,
.prose h3:first-child { margin-top: 0; }

.prose em { font-style: italic; }

.prose strong { font-weight: 600; color: var(--fg); }

.prose a {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 0.22em;
}

.prose a:hover { text-decoration-color: currentColor; }

.prose .kv {
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
  color: var(--muted);
  margin-top: 0.35em;
}

.prose .li {
  position: relative;
  padding-left: 1.1em;
  margin-top: 0.5em;
  color: var(--prose-fg);
}

.prose .li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 5px;
  height: 1px;
  background: var(--faint);
}

.prose br { display: none; }

.prose pre.code,
pre.code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 20px 22px;
  overflow-x: auto;
}

.prose figure { margin-top: 2.2em; }

.prose figure img {
  width: 100%;
  border-radius: var(--radius);
}

.prose figcaption {
  margin-top: 12px;
  font-size: 0.9375rem;
  color: var(--faint);
}

/* ---------------------------------------------------------------- aside link */

/* Deliberately quiet: a secondary pointer, not a call to action. */
.aside-link {
  margin-top: 28px;
  font-size: 0.8125rem;
  color: var(--faint);
}

.aside-link a { text-decoration: none; border-bottom: 1px solid var(--line-soft); }

.aside-link a:hover { color: var(--muted); }

/* ---------------------------------------------------------------- article */

.article-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 24px;
  padding-bottom: clamp(24px, 3vw, 40px);
  font-size: 0.875rem;
  color: var(--faint);
}

.article-meta span:first-child { color: var(--fg); }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9375rem;
  color: var(--muted);
  text-decoration: none;
}

.back-link:hover { color: var(--fg); }

.back-link svg { width: 14px; height: 14px; }

/* ---------------------------------------------------------------- footer */

.site-footer {
  border-top: 1px solid var(--line-soft);
  padding-block: clamp(40px, 5vw, 72px) 40px;
}

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

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

.footer-brand {
  display: flex;
  flex-direction: column;
  gap: 12px;
  grid-column: 1 / -1;
}

@media (min-width: 900px) {
  .footer-brand { grid-column: auto; }
}

.footer-brand p {
  max-width: 30ch;
  font-size: 0.9375rem;
  color: var(--faint);
  letter-spacing: -0.005em;
}

.footer-col h2 {
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 14px;
}

.footer-col li + li { margin-top: 10px; }

.footer-col a {
  font-size: 0.9375rem;
  letter-spacing: -0.008em;
  color: var(--footer-link);
  text-decoration: none;
}

.footer-col a:hover { color: var(--fg); }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  align-items: center;
  margin-top: clamp(40px, 5vw, 64px);
  padding-top: 24px;
  border-top: 1px solid var(--line-soft);
  font-size: 0.875rem;
  color: var(--faint);
}

.footer-bottom a { text-decoration: none; }

.footer-bottom a:hover { color: var(--fg); }

.footer-bottom .spacer { margin-left: auto; }

@media (max-width: 640px) {
  .footer-bottom .spacer { margin-left: 0; }
}

/* ---------------------------------------------------------------- motion */

@view-transition { navigation: auto; }

@keyframes page-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

main { animation: page-in 0.36s var(--ease) both; }

::view-transition-old(root) {
  animation: fade-out 0.16s ease both;
}

::view-transition-new(root) {
  animation: page-in 0.28s var(--ease) both;
}

@keyframes fade-out {
  to { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  main { animation: none; }
  @view-transition { navigation: none; }
}
