:root,
[data-theme="light"] {
  --paper: #f1f8ff;
  --ink: #17171a;
  --muted: #9ca1b9;
  --rule: #b2e0d4;
  --accent: #2e7c65;      /* graph-edge blue, used sparingly (links, edges) */
  --accent-warm: #3d6d8a; /* primary interactive/highlight color */
  --max: 800px;
  --gutter: 28px;
}

/* Dark mode swaps background/ink/rule only — accent colors stay the
   same as light mode so the palette reads as one consistent identity
   rather than two different color schemes. */
[data-theme="dark"] {
  --paper: #17191a;
  --ink: #e4e8f6;
  --muted: #888ca1;
  --rule: #364a40;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Pavanam', system-ui, sans-serif;
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  transition: background 0.2s, color 0.2s;
}

h1, h2 {
  font-family: 'Tiro Gurmukhi', Georgia, serif;
  letter-spacing: -0.01em;
  color: var(--ink);
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.15s;
}
a:hover { color: var(--accent-warm); }

a:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.topnav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px var(--gutter);
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(6px);
}
.topnav-links { display: flex; gap: 20px; flex-wrap: wrap; }
.topnav a {
  color: var(--muted);
  text-decoration: none;
  position: relative;
  padding-bottom: 2px;
}

/* Mobile nav: instead of letting items wrap wherever they happen to
   run out of room, force a deliberate grid — 3-per-row (two rows) down
   to 640px, then 2-per-row (three rows) once it's too tight for that.
   The toggle is pulled out of the flex flow and pinned to the corner
   (rather than given its own row) so it doesn't leave a mostly-empty
   row above the links. */
@media (max-width: 640px) {
  .theme-toggle {
    position: absolute;
    top: 14px;
    right: var(--gutter);
  }
  .topnav-links {
    width: 100%;
    justify-content: center;
    gap: 10px 6%;
    padding-right: 46px; /* clears the toggle pinned in the corner */
  }
  .topnav-links a { flex: 0 0 28%; text-align: center; }
}
@media (max-width: 400px) {
  .topnav-links a { flex: 0 0 42%; }
}
.topnav a::after {
  content: '';
  position: absolute;
  left: 0; right: 100%;
  bottom: -1px;
  height: 1px;
  background: var(--accent-warm);
  transition: right 0.2s ease;
}
.topnav a:hover, .topnav a.is-current { color: var(--accent-warm); }
.topnav a:hover::after, .topnav a.is-current::after { right: 0; }

/* Reading-progress bar along the bottom edge of the header. */
.progress-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--rule);
  overflow: hidden;
  transition: height 0.15s ease;
}
.progress-bar:hover { height: 5px; }
.progress-bar-fill {
  height: 100%;
  width: 0%;
  background: var(--accent-warm);
  transition: width 0.1s linear;
}

.theme-toggle {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--rule);
  border-radius: 50%;
  color: var(--muted);
  cursor: pointer;
  padding: 0;
}
.theme-toggle:hover { color: var(--accent-warm); border-color: var(--accent-warm); }
.theme-toggle svg {
  width: 15px;
  height: 15px;
  position: absolute;
  transition: opacity 0.25s, transform 0.35s;
}
.icon-sun { opacity: 1; transform: rotate(0deg); }
.icon-moon { opacity: 0; transform: rotate(-60deg); }
[data-theme="dark"] .icon-sun { opacity: 0; transform: rotate(60deg); }
[data-theme="dark"] .icon-moon { opacity: 1; transform: rotate(0deg); }

main {
  position: relative;
  z-index: 1;
  padding-bottom: 80px;
}

.section-inner {
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  position: relative;
}

.section-inner-wide {
  display: flex;
  position: relative;
  padding: 0 calc(var(--gutter)*7) 0;
  margin: 0 auto;
}


/* ---------- Hero: first fold, full viewport height, two columns ---------- */

.hero {
  min-height: 100vh;
  display: flex;
  align-items: center;
  position: relative;
  /* --nav-height is measured live in JS from the actual (possibly
     multi-row) nav, so the hero always clears it regardless of how
     many rows the nav links wrap to. */
  padding: calc(var(--nav-height, 74px) + 16px) var(--gutter) 70px;
  border-bottom: 1px solid var(--rule);
  overflow: hidden;
}

.hero-graph {
  position: absolute;
  bottom: -60px;
  right: -40px;
  width: min(56vw, 580px);
  height: auto;
  opacity: 0.4;
  overflow: visible;
  z-index: 0;
  pointer-events: none;
}
.hero-graph .nodes circle { pointer-events: auto; }
.hero-graph .edges line {
  stroke: var(--accent);
  stroke-width: 1.2;
  opacity: 0.28;
  transition: opacity 0.2s, stroke 0.2s;
}
[data-theme="dark"] .hero-graph .edges line { opacity: 0.5; stroke-width: 1.3; }
[data-theme="dark"] .hero-graph .edges line.is-active { opacity: 0.9; }
.hero-graph .edges line.is-active { stroke: var(--accent-warm); opacity: 0.8; }
.hero-graph .edges line.is-pulsing { stroke: var(--accent-warm); opacity: 1; stroke-width: 2; }
.hero-graph .nodes circle {
  fill: var(--paper);
  stroke: var(--accent-warm);
  stroke-width: 1.4;
  opacity: 1;
  transition: opacity 0.2s, r 0.2s;
  cursor: pointer;
}
.hero-graph .nodes circle.is-linked { opacity: 1; }
.hero-graph .nodes circle.is-active { opacity: 1; r: 20; }
.hero-graph .nodes circle.is-pulsing { opacity: 1; r: 21; }
@media (max-width: 700px) { .hero-graph { width: 62vw; max-width: 280px; bottom: -20px; right: -20px; opacity: 0.35; } }

.hero-columns {
  max-width: 1040px;
  width: 100%;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 56px;
  position: relative;
  z-index: 1;
}
.hero-left { justify-items: right }
.hero-left, .hero-right { flex: 1; min-width: 0; }
.hero-divider { width: 1px; align-self: stretch; background: var(--rule); flex-shrink: 0; }

@media (max-width: 760px) {
  .hero { min-height: auto; padding: calc(var(--nav-height, 130px) + 20px) var(--gutter) 56px; }
  .hero-columns { flex-direction: column; align-items: center; gap: 36px; }
  .hero-divider { display: none; }
  .hero-sub { justify-self: center; }
  .icon-links { justify-self: center; }
}

/* Hero load-in: a single orchestrated entrance, staggered via inline
   transition-delay set in JS. */
.hero-intro {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.hero-intro.is-visible { opacity: 0.8; transform: translateY(0); }

.hero-identity {
  display: flex;
  align-items: center;
  gap: 16px;
}

.hero-photo {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--rule);
  flex-shrink: 0;
  transition: transform 0.25s ease;
}
.hero-photo:hover { transform: rotate(-4deg) scale(1.04); }

.hero h1 {
  margin: 0;
  font-size: 48px;
  font-weight: 700;
  line-height: 1.4;
  text-decoration: underline;
  text-decoration-style: wavy;
  text-decoration-color: var(--accent-warm);
  text-decoration-thickness: 3px;
  text-underline-offset: 13px;
}

.hero-role {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 16px;
  font-weight: 400;
}

.hero-sub {
  max-width: 420px;
  color: var(--ink);
  font-size: 18px;
  margin: 8px 0 32px;
}

.icon-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.icon-link {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rule);
  border-radius: 50%;
  color: var(--muted);
  transition: color 0.15s, border-color 0.15s, transform 0.15s ease;
}
.icon-link svg { width: 15px; height: 15px; }
.icon-link:hover {
  color: var(--accent-warm);
  border-color: var(--accent-warm);
  transform: translateY(-2px);
}
.icon-link-text {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
}

.hero-right h2 { font-size: 24px; margin: 0; }
.hero-right p { color: var(--ink); max-width: 440px; margin-top: 4px;}
.hero-right {
  background: color-mix(in srgb, var(--accent-warm) 7%, var(--paper));
  border-radius: 3px;
  padding: 28px 30px;
  position: relative;
  z-index: 2;
}
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rule);
  border-radius: 50%;
  color: var(--muted);
  animation: bob 2.4s ease-in-out infinite;
}
.scroll-cue svg { width: 15px; height: 15px; }
.scroll-cue:hover { color: var(--accent-warm); border-color: var(--accent-warm); }
@keyframes bob {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, 6px); }
}
@media (max-width: 760px) { .scroll-cue { display: none; } }

/* ---------- Rest of the page ---------- */

section {
  padding: 60px 0;
  position: relative;
  scroll-margin-top: 84px;
}

/* Full-width color band for alternating sections — full-bleed 
   and .section-inner carries the reading column width. No 
   extra padding/margin here, so spacing stays identical to 
   plain sections. */
.section-color {
  background: color-mix(in srgb, var(--accent-warm) 6%, var(--paper));
}

section h2 {
  font-size: 32px;
  margin: 0;
}

.section-head {
  display: flex;
  align-items: center;
  gap: 14px;
}
.section-head-space {
  margin-bottom: 24px;
}
.section-icon {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  color: var(--accent-warm);
}

.section-sub {
  color: var(--muted);
  font-size: 13.5px;
  margin: 0 0 20px;
}

/* Publications */
.pub-list {
  list-style: none;
  counter-reset: pub;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.pub-list li {
  counter-increment: pub;
  position: relative;
  padding-left: 34px;
}
.pub-list li::before {
  content: counter(pub);
  position: absolute;
  left: 0;
  top: 1px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--muted);
}
.pub-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.pub-title {
  font-weight: 600;
  color: var(--ink);
}
.pub-title a { color: inherit; }
.pub-year {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}
.pub-authors {
  color: var(--ink);
  font-size: 15px;
  margin-top: 4px;
}
.pub-authors strong { font-weight: 600; }

/* Venue and its Paper/Code links share one line — venue left, links
   right-aligned — instead of links getting a separate row. */
.pub-venue-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 2px;
}
.pub-venue { color: var(--muted); font-size: 14px; }
.pub-notes {
  color: var(--muted);
  font-size: 13px;
  font-style: italic;
  margin-top: 4px;
}

.pub-links { display: flex; gap: 16px; }
.pub-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
}
.pub-link svg { width: 11px; height: 11px; }
.pub-link:hover { color: var(--accent-warm); }

/* Experience entries */
.entry-list { display: flex; flex-direction: column; gap: 26px; }

/* Industry becomes a gallery of cards instead of a stacked list — a
   different shape from Research's stacked entries just below it. */
.entry-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
}
.entry-grid .entry {
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.entry-grid .entry:has(.entry-toggle:hover),
.entry-grid .entry:has(.entry-toggle:focus-visible) {
  border-color: var(--accent-warm);
  background: color-mix(in srgb, var(--accent-warm) 6%, var(--paper));
}
.entry-grid .entry-toggle {
  padding: 0;
  margin: 0;
  border-left: none;
  border-radius: 0;
  background: none !important;
}
@media (max-width: 1240px) { 
  .section-inner-wide { padding: 0 calc(var(--gutter)) 0; } 
  .entry-grid { grid-template-columns: 1fr 1fr; } 
}
@media (max-width: 640px) { .entry-grid { grid-template-columns: 1fr; } }
.entry-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  flex: 1;
  min-width: 0;
}
.entry-toggle {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  background: none;
  border: none;
  border-left: 2px solid transparent;
  padding: 10px 12px;
  margin: -10px -12px;
  border-radius: 3px;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.entry-toggle-main { flex: 1; min-width: 0; }
.entry-toggle:hover, .entry-toggle:focus-visible {
  background: color-mix(in srgb, var(--accent-warm) 8%, transparent);
  border-left-color: var(--accent-warm);
}
.entry-chevron {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  margin-top: 3px;
  color: var(--muted);
  transition: transform 0.3s ease, color 0.15s;
}
.entry-toggle[aria-expanded="true"] .entry-chevron { transform: rotate(180deg); }
.entry-toggle:hover .entry-chevron { color: var(--accent-warm); }

/* Experience cards: role is the highlight (title), lab/company is the
   subtitle, then dates — the opposite emphasis from the org-led version. */
.exp-title { font-weight: 600; color: var(--ink); font-size: 16.5px; }
.exp-org { color: var(--muted); font-size: 14.5px; margin-top: 4px; }
.exp-dates {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--muted);
  margin-top: 6px;
  margin-bottom: 6px;
}

/* Card footer: category (Academic/Industry) on the left, subfield or
   program note on the right — sits below the bullets, always visible
   regardless of the card's expanded state. */
.entry-footer {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px dashed var(--rule);
}
.footer-role {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--accent-warm);
}
.footer-subtype { font-size: 13px; color: var(--muted); text-align: right; }

/* Education timeline reuses these */
.entry-role { font-weight: 600; }
.entry-dates {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}
.entry-org { color: var(--muted); font-size: 15px; margin-top: 2px; }
.entry-degree { color: var(--ink); font-size: 15px; margin-top: 4px; }
.entry-extra { color: var(--muted); font-size: 13.5px; margin-top: 3px; }

/* Collapsible bullet details — animated purely with CSS (grid track
   size), so the rest of the page reflows smoothly instead of jumping. */
.details-wrap {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.35s ease;
}
.details-wrap.is-open { grid-template-rows: 1fr; }
.details-inner { overflow: hidden; min-height: 0; }
.entry-details {
  margin: 10px 0 0;
  padding-left: 18px;
  color: var(--muted);
  font-size: 14px;
  list-style: none;
}
.entry-details li {
  position: relative;
  margin-bottom: 5px;
  padding-left: 4px;
}
.entry-details li::before {
  content: '\2013';
  position: absolute;
  left: -16px;
  color: var(--muted);
  font-family: 'JetBrains Mono', monospace;
}

/* Small role-progression list for a promotion within the same position —
   a mini version of the Education timeline (dot + connecting line), sits
   above the bullets with real space separating it from the overall dates.
*/
.role-progression {
  position: relative;
  margin: 12px 0;
  padding: 4px 0 14px 26px;
  border-bottom: 1px dashed var(--rule);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.role-progression::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 6px;
  bottom: 20px;
  width: 1px;
  background: var(--rule);
}
.role-progression-item { position: relative; }
.role-progression-marker {
  position: absolute;
  left: -26px;
  top: 3px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: transparent;
  border: 2px solid var(--accent-warm);
}
.role-progression-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 13.5px;
  color: var(--ink);
}
.role-progression .prog-dates {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  color: var(--muted);
  white-space: nowrap;
}

/* Simple line lists (teaching, awards) */
.line-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.line-list li {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.line-list .item-main { font-weight: 400; color: var(--ink); }
.line-list .item-code { font-weight: 600; color: var(--ink); }
.line-list .item-org { color: var(--muted); font-size: 14.5px; margin-top: 2px; }
.line-list .item-dates {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}

/* Below this width the date doesn't reliably fit next to the title on
   every row — rather than some rows wrapping and others not, force it
   onto its own line uniformly. */
@media (max-width: 480px) {
  #teaching-list li { flex-direction: column; align-items: flex-start; gap: 4px; }
}

/* Awards: year leads in its own aligned column, then the award text —
   a small table shape instead of the left-main/right-date pattern above. */
#awards-list li {
  display: flex;
  justify-content: flex-start;
  align-items: baseline;
  gap: 26px;
}
.award-year {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--muted);
  width: 40px;
  flex-shrink: 0;
}
.award-text { color: var(--ink); }
.award-text .item-code { font-weight: 600; color: var(--ink); }

/* Narrow screens: keep the year as its own column, but stack org and
   award name into two lines within the second column instead of
   letting them crowd onto one line. */
@media (max-width: 480px) {
  .award-text { display: flex; flex-direction: column; gap: 2px; }
}

/* Education timeline */
.timeline {
  position: relative;
  padding-left: 26px;
  display: flex;
  flex-direction: column;
  gap: 30px;
}
.timeline::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--rule);
}
.timeline-item { position: relative; }
.timeline-marker {
  position: absolute;
  left: -26px;
  top: 4px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: transparent;
  border: 2px solid var(--accent-warm);
}

/* Reveal-on-scroll: an entrance the first time each item
   comes into view, staggered slightly within its own list. */
.reveal {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* Section headings get a slightly more dramatic scale+rise entrance
   than list rows — a bigger gesture for a bigger element. */
.reveal-scale {
  opacity: 0;
  transform: translateY(16px) scale(0.93);
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(.2,.8,.2,1);
}
.reveal-scale.is-visible { opacity: 1; transform: translateY(0) scale(1); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .hero-intro, .reveal-scale { transition: none; opacity: 1; transform: none; }
  .scroll-cue { animation: none; }
  .details-wrap { transition: none; }
}

.back-to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease, color 0.15s, border-color 0.15s;
  z-index: 15;
}
.back-to-top svg { width: 17px; height: 17px; }
.back-to-top.is-visible { opacity: 1; transform: translateY(0); pointer-events: auto; }
.back-to-top:hover { color: var(--accent-warm); border-color: var(--accent-warm); }

/* ---------- Print ---------- */
@media print {
  /* Force a light, ink-friendly palette regardless of the active theme. */
  :root, [data-theme="dark"], [data-theme="light"] {
    --paper: #ffffff;
    --ink: #111111;
    --muted: #555555;
    --rule: #cccccc;
    --accent: #2E3B7C;
    --accent-warm: #8198b5;
  }
  body { font-size: 12.5px; }

  /* Drop all navigation/interactive chrome — none of it means anything
     on paper. */
  .topnav, .progress-bar, .theme-toggle, .scroll-cue, .back-to-top,
  .side-rail, .entry-chevron {
    display: none !important;
  }

  /* Hero: no full-viewport height, no ambient float animation, stack to
     one column so it isn't fighting for width against page margins. */
  .hero {
    min-height: auto;
    padding: 0 0 20px;
    border-bottom: 1px solid var(--rule);
  }
  .hero-columns { flex-direction: column; gap: 16px; }
  .hero-divider { display: none; }
  .hero-right { background: none; padding: 0; }
  .hero-graph .nodes circle { fill: #ffffff; stroke: var(--accent-warm); }
  .hero-graph .edges line { stroke: var(--accent); opacity: 0.4; }

  /* Full-bleed color bands read as plain white on paper — a thin top
     rule marks the section instead of spending ink on a tint. */
  .section-color { background: none; border-top: 1px solid var(--rule); }

  section { padding: 24px 0; border-top: 1px solid var(--rule); }

  /* Always show every card's bullets on paper, regardless of whatever
     was expanded/collapsed on screen — a printout should show everything. */
  .details-wrap { display: block !important; }
  .details-inner { overflow: visible !important; }
  .entry-toggle { cursor: default; }
  .entry-toggle:hover, .entry-toggle:focus-visible { background: none; border-left-color: transparent; }

  /* Cards read better as a single flowing column on paper than a grid. */
  .entry-grid { display: block; }
  .entry-grid .entry { margin-bottom: 16px; break-inside: avoid; }

  .pub-list li, .timeline-item, .entry { break-inside: avoid; }

  .reveal, .reveal-scale, .hero-intro { opacity: 1 !important; transform: none !important; }
}

/* Sticky side rails — social icons on the left, plaintext email on the
   right, both pinned while scrolling. Only shown where there's real
   margin outside the reading column to hold them without crowding it. */
.side-rail {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.side-rail.is-visible { opacity: 1; pointer-events: auto; }
.side-rail-left { left: 32px; }
.side-rail-right { right: 32px; }
.side-rail-line { width: 1px; height: 64px; background: var(--rule); }
.side-rail-icons { display: flex; flex-direction: column; gap: 12px; }
.side-rail-icons .icon-link { width: 30px; height: 30px; }
.side-rail-icons .icon-link svg { width: 14px; height: 14px; }

.side-rail-email {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--muted);
  background: none;
  border: none;
  padding: 4px 0;
  cursor: pointer;
  transition: color 0.15s;
}
.side-rail-email:hover, .side-rail-email:focus-visible { color: var(--accent-warm); }
.side-rail-email.is-copied { color: var(--accent-warm); }

@media (max-width: 1240px) {
  .side-rail { display: none; }
}