/* R4 private local prototype. Static, no remote fonts or assets. */

:root {
  --bg: #04060a;
  --ground: #070b11;
  --surface: #0b1017;
  --raised: #111925;
  --text: #f3f7f9;
  --text-2: #b3c2cc;
  --dim: #869aa8;
  --green: #53e08a;
  --green-active: #26c862;
  --cyan: #74e6f7;
  --border: #1d2a35;
  --border-strong: #354a58;

  --display: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Times New Roman", serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "Cascadia Code", "Cascadia Mono", "SF Mono", Consolas, monospace;

  --wrap: 74rem;
  --gutter: clamp(16px, 4vw, 48px);
  --radius: 10px;
  --ease: 150ms ease;
  --masthead: 64px;
  /* Space kept above in-page scroll targets: the sticky masthead, or none once it scrolls away. */
  --sticky-offset: var(--masthead);
  /* H3: 48 px on phones, about 86-88 px on wide desktops (was 72-120 px). */
  --section-gap: clamp(48px, 6vw, 88px);

  color-scheme: dark;
}

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

html {
  scroll-padding-top: calc(var(--sticky-offset) + 16px);
}

@media (prefers-reduced-motion: no-preference) {
  :root:not([data-motion="paused"]):not([data-motion="reduced"]) {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  overflow-wrap: break-word;
}

a {
  color: var(--cyan);
  text-underline-offset: 0.2em;
  transition: color var(--ease), border-color var(--ease), background-color var(--ease);
}

a:hover {
  color: var(--green);
}

:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 4px;
}

main:focus,
.section:focus,
[tabindex="-1"]:focus {
  outline: none;
}

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

/* Skip link and notice */

.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 30;
  padding: 10px 16px;
  border-radius: var(--radius);
  background: var(--text);
  color: var(--bg);
  font-weight: 600;
}

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

.prototype-notice {
  margin: 0;
  padding: 5px var(--gutter);
  border-bottom: 1px solid var(--border);
  background: var(--ground);
  color: var(--text-2);
  font-family: var(--mono);
  font-size: 0.6875rem;
  line-height: 1.5;
  letter-spacing: 0.02em;
  text-align: center;
}

.prototype-notice,
.site-footer p,
.cta-row {
  max-width: none;
}

/* Page-wide decorative syntax field. One viewport-sized layer behind everything. */

.syntax-layer {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}

/* Static fallback (no JS or no canvas): .04 over the reading column, stronger in the page margins. */
.syntax-fallback {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 18px 12px;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 2.6;
  white-space: pre;
  opacity: 0.04;
}

@supports ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .syntax-fallback {
    opacity: 0.12;
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(50% - var(--wrap) / 2), rgba(0, 0, 0, 0.33) calc(50% - var(--wrap) / 2 + 40px), rgba(0, 0, 0, 0.33) calc(50% + var(--wrap) / 2 - 40px), #000 calc(50% + var(--wrap) / 2), #000 100%);
    mask-image: linear-gradient(90deg, #000 0, #000 calc(50% - var(--wrap) / 2), rgba(0, 0, 0, 0.33) calc(50% - var(--wrap) / 2 + 40px), rgba(0, 0, 0, 0.33) calc(50% + var(--wrap) / 2 - 40px), #000 calc(50% + var(--wrap) / 2), #000 100%);
  }
}

.syntax-field {
  position: absolute;
  inset: 0;
  display: none;
  width: 100%;
  height: 100%;
}

.has-field .syntax-field {
  display: block;
}

.has-field .syntax-fallback {
  display: none;
}

/* Masthead */

.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.masthead-row {
  display: flex;
  align-items: center;
  gap: 8px 28px;
  min-height: var(--masthead);
}

.brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 2px;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  text-decoration: none;
}

.brand:hover {
  color: var(--green);
}

.nav {
  margin-left: auto;
}

.nav-list {
  display: flex;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-list a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: var(--radius);
  color: var(--text-2);
  font-size: 0.9375rem;
  text-decoration: none;
}

.nav-list a::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 6px;
  height: 2px;
  border-radius: 1px;
  background: transparent;
  transition: background-color var(--ease);
}

.nav-list a:hover {
  color: var(--text);
}

.nav-list a[aria-current] {
  color: var(--text);
}

.nav-list a[aria-current]::after {
  background: var(--green);
}

.effects-toggle {
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-2);
  font-family: var(--mono);
  font-size: 0.8125rem;
  cursor: pointer;
  transition: color var(--ease), border-color var(--ease);
}

.effects-toggle:hover {
  border-color: var(--cyan);
  color: var(--text);
}

.effects-toggle[aria-pressed="true"] {
  border-color: var(--cyan);
  color: var(--cyan);
}

.effects-toggle[hidden] {
  display: none;
}

/* Hero */

.hero {
  position: relative;
  padding: clamp(32px, 5vw, 64px) 0 0;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 24px;
  align-items: end;
  min-height: min(calc(100svh - var(--masthead) - 28px - clamp(32px, 5vw, 64px)), 860px);
}

.hero-text {
  position: relative;
  z-index: 1;
  /* P5: the portrait block comes first in the markup (mobile reading and focus order); desktop keeps text left. */
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  padding-bottom: clamp(32px, 6vw, 88px);
}

h1 {
  margin: 0 0 18px;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.125rem, 0.9rem + 3.2vw, 3.75rem);
  line-height: 1.04;
  letter-spacing: -0.012em;
}

.name-line {
  display: block;
}

.role {
  margin: 0 0 22px;
  color: var(--green);
  font-family: var(--mono);
  font-size: clamp(0.875rem, 0.82rem + 0.25vw, 1rem);
  letter-spacing: 0.03em;
}

.intro {
  max-width: 38ch;
  margin: 0 0 32px;
  color: var(--text-2);
  font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
}

/* H3: introduction and focus read as one block, about 46ch wide, with a 14 px step between them. */
.hero-intro {
  max-width: 46ch;
  margin: 0 0 32px;
  font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem); /* ch measured in the introduction's own size */
}

.hero-intro .intro {
  max-width: none;
  margin: 0;
}

.hero-intro .intro-focus {
  margin-top: 14px;
  font-size: 1rem;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0;
}

.cta {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--mono);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
}

.cta-primary {
  border-color: var(--green);
  background: var(--green);
  color: var(--bg);
}

.cta-primary:hover,
.cta-primary:active {
  border-color: var(--green-active);
  background: var(--green-active);
  color: var(--bg);
}

.cta-secondary {
  border-color: var(--cyan);
  color: var(--cyan);
}

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

/* Portrait: free-standing cutout, no card frame. */

.hero-portrait {
  position: relative;
  display: flex;
  justify-content: flex-end;
  grid-column: 2;
  grid-row: 1;
}

/* P5: the reveal control sits outside the sampled portrait box. On desktop the row generates no box, so the control
   keeps its place at the portrait's top-right corner (the portrait's top and right edges are this block's). */
.portrait-controls {
  display: contents;
}

.portrait {
  position: relative;
  flex: none;
  width: min(124%, 660px);
  pointer-events: none;
  aspect-ratio: 1 / 1;
}

.portrait-halo {
  position: absolute;
  left: 12%;
  right: 12%;
  top: 8%;
  bottom: 8%;
  border-radius: 50%;
  background: radial-gradient(closest-side at 50% 44%, rgba(116, 230, 247, 0.5), rgba(83, 224, 138, 0.12) 60%, transparent 100%);
  opacity: 0.2;
}

/* H2: the responsive <picture> wrapper generates no box, so the image keeps its R5 layout. */
.portrait picture {
  display: contents;
}

.portrait-img {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 100%;
  transform-origin: 50% 100%;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.85rem;
}

/* Bottom fade into the page: CSS mask where supported, overlay gradient otherwise. */
@supports ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .portrait-img {
    -webkit-mask-image: linear-gradient(180deg, #000 74%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 74%, transparent 100%);
  }
}

@supports not ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .portrait::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 28%;
    background: linear-gradient(180deg, rgba(4, 6, 10, 0), var(--bg));
    pointer-events: none;
  }
}

.portrait.is-missing .portrait-img {
  display: none;
}

/* Breathing runs only once motion.js has confirmed motion is allowed; it holds while
   the tab is hidden or the portrait is offscreen. */
[data-motion="running"] .portrait-img,
[data-motion="suspended"] .portrait-img {
  animation: breathe 7s ease-in-out infinite;
}

[data-motion="suspended"] .portrait-img,
[data-portrait="offscreen"] .portrait-img {
  animation-play-state: paused;
}

@keyframes breathe {
  0%,
  100% { transform: scale(1); }
  50% { transform: scale(1.018); }
}

/* R5 coded face: hero.js draws numbers and coding signs over the image's own box.
   The image stays in the document as the accessible portrait and the fallback. */
.portrait-glyphs {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* Keyboard/touch equivalent of the pointer's coded-detail highlight; shown by hero.js
   only while the coded face is present. */
.detail-toggle {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text-2);
  font-family: var(--mono);
  font-size: 0.75rem;
  cursor: pointer;
  pointer-events: auto;
  transition: color var(--ease), border-color var(--ease);
}

.detail-toggle:hover,
.detail-toggle[aria-pressed="true"] {
  border-color: var(--cyan);
  color: var(--text);
}

.detail-toggle[hidden] {
  display: none;
}

.glyph-pending .portrait-img,
.has-glyph-face .portrait-img {
  opacity: 0;
  animation: none;
}

@supports ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .portrait-glyphs {
    -webkit-mask-image: linear-gradient(180deg, #000 74%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 74%, transparent 100%);
  }
}

/* Sections: numbered rail, ruled top edge. */

.section {
  padding: var(--section-gap) 0 0;
  scroll-margin-top: calc(var(--sticky-offset) + 8px);
}

.section:last-of-type {
  padding-bottom: var(--section-gap);
}

.section-grid {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
}

.rail {
  margin: 0;
  padding-top: 18px;
  border-top: 1px solid var(--border-strong);
  color: var(--green);
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
}

.section-body {
  min-width: 0;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

h2 {
  max-width: 22ch;
  margin: 0 0 clamp(28px, 4vw, 48px);
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.875rem, 1.3rem + 2vw, 3rem);
  line-height: 1.12;
}

h3 {
  margin: 0 0 10px;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.5625rem);
  line-height: 1.28;
}

.meta {
  margin: 0 0 12px;
  color: var(--cyan);
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: 0.03em;
}

p {
  max-width: 62ch;
}

:target {
  scroll-margin-top: calc(var(--sticky-offset) + 16px);
}

/* Capability system */

.cap-system {
  display: grid;
  grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
}

.cap-select {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--border);
}

.cap-link {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  padding: 10px 14px 10px 12px;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;
  color: var(--text-2);
  font-family: var(--display);
  font-size: 1.1875rem;
  text-decoration: none;
  transition: color var(--ease), border-color var(--ease), background-color var(--ease);
}

.cap-index {
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.75rem;
}

.cap-link:hover {
  background: var(--surface);
  color: var(--text);
}

.cap-link[aria-current="true"] {
  border-left-color: var(--green);
  background: var(--raised);
  color: var(--text);
}

.cap-link[aria-current="true"] .cap-index {
  color: var(--green);
}

.cap-panel {
  padding: 0 0 28px;
}

.cap-panel + .cap-panel {
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

.cap-enhanced .cap-panel + .cap-panel {
  padding-top: 0;
  border-top: 0;
}

.cap-panel h3 {
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
}

.cap-panel p {
  margin: 0 0 16px;
  color: var(--text-2);
  font-size: 1.125rem;
}

.cap-panel .cap-related {
  margin: 0;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.cap-related a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--sans);
  font-size: 0.9375rem;
}

.cap-related-label {
  display: block;
}

/* P9: the capability map keeps the P8 drawing's geometry (600 x 132 units: boxes 172, 180 and 140 wide and 48
   tall, centred at 110, 300 and 490 on the wire), but its three boxes are real links. Only the wire and the end
   ticks stay a decorative, hidden SVG behind them. */
.cap-diagram {
  position: relative;
  display: block;
  width: 100%;
  max-width: 600px;
  margin-top: 12px;
  font-family: var(--mono);
}

.cap-wires {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.cap-wire {
  fill: none;
  stroke: var(--border-strong);
  stroke-width: 1;
  stroke-dasharray: 3 5;
}

.cap-tick {
  fill: none;
  stroke: var(--border-strong);
}

.cap-map {
  position: relative;
  display: grid;
  grid-template-columns: 4% 28.6667% 2.3333% 30% 5% 23.3333% 6.6667%;
  align-items: center;
  aspect-ratio: 600 / 132;
  margin: 0;
  padding: 0;
  list-style: none;
}

.cap-map li:nth-child(1) {
  grid-column: 2;
}

.cap-map li:nth-child(2) {
  grid-column: 4;
}

.cap-map li:nth-child(3) {
  grid-column: 6;
}

.cap-node {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-height: 48px;
  padding: 4px 8px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--bg);
  color: var(--dim);
  font-size: 13px;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  transition: color var(--ease), border-color var(--ease), background-color var(--ease);
}

.cap-node:hover {
  color: var(--text);
}

.cap-node.is-selected {
  border-color: var(--green);
  background: var(--raised);
  box-shadow: inset 0 0 0 0.5px var(--green);
  color: var(--text);
}

/* Work briefs */

.brief {
  max-width: 52rem;
}

/* P5: 40 px between consecutive full case studies, whether their details are open or closed. */
.brief + .brief {
  margin-top: 40px;
}

.brief-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 20px;
}

.case-title {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.875rem);
  letter-spacing: 0.08em;
}

.brief-head .meta {
  margin: 0 0 8px;
}

.brief-lede {
  margin: 0;
  color: var(--text-2);
  font-size: 1.125rem;
}

.case-details {
  margin-top: 22px;
}

.case-details summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--cyan);
  border-radius: var(--radius);
  color: var(--cyan);
  font-family: var(--mono);
  font-size: 0.875rem;
  cursor: pointer;
  list-style: none;
  transition: color var(--ease), border-color var(--ease);
}

.case-details summary::-webkit-details-marker {
  display: none;
}

.case-details summary::before {
  content: "+" / "";
  color: var(--green);
}

.case-details[open] summary::before {
  content: "\2212" / "";
}

.case-details summary:hover {
  border-color: var(--text);
  color: var(--text);
}

.case-rows {
  margin: 24px 0 0;
  border-top: 1px solid var(--border);
}

.case-row {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 8px 24px;
  padding: 18px 0;
  border-bottom: 1px solid var(--border);
}

.case-row dt,
.skill-row dt {
  color: var(--cyan);
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.case-row dd {
  max-width: 62ch;
  margin: 0;
  color: var(--text-2);
}

/* SECURE VAULT lab workflow: static figure inside the expanded case study. The ordered list
   carries the sequence; the arrows between steps are decorative. */
.lab-figure {
  max-width: 64rem;
  margin: 28px 0 0;
  padding: clamp(16px, 3vw, 28px);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
}

/* H3: the figure reads as a conceptual architecture overview: title, provenance caption, note,
   environment, then four grouped stages with their components. */
.lab-title {
  margin: 0 0 8px;
  color: var(--text);
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.1875rem, 1.1rem + 0.4vw, 1.375rem);
  line-height: 1.3;
}

.lab-figure figcaption {
  margin: 0;
  color: var(--text);
  font-size: 0.9375rem;
}

.lab-env {
  margin: 14px 0 0;
  color: var(--text-2);
  font-size: 0.9375rem;
}

.lab-note {
  margin: 6px 0 0;
  color: var(--text-2);
  font-size: 0.875rem;
}

.lab-label {
  margin: 20px 0 10px;
  color: var(--cyan);
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.lab-flow {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px 32px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lab-step {
  position: relative;
  padding: 12px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font-size: 0.9375rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.lab-step-join {
  border-color: var(--green);
}

.lab-step-title {
  margin: 0;
  color: var(--text);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.35;
}

.lab-parts {
  margin: 10px 0 0;
  padding: 10px 0 0;
  border-top: 1px solid var(--border);
  list-style: none;
}

.lab-parts li + li {
  margin-top: 6px;
}

.lab-parts p {
  margin: 0;
  color: var(--text-2);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.lab-flow .lab-step:not(:last-child)::after {
  content: "\2192";
  content: "\2192" / "";
  position: absolute;
  top: 14px; /* level with the stage titles */
  right: -24px;
  color: var(--green);
  font-family: var(--mono);
}

.lab-input {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 0;
}

.lab-input .lab-step {
  border-style: dashed;
}

.lab-arrow {
  color: var(--green);
  font-family: var(--mono);
}

.lab-target {
  color: var(--text-2);
  font-size: 0.9375rem;
}

.brief-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 clamp(24px, 4vw, 48px);
  align-items: start; /* shared top edge; each column ends with its own content */
  margin-top: clamp(40px, 5vw, 56px);
}

.brief-minor {
  padding-top: 18px;
  border-top: 1px solid var(--border-strong);
}

.brief-minor p {
  margin: 0;
  color: var(--text-2);
}

/* Experience */

.roles {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--border);
}

.role-item {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  grid-template-areas: "when title" "when copy";
  gap: 0 32px;
  padding: 24px 0;
  border-bottom: 1px solid var(--border);
}

.role-item h3 {
  grid-area: title;
  max-width: 40ch;
}

.role-item .meta {
  grid-area: when;
  margin: 0.35em 0 8px;
}

.role-copy {
  grid-area: copy;
  margin: 0;
  color: var(--text-2);
}

/* Two résumé bullets per employer. */
.role-points {
  max-width: 62ch;
  padding-left: 1.25em;
  list-style: disc;
}

.role-points li + li {
  margin-top: 8px;
}

/* Each bullet keeps its text in a paragraph, so the page field stays quiet behind it. */
.role-points p {
  margin: 0;
}

.role-points li::marker {
  color: var(--green);
}

/* Skills and education */

.skill-rows {
  margin: 0;
  border-top: 1px solid var(--border);
}

.skill-row {
  display: grid;
  grid-template-columns: 16rem minmax(0, 1fr);
  gap: 6px 32px;
  padding: 18px 0;
  border-bottom: 1px solid var(--border);
}

.skill-row dt {
  padding-top: 0.2em;
}

.skill-row dd {
  margin: 0;
  color: var(--text);
}

.degree {
  padding: 22px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.degree .meta {
  max-width: none;
  margin: 0;
}

/* H3: contact sits apart from the degree, with its labels and values aligned in two columns. */
.contact {
  margin-top: clamp(36px, 4vw, 48px);
}

.contact h3 {
  margin-bottom: 14px;
}

.contact p {
  margin: 0 0 12px;
}

/* H4: the résumé request uses the existing outline CTA; the note sits close beneath it. */
.contact .contact-cta {
  margin: 24px 0 8px;
}

.contact .contact-note {
  color: var(--text-2);
  font-size: 0.875rem;
}

.contact-rows {
  margin: 20px 0 0;
  border-top: 1px solid var(--border);
}

.contact-row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: 4px 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}

.contact-row dt {
  color: var(--text-2);
}

.contact-row dd {
  margin: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* Deep-link landing cue for related items. */
.brief-minor:target,
.skill-row:target {
  border-top-color: var(--green);
}

/* One-time section reveal: only when motion.js has confirmed motion is allowed. */
.reveal-on .reveal:not(.is-in) {
  opacity: 0;
  transform: translateY(10px);
}

.reveal-on .reveal {
  transition: opacity 220ms ease-out, transform 220ms ease-out;
}

/* Footer */

.site-footer {
  padding: 28px 0 36px;
  border-top: 1px solid var(--border);
  background: var(--ground);
  font-family: var(--mono);
  font-size: 0.8125rem;
}

.site-footer p {
  margin: 0;
}

.site-footer a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  /* F1: the credit reads in cyan at rest and warms to green with a soft glow on hover and keyboard
     focus (the 3 px focus ring stays). One short transition, no continuous animation. */
  color: var(--cyan);
  text-shadow: none;
  transition: color 220ms ease, text-shadow 220ms ease;
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--green);
  text-shadow: 0 0 10px rgba(83, 224, 138, 0.45);
}

/* Responsive */

@media (max-width: 1023.98px) {
  /* The lab workflow reads top to bottom below desktop widths. */
  .lab-flow {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }

  .lab-flow .lab-step:not(:last-child)::after {
    content: "\2193";
    content: "\2193" / "";
    top: auto;
    right: auto;
    bottom: -25px;
    left: 16px;
    transform: none;
  }

  .cap-system {
    grid-template-columns: minmax(0, 1fr);
  }

  /* H3: the paired detection and response briefs stack on tablets instead of two narrow columns. */
  .brief-pair {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  .role-item {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "title" "when" "copy";
  }

  .role-item .meta {
    margin: 0 0 10px;
  }

  .skill-row {
    grid-template-columns: 13rem minmax(0, 1fr);
  }
}

@media (max-width: 759.98px) {
  :root {
    --masthead: 98px;
  }

  body {
    font-size: 1rem;
  }

  .masthead-row {
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0 12px;
    padding-top: 4px;
    padding-bottom: 4px;
  }

  .nav {
    order: 3;
    width: 100%;
    margin-left: -10px;
  }

  .nav-list {
    gap: 0;
  }

  .nav-list a {
    padding: 0 10px;
    font-size: 0.875rem;
  }

  .nav-list a::after {
    left: 10px;
    right: 10px;
  }

  .effects-toggle {
    padding: 0 12px;
    font-size: 0.75rem;
  }

  /* Portrait-led: portrait first, name rides over its faded lower edge, actions before the paragraph. */
  .hero {
    padding-top: 12px;
  }

  .hero-grid {
    display: flex;
    flex-direction: column;
    gap: 0;
    min-height: 0;
  }

  /* P5: portrait, then a dedicated reveal-control row, then the name (no overlap with either). */
  .hero-portrait {
    flex-direction: column;
    align-items: center;
    margin-bottom: 16px;
  }

  .portrait {
    width: min(100%, 380px, 38svh);
  }

  /* The row is reserved even while the control is hidden, so nothing moves when it appears. */
  .portrait-controls {
    display: flex;
    justify-content: center;
    width: 100%;
    min-height: 44px;
    margin-top: 8px;
  }

  .detail-toggle {
    position: static;
    padding: 0 16px;
    white-space: nowrap;
  }

  .hero-text {
    position: relative;
    display: flex;
    flex-direction: column;
    padding-bottom: 0;
  }

  .role {
    margin-bottom: 18px;
  }

  .cta-row {
    order: 3;
    margin-bottom: 20px;
  }

  /* P5: the two hero actions stack at the same full content width, 12 px apart. */
  .hero .cta-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }

  .hero .cta {
    justify-content: center;
  }

  .intro {
    order: 4;
    margin-bottom: 0;
  }

  .hero-intro {
    order: 4;
    margin-bottom: 0;
  }

  .cta {
    min-height: 46px;
    padding: 0 18px;
  }

  .section-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .rail {
    padding-top: 12px;
  }

  .section-body {
    padding-top: 6px;
    border-top: 0;
  }

  .cap-diagram {
    display: none;
  }

  .case-row,
  .skill-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .brief-pair {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }

  /* P5: tighter tracking for project titles on phones (0.08em on wider screens). */
  .case-title {
    letter-spacing: 0.02em;
  }
}

@media (max-width: 359.98px) {
  .nav-list a {
    padding: 0 8px;
  }

  .nav-list a::after {
    left: 8px;
    right: 8px;
  }

  .nav {
    margin-left: -8px;
  }

  .cta {
    padding: 0 14px;
  }
}

/* Short viewports (high browser zoom, landscape phones): the masthead scrolls away with the page
   instead of covering a large share of the screen, and scroll targets drop its offset. */
@media (max-height: 30rem) {
  :root {
    --sticky-offset: 0px;
  }

  .masthead {
    position: relative;
  }
}

@media (prefers-reduced-motion: reduce) {
  .portrait-img {
    animation: none !important;
  }

  .reveal-on .reveal:not(.is-in) {
    opacity: 1;
    transform: none;
  }

  a,
  .cap-link,
  .cap-node,
  .effects-toggle,
  .case-details summary,
  .nav-list a::after {
    transition: none;
  }

  /* F1: the footer credit changes colour and glow instantly. */
  .site-footer a {
    transition: none;
  }
}

/* P5 closeout: without scripting the reveal control can never appear, so its reserved row is removed. The media
   feature needs no script timing, so normal start-up keeps the reserved row and never shifts. */
@media (scripting: none) {
  .portrait-controls {
    display: none;
  }
}

@media (forced-colors: active) {
  .syntax-layer,
  .portrait-halo,
  .cap-wires {
    display: none;
  }

  /* P9: the map links stay usable in forced colours, drawn with system colours; only the wire is hidden. */
  .cap-node {
    border: 1px solid LinkText;
    background: Canvas;
    color: LinkText;
  }

  .cap-node[aria-current="true"] {
    border: 3px solid Highlight;
    forced-color-adjust: none;
    background: Canvas;
    color: LinkText;
  }

  /* P5 closeout: the reveal control is not offered with forced colours, so its reserved row is removed too. */
  .portrait-controls {
    display: none;
  }

  .portrait-img {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .portrait-glyphs {
    display: none;
  }

  .glyph-pending .portrait-img,
  .has-glyph-face .portrait-img {
    opacity: 1;
  }

  .cap-link {
    border-left-color: Canvas;
  }

  .cap-link[aria-current="true"] {
    border-left: 6px solid Highlight;
    forced-color-adjust: none;
    background: Canvas;
    color: LinkText;
  }

  .nav-list a[aria-current]::after {
    background: Highlight;
    forced-color-adjust: none;
  }

  /* F1: a plain system link colour with no glow; hover and focus underline it. */
  .site-footer a,
  .site-footer a:hover,
  .site-footer a:focus-visible {
    color: LinkText;
    text-shadow: none;
  }

  .site-footer a:hover,
  .site-footer a:focus-visible {
    text-decoration-thickness: 2px;
  }
}
