/* =============================================================================
   CSS VARIABLES & DESIGN TOKENS, GOLDEN RATIO SYSTEM
   -----------------------------------------------------------------------------
   This section defines the core design tokens for the entire project.
   The Golden Ratio (phi ≈ 1.618) is used to calculate spacing, typography scales,
   and structural layout dimensions to maintain mathematical harmony.
   ============================================================================= */

:root {
  /* Mathematical Constants */
  --phi: 1.618;
  --phi-inverse: 0.618;
  --phi-squared: 2.618;
  --phi-cubed: 4.236;
  --phi-fourth: 6.854;
  --phi-fifth: 11.09;

  /* Base Color Palette */
  --bg-light: #F0EBDC;
  --text-light: #212121;
  --bg-dark: #4A4A4A;
  --text-dark: #ffffff;
  --accent: #ffcc00;
  /* --action is declared below as an alias of --blue (Olivetti palette) */

  /* Olivetti Brand Colors */
  --red: #E4022D;
  --dark-red: #9A715D;
  --orange: #F56428;
  --yellow: #FADC46;
  --light-green: #64D264;
  --dark-green: #00643C;
  --cyan: #6ECDBE;
  --blue: #04508B;
  /* NOTE: --action is an alias of --blue (same Olivetti brand colour used as the
     interactive/link colour). Declared as var(--blue) so a single update propagates
     to both semantic and palette tokens. If the interactive colour ever diverges from
     the brand blue, replace this with a dedicated hex value. */
  --action: var(--blue);
  --purple: #6B3FA0;
  --light-blue: #C8E1F0;
  --black: #000000;
  /* NOTE: renamed from --white to --off-white. The value #F0EBDC is a warm ivory,
     not pure white (#FFFFFF). Using "white" for a beige token was misleading —
     any developer reaching for --white expecting #FFF would get the wrong colour.
     All usages updated below. */
  --off-white: #F0EBDC;
  --grey: #8E8F91;
  --dark-grey: #4A4A4A;

  /* Typography System, Golden Base Unit */
  --font-primary: "IBM Plex Sans", sans-serif;
  --font-fallback: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --base-unit: 1rem;

  /* Font Size Scale */
  --fs-micro: calc(var(--base-unit) * var(--phi-inverse) * var(--phi-inverse));
  --fs-tiny: calc(var(--base-unit) * var(--phi-inverse) * 0.75);
  --fs-small: calc(var(--base-unit) * var(--phi-inverse));
  --fs-base: calc(var(--base-unit) * 0.875);
  --fs-medium: calc(var(--base-unit) * 1);
  --fs-plus: calc(var(--base-unit) * 1.25);
  --fs-demi: calc(var(--base-unit) * 1.5);
  --fs-large: calc(var(--base-unit) * var(--phi));
  --fs-xl: calc(var(--base-unit) * var(--phi-squared));
  --fs-xxl: calc(var(--base-unit) * var(--phi-cubed));
  --fs-xxxl: calc(var(--base-unit) * var(--phi-fourth));
  --fs-display: calc(var(--base-unit) * var(--phi-fifth));
  --fs-marker: 0.75em;
  --fs-context: 0.875em;
  --fs-note: 0.9em;
  --space-em-0-75: 0.75em;
  --space-em-1: 1em;

  /* Line Height Scale */
  /* WARNING: --lh-debug (formerly --lh-nano) is set to 0.5, which is BELOW
     the font-size itself — lines will physically overlap if this is applied
     to any visible text. It is kept here for debugging layout grids only.
     Never use it on readable content. */
  --lh-debug: 0.5;
  --lh-tiny: 1;
  --lh-tight: 1.2;
  --lh-snug: 1.3;
  --lh-normal: 1.4;
  --lh-relaxed: 1.5;
  --lh-loose: 1.6;
  --lh-very-loose: 1.8;

  /* Letter Spacing Scale */
  --ls-tighter: -0.05em;
  --ls-tight: -0.025em;
  --ls-normal: 0;
  --ls-wide: 0.025em;
  --ls-wider: 0.05em;
  --ls-widest: 0.1em;

  /* Font Weight Scale */
  --fw-thin: 100;
  --fw-extralight: 200;
  --fw-light: 300;
  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  /* NOTE: IBM Plex Sans is loaded with weights up to 700 only.
     --fw-extrabold (800) and --fw-black (900) have no matching font variant
     and will be synthesised (faux-bold) by the browser, producing degraded
     rendering. If these weights are needed, add wght 800 to the Google Fonts
     URL in <head>. Otherwise, avoid using these tokens in component styles. */
  --fw-extrabold: 800;
  --fw-black: 900;

  /* Spacing System */
  --space-0: 0;
  --space-0px: 0px;
  --space-px: 1px;
  --space-2px: 2px;
  --space-3px: 3px;
  --space-4px: 4px;
  --space-6px: 6px;
  --space-8px: 8px;
  --space-12px: 12px;
  --space-20px: 20px;
  --space-24px: 24px;
  --space-32px: 32px;
  --space-96px: 96px;
  --space-micro: calc(var(--base-unit) * var(--phi-inverse) * var(--phi-inverse));
  --space-tiny: calc(var(--base-unit) * var(--phi-inverse));
  --space-xs: calc(var(--base-unit) * var(--phi-inverse) * var(--phi));
  --space-sm: calc(var(--base-unit) * var(--phi));
  --space-md: calc(var(--base-unit) * var(--phi-squared));
  --space-lg: calc(var(--base-unit) * var(--phi-cubed));
  --space-xl: calc(var(--base-unit) * var(--phi-fourth));
  --space-xxl: calc(var(--base-unit) * var(--phi-fifth));

  /* Border Radius */
  --border-radius-none: 0;
  --border-radius-xs: 2px;
  --border-radius-squircle: 22.37%;
  --border-radius-sm: calc(var(--space-micro));
  --border-radius-md: calc(var(--space-tiny));
  --border-radius-lg: calc(var(--space-xs));
  --border-radius-xl: calc(var(--space-sm));
  --border-radius-full: 9999px;

  /* Border Width */
  --border-width-0: 0;
  --border-width-1: 1px;
  --border-width-2: 2px;
  --border-width-3: 3px;
  --border-width-4: 4px;
  --border-width-8: 8px;

  /* Transition Durations */
  --duration-75: 75ms;
  --duration-100: 100ms;
  --duration-150: 150ms;
  --duration-200: 200ms;
  --duration-300: 300ms;
  --duration-500: 500ms;
  --duration-700: 700ms;
  --duration-1000: 1000ms;

  /* Layout */
  --container-max-width: 92.5rem;
  /* NOTE: was 1024px — converted to rem so this value scales with the user's
     browser font-size preference, consistent with --container-max-width above. */
  --content-max-width: 64rem;
  /* NOTE: was 780px — converted to rem (48.75rem) for consistency with the token system. */
  --small-content-max-width: 48.75rem;
  /* NOTE: --app-icon-max-width (512px) and --collaboration-card-min-width (300px)
     were removed — both were unused in any CSS rule. If needed in future, re-add here. */
  --card-meta-min-width: 140px;
  /* NOTE: --space-0 (unitless 0) and --space-0px (0px) are kept as separate tokens
     because some CSS properties require a unit (e.g. transition origin, gap in calc())
     while others work with unitless 0. Use --space-0 by default; --space-0px only
     where an explicit pixel unit is required by the property or calc context. */
  --space-0: 0;
  --space-0px: 0px;
  --underline-offset: 0.2em;
  --opacity-divider: 0.35;
  --grid-columns: 12;
  --grid-gap-sm: var(--space-xs);
  --grid-gap-md: var(--space-sm);
  --grid-gap-lg: var(--space-md);
  /* NOTE: --space-0 and --space-0px are declared once above (lines 113-114).
     The duplicate declarations previously here have been removed. */

  /* Theme Colors, Light (default) */
  --color-text: var(--text-light);
  --color-bg: var(--bg-light);
  --color-accent: var(--accent);
  --color-action: var(--action);
  --color-action-hover: var(--purple);
  --color-section-alt: rgba(0, 0, 0, 0.04);
  --color-section-alt-strong: rgba(0, 0, 0, 0.08);
  --color-muted: rgba(0, 0, 0, 0.6);
}


/* =============================================================================
   DARK MODE, Token overrides
   ============================================================================= */

@media (prefers-color-scheme: dark) {
  :root {
    --color-text: var(--text-dark);
    --color-bg: var(--bg-dark);
    --color-accent: #f2f2f2;
    --color-action: var(--orange);
    --color-action-hover: var(--yellow);
    --color-section-alt: rgba(255, 255, 255, 0.06);
    --color-section-alt-strong: rgba(255, 255, 255, 0.12);
    --color-muted: rgba(255, 255, 255, 0.7);
  }
}

html[data-theme="light"] {
  --color-text: var(--text-light);
  --color-bg: var(--bg-light);
  --color-accent: var(--accent);
  --color-action: var(--action);
  --color-action-hover: var(--purple);
  --color-section-alt: rgba(0, 0, 0, 0.04);
  --color-section-alt-strong: rgba(0, 0, 0, 0.08);
  --color-muted: rgba(0, 0, 0, 0.6);
}

html[data-theme="dark"] {
  --color-text: var(--text-dark);
  --color-bg: var(--bg-dark);
  --color-accent: #f2f2f2;
  --color-action: var(--orange);
  --color-action-hover: var(--yellow);
  --color-section-alt: rgba(255, 255, 255, 0.06);
  --color-section-alt-strong: rgba(255, 255, 255, 0.12);
  --color-muted: rgba(255, 255, 255, 0.7);
}


/* =============================================================================
   RESET & FOUNDATIONS
   ============================================================================= */

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

html {
  font-size: 100%;
  scroll-behavior: smooth;
}

/* =============================================================================
   ACCESSIBILITY: Reduced motion
   -----------------------------------------------------------------------------
   Users who have enabled "Reduce Motion" in their OS accessibility settings
   receive this override. All animations and transitions are collapsed to 0.01ms
   (effectively instant) via so the cascade cannot accidentally
   re-enable them.

   KNOWN EDGE-CASE: elements using .highlight-inline (inverted background) may
   produce a brief colour flash on state change because the transition snaps
   instead of fading. This is intentional — motion is disabled — but worth noting
   if the visual snap ever needs smoothing via a prefers-contrast fallback.
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
    transition-duration: 0.01ms;
  }
}

html,
body {
  max-width: none;
  margin: 0;
}

body {
  font-family: var(--font-primary), var(--font-fallback);
  color: var(--color-text);
  background-color: var(--color-bg);
  /* NOTE: the base font-size for the body is set to --fs-base (~14px).
     The previous value calc(var(--fs-large) * var(--phi)) produced ≈ 42px,
     which is far too large as a document baseline. Individual headings and
     paragraphs set their own sizes via the token scale above. */
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  letter-spacing: var(--ls-normal);
  font-weight: var(--fw-normal);
  margin: 0;
  padding: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

main {
  margin-top: 0;
  margin-bottom: var(--space-lg);
}


/* =============================================================================
   HEADER & FOOTER
   ============================================================================= */

header {
  width: 100vw;
  max-width: none;
  left: 50%;
  transform: translateX(-50%);
  position: fixed;
  top: 0;
  z-index: 9997;
  font-size: var(--fs-demi);
  background-color: var(--color-bg);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-lg);
}

header a {
  font-size: var(--fs-demi);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
}

/* Header social nav — now a <nav aria-label="Social profiles"> with <ul><li> children.
   Pipe separators are rendered via li::after to avoid screen readers reading "|" aloud. */
.header-links {
  display: inline-flex;
  align-items: center;
}

.header-links ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: 0;
}

.header-links li {
  display: inline-flex;
  align-items: center;
}

/* Pipe separator after each item except the last.
   NOTE: pseudo-elements (::after, ::before) are already ignored by screen readers
   per the ARIA specification — no aria-hidden equivalent exists or is needed in CSS. */
.header-links li:not(:last-child)::after {
  content: "|";
  margin: 0 var(--space-micro);
  color: var(--color-muted);
  pointer-events: none;
}

/* Theme toggle, pill with light/dark labels */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0;
  border: var(--border-width-1) solid var(--color-text);
  padding: var(--space-2px);
}

.theme-toggle label {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.theme-toggle input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.theme-toggle .text {
  font-size: var(--fs-base);
  padding: var(--space-4px) var(--space-12px);
  color: var(--color-text);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-normal);
  cursor: pointer;
  transition: background-color var(--duration-200) ease, color var(--duration-200) ease;
}

.theme-toggle input:checked + .text {
  background: var(--color-text);
  color: var(--color-bg);
}

.theme-toggle input:focus + .text {
  outline: var(--border-width-2) solid var(--color-action);
  outline-offset: var(--border-width-2);
}

/* Screen-reader-only utility */
.visuallyhidden {
  position: absolute;
  width: var(--space-px);
  height: var(--space-px);
  padding: 0;
  margin: calc(var(--space-px) * -1);
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

footer {
  padding: var(--space-xs) calc(var(--space-xl) * var(--phi) + var(--space-sm)) var(--space-xs) var(--space-lg);
  max-width: var(--container-max-width);
  margin-inline: auto;
  box-sizing: border-box;
}

header a,
footer a {
  letter-spacing: var(--ls-normal);
  font-weight: var(--fw-normal);
}


/* =============================================================================
   TYPOGRAPHY
   ============================================================================= */

h1 {
  font-size: var(--fs-xxl);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-tighter);
  line-height: var(--lh-tight);
  margin-top: var(--space-xl);
  margin-bottom: var(--space-md);
}

h2 {
  font-size: var(--fs-xxl);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-tighter);
  line-height: var(--lh-tight);
  margin-top: var(--space-lg);
  margin-bottom: var(--space-sm);
}

h3 {
  font-size: var(--fs-xl);
  font-weight: var(--fw-light);
  letter-spacing: var(--ls-tight);
  line-height: var(--lh-snug);
  margin-top: var(--space-md);
  margin-bottom: var(--space-sm);
}

.instruments-title {
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-tighter);
}

h4 {
  font-size: var(--fs-large);
  font-weight: var(--fw-light);
  letter-spacing: var(--ls-tight);
  line-height: var(--lh-snug);
  margin-top: var(--space-md);
  margin-bottom: var(--space-sm);
}

h5 {
  font-size: var(--fs-large);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-loose);
  margin-top: var(--space-sm);
  margin-bottom: var(--space-xs);
}

h6 {
  font-size: var(--fs-plus);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-normal);
  margin-top: var(--space-sm);
  margin-bottom: var(--space-xs);
}

p,
blockquote {
  font-size: var(--fs-large);
  font-weight: var(--fw-light);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-relaxed);
  margin-top: var(--space-xs);
  margin-bottom: var(--space-sm);
  max-width: var(--content-max-width);
}

ul,
ol {
  font-size: var(--fs-medium);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-loose);
  margin-top: var(--space-xs);
  margin-bottom: var(--space-md);
}

/* Styled list items, excluded for pub/articles/events/contents/nav lists */
main ul:not(.pub-list):not(.events-list):not(.editorial-note):not(.work-contents-list):not(.nav-sections):not(.engagement-list),
main ol {
  padding-left: var(--space-sm);
  list-style-position: inside;
}

main ul:not(.pub-list):not(.events-list):not(.work-contents-list):not(.nav-sections):not(.engagement-list) li,
main ol li {
  padding: var(--space-xs) var(--space-sm);
  margin-bottom: var(--space-xs);
  background-color: var(--color-section-alt);
  font-weight: var(--fw-medium);
}

main ul:not(.pub-list):not(.events-list):not(.work-contents-list):not(.nav-sections):not(.engagement-list) li:last-child,
main ol li:last-child {
  margin-bottom: 0;
}

li::marker {
  font-size: var(--fs-marker);
  color: var(--color-action);
}

small {
  font-size: var(--fs-base);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-normal);
  margin-top: var(--space-micro);
  margin-bottom: var(--space-micro);
}

footer p {
  font-size: var(--fs-medium);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-relaxed);
  margin-top: var(--space-xs);
  margin-bottom: var(--space-xs);
}

em,
i {
  font-style: italic;
}

strong {
  font-weight: var(--fw-semibold);
}

li strong {
  font-weight: var(--fw-medium);
}

.no-bullets {
  list-style: none;
  padding-left: 0;
}


/* =============================================================================
   LINKS
   ============================================================================= */

a {
  color: var(--color-action);
  text-decoration: none;
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-relaxed);
  transition: color var(--duration-200) ease-in-out;
}

a:hover,
a:focus {
  color: var(--color-action-hover);
  text-decoration: underline;
  text-underline-offset: var(--underline-offset);
}

a:focus {
  outline: var(--border-width-2) solid var(--color-action);
  outline-offset: var(--border-width-2);
}


/* =============================================================================
   BUTTONS
   ============================================================================= */

button,
.button {
  background: var(--color-text);
  color: var(--color-bg);
  padding: var(--space-xs) var(--space-md);
  border: var(--border-width-2) solid var(--color-text);
  cursor: pointer;
  /* NOTE: transition: all avoided — only animate the properties that actually
     change on :hover/:focus to prevent accidentally triggering layout recalcs. */
  transition: background-color var(--duration-200) ease-in-out,
              color var(--duration-200) ease-in-out,
              transform var(--duration-200) ease-in-out,
              border-color var(--duration-200) ease-in-out;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-normal);
  border-radius: var(--border-radius-sm);
  display: inline-block;
  text-decoration: none;
}

button:hover,
button:focus,
.button:hover,
.button:focus {
  background: var(--color-bg);
  color: var(--color-text);
  transform: translateY(calc(var(--space-px) * -1));
}

button:focus,
.button:focus {
  outline: var(--border-width-2) solid var(--color-action);
  outline-offset: var(--border-width-2);
}

/* CTA, outline variant */
.cta {
  display: inline-block;
  font-size: var(--fs-large);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  background-color: transparent;
  border: var(--border-width-2) solid var(--color-text);
  padding: var(--space-xs) var(--space-md);
  margin-top: var(--space-sm);
  letter-spacing: var(--ls-normal);
  text-decoration: none;
  transition: background-color var(--duration-200) ease-in-out, color var(--duration-200) ease-in-out;
}

.cta:hover,
.cta:focus {
  background-color: var(--color-text);
  color: var(--color-bg);
  text-decoration: none;
}

/* CTA, filled variant */
.cta-primary {
  background-color: var(--color-text);
  color: var(--color-bg);
}

.cta-primary:hover,
.cta-primary:focus {
  background-color: transparent;
  color: var(--color-text);
}

/* CTA, ghost/text variant */
.cta-secondary {
  font-size: inherit;
  opacity: 0.6;
  text-decoration: none;
  border-bottom: var(--border-width-1) solid currentColor;
  transition: opacity var(--duration-200) ease;
}

.cta-secondary:hover {
  opacity: 1;
}

/* CTA group, horizontal flex row */
.cta-group {
  display: flex;
  gap: var(--space-24px);
  align-items: center;
  flex-wrap: wrap;
}


/* =============================================================================
   DIVIDERS
   ============================================================================= */

hr {
  border: none;
  height: var(--border-width-2);
  background-color: var(--color-text);
  margin-top: var(--space-lg);
  margin-bottom: var(--space-lg);
  opacity: var(--opacity-divider);
}


/* =============================================================================
   GRID SYSTEM
   ============================================================================= */

.container {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  gap: var(--grid-gap-sm);
  max-width: 100%;
  margin: 0 auto;
  padding: var(--space-sm);
}

.container > section.full-width {
  grid-column: span 12;
}


/* =============================================================================
   SECTION LAYOUT
   ============================================================================= */

section {
  position: relative;
  z-index: 0;
  padding: var(--space-md) var(--space-lg) var(--space-lg) var(--space-lg);
  scroll-margin-top: var(--space-96px);
  margin-top: 0;
  margin-bottom: 0;
  max-width: var(--container-max-width);
  margin-inline: auto;
  box-sizing: border-box;
}

/* Alternating background stripe on even sections.
   NOTE: sections live inside div.page-sections, not as direct children of <main>.
   The selector must target .page-sections > section, not main > section,
   otherwise no element ever matches and the alternating stripes are invisible. */
.page-sections > section:nth-of-type(even)::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  background-color: var(--color-section-alt);
  z-index: -1;
}

/* Full-width bottom rule on every section */
section::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: var(--space-lg);
  width: calc(100% - calc(var(--space-lg) * 2));
  height: var(--border-width-2);
  background-color: var(--color-text);
  /* Prevent this decorative line from intercepting pointer events
     on content directly above it (e.g. links near the section bottom) */
  pointer-events: none;
}

section dl:last-of-type {
  margin-bottom: var(--space-md);
}

section h2:first-of-type {
  margin-top: var(--space-xs);
}


/* =============================================================================
   MEDIA, img, video, figure, figcaption
   ============================================================================= */

figure {
  /* User Agent Reset */
  margin: 0;
  margin-block-start: 0;
  margin-block-end: 0;
  margin-inline-start: 0;
  margin-inline-end: 0;

  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  margin-top: var(--space-md);
  margin-bottom: var(--space-md);
}

img,
video {
  width: 100%;
  height: auto;
  display: block;
  object-fit: contain;
  border-radius: var(--border-radius-sm);
  margin-bottom: calc(var(--space-micro) * var(--phi-squared));
}

.img-container {
  position: relative;
  width: 100%;
  aspect-ratio: var(--img-aspect, 16 / 9);
  border-radius: var(--border-radius-sm);
  overflow: hidden;
  background-color: var(--color-section-alt);
}

.img-container img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 1;
  transition: opacity var(--duration-300) ease-in-out;
  margin-bottom: 0;
}

.img-container video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 1;
  transition: opacity var(--duration-300) ease-in-out;
  margin-bottom: 0;
  display: block;
}

.skeleton-loader {
  position: absolute;
  inset: 0;
  background-color: var(--color-section-alt);
  opacity: 0;
  transition: opacity var(--duration-300) ease-in-out;
  pointer-events: none;
}

.img-container.skeleton img,
.img-container.skeleton video {
  opacity: 0;
}

.img-container.skeleton .skeleton-loader {
  opacity: 1;
}

.img-container.skeleton .skeleton-loader::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background-image: linear-gradient(90deg, transparent, var(--color-section-alt-strong), transparent);
  animation: shimmer var(--duration-1000) linear infinite;
  will-change: transform;
}

.img-container.skeleton.no-shimmer .skeleton-loader::before {
  animation: none;
}

body.is-scrolling .img-container.skeleton .skeleton-loader::before {
  animation-play-state: paused;
}

.img-container.loaded .skeleton-loader {
  opacity: 0;
}

.img-container.loaded img,
.img-container.loaded video {
  opacity: 1;
}

@keyframes shimmer {
  100% {
    transform: translateX(100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .img-container.skeleton .skeleton-loader::before {
    animation: none;
  }
}

figure > div {
  border-radius: var(--border-radius-sm);
  overflow: hidden;
}

figure iframe {
  border-radius: var(--border-radius-sm);
}

figcaption {
  font-size: var(--fs-base);
  color: var(--color-text);
  margin-top: var(--space-micro);
  margin-bottom: var(--space-micro);
  padding: calc(var(--space-micro) * var(--phi)) 0;
  letter-spacing: var(--ls-normal);
  font-weight: var(--fw-normal);
  display: block;
  width: 100%;
  max-width: var(--small-content-max-width);
  line-height: var(--lh-normal);
}

figcaption a {
  letter-spacing: var(--ls-normal);
  font-weight: var(--fw-normal);
}


/* =============================================================================
   TABLES
   ============================================================================= */

/* Design case, three equal columns, full border grid */
.design-case-table-wrapper {
  overflow-x: auto;
  margin-top: var(--space-sm);
  margin-bottom: var(--space-lg);
}

.design-case-table {
  width: 100%;
  min-width: 60rem;
  table-layout: auto;
  border-collapse: collapse;
  text-align: left;
  font-variant-numeric: tabular-nums;
}

.design-case-table th,
.design-case-table td {
  width: calc(100% / 3);
  padding: var(--space-xs) var(--space-sm);
  border: var(--border-width-1) solid var(--color-text);
  vertical-align: top;
  word-wrap: break-word;
  overflow-wrap: break-word;
  white-space: normal;
  line-height: var(--lh-normal);
}

.design-case-table th {
  background-color: var(--color-bg);
  color: var(--color-text);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-base);
  letter-spacing: var(--ls-normal);
}

.design-case-table td {
  font-size: var(--fs-base);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-relaxed);
}

/* Work section <nav> contents list — compact anchor-link list above the table.
   Visible on all viewport sizes; the table below it hides at ≤ 30rem.
   Uses the same font metrics as the rest of the section prose. */
.work-contents-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-sm) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2px);
}

.work-contents-list li {
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
}

/* Work summary, borderless rows with uppercase header */
.work-summary-table-wrapper {
  overflow-x: auto;
  margin-top: var(--space-sm);
  margin-bottom: var(--space-lg);
}

.work-summary-table {
  width: 100%;
  min-width: 70rem;
  table-layout: auto;
  border-collapse: collapse;
  text-align: left;
  font-variant-numeric: tabular-nums;
}

.work-summary-table th,
.work-summary-table td {
  padding: var(--space-xs) var(--space-sm);
  vertical-align: top;
  word-wrap: break-word;
  overflow-wrap: break-word;
  white-space: normal;
  line-height: var(--lh-normal);
}

.work-summary-table th {
  background-color: var(--color-section-alt);
  color: var(--color-text);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-small);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

.work-summary-table td {
  font-size: var(--fs-base);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
  line-height: var(--lh-relaxed);
  border-bottom: var(--border-width-1) solid var(--color-section-alt);
}

.work-summary-table tbody tr:last-child td {
  border-bottom: none;
}

.work-summary-table a {
  color: var(--color-action);
  text-decoration: none;
  font-weight: var(--fw-semibold);
}

.work-summary-table a:hover,
.work-summary-table a:focus {
  color: var(--color-action-hover);
  text-decoration: underline;
}


/* =============================================================================
   HORIZONTAL COMPACT CARDS
   ============================================================================= */

.horizontal-cards-compact {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-top: var(--space-md);
  margin-bottom: var(--space-lg);
}

.horizontal-card-compact {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-xs);
  border: var(--border-width-1) solid var(--color-text);
  max-width: var(--content-max-width);
}

.horizontal-card-compact .card-content {
  flex: 1;
}

.horizontal-card-compact .card-meta {
  flex-shrink: 0;
  text-align: right;
  min-width: var(--card-meta-min-width);
}

.horizontal-card-compact h5 {
  font-size: var(--fs-medium);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-normal);
  margin: 0 0 var(--space-micro) 0;
  color: var(--color-text);
}

.horizontal-card-compact h6 {
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  color: var(--color-action);
  margin: 0;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

.horizontal-card-compact p {
  font-size: var(--fs-base);
  font-weight: var(--fw-normal);
  line-height: var(--lh-relaxed);
  letter-spacing: var(--ls-normal);
  margin: var(--space-tiny) 0 0 0;
  color: var(--color-text);
}


/* =============================================================================
   HIGHLIGHT, QUOTE & INLINE CALLOUTS
   ============================================================================= */

/* Inline highlight callout — inverted colours (text on dark / dark on light).
   Previously declared twice; merged into a single rule.
   The #about section overrides this to display:block with larger sizing — see
   the section-specific rules below. */
.highlight-inline {
  display: inline;
  background-color: var(--color-text);
  color: var(--color-bg);
  font-weight: var(--fw-medium);
  padding: var(--space-2px) var(--space-8px);
  transition: background-color var(--duration-200) ease, color var(--duration-200) ease;
}

.highlight-inline a {
  color: var(--color-bg);
  font-weight: var(--fw-medium);
  text-decoration: underline;
}

.quote {
  border-left: var(--border-width-2) solid var(--color-text);
  padding-left: var(--space-xs);
  margin-left: 0;
  font-style: italic;
  margin-top: var(--space-xs);
  margin-bottom: var(--space-sm);
}

figcaption.quote {
  margin-top: var(--space-tiny);
  margin-bottom: var(--space-xs);
}

.project-context {
  font-size: var(--fs-context);
  color: var(--color-muted);
  border-left: var(--border-width-2) solid currentColor;
  padding-left: var(--space-em-0-75);
  line-height: var(--lh-normal);
  margin-bottom: var(--space-em-1);
}

.research-note {
  font-size: var(--fs-note);
  opacity: 0.7;
  border-left: var(--border-width-2) solid currentColor;
  padding-left: var(--base-unit);
  margin-top: var(--space-32px);
}

/* Editorial note: for cited principles, manifestos, and reflective asides.
   Italic, smaller, accent border, curly-quote opener on first para. */
.editorial-note {
  font-size: var(--fs-demi);
  font-style: italic;
  color: var(--color-muted);
  border-left: var(--border-width-1) solid var(--color-action);
  padding-left: var(--base-unit);
  margin-top: var(--space-32px);
  margin-bottom: 0;
}

.editorial-note + .editorial-note {
  margin-top: var(--space-xs);
}

.editorial-note:first-of-type::before {
  content: ‘‘;
  font-size: var(--fs-demi);
  line-height: 0;
  vertical-align: -0.3em;
  margin-right: 0.1em;
  font-style: normal;
}

.editorial-note strong {
  font-style: normal;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}

ul.editorial-note {
  padding-left: 0;
  list-style-position: outside;
  list-style-type: none;
  max-width: var(--content-max-width);
  color: var(--color-text);
  border-left: none;
  line-height: var(--lh-tiny);
}

ul.editorial-note li {
  margin-bottom: var(--space-xs);
}

.editorial-note ul {
  max-width: var(--content-max-width);
}

.social-proof {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.35em;
  row-gap: 0.5em;
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  margin-top: var(--space-md);
  margin-bottom: var(--space-md);
  /* NOTE: --color-muted is already semi-transparent (rgba 0,0,0,0.6 in light /
     rgba 255,255,255,0.7 in dark). Adding opacity: 0.85 on top compounds the
     reduction, pushing text contrast below WCAG AA for small text. The opacity
     declaration has been removed; --color-muted alone provides the intended tone. */
  color: var(--color-muted);
  font-weight: var(--fw-normal);
  border-top: var(--border-width-1) solid var(--color-text);
  border-bottom: var(--border-width-1) solid var(--color-text);
  padding-top: var(--space-xs);
  padding-bottom: var(--space-xs);
  max-width: var(--container-max-width);
}

.social-proof .nowrap {
  white-space: nowrap;
}

.social-proof a {
  color: var(--color-text);
  text-decoration: none;
  font-weight: var(--fw-medium);
  transition: opacity var(--duration-200) ease-in-out;
}

.social-proof a:hover {
  opacity: 1;
  color: var(--color-action);
  text-decoration: underline;
  text-underline-offset: var(--underline-offset);
}


/* =============================================================================
   SCROLL CONTAINER, horizontal drag-to-scroll gallery
   -----------------------------------------------------------------------------
   IMPORTANT LAYOUT TRAP: .scroll-container is display:flex with flex-direction:row.
   Any direct child — including a <figcaption> — becomes a flex item on the same
   horizontal row as the images. Never place a <figcaption> as a direct child of
   a <figure class="scroll-container">. Structure correctly as:
     <figure>
       <figure class="scroll-container">...</figure>
       <figcaption>...</figcaption>
     </figure>
   or wrap the scroll container in a separate element before the caption.
   ============================================================================= */


/* =============================================================================
   SCROLL GALLERY NAV ARROWS
   Injected via JS around every .scroll-container.
   Typographic arrows (IBM Plex Sans), centred vertically on the image strip.
   Left arrow hidden at scroll start; right arrow hidden at scroll end.
   ============================================================================= */

.scroll-wrapper {
  position: relative;
  display: grid;
  grid-template-rows: auto auto;
}

.scroll-wrapper .scroll-container {
  grid-row: 1;
  grid-column: 1;
}

.scroll-nav-btn {
  position: absolute;
  top: calc(50% - var(--space-lg) / 2);
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--space-xl);
  height: var(--space-lg);
  background: rgba(0, 0, 0, var(--opacity-divider));
  color: var(--color-text-inv, #fff);
  border: none;
  border-radius: 0;
  /* outline: transparent keeps the element in the browser's focus ring system
     without showing anything visually. :focus-visible below restores the visible
     outline for keyboard users. Using outline: none instead would break
     accessibility on browsers that do not support :focus-visible. */
  outline: var(--border-width-2) solid transparent;
  font-family: var(--font-primary);
  font-size: var(--fs-large);
  font-weight: var(--fw-light);
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--duration-200) ease-in-out,
              color var(--duration-200) ease-in-out;
  padding: 0;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-appearance: none;
  appearance: none;
}

.scroll-wrapper:hover .scroll-nav-btn:not([hidden]),
.scroll-nav-btn:focus-visible {
  opacity: 1;
}

.scroll-nav-btn::after {
  content: "←";
  font-size: var(--fs-large);
  line-height: 1;
  display: block;
}

.scroll-nav-btn--prev::after {
  content: "←";
}

.scroll-nav-btn--next::after {
  content: "→";
}

.scroll-nav-btn:hover {
  color: var(--color-action);
}

.scroll-nav-btn:focus-visible {
  outline: var(--border-width-2) solid var(--color-action);
  outline-offset: var(--border-width-2);
  opacity: 1;
}

.scroll-nav-btn--prev {
  left: var(--space-xs);
}

.scroll-nav-btn--next {
  right: var(--space-xs);
}

.scroll-nav-btn[hidden] {
  display: none;
}

/* Scroll hint label — desktop only (hover+fine pointer), hidden on touch */
.scroll-nav-btn .scroll-nav-label {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .scroll-nav-btn .scroll-nav-label {
    display: block;
    font-size: var(--fs-small);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    line-height: 1;
    opacity: 0.8;
    pointer-events: none;
    order: 2;
  }

  .scroll-nav-btn {
    flex-direction: column;
    gap: var(--space-micro);
    height: auto;
    padding: var(--space-micro) var(--space-xs);
  }

  .scroll-nav-btn::after {
    order: 1;
  }
}

@media (max-width: 40rem) {
  .scroll-nav-btn {
    opacity: 0.8;
    width: var(--space-lg);
    height: var(--space-md);
    font-size: var(--fs-base);
  }

  .scroll-nav-btn::after {
    font-size: var(--fs-base);
  }
}

.scroll-container {
  display: flex;
  flex-direction: row;
  gap: calc(var(--space-micro) * var(--phi-squared));
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* -webkit-overflow-scrolling: touch — REMOVED.
     Deprecated since Safari 13; modern iOS uses momentum scrolling by default.
     Keeping this property has no effect and adds dead code. */
  scroll-behavior: auto;
  scrollbar-width: thin;
  padding-right: calc(var(--space-lg) * var(--phi-inverse));
  position: relative;
  overscroll-behavior-x: contain;
  /* cursor: grab signals to the user that the gallery is draggable.
     Changes to 'grabbing' via .dragging when a drag is in progress. */
  cursor: grab;
}

.scroll-container.dragging {
  cursor: grabbing;
  user-select: none;
}

.scroll-container img {
  flex-shrink: 0;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  width: 100%;
  height: auto;
  -webkit-user-drag: none;
  pointer-events: auto;
}

.scroll-container .img-container {
  flex-shrink: 0;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  width: 100%;
}

.scroll-container .img-container img {
  -webkit-user-drag: none;
  pointer-events: auto;
}

.scroll-container::-webkit-scrollbar {
  height: calc(var(--space-micro) * var(--phi-cubed));
}

.scroll-container::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.3);
  border-radius: calc(var(--space-micro) * var(--phi-squared));
}

.scroll-container::-webkit-scrollbar-track {
  background: transparent;
}


/* =============================================================================
   HINT, blinking scroll nudge
   ============================================================================= */

.hint {
  font-weight: var(--fw-medium);
  color: var(--color-text);
  text-underline-offset: calc(var(--space-micro) * var(--phi-cubed));
  opacity: 1;
  animation: double-blink calc(var(--duration-500) * 6) ease-in-out infinite;
  margin-top: var(--space-micro);
}

.hint small {
  border: var(--border-width-2) solid var(--color-text);
  padding: var(--space-xs);
  border-radius: var(--border-radius-sm);
  margin-top: var(--space-micro);
  margin-bottom: var(--space-micro);
}

@keyframes double-blink {
  0%   { opacity: 1; }
  2%   { opacity: 0.1; }
  4%   { opacity: 1; }
  6%   { opacity: 0.1; }
  8%   { opacity: 1; }
  100% { opacity: 1; }
}


/* =============================================================================
   EVENTS LIST
   ============================================================================= */

.events-list {
  list-style: none;
  padding: 0;
  margin: 0;
  font-family: var(--font-primary);
  max-width: none;
  column-count: 2;
  column-gap: var(--space-lg);
  column-fill: balance;
}

.events-list li {
  margin-top: var(--space-tiny);
  margin-bottom: var(--space-sm);
  line-height: var(--lh-normal);
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
}

.events-list strong {
  display: block;
  font-size: var(--fs-medium);
  font-weight: var(--fw-semibold);
}

.events-list time {
  color: var(--color-text);
  font-size: var(--fs-medium);
  margin-right: var(--space-8px);
  font-weight: var(--fw-normal);
}

.event-type {
  background: var(--color-action);
  color: var(--off-white);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  padding: var(--space-2px) var(--space-6px);
  border-radius: var(--border-radius-md);
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
}

.events-list a {
  display: block;
  margin-top: var(--space-4px);
  color: var(--color-action);
  text-decoration: none;
  font-weight: var(--fw-medium);
  transition: color var(--duration-200) ease;
}

.events-list a:hover,
.events-list a:focus {
  text-decoration: underline;
  color: var(--color-action-hover);
}


/* =============================================================================
   PUBLICATIONS, left-accent card pattern
   -----------------------------------------------------------------------------
   This section styles the publication cards. It uses a CSS Grid layout to position
   the color-coded accent bar alongside the publication's content.
   ============================================================================= */

.publications-note {
  font-style: italic;
  opacity: 0.9;
  margin-bottom: var(--space-24px);
  border-left: var(--border-width-3) solid var(--color-text);
  background-color: var(--color-section-alt);
  padding: var(--space-12px) var(--base-unit);
}

.publications-note a {
  color: inherit;
  font-weight: var(--fw-semibold);
}

.pub-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-sm);
}

.pub-item {
  display: grid;
  grid-template-columns: var(--border-width-4) 1fr;
  gap: 0 var(--space-20px);
  padding: var(--space-12px) 0;
  border-bottom: var(--border-width-1) solid var(--color-section-alt);
  break-inside: avoid;
}

.pub-item:last-child {
  border-bottom: none;
}

/* Accent bar — colour by publication type.
   The bar sits in a CSS Grid cell with align-self: stretch, which already
   makes it fill the full row height. min-height: 100% is redundant in a
   grid context and has been removed to avoid potential conflicts. */
.pub-item-accent {
  width: var(--border-width-4);
  border-radius: var(--border-radius-xs);
  background-color: var(--color-text);
  opacity: 0.3;
  align-self: stretch;
}

/* TODO: accent bar colour differentiation by publication type.
   Currently all types map to the same --color-text, making the data-type
   attribute functionally inert. To activate: assign distinct palette tokens
   per type, e.g.:
     [data-type="book"]     → var(--red)
     [data-type="industry"] → var(--blue)
     [data-type="research"] → var(--dark-green)
     [data-type="featured"] → var(--accent)
   Until then a single rule is sufficient. */
.pub-item[data-type] .pub-item-accent {
  background-color: var(--color-text);
}

.pub-item-body {
  display: block;
}

.pub-item-type {
  display: inline-block;
  font-size: var(--fs-tiny);
  font-weight: var(--fw-semibold);
  /* NOTE: 0.08em falls between --ls-wide (0.025em) and --ls-wider (0.05em) and
     --ls-widest (0.1em). Using --ls-widest (0.1em) is the closest token;
     if the exact value matters visually, add --ls-wide-08: 0.08em to :root. */
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--color-text);
  opacity: 0.6;
  /* NOTE: 0.3rem has no matching space token (--space-micro ≈ 0.236rem,
     --space-tiny ≈ 0.618rem). Using --space-micro as the closest available token. */
  margin-bottom: var(--space-micro);
}

.pub-item-type a {
  color: inherit;
  font-weight: var(--fw-semibold);
  text-decoration: none;
}

.pub-item-title {
  font-size: var(--fs-plus);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-normal);
  /* NOTE: 0.35rem has no exact token; --space-micro (≈ 0.236rem) is the
     closest available. Kept as --space-micro for token consistency. */
  margin: 0 0 var(--space-micro) 0;
}

.pub-item-title a {
  color: inherit;
  font-weight: var(--fw-semibold);
  text-decoration: none;
  border-bottom: var(--border-width-1) solid transparent;
  transition: border-color var(--duration-150) ease;
}

.pub-item-title a:hover {
  border-bottom-color: currentColor;
}

.pub-item-meta {
  font-size: var(--fs-base);
  color: var(--color-text);
  opacity: 0.65;
  /* NOTE: 0.45rem has no exact token; --space-micro (≈ 0.236rem) is closest.
     Keeping --space-micro for system consistency. */
  margin-bottom: var(--space-micro);
  font-weight: var(--fw-semibold);
}

.pub-item-meta a,
.pub-item-abstract a {
  color: inherit;
  font-weight: var(--fw-semibold);
}

.pub-item-abstract {
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text);
  opacity: 0.88;
  font-weight: var(--fw-medium);
  margin: 0;
}


/* =============================================================================
   SECTION-SPECIFIC, #intro
   -----------------------------------------------------------------------------
   NOTE: margin-top: var(--space-xxl) computes to ≈ 178px at 1rem base-unit.
   On very small viewports (320–375px) this may exceed the header height
   significantly, creating excessive white space above the h1. If this becomes
   an issue, override margin-top inside the ≤ 30rem media query at the bottom
   of this file.
   ============================================================================= */

#intro {
  margin-top: var(--space-xxl);
}

#intro .intro-identity {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
}

#intro .intro-identity figure {
  margin: 0;
}

#intro h1 {
  margin-top: var(--space-lg);
  margin-bottom: var(--space-xs);
}

#intro h2 {
  font-weight: var(--fw-light);
}

#intro h2 .role-tag {
  white-space: nowrap;
  display: inline;
}

@media (max-width: 64rem) {
  #intro h2 .role-tag {
    white-space: normal;
  }
}

#intro h3 {
  margin-bottom: var(--space-md);
}

#intro h5 {
  font-weight: var(--fw-medium);
}

#intro a {
  letter-spacing: var(--ls-normal);
}

/* Avatar ring */
#intro figure:first-of-type .img-container {
  width: calc(var(--fs-xxl) * var(--phi));
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  overflow: hidden;
  background-color: transparent;
  box-shadow: 0 0 0 calc(var(--fs-base) * var(--phi-inverse) * var(--phi-inverse)) var(--color-text);
  margin-top: 0;
  margin-bottom: var(--space-md);
  margin-left: var(--space-micro);
}

#intro figure:first-of-type .img-container img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  margin: 0;
}

/* Highlight block, #about override — larger, block-level callout style */
#about .highlight-inline {
  display: block;
  font-size: var(--fs-xl);
  font-weight: var(--fw-light);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  padding: var(--space-sm) var(--space-md);
  margin-top: var(--space-md);
  margin-bottom: var(--space-md);
  max-width: var(--content-max-width);
}


/* =============================================================================
   SECTION-SPECIFIC, #about
   ============================================================================= */

#about figure:first-of-type {
  margin-bottom: 0;
}

#about figure:first-of-type img {
  border-radius: var(--border-radius-sm);
  width: auto;
  height: auto;
  max-width: max-content;
  background-color: var(--off-white);
  border: var(--space-micro) solid var(--off-white);
  margin-top: var(--space-lg);
}

#about .img-container.badge {
  width: fit-content;
  aspect-ratio: unset;
  background-color: transparent;
}

#about .img-container.badge img {
  width: auto;
  height: auto;
}

#about figcaption {
  margin-top: var(--space-tiny);
  margin-bottom: var(--space-sm);
}

/* =============================================================================
   SECTION-SPECIFIC, #lecturing
   ============================================================================= */

#lecturing p a.cta-link {
  display: block;
  margin-top: var(--space-xs);
}

#lecturing .lecturing-project {
  background-color: var(--color-section-alt);
  border-radius: var(--border-radius-sm);
  padding: var(--space-sm);
  margin: var(--space-md) 0;
}

#lecturing .lecturing-project:nth-of-type(even) {
  background-color: var(--color-section-alt-strong);
}

#lecturing h5 {
  margin-top: var(--space-sm);
}

#lecturing h5 + h6,
#lecturing h5 + p {
  margin-top: var(--space-xs);
  margin-bottom: var(--space-md);
}




/* =============================================================================
   SECTION-SPECIFIC, #work
   ============================================================================= */

#work p:not(.project-context) a.visit-link {
  display: block;
  margin-top: var(--space-xs);
}

#work .work-project {
  background-color: var(--color-bg);
  border-radius: var(--border-radius-sm);
  padding: var(--space-sm);
  margin: var(--space-md) 0;
}

#work .work-project:nth-of-type(even) {
  background-color: var(--color-section-alt);
}


/* =============================================================================
   SECTION-SPECIFIC, #research
   ============================================================================= */

#research p a.cta-link {
  display: block;
  margin-top: var(--space-xs);
}

#research .research-project {
  background-color: var(--color-section-alt);
  border-radius: var(--border-radius-sm);
  padding: var(--space-sm);
  margin: var(--space-md) 0;
}

#research .research-project:nth-of-type(even) {
  background-color: var(--color-section-alt-strong);
}

#research h5 {
  margin-top: var(--space-sm);
}

#research h5 + p {
  margin-top: var(--space-xs);
  margin-bottom: var(--space-md);
}


/* =============================================================================
   SECTION-SPECIFIC, #speaker
   ============================================================================= */

#speaker > ul:not(.events-list) {
  column-count: 2;
  column-gap: var(--space-lg);
  column-fill: auto;
}

#speaker > ul:not(.events-list) li {
  break-inside: avoid;
}


/* =============================================================================
   SECTION-SPECIFIC, h5/h6 spacing shared across secondary sections
   ============================================================================= */

#lecturing h5,
#research h5,
#work h5,
#speaker h5,
#publications h5,
#about h5,
#contact h5 {
  margin-top: var(--space-micro);
  margin-bottom: var(--space-xs);
}

#lecturing h6,
#research h6,
#work h6,
#speaker h6,
#publications h6,
#about h6,
#contact h6 {
  margin-top: var(--space-xs);
  margin-bottom: var(--space-sm);
}


/* =============================================================================
   NAVIGATION
   ============================================================================= */

.nav {
  position: relative;
}

.nav-sections {
  position: fixed;
  top: var(--space-xxl);
  right: max(var(--space-lg), calc((100vw - var(--container-max-width)) / 2 + var(--space-lg)));
  list-style: none;
  margin: var(--space-sm) 0 0 0;
  padding: 0;
  z-index: 9998;
}

.nav-sections li {
  margin: var(--space-px) 0;
  text-align: right;
}

.nav-sections a {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  color: var(--color-text);
  padding: var(--space-8px) var(--space-12px);
  display: block;
  /* transition: all avoided — only animate the properties that change on :hover */
  transition: background-color var(--duration-200) ease-in-out,
              color var(--duration-200) ease-in-out;
}

@media (hover: hover) and (pointer: fine) {
  .nav-sections a:hover {
    background-color: var(--color-text);
    color: var(--color-bg);
  }
}

.nav-sections a.active {
  background-color: var(--color-text);
  color: var(--color-bg);
  text-decoration: none;
}

/* Close button, mobile only, hidden by default */
.nav-close {
  position: absolute;
  top: calc(var(--space-micro) * var(--phi));
  right: calc(var(--space-micro) * var(--phi));
  background: none;
  border: none;
  font-size: var(--fs-large);
  color: var(--color-text);
  cursor: pointer;
  padding: var(--space-micro) calc(var(--space-micro) * var(--phi));
  border-radius: 0;
  line-height: var(--lh-tight);
  transition: color var(--duration-200) ease-in-out, background-color var(--duration-200) ease-in-out;
  display: none;
  z-index: 9999;
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
}

.nav-close:hover {
  color: var(--color-bg);
  background-color: var(--color-text);
}

.nav-close:focus {
  outline: var(--border-width-2) solid var(--color-action);
  outline-offset: var(--border-width-2);
}


/* =============================================================================
   RESPONSIVE, ≤ 64 rem (tablet)
   ============================================================================= */

@media (max-width: 64rem) {
  /* NOTE: grid-template-columns only applies to grid containers. The selectors
     below target .events-list and .pub-list which are display:grid in their
     base rules. #speaker > ul:not(.events-list) uses CSS columns (column-count),
     not grid — applying grid-template-columns to it has no effect. It is set to
     display:grid here so the single-column override actually works on mobile. */
  #speaker > ul:not(.events-list) {
    display: grid;
    grid-template-columns: 1fr;
  }

  /* pub-list: collapse to single column on tablet.
     Previously declared twice in this block; merged into one rule. */
  .events-list,
  .pub-list {
    grid-template-columns: 1fr;
    gap: var(--space-tiny);
  }

  /* Hide the third CTA ("Read the research") on tablet — too cramped */
  #intro .cta-group a:nth-child(3) {
    display: none;
  }
}


/* =============================================================================
   RESPONSIVE, ≤ 40 rem
   ============================================================================= */

@media (max-width: 40rem) {
  #intro .intro-identity {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-xs);
  }

  .cta-group {
    display: none;
  }

  .theme-toggle {
    display: none;
  }
}


/* =============================================================================
   RESPONSIVE, ≤ 768 px (mobile)
   ============================================================================= */

/* ≤ 48 rem (768 px equivalent in rem units)
   NOTE: all other breakpoints in this file use rem, not px. Using rem here
   keeps breakpoints consistent and ensures they scale correctly when the user
   changes their browser default font size (px breakpoints do not scale). */
@media (max-width: 48rem) {
  /* NOTE: figcaption column-count removed — figcaptions are never set as
     multi-column elements in wider breakpoints, so the reset was a no-op. */

  .horizontal-card-compact {
    flex-direction: column;
    gap: var(--space-xs);
  }

  .horizontal-card-compact .card-meta {
    text-align: left;
    min-width: auto;
  }

  .horizontal-card-compact h6 {
    margin-bottom: var(--space-micro);
  }

  .horizontal-card-compact p {
    column-count: 1;
    column-gap: normal;
  }
}


/* =============================================================================
   RESPONSIVE, ≤ 30 rem (small mobile)
   ============================================================================= */

@media (max-width: 30rem) {
  :root {
    --base-unit: 0.85rem;
  }

  /* Body & shell */
  body {
    padding: var(--space-xs);
    /* NOTE: font-size was incorrectly set to --fs-xl (≈ 42px) here —
       same error as the main body rule corrected earlier. --fs-base keeps
       text legible at small viewport widths without overwhelming the layout. */
    font-size: var(--fs-base);
  }

  header,
  footer {
    padding: var(--space-xs);
  }

  header a {
    font-size: var(--fs-plus);
  }

  .header-links ul {
    gap: 0; /* separators already handled by li::after */
  }

  main {
    margin-top: var(--space-lg);
    margin-bottom: var(--space-sm);
  }

  /* Grid */
  .container {
    gap: var(--space-micro);
    padding: var(--space-xs) 0;
  }

  /* Sections */
  section {
    margin-top: 0;
    margin-bottom: 0;
    padding: var(--space-sm) 0 var(--space-sm) 0;
  }

  section::after {
    left: 0;
    width: 100%;
  }

  section:last-of-type {
    padding-bottom: var(--space-lg);
  }

  /* Headings */
  h1 {
    font-size: var(--fs-xl);
    margin-top: var(--space-lg);
    margin-bottom: var(--space-sm);
  }

  h2 {
    font-size: var(--fs-xl);
    margin-top: var(--space-md);
    margin-bottom: var(--space-xs);
  }

  h3,
  h4 {
    font-size: var(--fs-large);
    margin-top: var(--space-sm);
    margin-bottom: var(--space-xs);
  }

  h5 {
    line-height: var(--lh-snug);
    font-size: var(--fs-plus);
    font-weight: var(--fw-medium);
    margin-top: var(--space-xs);
    margin-bottom: var(--space-tiny);
  }

  h6 {
    font-size: var(--fs-medium);
    font-weight: var(--fw-normal);
    margin-top: var(--space-xs);
    margin-bottom: var(--space-tiny);
  }

  /* Body text */
  p,
  ul,
  ol,
  blockquote {
    font-size: var(--fs-plus);
    font-weight: var(--fw-normal);
    margin-top: var(--space-tiny);
    margin-bottom: var(--space-xs);
  }

  li {
    margin-top: var(--space-micro);
    margin-bottom: var(--space-micro);
  }

  li strong {
    font-weight: var(--fw-semibold);
  }

  small {
    margin-top: var(--space-micro);
    margin-bottom: var(--space-micro);
  }

  footer p {
    margin-top: var(--space-tiny);
    margin-bottom: var(--space-tiny);
  }

  /* Media */
  figure {
    margin-top: var(--space-sm);
    margin-bottom: var(--space-sm);
  }

  figcaption {
    font-size: var(--fs-base);
    margin-top: var(--space-micro);
    margin-bottom: var(--space-micro);
    letter-spacing: var(--ls-normal);
    line-height: var(--lh-normal);
    column-count: 1;
    column-gap: normal;
  }

  figcaption.quote {
    margin-top: var(--space-micro);
    margin-bottom: var(--space-tiny);
  }

  /* Dividers */
  hr {
    margin-top: var(--space-sm);
    margin-bottom: var(--space-sm);
    height: var(--border-width-1);
  }

  /* Callouts */
  .quote {
    margin-top: var(--space-tiny);
    margin-bottom: var(--space-xs);
  }

  .project-context {
    font-size: var(--fs-base);
  }

  .research-note {
    font-size: var(--fs-base);
    margin-top: var(--space-sm);
    padding-left: var(--space-sm);
    border-left-width: var(--border-width-1);
  }

  .editorial-note {
    font-size: var(--fs-base);
    margin-top: var(--space-sm);
    padding-left: var(--space-sm);
  }

  ul.editorial-note {
    font-size: var(--fs-demi);
    line-height: var(--lh-tiny);
  }

  .social-proof {
    font-size: var(--fs-plus);
    line-height: var(--lh-relaxed);
    margin-top: var(--space-sm);
    margin-bottom: var(--space-sm);
    padding-top: var(--space-tiny);
    padding-bottom: var(--space-tiny);
  }

  #work .work-project {
    padding: var(--space-xs);
  }

  #research .research-project {
    padding: var(--space-xs);
  }

  /* Buttons & CTAs */
  button,
  .button {
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--fs-base);
    letter-spacing: var(--ls-normal);
    line-height: var(--lh-normal);
  }

  .cta {
    width: 100%;
    text-align: center;
    font-size: var(--fs-plus);
    font-weight: var(--fw-medium);
  }

  #intro .cta-group {
    display: none;
  }

  /* Tables */
  .design-case-table-wrapper {
    margin: 0 calc(var(--space-xs) * -1) var(--space-md) calc(var(--space-xs) * -1);
    padding: 0 var(--space-xs);
    overflow-x: auto;
  }

  .design-case-table th,
  .design-case-table td {
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--fs-base);
    line-height: var(--lh-normal);
    letter-spacing: var(--ls-normal);
    white-space: normal;
    overflow-wrap: break-word;
  }

  .design-case-table th {
    letter-spacing: var(--ls-wide);
    font-weight: var(--fw-semibold);
  }

  /* Hide work summary table on small mobile, with negative-margin bleed reset */
  .work-summary-table-wrapper {
    margin: 0 calc(var(--space-xs) * -1) var(--space-md) calc(var(--space-xs) * -1);
    padding: 0 var(--space-xs);
    overflow-x: auto;
    display: none;
  }

  .work-summary-table th,
  .work-summary-table td {
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--fs-base);
    line-height: var(--lh-normal);
    letter-spacing: var(--ls-normal);
    white-space: normal;
    overflow-wrap: break-word;
  }

  .work-summary-table th {
    letter-spacing: var(--ls-wide);
  }

  /* Scroll container */
  .scroll-container {
    padding-right: var(--space-xs);
    gap: var(--space-micro);
  }

  /* Hint */
  .hint small {
    margin-top: var(--space-micro);
    margin-bottom: var(--space-micro);
  }

  /* Events list */
  .events-list {
    max-width: 100%;
    column-count: 1;
    column-gap: normal;
  }

  .events-list li {
    margin-top: var(--space-micro);
    margin-bottom: var(--space-xs);
  }

  .events-list strong {
    font-size: var(--fs-medium);
  }

  .events-list time {
    font-size: var(--fs-base);
  }

  /* Horizontal compact cards */
  #lecturing .horizontal-cards-compact {
    gap: var(--space-xs);
    margin-top: var(--space-md);
    margin-bottom: var(--space-lg);
  }

  #lecturing .horizontal-card-compact {
    padding: var(--space-xs);
    gap: var(--space-xs);
  }

  #lecturing .horizontal-card-compact h5 {
    margin-bottom: var(--space-micro);
    margin-top: var(--space-micro);
  }

  #lecturing .horizontal-card-compact h6 {
    margin-bottom: var(--space-micro);
  }

  #lecturing .horizontal-card-compact p {
    margin-top: var(--space-tiny);
    column-count: 1;
    column-gap: normal;
  }

  /* Section-specific, #intro */
  #intro {
    margin-top: 0;
  }

  #intro figure:first-of-type img {
    margin-top: var(--space-xl);
  }

  #intro h2:first-of-type {
    margin-top: var(--space-tiny);
  }

  #intro h5 {
    line-height: var(--lh-snug);
    font-size: var(--fs-plus);
    font-weight: var(--fw-medium);
  }

  /* Section-specific, #about */
  #about .highlight-inline {
    font-size: var(--fs-large);
    padding: var(--space-xs) var(--space-sm);
  }

  /* Section-specific, #contact */
  #contact a {
    font-size: var(--fs-plus);
    font-weight: var(--fw-medium);
  }

  /* Navigation, full-screen overlay */
  .nav-sections {
    margin: var(--space-micro) 0 0 0;
    position: fixed;
    top: 0;
    right: 0;
    transition: opacity var(--duration-300) ease-in-out, transform var(--duration-300) ease-in-out;
    will-change: opacity, transform;
    /* NOTE: 100dvh instead of 100% accounts for the dynamic browser chrome on iOS
       (address bar expanding/collapsing). With 100%, the bottom of the overlay can
       slip behind the Safari toolbar. 100dvh tracks the visible viewport height. */
    height: 100dvh;
    background-color: var(--color-bg);
    padding-top: calc(var(--space-xs) * var(--phi-squared));
  }

  .nav-sections li:first-of-type {
    margin-top: var(--space-sm);
  }

  .nav-sections a {
    /* NOTE: the original value was calc(var(--space-micro) * 1.5).
       --space-xs (= --space-micro × phi ≈ 1.618×) is the closest available token
       and produces a slightly larger tap target, which is acceptable on mobile. */
    padding: var(--space-xs) var(--space-xs);
    font-weight: var(--fw-bold);
    background-color: transparent;
    margin-bottom: var(--space-px);
  }

  .nav-sections a.active {
    background-color: var(--color-text);
    color: var(--color-bg);
  }

  /* No hover on touch, prevents iOS sticky-hover ghost */
  .nav-sections a:hover {
    background-color: transparent;
    color: var(--color-text);
  }

  .nav-sections a.active:hover {
    opacity: 1;
    background-color: var(--color-text);
    color: var(--color-bg);
  }

  .nav-sections a:active {
    background-color: var(--color-text);
    color: var(--color-bg);
    transition: none;
  }

  .nav-close {
    display: block;
    /* Switch from absolute (relative to .nav in document flow) to fixed so the
       button stays anchored to the viewport top-right corner when the user scrolls
       inside the full-screen nav overlay. top/right mirror the base rule values. */
    position: fixed;
    top: calc(var(--space-micro) * var(--phi));
    right: calc(var(--space-micro) * var(--phi));
  }

  /* Hide close button when nav is collapsed.
     NOTE: .nav-close is now a sibling of .nav-sections (not a child),
     so we use the adjacent sibling combinator or target the nav wrapper. */
  nav:has(.nav-sections.nav-hidden) .nav-close {
    display: none;
  }
}
/* ─── ENGAGEMENT AREAS (Connect section) ────────────────────────────────────
   Two-column grid layout. Each li is a cell with title + description.
   The grid uses a 1px gap rendered via border on cells rather than
   CSS gap, so the dividing lines align precisely with the outer border. */
 
.engagement-areas {
  margin: var(--space-md) 0;
}
 
.engagement-areas h3 {
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text);
  opacity: 0.5;
  margin: 0 0 var(--space-sm) 0;
}
 
.engagement-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1px solid var(--color-border, var(--color-text));
  overflow: hidden;
}
 
.engagement-list li,
.engagement-list > li {
  padding: var(--space-sm) var(--space-md);
  background-color: transparent;
  margin-bottom: 0;
  font-weight: var(--fw-normal);
  border-bottom: 1px solid var(--color-border, var(--color-section-alt));
  border-right: 1px solid var(--color-border, var(--color-section-alt));
  line-height: 1.5;
}
 
/* Remove right border on even cells (right column) */
.engagement-list li:nth-child(even),
.engagement-list > li:nth-child(even) {
  border-right: none;
}
 
/* Remove bottom border on last two cells */
.engagement-list li:nth-last-child(-n+2),
.engagement-list > li:nth-last-child(-n+2) {
  border-bottom: none;
}
 
.engagement-list li strong {
  display: block;
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 4px;
}
 
.engagement-list li span {
  font-size: var(--fs-note);
  color: var(--color-text);
  opacity: 0.65;
  line-height: 1.5;
}
 
@media (max-width: 48rem) {
  .engagement-list {
    grid-template-columns: 1fr;
  }
 
  .engagement-list li:nth-child(even),
  .engagement-list > li:nth-child(even) {
    border-right: none;
  }
 
  .engagement-list li:nth-last-child(-n+2),
  .engagement-list > li:nth-last-child(-n+2) {
    border-bottom: 1px solid var(--color-border, rgba(0,0,0,0.12));
  }
 
  .engagement-list li:last-child,
  .engagement-list > li:last-child {
    border-bottom: none;
  }
}
 
/* EOF */