/* ===========================================================================
   VVCT — one-page site.
   All of the design lives in this file. Content lives in src/content/*.md.

   The design is a light single page in four sections: hero, capability grid,
   approach, contact. Two typefaces carry it — a system grotesque for display
   and prose, the system monospace for labels, nav and metadata — which keeps
   the engineering register of the old card design without the card chrome.

   Ink on paper: warm off-white ground, near-black text, hairlines rather than
   boxes, and type kept at book weights — nothing is set bold except the small
   monospace labels, and those only to semibold.

   Nothing on the page is numbered (see AGENTS.md, hard rule 4), and every
   foreground/background pair clears WCAG AA: the tightest are --muted on
   --bg at about 5.4:1 and --accent on --bg at about 5.2:1.
   =========================================================================== */

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

* {
  margin: 0;
  padding: 0;
}

:root {
  color-scheme: light;

  /* Palette */
  --bg: #faf9f7;
  --ink: #17171a;
  --body: #45454b;
  --muted: #66666d;
  --line: #e6e4de;
  --accent: #b8412e;

  /* Label weight. Bold monospace that read as restraint on the dark ground
     reads as shouting on paper; semibold carries the same labels. */
  --label-weight: 600;

  /* Type */
  --sans: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
    Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas,
    'Liberation Mono', 'DejaVu Sans Mono', monospace;

  /* Rhythm */
  --wrap: 1100px;
  --pad-x: clamp(20px, 5vw, 48px);
  --head-h: 88px;
  --tap: 44px;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--head-h) + 24px);
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  overflow-wrap: break-word;
  padding-bottom: env(safe-area-inset-bottom);
}

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

.wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: max(var(--pad-x), env(safe-area-inset-left));
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* --- Header ---------------------------------------------------------------- */

.site-head {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--head-h);
}

.brand {
  display: flex;
  align-items: center;
  min-height: var(--tap);
}

.brand img {
  display: block;
  width: auto;
  height: 56px;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(2px, 1vw, 12px);
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 clamp(8px, 1.5vw, 14px);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: var(--label-weight);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
  transition: color 0.15s ease;
}

.site-nav a:hover {
  color: var(--ink);
}

.site-nav a[aria-current] {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}

@media (max-width: 560px) {
  .brand img {
    height: 40px;
  }

  .site-nav a {
    font-size: 11px;
    letter-spacing: 0.08em;
  }
}

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

.hero {
  padding-block: clamp(88px, 16vh, 170px) clamp(64px, 10vh, 104px);
}

.kicker {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: var(--label-weight);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: clamp(20px, 3vw, 32px);
}

.hero h1 {
  font-size: clamp(2.5rem, 7.4vw, 4.9rem);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.03em;
  max-width: 14ch;
  text-wrap: balance;
}

.lede {
  margin-top: clamp(24px, 4vw, 36px);
  font-size: clamp(1.0625rem, 1rem + 0.5vw, 1.25rem);
  line-height: 1.65;
  color: var(--body);
  max-width: 56ch;
}

.cta {
  display: inline-flex;
  align-items: center;
  margin-top: clamp(32px, 5vw, 48px);
  min-height: var(--tap);
  padding: 0 26px;
  border: 1px solid var(--muted);
  font-family: var(--mono);
  font-size: 13px;
  font-weight: var(--label-weight);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  transition: color 0.15s ease, border-color 0.15s ease;
}

.cta:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* --- Sections ---------------------------------------------------------------- */

.section {
  border-top: 1px solid var(--line);
  padding-block: clamp(72px, 12vw, 128px);
}

.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: var(--label-weight);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}

.section h2 {
  font-size: clamp(1.75rem, 4vw, 2.6rem);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  max-width: 24ch;
  text-wrap: balance;
  margin-bottom: clamp(28px, 5vw, 48px);
}

/* --- Capability grid --------------------------------------------------------- */

/* A hairline grid: each cell outlines itself in the line colour and the 1px
   gap is exactly filled by the two outlines that meet in it, so the rules read
   as drawn, not as floating boxes.

   The outline is what keeps this robust. Painting the lines as a background
   behind the gaps is the obvious alternative, but that colour also shows
   through any track the cells do not fill — a row of two under a row of three
   ends in a grey slab — which forces the last cell to span the row and breaks
   the moment the cell count divides evenly. Outlines are drawn by the cells
   themselves, so an unfilled track is simply page. */
.cells {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 1px;
  margin: 1px;
}

.cell {
  background: var(--bg);
  outline: 1px solid var(--line);
  padding: clamp(22px, 3vw, 32px);
}

.cell h3 {
  font-size: 1.05rem;
  font-weight: 560;
  letter-spacing: -0.01em;
  margin-bottom: 14px;
  transition: color 0.15s ease;
}

.cell:hover h3 {
  color: var(--accent);
}

.cell p {
  color: var(--body);
  font-size: 0.95rem;
  line-height: 1.6;
}

/* --- Prose ------------------------------------------------------------------- */

.prose {
  max-width: 62ch;
}

.prose p {
  color: var(--body);
  font-size: 1.0625rem;
  line-height: 1.7;
  margin-bottom: 1.4em;
}

.prose p:last-child {
  margin-bottom: 0;
}

.prose a,
.rows a {
  color: var(--ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition: color 0.15s ease;
}

.prose a:hover,
.rows a:hover {
  color: var(--accent);
}

.plain {
  list-style: none;
  margin-bottom: 1.4em;
}

.plain li {
  position: relative;
  padding-left: 1.6em;
  color: var(--body);
  line-height: 1.7;
}

.plain li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.85em;
  width: 0.8em;
  height: 1px;
  background: var(--muted);
}

/* --- Contact rows -------------------------------------------------------------- */

.rows {
  border-top: 1px solid var(--line);
}

.row {
  display: grid;
  grid-template-columns: clamp(88px, 18vw, 160px) 1fr;
  gap: 16px;
  align-items: baseline;
  padding-block: 16px;
  border-bottom: 1px solid var(--line);
}

.row dt {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: var(--label-weight);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.row dd {
  color: var(--body);
}

/* --- Footer ---------------------------------------------------------------------- */

.site-foot {
  border-top: 1px solid var(--line);
  padding-block: 28px;
}

.site-foot p {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: var(--label-weight);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --- Reveal on scroll --------------------------------------------------------------
   app.js adds .reveal before observing and .in when a section enters the
   viewport. Without JavaScript neither class exists and everything is simply
   visible. */

.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal.in {
  opacity: 1;
  transform: none;
}

/* --- Utilities ----------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--pad-x);
  background: var(--ink);
  color: var(--bg);
  padding: 12px 20px;
  text-decoration: none;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 2px;
  z-index: 1000;
}

.skip-link:focus {
  top: 10px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  * {
    transition: none !important;
    animation: none !important;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }
}

/* --- Print ------------------------------------------------------------------------------
   The screen design is already ink on paper, so printing only has to drop the
   chrome and take the tint out of the ground. */

@media print {
  body {
    background: #fff;
    color: #000;
  }

  .site-head,
  .skip-link,
  .cta,
  .site-foot {
    display: none;
  }

  .hero,
  .section {
    padding-block: 24px;
    border: 0;
  }

  .cell {
    background: #fff;
    outline-color: #ccc;
  }
}
