/* =========================================================================
   bartas.space — The Flight Test Card
   Materials: international orange field, printed card stock, kneeboard black,
   grease-pencil red. Type: Archivo (variable width/weight) + Courier Prime.
   ========================================================================= */

/* ---- Fonts (self-hosted; the footer promises no tracking) ---------------- */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(assets/fonts/archivo-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(assets/fonts/archivo-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/courierprime-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/courierprime-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/courierprime-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/courierprime-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Caveat, subsetted to the pronunciation note — the one handwritten line */
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(assets/fonts/caveat-scribble.woff2) format('woff2');
  unicode-range: U+0020-007E, U+2019;
}

/* ---- Tokens ------------------------------------------------------------- */

:root {
  /* Field: the day-glo orange of a flight test article's high-visibility panels */
  --orange: #f04a16;
  --orange-shade: #d84213;

  /* Stock: printed card, held cool so it reads as form paper, not parchment */
  --stock: #eae7df;
  --stock-2: #ded9cd;
  --stock-3: #d2ccbd;

  /* Kneeboard */
  --board: #16130f;
  --board-2: #221d17;

  --ink: #16130f;
  --graphite: #5c5344;
  --red: #b01b10;
  --red-deep: #8d150c;

  --rule: rgba(22, 19, 15, 0.9);
  --rule-soft: rgba(22, 19, 15, 0.24);
  --rule-hair: rgba(22, 19, 15, 0.14);

  --gutter: 4.5rem;
  --sheet-max: 76rem;
  --measure: 68ch;

  --sans: 'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --typed: 'Courier Prime', ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  --hand: 'Caveat', 'Segoe Script', 'Bradley Hand', cursive;

  --step: cubic-bezier(0.16, 1, 0.3, 1);

  /* Card stock grain — authored material, not decoration */
  --grain: 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='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}

/* ---- Reset -------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5.25rem;
  /* The dropped patch reaches past the sheet onto the field; on viewports
     barely wider than the sheet it must clip, never scroll. `clip` keeps
     position: sticky working where `hidden` would not. */
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--orange);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.62;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

img, video { max-width: 100%; height: auto; display: block; }
h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: 1.08; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }

/* ---- Browser surfaces: these belong to the design, not to the browser --- */

::selection { background: var(--red); color: var(--stock); }
:root { caret-color: var(--red); accent-color: var(--red); }

:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 1px;
}
.on-board :focus-visible, body > nav :focus-visible { outline-color: var(--orange); }

html { scrollbar-color: var(--board) var(--orange); scrollbar-width: thin; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--orange-shade); }
::-webkit-scrollbar-thumb { background: var(--board); border: 3px solid var(--orange-shade); }
::-webkit-scrollbar-thumb:hover { background: var(--board-2); }

/* ---- Shared type patterns ---------------------------------------------- */

/* Printed field label: condensed, small, letterspaced — the form's own voice */
.label {
  font-family: var(--sans);
  font-stretch: 80%;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--graphite);
}

/* Typed value: mono earns its place on measured and tabulated data only */
.typed {
  font-family: var(--typed);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

a { color: var(--red); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { color: var(--red-deep); text-decoration-thickness: 2px; }

.prose { max-width: var(--measure); }
.prose p + p { margin-top: 1.05em; }
.prose em { font-style: italic; }

/* ---- Navigation: the kneeboard clip ------------------------------------- */

body > nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--board);
  color: var(--stock);
  border-bottom: 3px solid var(--ink);
}
.nav-inner {
  max-width: var(--sheet-max);
  margin: 0 auto;
  padding: 0 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 3.25rem;
}
.nav-name {
  font-stretch: 78%;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--stock);
  text-decoration: none;
  white-space: nowrap;
}
.nav-name:hover { color: var(--orange); }
.nav-points { display: flex; gap: 0.25rem; margin-left: auto; flex-wrap: wrap; }
.nav-points a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.3rem 0.55rem;
  color: rgba(234, 231, 223, 0.72);
  text-decoration: none;
  font-size: 0.8125rem;
  font-stretch: 88%;
  border-bottom: 2px solid transparent;
  transition: color 0.15s var(--step), border-color 0.15s var(--step);
}
.nav-points a .n {
  font-family: var(--typed);
  font-size: 0.6875rem;
  color: var(--orange);
}
.nav-points a:hover { color: var(--stock); border-bottom-color: var(--orange); }
.nav-points a[aria-current='true'] { color: var(--stock); border-bottom-color: var(--red); }
.nav-contact {
  padding: 0.34rem 0.7rem;
  background: var(--orange);
  color: var(--ink);
  font-weight: 700;
  font-size: 0.8125rem;
  font-stretch: 88%;
  text-decoration: none;
  white-space: nowrap;
}
.nav-contact:hover { background: var(--stock); color: var(--ink); }

/* ---- The sheet ---------------------------------------------------------- */

.sheet {
  max-width: var(--sheet-max);
  margin: 1.75rem auto 3rem;
  /* No background of its own — .stock below carries the card's surface, so the
     punched holes can be real holes rather than orange paint. */
  position: relative;
  /* Stock thickness. One lift claim, four terms, all of them the same card:
     the crevice where the cut edge meets the field, the contact the card's own
     thickness makes, the ambient lift it already had, and the cut edge itself —
     lit along the far edge, in shade along the near one. Without the first two
     the card does not touch anything: it sliced the dropped patches with a
     perfectly clean line and cast nothing onto them. */
  box-shadow:
    0 0 2px rgba(22, 19, 15, 0.34),
    0 0 7px rgba(22, 19, 15, 0.26),
    0 3px 7px -2px rgba(22, 19, 15, 0.42),
    0 14px 40px -16px rgba(22, 19, 15, 0.62),
    inset 0 1px 0 #f5f2ec,
    inset 1px 0 0 rgba(245, 242, 236, 0.7),
    inset -1px 0 0 rgba(22, 19, 15, 0.10),
    inset 0 -1px 0 rgba(22, 19, 15, 0.18);
}

/* The card's surface, and the only opaque thing between a dropped object and
   the reader. It is masked, so each punched hole is a genuine hole: what shows
   through is whatever lies under the card at that point — the orange field
   down most of the page, and the SFTE patch where that patch runs under the
   left edge.

   Two mask layers, composited by addition: the punch, tiled down the gutter
   column only, and a plain solid covering everything to the right of it.
   Without the second layer the mask would stop at the gutter and take the
   whole card with it.

   z-index puts this below the page's content but above nothing else in the
   card — which is why .dropped-patch sits at -2. That pair of numbers is the
   whole trick: patch, then punched surface, then content. */
.stock {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--stock);
  background-image: var(--grain);
  pointer-events: none;
  --punch: radial-gradient(circle at center,
    transparent 0, transparent 5.4px, #000 5.9px);
  --rest: linear-gradient(#000, #000);
  -webkit-mask-image: var(--punch), var(--rest);
          mask-image: var(--punch), var(--rest);
  -webkit-mask-size: var(--gutter) 7.5rem, calc(100% - var(--gutter) + 1px) 100%;
          mask-size: var(--gutter) 7.5rem, calc(100% - var(--gutter) + 1px) 100%;
  -webkit-mask-position: 0 3.25rem, 100% 0;
          mask-position: 0 3.25rem, 100% 0;
  -webkit-mask-repeat: repeat-y, no-repeat;
          mask-repeat: repeat-y, no-repeat;
}

/* What the punched edge does to the light. The hole itself is cut out of
   .stock; this layer only shades it — translucent, so it darkens the patch and
   the field alike, and confined strictly *inside* the rim.

   Everything outside the rim must stay clean. A soft ring on the card's surface
   around the hole is a shadow cast onto the card, which is what something
   sitting proud of the card would do: that is what made these read as studs
   rather than holes. Inside the rim, occlusion is heaviest at the top — the
   card's own cut wall on the far side of the opening — and lightest at the
   bottom, which is the reading that says valley rather than hill. */
.sheet::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--gutter);
  border-right: 1px dashed var(--rule-soft);
  background-image:
    radial-gradient(circle at 50% calc(50% - 1.4px),
      rgba(22, 19, 15, 0.34) 0, rgba(22, 19, 15, 0.34) 1.6px,
      rgba(22, 19, 15, 0.05) 4px, transparent 4.2px),
    radial-gradient(circle at center, transparent 0, transparent 3.4px,
      rgba(22, 19, 15, 0.10) 4.6px, rgba(22, 19, 15, 0.30) 5.3px, transparent 5.5px);
  background-size: var(--gutter) 7.5rem, var(--gutter) 7.5rem;
  background-position: 0 3.25rem, 0 3.25rem;
  background-repeat: repeat-y, repeat-y;
  pointer-events: none;
}

/* Printed trim rule, inset from the sheet edge */
.sheet::after {
  content: '';
  position: absolute;
  inset: 0.5rem 0.5rem 0.5rem calc(var(--gutter) + 0.5rem);
  border: 1px solid var(--rule-soft);
  pointer-events: none;
}

.sheet > * { padding-left: calc(var(--gutter) + 2rem); padding-right: 2rem; }

/* Sheet header strip */
.strip {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.1rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--rule);
}
.strip span { font-family: var(--typed); font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--graphite); }

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

.head { padding-top: 2.5rem; padding-bottom: 2.75rem; }

.head h1 {
  font-size: clamp(2.6rem, 10.5vw, 6rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 0.92;
  text-transform: uppercase;
  margin-bottom: 1.35rem;
}
/* One width for both lines: the given name is simply the shorter of the two. */
.head h1 .given,
.head h1 .family { display: block; font-stretch: 80%; }

.head .prose { font-size: clamp(1.0625rem, 1.9vw, 1.25rem); }

/* Identity block: the name and its gloss, with the holder's photo alongside */
.ident {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 11.5rem;
  grid-template-areas:
    "name  id"
    "prose id";
  column-gap: 2rem;
  align-items: start;
}
.ident h1 { grid-area: name; }
.ident .prose { grid-area: prose; }
.ident .idcard { grid-area: id; }
/* The holder's photo is not evidence of the work, so it carries no plate number
   and no caption. It is the print somebody taped to the card: set down a couple
   of degrees off square and held by two hand-torn strips across opposite corners.
   Compounded with .plate because the plate rules come later in the file. */
.plate.idcard {
  --tape-a: 0.8rem;   /* how far each strip sits inside the corner it holds */
  --tape-b: 1.2rem;
  padding: 0.5rem;
  margin-top: 0.35rem;
  transform: rotate(-2.6deg);
}
/* Two strips of clear tape. Translucent warm white so the print reads through
   them, a darker hairline down each long edge where the tape catches the light,
   and a torn short end at both ends. No shadow: tape lies flat. */
.plate.idcard::before,
.plate.idcard::after {
  content: "";
  position: absolute;
  z-index: 2;
  height: 1.15rem;
  background: linear-gradient(
    to bottom,
    rgba(22, 19, 15, 0.19) 0,
    rgba(255, 253, 247, 0.3) 1.5px,
    rgba(255, 253, 247, 0.45) 38%,
    rgba(255, 253, 247, 0.24) 57%,
    rgba(255, 253, 247, 0.4) 90%,
    rgba(22, 19, 15, 0.21) 100%
  );
  clip-path: polygon(
    2% 0%, 98% 0%,
    100% 27%, 96% 53%, 100% 78%, 97% 100%,
    3% 100%, 0% 75%, 4% 49%, 0% 25%
  );
}
.plate.idcard::before {
  top: 0;
  left: 0;
  width: 5.4rem;
  transform: translate(calc(-50% + var(--tape-a)), calc(-50% + var(--tape-a))) rotate(-45deg);
}
.plate.idcard::after {
  bottom: 0;
  right: 0;
  width: 4.9rem;
  transform: translate(calc(50% - var(--tape-b)), calc(50% - var(--tape-b))) rotate(-46.5deg);
}

/* The pronunciation gloss, written in the margin of test point 01 */
.point-head .pronounce {
  /* held off the trim rule — a note in the margin, not set to the edge */
  margin: 0 1.5rem 0 auto;
  padding-left: 1rem;
  font-family: var(--hand);
  font-size: clamp(1.15rem, 2.3vw, 1.5rem);
  font-weight: 600;
  line-height: 1;
  color: var(--red);
  rotate: -2.2deg;
  transform-origin: left top;
}
/* the phonetic spelling never breaks across lines */
.point-head .pronounce span { white-space: nowrap; }

/* Printed field grid */
.fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule-soft);
  margin: 2rem 0 2.25rem;
}
.fields > div {
  border-bottom: 1px solid var(--rule-soft);
  border-right: 1px solid var(--rule-soft);
  padding: 0.7rem 0.85rem 0.8rem;
  min-width: 0;
}
.fields dt { margin-bottom: 0.3rem; }
.fields dd {
  margin: 0;
  font-family: var(--typed);
  font-size: 0.9375rem;
  line-height: 1.4;
  overflow-wrap: break-word;
}
.fields dd a { text-decoration-line: underline; }

/* Action lines — filled fields, not buttons pretending to be a landing page */
.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.act {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.6rem 1rem;
  font-family: var(--typed);
  font-size: 0.875rem;
  font-weight: 700;
  text-decoration: none;
  border: 1px solid var(--rule);
  color: var(--ink);
  background: transparent;
  transition: background 0.16s var(--step), color 0.16s var(--step), transform 0.16s var(--step);
}
.act svg { width: 1rem; height: 1rem; flex: none; }
.act:hover { background: var(--ink); color: var(--stock); }
.act-primary { background: var(--orange); border-color: var(--ink); border-width: 2px; }
.act-primary:hover { background: var(--ink); color: var(--stock); }

/* Point index: the card lists its own test points, at every width */
.index { display: none; margin: 1.75rem 0 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule-soft); }
.index ol { display: flex; flex-wrap: wrap; }
.index li { flex: 1 1 auto; border-right: 1px solid var(--rule-hair); }
.index li:last-child { border-right: none; }
.index a {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.62rem 0.9rem;
  text-decoration: none;
  color: var(--ink);
  font-size: 0.875rem;
  font-stretch: 88%;
  white-space: nowrap;
  transition: background 0.14s var(--step), color 0.14s var(--step);
}
.index a .n { font-family: var(--typed); font-size: 0.75rem; color: var(--red); }
.index a:hover { background: var(--stock-2); color: var(--red); }

/* ---- Plates (photographs taped to the card) ----------------------------- */

figure { margin: 0; }

.plate { position: relative; background: var(--stock-2); padding: 0.55rem; border: 1px solid var(--rule-soft); }
.plate img, .plate video { width: 100%; display: block; }
.plate figcaption {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  margin-top: 0.55rem;
  padding-top: 0.45rem;
  border-top: 1px solid var(--rule-soft);
  font-family: var(--typed);
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--graphite);
  /* a caption is typed copy too — hold it to a readable measure under wide plates */
  max-width: var(--measure);
}
.plate figcaption b { color: var(--ink); font-weight: 700; white-space: nowrap; }

.head-plate { margin-top: 2.25rem; }

/* ---- Test points -------------------------------------------------------- */

.point { padding-top: 3.25rem; padding-bottom: 1rem; border-top: 2px solid var(--rule); }
.point:first-of-type { border-top: none; }

.point-head {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 2rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule-soft);
}
.point-head .n {
  font-family: var(--typed);
  font-weight: 700;
  font-size: 1rem;
  color: var(--red);
  background: var(--stock-2);
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--rule-soft);
}
.point-head h2 {
  font-size: clamp(1.5rem, 3.4vw, 2.15rem);
  font-stretch: 84%;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.point-head .count { margin-left: auto; white-space: nowrap; }

/* ---- 01 About ----------------------------------------------------------- */

.about { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 2.5rem; align-items: start; }

/* ---- 02 Experience: the log ---------------------------------------------- */

.log { border-top: 1px solid var(--rule-soft); }
.log > li {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr);
  gap: 1.5rem;
  padding: 1.35rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.log .when { font-family: var(--typed); font-size: 0.875rem; color: var(--graphite); padding-top: 0.2rem; }
.log h3 { font-size: 1.125rem; font-weight: 700; line-height: 1.3; margin-bottom: 0.3rem; }
.log .where { font-family: var(--typed); font-size: 0.8125rem; color: var(--graphite); }
.log p.note { margin-top: 0.55rem; max-width: var(--measure); }

/* Dropped objects: things out of the record's own story, lying on the orange
   field beside the entry that tells it and slipped part-way under the card's
   edge. z-index puts them under the sheet — the sheet itself is what crops
   them — and they cast the sheet's kind of shadow because they lie on the
   same desk.

   Each is set at the height it really is: CSS centimetres are defined as
   96px to the inch, so on a display scaled the way the OS intends these come
   out life-size, and the two objects are always right relative to each other.
   The field beside the card only exists once the sheet has stopped growing,
   so below the breakpoint at the foot of this block they do not exist at all
   — nothing to clip, nothing to download. */
#experience, #publications { position: relative; }
.dropped-patch {
  display: none;
  position: absolute;
  /* Below .stock, not merely below the card: .stock is what crops these now,
     and its punched holes are what let them show through. */
  z-index: -2;
  height: var(--patch-height);
  width: auto;
  /* How far the object lies out past the sheet: as far as it wants, but never
     further than there is field to lie on, so a narrow desk tucks it back
     under the card instead of letting the window guillotine it. Both objects
     share one reach — two things set down on the same desk. --bulge is how
     far the object's own tilt throws its corner past its upright box (plus a
     few px, because 100vw counts a scrollbar the sheet is not centred in), so
     the clamp measures the shape rather than the rectangle. */
  --field: max(0px, (100vw - var(--sheet-max)) / 2 - var(--bulge));
  --overhang: min(11.5rem, var(--field));
  filter: drop-shadow(0 9px 13px rgba(22, 19, 15, 0.38));
  pointer-events: none;
}
/* Defence Staff, 8.5 cm: beside the 2025–2026 experience entry, right edge.
   The 2rem and 6.5rem below are the section's own inset from the sheet edge,
   so --overhang measures from the edge of the card itself. */
.dropped-patch.defence {
  --patch-height: 8.5cm;
  --bulge: 38px;
  top: 8.5rem;
  right: calc(-2rem - var(--overhang));
  rotate: -12deg;
}
/* SFTE European Chapter, 7 cm: beside the SFTE symposium paper, left edge,
   lying across the punched holes. Opposite edge and opposite tilt from the
   other object — two patches dropped on the same side would read as a motif. */
.dropped-patch.sfte {
  --patch-height: 7cm;
  --bulge: 22px;
  top: 29.5rem;
  left: calc(-6.5rem - var(--overhang));
  rotate: 7deg;
}
/* 80rem, not the sheet's own 76rem: at exactly --sheet-max the field is zero
   wide and all that would show is the tilted corner, cut flat by the window.
   From here the objects slide out from under the card as the desk widens. */
@media (min-width: 80rem) {
  .dropped-patch { display: block; }
}

/* ---- 03 Projects -------------------------------------------------------- */

.entry { padding: 2rem 0; border-bottom: 1px solid var(--rule-soft); }
.entry:first-child { padding-top: 0; }
.entry-lead { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 2.25rem; align-items: start; }
.entry-lead.flip > figure { order: 2; }
.entry h3 { font-size: clamp(1.3rem, 2.6vw, 1.7rem); letter-spacing: -0.015em; margin: 0 0 0.7rem; }

.entry-field, .diss .entry-field {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.2rem 0.9rem;
  align-items: baseline;
  margin: 0 0 1rem;
  padding-bottom: 0.8rem;
  border-bottom: 1px solid var(--rule-hair);
}
.entry-field dt { padding-top: 0.1rem; }
.entry-field dd { margin: 0; font-family: var(--typed); font-size: 0.8125rem; line-height: 1.5; }
.entry .prose { font-size: 1rem; }

.links { display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem; margin-top: 1rem; }
.links a { font-family: var(--typed); font-size: 0.8125rem; }

/* Case study disclosure — a card folded open */
details.case { margin-top: 1.25rem; border: 1px solid var(--rule-soft); background: var(--stock-2); }
details.case > summary {
  cursor: pointer;
  list-style: none;
  padding: 0.7rem 0.95rem;
  font-family: var(--sans);
  font-stretch: 82%;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
details.case > summary::-webkit-details-marker { display: none; }
details.case > summary::before {
  content: '';
  width: 0.7rem; height: 0.7rem;
  border: 1px solid var(--rule);
  background:
    linear-gradient(to bottom, transparent 45%, var(--ink) 45%, var(--ink) 55%, transparent 55%),
    linear-gradient(to right, transparent 45%, var(--ink) 45%, var(--ink) 55%, transparent 55%);
  flex: none;
}
details.case[open] > summary::before { background: linear-gradient(to bottom, transparent 45%, var(--ink) 45%, var(--ink) 55%, transparent 55%); }
details.case > summary:hover { background: var(--stock-3); }
.case-body { padding: 0.5rem 0.95rem 1.25rem; border-top: 1px solid var(--rule-soft); }
.case-body h4 {
  font-stretch: 82%;
  font-size: 0.6875rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--graphite);
  margin: 1.15rem 0 0.4rem;
}
.case-body p { max-width: var(--measure); font-size: 0.9375rem; }
.case-figs { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; margin-top: 1.15rem; }
.case-figs .plate { background: var(--stock); }
.case-links { margin-top: 1.15rem; font-family: var(--typed); font-size: 0.8125rem; }

/* ---- 04 Publications ---------------------------------------------------- */

.diss { position: relative; border: 2px solid var(--rule); padding: 1.5rem 1.6rem; margin-bottom: 2.5rem; background: var(--stock-2); }
.diss h3 { font-size: clamp(1.15rem, 2.4vw, 1.5rem); margin: 0.45rem 0 0.7rem; max-width: 44ch; }
.diss p { font-family: var(--typed); font-size: 0.875rem; }

/* Rubber stamp — pressed, not printed. Sized like the thing itself. */
.stamp {
  position: absolute;
  top: -1.6rem;
  right: 1.5rem;
  rotate: -7deg;
  display: grid;
  justify-items: center;
  gap: 0.15rem;
  border: 3px solid var(--red);
  color: var(--red);
  background: var(--stock);
  padding: 0.6rem 1.15rem 0.55rem;
  font-family: var(--typed);
  font-weight: 700;
  font-size: clamp(0.9375rem, 1.5vw, 1.125rem);
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  box-shadow: inset 0 0 0 2px var(--stock), inset 0 0 0 5px var(--red);
  opacity: 0.92;
}
.stamp b {
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  letter-spacing: 0.14em;
  /* the word is cut from the same block; the date wheel sits under it */
  padding-bottom: 0.3rem;
  border-bottom: 2px solid var(--red);
  margin-bottom: 0.15rem;
}

.pubs { border-top: 1px solid var(--rule); }
.pubs > li {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: 1.25rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule-hair);
}
.pubs .year { font-family: var(--typed); font-size: 0.8125rem; color: var(--graphite); }
.pubs a, .pubs .untitled { font-size: 1rem; line-height: 1.4; }
.pubs .untitled { color: var(--ink); }
.pubs .venue { display: block; font-family: var(--typed); font-size: 0.75rem; color: var(--graphite); margin-top: 0.25rem; }

.group { font-stretch: 82%; font-size: 0.6875rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--graphite); margin: 2rem 0 0.6rem; }

details.more { margin-top: 2rem; border-top: 1px solid var(--rule); }
details.more > summary {
  cursor: pointer;
  list-style: none;
  padding: 0.85rem 0;
  font-stretch: 82%;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::after { content: '+'; font-family: var(--typed); color: var(--red); font-size: 1.125rem; }
details.more[open] > summary::after { content: '–'; }
details.more > summary:hover { color: var(--red); }

/* ---- 05 Skillset: a matrix, not a rack of cards ------------------------- */

.matrix { border-top: 1px solid var(--rule); }
.matrix > div {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: 1.5rem;
  padding: 1.3rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.matrix h3 { font-size: 1.0625rem; font-stretch: 88%; letter-spacing: -0.005em; }
.matrix ul { display: grid; gap: 0.4rem; }
.matrix li { display: grid; grid-template-columns: 1.1rem minmax(0, 1fr); gap: 0.4rem; font-size: 0.9375rem; }
.matrix li::before { content: '·'; font-family: var(--typed); color: var(--red); font-weight: 700; }

.chips { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 1.5rem; padding: 1.3rem 0; border-bottom: 1px solid var(--rule-soft); }
.chips .set { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chips .set span {
  font-family: var(--typed);
  font-size: 0.8125rem;
  padding: 0.22rem 0.55rem;
  border: 1px solid var(--rule-soft);
  background: var(--stock-2);
}

/* ---- 06 Beyond ---------------------------------------------------------- */

.beyond { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 2.5rem; align-items: start; }
.beyond-list { margin-top: 1.25rem; display: grid; gap: 0.85rem; }
.beyond-list li { padding-left: 1.1rem; border-left: 1px solid var(--rule-soft); font-size: 0.9375rem; }
.beyond-list b { font-weight: 700; }

/* ---- Signature block ---------------------------------------------------- */

footer {
  background: var(--board);
  color: var(--stock);
  margin-top: 3rem;
  border-top: 3px solid var(--ink);
}
.sig {
  max-width: var(--sheet-max);
  margin: 0 auto;
  padding: 3.5rem 1.25rem 2.5rem;
}
.sig h2 {
  font-size: clamp(1.5rem, 3.2vw, 2rem);
  font-stretch: 84%;
  text-transform: uppercase;
  letter-spacing: -0.015em;
  margin-bottom: 1.5rem;
  color: var(--stock);
}
.sig-mail {
  display: inline-block;
  font-family: var(--typed);
  font-size: clamp(1.15rem, 3.6vw, 1.9rem);
  font-weight: 700;
  color: var(--orange);
  text-decoration: none;
  border-bottom: 2px solid var(--orange);
  padding-bottom: 0.15rem;
}
.sig-mail:hover { color: var(--stock); border-bottom-color: var(--stock); }
.sig-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 1.5rem;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(234, 231, 223, 0.28);
}
.sig-fields .label { color: rgba(234, 231, 223, 0.62); }
.sig-fields dd { margin: 0.4rem 0 0; font-family: var(--typed); font-size: 0.9375rem; }
.sig-fields a { color: var(--stock); text-decoration-color: rgba(234, 231, 223, 0.45); }
.sig-fields a:hover { color: var(--orange); text-decoration-color: var(--orange); }
.sig-close {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1.5rem 2.5rem;
  margin-top: 3rem;
}
.sig-close > div { display: grid; gap: 0.45rem; }
.sig-close .label { color: rgba(234, 231, 223, 0.62); }
.sig-rule { display: block; height: 1px; background: rgba(234, 231, 223, 0.45); margin-top: 1.5rem; }

.end {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 2.75rem;
  font-stretch: 80%;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(234, 231, 223, 0.62);
}
.end::before, .end::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(234, 231, 223, 0.28);
}

.fine {
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(234, 231, 223, 0.28);
  font-family: var(--typed);
  font-size: 0.75rem;
  line-height: 1.7;
  color: rgba(234, 231, 223, 0.6);
  max-width: var(--measure);
}

/* ---- The authored moment: grease-pencil annotation ---------------------- */

.mark { position: relative; display: inline-block; white-space: nowrap; }
/* A phrase-length underline has to survive wrapping, so it is drawn as one
   stroke per line fragment, positioned by script against the paragraph. */
.mark[data-mark="underline"] { display: inline; white-space: normal; position: static; }
.mark-host { position: relative; }
.mark-line {
  position: absolute;
  overflow: visible;
  pointer-events: none;
  color: var(--red);
}
.mark > svg {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  width: calc(100% + 1.4rem);
  height: calc(100% + 0.85rem);
  overflow: visible;
  pointer-events: none;
  color: var(--red);
}
.mark > svg path, .mark-line path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  opacity: 0.9;
}
.mark.drawn > svg path, .mark-line.drawn path {
  animation: draw 0.72s var(--step) forwards;
}
.mark.drawn > svg path:nth-child(2) { animation-delay: 0.13s; }
/* Lines re-laid-out after a resize or font swap must not replay the draw. */
.mark-line.settled path { stroke-dashoffset: 0; animation: none; }
@keyframes draw { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .mark > svg path, .mark-line path { stroke-dashoffset: 0; animation: none; }
  .mark.drawn > svg path, .mark-line.drawn path { animation: none; }
  * { transition-duration: 0.01ms !important; }
}

/* ---- Responsive --------------------------------------------------------- */

@media (max-width: 60rem) {
  .about, .entry-lead, .beyond { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; }
  .entry-lead.flip > figure { order: 0; }
  .ident {
    grid-template-columns: minmax(0, 1fr) 9rem;
    grid-template-areas:
      "name  name"
      "prose id";
    column-gap: 1.75rem;
  }
  .matrix > div, .chips { grid-template-columns: minmax(0, 1fr); gap: 0.7rem; }
  .log > li { grid-template-columns: 6.5rem minmax(0, 1fr); gap: 1rem; }
}

@media (max-width: 46rem) {
  :root { --gutter: 2.1rem; }
  body { font-size: 1rem; }
  .sheet { margin: 0.5rem 0.5rem 2rem; }
  /* Same punched hole, smaller: the cut in .stock and the shading over it are
     scaled together, so they must be edited together. */
  .stock {
    --punch: radial-gradient(circle at center,
      transparent 0, transparent 3.4px, #000 3.8px);
    -webkit-mask-size: var(--gutter) 5.5rem, calc(100% - var(--gutter) + 1px) 100%;
            mask-size: var(--gutter) 5.5rem, calc(100% - var(--gutter) + 1px) 100%;
  }
  .sheet::before {
    background-image:
      radial-gradient(circle at 50% calc(50% - 0.9px),
        rgba(22, 19, 15, 0.34) 0, rgba(22, 19, 15, 0.34) 1px,
        rgba(22, 19, 15, 0.05) 2.5px, transparent 2.7px),
      radial-gradient(circle at center, transparent 0, transparent 2.1px,
        rgba(22, 19, 15, 0.10) 2.9px, rgba(22, 19, 15, 0.30) 3.3px, transparent 3.5px);
    background-size: var(--gutter) 5.5rem, var(--gutter) 5.5rem;
  }
  .sheet > * { padding-left: calc(var(--gutter) + 1rem); padding-right: 1rem; }
  .sheet::after { inset: 0.4rem 0.4rem 0.4rem calc(var(--gutter) + 0.4rem); }
  .head { padding-top: 0.9rem; padding-bottom: 1.75rem; }
  .head h1 { letter-spacing: -0.025em; margin-bottom: 0.65rem; }
  .head .prose { font-size: 1rem; line-height: 1.55; }
  .fields { margin: 0.85rem 0 0.85rem; }
  .fields > div { padding: 0.45rem 0.6rem 0.5rem; }
  .head-plate { margin-top: 1.25rem; }
  .actions { gap: 0.45rem; }
  .act { padding: 0.5rem 0.85rem; }
  .index { display: block; }
  .strip { padding-top: 0.65rem; padding-bottom: 0.65rem; }
  .point { padding-top: 2.5rem; }
  .point-head { flex-wrap: wrap; gap: 0.7rem; margin-bottom: 1.5rem; }
  .point-head .count { margin-left: 0; width: 100%; }
  /* the note keeps its place beside the heading, shrinking to fit the margin */
  .point-head .pronounce {
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
    padding-left: 0.6rem;
    font-size: 0.85rem;
    line-height: 1.25;
    text-align: right;
  }
  .log > li { grid-template-columns: minmax(0, 1fr); gap: 0.35rem; }
  .pubs > li { grid-template-columns: 3.2rem minmax(0, 1fr); gap: 0.85rem; }
  .fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .index a { padding: 0.55rem 0.7rem; font-size: 0.8125rem; }
  .nav-inner { gap: 0.75rem; min-height: 3rem; }
  .nav-points { display: none; }
  .nav-contact { margin-left: auto; }
  .sig { padding: 2.5rem 1.25rem 2rem; }
  /* No room to stamp the corner on a phone — it lands in the flow instead */
  .stamp {
    position: static;
    display: inline-grid;
    margin: 0 0 1.1rem;
    padding: 0.5rem 0.9rem 0.45rem;
  }
  .ident { grid-template-columns: minmax(0, 1fr) 8.5rem; column-gap: 1.1rem; }
  /* Shorter strips, held further in: the trim rule is much closer here */
  .plate.idcard { --tape-a: 0.75rem; --tape-b: 1.15rem; }
  .plate.idcard::before { width: 4.3rem; }
  .plate.idcard::after { width: 3.9rem; }
}

@media (max-width: 30rem) {
  .act { padding: 0.5rem 0.75rem; font-size: 0.8125rem; }
}

/* R1: the surname is the widest object on the page; step it at the narrow end. */
@media (max-width: 22.5rem) {
  .head h1 { font-size: 2.125rem; }
}

/* Touch: the same lines, with enough card behind them for a thumb.
   Kept after the width queries so the taller padding wins on touch devices. */
@media (pointer: coarse) {
  .nav-contact { padding-top: 0.9rem; padding-bottom: 0.9rem; }
  .nav-points a { padding-top: 0.7rem; padding-bottom: 0.7rem; }
  .index a { padding-top: 0.85rem; padding-bottom: 0.85rem; }
  .act { padding-top: 0.75rem; padding-bottom: 0.75rem; }
}

/* ---- Print: the sheet is already a document ----------------------------- */

@media print {
  body > nav, .actions, details.case, .nav-points, .index, .sig-close, .end, .dropped-patch { display: none; }
  body { background: #fff; }
  .sheet { box-shadow: none; margin: 0; max-width: none; }
  .sheet::before { display: none; }
  /* The card's surface stays; the punch does not, since the gutter is gone. */
  .stock { -webkit-mask-image: none; mask-image: none; }
  .sheet > * { padding-left: 0; padding-right: 0; }
  footer { background: #fff; color: var(--ink); }
  .sig-mail, .sig h2, .sig-fields a { color: var(--ink); }
  a { text-decoration: none; }
}
