/* ─────────────────────────────────────────────────────────────────────
   neilbuilds.dev — "load-bearing"

   Weathering steel. Corten is the alloy you choose BECAUSE it rusts:
   the oxide layer is the protection, not the failure. Twelve years of
   production software has the same shape, so the palette is literal.

   This stylesheet is shared by four pages that do two different jobs.
   The profile is allowed to be loud. /privacy and /sms-terms are read
   by a carrier reviewer hunting one sentence, and they inherit the
   palette but nothing else — see `.doc` at the bottom.
   ───────────────────────────────────────────────────────────────────── */

:root {
  --ground:    #14110F;
  --panel:     #1C1815;
  --panel-2:   #241F1B;
  --rule:      #332C26;
  --rule-lit:  #4A4038;

  --oxide:     #C1502E;
  --oxide-br:  #E4703F;
  --oxide-dim: #6B2F1C;

  --text:      #E6DFD5;
  --dim:       #8A8078;
  --faint:     #574F48;
  --steel:     #7D8B94;

  --display: 'Archivo', 'Archivo Expanded', 'Helvetica Neue', sans-serif;
  --body:    'Newsreader', Georgia, 'Times New Roman', serif;
  --mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;

  --gutter: clamp(20px, 5vw, 72px);
  --measure: 64ch;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--body);
  font-size: clamp(16px, 1.05vw + 12px, 19px);
  line-height: 1.62;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
}

/* Grain. Two layers: a fine noise for tooth, and a very wide vertical
   gradient so the page reads as lit from above rather than flat. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 100;
  opacity: .30;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 99;
  background: linear-gradient(180deg, rgba(228,112,63,.045) 0%, rgba(0,0,0,0) 38%, rgba(0,0,0,.30) 100%);
}

/* ── type ─────────────────────────────────────────────────────────── */

h1, h2, h3, .eyebrow, .nav a, .btn {
  font-family: var(--display);
  font-variation-settings: 'wdth' 112;
}

h1 {
  font-weight: 800;
  font-variation-settings: 'wdth' 120;
  font-size: clamp(2.6rem, 9.5vw, 7.4rem);
  line-height: .88;
  letter-spacing: -.028em;
  margin: 0;
  text-wrap: balance;
}

h2 {
  font-weight: 700;
  font-size: clamp(1.5rem, 3.2vw, 2.4rem);
  line-height: 1.04;
  letter-spacing: -.018em;
  margin: 0 0 .6em;
  text-wrap: balance;
}

h3 {
  font-weight: 600;
  font-size: 1.06rem;
  letter-spacing: -.006em;
  margin: 0 0 .35em;
}

p { margin: 0 0 1.05em; max-width: var(--measure); }
a { color: var(--oxide-br); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--text); }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--oxide-br);
  outline-offset: 3px;
}

.eyebrow {
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--oxide);
  font-variation-settings: 'wdth' 100;
  margin: 0 0 1.1rem;
  display: flex;
  align-items: center;
  gap: .8em;
}
.eyebrow::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--rule-lit), transparent);
}

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ── layout ───────────────────────────────────────────────────────── */

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

section { padding: clamp(56px, 9vw, 120px) 0; border-top: 1px solid var(--rule); }
section:first-of-type { border-top: 0; }

/* ── nav ──────────────────────────────────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: baseline;
  gap: clamp(14px, 3vw, 34px);
  padding: 16px var(--gutter);
  background: rgba(20,17,15,.86);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
  flex-wrap: wrap;
}
.nav .mark {
  font-family: var(--display);
  font-weight: 800;
  font-variation-settings: 'wdth' 118;
  font-size: .95rem;
  letter-spacing: -.01em;
  color: var(--text);
  text-decoration: none;
  margin-right: auto;
}
.nav .mark b { color: var(--oxide-br); font-weight: 800; }
.nav a:not(.mark) {
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-variation-settings: 'wdth' 100;
  color: var(--dim);
  text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: color .18s, border-color .18s;
}
.nav a:not(.mark):hover,
.nav a[aria-current="page"] { color: var(--oxide-br); border-bottom-color: var(--oxide); }

/* ── hero ─────────────────────────────────────────────────────────── */

/* Two columns: the type, and the rotating cluster. Stacks on narrow screens,
   type first. The cluster carries the visual weight the removed diagram left. */
.hero {
  padding-top: clamp(40px, 7vw, 90px);
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(20px, 3vw, 50px);
  align-items: center;
}
@media (max-width: 880px) {
  .hero { grid-template-columns: 1fr; gap: 8px; }
}
.hero .stage {
  position: relative;
  aspect-ratio: 1 / 0.82;
  min-height: 240px;
}
.hero .stage canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  /* Decorative and aria-hidden: never intercept touch, so a finger dragged over
     it scrolls the page normally instead of being captured. */
  pointer-events: none;
}
@media (max-width: 880px) {
  .hero .stage { min-height: 300px; margin-top: 10px; }
}
/* The hero H1 shares its row with the cluster now, so it is sized to keep
   "Neil Le" on one line in the narrower column rather than the full-width
   7.4rem used elsewhere. On a stacked phone it goes full width and grows again. */
.hero h1 { font-size: clamp(2.4rem, 5.6vw, 4.8rem); }
@media (max-width: 880px) { .hero h1 { font-size: clamp(2.6rem, 12vw, 4.4rem); } }
.hero .role {
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--steel);
  margin: 0 0 1.4rem;
}
.hero h1 .thin {
  font-weight: 300;
  font-variation-settings: 'wdth' 118;
  color: var(--dim);
  display: block;
}
.hero .lede {
  font-size: clamp(1.08rem, 1.5vw, 1.34rem);
  line-height: 1.5;
  color: var(--text);
  max-width: 54ch;
  margin: 2.1rem 0 0;
}
.hero .lede em { color: var(--oxide-br); font-style: normal; }

/* ── the span drawing ─────────────────────────────────────────────── */

figure.span {
  margin: clamp(38px, 6vw, 68px) 0 0;
  padding: clamp(18px, 3vw, 34px);
  background:
    linear-gradient(var(--panel), var(--panel)) padding-box,
    linear-gradient(140deg, var(--rule-lit), var(--rule) 40%, var(--oxide-dim)) border-box;
  border: 1px solid transparent;
  overflow-x: auto;
}
figure.span svg { display: block; width: 100%; height: auto; min-width: 540px; color: var(--dim); }
figure.span figcaption {
  font-family: var(--mono);
  font-size: .74rem;
  line-height: 1.62;
  color: var(--dim);
  margin-top: 1.1rem;
  padding-top: .9rem;
  border-top: 1px solid var(--rule);
  max-width: 74ch;
}

/* ── load figures ─────────────────────────────────────────────────── */

.loads {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}
.load { background: var(--panel); padding: clamp(18px, 2.6vw, 28px); }
.load .n {
  font-family: var(--display);
  font-variation-settings: 'wdth' 122;
  font-weight: 800;
  font-size: clamp(1.7rem, 3.4vw, 2.7rem);
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--oxide-br);
  font-variant-numeric: tabular-nums;
}
.load .l {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  margin-top: .7rem;
  line-height: 1.45;
}

/* ── work ─────────────────────────────────────────────────────────── */

.job {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: clamp(14px, 3vw, 46px);
  padding: clamp(26px, 3.6vw, 42px) 0;
  border-top: 1px solid var(--rule);
}
.job:first-of-type { border-top: 0; padding-top: 0; }
@media (max-width: 760px) { .job { grid-template-columns: 1fr; } }

.job .meta { font-family: var(--mono); font-size: .74rem; line-height: 1.75; }
.job .meta .org { color: var(--text); font-weight: 600; letter-spacing: .02em; }
.job .meta .when { color: var(--faint); }
.job .meta .where { color: var(--steel); }

.job h3 {
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  font-weight: 700;
  font-variation-settings: 'wdth' 114;
  color: var(--text);
}
.job ul { list-style: none; margin: .9rem 0 0; padding: 0; }
.job li {
  position: relative;
  padding-left: 1.5rem;
  margin-bottom: .8rem;
  max-width: var(--measure);
  color: var(--dim);
}
.job li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .72em;
  width: .7rem;
  height: 1px;
  background: var(--oxide);
}
.job li strong { color: var(--text); font-weight: 600; }

/* ── stack ────────────────────────────────────────────────────────── */

.stack { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 1.6rem; }
.stack span {
  font-family: var(--mono);
  font-size: .73rem;
  padding: 5px 11px;
  border: 1px solid var(--rule-lit);
  color: var(--dim);
  background: var(--panel);
}
.stack span.hot { color: var(--oxide-br); border-color: var(--oxide-dim); }

/* ── contact / compliance ─────────────────────────────────────────── */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(20px, 4vw, 52px);
  align-items: start;
}

.channel {
  display: block;
  padding: clamp(18px, 2.6vw, 26px);
  background: var(--panel);
  border: 1px solid var(--rule);
  text-decoration: none;
  transition: border-color .2s, background .2s, transform .2s;
}
.channel:hover { border-color: var(--oxide); background: var(--panel-2); transform: translateY(-2px); }
.channel .k {
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--steel);
}
.channel .v {
  font-family: var(--display);
  font-variation-settings: 'wdth' 112;
  font-weight: 600;
  font-size: clamp(1rem, 1.9vw, 1.3rem);
  color: var(--text);
  margin-top: .5rem;
  word-break: break-word;
}
.channel:hover .v { color: var(--oxide-br); }

/* The A2P disclosure. This block is the reason the campaign passes;
   it is deliberately unmissable rather than buried in a footer. */
.disclosure {
  border-left: 3px solid var(--oxide);
  background: var(--panel);
  padding: clamp(16px, 2.4vw, 24px);
  margin-top: 1.6rem;
}
.disclosure p {
  font-family: var(--mono);
  font-size: .78rem;
  line-height: 1.7;
  color: var(--dim);
  margin: 0;
  max-width: 68ch;
}
.disclosure p + p { margin-top: .8rem; }
.disclosure strong { color: var(--text); font-weight: 600; }

/* ── form ─────────────────────────────────────────────────────────── */

.field { margin-bottom: 1.4rem; max-width: 34rem; }
.field label {
  display: block;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: .55rem;
}
.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field textarea {
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--rule-lit);
  color: var(--text);
  font-family: var(--body);
  font-size: 1rem;
  padding: .72rem .85rem;
  border-radius: 0;
}
.field textarea { min-height: 8rem; resize: vertical; font-size: .96rem; }
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field .hint { font-family: var(--mono); font-size: .7rem; color: var(--faint); margin-top: .45rem; }

.consent {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .85rem;
  align-items: start;
  max-width: 40rem;
  padding: clamp(14px, 2vw, 20px);
  background: var(--panel);
  border: 1px solid var(--rule-lit);
  border-left: 3px solid var(--oxide);
  margin: 1.8rem 0;
}
.consent input[type="checkbox"] {
  width: 1.15rem;
  height: 1.15rem;
  margin: .18rem 0 0;
  accent-color: var(--oxide);
  flex: none;
}
.consent label {
  font-family: var(--mono);
  font-size: .76rem;
  line-height: 1.68;
  color: var(--dim);
  margin: 0;
  text-transform: none;
  letter-spacing: 0;
}
.consent label a { color: var(--oxide-br); }

.btn {
  display: inline-block;
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-variation-settings: 'wdth' 105;
  color: var(--ground);
  background: var(--oxide-br);
  border: 1px solid var(--oxide-br);
  padding: .85rem 1.7rem;
  cursor: pointer;
  border-radius: 0;
  transition: background .18s, color .18s;
}
.btn:hover { background: transparent; color: var(--oxide-br); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.formnote {
  font-family: var(--mono);
  font-size: .74rem;
  color: var(--steel);
  margin-top: 1rem;
  min-height: 1.2em;
}
.formnote.err { color: var(--oxide-br); }

/* ── footer ───────────────────────────────────────────────────────── */

footer {
  border-top: 1px solid var(--rule);
  padding: clamp(30px, 5vw, 56px) 0 clamp(38px, 6vw, 70px);
  font-family: var(--mono);
  font-size: .74rem;
  color: var(--faint);
}
footer .flinks { display: flex; flex-wrap: wrap; gap: 1.4rem; margin-bottom: 1.4rem; }
footer .flinks a { color: var(--dim); text-decoration: none; border-bottom: 1px solid var(--rule-lit); padding-bottom: 2px; }
footer .flinks a:hover { color: var(--oxide-br); border-bottom-color: var(--oxide); }
footer p { font-size: .74rem; color: var(--dim); max-width: 70ch; margin: 0 0 .5em; }
/* The A2P sentence appears in the footer of every page on purpose, so it is
   never more than one screen away from wherever a reviewer happens to land.
   It has to be legible to do that job. */
footer p:last-child { color: var(--steel); }

/* ── documents (/privacy, /sms-terms) ─────────────────────────────────
   Deliberately quiet. A carrier reviewer is scanning for one sentence
   and a recruiter may be reading it on a phone; neither is served by
   the drawing-board treatment the profile gets. */

.doc { max-width: 46rem; padding: clamp(40px, 7vw, 82px) 0; }
.doc h1 {
  font-size: clamp(2rem, 5.2vw, 3.1rem);
  font-variation-settings: 'wdth' 116;
  font-weight: 700;
  line-height: 1;
  margin-bottom: .5rem;
}
.doc .updated {
  font-family: var(--mono);
  font-size: .74rem;
  color: var(--dim);
  letter-spacing: .06em;
  margin-bottom: 2.6rem;
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--rule);
}
.doc h2 {
  font-size: clamp(1.12rem, 2vw, 1.4rem);
  font-variation-settings: 'wdth' 108;
  margin: 2.6rem 0 .7rem;
  color: var(--text);
}
.doc h3 { color: var(--steel); font-size: .95rem; margin: 1.7rem 0 .4rem; }
.doc p, .doc li { color: var(--dim); font-size: .98rem; }
.doc ul { padding-left: 1.15rem; margin: 0 0 1.1em; }
.doc li { margin-bottom: .5em; max-width: var(--measure); }
.doc strong { color: var(--text); font-weight: 600; }

/* The sentence carriers look for. Marked so it cannot be missed by a
   reviewer skimming, and so it cannot be quietly edited away later. */
.doc .keystone {
  border-left: 3px solid var(--oxide);
  background: var(--panel);
  padding: 1.1rem 1.3rem;
  margin: 1.4rem 0 1.8rem;
}
.doc .keystone p { color: var(--text); margin: 0; font-size: 1rem; }

.doc table { width: 100%; border-collapse: collapse; margin: 1rem 0 1.6rem; font-size: .88rem; }
.doc th, .doc td {
  text-align: left;
  padding: .6rem .8rem;
  border: 1px solid var(--rule);
  vertical-align: top;
}
.doc th {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--steel);
  background: var(--panel);
  font-weight: 600;
}
.doc td { color: var(--dim); }
.doc td.mono { font-family: var(--mono); font-size: .8rem; color: var(--text); }

/* On a phone a three-column table is three columns of one word each. These
   are documents someone actually reads — a carrier reviewer looking for one
   sentence, a recruiter on a train — so the rows stack into cards instead.
   The header row is dropped because the first cell already names the row. */
@media (max-width: 640px) {
  .doc table { display: block; margin: 1.2rem 0 1.8rem; }
  .doc thead { display: none; }
  .doc tbody { display: block; }
  .doc tr {
    display: block;
    border: 1px solid var(--rule);
    margin-bottom: .8rem;
    background: var(--panel);
  }
  .doc td { display: block; border: 0; border-top: 1px solid var(--rule); }
  .doc tr td:first-child {
    border-top: 0;
    color: var(--text);
    font-family: var(--mono);
    font-size: .72rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    background: var(--panel-2);
  }
}

/* ── page-load reveal ─────────────────────────────────────────────────
   One orchestrated sequence on the profile, nothing scattered. */
.rise { opacity: 0; transform: translateY(14px); animation: rise .78s cubic-bezier(.2,.7,.3,1) forwards; }
.rise:nth-child(1) { animation-delay: .04s; }
.rise:nth-child(2) { animation-delay: .13s; }
.rise:nth-child(3) { animation-delay: .22s; }
.rise:nth-child(4) { animation-delay: .31s; }
.rise:nth-child(5) { animation-delay: .40s; }
@keyframes rise { to { opacity: 1; transform: none; } }
