:root {
  --ink: #2a2e35;
  --ink-soft: #6b7280;
  --bg: #fdfdfc;
  --card: rgba(255,255,255,.86);
  --card-solid: #ffffff;
  --line: #e3e5e8;
  --line-strong: #c9ced6;
  --topo: #6ea9d2;
  --topo-opacity: .38;
  --accent: #2f6d99;
  --go: #2f7d4f;
  --marginal: #a8730f;
  --shadow: 0 1px 2px rgba(42,46,53,.05), 0 8px 24px rgba(42,46,53,.06);
  --shadow-lift: 0 2px 4px rgba(42,46,53,.06), 0 16px 40px rgba(42,46,53,.10);
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #e7e9ec;
    --ink-soft: #98a1ad;
    --bg: #14171b;
    --card: rgba(27,31,37,.82);
    --card-solid: #1b1f25;
    --line: #2b3138;
    --line-strong: #3a424c;
    --topo: #7fb0d6;
    --topo-opacity: .28;
    --accent: #7ab6dd;
    --go: #6cc48c;
    --marginal: #e0aa4a;
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35);
    --shadow-lift: 0 2px 4px rgba(0,0,0,.45), 0 16px 40px rgba(0,0,0,.5);
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --ink: #e7e9ec;
  --ink-soft: #98a1ad;
  --bg: #14171b;
  --card: rgba(27,31,37,.82);
  --card-solid: #1b1f25;
  --line: #2b3138;
  --line-strong: #3a424c;
  --topo: #7fb0d6;
  --topo-opacity: .28;
  --accent: #7ab6dd;
  --go: #6cc48c;
  --marginal: #e0aa4a;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35);
  --shadow-lift: 0 2px 4px rgba(0,0,0,.45), 0 16px 40px rgba(0,0,0,.5);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Exo 2', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
}

/* ---------- topographic backdrop ----------
   One inline SVG, tiled by an SVG <pattern>, colored through currentColor
   so light and dark mode share a single copy of the contour data. Fixed, so
   the page slides over the terrain rather than dragging it along. */

.topo {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  color: var(--topo);
  opacity: var(--topo-opacity);
  pointer-events: none;
}

.topo .fine { display: none; }

@media (max-width: 700px) {
  .topo .coarse { display: none; }
  .topo .fine { display: block; }
}

/* ---------- shell ---------- */

.wrap { width: 100%; max-width: 1080px; margin: 0 auto; padding: 0 24px; }

section { scroll-margin-top: 84px; }

a { color: var(--accent); }

/* ---------- top bar ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 24px;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}

.login {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--card-solid);
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: .6px;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: var(--shadow);
  transition: border-color .18s ease, transform .18s ease;
}

.login:hover { border-color: var(--accent); transform: translateY(-1px); }
.login:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.login svg { width: 15px; height: 15px; flex: none; }

.topnav { margin-left: auto; display: flex; align-items: center; gap: 4px; }

.topnav > a, .dd > button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: .3px;
  text-decoration: none;
  cursor: pointer;
}

.topnav > a:hover, .dd > button:hover { background: var(--line); }
.topnav > a:focus-visible, .dd > button:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* ---------- applications dropdown ---------- */

.dd { position: relative; }

.dd > button svg { width: 11px; height: 11px; transition: transform .18s ease; }
.dd > button[aria-expanded="true"] svg { transform: rotate(180deg); }

.dd-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 264px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--card-solid);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-lift);
}

.dd-menu[hidden] { display: none; }

.dd-menu a, .dd-menu .dead {
  display: block;
  padding: 9px 12px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--ink);
  font-size: 14.5px;
  line-height: 1.35;
}

.dd-menu a:hover { background: var(--line); }
.dd-menu a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dd-menu .dead { color: var(--ink-soft); cursor: default; }
.dd-menu .note { display: block; font-size: 12.5px; color: var(--ink-soft); }

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

.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 26px;
  padding: clamp(48px, 10vh, 96px) 24px clamp(20px, 3vh, 36px);
}

.lockup { display: flex; align-items: center; gap: clamp(20px, 4.5vw, 36px); color: var(--ink); }

.frond { width: clamp(60px, 12vw, 96px); height: auto; flex: none; }

/* The wordmark is the page's one h1. Reset the heading defaults so it
   renders exactly as the lockup did when it was a div. */
.wordmark { display: flex; flex-direction: column; margin: 0; font-size: inherit; font-weight: inherit; }

.name {
  font-weight: 700;
  font-size: clamp(32px, 8vw, 60px);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: clamp(2px, .75vw, 5px);
  white-space: nowrap;
}

.sub {
  font-weight: 300;
  font-size: clamp(13px, 3.4vw, 26px);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: clamp(5.5px, 1.78vw, 13px);
  white-space: nowrap;
  margin-top: clamp(6px, 1.4vw, 12px);
  /* tracking adds a trailing gap after the last letter; pull it back so the
     two lines optically align on the right edge */
  margin-right: calc(-1 * clamp(5.5px, 1.78vw, 13px));
}

.tagline {
  font-weight: 400;
  font-size: clamp(17px, 3.6vw, 26px);
  text-transform: uppercase;
  letter-spacing: clamp(2.5px, .72vw, 7px);
  color: var(--ink);
  margin: 0;
}

.positioning {
  max-width: 42ch;
  margin: 0;
  font-size: clamp(15px, 2.2vw, 17.5px);
  font-weight: 300;
  color: var(--ink-soft);
}

/* ---------- section furniture ---------- */

.band { padding: clamp(40px, 7vh, 72px) 0; }

/* Capabilities follows the hero directly, and hero bottom padding plus band
   top padding left a dead screen between them. */
#capabilities { padding-top: clamp(4px, 1.5vh, 16px); }

h2 {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 3.2px;
  color: var(--ink-soft);
}

.band > .wrap > .lede {
  margin: 0 0 30px;
  max-width: 56ch;
  font-size: clamp(17px, 2.6vw, 21px);
  font-weight: 300;
}

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

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
}

.card {
  padding: 24px 24px 26px;
  background: var(--card);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}

/* Cards are <details>. Collapsed they are a row of headings, which is what
   makes the section survivable on a phone. A script opens them on wide
   viewports, where the scroll cost does not exist and the copy should just
   be there. */
.card { padding: 0; }

.card > summary {
  display: flex;
  align-items: start;
  gap: 14px;
  padding: 20px 22px;
  cursor: pointer;
  list-style: none;
  border-radius: 14px;
}

.card > summary::-webkit-details-marker { display: none; }
.card > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.card > summary:hover h3 { color: var(--accent); }

.card h3 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .4px;
}

.card p {
  margin: 0;
  padding: 0 22px 22px;
  font-size: 14.5px;
  font-weight: 300;
  color: var(--ink-soft);
}

/* Offsets center the glyphs on the first line of the heading rather than on
   the whole summary, which is what a three-line title needs. */
.card-icon {
  width: 30px; height: 30px;
  flex: none;
  margin-top: -2px;
  color: var(--accent);
  display: block;
}

.card-chev {
  width: 16px; height: 16px;
  flex: none;
  margin-top: 6px;
  margin-left: auto;
  color: var(--ink-soft);
  transition: transform .18s ease;
}

.card[open] > summary .card-chev { transform: rotate(180deg); }

/* ---------- applications ---------- */

.app {
  background: var(--card);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 28px clamp(20px, 3.6vw, 34px) 30px;
  margin-bottom: 20px;
}

.app-head { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; }

.app-head h3 {
  margin: 0;
  font-size: clamp(21px, 3.6vw, 27px);
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.badge {
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.badge.live { color: var(--go); border-color: var(--go); }
.badge.beta { color: var(--marginal); border-color: var(--marginal); }

.app p { max-width: 66ch; font-weight: 300; }

.cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
  padding: 11px 20px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: .8px;
  text-transform: uppercase;
  transition: transform .18s ease, box-shadow .18s ease;
}

.cta:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.cta:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.cta svg { width: 16px; height: 16px; }

/* Two up, always. Auto-fit dropped a lone fourth panel onto its own row and
   the block read as a mistake rather than a set. */
.shots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: 22px 20px;
  margin: 22px 0 0;
}

@media (max-width: 700px) { .shots { grid-template-columns: 1fr; } }

figure { margin: 0; }

/* Fixed 3:2 tiles with object-fit: contain. The four panels range from 1.09
   to 2.11 in aspect, and at natural height the grid rows read as broken.
   Contain rather than cover because these are charts: cropping a color bar
   or an axis off one costs more than the letterboxing does. */
figure img {
  display: block;
  width: 100%;
  /* height: auto is load bearing. The width/height attributes below are
     presentational hints, and without this the attribute height wins and
     the tile renders at the source image's pixel height. */
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: contain;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card-solid);
}

/* The findings table is a screenshot of text. It is legible only at close
   to native width, so it gets its own full-width row and no fixed ratio. */
.feature { margin-top: 26px; }

.feature img {
  width: 100%;
  max-width: 968px;
  height: auto;
  aspect-ratio: auto;
  padding: 0;
  object-fit: fill;
}

.feature figcaption { max-width: 968px; }

figcaption {
  margin-top: 9px;
  font-size: 13px;
  font-weight: 300;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* ---------- contact ---------- */

.contact-line {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: clamp(19px, 3.4vw, 26px);
  font-weight: 300;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: 4px;
}

.contact-line:hover { border-color: var(--accent); color: var(--accent); }
.contact-line:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.contact-line svg { width: 22px; height: 22px; flex: none; color: var(--accent); }

footer {
  padding: 34px 24px 44px;
  text-align: center;
  font-size: 12px;
  font-weight: 300;
  letter-spacing: .8px;
  color: var(--ink-soft);
  text-transform: uppercase;
  border-top: 1px solid var(--line);
}

/* Four nav items plus the Log In pill stopped fitting on one line once
   About was added, and Contact ran off the right edge. Below 700 px the bar
   wraps and the nav takes its own row rather than being clipped (620 was
   the first breakpoint; at 621-640 the single row still overflowed). */
@media (max-width: 700px) {
  .topbar { flex-wrap: wrap; padding: 7px 14px 4px; gap: 4px 8px; }
  .login { padding: 7px 12px; font-size: 13px; }
  .topnav {
    width: 100%;
    margin-left: 0;
    justify-content: space-between;
  }
  .topnav > a, .dd > button { padding: 6px 4px; font-size: 13px; }
  .dd-menu { min-width: 232px; right: auto; left: 0; }
  .wrap { padding: 0 18px; }
  section { scroll-margin-top: 96px; }
}

/* ---------- in the field ---------- */

.field {
  margin-top: 30px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
}

.field img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card-solid);
}

/* ---------- about ---------- */

/* Two short lines of copy next to a portrait. Left to span the full 1080 px
   the text stranded itself against a wall of empty grid, so the block is
   capped and the copy sits centered against the photograph. */
.about {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  align-items: center;
  gap: clamp(20px, 4vw, 40px);
  max-width: 760px;
}

@media (max-width: 640px) { .about { grid-template-columns: 1fr; } }

.about img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--card-solid);
}

.about h3 {
  margin: 0 0 10px;
  font-size: clamp(20px, 3.4vw, 26px);
  font-weight: 600;
  letter-spacing: .6px;
}

.about p { margin: 0 0 14px; max-width: 58ch; font-weight: 300; }

.linkedin {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 14.5px;
  text-decoration: none;
  color: var(--accent);
}

.linkedin:hover { text-decoration: underline; }
.linkedin svg { width: 18px; height: 18px; flex: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .login, .cta, .dd > button svg, .card-chev { transition: none; }
  .login:hover, .cta:hover { transform: none; }
}

/* ---------- three pages, one bar (2026-09-15) ---------- */

/* Brand at the left of the bar, where a visitor expects it; login moved to
   the right edge as a quiet link, and Contact made the one filled button.
   A prospective client's first action is contact, not login. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--ink);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 2.6px;
  text-transform: uppercase;
  padding: 4px 6px 4px 2px;
  border-radius: 8px;
}
.brand svg { width: 22px; height: auto; }
.brand:hover { color: var(--accent); }
.brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.topnav .contact-btn {
  background: var(--ink);
  color: var(--bg);
  border-radius: 999px;
  padding: 8px 16px;
  margin-left: 4px;
}
.topnav .contact-btn:hover { background: var(--accent); color: #fff; }

.topnav .login {
  margin-left: 4px;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  padding: 8px 8px;
  box-shadow: none;
}
.topnav .login:hover { color: var(--accent); transform: none; }

/* Below 620 px the nav row holds five items in 362 px. Log in drops to its
   lock icon (the link keeps its name through aria-label) and Contact
   tightens, or the row runs 15 px past the screen and the page scrolls
   sideways (seen live 2026-09-15 at 390 wide). */
@media (max-width: 700px) {
  .brand { font-size: 13px; letter-spacing: 2px; }
  .topnav .contact-btn { padding: 6px 10px; }
  .topnav .login { padding: 6px 4px; gap: 0; }
  .topnav .login .login-text { display: none; }
  .topnav .login svg { width: 17px; height: 17px; }
}
/* 320 px phones: the row needs 356 px at the sizes above. */
@media (max-width: 360px) {
  .topbar { padding-left: 10px; padding-right: 10px; }
  .topnav { gap: 0; }
  .topnav > a, .dd > button { padding: 6px 3px; font-size: 12px; }
  .topnav .contact-btn { padding: 6px 8px; }
}

/* Applications on the landing page: two cards, one image and one line each.
   The detail moved to /preflight and /postflight. */
.apps {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  align-items: stretch;
}
@media (max-width: 700px) { .apps { grid-template-columns: 1fr; } }

.apps .app { margin: 0; display: flex; flex-direction: column; padding-top: 22px; }
.apps .app > a.thumb { display: block; margin: 0 0 18px; }
.apps .app > a.thumb img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: left top;   /* the panels read from their top-left corner */
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card-solid);
}
.apps .app > a.thumb:focus-visible img { outline: 2px solid var(--accent); outline-offset: 3px; }
.apps .app p { flex: 1; margin: 12px 0 18px; }

.actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cta.ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line-strong);
}
.cta.ghost:hover { border-color: var(--accent); color: var(--accent); }

/* The sentence that used to be missing beside every login button. */
.access-note {
  margin: 22px 0 0;
  max-width: 66ch;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.55;
  color: var(--ink-soft);
}
.access-note a { color: var(--ink); }

/* ---------- product pages ---------- */

.page-hero { padding: clamp(28px, 6vh, 56px) 0 clamp(8px, 2vh, 20px); }
.page-hero .eyebrow {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 3.2px;
  color: var(--ink-soft);
}
.page-hero h1 {
  margin: 0;
  font-size: clamp(34px, 6.5vw, 58px);
  font-weight: 700;
  letter-spacing: 1px;
  line-height: 1.05;
}
.page-hero .app-head { gap: 16px; }
.page-hero .positioning { text-align: left; margin: 18px 0 20px; max-width: 62ch; }
.page-hero .actions { margin-bottom: 8px; }

.demo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #000;
  box-shadow: var(--shadow);
}
.demo-note { margin: 10px 0 0; font-size: 13px; font-weight: 300; color: var(--ink-soft); max-width: 70ch; }

/* On the product pages the panels are the content, so they keep their own
   proportions instead of the 3:2 tile the landing page used. */
.page .shots figure img { aspect-ratio: auto; }
.page .feature img { max-width: 100%; }
.page section + section { padding-top: 0; }
.page .band h2 { margin-bottom: 14px; }
.page .band .lede { margin-bottom: 22px; }
