/* ==========================================================================
   Matthew Liepins — site styles

   Mobile-first. Base rules target small screens; `min-width` queries layer on
   larger layouts. Organised as: tokens → fonts → base → primitives →
   components → states.

   The card is the spine of the design. Every block of content on the page is
   either a card, a grid of cards, or type sitting directly on the ground.
   ========================================================================== */

/* --- Tokens --------------------------------------------------------------
   Colour, type and spacing decisions live here and nowhere else.

   Contrast measured against --ink / --ink-raised: --chalk 14.6 / 13.8,
   --chalk-dim 8.4 / 7.9, --chalk-faint 4.85 / 4.59, --brand 12.6 / 11.9.
   Every token here clears WCAG AA at any text size, and ink on a solid
   --brand button measures 12.6:1.

   --brand sits at hue 78 degrees. That arc is the widest one the product
   colours leave open once purple is ruled out: Lore is at 36, Grove 158,
   Quarry 205. Keep any new colour at least 35 degrees clear of all four.
   ------------------------------------------------------------------------- */
:root {
  --ink: #0A0A0A;
  --ink-raised: #121211;
  --ink-sunken: #0E0E0D;

  --chalk: #E0DDD8;
  --chalk-dim: #ADA8A1;
  --chalk-faint: #827D76;

  --brand: #A8E01F;
  --brand-bright: #BCEE44;

  --line: rgba(255, 255, 255, 0.08);
  --line-bright: rgba(255, 255, 255, 0.16);

  --font-display: 'Syne', system-ui, sans-serif;
  --font-sans: 'DM Sans', system-ui, -apple-system, sans-serif;
  --font-mono: 'Space Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* Type scale. Every size on the page comes from this list. */
  --text-micro: 11px;
  --text-meta: 13px;
  --text-body: clamp(15px, 0.6vw + 13.4px, 16.5px);
  --text-lead: clamp(16.5px, 1vw + 13.5px, 20px);
  --text-subhead: clamp(19px, 1.6vw + 14px, 27px);
  --text-h3: clamp(21px, 1.4vw + 16px, 28px);
  --text-h2: clamp(29px, 1.9vw + 23px, 58px);
  --text-h1: clamp(27px, 3.1vw + 17px, 76px);
  --text-display: clamp(28px, 6.4vw + 7px, 112px);

  /* Spacing */
  --gutter: 20px;
  --section-y: 76px;
  --card-pad: 24px;
  --radius: 14px;
  --measure: 66ch;

  /* Accents. One per venture or product; the card glow reads from --accent. */
  --stratum: #E8484F;
  --stratum-text: #F4868B;
  --bench: #C9C4BC;
  --bench-text: #E0DDD8;
  --lore: #EF9F27;
  --lore-text: #F5C06B;
  --grove: #3CD39C;
  --grove-text: #7BFFCC;
  --quarry: #6E93AE;
  --quarry-text: #A8C6DA;

  /* Status. Deliberately not the product colours: --status-live sits 94°
     from --brand so a live badge never reads as brand chrome. */
  --status-live: #5EEAD4;
  --status-beta: #E5A33D;
  --status-build: #F4868B;
}

@media (min-width: 700px) {
  :root { --gutter: 32px; --section-y: 104px; --card-pad: 28px; }
}
@media (min-width: 1100px) {
  :root { --gutter: 48px; --section-y: 130px; --card-pad: 30px; }
}

/* --- Fonts ---------------------------------------------------------------
   Self-hosted, latin subset. DM Sans and Syne are variable (400–800), so the
   whole family is one file each. No third-party font request is made.
   ------------------------------------------------------------------------- */
@font-face {
  font-family: 'DM Sans';
  src: url('./fonts/dm-sans-var-latin.woff2') format('woff2');
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Syne';
  src: url('./fonts/syne-var-latin.woff2') format('woff2');
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Space Mono';
  src: url('./fonts/space-mono-400-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Space Mono';
  src: url('./fonts/space-mono-700-latin.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* --- Keyframes ----------------------------------------------------------- */
@keyframes marqueeScroll { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(10px); } }
@keyframes cursorBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
@keyframes statusPing {
  0% { transform: scale(1); opacity: 0.75; }
  75%, 100% { transform: scale(2.4); opacity: 0; }
}
/* The highlight is 38% of the track, so 265% carries it fully off the right. */
@keyframes trackScan {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(265%); }
}

/* --- Base ---------------------------------------------------------------- */
* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  background-color: var(--ink);
  color: var(--chalk-dim);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: 1.7;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  background-image:
    url("data:image/svg+xml,%3Csvg width='60' height='60' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='30' cy='30' r='0.8' fill='%23ffffff' opacity='0.07'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg width='300' height='300' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='60' cy='90' r='8' fill='none' stroke='%23ffffff' stroke-width='0.5' opacity='0.045'/%3E%3Ccircle cx='220' cy='40' r='5' fill='none' stroke='%23ffffff' stroke-width='0.5' opacity='0.04'/%3E%3Ccircle cx='150' cy='250' r='12' fill='none' stroke='%23ffffff' stroke-width='0.4' opacity='0.035'/%3E%3Cpath d='M240 200 L260 200 L260 220' fill='none' stroke='%23ffffff' stroke-width='0.5' opacity='0.05'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg width='400' height='400' xmlns='http://www.w3.org/2000/svg'%3E%3Cline x1='100' y1='50' x2='140' y2='50' stroke='%23A8E01F' stroke-width='0.4' opacity='0.07'/%3E%3Cline x1='300' y1='180' x2='300' y2='220' stroke='%23A8E01F' stroke-width='0.4' opacity='0.06'/%3E%3Cpath d='M50 300 Q70 280 90 300' fill='none' stroke='%23ffffff' stroke-width='0.5' opacity='0.05'/%3E%3C/svg%3E");
}

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

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

h1, h2, h3 { font-weight: 800; }

/* The custom cursor only replaces the native one once JS has actually started
   tracking it, so a script failure never leaves a pointerless page. */
html.has-custom-cursor,
html.has-custom-cursor a,
html.has-custom-cursor button { cursor: none; }

/* --- Focus --------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10000;
  padding: 12px 20px;
  background: var(--brand);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  text-decoration: none;
}
.skip-link:focus { left: 8px; top: 8px; }

/* ==========================================================================
   Primitives
   ========================================================================== */

.wrap { max-width: 1280px; margin: 0 auto; padding: 0 var(--gutter); }

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

.section-head { margin-bottom: 36px; }
@media (min-width: 700px) { .section-head { margin-bottom: 48px; } }

.eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--brand);
}

.label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--chalk-faint);
}

.section-title {
  font-family: var(--font-display);
  font-size: var(--text-h1);
  line-height: 0.98;
  letter-spacing: -0.035em;
  color: var(--chalk);
  margin: 18px 0 0;
}

.prose {
  font-family: var(--font-sans);
  font-size: var(--text-lead);
  line-height: 1.72;
  color: var(--chalk-dim);
  max-width: var(--measure);
  margin: 0;
  text-wrap: pretty;
}


/* --- Card ----------------------------------------------------------------
   The repeating unit. --accent drives the corner glow and the tagline colour.
   ------------------------------------------------------------------------- */
.card {
  --accent: var(--brand);
  --accent-text: var(--brand);
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: var(--card-pad);
  background: var(--ink-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color 0.35s ease, transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Corner bloom.
   This must stay `inset: 0` and use an explicitly sized ellipse. The earlier
   version floated a `circle` inside a box inset -40% 45% 55% -25%: on a wide,
   short card that box is wide and flat, but `circle` defaults to
   farthest-CORNER sizing, so the top and bottom edges land at roughly 30% of
   the radius — the gradient was still at 57% opacity where the box clipped it,
   drawing a hard horizontal band across the middle of the card.

   Anchoring the gradient to the card itself means the only place it can be
   clipped is the card's own rounded border, which reads as a boundary rather
   than an artefact. It fades out by ~75% across, leaving the far corner clean.
   ------------------------------------------------------------------------- */
.card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(140% 140% at -5% -10%, var(--accent) 0%, transparent 60%);
  opacity: 0.15;
  transition: opacity 0.5s ease;
  pointer-events: none;
}
.card > * { position: relative; }

@media (hover: hover) {
  .card:hover { border-color: var(--line-bright); transform: translateY(-4px); }
  .card:hover::before { opacity: 0.23; }
}

/* Wraps so a status badge drops below the name instead of colliding with
   it. The name is never allowed to shrink, so the badge is what moves. */
.card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 12px;
}
.card-name {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  letter-spacing: -0.02em;
  color: var(--chalk);
  margin: 0;
}
.card-tagline {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: clamp(15px, 0.5vw + 14px, 16.5px);
  color: var(--accent-text);
  margin: 12px 0 0;
}
.card-blurb {
  font-family: var(--font-sans);
  font-size: clamp(14.5px, 0.4vw + 13.5px, 15.5px);
  line-height: 1.65;
  color: var(--chalk-dim);
  margin: 10px 0 0;
  text-wrap: pretty;
}
.card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 5px 14px;
  margin: 18px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.4px;
  color: var(--chalk-faint);
}
.card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: auto;
  padding-top: 20px;
}

/* Feature card — the two ventures. Taller, roomier, image-capable. */
.card-feature { --card-pad: 26px; }
@media (min-width: 700px) { .card-feature { --card-pad: 34px; } }
/* Solved against the rendered width of "Hatchbench", the longest name,
   in the narrowest column this card ever occupies (228px at 320px). */
.card-feature .card-name { font-size: clamp(21px, 1.2vw + 17px, 40px); }

/* --- Status badge --------------------------------------------------------- */
.status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  padding: 5px 11px;
  border: 1px solid;
  border-radius: 100px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 1.4px;
  white-space: nowrap;
}
.status[data-tone='live'] {
  color: var(--status-live);
  border-color: rgba(94, 234, 212, 0.4);
  background: rgba(94, 234, 212, 0.1);
}
.status[data-tone='beta'] {
  color: var(--status-beta);
  border-color: rgba(229, 163, 61, 0.4);
  background: rgba(229, 163, 61, 0.08);
}
.status[data-tone='build'] {
  color: var(--status-build);
  border-color: rgba(244, 134, 139, 0.4);
  background: rgba(232, 72, 79, 0.10);
}
.status[data-tone='quiet'] { color: var(--chalk-dim); border-color: var(--line-bright); }

.dot { position: relative; display: inline-flex; width: 6px; height: 6px; flex: none; }
.dot::before,
.dot::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: currentColor; }
.dot::before { animation: statusPing 1.8s cubic-bezier(0, 0, 0.2, 1) infinite; }

/* --- Status tracker ------------------------------------------------------
   A live readout inside a card, for work that is ongoing rather than shipped.
   The bar is deliberately indeterminate — a sweeping highlight rather than a
   percentage — because a percentage would be a claim about progress that
   nobody can verify, and would go stale the moment it stopped being edited.
   Inherits --accent from the card it sits in.
   ------------------------------------------------------------------------- */
.tracker {
  margin-top: 18px;
  padding: 14px 16px;
  background: var(--ink-sunken);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.tracker-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.tracker-updated {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--chalk-faint);
  white-space: nowrap;
}

/* DM Sans, not the display face. Syne is wide enough that "Engine
   Development" overflowed this column at 320px and again at the 700px
   two-column breakpoint where the cards get narrow. The status string is
   also hand-edited, so it wraps rather than clipping if it ever runs long. */
.tracker-value {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-top: 9px;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(16px, 0.6vw + 14px, 19px);
  line-height: 1.35;
  letter-spacing: -0.005em;
  color: var(--accent-text);
}
.tracker-value .dot { color: var(--accent-text); margin-top: 0.5em; }

.tracker-bar {
  position: relative;
  height: 3px;
  margin-top: 12px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.07);
  overflow: hidden;
}
.tracker-bar::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 38%;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: trackScan 2.8s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

/* --- Buttons and links ---------------------------------------------------
   Minimum 46px tall so they clear the touch-target guidance on phones.
   ------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 46px;
  padding: 12px 22px;
  border-radius: 8px;
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  letter-spacing: 0.4px;
  text-decoration: none;
  transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}
.btn-primary { background: var(--brand); color: var(--ink); font-weight: 700; }
.btn-primary:hover { background: var(--brand-bright); }
.btn-chalk { background: var(--chalk); color: var(--ink); font-weight: 700; }
.btn-chalk:hover { background: #FFFFFF; }
.btn-ghost { color: var(--chalk-dim); border-color: var(--line-bright); }
.btn-ghost:hover { color: var(--chalk); border-color: var(--chalk-faint); }

.link-quiet {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  color: var(--chalk-faint);
  text-decoration: none;
  transition: color 0.3s ease;
}
.link-quiet:hover { color: var(--chalk); }

.link-underline {
  color: var(--brand);
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(168, 224, 31, 0.32);
  transition: border-bottom-color 0.3s ease;
}
.link-underline:hover { border-bottom-color: var(--brand); }

/* --- Grids ---------------------------------------------------------------- */
.grid { display: grid; gap: 16px; }
@media (min-width: 700px) { .grid { gap: 20px; } }

.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
@media (min-width: 900px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 700px) and (max-width: 1099px) { .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }

/* ==========================================================================
   Fixed chrome
   ========================================================================== */

.cursor-dot,
.cursor-glow { display: none; }

@media (hover: hover) and (pointer: fine) {
  .cursor-dot {
    display: block;
    position: fixed;
    left: -100px;
    top: -100px;
    width: 8px;
    height: 8px;
    background: var(--brand);
    border-radius: 50%;
    pointer-events: none;
    z-index: 9999;
    transform: translate(-50%, -50%);
    transition: width 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                height 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                background 0.3s ease, border 0.3s ease, opacity 0.3s ease;
    will-change: left, top;
  }
  .cursor-glow {
    display: block;
    position: fixed;
    left: -100px;
    top: -100px;
    width: 50px;
    height: 50px;
    background: radial-gradient(circle, rgba(168, 224, 31, 0.13) 0%, transparent 70%);
    border-radius: 50%;
    pointer-events: none;
    z-index: 9998;
    transform: translate(-50%, -50%);
    transition: opacity 0.3s ease;
    will-change: left, top;
  }
}

.progress-track { position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 1000; }
.progress-bar { height: 100%; width: 0%; background: var(--brand); }

/* --- Nav -----------------------------------------------------------------
   A single row at every width. The old layout stacked into a column on
   phones, which pushed a three-line header over the hero.
   ------------------------------------------------------------------------- */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  padding: 12px var(--gutter);
  background: rgba(10, 10, 10, 0.72);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s ease;
}
.nav[data-scrolled] { border-bottom-color: var(--line); }

.nav-mark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 17px;
  letter-spacing: -0.5px;
  color: var(--chalk);
  text-decoration: none;
}
.nav-links { display: flex; align-items: center; gap: 4px; }
.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.4px;
  color: var(--chalk-dim);
  text-decoration: none;
  transition: color 0.3s ease;
}
.nav-link:hover { color: var(--chalk); }
.nav-link[data-desktop-only] { display: none; }
@media (min-width: 560px) {
  .nav-links { gap: 8px; }
  .nav-link { padding: 0 12px; }
  .nav-link[data-desktop-only] { display: inline-flex; }
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 108px 0 72px;
  position: relative;
}
.hero-eyebrow { opacity: 0; animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.15s forwards; }
.hero-name {
  font-family: var(--font-display);
  font-size: var(--text-display);
  line-height: 0.88;
  letter-spacing: -0.045em;
  color: var(--chalk);
  margin: 22px 0 0;
  opacity: 0;
  animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.3s forwards;
}
.hero-tagline {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-subhead);
  line-height: 1.38;
  color: var(--chalk-dim);
  max-width: 22ch;
  margin: 24px 0 0;
  opacity: 0;
  animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.55s forwards;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 32px;
  opacity: 0;
  animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.75s forwards;
}
.hero-actions .btn { flex: 1 1 auto; }
@media (min-width: 560px) { .hero-actions .btn { flex: 0 0 auto; } }

.hero-hint {
  position: absolute;
  bottom: 26px;
  left: 0;
  right: 0;
  display: none;
  justify-content: center;
  opacity: 0;
  animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) 1.1s forwards;
}
@media (min-height: 720px) { .hero-hint { display: flex; } }
.hero-hint-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  animation: float 3s ease-in-out infinite;
}
.hero-hint-rule { width: 1px; height: 40px; background: linear-gradient(to bottom, var(--chalk-faint), transparent); }

/* --- Marquee -------------------------------------------------------------- */
.marquee-band {
  overflow: hidden;
  padding: 26px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  transform: rotate(-1.5deg);
  margin: 0 -8vw;
}
.marquee { display: flex; white-space: nowrap; animation: marqueeScroll 25s linear infinite; }
.marquee span {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(26px, 4.5vw, 54px);
  letter-spacing: 0.02em;
  color: rgba(224, 221, 216, 0.06);
  padding-right: 40px;
}

/* ==========================================================================
   Bio
   No sticky scroll-locking. The section sits in normal flow and the
   typewriter runs on a timer once the card scrolls into view, so the text is
   readable at any scroll speed and does not cost three screens of height.
   ========================================================================== */
.bio-grid { display: grid; gap: 24px; align-items: start; }
@media (min-width: 860px) { .bio-grid { grid-template-columns: 320px 1fr; gap: 44px; } }

.bio-photo {
  width: 100%;
  max-width: 320px;
  aspect-ratio: 3 / 4;
  background: var(--ink-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 860px) { .bio-photo { max-width: none; } }
.bio-photo img { width: 100%; height: 100%; object-fit: cover; }

.bio-heading {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  line-height: 1.04;
  letter-spacing: -0.03em;
  color: var(--chalk);
  margin: 0;
}
.bio-card { --accent: var(--brand); margin-top: 22px; }
.bio-card p {
  font-family: var(--font-sans);
  font-size: var(--text-lead);
  line-height: 1.8;
  color: var(--chalk);
  margin: 0;
  /* Hold the card's height steady while the text types in, so the page below
     does not jump on every character. */
  min-height: 11.5em;
}
@media (min-width: 560px) { .bio-card p { min-height: 9.5em; } }
@media (min-width: 860px) { .bio-card p { min-height: 8.5em; } }
.bio-caret { color: var(--brand); animation: cursorBlink 0.8s step-end infinite; }

.bio-chips { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 20px; }
.chip {
  display: inline-flex;
  align-items: center;
  padding: 9px 16px;
  border-radius: 100px;
  border: 1px solid;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.chip.revealed { opacity: 1; transform: translateY(0); }

/* ==========================================================================
   About
   ========================================================================== */
.statement {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-h2);
  line-height: 1.12;
  letter-spacing: -0.03em;
  color: var(--chalk);
  margin: 0;
  max-width: 20ch;
  text-wrap: pretty;
}
.facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin-top: 40px; }
@media (min-width: 700px) { .facts { grid-template-columns: repeat(4, 1fr); } }
.fact { background: var(--ink); padding: 20px var(--card-pad); }
.fact-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(16px, 0.6vw + 14px, 19px);
  color: var(--chalk);
  margin-top: 8px;
}

/* ==========================================================================
   Thoughts
   ========================================================================== */
.thought-date { margin-bottom: 12px; }
.thought-body {
  font-family: var(--font-sans);
  font-size: clamp(15px, 0.5vw + 14px, 16.5px);
  line-height: 1.72;
  color: var(--chalk-dim);
  margin: 0;
  text-wrap: pretty;
}

/* ==========================================================================
   Hatchbench
   ========================================================================== */
.hb-title {
  font-family: var(--font-display);
  font-size: clamp(26px, 4.9vw + 10px, 100px);
  line-height: 0.92;
  letter-spacing: -0.04em;
  color: var(--chalk);
  margin: 20px 0 0;
}
.hb-title em { font-style: normal; color: var(--brand); }

.hb-lede {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-subhead);
  line-height: 1.42;
  color: var(--chalk-dim);
  max-width: 44ch;
  margin: 24px 0 0;
  text-wrap: pretty;
}

.hb-siblings {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  margin-top: 40px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 700px) { .hb-siblings { grid-template-columns: repeat(2, 1fr); } }
.hb-sibling { background: var(--ink); padding: 22px var(--card-pad); }
.hb-sibling[data-current] { background: var(--ink-raised); }
.hb-sibling-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--chalk-faint);
}
.hb-sibling[data-current] .hb-sibling-name { color: var(--brand); }
.hb-sibling-role {
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  color: var(--chalk-faint);
  margin: 7px 0 0;
}
.hb-sibling[data-current] .hb-sibling-role { color: var(--chalk-dim); }

.hb-quote { margin: 44px 0 0; padding: 0 0 0 22px; border-left: 2px solid var(--brand); }
.hb-quote p {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-subhead);
  line-height: 1.4;
  letter-spacing: -0.015em;
  color: var(--chalk);
  margin: 0;
  max-width: 52ch;
  text-wrap: pretty;
}
.hb-quote cite {
  display: block;
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-style: normal;
  letter-spacing: 1px;
  color: var(--chalk-faint);
}

.hb-kits {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 18px var(--card-pad);
  background: var(--ink-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.hb-kit {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 14px;
  color: var(--chalk-dim);
  text-decoration: none;
  padding: 0 15px;
  border: 1px solid var(--line);
  border-radius: 100px;
  transition: color 0.3s ease, border-color 0.3s ease;
}
.hb-kit:hover { color: var(--chalk); border-color: var(--line-bright); }

.hb-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 44px;
  padding-top: 32px;
  border-top: 1px solid var(--line);
}
.hb-cta .btn { flex: 1 1 auto; }
@media (min-width: 560px) { .hb-cta .btn { flex: 0 0 auto; } }

/* ==========================================================================
   Contact / footer
   ========================================================================== */
.contact { text-align: center; }
.contact-inner { display: flex; flex-direction: column; align-items: center; }
.contact-title {
  font-family: var(--font-display);
  font-size: clamp(25px, 5vw + 9px, 96px);
  line-height: 1.02;
  letter-spacing: -0.04em;
  color: var(--chalk);
  margin: 20px 0 0;
  max-width: 15ch;
}
.contact-email {
  display: inline-block;
  margin-top: 30px;
  font-family: var(--font-mono);
  font-size: clamp(14px, 1.4vw + 10px, 20px);
  letter-spacing: 0.3px;
  word-break: break-word;
}

.footer {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 28px 0;
  border-top: 1px solid var(--line);
}
@media (min-width: 700px) { .footer { flex-direction: row; justify-content: space-between; align-items: center; } }
.footer-links { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.footer-note { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--chalk-faint); }

/* ==========================================================================
   Scroll reveal states
   Translations are small on phones — a 120px slide on a 390px-wide screen
   reads as content flying in from off-canvas.
   ========================================================================== */
[data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.75s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.75s cubic-bezier(0.16, 1, 0.3, 1);
}
[data-reveal].revealed { opacity: 1; transform: none; }


@media (min-width: 860px) {
  [data-reveal='left'] { transform: translateX(-60px); }
  [data-reveal='right'] { transform: translateX(60px); }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .marquee,
  .bio-caret,
  .hero-hint-inner,
  .tracker-bar::after,
  .dot::before { animation: none !important; }
  /* Without the sweep the track would read as an empty bar, so fill it. */
  .tracker-bar::after { width: 100%; background: var(--accent); opacity: 0.5; }
  .hero-eyebrow,
  .hero-name,
  .hero-tagline,
  .hero-actions,
  .hero-hint { opacity: 1; animation: none !important; }
  .card:hover { transform: none; }
  .chip { opacity: 1; transform: none; }
}
