/* ==========================================================================
   XYK LABS — ported from the original All Together Capital landing system
   Ink on paper: warm paper canvas, one ink line grid, dark ASCII video
   screens set into the page, mono data labels, wine-Tyrian accent.
   ========================================================================== */

@font-face {
  font-family: "Switzer";
  src: url("/fonts/switzer-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Geist Mono";
  src: url("/fonts/geist-mono-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #f2efe9;
  --ink: #1a1915;
  --ink-dim: rgba(26, 25, 21, 0.72);
  --ink-subtle: rgba(26, 25, 21, 0.5);
  /* ONE line on the whole site (Hisham: "i need all the lines on the website
     to match") — the legacy soft/seam tokens are aliases of the frame line,
     so every rule, seam, and card border rasterizes identically */
  --frame-line: #26251f;
  --frame-line-w: 1px;
  --line: var(--frame-line);
  --line-soft: var(--frame-line);
  --line-strong: var(--frame-line);
  /* wine-Tyrian accent (2026-07-09, replaced signal orange #ff4400) — the one
     color: wordmark, kickers, active nav tick, selection, selected strip cell,
     and the comet phosphor tint over media */
  --accent: #a51e5a;
  /* inverted panels: dark ink blocks sitting on the paper page */
  --paper: #1a1915;
  --paper-ink: #f2efe9;
  --paper-ink-dim: rgba(242, 239, 233, 0.66);

  --font-sans: "Switzer", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* ONE body size site-wide — every body paragraph reads these tokens */
  --fs-body: clamp(1.05rem, 1.25vw, 1.2rem);
  --lh-body: 1.55;

  --pad: clamp(22px, 3.2vw, 50px);
  /* GI grid geometry: rails ~10.6vw in from each edge (measured off their site).
     Past ~1980px the second term wins: the content column locks near 1560px and
     the rails absorb the extra width inside the (also capped) outer frame —
     ultrawide gets margins, not giant cells */
  --rail: round(max(clamp(16px, 10.6vw, 280px), calc((100vw - 1560px) / 2 - var(--outer-x))), 1px);
  --frame-gutter: var(--rail);
  --pad-inner: clamp(20px, 2.6vw, 48px);
  --pad-x: calc(var(--rail) + var(--pad-inner));
  /* outer frame: two vertical rules inset from the viewport sides, running
     the full height of the page — no top/bottom caps (removed 2026-07-08).
     Horizontally the frame caps at 2000px — past that the page becomes a
     centered card and the viewport edges go dead. Positions are snapped to
     whole pixels so every 1px line rasterizes at the same weight. */
  --outer: round(clamp(10px, 1.4vw, 22px), 1px);
  --outer-x: round(max(var(--outer), calc((100vw - 2000px) / 2)), 1px);
  /* shared height for section title + closing bands */
  --band-h: clamp(6rem, 9.6vw, 9.5rem);
  /* shared viewport breathing room for the hero and desktop rail */
  --bottom-inset: clamp(24px, 4vh, 48px);
  --ease-out: cubic-bezier(0.19, 1, 0.22, 1);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* no visible scrollbar — the frame owns the right edge */
  scrollbar-width: none;
}
html::-webkit-scrollbar { display: none; }

body {
  margin: 0;
  position: relative;
  /* no top inset — the page and its vertical rules run to the viewport top */
  padding: 0 var(--outer-x);
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 420;
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* the outer frame: two verticals only, top of page to bottom — no box caps */
.outer-frame {
  position: absolute;
  top: 0;
  left: var(--outer-x);
  right: var(--outer-x);
  bottom: 0;
  border-inline: var(--frame-line-w) solid var(--frame-line);
  pointer-events: none;
  z-index: 50;
}

::selection { background: var(--accent); color: var(--paper-ink); }

a { color: inherit; text-decoration: none; }

/* keyboard users get a visible ring everywhere; mouse users never see it */
a:focus-visible,
button:focus-visible,
input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

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

.skip-link {
  position: fixed;
  top: -100px; left: 16px;
  z-index: 500;
  background: var(--paper); color: var(--paper-ink);
  padding: 10px 16px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  transition: top 0.2s;
}
.skip-link:focus { top: 16px; }

.font-mono {
  font-family: var(--font-mono);
  font-weight: 460;
  letter-spacing: 0.07em;
}

.text-md {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-dim);
}

/* ==========================================================================
   SHELL — central column bounded by hairlines (the GI grid feel)
   ========================================================================== */

.shell {
  position: relative;
  width: 100%;
}

/* frame rails — continuous vertical guides at the content-column edges */
/* rails draw OVER content (GI-style) — content padding keeps text clear of them */
.shell::before,
.shell::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--frame-line-w);
  background: var(--frame-line);
  pointer-events: none;
  z-index: 4;
}
.shell::before { left: var(--frame-gutter); }
.shell::after { right: var(--frame-gutter); }

.pad { padding: var(--pad) var(--pad-x); }

.section {
  position: relative;
  border-top: var(--frame-line-w) solid var(--frame-line);
  /* desktop has no fixed header — anchors land flush on the section rule */
  scroll-margin-top: 0;
}

/* fingers need 44px; mice keep the compact GI proportion */
@media (pointer: coarse) {
  /* invisible hit-area extensions — the compact visuals stay, the target grows */
  .side-nav a,
  .brand-box,
  .side-email,
  .pf-link {
    position: relative;
  }
  /* brand-box uses ::before — its ::after is the double-rule line */
  .side-nav a::after,
  .brand-box::before,
  .side-email::after {
    content: "";
    position: absolute;
    inset: -9px 0;
  }
  .pf-link::after {
    content: "";
    position: absolute;
    inset: -15px 0;
  }
  .footer-col a { padding-block: 10px; }
  .pf-mark { min-height: 48px; }
}

/* ==========================================================================
   HERO
   ========================================================================== */

.hero {
  position: relative;
  min-height: calc(100svh - var(--bottom-inset));
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* the screen leads from the viewport top; the statement sits under it
   (2026-07-08 — "video then text", plus the headline the text was missing) */
.hero-screen {
  position: relative;
  flex: 1;
  min-height: 380px;
  margin-left: calc(var(--rail) + var(--frame-line-w));
  border-bottom: var(--frame-line-w) solid var(--frame-line);
  background: #000;
  overflow: hidden;
}
.hero-screen .ascii-host { position: absolute; inset: 0; }

/* home spread under the screen: statement left, lede bottom-aligned right */
.hero-content {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 11fr) minmax(0, 8fr);
  gap: clamp(28px, 5vw, 88px);
  align-items: end;
  padding: clamp(32px, 5.5vh, 64px) calc(var(--rail) + var(--pad-inner)) clamp(36px, 6vh, 72px);
}

.hero-kicker {
  margin: 0 0 clamp(12px, 1.8vh, 18px);
  font-size: 0.64rem;
  color: var(--accent);
}

.hero-title {
  margin: 0;
  max-width: 22ch;
  font-size: clamp(2rem, 3.3vw, 3.3rem);
  line-height: 1.12;
  font-weight: 560;
  letter-spacing: -0.026em;
  text-wrap: balance;
}

/* the full-height hero frame is drawn by .hero-guides instead */
.hero-content::before,
.hero-content::after { display: none; }

/* the two vertical grid lines, running full height over the hero ASCII */
.hero-guides {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}
.hero-guides::before,
.hero-guides::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--frame-line-w);
  background: var(--frame-line);
}
.hero-guides::before { left: var(--rail); }
.hero-guides::after { right: var(--rail); }

/* the lede: quieter than the statement, bottom-aligned beside it */
.hero-highlight {
  color: var(--ink-dim);
  max-width: 46ch;
  display: flex;
  flex-direction: column;
  gap: 0.9em;
}

.hero-highlight p {
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 470; /* lede weight — shared with the footer closer blurb */
}

/* Hero controls — settings toggle + panel */

.hero-controls {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  flex: none;
}

.settings-toggle {
  appearance: none;
  border: 0;
  background: none;
  color: var(--ink);
  opacity: 0.6;
  cursor: pointer;
  padding: 8px;
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
}
.settings-toggle:hover { opacity: 1; }
.settings-toggle[aria-expanded="true"] { opacity: 1; transform: rotate(90deg); }

.settings-panel {
  position: absolute;
  bottom: calc(100% + 10px);
  right: 0;
  width: min(300px, calc(100vw - 2 * var(--pad)));
  background: rgba(0, 0, 0, 0.82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid var(--line);
}

.settings-row {
  padding: 12px 16px;
  border-top: 1px solid var(--line-soft);
}
.settings-row:first-child { border-top: 0; }

.settings-head {
  font-size: 0.7rem;
  color: var(--ink-subtle);
}

.settings-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.64rem;
  color: var(--ink-subtle);
  margin-bottom: 9px;
}
.settings-label output { color: var(--ink-dim); }

input[type="range"] {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  height: 14px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 2px;
  background: var(--line-strong);
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px; height: 12px;
  margin-top: -5px;
  background: var(--ink);
  border-radius: 0;
  transition: background-color 0.2s;
}
input[type="range"]:hover::-webkit-slider-thumb { background: var(--accent); }
input[type="range"]::-moz-range-track {
  height: 2px;
  background: var(--line-strong);
}
input[type="range"]::-moz-range-thumb {
  width: 12px; height: 12px;
  background: var(--ink);
  border: 0; border-radius: 0;
}
input[type="range"]:hover::-moz-range-thumb { background: var(--accent); }

/* ==========================================================================
   SIDE RAIL — fixed nav column living in the left margin, between the outer
   frame's left border and the left grid line: those two existing lines ARE
   its edges. Brand band up top, section index, Email band pinned at bottom.
   Replaces the old scroll-out rail badges (brand/CTA are now always visible).
   ========================================================================== */

.side {
  position: fixed;
  top: 0;
  bottom: 0;
  left: var(--outer-x);
  width: calc(var(--rail) + var(--frame-line-w));
  z-index: 120;
  /* the column is a clean room: opaque paper paints over every section
     rule, tint panel, and stray pixel that would otherwise cross the zone —
     nothing lives here but the nav. It draws its own two vertical edges,
     sitting exactly where the outer frame border and the left grid line run */
  background: var(--bg);
  border-left: var(--frame-line-w) solid var(--frame-line);
  border-right: var(--frame-line-w) solid var(--frame-line);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: clamp(18px, 2.6vh, 26px);
  padding: clamp(64px, 12vh, 140px) 0 var(--bottom-inset);
  isolation: isolate;
}

/* One opaque utility block: brand, index, and contact share a single frame.
   Its paper fill is intentional protection from the live ASCII field below. */
.side-panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex: none;
  flex-direction: column;
  background: var(--bg);
  border-block: var(--frame-line-w) solid var(--frame-line);
}

/* boxed, letter-spaced wordmark band with its double rule underneath —
   the band's sides sit on the outer frame and the grid line */
.brand-box {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-block: var(--frame-line-w) solid var(--frame-line);
  padding: 7px 8px;
  color: var(--ink);
  font-family: var(--font-mono);
  font-weight: 620;
  /* bumped again from 0.8rem/0.24em ("gotta make the alltogether even
     bigger") — larger glyphs, tighter tracking, still inside the 150px rail */
  font-size: 1rem;
  letter-spacing: 0.15em;
  text-indent: 0.15em; /* recenters: the tracking trails the last glyph */
  line-height: 1;
  padding-block: 9px;
  white-space: nowrap;
  user-select: none;
  transition: color 0.25s;
}
.brand-cat { display: none; }
.side-panel > .brand-box { border-top: 0; }
.brand-box::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -5px;
  height: var(--frame-line-w);
  background: currentColor;
}
.brand-box:hover { color: var(--accent); }
/* the wordmark is the rail's "home" entry: lit while the hero is on screen,
   so exactly one index item is active at every scroll position */
.brand-box.active { color: var(--accent); }

.side-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 20px clamp(14px, 1.4vw, 24px) 14px;
}

/* the index speaks the site's label language: numbered mono caps, like a
   document's table of contents */
.side-nav a {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 6px 0;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.64rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: color 0.25s;
}

.side-nav .nav-i {
  color: var(--ink-subtle);
  transition: color 0.25s;
}
.side-nav a.active .nav-i { color: var(--accent); }
/* the index tick: an orange bar marks the section on screen */
.side-nav a::before {
  content: "";
  position: absolute;
  left: -11px;
  top: 50%;
  transform: translateY(-50%);
  width: 2px;
  height: 0.85em;
  background: var(--accent);
  opacity: 0;
  transition: opacity 0.25s;
}
.side-nav a:hover { color: var(--ink); }
.side-nav a.active { color: var(--accent); }
.side-nav a.active::before { opacity: 1; }

/* Contact closes the utility block directly beneath the index. */
.side-email {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 14px;
  border-block: var(--frame-line-w) solid var(--frame-line);
  font-family: var(--font-mono);
  font-weight: 560;
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  margin-top: 0;
  border-bottom: 0;
  transition: background-color 0.25s, color 0.25s;
}
.side-email:hover {
  background: var(--paper);
  color: var(--paper-ink);
}

/* The triple-cat crest occupies the quiet lower rail. It gives the
   margin a memorable identity while leaving the section index easy to scan. */
.side-seal {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: auto;
  padding: 22px 12px;
  border-block: var(--frame-line-w) solid var(--frame-line);
  background: var(--bg);
  color: var(--ink-subtle);
  text-align: center;
}

.side-seal-mark {
  display: block;
  width: min(126px, 86%);
  height: auto;
  opacity: 1;
  mix-blend-mode: multiply;
  transition: opacity 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}

.side-seal:hover { color: var(--accent); }
.side-seal:hover .side-seal-mark {
  opacity: 1;
  transform: translateY(-2px);
}

/* the rail margin needs room for the wordmark band on desktop, and the
   full-bleed hero video starts at the left grid line — never under the rail */
@media (min-width: 901px) {
  :root {
    --rail: round(max(clamp(150px, 10.6vw, 280px), calc((100vw - 1560px) / 2 - var(--outer-x))), 1px);
  }
}

/* below the rail layout the nav folds into a slim bar pinned to the top */
@media (max-width: 900px) {
  :root { --mobile-nav-h: 82px; }
  /* landing.js replaces the fallback with the sticky bar's measured height,
     including its wrapped phone layout and real loaded-font metrics. */
  /* Exact equality makes the sticky-bar bottom rule and section top rule
     occupy one visual datum after an anchor scroll. */
  .section { scroll-margin-top: var(--mobile-nav-h); }
  .side {
    position: sticky;
    top: 0;
    bottom: auto;
    left: auto;
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 16px;
    padding: 10px 14px;
    background: rgba(242, 239, 233, 0.92);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-left: 0;
    border-right: 0;
    border-bottom: var(--frame-line-w) solid var(--frame-line);
    z-index: 125;
  }
  .side-panel { display: contents; }
  .brand-box {
    gap: 7px;
    border: var(--frame-line-w) solid var(--frame-line);
    padding: 6px 10px;
  }
  .brand-cat {
    display: block;
    width: 30px;
    height: 22px;
    object-fit: contain;
    opacity: 1;
    mix-blend-mode: multiply;
  }
  /* Desktop removes this edge because the surrounding panel owns it. Once
     the panel dissolves on mobile, the brand box must own its complete frame
     and the same double bottom rule used by the desktop wordmark. */
  .side-panel > .brand-box {
    border-top: var(--frame-line-w) solid var(--frame-line);
  }
  .brand-box::after { display: block; }
  .side-nav { flex-direction: row; gap: 14px; padding-inline: 0; }
  .side-nav a::before { display: none; }
  .side-seal { display: none; }
  /* Once the rail becomes the horizontal header it no longer owns a left
     media gutter. Let the hero screen fill the complete framed width. */
  .hero-screen { margin-left: 0; }
  .side-email {
    margin: 0 0 0 auto;
    border: var(--frame-line-w) solid var(--frame-line);
    padding: 7px 12px;
  }
}

/* narrow phones: brand + email share the first row, the index wraps below */
@media (max-width: 600px) {
  :root { --mobile-nav-h: 120px; }
  /* the index wraps to a second row — JS measures the resulting bar */
  .side { flex-wrap: wrap; gap: 8px 12px; }
  .side-nav { order: 3; width: 100%; }
}

/* ==========================================================================
   SECTION FURNITURE
   ========================================================================== */

.section-title {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(10px, 1vw, 14px);
  min-height: var(--band-h);
  /* the rule under the title runs edge-to-edge, all the way to the frame */
  border-bottom: var(--frame-line-w) solid var(--frame-line);
}

.section-label {
  margin: 0;
  font-size: 0.64rem;
  line-height: 1;
  color: var(--accent);
  text-transform: uppercase;
}

/* empty closing band (team→footer only) — half the title-band height */
.section-end {
  border-top: var(--frame-line-w) solid var(--frame-line);
  min-height: calc(var(--band-h) / 2);
}

.section-title h2 {
  margin: 0;
  font-size: clamp(1.6rem, 2.75vw, 2.6rem);
  line-height: 1.1;
  font-weight: 540;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  margin-inline: var(--rail);
}

/* center divider between the two halves */
.split > :nth-child(2) {
  border-left: var(--frame-line-w) solid var(--frame-line);
}

/* full-width bright rule (spans gutters, all the way to the frame) */
.rule-full {
  border-top: var(--frame-line-w) solid var(--frame-line);
}

/* inside rail-bounded containers only the inner inset applies */
.split .pad { padding-inline: var(--pad-inner); }

.split-copy {
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 2.8vw, 40px);
  /* distribute across the full cell height so the copy fills its box (GI-style) */
  justify-content: space-between;
}

.split-media {
  position: relative;
}

/* invisible spacer sets the row's minimum height; --media-h (set by landing.js)
   keeps every section's media panel identical site-wide, with a 16:10 fallback
   when it's unset (no JS, or stacked layouts). The cell's own height stays auto
   so it can still stretch, and the ASCII covers whatever it gets. */
.split-media::before {
  content: "";
  display: block;
  height: var(--media-h, auto);
  aspect-ratio: 16 / 10;
  /* with a definite height the aspect ratio TRANSFERS to width (h × 1.6),
     poking past the cell and giving the page a horizontal scrollbar — cap it */
  max-width: 100%;
}

/* the card strip: pinned to the cell bottom, rule above, flush to the
   section's bottom rule, edge-to-edge in its cell; inverts white on hover */
.section-card {
  appearance: none;
  background: none;
  border: 0;
  border-top: var(--frame-line-w) solid var(--frame-line);
  margin-inline: calc(-1 * var(--pad-inner));
  margin-bottom: calc(-1 * var(--pad));
  padding: 26px var(--pad-inner) clamp(30px, 3.2vw, 48px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 0.25s, color 0.25s;
}

.section-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.section-card-arrow {
  color: var(--ink-subtle);
  font-size: 1.25rem;
  line-height: 1;
  transition: color 0.3s, transform 0.3s var(--ease-out);
}

.section-card:hover .section-card-arrow {
  color: var(--paper-ink);
  transform: translate(2px, -2px);
}
.section-card:hover {
  background: var(--paper);
  color: var(--paper-ink);
}
.section-card:hover .section-card-sub { color: var(--paper-ink-dim); }

.section-card-title {
  font-weight: 640;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.section-card-sub {
  color: var(--ink-subtle);
  font-size: 0.95rem;
  transition: color 0.25s;
}

/* section media panels — fill the grid cell completely (GI: width/height 100%) */
.ascii-square {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.ascii-square .ascii-host { position: absolute; inset: 0; }

/* Project and research plates run the hero film's renderer at the hero's own
   settings — same cell, tile, glyph, ramp and comet. What they do NOT share is
   the hero's fixed exposure: these clips are graded all over the place, so they
   carry data-expose="auto" and read their thresholds off each frame instead,
   landing near the hero's coverage whatever the shot (see ascii.js FILM_TOP). */
.ascii-square .pf-stage {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  background: #e7e1d9;
  opacity: 1;
  transition: opacity 0.28s var(--ease-out);
}

.ascii-square .pf-stage.is-swapping { opacity: 0.16; }

/* editorial pull quote: one orange rule, no panel wash — the rule gives the
   quote its identity (the old gradient backplate was rejected 2026-07-08) */
.quote {
  border-left: 2px solid var(--accent);
  padding: 4px 0 4px clamp(18px, 2vw, 26px);
  max-width: 58ch;
}
.quote p { margin: 0; color: var(--ink); font-weight: 490; }
.quote em { font-style: normal; color: var(--accent); }

/* ==========================================================================
   PORTFOLIO
   ========================================================================== */

/* portfolio player — featured ASCII stage + selectable mark strip */
.pf-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  width: 100%;
}

.pf-kicker {
  margin: 0;
  font-size: 0.64rem; /* ALL mono micro-labels share this one size */
  color: var(--accent);
}

.pf-count {
  margin: 0;
  font-size: 0.64rem;
  color: var(--ink-subtle);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* visit link — quiet mono row under the program note */
.pf-link {
  margin-top: 4px;
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-subtle);
  transition: color 0.25s;
  width: fit-content;
}
.pf-link:hover { color: var(--accent); }

.pf-title {
  margin: 0;
  font-size: clamp(1.9rem, 2.6vw, 2.6rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.04;
}

/* one logical block: keep it anchored to the top while the cell fills,
   so the kicker/title don't jump as descriptions change length */
.pf-info {
  gap: clamp(14px, 1.6vw, 22px);
  justify-content: flex-start;
  transition: opacity 0.3s var(--ease-out);
}

/* company swap: text dips while the stage crossfades */
.pf-info.pf-swapping { opacity: 0; }

/* logo strip between the rails, GI press-grid style: dim marks, white active cell */
.pf-strip {
  margin-inline: var(--rail);
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: 1px;
  background: var(--line-strong);
}

.pf-mark {
  appearance: none;
  border: 0;
  background: var(--bg);
  color: var(--ink-subtle);
  font: inherit;
  font-weight: 640;
  font-size: clamp(0.74rem, 0.92vw, 1rem);
  letter-spacing: -0.01em;
  line-height: 1.1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 clamp(10px, 1.4vw, 26px);
  height: clamp(58px, 5.8vw, 92px);
  cursor: pointer;
  transition: color 0.25s, background-color 0.25s;
}
/* GI press-grid hover: the whole cell inverts to the ink block — the "preview"
   weight that signals the strip is clickable */
.pf-mark:hover {
  color: var(--paper-ink);
  background: var(--paper);
}
/* selected = the accent commit: a solid accent cell, logo knocked out to cream
   (the accent is dark, so a light logo reads on it). Loudest state, so hover
   leaves it alone */
.pf-mark.active,
.pf-mark.active:hover {
  color: var(--paper-ink);
  background: var(--accent);
}

/* the logo itself: any source file rendered monochrome via mask + currentColor */
/* any logo file rendered monochrome via mask + currentColor.
   --ls / --lww are per-logo optical corrections set inline: icons get a
   taller box, ultra-wide wordmarks a wider one, so every mark reads at the
   same visual weight despite wildly different aspect ratios */
.pf-logo {
  display: block;
  width: min(var(--lww, 72%), 150px);
  height: calc(clamp(18px, 1.9vw, 30px) * var(--ls, 1));
  background: currentColor;
  mask-size: contain;
  mask-position: center;
  mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  transition: background-color 0.25s;
}


/* ==========================================================================
   STUDIO
   ========================================================================== */

/* One portrait and one studio statement: the closing section stays as direct
   as the lab itself instead of expanding into a second manifesto. */
.team-duo {
  margin-inline: var(--rail);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.team-duo > :nth-child(2) {
  border-left: var(--frame-line-w) solid var(--frame-line);
}

/* .team-duo already sits between the page rails, so its copy needs only the
   shared inner-cell inset. Using the page-level .pad width here applied the
   rail a second time and collapsed the text into a narrow center column. */
.team-duo .pad {
  padding-inline: var(--pad-inner);
}

.team-card {
  position: relative;
  display: flex;
  flex-direction: column;
  color: var(--ink);
}

.team-photo {
  position: relative;
  /* identical height to every other media panel (16:10 when --media-h unset),
     but the portrait also absorbs whatever extra height the studio copy adds —
     the card must never end in a band of dead paper below the caption */
  height: var(--media-h, auto);
  aspect-ratio: 16 / 10;
  flex: 1 0 auto;
  overflow: hidden;
}

/* selective ASCII: the subject stays photographic (data-mask cutout woven
   inside the canvas), the art fills the surround — no DOM layers above */
.team-photo .ascii-host {
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* caption band on paper below the screen — nothing sits over the media */
.team-caption {
  border-top: var(--frame-line-w) solid var(--frame-line);
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: clamp(18px, 1.8vw, 26px) var(--pad-inner) clamp(22px, 2.2vw, 32px);
}

.team-kicker {
  margin: 0;
  font-size: 0.64rem; /* ALL mono micro-labels share this one size */
  color: var(--accent);
}

.team-card-name {
  margin: 0;
  font-size: clamp(1.6rem, 2.3vw, 2.3rem);
  font-weight: 620;
  letter-spacing: -0.018em;
  line-height: 1.05;
}

.team-card .team-go {
  color: var(--ink-subtle);
  transition: color 0.3s, transform 0.3s var(--ease-out);
}

/* The caption band IS the link — the portrait above it is not clickable and
   does not trigger the invert. Hovering a photograph should not arm a link the
   pointer isn't on, and the band carries the name and the arrow that say where
   it goes. That makes this the same object as the contact card beside it: one
   clickable paper band that inverts under the pointer, nothing more. */
.team-caption {
  transition: background-color 0.3s, color 0.3s;
}
.team-caption:hover {
  background: var(--paper);
  color: var(--paper-ink);
}
.team-caption:hover .team-go {
  color: var(--paper-ink);
  transform: translate(2px, -2px);
}

/* Keep the two clickable closing bands on the same grid line. Their different
   type scales otherwise give the founder caption and contact card slightly
   different intrinsic heights, even though their bottom edges already match. */
@media (min-width: 1025px) {
  .team-caption,
  .team-about .section-card {
    min-height: 130px;
  }
}

/* ==========================================================================
   FOOTER
   ========================================================================== */

.footer {
  border-top: var(--frame-line-w) solid var(--frame-line);
}

/* links + copyright share one seam-grid box between the rails */
.footer-box {
  margin-inline: var(--rail);
  display: grid;
  gap: 1px;
  background: var(--line-strong);
}

.footer-links {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--line-strong);
}

/* Continue the link/copyright seam through both rails to the outer frame. On
   desktop the left segment sits directly under the fixed Email band's rule. */
.footer-links::before,
.footer-links::after {
  content: "";
  position: absolute;
  top: 100%;
  width: var(--rail);
  height: var(--frame-line-w);
  background: var(--frame-line);
  pointer-events: none;
}
.footer-links::before { right: 100%; }
.footer-links::after { left: 100%; }

.footer-col {
  display: flex;
  flex-direction: column;
  padding: clamp(20px, 2.4vw, 32px);
  background: var(--bg);
  font-size: 0.86rem;
}

.footer-col-head {
  margin: 0 0 6px;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--ink);
}

.footer-col a {
  color: var(--ink-subtle);
  transition: color 0.25s;
  width: fit-content;
  /* same visual rhythm as the old 9px gap, but a tappable ~33px target */
  padding-block: 5.5px;
}
.footer-col a:hover { color: var(--accent); }

.footer-fine { margin: 0; color: var(--ink-subtle); font-size: 0.78rem; padding-block: 5.5px; }

.footer-copy {
  margin: 0;
  background: var(--bg);
  padding: 24px clamp(20px, 2.6vw, 48px) 32px;
  color: var(--ink-subtle);
  font-size: 0.78rem;
}

/* ==========================================================================
   ASCII host
   ========================================================================== */

.ascii-host {
  position: relative;
  overflow: hidden;
  /* screens boot as bare black plates — no poster backdrop, no load fade;
     the first frame paints the moment it exists */
  background-color: #000;
}

.ascii-host canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* ==========================================================================
   REVEALS
   ========================================================================== */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
}
.reveal.in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .team-go { transition: none; }
  .section-card-arrow { transition: none; }
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 1024px) {
  .split { grid-template-columns: 1fr; }
  .split > :nth-child(2) {
    border-left: 0;
    border-top: var(--frame-line-w) solid var(--frame-line);
  }
  /* thesis stacks film-first like the portfolio player; the divider moves
     to the copy block so the single line stays between the two */
  #thesis .split-media { order: -1; border-top: 0; }
  #thesis .split-copy { border-top: var(--frame-line-w) solid var(--frame-line); }
  .team-duo { grid-template-columns: 1fr; }
  .team-duo > :nth-child(2) {
    border-left: 0;
    border-top: var(--frame-line-w) solid var(--frame-line);
  }
  .pf-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .footer-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* odd column out spans the row — an unfilled cell paints the dark seam
     background as a solid ink block */
  .footer-links > .footer-col:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

@media (max-width: 720px) {
  :root {
    --rail: 0px;
    --pad-x: 18px;
    --outer: 0px;
  }
  .shell::before,
  .shell::after,
  .hero-guides,
  .outer-frame { display: none; }
  .hero-content { grid-template-columns: 1fr; gap: 20px; padding-inline: var(--pad-x); }
  .hero-screen { margin-left: 0; min-height: 46svh; }
  .hero-controls {
    position: static;
    flex-direction: row;
    justify-content: flex-end;
  }
  .settings-panel {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(340px, calc(100vw - 32px));
    z-index: 130;
  }
  .footer-links { grid-template-columns: 1fr; }
}

/* ========================================================================== 
   XYK CONTENT ADAPTATION
   The frame, typography, spacing, media treatment, and motion above remain
   the original ATC system. These rules only adapt its content geometry.
   ========================================================================== */

.work-section .pf-strip {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* research runs four experiments as a 2x2 block at every width */
#research .pf-strip {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.team-about {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(24px, 3vw, 42px);
}

.team-about h3 {
  max-width: 18ch;
  margin: 14px 0 0;
  font-size: clamp(1.9rem, 3vw, 3.2rem);
  font-weight: 560;
  letter-spacing: -0.035em;
  line-height: 1.04;
  text-wrap: balance;
}

.team-about > .text-md {
  max-width: 42ch;
  margin: 0;
}

.studio-note {
  display: grid;
  grid-template-columns: minmax(120px, 0.42fr) minmax(0, 1fr);
  gap: clamp(20px, 2.4vw, 36px);
  padding-block: clamp(20px, 2vw, 28px);
  border-block: var(--frame-line-w) solid var(--frame-line);
}

.studio-note p { margin: 0; }

.studio-note-kicker {
  color: var(--accent);
  font-size: 0.64rem;
  line-height: 1.45;
  letter-spacing: 0.06em;
}

.studio-note p:last-child {
  max-width: 38ch;
  color: var(--ink-dim);
  font-size: clamp(0.95rem, 1.08vw, 1.06rem);
  line-height: 1.55;
  text-wrap: pretty;
}

.team-about .section-card {
  margin-top: auto;
}

@media (max-width: 1024px) {
  .work-section .pf-strip {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  .studio-note { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .work-section .pf-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
