/* ============================================================================
   MatGen — design system.

   No framework. The whole site is this file plus two small scripts. Colour,
   type and spacing are custom properties so the dark and light themes are the
   same stylesheet with a different set of values, and so the inline SVG figures
   can pull the exact same palette the prose uses.

   The four-colour spectrum (--c1..--c4) is not decoration: it encodes position
   along the discovery pipeline, from target biology (violet) to the clinic
   (cyan), and every figure and section marker uses it that way.
   ============================================================================ */

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

:root {
  /* ---- dark, the default ---- */
  --bg:        #0B0A10;
  --bg-lift:   #131220;
  --bg-sink:   #08070C;
  --ink:       #ECEBF3;
  --muted:     #A5A3B8;
  --faint:     #86849C;
  --line:      rgba(236, 235, 243, .13);
  --line-soft: rgba(236, 235, 243, .065);
  --nav-bg:    rgba(11, 10, 16, .74);

  --c1: #BA61FF;   /* target biology      */
  --c2: #FF48B0;   /* structure, chemistry */
  --c3: #FF7D4B;   /* optimisation        */
  --c4: #3CD6FF;   /* translation, clinic */
  --accent: var(--c1);

  --c1-rgb: 186, 97, 255;
  --sel-fg: #150C22;

  /* Six samples along the same spectrum, one per discovery stage. Sampled by
     hand rather than interpolated: a straight RGB ramp from orange to cyan
     passes through grey, which would put a dead stage in the middle. */
  --p1: #A970FF; --p2: #D95FE8; --p3: #FF4FA3;
  --p4: #FF7A52; --p5: #FFB43C; --p6: #3CD6FF;

  /* A restrained bloom. Dark only — on paper it just reads as blur. */
  --glow:     0 0 30px rgba(186, 97, 255, .30);
  --glow-dot: 0 0 10px rgba(186, 97, 255, .70);
  --lattice-op: .5;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 28px rgba(0,0,0,.32);

  /* Display is Yantramanav Light — the face the site used for the MatGen
     wordmark before this rebuild, so the brand carries over, and nothing a
     template generator reaches for. It has to be a webfont: the headlines are
     set thin, and Arial has no weight below Regular, so a system stack would
     render them a whole weight heavier on Windows than on a Mac.
     Body stays on the installed Swiss stack — neutral, and nothing to fetch. */
  --display: 'Yantramanav', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --sans:    'Helvetica Neue', Helvetica, Arial, 'Liberation Sans', sans-serif;
  --mono:    'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --pad:  clamp(1.15rem, 4.5vw, 4rem);
  --maxw: 1180px;
  --sec:  clamp(4rem, 8vw, 7.5rem);
  --r:    10px;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) {
    --bg:        #F6F5FB;
    --bg-lift:   #FFFFFF;
    --bg-sink:   #EEECF6;
    --ink:       #15131F;
    --muted:     #55536B;
    --faint:     #6C6A84;
    --line:      rgba(21, 19, 31, .15);
    --line-soft: rgba(21, 19, 31, .075);
    --nav-bg:    rgba(246, 245, 251, .78);

    --c1: #8028D8;
    --c2: #D01277;
    --c3: #B85416;
    --c4: #0C7FA5;

    --c1-rgb: 128, 40, 216;
    --sel-fg: #FBF7FF;

    --p1: #7B2BD4; --p2: #A81FBE; --p3: #C51678;
    --p4: #C0561C; --p5: #8F6205; --p6: #0C7FA5;

    --glow: none;
    --glow-dot: none;
    --lattice-op: .8;
    --shadow: 0 1px 2px rgba(21,19,31,.06), 0 10px 30px rgba(21,19,31,.07);
  }
}

/* Explicit choice always beats the OS preference. */
:root[data-theme='light'] {
  --bg:        #F6F5FB;
  --bg-lift:   #FFFFFF;
  --bg-sink:   #EEECF6;
  --ink:       #15131F;
  --muted:     #55536B;
  --faint:     #6C6A84;
  --line:      rgba(21, 19, 31, .15);
  --line-soft: rgba(21, 19, 31, .075);
  --nav-bg:    rgba(246, 245, 251, .78);
  --c1: #8028D8;
  --c2: #D01277;
  --c3: #B85416;
  --c4: #0C7FA5;
  --c1-rgb: 128, 40, 216;
  --sel-fg: #FBF7FF;
  --p1: #7B2BD4; --p2: #A81FBE; --p3: #C51678;
  --p4: #C0561C; --p5: #8F6205; --p6: #0C7FA5;
  --glow: none;
  --glow-dot: none;
  --lattice-op: .8;
  --shadow: 0 1px 2px rgba(21,19,31,.06), 0 10px 30px rgba(21,19,31,.07);
}

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; scroll-padding-top: 6rem; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

::selection { background: var(--accent); color: var(--sel-fg); }
a { color: inherit; }
img, svg { max-width: 100%; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

.skip {
  position: absolute; left: 50%; top: 0; transform: translate(-50%, -120%);
  z-index: 300; background: var(--bg-lift); color: var(--ink);
  border: 1px solid var(--line); border-radius: 0 0 var(--r) var(--r);
  padding: .7rem 1.2rem; font-size: .85rem; text-decoration: none;
  transition: transform .18s ease;
}
.skip:focus { transform: translate(-50%, 0); }

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

/* Light holds up at display size and goes weak below about 20px. So Regular is
   the default for a heading and Light is opted into by the few big ones, rather
   than the other way round — a new small heading then cannot inherit a weight
   that makes it disappear into the paragraph under it. */
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: -.02em;
  line-height: 1.1;
}
.h1, .h2, .page-head h1, .big, .mailto { font-weight: 300; }

.mono {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 400;
}
.num { font-variant-numeric: tabular-nums; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding-left: var(--pad); padding-right: var(--pad); }
.narrow { max-width: 68ch; }

.h1 { font-size: clamp(2.35rem, 5.6vw, 4.35rem); line-height: 1.05; letter-spacing: -.022em; text-wrap: balance; }
.h2 { font-size: clamp(1.7rem, 3.4vw, 2.7rem); letter-spacing: -.018em; max-width: 24ch; text-wrap: balance; }
.h3 { font-size: clamp(1.25rem, 2.1vw, 1.65rem); letter-spacing: -.024em; }

em.hl { font-style: normal; color: var(--accent); text-shadow: var(--glow); }

.lede {
  font-size: clamp(1.02rem, 1.25vw, 1.12rem);
  line-height: 1.7;
  color: var(--muted);
  max-width: 64ch;
}
.lede strong { color: var(--ink); font-weight: 500; }
.lede + .lede { margin-top: 1.1rem; }

.prose p { color: var(--muted); max-width: 64ch; }
.prose p + p { margin-top: 1.1rem; }
.prose strong { color: var(--ink); font-weight: 500; }
.prose a, .lede a, .big a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--accent); padding-bottom: 1px; transition: color .18s ease; }
.prose a:hover, .lede a:hover, .big a:hover { color: var(--accent); }

.big {
  font-family: var(--display);
  font-size: clamp(1.42rem, 2.7vw, 2.15rem);
  line-height: 1.3;
  letter-spacing: -.026em;
  max-width: 26ch;
  text-wrap: balance;
}
.big em { font-style: normal; color: var(--accent); text-shadow: var(--glow); }

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

section { padding: var(--sec) 0; }
.divider { height: 1px; background: var(--line-soft); }

/* Editorial two-column rhythm: a marker in the gutter, content in the column. */
.rail {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
}
@media (max-width: 860px) { .rail { grid-template-columns: minmax(0, 1fr); gap: 1.1rem; } }

.marker { display: flex; align-items: baseline; gap: .6rem; align-self: start; }
.marker b {
  font-family: var(--mono); font-size: .6875rem; font-weight: 500;
  /* --sel-fg is the colour that reads against a saturated accent in whichever
     theme resolved, which is exactly what this chip needs. */
  color: var(--sel-fg); background: var(--mk, var(--c1));
  padding: .1rem .34rem; border-radius: 3px; letter-spacing: .02em;
}
.marker span {
  font-family: var(--mono); font-size: .6875rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--faint);
}

/* ------------------------------------------------------------------ nav --- */

.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 200;
  background: var(--nav-bg);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease;
}
.nav.stuck { border-bottom-color: var(--line-soft); }
.nav-in {
  max-width: var(--maxw); margin: 0 auto;
  padding: .8rem var(--pad);
  display: flex; align-items: center; gap: 1rem;
}

.brand { display: flex; align-items: center; gap: .55rem; text-decoration: none; margin-right: auto; }
.brand .mark { width: 30px; height: 30px; color: var(--c1); flex: none; }
.brand .mark svg { display: block; width: 100%; height: 100%; }
.brand .wm { font-family: var(--display); font-size: 1.25rem; letter-spacing: -.02em; }
.brand:hover .mark { color: var(--c2); }
.brand .mark { transition: color .5s ease; }

.nav-links { display: flex; align-items: center; gap: .15rem; list-style: none; }
.nav-links a {
  display: block; padding: .42rem .7rem; border-radius: 6px;
  font-size: .875rem; color: var(--muted); text-decoration: none;
  transition: color .18s ease, background-color .18s ease;
  white-space: nowrap;
}
.nav-links a:hover { color: var(--ink); background: var(--line-soft); }
.nav-links a[aria-current='page'] { color: var(--ink); }
.nav-links a[aria-current='page']::after {
  content: ''; display: block; height: 2px; margin-top: 3px; border-radius: 2px;
  background: var(--accent);
}

.nav-cta {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .44rem .85rem; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink);
  font-size: .8125rem; font-weight: 500; text-decoration: none; white-space: nowrap;
  transition: border-color .18s ease, color .18s ease, background-color .18s ease;
}
.nav-cta:hover { border-color: var(--accent); color: var(--accent); }
.nav-cta svg { flex: none; width: 12px; height: 12px; opacity: .7; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: none;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); cursor: pointer;
  transition: color .18s ease, border-color .18s ease;
}
.icon-btn:hover { color: var(--ink); border-color: var(--muted); }
.icon-btn svg { width: 16px; height: 16px; display: block; }
/* The icon shows the theme currently in force, and must resolve by exactly the
   same rule the palette does — dark unless the OS asks for light, and an
   explicit data-theme beating both. */
.theme-btn .sun { display: block; }
.theme-btn .moon { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) .theme-btn .sun { display: none; }
  :root:not([data-theme='dark']) .theme-btn .moon { display: block; }
}
:root[data-theme='dark'] .theme-btn .sun { display: block; }
:root[data-theme='dark'] .theme-btn .moon { display: none; }
:root[data-theme='light'] .theme-btn .sun { display: none; }
:root[data-theme='light'] .theme-btn .moon { display: block; }

.menu-btn { display: none; }

@media (max-width: 940px) {
  .menu-btn { display: inline-flex; }
  .nav-drawer {
    position: absolute; inset: 100% 0 auto 0;
    background: var(--bg-lift); border-bottom: 1px solid var(--line);
    padding: .5rem var(--pad) 1.1rem;
    display: none;
  }
  .nav-drawer.open { display: block; }
  .nav-drawer .nav-links { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-drawer .nav-links a { padding: .7rem .25rem; border-bottom: 1px solid var(--line-soft); border-radius: 0; font-size: .95rem; }
  .nav-drawer .nav-links a[aria-current='page']::after { display: none; }
  .nav-drawer .nav-links a[aria-current='page'] { color: var(--accent); }
  .nav-drawer .nav-cta { margin-top: .9rem; }
}
@media (min-width: 941px) {
  .nav-drawer { display: contents; }
}

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

.hero {
  position: relative;
  min-height: clamp(600px, 92svh, 940px);
  display: flex; align-items: center;
  padding: 8.5rem 0 4.5rem;
  border-bottom: 1px solid var(--line-soft);
  overflow: hidden;
}
#lattice {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  /* Dissolve the globe into the page rather than cropping it at a hard edge,
     and keep it off the headline on the left. */
  -webkit-mask-image: radial-gradient(115% 92% at 74% 50%, #000 30%, transparent 74%);
  mask-image: radial-gradient(115% 92% at 74% 50%, #000 30%, transparent 74%);
}
@media (max-width: 1019px) {
  #lattice {
    -webkit-mask-image: radial-gradient(95% 62% at 70% 42%, #000 22%, transparent 74%);
    mask-image: radial-gradient(95% 62% at 70% 42%, #000 22%, transparent 74%);
    opacity: .75;
  }
}
@media (max-width: 719px) {
  #lattice { opacity: .34; }
  .hero { min-height: clamp(560px, 86svh, 820px); padding: 7.5rem 0 3.5rem; }
}
.hero-in { position: relative; z-index: 2; }
.hero .eyebrow { display: flex; align-items: center; gap: .7rem; margin-bottom: 1.9rem; }
.hero .eyebrow::after { content: ''; height: 1px; flex: 1; max-width: 5rem; background: var(--line); }
.hero h1 { margin-bottom: 1.5rem; max-width: 17ch; }
.hero .sub { font-size: clamp(1.05rem, 1.5vw, 1.22rem); line-height: 1.6; color: var(--muted); max-width: 46ch; margin-bottom: 2.4rem; }
.hero .sub strong { color: var(--ink); font-weight: 500; }

.hero-meta {
  position: absolute; z-index: 2; right: var(--pad); bottom: 2.2rem;
  text-align: right; display: flex; flex-direction: column; gap: .3rem;
}
@media (max-width: 1020px) { .hero-meta { display: none; } }

.cta { display: flex; flex-wrap: wrap; gap: .7rem; align-items: center; }
.btn {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--sans); font-size: .9rem; font-weight: 500;
  padding: .78rem 1.35rem; border-radius: 999px; text-decoration: none;
  border: 1px solid transparent; cursor: pointer;
  transition: background-color .2s ease, color .2s ease, border-color .2s ease, transform .2s ease;
}
.btn-p { background: var(--ink); color: var(--bg); }
.btn-p:hover { background: var(--accent); color: var(--sel-fg); transform: translateY(-1px); }
.btn-s { border-color: var(--line); color: var(--muted); }
.btn-s:hover { border-color: var(--accent); color: var(--accent); }
.btn svg { transition: transform .2s ease; flex: none; width: 15px; height: 15px; }
.btn:hover svg { transform: translateX(3px); }

/* ------------------------------------------------------------ page head --- */

.page-head {
  position: relative; overflow: hidden;
  padding: clamp(7.5rem, 13vw, 10.5rem) 0 clamp(2.75rem, 5vw, 4rem);
  border-bottom: 1px solid var(--line-soft);
}
.page-head .eyebrow { display: flex; align-items: center; gap: .7rem; margin-bottom: 1.4rem; }
.page-head .eyebrow::after { content: ''; height: 1px; flex: 1; max-width: 4rem; background: var(--line); }
.page-head h1 { font-size: clamp(2.05rem, 4.6vw, 3.4rem); letter-spacing: -.02em; max-width: 19ch; }
.page-head .lede { margin-top: 1.5rem; }
.head-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem); align-items: end; }
@media (max-width: 860px) { .head-grid { grid-template-columns: minmax(0, 1fr); align-items: start; } }

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

.cards {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; background: var(--line-soft);
  border: 1px solid var(--line-soft); border-radius: var(--r); overflow: hidden;
}
@media (max-width: 860px) { .cards { grid-template-columns: minmax(0, 1fr); } }
.card {
  display: block; background: var(--bg-lift); padding: 1.7rem 1.5rem 1.6rem;
  text-decoration: none; position: relative;
  transition: background-color .22s ease;
}
.card:hover { background: var(--bg); }
.card .glyph { color: var(--gc, var(--c1)); margin-bottom: 1.1rem; display: block; }
.card .glyph svg { display: block; width: 46px; height: 46px; }
.card h3 { font-size: 1.16rem; margin-bottom: .55rem; }
.card p { font-size: .9rem; color: var(--faint); line-height: 1.6; }
.card .go { display: inline-flex; align-items: center; gap: .4rem; margin-top: 1.1rem; font-size: .8125rem; color: var(--muted); white-space: nowrap; }
.card:hover .go { color: var(--gc, var(--c1)); }
.card .go svg { transition: transform .2s ease; flex: none; width: 14px; height: 14px; }
.card:hover .go svg { transform: translateX(3px); }

/* ------------------------------------------------------------- pipeline --- */
/* The six stages of discovery, each holding its own position on the spectrum. */

.pipe { margin-top: 2.5rem; border-top: 1px solid var(--line-soft); }
.stage {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 3rem);
  padding: 2.1rem 0;
  border-bottom: 1px solid var(--line-soft);
  position: relative;
}
@media (max-width: 780px) { .stage { grid-template-columns: minmax(0, 1fr); gap: 1rem; padding: 1.7rem 0; } }

.stage-id { display: flex; gap: .9rem; align-items: flex-start; }
.stage-id .sg { flex: none; color: var(--sc); }
.stage-id .sg svg { display: block; width: 52px; height: 52px; }
.stage-id .txt { min-width: 0; }
.stage-id .n {
  font-family: var(--mono); font-size: .625rem; letter-spacing: .09em;
  text-transform: uppercase; color: var(--sc); display: block; margin-bottom: .3rem;
}
.stage-id h3 { font-size: 1.12rem; letter-spacing: -.02em; }

.stage ul { list-style: none; columns: 2; column-gap: 2.5rem; }
@media (max-width: 620px) { .stage ul { columns: 1; } }
.stage li {
  font-size: .875rem; color: var(--muted); line-height: 1.5;
  padding: .28rem 0 .28rem .95rem; position: relative;
  break-inside: avoid;
}
.stage li::before {
  content: ''; position: absolute; left: 0; top: .82em;
  width: 4px; height: 4px; border-radius: 50%; background: var(--sc); opacity: .75;
}
.stage li i { font-style: italic; }

/* Spectrum rail: a thin strip showing where in the pipeline we are. */
.spectrum {
  display: flex; height: 3px; border-radius: 2px; overflow: hidden;
  margin-bottom: 2.2rem; max-width: 34rem;
}
.spectrum i { flex: 1; background: var(--s); }

/* ------------------------------------------------------------- projects --- */

.proj { border-top: 1px solid var(--line-soft); padding: clamp(2.5rem, 5vw, 4rem) 0; }
.proj:first-of-type { border-top: 0; padding-top: clamp(1rem, 2vw, 1.5rem); }
.proj-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
  gap: clamp(1.75rem, 4vw, 3.5rem); align-items: center;
}
@media (max-width: 940px) { .proj-grid { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; } }
/* Alternate sides on wide screens so the column does not read as a list. */
@media (min-width: 941px) { .proj:nth-of-type(even) .proj-copy { order: 2; } }

.proj-name { display: flex; align-items: baseline; gap: .75rem; margin-bottom: .9rem; flex-wrap: wrap; }
.proj-name h3 { font-size: clamp(1.45rem, 2.6vw, 2rem); }
.proj-name em { font-style: italic; }
/* DrugREV sets REV as a subscript, the way the product has always been written.
   The explicit line-height stops the default sub from adding leading to the row. */
.proj-name sub {
  font-size: .52em; vertical-align: baseline; position: relative; bottom: -.16em;
  letter-spacing: .04em; line-height: 0;
}
.proj-name .kind {
  font-family: var(--mono); font-size: .625rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--faint); border: 1px solid var(--line); border-radius: 3px; padding: .16rem .42rem;
}
.proj-copy p { color: var(--muted); font-size: .95rem; line-height: 1.68; max-width: 48ch; }
.proj-copy p + p { margin-top: .95rem; }
.proj-copy p strong { color: var(--ink); font-weight: 500; }

.tags { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: 1.4rem; }
.tag {
  font-family: var(--mono); font-size: .625rem; letter-spacing: .01em;
  color: var(--muted); border: 1px solid var(--line);
  padding: .3rem .55rem; border-radius: 4px; white-space: nowrap;
}

/* Bayesic keeps its pixel wordmark — it is how the app actually looks. */
@font-face {
  font-family: 'C64';
  src: url('../fonts/C64_Pro-STYLE.woff2') format('woff2'),
       url('../fonts/C64_Pro-STYLE.woff') format('woff');
  font-weight: normal; font-style: normal; font-display: swap;
}
.c64 { font-family: 'C64', var(--mono); letter-spacing: 0; font-size: .78em; }

/* --------------------------------------------------------------- figure --- */
/* Shared shell for every hand-built figure. The figures themselves only draw
   inside .fig-plot and never restyle these classes. */

.fig {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg-lift);
  overflow: hidden;
  box-shadow: var(--shadow);
}
/* The caption bar is a fixed one-line instrument readout. The status text
   changes length as the animation runs ("sampling poses" to "designed · 0
   off-target flags"), and letting it wrap grew the bar by a line and made the
   whole figure jump. So nothing here wraps: the title ellipses, and the status
   sits in a field of its own that scrolls its contents when they are too long
   for it. The live dot moved to the end of the bar so it stays put while the
   text underneath it moves. */
.fig-head {
  display: flex; align-items: center; gap: .75rem; flex-wrap: nowrap;
  padding: .6rem .85rem;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--mono); font-size: .625rem; letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.5;
}
.fig-h-l {
  color: var(--muted);
  flex: 1 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fig-h-r {
  color: var(--accent); font-variant-numeric: tabular-nums;
  /* Sized to the longest status the figures actually emit rather than to a
     share of the bar, so the title keeps every pixel it does not need. It may
     shrink below that on a tight bar — at which point the status scrolls. */
  flex: 0 1 13rem; min-width: 0;
  text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fig-head::after {
  content: ''; flex: none;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); box-shadow: var(--glow-dot);
}
/* Set by site.js only when the status actually overflows its field. Negative
   text-indent slides the line inside the box, which needs no inner element —
   the figures own their own markup and write straight into .fig-h-r. */
.fig-h-r.mq { text-overflow: clip; animation: fig-mq var(--mq-t, 6s) ease-in-out infinite alternate; }
@keyframes fig-mq {
  0%, 16%   { text-indent: 0; }
  84%, 100% { text-indent: calc(-1 * var(--mq, 0px)); }
}
@media (prefers-reduced-motion: reduce) {
  .fig-h-r.mq { animation: none; text-overflow: ellipsis; }
}
/* Below this the title cannot survive an ellipsis and the status needs the
   room. The project name is in the heading directly above the figure anyway. */
@media (max-width: 540px) {
  .fig-h-l { display: none; }
  .fig-h-r { width: auto; flex: 1 1 auto; max-width: none; }
}
.fig-plot { padding: .9rem .8rem .4rem; }
.fig-svg { display: block; width: 100%; height: auto; overflow: visible; }
/* Each figure is a 640-unit-wide instrument panel. Below roughly 700px the
   scale drops far enough that its 9-unit labels fall under 8px, so the plot
   gets a floor and pans inside its own scroller instead of becoming a
   decorative smudge. */
/* On a phone the figure is scaled down rather than panned. Holding it at a
   larger width and scrolling inside the frame did keep the labels a little
   bigger, but it showed under half the drawing at 320px — and these figures
   communicate through the whole composition moving, not through their tick
   labels. The drawing is SVG, so pinch-zoom stays crisp for anyone who wants
   the numbers. The frame's own type comes down with it so the chrome does not
   end up larger than the figure it is framing. */
@media (max-width: 560px) {
  .fig-head { font-size: .5625rem; padding: .55rem .7rem; }
  .fig-key { font-size: .5625rem; gap: .3rem .8rem; padding: .5rem .7rem .7rem; }
  .fig-plot { padding: .7rem .55rem .3rem; }
}

.fig-key {
  display: flex; flex-wrap: wrap; gap: .35rem 1.05rem; list-style: none;
  padding: .55rem .85rem .8rem;
  font-family: var(--mono); font-size: .625rem; color: var(--faint); letter-spacing: .01em;
}
.fig-key li { display: inline-flex; align-items: center; gap: .4rem; }
.fig-key i {
  width: 8px; height: 8px; border-radius: 2px; background: var(--k, var(--muted)); flex: none;
}
.fig-cap { font-family: var(--mono); font-size: .625rem; color: var(--faint); text-transform: uppercase; letter-spacing: .05em; margin-top: .7rem; }

/* --------------------------------------------------------------- howto ----- */

.flow { list-style: none; counter-reset: step; margin-top: 2.5rem; }
.flow > li {
  display: grid; grid-template-columns: 3.2rem minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 1.75rem);
  padding-bottom: 2rem; position: relative;
}
.flow > li::before {
  content: ''; position: absolute; left: 1.6rem; top: 3.2rem; bottom: -.4rem;
  width: 1px; background: var(--line);
}
.flow > li:last-child { padding-bottom: 0; }
.flow > li:last-child::before { display: none; }

.flow .dot {
  width: 3.2rem; height: 3.2rem; border-radius: 50%;
  border: 1px solid var(--line); background: var(--bg-lift);
  display: flex; align-items: center; justify-content: center;
  color: var(--sc, var(--c1)); position: relative; z-index: 1;
}
.flow .dot svg { width: 22px; height: 22px; display: block; }
.flow .body { padding-top: .35rem; }
.flow .body .n {
  font-family: var(--mono); font-size: .625rem; letter-spacing: .09em;
  text-transform: uppercase; color: var(--sc, var(--c1)); display: block; margin-bottom: .35rem;
}
.flow .body h3 { font-size: 1.1rem; margin-bottom: .45rem; }
.flow .body p { font-size: .92rem; color: var(--muted); max-width: 56ch; line-height: 1.62; }
.flow .body .meta { font-family: var(--mono); font-size: .6875rem; color: var(--faint); margin-top: .5rem; }
.flow .opt { font-family: var(--mono); font-size: .6rem; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); border: 1px solid var(--line); border-radius: 3px; padding: .1rem .35rem; margin-left: .5rem; vertical-align: 2px; }

/* ---------------------------------------------------------------- modes --- */

.modes {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; background: var(--line-soft);
  border: 1px solid var(--line-soft); border-radius: var(--r); overflow: hidden;
  margin-top: 2.5rem;
}
@media (max-width: 880px) { .modes { grid-template-columns: minmax(0, 1fr); } }
.mode { background: var(--bg-lift); padding: 1.6rem 1.4rem; }
.mode .n { font-family: var(--mono); font-size: .625rem; letter-spacing: .08em; text-transform: uppercase; color: var(--sc, var(--c1)); display: block; margin-bottom: .6rem; }
.mode h3 { font-size: 1.08rem; margin-bottom: .7rem; }
.mode ul { list-style: none; }
.mode li { font-size: .875rem; color: var(--muted); line-height: 1.55; padding: .32rem 0 .32rem .95rem; position: relative; }
.mode li::before { content: ''; position: absolute; left: 0; top: .78em; width: 4px; height: 4px; border-radius: 50%; background: var(--sc, var(--c1)); opacity: .7; }
.mode li b { color: var(--ink); font-weight: 500; }

/* ---------------------------------------------------------------- grids --- */
/* Hairline grids: the container paints the line colour and each cell paints
   over it. This only works while the grid is exactly filled, so the column
   count must always divide the item count — hence explicit steps, not auto-fit. */

.grid-6 {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; background: var(--line-soft);
  border: 1px solid var(--line-soft); border-radius: var(--r); overflow: hidden;
  margin-top: 2.5rem;
}
@media (max-width: 880px) { .grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .grid-6 { grid-template-columns: minmax(0, 1fr); } }
.cell { background: var(--bg-lift); padding: 1.5rem 1.35rem; }
.cell h4 { font-family: var(--sans); font-size: .92rem; font-weight: 600; margin-bottom: .45rem; letter-spacing: -.005em; }
.cell p { font-size: .85rem; line-height: 1.58; color: var(--faint); }

.stack { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; background: var(--line-soft); border: 1px solid var(--line-soft); border-radius: var(--r); overflow: hidden; margin-top: 2rem; }
@media (max-width: 880px) { .stack { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.stack-col { background: var(--bg-lift); padding: 1.35rem 1.25rem; }
.stack-col h4 { font-family: var(--mono); font-size: .625rem; letter-spacing: .08em; text-transform: uppercase; color: var(--sc, var(--muted)); font-weight: 500; margin-bottom: .7rem; }
.stack-col ul { list-style: none; }
.stack-col li { font-size: .82rem; color: var(--muted); padding: .16rem 0; font-family: var(--mono); }

/* ------------------------------------------------------------------ faq --- */

.faq { margin-top: 2.2rem; border-top: 1px solid var(--line-soft); }
.faq details { border-bottom: 1px solid var(--line-soft); }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.05rem 0; cursor: pointer; list-style: none;
  font-family: var(--display); font-size: 1.02rem; font-weight: 400; letter-spacing: -.02em;
  transition: color .18s ease;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary::after {
  content: ''; flex: none; width: 10px; height: 10px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .22s ease; color: var(--faint);
}
.faq details[open] summary::after { transform: rotate(225deg) translate(-2px, -2px); }
.faq details[open] summary { color: var(--accent); }
.faq .a { padding: 0 0 1.2rem; }
.faq .a p { font-size: .92rem; color: var(--muted); max-width: 68ch; line-height: 1.65; }
.faq .a p + p { margin-top: .8rem; }

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

/* The mark drifts across the spectrum — the one piece of pure decoration on
   the site, kept because it is the brand's own long-standing behaviour. */
@keyframes spectrum {
  0%, 100% { color: var(--p1); }
  25%      { color: var(--p3); }
  50%      { color: var(--p4); }
  75%      { color: var(--p6); }
}
.mark-xl { display: block; width: clamp(88px, 15vw, 150px); color: var(--p1); animation: spectrum 36s linear infinite; }
.mark-xl svg { display: block; width: 100%; height: auto; }
@media (prefers-reduced-motion: reduce) { .mark-xl { animation: none; } }


.contact-grid { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4rem); }
@media (max-width: 860px) { .contact-grid { grid-template-columns: minmax(0, 1fr); } }
.channels { list-style: none; }
.channels li { border-top: 1px solid var(--line-soft); padding: 1.05rem 0; }
.channels li:last-child { border-bottom: 1px solid var(--line-soft); }
.channels .k { font-family: var(--mono); font-size: .625rem; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); display: block; margin-bottom: .3rem; }
.channels a, .channels span.v { font-size: 1rem; color: var(--ink); text-decoration: none; }
.channels a { border-bottom: 1px solid var(--line); transition: color .18s ease, border-color .18s ease; }
.channels a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.socials { display: flex; gap: .55rem; margin-top: .2rem; }
.socials a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); transition: color .18s ease, border-color .18s ease;
}
.socials a:hover { color: var(--accent); border-color: var(--accent); }
.socials svg { width: 15px; height: 15px; display: block; }

.mailto {
  display: inline-block; font-family: var(--display);
  font-size: clamp(1.35rem, 3.2vw, 2.1rem); letter-spacing: -.02em;
  text-decoration: none; color: var(--ink);
  border-bottom: 1px solid var(--line); padding-bottom: .12rem;
  transition: color .2s ease, border-color .2s ease;
}
.mailto:hover { color: var(--accent); border-bottom-color: var(--accent); }

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

footer { border-top: 1px solid var(--line-soft); padding: 2.75rem 0 2.25rem; background: var(--bg-sink); }
.foot { display: flex; flex-wrap: wrap; gap: 1.4rem 2.5rem; justify-content: space-between; }
.foot-brand { display: flex; align-items: center; gap: .5rem; }
.foot-brand .mark { width: 22px; height: 22px; color: var(--c1); }
.foot-brand .mark svg { display: block; width: 100%; height: 100%; }
.foot-brand b { font-family: var(--display); font-size: 1.05rem; font-weight: 400; }
.foot-nav { display: flex; flex-wrap: wrap; gap: .3rem 1.3rem; list-style: none; }
.foot-nav a { font-size: .82rem; color: var(--muted); text-decoration: none; }
.foot-nav a:hover { color: var(--ink); }
.foot-legal { display: flex; flex-wrap: wrap; gap: .4rem 1.5rem; align-items: center; width: 100%; margin-top: 1.75rem; padding-top: 1.4rem; border-top: 1px solid var(--line-soft); }

/* --------------------------------------------------------- section aside -- */

.aside {
  background: var(--bg-lift);
  border-block: 1px solid var(--line-soft);
}

.callout {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--bg-lift); padding: clamp(1.5rem, 3vw, 2.25rem);
  display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: center; justify-content: space-between;
  margin-top: 3rem;
}
.callout .t { max-width: 42ch; }
.callout h3 { font-size: 1.25rem; margin-bottom: .4rem; }
.callout p { font-size: .92rem; color: var(--muted); }

/* A faint dot lattice, the netglobe motif at page scale. It lives on a masked
   pseudo-element so it can fade out of the corner the headline occupies rather
   than sitting behind the text. */
.lattice-bg { position: relative; }
.lattice-bg::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(circle at 1px 1px, var(--line) 1px, transparent 0);
  background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(115% 105% at 92% 6%, #000 0%, transparent 58%);
  mask-image: radial-gradient(115% 105% at 92% 6%, #000 0%, transparent 58%);
  opacity: .7;
}
.lattice-bg > * { position: relative; z-index: 1; }

/* ------------------------------------------------------- scroll reveal ---- */

.rv { opacity: 0; transform: translateY(12px); transition: opacity .65s cubic-bezier(.22,.61,.36,1), transform .65s cubic-bezier(.22,.61,.36,1); }
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; transition: none; }
  .btn:hover, .card:hover .go svg { transform: none; }
}

/* ------------------------------------------------------------ utilities --- */

.mt-1 { margin-top: .75rem; } .mt-2 { margin-top: 1.5rem; } .mt-3 { margin-top: 2.5rem; }
.mt-4 { margin-top: 3.5rem; }
.tight { padding-top: 0; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
