/* ==========================================================================
   Seam Saif — portfolio and CV
   Design tokens, layout and components. Dark and light themes share every
   rule; only the custom properties below change.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
  --font-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --container: 1160px;
  --gutter: clamp(16px, 4vw, 32px);
  --header-h: 64px;
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 18px;
  --ease: cubic-bezier(.2, .7, .2, 1);

  /* dark theme (default) */
  color-scheme: dark;
  --bg: #070d18;
  --bg-glow: rgba(56, 189, 248, .07);
  --header-bg: rgba(7, 13, 24, .66);
  --surface: rgba(13, 21, 37, .6);
  --surface-solid: #0d1525;
  --surface-2: rgba(20, 31, 52, .55);
  --surface-3: rgba(26, 38, 62, .62);
  --border: #1c2940;
  --border-strong: #2a3a5a;
  --text: #e6ecf5;
  --text-2: #b3bfd2;
  --muted: #8392ab;
  --accent: #38bdf8;
  --accent-strong: #7dd3fc;
  --accent-ink: #03121d;
  --accent-soft: rgba(56, 189, 248, .12);
  --accent-rgb: 56, 189, 248;
  --copper-rgb: 227, 167, 92;
  --copper: #e3a75c;
  --copper-soft: rgba(227, 167, 92, .13);
  --copper-glow: rgba(227, 167, 92, .55);     /* the chip's LED */
  --accent-ring: rgba(56, 189, 248, .5);      /* the timeline nodes' ripple */
  --ok: #34d399;
  --ok-soft: rgba(52, 211, 153, .12);
  --warn: #fbbf24;
  --warn-soft: rgba(251, 191, 36, .12);
  --info: #60a5fa;
  --info-soft: rgba(96, 165, 250, .13);
  --danger: #f87171;
  --danger-soft: rgba(248, 113, 113, .12);
  --input-bg: rgba(7, 13, 24, .55);
  --pin: #7d8ea8;
  --edge-lit: #34476c;     /* side walls of the 3D profile chip: lit, */
  --edge-shade: #111a2c;   /* in shadow, */
  --edge-mid: #1d2a42;     /* between (older browsers) */
  --edge-line: #2a3a5a;    /* and their back outline */
  --back-line: rgba(140, 175, 230, .55);   /* the back of the glass, seen through it */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
  --shadow: 0 18px 40px -22px rgba(0, 0, 0, .75);
  --backdrop: rgba(2, 6, 13, .74);

  /* circuit background (read by circuit-bg.js) */
  --trace: rgba(120, 150, 195, .13);
  --trace-node: rgba(140, 170, 215, .26);
  --signal: #38bdf8;
  --signal-alt: #e3a75c;
  --signal-red: #ff8a8a;
  --signal-green: #7ee2a8;
}

/* light theme: chosen with the header button (the site opens in dark) */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f6fa;
  --bg-glow: rgba(3, 105, 161, .06);
  --header-bg: rgba(244, 246, 250, .72);
  --surface: rgba(255, 255, 255, .58);
  --surface-solid: #ffffff;
  --surface-2: rgba(255, 255, 255, .55);
  --surface-3: rgba(226, 232, 242, .6);
  --border: #dde3ec;
  --border-strong: #c3cddc;
  --text: #0c1424;
  --text-2: #344256;
  --muted: #5a6a80;
  --accent: #0369a1;
  --accent-strong: #075985;
  --accent-ink: #ffffff;
  --accent-soft: rgba(3, 105, 161, .08);
  --accent-rgb: 3, 105, 161;
  --copper-rgb: 154, 91, 22;
  --copper: #9a5b16;
  --copper-soft: rgba(154, 91, 22, .1);
  --copper-glow: rgba(154, 91, 22, .45);
  --accent-ring: rgba(3, 105, 161, .45);
  --ok: #047857;
  --ok-soft: rgba(4, 120, 87, .09);
  --warn: #8a5a00;
  --warn-soft: rgba(161, 98, 7, .1);
  --info: #1d4ed8;
  --info-soft: rgba(29, 78, 216, .08);
  --danger: #b91c1c;
  --danger-soft: rgba(185, 28, 28, .08);
  --input-bg: rgba(255, 255, 255, .72);
  --pin: #9aa8bc;
  --edge-lit: #ffffff;
  --edge-shade: #b9c4d5;
  --edge-mid: #dfe5ee;
  --edge-line: #c3cddc;
  --back-line: rgba(40, 60, 95, .3);
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, .06);
  --shadow: 0 18px 40px -24px rgba(15, 23, 42, .28);
  --backdrop: rgba(15, 23, 42, .55);

  --trace: rgba(40, 60, 95, .085);
  --trace-node: rgba(40, 60, 95, .17);
  --signal: #0284c7;
  --signal-alt: #c2410c;
  --signal-red: #e5484d;
  --signal-green: #1f9d55;
}


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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

html.modal-open { overflow: hidden; }

/* The soft glow at the top right stays in place while the page scrolls. It is
   a fixed layer the graphics card keeps ready, not a fixed background, which
   browsers (Safari especially) would repaint on every scroll step. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background: radial-gradient(1100px 560px at 85% -8%, var(--bg-glow), transparent 65%);
}

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

h1, h2, h3, h4 { margin: 0; line-height: 1.2; font-weight: 600; letter-spacing: -.01em; color: var(--text); }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; }
strong { font-weight: 600; color: var(--text); }
em { font-style: italic; }
time { font-variant-numeric: tabular-nums; }

a {
  color: var(--accent);
  text-decoration: none;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
a:hover { color: var(--accent-strong); text-decoration: underline; }

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

::selection { background: var(--accent); color: var(--accent-ink); }

button,
input,
textarea,
select { font: inherit; color: inherit; }
button { cursor: pointer; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

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

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  transform: translateY(-160%);
}
.skip-link:focus { transform: none; color: var(--accent-ink); text-decoration: none; }

.container {
  width: 100%;
  max-width: calc(var(--container) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.mono { font-family: var(--font-mono); font-size: .92em; }

/* ---------- Circuit background ---------- */
.circuit-bg {
  position: fixed;
  inset: 0 0 auto 0;
  height: 100vh;
  height: 100lvh;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
/* the moving pulses are drawn on their own layer above the still board, so
   animating them never redraws the board underneath */
.circuit-pulses { will-change: transform; }
.circuit-svg {
  position: absolute;
  top: 0;
  left: 0;
  max-width: none;   /* keeps its own size, so zooming in shows the board larger */
}
.cb-trace { fill: none; stroke: var(--trace); stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }
.cb-via { fill: var(--bg); stroke: var(--trace-node); stroke-width: 1.7; }
.cb-tail { fill: none; stroke-width: 1.6; stroke-linecap: butt; stroke-linejoin: round; }
.cb-main .cb-tail { stroke: var(--signal); }
.cb-alt .cb-tail { stroke: var(--signal-alt); }
.cb-red .cb-tail { stroke: var(--signal-red); }
.cb-green .cb-tail { stroke: var(--signal-green); }
.cb-glow-main stop { stop-color: var(--signal); }
.cb-glow-alt stop { stop-color: var(--signal-alt); }
.cb-glow-red stop { stop-color: var(--signal-red); }
.cb-glow-green stop { stop-color: var(--signal-green); }
:root[data-motion="off"] .cb-pulses { display: none; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  min-height: 44px;
  padding: .62em 1.15em;
  border: 1px solid transparent;
  border-radius: 10px;
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.btn:hover { text-decoration: none; }

.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: var(--accent-strong); color: var(--accent-ink); }

.btn-secondary { background: var(--surface-2); border-color: var(--border-strong); color: var(--text); }
.btn-secondary:hover { border-color: var(--accent); color: var(--text); }

.btn-ghost { background: transparent; color: var(--accent); border-color: transparent; }
.btn-ghost:hover { background: var(--accent-soft); color: var(--accent-strong); }

.btn-sm { min-height: 38px; padding: .45em .9em; font-size: .88rem; border-radius: 9px; }

.btn[disabled],
.btn[aria-busy="true"] { opacity: .65; cursor: progress; }

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--text-2);
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.icon-btn:hover { border-color: var(--accent); color: var(--text); }
.icon-btn .icon { width: 19px; height: 19px; }

/* ---------- Header and navigation ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--header-bg);
  border-bottom: 1px solid transparent;
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
  transition: border-color .2s var(--ease);
}
.site-header.is-scrolled { border-bottom-color: var(--border); }

.header-inner {
  display: flex;
  align-items: center;
  gap: 16px;
  height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-weight: 600;
  letter-spacing: -.01em;
}
.brand:hover { color: var(--text); text-decoration: none; }

.brand-mark {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1.5px solid var(--accent);
  border-radius: 7px;
  background: var(--surface-2);
  color: var(--text);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .02em;
}
/* the photo fills the logo chip, inside its outline and pins */
.brand-photo {
  width: 100%;
  height: 100%;
  border-radius: 5.5px;
  object-fit: cover;
}
/* three pins on each side of the logo chip */
.brand-mark::before,
.brand-mark::after {
  content: "";
  position: absolute;
  top: 7px;
  bottom: 7px;
  width: 4px;
  background: repeating-linear-gradient(to bottom, var(--accent) 0 2.5px, transparent 2.5px 7px);
}
.brand-mark::before { left: -5.5px; }
.brand-mark::after { right: -5.5px; }

.site-nav { margin-left: auto; }
.nav-list {
  display: flex;
  align-items: center;
  gap: 2px;
  list-style: none;
}
.nav-link {
  position: relative;
  display: block;
  padding: 8px 11px;
  border-radius: 8px;
  color: var(--text-2);
  font-size: .93rem;
  font-weight: 500;
}
.nav-link:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
.nav-link[aria-current="true"] { color: var(--text); }
.nav-link[aria-current="true"]::after {
  content: "";
  position: absolute;
  left: 11px;
  right: 11px;
  bottom: 3px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}
.nav-cv { display: none; }

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.page-header-actions { margin-left: auto; }
.nav-toggle { display: none; }

/* theme and motion toggle icons */
.theme-toggle .icon-moon,
:root[data-theme="light"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: block; }

.motion-toggle .icon-off,
:root[data-motion="off"] .motion-toggle .icon-on { display: none; }
:root[data-motion="off"] .motion-toggle .icon-off { display: block; }

@media (max-width: 1079px) {
  .nav-toggle { display: inline-grid; }
  .header-cv { display: none; }
  .header-actions { margin-left: auto; }
  .site-nav {
    position: absolute;
    top: var(--header-h);
    left: 0;
    right: 0;
    display: none;
    padding: 12px var(--gutter) 20px;
    background: var(--surface-solid);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow);
  }
  .site-nav.is-open { display: block; }
  .nav-list { flex-direction: column; align-items: stretch; gap: 2px; }
  .nav-link { padding: 12px 12px; font-size: 1rem; }
  .nav-link[aria-current="true"] { background: var(--accent-soft); }
  .nav-link[aria-current="true"]::after { display: none; }
  .nav-cv { display: flex; width: 100%; margin-top: 12px; }
}

/* ---------- Sections ---------- */
main { position: relative; }

.section { padding-block: clamp(64px, 9vw, 112px); }
.section + .section { padding-top: clamp(24px, 4vw, 48px); }

.section-head { margin-bottom: clamp(28px, 4vw, 44px); max-width: 760px; }

.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.eyebrow-index { color: var(--muted); }
/* a short trace ending in a via */
.eyebrow::after {
  content: "";
  width: 64px;
  height: 9px;
  background:
    radial-gradient(circle, var(--accent-strong) 0 1.6px, transparent 2.6px) -9px 50% / 9px 9px no-repeat,
    radial-gradient(circle at calc(100% - 4.5px) 50%, transparent 0 2px, var(--accent) 2.5px 4px, transparent 4.5px),
    linear-gradient(var(--accent), var(--accent)) left center / calc(100% - 9px) 1px no-repeat;
  opacity: .8;
}

.section-title { font-size: clamp(1.75rem, 1.25rem + 2vw, 2.4rem); }
.section-intro { margin-top: 12px; color: var(--text-2); font-size: 1.04rem; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(18px, 2.4vw, 26px);
  box-shadow: var(--shadow-sm);
}

.lead { font-size: 1.12rem; color: var(--text-2); }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: .76rem;
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-warn { color: var(--warn); background: var(--warn-soft); }
.badge-ok { color: var(--ok); background: var(--ok-soft); }
.badge-info { color: var(--info); background: var(--info-soft); }

.tag {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 6px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-2);
  font-size: .8rem;
}
.tag-accent { color: var(--accent); border-color: transparent; background: var(--accent-soft); font-weight: 600; }

.cite {
  font-family: var(--font-mono);
  font-size: .86em;
  font-weight: 500;
  white-space: nowrap;
}

/* ---------- Hero ---------- */
.hero { padding-top: clamp(40px, 8vh, 96px); padding-bottom: clamp(48px, 7vw, 80px); overflow-x: clip; }

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, .9fr);
  align-items: center;
  gap: clamp(32px, 6vw, 72px);
}


.hero-title {
  font-size: clamp(2.8rem, 1.9rem + 4.4vw, 4.6rem);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.04;
}
.hero-role {
  margin-top: 12px;
  font-size: clamp(1.2rem, 1rem + 1vw, 1.55rem);
  font-weight: 500;
  color: var(--accent);
}
.hero-tagline {
  margin-top: 6px;
  color: var(--copper);
  font-family: var(--font-mono);
  font-size: .95rem;
}
.hero-lead {
  max-width: 60ch;
  margin-top: 20px;
  color: var(--text-2);
  font-size: 1.08rem;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

.social-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 26px;
  list-style: none;
}
.social-link {
  display: inline-grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text-2);
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.social-link:hover { border-color: var(--accent); color: var(--text); }
.social-link .icon { width: 19px; height: 19px; }

/* The profile "chip": a 3D IC package of thick glass, with pins, holding a
   small datasheet, seen from slightly above and to the right. The face (.chip)
   keeps its translucent glass look, and the notch is a real cut-out (CSS
   mask), so the circuit board shows through. The package's side walls are
   real 3D surfaces: four straight walls and narrow strips that follow the
   rounded corners and the inside of the notch. Walls that face the viewer
   (the top, the right side, the notch's inner wall) are shaded by how much
   they face a light at the top left. A wall that faces away is seen through
   the glass instead, as just its back edge. Every pin leaves the side at half
   the package's thickness, then bends down like a DIP leg. The package rests
   tilted slightly towards the viewer, sways slowly while animations are on
   and leans towards the mouse, or with the phone (main.js). */

.hero-chip {
  display: flex;
  justify-content: center;
  padding-inline: 14px;
  perspective: 1300px;
  perspective-origin: 50% 10%;   /* the eye level is near the top: the chip is seen from slightly above */
}
.chip-package {
  --depth: 24px;                 /* thickness of the package */
  --notch-r: 22.5px;             /* radius of the notch: the inner edge of its outline */
  --r: 18px;                     /* corner radius, as --radius-lg */
  --rest-x: -8deg;               /* top tilted towards the viewer */
  --rest-y: -10deg;              /* right side turned towards the viewer */
  position: relative;
  width: 100%;
  transform-style: preserve-3d;
  /* turn first round the vertical axis, so the text rows stay level */
  transform: rotateY(var(--rest-y)) rotateX(var(--rest-x));
}
/* The chip's movement is carried by two outer layers, each turned by a plain
   transform, which the graphics card animates by itself (smooth at the
   screen's full refresh rate, on Safari, Chrome, Edge and Firefox alike):
   .chip-sway turns slowly back and forth while animations are on;
   .chip-tilt leans towards the mouse or with the phone (main.js sets it). */
.chip-sway,
.chip-tilt {
  transform-style: preserve-3d;
  will-change: transform;
}
.chip-sway { width: min(100%, 310px); }
.chip-tilt { transition: transform .6s var(--ease); }
/* following a phone's tilt: main.js already smooths it, so no extra delay */
.chip-tilt.is-phone-tilt { transition: none; }
/* side walls; --phi is the direction a wall faces (0deg right, 90deg down) */
.chip-edge {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  pointer-events: none;
}
.chip-edge b {
  position: absolute;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
}
.chip-edge i {
  position: absolute;
  display: block;
  transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  background: var(--edge-mid);
}
@supports (width: calc(1px * cos(0deg))) {
  .chip-edge i {
    --shade: calc(.5 + .5 * cos(var(--phi) - 225deg));   /* 1 facing the light, 0 facing away */
    background: color-mix(in srgb, var(--edge-lit) calc(var(--shade) * 100%), var(--edge-shade));
  }
}
/* the inside of each wall: turned to face the other way, so it is drawn
   exactly when the wall itself is not, i.e. when it is seen through the glass.
   Only its back edge shows. On the curved strips it is trimmed to the exact
   15-degree arc, so the lines of neighbouring strips meet without overlapping. */
.chip-edge i::before {
  content: "";
  position: absolute;
  inset: 0;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  transform: rotateY(180deg);
}
.e-arc:not(.e-notch) i::before { inset: calc(var(--r) * .0145) 0; }
.e-notch i::before { inset: calc(var(--notch-r) * .0145) 0; }
/* its back edge (left and right swap sides when the inside is turned round) */
.e-right::before,
.e-arc:not(.e-notch) i::before { border-left: 1px solid var(--back-line); }
.e-left::before,
.e-notch i::before { border-right: 1px solid var(--back-line); }
.e-top::before { border-top: 1px solid var(--back-line); }
.e-bottom::before { border-bottom: 1px solid var(--back-line); }
/* straight walls, hinged on the face's outline and folded back by --depth */
.e-top {
  --phi: 270deg;
  bottom: 100%;
  height: var(--depth);
  border-top: 1px solid var(--edge-line);
  transform-origin: 50% 100%;
  transform: rotateX(90deg);
}
.e-top-l { left: var(--r); right: calc(50% + var(--notch-r)); }
.e-top-r { left: calc(50% + var(--notch-r)); right: var(--r); }
.e-right {
  --phi: 0deg;
  left: 100%;
  top: var(--r);
  bottom: var(--r);
  width: var(--depth);
  border-right: 1px solid var(--edge-line);
  transform-origin: 0 50%;
  transform: rotateY(90deg);
}
.e-bottom {
  --phi: 90deg;
  top: 100%;
  left: var(--r);
  right: var(--r);
  height: var(--depth);
  border-bottom: 1px solid var(--edge-line);
  transform-origin: 50% 0;
  transform: rotateX(-90deg);
}
.e-left {
  --phi: 180deg;
  right: 100%;
  top: var(--r);
  bottom: var(--r);
  width: var(--depth);
  border-left: 1px solid var(--edge-line);
  transform-origin: 100% 50%;
  transform: rotateY(-90deg);
}
/* curved walls: 15-degree strips set around the centre of each corner and
   of the notch (each <b> is that centre point) */
.e-tl { left: var(--r); top: var(--r); --base: 180deg; }
.e-tr { left: calc(100% - var(--r)); top: var(--r); --base: 270deg; }
.e-br { left: calc(100% - var(--r)); top: calc(100% - var(--r)); --base: 0deg; }
.e-bl { left: var(--r); top: calc(100% - var(--r)); --base: 90deg; }
.e-notch { left: 50%; top: 0; }
.e-arc i:nth-child(1) { --k: 7.5deg; }
.e-arc i:nth-child(2) { --k: 22.5deg; }
.e-arc i:nth-child(3) { --k: 37.5deg; }
.e-arc i:nth-child(4) { --k: 52.5deg; }
.e-arc i:nth-child(5) { --k: 67.5deg; }
.e-arc i:nth-child(6) { --k: 82.5deg; }
.e-arc i:nth-child(7) { --k: 97.5deg; }
.e-arc i:nth-child(8) { --k: 112.5deg; }
.e-arc i:nth-child(9) { --k: 127.5deg; }
.e-arc i:nth-child(10) { --k: 142.5deg; }
.e-arc i:nth-child(11) { --k: 157.5deg; }
.e-arc i:nth-child(12) { --k: 172.5deg; }
/* corners bulge outwards: each strip faces away from the corner's centre
   (.9914 = cos 7.5deg puts the strip on the arc, .29 is its width with a
   little overlap so no seam shows) */
.e-arc:not(.e-notch) i {
  --phi: calc(var(--base) + var(--k));
  left: 0;
  top: calc(var(--r) * -.145);
  width: var(--depth);
  height: calc(var(--r) * .29);
  border-right: 1px solid var(--edge-line);
  transform-origin: 0 50%;
  transform: rotate(var(--phi)) translateX(calc(var(--r) * .9914)) rotateY(90deg);
}
/* the notch is hollow: its strips face in, towards the notch's centre, so
   from above its inner wall shows as the curved side of the cut */
.e-notch i {
  --phi: calc(var(--k) + 180deg);
  left: calc(var(--depth) * -1);
  top: calc(var(--notch-r) * -.145);
  width: var(--depth);
  height: calc(var(--notch-r) * .29);
  border-left: 1px solid var(--edge-line);
  transform-origin: 100% 50%;
  transform: rotate(var(--k)) translateX(calc(var(--notch-r) * .9914)) rotateY(-90deg);
}
.chip {
  position: relative;
  padding: 30px 26px 20px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, var(--surface-3), var(--surface) 60%);
  -webkit-mask: radial-gradient(circle at 50% 0, transparent 22.5px, #000 23.5px);
  mask: radial-gradient(circle at 50% 0, transparent 22.5px, #000 23.5px);
}
.chip-notch {
  position: absolute;
  top: -1px;
  left: 50%;
  width: 47px;
  height: 23.5px;
  transform: translateX(-50%);
  border: 1px solid var(--border-strong);
  border-top: 0;
  border-radius: 0 0 24px 24px;
}
/* pins: a bright band (the "signal") runs along them while animations are on */
.chip-pins,
.chip-legs {
  position: absolute;
  top: 40px;
  bottom: 40px;
  width: 13px;
  background: linear-gradient(to bottom, transparent 40%, var(--accent) 50%, transparent 60%) 0 0 / 100% 250% no-repeat, var(--pin);
  -webkit-mask: repeating-linear-gradient(to bottom, #000 0 7px, transparent 7px 27px);
  mask: repeating-linear-gradient(to bottom, #000 0 7px, transparent 7px 27px);
  opacity: .85;
}
.chip-pins-left { left: -14px; }
.chip-pins-right { right: -14px; }
.chip-pins { transform: translateZ(calc(var(--depth) / -2)); }
/* the legs: the outer end of each pin, bent down past the package */
.chip-legs { width: 20px; opacity: .6; }
.chip-legs-left {
  left: -14px;
  transform-origin: left center;
  transform: translateZ(calc(var(--depth) / -2)) rotateY(90deg);
}
.chip-legs-right {
  right: -14px;
  transform-origin: right center;
  transform: translateZ(calc(var(--depth) / -2)) rotateY(-90deg);
}
.chip-dot {
  position: absolute;
  top: 16px;
  left: 18px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--copper);
}

.chip-label {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-align: right;
}
.chip-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 14px 0 16px;
}
.chip-avatar {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 68px;
  height: 68px;
  border-radius: 50%;
  overflow: hidden;
  background: linear-gradient(135deg, var(--accent-soft), var(--copper-soft)), var(--surface-2);
  border: 1.5px solid var(--border-strong);
}
.chip-initials {
  color: var(--text);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: .02em;
}
.chip-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* the name has the whole space beside the photo */
.chip-name { font-size: 1.55rem; font-weight: 600; line-height: 1.15; letter-spacing: -.01em; }

.chip-specs { margin: 0; }
.chip-specs div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 9px 0;
  border-top: 1px dashed var(--border-strong);
}
.chip-specs dt {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.chip-specs dd {
  margin: 0;
  color: var(--text);
  font-size: .93rem;
  font-weight: 500;
  text-align: right;
}

.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin-top: clamp(40px, 6vw, 64px);
  list-style: none;
}
.stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.stat-value {
  font-size: 2rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.stat-label { color: var(--text-2); font-size: .9rem; line-height: 1.45; }
.stat-label span { display: block; color: var(--muted); font-size: .82rem; }

/* ---------- About ---------- */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(28px, 5vw, 56px);
  align-items: start;
}
.about-text { display: grid; gap: 16px; }
.about-text p:not(.lead) { color: var(--text-2); }

.focus-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  list-style: none;
}
.focus-card { display: grid; gap: 8px; align-content: start; }
.focus-card h3 { font-size: 1.02rem; }
.focus-card p { color: var(--text-2); font-size: .93rem; }
.icon-tile {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: var(--accent-soft);
  color: var(--accent);
}
.icon-tile .icon { width: 21px; height: 21px; }
.icon-tile-copper { background: var(--copper-soft); color: var(--copper); }

/* ---------- Education timeline ---------- */
.timeline {
  position: relative;
  display: grid;
  gap: 16px;
  list-style: none;
}
.timeline::before {
  content: "";
  position: absolute;
  top: 30px;
  bottom: 30px;
  left: 11px;
  width: 2px;
  background:
    linear-gradient(transparent, var(--accent), transparent) 0 -80px / 2px 80px no-repeat,
    linear-gradient(var(--accent), var(--border-strong) 70%);
  opacity: .55;
}
.timeline-item { position: relative; padding-left: 42px; }
.timeline-marker {
  position: absolute;
  top: 28px;
  left: 4px;
  width: 16px;
  height: 16px;
  border: 2px solid var(--accent);
  border-radius: 50%;
  background: var(--bg);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.edu-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 20px;
}
.edu-row + .edu-row { margin-top: 6px; }
.edu-degree { font-size: 1.12rem; }
.edu-degree span { font-weight: 400; color: var(--text-2); }
.edu-grade { font-variant-numeric: tabular-nums; white-space: nowrap; }
.edu-grade > span {
  margin-right: 6px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .76rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.edu-grade strong { font-size: 1.05rem; }
.edu-school { color: var(--text-2); }
.edu-date { color: var(--muted); font-size: .92rem; white-space: nowrap; }
.edu-note {
  display: flex;
  gap: 10px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  color: var(--text-2);
  font-size: .94rem;
}
.edu-note .icon { margin-top: .25em; color: var(--copper); }

/* ---------- Research ---------- */
.pub-list { display: grid; gap: 16px; }
.pub-card { display: grid; gap: 10px; scroll-margin-top: calc(var(--header-h) + 24px); transition: border-color .3s var(--ease), box-shadow .3s var(--ease); }
.pub-card:target { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.pub-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
}
.pub-key {
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--surface-3);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: .82rem;
  font-weight: 500;
}
.pub-type {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.pub-meta .badge { margin-left: auto; }
.pub-title { font-size: 1.12rem; line-height: 1.4; }
.pub-authors,
.pub-venue { color: var(--text-2); font-size: .95rem; }
.pub-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.pub-related {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-self: start;
  font-size: .92rem;
  font-weight: 500;
}

/* ---------- Projects ---------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 24px;
}
.filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-2);
  font-size: .9rem;
  font-weight: 500;
  transition: border-color .18s var(--ease), color .18s var(--ease), background-color .18s var(--ease);
}
.filter-btn:hover { border-color: var(--border-strong); color: var(--text); }
.filter-btn[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }
.filter-count {
  min-width: 22px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .75rem;
  text-align: center;
}
.filter-btn[aria-pressed="true"] .filter-count { background: var(--accent); color: var(--accent-ink); }

.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  gap: 20px;
  list-style: none;
}
.project-item[hidden] { display: none; }
.project-item { scroll-margin-top: calc(var(--header-h) + 24px); }

.project-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 0;
  overflow: hidden;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.project-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow); }

.project-media {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
  background: var(--surface-2);
  cursor: pointer;
}
.project-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.4s var(--ease); }
.project-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(5, 10, 19, .78);
  color: #e6ecf5;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .04em;
}

/* illustrated covers for projects without photos */
.cover-diagram {
  width: 100%;
  height: 100%;
  background-color: var(--surface-solid);
  background-image: radial-gradient(var(--border-strong) 1px, transparent 1.2px);
  background-size: 16px 16px;
}
.cover-diagram svg { width: 100%; height: 100%; }
.dg-box { fill: var(--surface-solid); stroke: var(--border-strong); stroke-width: 1.2; }
.dg-mcu { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.6; }
.dg-cloud { fill: var(--copper-soft); stroke: var(--copper); stroke-width: 1.2; }
.dg-line { fill: none; stroke: var(--accent); stroke-width: 1.4; }
.dg-dash { fill: none; stroke: var(--copper); stroke-width: 1.3; stroke-dasharray: 4 4; }
.dg-node { fill: var(--accent); }
.dg-text { fill: var(--text-2); font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .04em; }
.dg-title { fill: var(--text); font-family: var(--font-mono); font-size: 13px; font-weight: 500; letter-spacing: .06em; }
.dg-small { fill: var(--copper); font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .06em; }

.cover-code {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 18px;
  background-color: var(--surface-solid);
  background-image: radial-gradient(var(--border-strong) 1px, transparent 1.2px);
  background-size: 16px 16px;
}
.code-window {
  width: 100%;
  max-width: 400px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: #0a111e;
  box-shadow: var(--shadow);
  text-align: left;
  overflow: hidden;
}
.code-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  background: #121b2c;
  border-bottom: 1px solid #1f2b42;
}
.code-bar i { width: 8px; height: 8px; border-radius: 50%; background: #2c3a55; }
.code-bar span { margin-left: 6px; color: #8a9ab3; font-family: var(--font-mono); font-size: .7rem; }
.code-window pre {
  margin: 0;
  padding: 10px 14px 12px;
  overflow: hidden;
  color: #c7d3e6;
  font-family: var(--font-mono);
  font-size: .72rem;
  line-height: 1.6;
}
.code-window .c-com { color: #6f819d; }
.code-window .c-kw { color: #7dd3fc; }
.code-window .c-lbl { color: #e3a75c; }

.project-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 10px;
  padding: 18px 20px 20px;
}
.project-tech {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .04em;
}
.project-title { font-size: 1.1rem; line-height: 1.35; }
.project-desc { color: var(--text-2); font-size: .94rem; }
.project-metric {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  align-self: flex-start;
  padding: 3px 10px;
  border-radius: 6px;
  background: var(--copper-soft);
  color: var(--copper);
  font-family: var(--font-mono);
  font-size: .76rem;
  font-weight: 500;
}
.project-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: auto;
  padding-top: 8px;
}
.projects-more { margin-top: 28px; text-align: center; }
.projects-more a { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; }

/* ---------- Skills ---------- */
.skills-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr));
  gap: 16px;
}
.skill-card { display: grid; gap: 14px; align-content: start; }
.skill-title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 1.02rem;
}
.skill-title .icon-tile { width: 36px; height: 36px; border-radius: 9px; }
.skill-title .icon-tile .icon { width: 18px; height: 18px; }
.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  list-style: none;
}
.chip-list li { display: flex; }
/* each skill box is a link that searches the web for it in a new tab */
.chip-list a {
  display: block;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: .82rem;
  line-height: 1.35;
  white-space: nowrap;
  text-decoration: none;
  transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
.chip-list a:hover,
.chip-list a:focus-visible { border-color: var(--accent); background: var(--accent-soft); color: var(--text); text-decoration: none; }

/* ---------- Industrial training ---------- */
.training-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  list-style: none;
}
.training-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
.training-card h3 { font-size: 1.06rem; }
.training-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
  margin: 4px 0 10px;
  color: var(--muted);
  font-size: .88rem;
}
.training-meta span { display: inline-flex; align-items: center; gap: 6px; }
.training-meta .icon { width: 15px; height: 15px; }
.training-card p:last-child { color: var(--text-2); font-size: .95rem; }

/* ---------- Achievements ---------- */
.achieve-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
.achieve-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
.achieve-card h3 { font-size: 1.06rem; }
.achieve-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  margin: 4px 0 10px;
  color: var(--muted);
  font-size: .88rem;
}
.achieve-card p:last-child { color: var(--text-2); font-size: .95rem; }
.grade-pill {
  padding: 1px 9px;
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .8rem;
  font-weight: 500;
}

/* ---------- References ---------- */
.ref-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  list-style: none;
}
.ref-card { display: grid; gap: 4px; align-content: start; }
.ref-card h3 { font-size: 1.06rem; }
.ref-card h3 a { color: var(--text); }
.ref-card h3 a:hover { color: var(--accent); }
.ref-card h3 .icon { display: inline; width: 14px; height: 14px; margin-left: 4px; vertical-align: -1px; color: var(--muted); }
.ref-role { color: var(--text-2); font-size: .95rem; }
.ref-mail {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: start;
  margin-top: 6px;
  font-size: .93rem;
  word-break: break-all;
}
.ref-note { justify-self: start; margin-top: 8px; }

/* ---------- Contact ---------- */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr);
  gap: clamp(28px, 5vw, 56px);
  align-items: start;
}
.contact-info { display: grid; gap: 24px; }
.contact-list { display: grid; gap: 4px; list-style: none; }
.contact-list li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 14px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.contact-list li:last-child { border-bottom: 0; }
.contact-list .icon-tile { width: 38px; height: 38px; border-radius: 10px; }
.contact-list .icon-tile .icon { width: 18px; height: 18px; }
.contact-label {
  display: block;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.contact-value {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 10px;
  word-break: break-word;
}
.contact-value a { color: var(--text); font-weight: 500; }
.contact-value a:hover { color: var(--accent); }
.contact-alt { margin-top: 2px; }
.contact-alt a { color: var(--text-2); font-weight: 400; }
.copy-btn {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
}
.copy-btn:hover { border-color: var(--accent); color: var(--accent); }
.copy-btn .icon { width: 15px; height: 15px; }
.contact-actions { display: flex; flex-wrap: wrap; gap: 12px; }

.contact-form { display: grid; gap: 16px; }
.contact-form h3 { font-size: 1.15rem; }
.form-intro { margin-top: -8px; color: var(--muted); font-size: .9rem; }
.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.field { display: grid; gap: 6px; }
.field label { font-size: .9rem; font-weight: 500; color: var(--text); }
.field label .optional { color: var(--muted); font-weight: 400; }
.field input,
.field textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--input-bg);
  color: var(--text);
  font-size: 1rem;
  line-height: 1.5;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.field textarea { min-height: 150px; resize: vertical; }
.field input::placeholder,
.field textarea::placeholder { color: var(--muted); opacity: .8; }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.field [aria-invalid="true"] { border-color: var(--danger); }
.field-error { min-height: 0; color: var(--danger); font-size: .84rem; }
.field-error:empty { display: none; }

.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
}
.form-note { color: var(--muted); font-size: .86rem; }

.form-status {
  display: none;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: .93rem;
}
.form-status.is-visible { display: flex; }
.form-status .icon { margin-top: .2em; }
.form-status[data-tone="success"] { background: var(--ok-soft); color: var(--ok); }
.form-status[data-tone="error"] { background: var(--danger-soft); color: var(--danger); }
.form-status[data-tone="info"] { background: var(--info-soft); color: var(--info); }
.form-status a { color: inherit; text-decoration: underline; }

/* ---------- Footer ---------- */
.site-footer {
  margin-top: clamp(40px, 6vw, 72px);
  border-top: 1px solid var(--border);
  background: var(--header-bg);
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
  padding-block: 28px 72px;      /* room for the back-to-top button */
  color: var(--muted);
  font-size: .9rem;
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  list-style: none;
}
.footer-links a { color: var(--text-2); }
.footer-links a:hover { color: var(--accent); }

/* ---------- Floating UI ---------- */
.to-top {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 40;
  box-shadow: var(--shadow);
}
.to-top[hidden] { display: none; }

.toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: 300;
  padding: 10px 18px;
  border-radius: 10px;
  background: var(--text);
  color: var(--bg);
  font-size: .9rem;
  font-weight: 500;
  box-shadow: var(--shadow);
  transform: translate(-50%, 12px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* ---------- Project dialog ---------- */
.dialog {
  width: min(1000px, calc(100% - 24px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-solid);
  color: var(--text);
  box-shadow: 0 30px 80px -24px rgba(0, 0, 0, .65);
  overflow: hidden;
}
.dialog::backdrop { background: var(--backdrop); }
.dialog-scroll {
  max-height: calc(100dvh - 34px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.dialog-bar {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  justify-content: flex-end;
  height: 0;
}
.dialog-close {
  margin: 14px 14px 0 0;
  background: var(--surface-solid);
  box-shadow: var(--shadow-sm);
}
.dialog-content { padding: clamp(20px, 3.4vw, 36px); }

.dlg-head { padding-right: 52px; margin-bottom: 22px; }
.dlg-kicker {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.dlg-title { margin-top: 8px; font-size: clamp(1.35rem, 1.1rem + 1.2vw, 1.85rem); }
.dlg-lead { margin-top: 12px; color: var(--text-2); font-size: 1.02rem; }
.dlg-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }

.dlg-media { display: grid; gap: 18px; margin-bottom: 26px; }

.dlg-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr);
  gap: clamp(22px, 3.5vw, 36px);
}
.dlg-main { display: grid; gap: 22px; align-content: start; }
.dlg-main h3,
.dlg-side h3 {
  margin-bottom: 8px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .76rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.dlg-main p { color: var(--text-2); }

.check-list { display: grid; gap: 7px; list-style: none; }
.check-list li {
  position: relative;
  padding-left: 22px;
  color: var(--text-2);
}
.check-list li::before {
  content: "";
  position: absolute;
  top: .62em;
  left: 2px;
  width: 8px;
  height: 8px;
  border: 1.5px solid var(--accent);
  border-radius: 50%;
}
.steps { display: grid; gap: 8px; padding-left: 0; list-style: none; counter-reset: step; }
.steps li {
  position: relative;
  padding-left: 34px;
  color: var(--text-2);
  counter-increment: step;
}
.steps li::before {
  content: counter(step);
  position: absolute;
  top: .1em;
  left: 0;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .75rem;
  font-weight: 500;
}

.mini-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .9rem;
}
.mini-table th,
.mini-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}
.mini-table th {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.mini-table td { color: var(--text-2); }
.mini-table td:first-child { color: var(--text); font-weight: 500; white-space: nowrap; }
.mini-table code { font-family: var(--font-mono); color: var(--accent); }
.table-scroll { overflow-x: auto; }

.dlg-side { display: grid; gap: 22px; align-content: start; }
.facts {
  margin: 0;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.facts div { padding: 8px 0; border-bottom: 1px dashed var(--border-strong); }
.facts div:first-child { padding-top: 0; }
.facts div:last-child { padding-bottom: 0; border-bottom: 0; }
.facts dt {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.facts dd { margin: 2px 0 0; color: var(--text); font-size: .93rem; }

.gallery { margin: 0; }
.gallery-stage {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  max-height: 72vh;              /* also narrows tall images, so centre the stage */
  margin-inline: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background:
    repeating-conic-gradient(var(--surface-2) 0 25%, var(--surface-solid) 0 50%) 0 0 / 22px 22px;
  overflow: hidden;
  cursor: zoom-in;
}
.gallery-stage.is-tall { aspect-ratio: 4 / 5; }
.dlg-side .gallery-stage { aspect-ratio: 4 / 3; }
.gallery-stage img {
  position: absolute;
  inset: 10px;
  width: calc(100% - 20px);
  height: calc(100% - 20px);
  object-fit: contain;
}
.gallery-caption {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 10px;
  color: var(--muted);
  font-size: .88rem;
}
.gallery-caption a { white-space: nowrap; }
.gallery-thumbs {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  overflow-x: auto;
  padding-bottom: 4px;
}
.gallery-thumb {
  flex: none;
  width: 92px;
  height: 60px;
  padding: 0;
  border: 2px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-2);
  opacity: .7;
  transition: opacity .18s var(--ease), border-color .18s var(--ease);
}
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumb:hover { opacity: 1; }
.gallery-thumb[aria-current="true"] { border-color: var(--accent); opacity: 1; }

.video-frame {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #000;
}
.video-frame video { width: 100%; max-height: 62vh; background: #000; }
.video-caption { margin-top: 8px; color: var(--muted); font-size: .88rem; }

/* ---------- Simple pages (404, thanks) ---------- */
.page-center {
  display: grid;
  place-items: center;
  min-height: calc(100vh - var(--header-h) - 120px);
  padding-block: 64px;
  text-align: center;
}
.page-center .card { max-width: 560px; padding: clamp(28px, 5vw, 44px); }
.page-code {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .85rem;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.page-title { margin: 10px 0 12px; font-size: clamp(1.8rem, 1.4rem + 2vw, 2.4rem); }
.page-text { color: var(--text-2); }
.page-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 24px; }
.outcome { display: none; }
.outcome-default { display: block; }
.outcome:target { display: block; }
.outcome:target ~ .outcome-default { display: none; }

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .hero-grid,
  .about-grid,
  .contact-grid { grid-template-columns: 1fr; }
  .hero-chip { justify-content: flex-start; }
  .dlg-grid { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .training-grid,
  .achieve-grid,
  .ref-grid,
  .field-row { grid-template-columns: 1fr; }
  .focus-grid { grid-template-columns: 1fr; }
  .pub-meta .badge { margin-left: 0; }
  .hero-chip { justify-content: center; }   /* phones: the 3D chip sits in the middle */
}

@media (max-width: 560px) {
  .stats { grid-template-columns: 1fr; }
  .stat { flex-direction: row; align-items: center; gap: 16px; }
  .stat-value { min-width: 1.3em; }
}

@media (max-width: 480px) {
  .hero-actions .btn { flex: 1 1 100%; }
  .stat { padding: 14px 16px; }
  .stat-value { font-size: 1.65rem; }
  .brand-name { display: none; }
  .chip { padding-inline: 20px; }
  .header-actions { gap: 6px; }
}


/* ==========================================================================
   HDR mode: wide colour and brighter lights
   <html data-hdr="on"> while the floating HDR button is on (the default on
   screens that can show more than standard colours; theme.js and main.js).
   On wide-gamut Display-P3 screens (MacBooks, iPhones and iPads, most recent
   Android phones and many laptops) the accents, copper, buttons and the
   background's signal lights use colours beyond the standard sRGB range, so
   they look more vivid. On HDR screens the lights also glow brighter than
   normal white (see "HDR lights" below). Standard screens look as before.
   ========================================================================== */
@supports (color: color(display-p3 1 1 1)) {
  @media (color-gamut: p3) {
    :root[data-hdr="on"] {
      --bg-glow: color(display-p3 .14 .62 1 / .1);
      --accent: color(display-p3 .12 .74 1);
      --accent-strong: color(display-p3 .5 .87 1);
      --accent-soft: color(display-p3 .12 .74 1 / .14);
      --copper: color(display-p3 1 .62 .2);
      --copper-soft: color(display-p3 1 .62 .2 / .15);
      --copper-glow: color(display-p3 1 .6 .16 / .8);
      --accent-ring: color(display-p3 .12 .74 1 / .6);
      --ok: color(display-p3 .2 .95 .58);
      --ok-soft: color(display-p3 .2 .95 .58 / .13);
      --warn: color(display-p3 1 .8 .08);
      --warn-soft: color(display-p3 1 .8 .08 / .13);
      --info: color(display-p3 .36 .62 1);
      --info-soft: color(display-p3 .36 .62 1 / .14);
      --danger: color(display-p3 1 .36 .36);
      --danger-soft: color(display-p3 1 .36 .36 / .13);
      --signal: color(display-p3 .1 .78 1);
      --signal-alt: color(display-p3 1 .6 .14);
      --signal-red: color(display-p3 1 .38 .42);
      --signal-green: color(display-p3 .3 1 .54);
    }
    :root[data-hdr="on"][data-theme="light"] {
      --bg-glow: color(display-p3 0 .45 .85 / .07);
      --accent: color(display-p3 0 .42 .8);
      --accent-strong: color(display-p3 0 .34 .66);
      --accent-soft: color(display-p3 0 .42 .8 / .09);
      --copper: color(display-p3 .72 .36 0);
      --copper-soft: color(display-p3 .72 .36 0 / .11);
      --copper-glow: color(display-p3 .9 .45 0 / .55);
      --accent-ring: color(display-p3 0 .42 .8 / .45);
      --ok: color(display-p3 0 .52 .27);
      --ok-soft: color(display-p3 0 .52 .27 / .1);
      --warn: color(display-p3 .6 .38 0);
      --warn-soft: color(display-p3 .6 .38 0 / .11);
      --info: color(display-p3 .1 .3 .9);
      --info-soft: color(display-p3 .1 .3 .9 / .09);
      --danger: color(display-p3 .78 .08 .1);
      --danger-soft: color(display-p3 .78 .08 .1 / .09);
      --signal: color(display-p3 0 .5 .92);
      --signal-alt: color(display-p3 .92 .34 0);
      --signal-red: color(display-p3 .95 .18 .24);
      --signal-green: color(display-p3 0 .7 .3);
    }
  }
}

/* The floating HDR button (bottom left): just the word HDR, with no box
   around it. It only appears on screens that can show wide colour or HDR;
   the word is green while HDR mode is on and faded while it is off. */
.hdr-toggle {
  position: fixed;
  left: 12px;
  bottom: 12px;
  z-index: 40;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  height: 40px;
  padding: 0 8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font: 700 .8rem/1 var(--font-mono);
  letter-spacing: .1em;
  opacity: .45;
  cursor: pointer;
  transition: color .25s var(--ease), opacity .25s var(--ease), text-shadow .25s var(--ease);
}
:root.can-p3 .hdr-toggle,
:root.can-hdr .hdr-toggle { display: inline-flex; }
@media (hover: hover) {
  .hdr-toggle:hover { opacity: .8; }
}
:root[data-hdr="on"] .hdr-toggle {
  color: var(--signal-green);
  opacity: 1;
  text-shadow: 0 0 9px var(--signal-green);
}
:root[data-hdr="on"][data-theme="light"] .hdr-toggle { text-shadow: none; }
@media (max-width: 480px) {
  .hdr-toggle { left: 6px; bottom: 8px; }
}

/* HDR lights. On HDR screens (MacBook Pro and other Macs with EDR, iPhones
   and iPads, HDR Android phones, Windows laptops with HDR on) the small
   lights also glow from a tiny HDR image: the chip's LED, the timeline
   nodes and the background's signal pulses (circuit-bg.js). The images (assets/img/hdr/) are 16-bit PNGs in
   Rec.2100 PQ with BT.2020 colours, the same signal format as HDR10 video,
   so their cores shine past normal white while the rest of the page stays
   at normal brightness. Each glow is a small layer of its own, so only the
   glow is drawn in HDR. dynamic-range-limit lets HDR content use the
   screen's full HDR range while HDR mode is on, and keeps it at normal
   brightness when it is off. */
:root[data-hdr="on"] { dynamic-range-limit: no-limit; }
:root[data-hdr="off"] { dynamic-range-limit: standard; }
@media (dynamic-range: high) {
  :root[data-hdr="on"] :is(.chip-dot, .timeline-marker)::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 34px;
    height: 34px;
    margin: -17px 0 0 -17px;
    background: url("../img/hdr/glow-copper.png") center / 100% 100% no-repeat;
    pointer-events: none;
    will-change: transform;
  }
  :root[data-hdr="on"] .timeline-marker::after {
    width: 28px;
    height: 28px;
    margin: -14px 0 0 -14px;
    background-image: url("../img/hdr/glow-blue.png");
  }
}

/* ---------- Motion ----------
   Everything below runs only while <html data-motion="on">: on by default,
   switched with the wave button in the header (the choice is remembered). */

/* Entrance: blocks fade up as they scroll into view (list kept in step with
   REVEAL in main.js; theme.js adds .reveal-on before the first paint). */
:root.reveal-on[data-motion="on"] :is(.section-head, .about-text > *, .focus-card, .timeline-item, .pub-card, .filters, .project-item, .skill-card, .chip-list li, .training-card, .achieve-card, .ref-card, .contact-list li, .contact-actions, .contact-form, .projects-more):not(.is-visible) {
  opacity: 0;
  transform: translateY(18px);
}
/* The hero is on screen at load, so it rises in with plain CSS (no waiting
   for scripts); numbers and the typed tagline stay hidden until main.js has
   reset them, so they never flash their final values first. */
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }
:root[data-motion="on"] .hero-copy > *,
:root[data-motion="on"] .hero-chip,
:root[data-motion="on"] .stat { animation: rise .9s var(--ease) both; }
:root[data-motion="on"] .hero-copy > :nth-child(2) { animation-delay: .08s; }
:root[data-motion="on"] .hero-copy > :nth-child(3) { animation-delay: .16s; }
:root[data-motion="on"] .hero-copy > :nth-child(4) { animation-delay: .24s; }
:root[data-motion="on"] .hero-copy > :nth-child(5) { animation-delay: .32s; }
:root[data-motion="on"] .hero-copy > :nth-child(6) { animation-delay: .4s; }
:root[data-motion="on"] .hero-chip { animation-delay: .25s; }
:root[data-motion="on"] .stat:nth-child(1) { animation-delay: .45s; }
:root[data-motion="on"] .stat:nth-child(2) { animation-delay: .55s; }
:root[data-motion="on"] .stat:nth-child(3) { animation-delay: .65s; }
:root.reveal-on[data-motion="on"]:not(.reveal-ready) :is(.type-text, [data-count]) { visibility: hidden; }

.reveal { transition: opacity .9s var(--ease) var(--reveal-delay, 0s), transform .9s var(--ease) var(--reveal-delay, 0s); }
.pub-card.reveal {
  transition: opacity .9s var(--ease) var(--reveal-delay, 0s), transform .9s var(--ease) var(--reveal-delay, 0s),
    border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.chip-list li.reveal {
  transition: opacity .7s var(--ease) var(--reveal-delay, 0s), transform .7s var(--ease) var(--reveal-delay, 0s),
    border-color .2s var(--ease), color .2s var(--ease);
}

/* While a section is off screen (main.js marks it), its animations hold
   still, so the processor and graphics card only work on what can be seen.
   They carry on from the same point when it comes back into view. */
.is-offscreen *,
.is-offscreen *::before,
.is-offscreen *::after { animation-play-state: paused !important; }

/* Typed tagline caret */
.type-caret {
  display: inline-block;
  width: .55em;
  height: 1.05em;
  margin-left: 3px;
  vertical-align: -.18em;
  background: currentColor;
  opacity: .7;
}

/* Small parts that behave like the hardware they show */
@keyframes pins-scan { from { background-position: 0 0%; } to { background-position: 0 100%; } }
@keyframes led-glow {
  0%, 100% { opacity: .7; box-shadow: 0 0 0 0 transparent; }
  50% { opacity: 1; box-shadow: 0 0 10px 2px var(--copper-glow); }
}
@keyframes led-blink { 50% { opacity: .35; } }
@keyframes chip-sway {
  0%, 100% { transform: rotateY(0deg) rotateX(0deg); }
  25% { transform: rotateY(3deg) rotateX(2deg); }
  50% { transform: rotateY(5deg) rotateX(-1deg); }
  75% { transform: rotateY(2deg) rotateX(-2deg); }
}
@keyframes node-pulse {
  0% { box-shadow: 0 0 0 4px var(--accent-soft), 0 0 0 4px var(--accent-ring); }
  70%, 100% { box-shadow: 0 0 0 4px var(--accent-soft), 0 0 0 13px transparent; }
}
@keyframes bus-signal { from { background-position: 0 -80px, 0 0; } to { background-position: 0 calc(100% + 80px), 0 0; } }
@keyframes trace-signal {
  0% { background-position: -9px 50%, 0 0, left center; }
  70%, 100% { background-position: 100% 50%, 0 0, left center; }
}
@keyframes caret-blink { 50% { opacity: 0; } }

:root[data-motion="on"] :is(.chip-pins-left, .chip-legs-left) { animation: pins-scan 3.6s linear infinite; }
:root[data-motion="on"] :is(.chip-pins-right, .chip-legs-right) { animation: pins-scan 3.6s linear -1.8s infinite reverse; }
:root[data-motion="on"] .chip-sway { animation: chip-sway 14s ease-in-out infinite; }
:root[data-motion="on"] .chip-dot { animation: led-glow 2.8s ease-in-out infinite; }
:root[data-motion="on"] .brand-mark::before { animation: led-blink 2.4s ease-in-out infinite; }
:root[data-motion="on"] .brand-mark::after { animation: led-blink 2.4s ease-in-out -1.2s infinite; }
:root[data-motion="on"] .timeline-marker { animation: node-pulse 3s ease-out infinite; }
:root[data-motion="on"] .timeline-item:nth-child(2) .timeline-marker { animation-delay: .6s; }
:root[data-motion="on"] .timeline-item:nth-child(3) .timeline-marker { animation-delay: 1.2s; }
:root[data-motion="on"] .timeline::before { animation: bus-signal 4.5s ease-in-out infinite; }
:root[data-motion="on"] .eyebrow::after { animation: trace-signal 3.4s ease-in infinite; }
:root[data-motion="on"] .badge::before { animation: led-blink 2.6s ease-in-out infinite; }
:root[data-motion="on"] .type-caret { animation: caret-blink 1.1s steps(1) infinite; }
:root[data-motion="on"] .project-card:hover .project-media img { transform: scale(1.045); }
/* Icons: each one moves the way its subject does (parts are classed in the
   icon set at the top of index.html). */
.ic-core, .ic-charge, .ic-page { fill: currentColor; fill-opacity: 0; }
.ic-signal { opacity: 0; }
.ic-rays, .ic-tilt, .ic-orbit, .ic-turn, .ic-ring, .ic-blink, .ic-plus { transform-box: fill-box; transform-origin: center; }
.ic-swing { transform-box: fill-box; transform-origin: 50% 0; }

:root[data-motion="on"] .ic-scroll { animation: ic-scroll 2.8s linear infinite; }            /* signal: oscilloscope trace */
:root[data-motion="on"] .ic-core { animation: ic-fill 3s ease-in-out infinite; }              /* chip: core activity */
:root[data-motion="on"] .ic-pins-a { animation: ic-dim 2.4s ease-in-out infinite; }
:root[data-motion="on"] .ic-pins-b { animation: ic-dim 2.4s ease-in-out -1.2s infinite; }
:root[data-motion="on"] .ic-trace { opacity: .55; }                                           /* PCB: pulse along a trace */
:root[data-motion="on"] .ic-signal { opacity: 1; stroke-width: 2.4; stroke-dasharray: .22 1; animation: ic-signal 2.2s linear infinite; }
:root[data-motion="on"] .ic-charge { animation: ic-charge 4s ease-in-out infinite; }          /* power: charge and flicker */
:root[data-motion="on"] .ic-br-l { animation: ic-left 3.2s ease-in-out infinite; }
:root[data-motion="on"] .ic-br-r { animation: ic-right 3.2s ease-in-out infinite; }
:root[data-motion="on"] .ic-slash { animation: ic-dim 3.2s ease-in-out infinite; }
:root[data-motion="on"] .ic-trend { stroke-dasharray: 1; animation: ic-draw 4.5s ease-in-out infinite; }   /* forecast line */
:root[data-motion="on"] .ic-arc1 { animation: ic-glow 2.4s ease-in-out infinite; }             /* antenna: radio waves */
:root[data-motion="on"] .ic-arc2 { animation: ic-glow 2.4s ease-in-out .5s infinite; }
:root[data-motion="on"] .ic-orbit { animation: ic-spin 16s linear infinite; }                  /* atom: orbits */
:root[data-motion="on"] .ic-rays { animation: ic-spin 24s linear infinite; }
:root[data-motion="on"] .ic-turn { animation: ic-sway 4s ease-in-out infinite; }               /* wrench: tightening */
:root[data-motion="on"] .ic-tilt { animation: ic-sway 6s ease-in-out infinite; }
:root[data-motion="on"] .ic-swing { animation: ic-sway 5s ease-in-out infinite; }              /* medal: hanging swing */
:root[data-motion="on"] .ic-back { animation: ic-dim 3.6s ease-in-out infinite; }
:root[data-motion="on"] .ic-front,
:root[data-motion="on"] .ic-layer-top,
:root[data-motion="on"] .ic-bounce { animation: ic-float 3.4s ease-in-out infinite; }          /* layers, map pin */
:root[data-motion="on"] .ic-page { animation: ic-fill 4s ease-in-out infinite; }
:root[data-motion="on"] .ic-voice { animation: ic-glow 2.2s ease-in-out infinite; }            /* microphone: speaking */
:root[data-motion="on"] .ic-lang-a { animation: ic-dim 4s ease-in-out infinite; }              /* language: translation */
:root[data-motion="on"] .ic-lang-b { animation: ic-glow 4s ease-in-out infinite; }
:root[data-motion="on"] .ic-flap { animation: ic-sink 3.2s ease-in-out infinite; }             /* envelope flap */
:root[data-motion="on"] .ic-ring { animation: ic-ring 4.5s ease-in-out infinite; }             /* phone: ringing */
:root[data-motion="on"] .ic-blink { animation: ic-blink 5s ease-in-out infinite; }             /* eye: blink */
:root[data-motion="on"] .ic-plus { animation: ic-pop 2.8s ease-in-out infinite; }
:root[data-motion="on"] .ic-fly { animation: ic-fly 3s ease-in-out infinite; }                 /* send: paper plane */
:root[data-motion="on"] .ic-drop { animation: ic-drop 2.6s ease-in-out infinite; }             /* download arrow */
:root[data-motion="on"] .ic-nudge { animation: ic-nudge 2.6s ease-in-out infinite; }
:root[data-motion="on"] .ic-ecg { stroke-dasharray: 1 1; animation: ic-sweep 3s linear infinite; }  /* ECG sweep */

@keyframes ic-scroll { to { transform: translateX(-10px); } }
@keyframes ic-fill { 0%, 100% { fill-opacity: 0; } 50% { fill-opacity: .45; } }
@keyframes ic-dim { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes ic-glow { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
@keyframes ic-charge {
  0%, 100% { fill-opacity: 0; }
  55% { fill-opacity: .35; }
  60% { fill-opacity: .05; }
  66% { fill-opacity: .4; }
  85% { fill-opacity: .08; }
}
@keyframes ic-signal { from { stroke-dashoffset: .22; } to { stroke-dashoffset: -1; } }
@keyframes ic-left { 50% { transform: translateX(-.9px); } }
@keyframes ic-right { 50% { transform: translateX(.9px); } }
@keyframes ic-draw {
  0% { stroke-dashoffset: 1; opacity: 1; }
  45%, 80% { stroke-dashoffset: 0; opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ic-spin { to { transform: rotate(360deg); } }
@keyframes ic-sway { 0%, 100% { transform: rotate(-7deg); } 50% { transform: rotate(7deg); } }
@keyframes ic-float { 50% { transform: translateY(-1.4px); } }
@keyframes ic-sink { 50% { transform: translateY(1.1px); } }
@keyframes ic-ring {
  0%, 14%, 100% { transform: rotate(0); }
  2%, 6%, 10% { transform: rotate(-10deg); }
  4%, 8%, 12% { transform: rotate(10deg); }
}
@keyframes ic-blink { 0%, 90%, 100% { transform: scaleY(1); } 94% { transform: scaleY(.12); } }
@keyframes ic-pop { 50% { transform: scale(1.22); } }
@keyframes ic-fly { 50% { transform: translate(.8px, -.8px); } }
@keyframes ic-drop { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(1.6px); } }
@keyframes ic-nudge { 0%, 60%, 100% { transform: translateX(0); } 30% { transform: translateX(2px); } }
@keyframes ic-sweep { from { stroke-dashoffset: 1; } to { stroke-dashoffset: -1; } }

/* ---------- Print: a clean, ink-friendly page ---------- */
@media print {
  :root { color-scheme: light; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .circuit-bg,
  .site-header,
  .skip-link,
  .hero-actions,
  .social-list,
  .filters,
  .project-media,
  .project-actions,
  .projects-more,
  .contact-form,
  .contact-actions,
  .copy-btn,
  .to-top,
  .hdr-toggle,
  .toast,
  .dialog,
  .site-footer { display: none !important; }
  .section,
  .hero { padding-block: 12pt; }
  .card,
  .stat,
  .chip { background: #fff; border-color: #bbb; box-shadow: none; break-inside: avoid; }
  .chip-sway,
  .chip-tilt,
  .chip-package { transform: none !important; animation: none !important; }
  body::before { display: none; }
  .chip-edge,
  .chip-legs { display: none; }
  a { color: #000; }
  .hero-grid,
  .about-grid,
  .contact-grid { grid-template-columns: 1fr; }
  :is(.section-head, .about-text > *, .focus-card, .timeline-item, .pub-card, .filters, .project-item, .skill-card, .chip-list li, .training-card, .achieve-card, .ref-card, .contact-list li, .contact-actions, .contact-form, .projects-more) { opacity: 1 !important; transform: none !important; }
}
