/* ==========================================================================
   styles.css - all the styling for the portfolio.

   Want a different look? Start with the tokens in :root below. Colours,
   fonts, spacing and radius are set once there and reused everywhere else.

   Two palettes: the light theme is "Stone & Denim" (denim blue on stone
   paper, with brass highlights), the dark theme is "Graphite & Amber". The
   site opens in light; the switch in the header slides between them and
   the choice is remembered.
   ========================================================================== */

/* ---------- Tokens: light theme, Stone & Denim (the default) ---------- */
:root {
  --bg: #f4f2ed;
  --surface: #fefdfb;
  --ink: #1e2a3a;
  --muted: #5e6673;
  --line: #dcd8d0;
  --line-strong: #bab4a8;
  --accent: #1f4e8c;
  --accent-ink: #f6f9ff;
  --accent-soft: #f2e4b8;
  --warm: #8a6508; /* brass: step numbers and bullets, the orange half of the pairing */
  --grid: rgba(30, 42, 58, 0.07);
  --shadow: 0 1px 2px rgba(30, 42, 58, 0.06), 0 18px 32px -20px rgba(30, 42, 58, 0.35);
  --slot: 1.25rem; /* theme switch: one slot (the circle) */
  --knob-x: calc(var(--slot) * -1); /* strip offset: circle at the left for light, at the right for dark */
  color-scheme: light;

  --font-display: "Schibsted Grotesk", "Helvetica Neue", Arial, sans-serif;
  --font-body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --text-sm: 0.875rem;
  --text-base: 1.0625rem;
  --text-lg: 1.25rem;
  --text-xl: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
  --text-2xl: clamp(2rem, 1.4rem + 2.4vw, 3rem);
  --text-3xl: clamp(2.75rem, 1.5rem + 5vw, 5.25rem);

  --wrap: 68rem;
  --gutter: clamp(16px, 5vw, 40px);
  --radius: 10px;
  --header-h: 4rem;
}

/* ---------- Tokens: dark theme, Graphite & Amber ---------- */
/* Follows the system setting, unless the toggle has stamped data-theme on <html>. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #111417;
    --surface: #191d21;
    --ink: #eceff2;
    --muted: #9aa3ab;
    --line: #272c32;
    --line-strong: #3c434b;
    --accent: #f2b134;
    --accent-ink: #1a1200;
    --accent-soft: #3d2e0a;
    --warm: #f2b134;
    --grid: rgba(236, 239, 242, 0.06);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 18px 32px -20px rgba(0, 0, 0, 0.8);
    --knob-x: 0px;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #111417;
  --surface: #191d21;
  --ink: #eceff2;
  --muted: #9aa3ab;
  --line: #272c32;
  --line-strong: #3c434b;
  --accent: #f2b134;
  --accent-ink: #1a1200;
  --accent-soft: #3d2e0a;
  --warm: #f2b134;
  --grid: rgba(236, 239, 242, 0.06);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 18px 32px -20px rgba(0, 0, 0, 0.8);
  --knob-x: 0px;
  color-scheme: dark;
}

/* ---------- Base ---------- */
/* Big monitors: the page is set in rem, so scaling the root scales type, spacing and the column together. */
@media (min-width: 1600px) { html { font-size: 112.5%; } }
@media (min-width: 2200px) { html { font-size: 125%; } }

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

html {
  scroll-behavior: smooth;
  /* The drawers change height on screen; the browser must not shift the page to compensate. */
  overflow-anchor: none;
  /* Anchored sections land below the sticky header instead of under it. */
  scroll-padding-top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + 1rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

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

a {
  color: inherit;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.18em;
}
a:hover { text-decoration-color: var(--accent); }

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

h1, h2, h3 { text-wrap: balance; }

.icon {
  width: 1em;
  height: 1em;
  flex: none;
}

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

.mono {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

.eyebrow {
  margin: 0 0 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}

.skip-link {
  position: absolute;
  top: -100px;
  left: 1rem;
  z-index: 100;
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  background: var(--accent);
  color: var(--accent-ink);
  text-decoration: none;
}
.skip-link:focus { top: 1rem; }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 50;
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-right: auto;
  font-weight: 600;
  text-decoration: none;
}

.monogram {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.site-nav ul {
  display: flex;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  display: inline-block;
  padding: 0.45rem 0.7rem;
  border-radius: 6px;
  color: var(--muted);
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
}
.site-nav a:hover {
  color: var(--ink);
  background: var(--accent-soft);
}
.site-nav a[aria-current="true"] {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.4em;
}

.nav-toggle,
.theme-switch {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}
.nav-toggle:hover,
.theme-switch:hover { border-color: var(--ink); }

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.7rem;
  border-radius: 6px;
  font-size: 0.9rem;
  font-weight: 500;
}

/* Theme switch: one strip (sun, circle, moon) slides inside a small pill window that shows two of the three,
   held in a thin surface casing. The circle is the window's full height.
   Light: circle left, moon beside it. Dark: sun beside it, circle right. */
.theme-switch {
  display: inline-flex;
  padding: 3px;
  border-radius: 999px;
}
.switch-window {
  display: block;
  width: calc(var(--slot) * 2);
  height: var(--slot);
  overflow: hidden;
  border-radius: 999px;
  background: var(--accent-soft);
}
.switch-strip {
  display: grid;
  grid-template-columns: repeat(3, var(--slot));
  width: calc(var(--slot) * 3);
  height: var(--slot);
  transform: translateX(var(--knob-x));
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.switch-strip .icon {
  width: calc(var(--slot) * 0.6);
  height: calc(var(--slot) * 0.6);
  place-self: center;
  color: var(--ink);
  opacity: 0.75;
}
.switch-knob {
  width: var(--slot);
  height: var(--slot);
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: background-color 0.25s ease;
}

/* Load-time nudge: three seconds after load the strip glides 60% of the way toward the dark side, holds 0.4s, and bounces back quicker.
   Runs once; script.js adds the class. */
/* 1.55s total: 0.8s out to 60% of the travel, 0.4s hold, 0.35s back with a slight settle. */
@keyframes knob-hint {
  0%     { transform: translateX(var(--knob-x)); animation-timing-function: cubic-bezier(0.45, 0, 0.3, 1); }
  51.6%  { transform: translateX(calc(var(--knob-x) + var(--slot) * 0.6)); animation-timing-function: linear; }
  77.4%  { transform: translateX(calc(var(--knob-x) + var(--slot) * 0.6)); animation-timing-function: cubic-bezier(0.34, 1.4, 0.64, 1); }
  100%   { transform: translateX(var(--knob-x)); }
}
.theme-switch.is-hinting .switch-strip {
  animation: knob-hint 1.55s 3s 1 both;
}

/* Crossfade between the palettes when the switch is clicked. script.js adds the class for under half a second. */
html.theme-transition,
html.theme-transition *,
html.theme-transition *::before,
html.theme-transition *::after {
  transition: background-color 0.35s ease, color 0.35s ease, border-color 0.35s ease, fill 0.35s ease, stroke 0.35s ease, box-shadow 0.35s ease, transform 0.25s cubic-bezier(0.2, 0.7, 0.2, 1) !important;
}

@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  .site-nav ul {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.5rem var(--gutter) 1rem;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
  }
  .site-header.is-open .site-nav ul { display: flex; }
  .site-nav a {
    display: block;
    padding: 0.6rem 0.7rem;
    font-size: 1rem;
  }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding-block: clamp(4rem, 10vw, 7.5rem) clamp(3rem, 8vw, 6rem);
  border-bottom: 1px solid var(--line);
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 28px 28px;
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.9), transparent 92%);
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.9), transparent 92%);
}
.hero .wrap { position: relative; }

.display {
  max-width: 22ch;
  margin: 0 0 1.25rem;
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.025em;
}
.display mark {
  color: inherit;
  background: none;
  box-shadow: inset 0 -0.4em 0 var(--accent-soft);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.lede {
  max-width: 52ch;
  margin: 0 0 1.75rem;
  font-size: var(--text-lg);
  line-height: 1.5;
  color: var(--muted);
  text-wrap: pretty;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 2rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.15rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.15s ease, filter 0.15s ease, transform 0.15s ease;
}
.btn:hover { border-color: var(--ink); }
.btn:active { transform: translateY(1px); }
.btn-primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
}
.btn-primary:hover {
  border-color: var(--accent);
  filter: brightness(1.08);
}

.social {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.social a {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--muted);
  font-weight: 500;
  text-decoration: none;
}
.social a:hover { color: var(--accent); }

/* ---------- Sections ---------- */
.section {
  padding-block: clamp(3rem, 7vw, 5.5rem);
  border-bottom: 1px solid var(--line);
}

.section-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2.4fr);
  gap: 2rem clamp(2rem, 5vw, 4rem);
}

.section-head {
  position: sticky;
  top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + 1.5rem);
  align-self: start;
}
.section-head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.section-note { margin: 0.9rem 0 0; }
.section-sub {
  max-width: 34ch;
  margin: 0.9rem 0 0;
  color: var(--muted);
  line-height: 1.5;
  text-wrap: pretty;
}

.section-body { min-width: 0; }

@media (max-width: 800px) {
  .section-grid { grid-template-columns: 1fr; gap: 1.5rem; }
  .section-head { position: static; }
}

/* ---------- About ---------- */
.about-body {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

.prose p {
  max-width: 62ch;
  margin: 0 0 1em;
  text-wrap: pretty;
}
.prose p:last-child { margin-bottom: 0; }

.facts {
  display: grid;
  gap: 0.9rem;
  margin: 0;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.facts div { display: grid; gap: 0.15rem; }
.facts dt {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.facts dd {
  margin: 0;
  font-weight: 500;
}

.about-side {
  display: grid;
  gap: 1rem;
  align-content: start;
}

/* Now: what you're working on this month. Dashed, because it changes. */
.now {
  padding: 1.25rem 1.5rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}
.now .cs-heading-row { margin-bottom: 0.6rem; }
.now .eyebrow { margin: 0; }
.now-list {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.now-list li {
  position: relative;
  padding-left: 1.1rem;
  font-size: var(--text-sm);
  line-height: 1.5;
}
.now-list li::before {
  content: "";
  position: absolute;
  top: 0.6em;
  left: 0;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 1px;
  background: var(--warm);
}
.now-date {
  margin: 0.75rem 0 0;
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* How I work: an ordinary block in the flow (in its own section, so the About spacing below is switched off there). With a mouse or trackpad, script.js opens each drawer as its header reaches
   a fixed spot on screen (see the scroll engine in script.js); .drawers-pin is what it measures. */
.principles-block {
  margin-top: 2.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}
.section-how .principles-block { margin-top: 0; padding-top: 0; border-top: 0; }
.drawers-pin { position: relative; }
.principles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem 2.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.principles li {
  position: relative;
  padding-left: 1.4rem;
}
.principles li::before {
  content: "";
  position: absolute;
  top: 0.45em;
  left: 0.1rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 2px;
  background: var(--warm);
}
.principles h4 {
  margin: 0 0 0.3rem;
  font-size: 1rem;
  font-weight: 600;
}
.principles p {
  max-width: 48ch;
  margin: 0;
  color: var(--muted);
  text-wrap: pretty;
}

/* Three ways of working: expandable panels. Collapsed only when JavaScript can open them (html.js). */
.accordion {
  --peek: 3.5rem; /* height of a closed drawer: list padding plus two lines of text. script.js reads this. */
  margin-top: 0.5rem;
  border-top: 1px solid var(--line);
}
.acc-item { border-bottom: 1px solid var(--line); }
.acc-heading { margin: 0; }
.acc-trigger {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  width: 100%;
  padding: 1rem 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.acc-trigger:focus-visible { outline-offset: -2px; }
.acc-label {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.acc-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  transition: color 0.15s ease;
}
.acc-trigger:hover .acc-title { color: var(--accent); }
.acc-chevron {
  width: 1.1rem;
  height: 1.1rem;
  color: var(--muted);
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.acc-item.is-open .acc-chevron { transform: rotate(180deg); }
html.js .acc-item .acc-chevron { transform: rotate(calc(180deg * var(--p, 0))); }
/* Drawer heights are set by script.js (from scroll progress in the stage, from taps elsewhere); --p (0 to 1) on each .acc-item drives the peek styling. */
.acc-panel {
  position: relative;
  overflow: hidden;
}
html.js .acc-panel { height: var(--peek); } /* the peek; script.js overrides this per frame */
html.js .acc-item:not(.is-open) .acc-panel { cursor: pointer; }
/* Closed drawers keep a two-line peek (--peek): the first line stays readable and the second fades out under a short gradient. */
.acc-panel::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 1.75rem;
  background: linear-gradient(to bottom, transparent, var(--bg));
  opacity: 0;
  pointer-events: none;
}
html.js .acc-panel::after { opacity: calc(1 - var(--p, 0)); }
.acc-list {
  display: grid;
  gap: 0.6rem;
  margin: 0;
  padding: 0.25rem 0 1.4rem 11rem;
  list-style: none;
}
.acc-list li {
  position: relative;
  max-width: 62ch;
  padding-left: 1.4rem;
  color: var(--muted);
  text-wrap: pretty;
}
.acc-list strong {
  color: var(--ink);
  font-weight: 600;
}
.acc-list li::before {
  content: "";
  position: absolute;
  top: 0.62em;
  left: 0.1rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 2px;
  background: var(--warm);
}

@media (max-width: 640px) {
  .about-body { grid-template-columns: 1fr; }
  .about-body .trail-band { order: 1; }
  .about-body .about-side { order: 2; }
  .trail-band .trail-link { margin-left: 0; }
  .principles { grid-template-columns: 1fr; }
  .acc-trigger {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.25rem 1rem;
  }
  .acc-label { grid-column: 1 / -1; }
  .acc-list { padding-left: 0; }
}

/* ---------- Project cards ---------- */
.cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}
/* Other work sits below the case-study grid at full width, so three cards have room. */
.other-work { margin-top: clamp(2.5rem, 6vw, 4rem); }
.cards-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .cards-3 { grid-template-columns: 1fr; }
}

.card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.card:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: var(--shadow);
}

.card-media {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  max-width: 100%;
  overflow: hidden;
  background-color: var(--accent-soft);
  background-image: radial-gradient(var(--line-strong) 1px, transparent 1px);
  background-size: 12px 12px;
  border-bottom: 1px solid var(--line);
}
.card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card-glyph {
  font-family: var(--font-display);
  font-size: 4.5rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--accent);
}

.card-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1.25rem 1.5rem 1.35rem;
}
.card-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.card h3,
.card h4 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.card p {
  margin: 0;
  color: var(--muted);
  text-wrap: pretty;
}

.card-links {
  display: flex;
  gap: 1rem;
  margin-top: auto;
  padding-top: 0.25rem;
}
.card-links a {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.card-links a:hover { text-decoration: underline; }

/* Featured card: spans the grid, media on the left. */
.card-featured {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
}
.card-featured .card-media {
  aspect-ratio: auto;
  min-height: 220px;
  padding: 1.5rem;
  border-bottom: 0;
  border-right: 1px solid var(--line);
}
.card-art {
  width: 100%;
  max-width: 400px;
  height: auto;
}
/* The case study card carries a long paragraph, so the art sits above the text at full width instead of in a narrow side column. */
.case-study .card-featured { grid-template-columns: minmax(0, 1fr); }
.case-study .card-featured .card-media {
  min-height: 220px;
  padding: 1.5rem;
  border-right: 0;
  border-bottom: 1px solid var(--line);
}
.case-study .card-art { max-width: 440px; }
/* Illustration tokens: every fill and stroke is a CSS variable so it reads in both themes. */
.art-muted { fill: var(--line-strong); }
.art-legacy { fill: var(--bg); stroke: var(--line-strong); }
.art-arrow { fill: none; stroke: var(--accent); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.art-cloud { fill: var(--surface); stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; }
.art-record { fill: var(--bg); stroke: var(--line-strong); }
.art-strip { fill: var(--accent); }
.art-link { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linecap: round; }

@media (max-width: 640px) {
  .cards { grid-template-columns: 1fr; }
  .card-featured,
  .case-study .card-featured { grid-template-columns: 1fr; }
  .card-featured .card-media,
  .case-study .card-featured .card-media {
    min-height: 0;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
}

/* ---------- Tags and chips ---------- */
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.tags li,
.chip {
  padding: 0.22rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.4;
}
/* Long tags wrap on narrow screens; the short Example chips stay on one line. */
.tags li { white-space: normal; }
.chip { white-space: nowrap; }
.chip-note { border-style: dashed; }

/* ---------- Case study ---------- */
.case-study {
  display: grid;
  gap: 2.75rem;
}
.cs-block { min-width: 0; }
.cs-heading {
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.cs-heading-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.cs-heading-row .cs-heading { margin: 0; }

/* Numbered phases: a real sequence, so the numbers earn their place. */
/* The numbered steps sit on a rail. script.js positions the rail (--rail-top, --rail-length) and fills it (--rail-fill)
   as the reader scrolls down through the numbers; a step whose node the fill has passed gets is-reached. */
.steps {
  position: relative;
  margin: 0;
  padding: 0;
  list-style: none;
}
.steps::before,
.steps::after {
  content: "";
  position: absolute;
  left: calc(0.25rem - 1px);
  top: var(--rail-top, 0.9rem);
  width: 2px;
  background: var(--line-strong);
  pointer-events: none;
}
.steps::before { height: var(--rail-length, calc(100% - 1.8rem)); }
.steps::after { height: var(--rail-fill, 0px); background: var(--warm); }
.steps li {
  display: grid;
  grid-template-columns: 3.4rem minmax(0, 1fr);
  gap: 0.25rem 0.75rem;
  padding-block: 1rem;
  border-top: 1px solid var(--line);
}
.steps li:first-child { padding-top: 0; border-top: 0; }
.steps li:last-child { padding-bottom: 0; }
.step-num {
  position: relative;
  z-index: 1;
  padding: 0.3rem 0 0 1.1rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  transition: color 0.3s ease;
}
.step-num::before {
  content: "";
  position: absolute;
  top: calc(0.3rem + 0.8em - 0.25rem);
  left: 0;
  width: 0.5rem;
  height: 0.5rem;
  border: 2px solid var(--line-strong);
  border-radius: 50%;
  background: var(--bg);
  transition: background-color 0.3s ease, border-color 0.3s ease;
}
.steps li.is-reached .step-num { color: var(--warm); }
.steps li.is-reached .step-num::before { background: var(--warm); border-color: var(--warm); }
.step-body { min-width: 0; }
.step-body h4 {
  margin: 0 0 0.3rem;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.step-body p {
  max-width: 60ch;
  margin: 0;
  color: var(--muted);
  text-wrap: pretty;
}

/* Metrics strip: four plain tiles, marked as example figures in the heading row. */
.metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem;
}
/* --r is the radius of the wash, animated by a transition; registering it lets browsers interpolate it. */
@property --r {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
.metric {
  --x: 50%;            /* where the wash starts; script.js sets these from the pointer */
  --y: 50%;
  --rmax: 40rem;       /* how far it has to spread to reach the farthest corner; script.js sets this per hover */
  --feather: 2.75rem;  /* the width of the soft edge */
  --r: 0px;
  position: relative;
  display: grid;
  min-width: 0;
  padding: 1.1rem 1.5rem 1.2rem;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  transition: border-color 0.5s ease, --r 0.24s ease-in;
}
/* On hover, focus or a tap the accent spreads from where the pointer came in, like a wash of watercolour: a soft-edged circle grows
   until it covers the tile, and drains back to where the pointer left (finishing its spread first if the pointer was quick). The fill and the second line wear the same mask, so the words appear exactly where the
   colour's edge has reached them. The face and the second line share one grid cell, so the tile is always tall enough
   for either. Both sit inside the padding, so their copies of the mask are shifted by the padding to line up. */
.metric::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: 0;
  background: var(--accent);
  -webkit-mask-image: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--r) - var(--feather)), transparent var(--r));
  mask-image: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--r) - var(--feather)), transparent var(--r));
  pointer-events: none;
}
.metric-face,
.metric-more {
  grid-area: 1 / 1;
  position: relative;
  z-index: 1;
}
/* The face wears the inverse of the same mask: it shows only where the colour is not, so it is covered as the wash
   spreads and uncovered, edge first, as the wash draws back. */
.metric-face {
  -webkit-mask-image: radial-gradient(circle at calc(var(--x) - 1.5rem) calc(var(--y) - 1.1rem), transparent calc(var(--r) - var(--feather)), #000 var(--r));
  mask-image: radial-gradient(circle at calc(var(--x) - 1.5rem) calc(var(--y) - 1.1rem), transparent calc(var(--r) - var(--feather)), #000 var(--r));
}
.metric-more {
  align-self: end;
  margin: 0;
  color: var(--accent-ink);
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  text-wrap: pretty;
  -webkit-mask-image: radial-gradient(circle at calc(var(--x) - 1.5rem) calc(var(--y) - 1.1rem), #000 calc(var(--r) - var(--feather)), transparent var(--r));
  mask-image: radial-gradient(circle at calc(var(--x) - 1.5rem) calc(var(--y) - 1.1rem), #000 calc(var(--r) - var(--feather)), transparent var(--r));
  pointer-events: none;
}
.metric:focus-visible { outline-offset: 3px; }
.metric:hover,
.metric:focus-visible,
.metric.is-flipped,
.metric.is-filling {
  --r: var(--rmax);
  border-color: var(--accent);
  transition: border-color 0.5s ease, --r 0.35s cubic-bezier(0.3, 0.1, 0.3, 1);
}
.metric-value {
  margin: 0 0 0.35rem;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
}
.metric-label {
  margin: 0;
  color: var(--muted);
  line-height: 1.45;
}

/* Outcomes (and the ask-me list in Contact): square accent bullets drawn in CSS. */
.ask-list,
.outcomes {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.6rem;
}
.ask-list li,
.outcomes li {
  position: relative;
  max-width: 62ch;
  padding-left: 1.4rem;
  text-wrap: pretty;
}
.ask-list li::before,
.outcomes li::before {
  content: "";
  position: absolute;
  top: 0.62em;
  left: 0.1rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 2px;
  background: var(--warm);
}

@media (max-width: 800px) {
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
  .metrics { grid-template-columns: 1fr; }
}

/* ---------- Certifications ---------- */
.creds {
  margin: 0;
  padding: 0;
  list-style: none;
}
.creds li {
  display: grid;
  gap: 0.2rem;
  padding-block: 1rem;
  border-top: 1px solid var(--line);
}
.creds li:first-child { padding-top: 0; border-top: 0; }
/* Trailhead standing: rank, badges, superbadges, and the profile link. */
.trail {
  display: grid;
  gap: 0.9rem;
  margin-bottom: 1.75rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.trail .cs-heading-row { margin: 0; }
.trail .eyebrow { margin: 0; }
/* In About the card is a band under both columns: label, the two badges and the verify link in one row that wraps
   as the width shrinks. On narrow screens it moves between the paragraphs and the facts card (see the 640px rules). */
.trail.trail-band {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2.5rem;
  margin: 0;
  padding: 1.1rem 1.5rem;
}
.trail-band .eyebrow { margin: 0; flex: none; }
.trail-band .badge { margin: 0; }
.trail-band .badge img { width: 56px; height: 56px; }
.trail-band .trail-link { margin-left: auto; }
.trail-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem 1rem;
  margin: 0;
}
.trail-stats div { display: grid; gap: 0.1rem; }
.trail-stats dt {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.trail-stats dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.trail-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  justify-self: start;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.trail-link:hover { text-decoration: underline; }
.trail-stats.two { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }

/* Badge row: official artwork on the left of each caption. A dashed ring stands in until the image file exists. */
.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2.5rem;
}
.badge {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0;
}
.badge img {
  flex: none;
  width: 88px;
  height: 88px;
  object-fit: contain;
}
.badge figcaption {
  display: grid;
  gap: 0.15rem;
}
.badge-name {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.badge-note {
  color: var(--muted);
  font-size: var(--text-sm);
}
.badge.is-missing img { display: none; }
.badge.is-missing::before {
  content: "";
  flex: none;
  width: 88px;
  height: 88px;
  border: 1px dashed var(--line-strong);
  border-radius: 50%;
  background: radial-gradient(var(--line-strong) 1px, transparent 1px) center / 8px 8px;
}
@media (max-width: 420px) {
  .trail-stats,
  .trail-stats.two { grid-template-columns: 1fr; }
}

.cred-name { font-weight: 600; }
a.cred-name { text-decoration-color: var(--line-strong); }
a.cred-name:hover { text-decoration-color: var(--accent); }
.cred-note {
  max-width: 60ch;
  color: var(--muted);
  font-size: var(--text-sm);
  text-wrap: pretty;
}
.creds-footnote {
  margin: 1rem 0 0;
  color: var(--muted);
  font-size: var(--text-sm);
}

/* ---------- Skills ---------- */
.skills { display: grid; }
.skill-group {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr);
  gap: 0.5rem 1rem;
  align-items: baseline;
  padding-block: 1rem;
  border-top: 1px solid var(--line);
}
.skill-group:first-child { padding-top: 0; border-top: 0; }
.skill-group:last-child { padding-bottom: 0; }
.skill-group h3 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
}

@media (max-width: 520px) {
  .skill-group { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Experience timeline ---------- */
.timeline {
  margin: 0;
  padding: 0;
  list-style: none;
}
.tl-item {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 0.35rem 1.5rem;
  padding-block: 1rem;
  border-top: 1px solid var(--line);
}
.tl-item:first-child { padding-top: 0; border-top: 0; }
.tl-item:last-child { padding-bottom: 0; }
.tl-when {
  margin: 0;
  padding-top: 0.3rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.tl-body h3 {
  margin: 0 0 0.35rem;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.tl-org {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--muted);
}
.tl-body h3 .chip {
  margin-left: 0.25rem;
  vertical-align: middle;
  letter-spacing: 0;
}
.tl-body p {
  max-width: 60ch;
  margin: 0;
  color: var(--muted);
  text-wrap: pretty;
}

@media (max-width: 520px) {
  .tl-item { grid-template-columns: 1fr; }
  .tl-when { padding-top: 0; }
}

/* ---------- Contact ---------- */
.section-contact .lede { margin-bottom: 1.5rem; }
.section-contact .actions { margin-bottom: 1.5rem; }

/* ---------- Footer ---------- */
.site-footer {
  padding-block: 2rem 3rem;
  color: var(--muted);
  font-size: 0.9rem;
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  align-items: center;
  justify-content: space-between;
}
.footer-inner p { margin: 0; }

/* ---------- Contact: the first-90-days plan and the ask-me list ---------- */
.plan { margin-top: 2.25rem; }
.plan-steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.plan-steps li {
  min-width: 0;
  padding-top: 0.9rem;
  border-top: 2px solid var(--warm);
}
.plan-when {
  margin: 0;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.plan-steps h4 {
  margin: 0.4rem 0 0.35rem;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.plan-steps p:not(.plan-when) {
  margin: 0;
  color: var(--muted);
  text-wrap: pretty;
}
.ask { margin-top: 2.25rem; }
.ask + .actions { margin-top: 2.25rem; }
.contact-note {
  margin: 1rem 0 0;
  color: var(--muted);
  font-size: var(--text-sm);
}
@media (max-width: 900px) {
  .plan-steps { grid-template-columns: 1fr; gap: 1.25rem; }
}

/* ---------- Motion preferences ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
  }
}
