* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html { scroll-behavior: smooth; }

/* Fixed header would otherwise cover the heading you jumped to */
section { scroll-margin-top: 96px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

:root {
  --bg-color: #050507;
  --text-main: #ffffff;
  --text-sub: #cbd5e1;
  --text-dim: #64748b;
  --text-accent: #ddfd0a;
  --link-hover: #38bdf8;
  --link-hover-bg: rgba(56, 189, 248, 0.1);
  --border-line: rgba(255, 255, 255, 0.12);
  --border-hover: rgba(255, 215, 0, 0.5);
  --toggle-bg: rgba(10, 11, 18, 0.85);
  --toggle-border: rgba(255, 255, 255, 0.12);
  --toggle-active-bg: rgba(255, 215, 0, 0.12);
  --badge-bg: rgba(255, 255, 255, 0.05);
  --badge-border: rgba(255, 255, 255, 0.15);
  /* Entry headings: a muted sibling of --text-accent. Distinct from plain
     white, but well short of the accent, so it never competes with it. */
  --text-heading: #d7e9a6;
}

body.light-mode {
  --bg-color: #f8fafc;
  --text-main: #0f172a;
  --text-sub: #334155;
  --text-dim: #64748b;
  --text-accent: #c2410c;
  --link-hover: #0369a1; /* Deep, vivid Ocean Blue for punchy contrast */
  --link-hover-bg: rgba(3, 105, 161, 0.12);
  --border-line: rgba(15, 23, 42, 0.14);
  --border-hover: rgba(194, 65, 12, 0.6);
  --toggle-bg: rgba(255, 255, 255, 0.9);
  --toggle-border: rgba(15, 23, 42, 0.15);
  --toggle-active-bg: rgba(15, 23, 42, 0.08);
  --badge-bg: rgba(15, 23, 42, 0.04);
  --badge-border: rgba(15, 23, 42, 0.15);
  --text-heading: #7c3a12;
}
html {
  width: 100%;
  overflow-x: hidden;
  /* Deliberately no background here. --bg-color is redefined on
     body.light-mode, so a background on <html> would resolve it against :root
     and stay dark forever. Leaving <html> transparent lets the body's
     background propagate to the whole canvas instead - including the area past
     the end of a short page, and the overscroll region. */
}

body {
  width: 100%;
  min-height: 100vh;   /* not 100%: <html> has no definite height to resolve against */
  background-color: var(--bg-color);
  color: var(--text-main);
  font-family: 'JetBrains Mono', monospace;
  font-size: 18px;
  overflow-x: hidden;
}

canvas#feaCanvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  cursor: crosshair;
}

.text-shield {
  text-shadow: 
    0 0 10px var(--bg-color),
    0 0 20px var(--bg-color),
    0 0 30px var(--bg-color);
}

/* TOP HEADER BAR */
.top-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  padding: 16px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 100;
  pointer-events: none;
}

.top-affiliation {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.82rem;
  color: var(--text-dim);
  background: var(--toggle-bg);
  border: 1px solid var(--toggle-border);
  padding: 7px 14px;
  border-radius: 8px;
  letter-spacing: 0.02em;
  pointer-events: auto;
}
.top-affiliation span {
  color: var(--text-main);
  font-weight: 600;
}

/* CENTERED FIELD TOGGLE (PHI) */
.field-toggle-container {
  background: var(--toggle-bg);
  border: 1px solid var(--toggle-border);
  padding: 4px;
  border-radius: 8px;
  display: flex;
  gap: 4px;
  pointer-events: auto;
}

.toggle-btn {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-dim);
  font-size: 1.15rem;
  padding: 5px 13px;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: baseline;
  justify-content: center;
  font-family: "Computer Modern Serif", "Latin Modern Math", "Cambria Math", "Times New Roman", serif;
  font-style: italic;
  line-height: 1;
}
.toggle-btn .latex-phi {
  font-weight: 700;
  font-style: italic;
  font-size: 1.25rem;
  margin-right: 1px;
}

.toggle-btn sub {
  font-family: "Computer Modern Serif", "Latin Modern Roman", "Cambria", "Times New Roman", serif;
  font-style: normal;
  font-weight: 400;
  font-size: 0.72rem;
  bottom: -0.2em;
  position: relative;
}

.toggle-btn:hover { color: var(--text-main); }
.toggle-btn.active {
  background: var(--toggle-active-bg);
  color: var(--text-accent);
  border-color: var(--border-hover);
  font-weight: 700;
}

/* RIGHT-ALIGNED TOP NAV */
.nav-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  pointer-events: auto;
}

.top-nav {
  display: flex;
  gap: 0.3rem;
  background: var(--toggle-bg);
  border: 1px solid var(--toggle-border);
  padding: 4px 6px;
  border-radius: 8px;
  pointer-events: auto;
}

.top-nav-link {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-sub);
  text-decoration: none;
  padding: 5px 12px;
  border-radius: 6px;
  border: 1px solid transparent;
  transition: all 0.15s ease;
}

/* Bright, high-contrast hover */
.top-nav-link:hover {
  color: var(--text-accent);
  background-color: var(--toggle-active-bg);
  border-color: var(--border-hover);
  text-shadow: 0 0 8px var(--toggle-active-bg);
}

.mobile-menu-toggle {
  display: none;
  background: var(--toggle-bg);
  border: 1px solid var(--toggle-border);
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  flex-direction: column;
  gap: 4px;
}

.menu-bar {
  display: block;
  width: 18px;
  height: 2px;
  background-color: var(--text-main);
  transition: all 0.25s ease;
}

.hero-stage {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  min-height: 100svh;
  text-align: center;
  padding: 6.5rem 1.5rem 5.5rem;
  pointer-events: none;
}

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--text-dim);
  background: var(--badge-bg);
  border: 1px solid var(--badge-border);
  padding: 0.45rem 1.05rem;
  border-radius: 9999px;
  margin-bottom: 1.3rem;
}
.badge-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: #22c55e;
  box-shadow: 0 0 10px #22c55e;
}

h1.hero-title {
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(2.6rem, 8vw, 4.6rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  margin-bottom: 0.5rem;
  line-height: 1.05;
}

h1.hero-title .char {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.35em);
  animation: charIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes charIn {
  to { opacity: 1; transform: translateY(0); }
}

.hero-subtitle {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--text-accent);
  margin-bottom: 1rem;
  letter-spacing: -0.01em;
}

.hero-bio {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.02rem;
  color: var(--text-sub);
  max-width: 780px;
  line-height: 1.75;
  font-weight: 400;
  margin-bottom: 1.8rem;
}

/* HERO-BOUND SCROLL INDICATOR */
.scroll-indicator {
  position: absolute;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  color: var(--text-dim);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  pointer-events: auto;
  transition: opacity 0.3s ease, visibility 0.3s ease;
  animation: pulse 2s infinite;
}
.scroll-indicator.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
@keyframes pulse {
  0%, 100% { opacity: 0.4; transform: translate(-50%, 0); }
  50% { opacity: 1; transform: translate(-50%, 4px); }
}

.content-wrapper {
  position: relative;
  z-index: 2;
  max-width: 1100px;
  margin: 0 auto;
  padding: 4.5rem 1.5rem 9rem;
}

section { 
  margin-bottom: 6rem; 
}

.section-header {
  margin-bottom: 2.4rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-bottom: 1px solid var(--border-line);
  padding-bottom: 1rem;
}
.section-title {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 2.1rem;
  font-weight: 700;
  letter-spacing: -0.03em;
}
.section-tag {
  font-size: 0.88rem;
  color: var(--text-dim);
}

.pub-item {
  margin-bottom: 2.5rem;
  padding-bottom: 1.8rem;
  border-bottom: 1px dashed var(--border-line);
}
.pub-item:last-child { border-bottom: none; margin-bottom: 0; }
.pub-meta {
  display: flex;
  gap: 0.85rem;
  align-items: center;
  margin-bottom: 0.55rem;
  font-size: 0.88rem;
}
.pub-journal { color: var(--text-accent); font-weight: 600; }
.pub-year { color: var(--text-dim); }
.pub-title {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.45;
  margin-bottom: 0.55rem;
  color: var(--text-heading);
}
.pub-authors {
  font-size: 0.98rem;
  color: var(--text-sub);
  margin-bottom: 1rem;
  line-height: 1.55;
}
.pub-authors strong { color: var(--text-main); }
.pub-links { display: flex; gap: 0.75rem; flex-wrap: wrap; }
/* Button & Link Hover Styles */
.btn-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 1rem;
  border-radius: 6px;
  background: var(--toggle-bg);
  border: 1px solid var(--border-line);
  color: var(--text-main);
  text-decoration: none;
  font-size: 0.88rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.18s ease;
}

.btn-link:hover {
  border-color: var(--link-hover);
  color: var(--link-hover);
  background-color: var(--link-hover-bg);
  font-weight: 600;
  box-shadow: 0 0 10px var(--link-hover-bg);
}

.projects-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 2.5rem;
}

/* Research projects and code repos run two-up: three across is too cramped
   for cards carrying a description plus pills plus links. Teaching entries are
   short enough to stay three-up. */
#projects .projects-grid,
#code .projects-grid {
  grid-template-columns: repeat(2, 1fr);
}
@media (max-width: 760px) {
  #projects .projects-grid,
  #code .projects-grid { grid-template-columns: 1fr; }
}

/* Bottom-aligning the pills only lines up their last row, so a card whose
   pills wrap to two lines starts one row higher than its neighbours. Subgrid
   makes every card in a row share the same two track heights, so the pill
   block starts at the same y no matter how many pills each card carries. */
@supports (grid-template-rows: subgrid) {
  .projects-grid > .project-entry {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 2;
  }
}
.project-entry {
  border-left: 2px solid var(--border-line);
  padding-left: 1.4rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.project-num {
  font-size: 0.85rem;
  color: var(--text-accent);
  font-weight: 600;
  margin-bottom: 0.4rem;
}
.project-title {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.35rem;
  font-weight: 700;
  margin-bottom: 0.6rem;
  color: var(--text-heading);
}
.project-desc {
  font-size: 0.98rem;
  color: var(--text-sub);
  line-height: 1.65;
  margin-bottom: 1.2rem;
}
.tool-pills { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.tool-pill {
  font-size: 0.8rem;
  padding: 0.25rem 0.65rem;
  border-radius: 4px;
  background: var(--badge-bg);
  border: 1px solid var(--badge-border);
  color: var(--text-dim);
}

.cv-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3.5rem;
}

.cv-col-title {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.15rem;
  font-weight: 700;
  margin-bottom: 1.8rem;
  color: var(--text-accent);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.cv-item {
  margin-bottom: 1.8rem;
  border-left: 2px solid var(--border-line);
  padding-left: 1.25rem;
}
.cv-role {
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--text-main);
}
.cv-institution {
  font-size: 0.95rem;
  color: var(--text-sub);
  margin: 0.3rem 0;
}
.cv-status {
  font-size: 0.85rem;
  color: var(--text-accent);
  font-weight: 500;
}

.contact-container {
  border-left: 2px solid var(--border-line);
  padding-left: 1.4rem;
}

footer {
  border-top: 1px solid var(--border-line);
  padding-top: 2.5rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.88rem;
  color: var(--text-dim);
}

@media (max-width: 1024px) {
  .top-header {
    flex-wrap: wrap;
    gap: 8px;
    justify-content: space-between;
    padding: 12px 16px;
  }
  .top-affiliation { display: none; }
}

@media (max-width: 768px) {
  body, html { font-size: 16px; }
  .cv-grid { grid-template-columns: 1fr; gap: 2rem; }
  h1.hero-title { font-size: 3rem; }
  .top-nav { display: none; }
}

.repo-title-link {
  color: var(--text-heading);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  transition: color 0.18s ease, text-shadow 0.18s ease;
}

.repo-title-link:hover {
  color: var(--link-hover);
  text-shadow: 0 0 12px rgba(56, 189, 248, 0.35);
}

.repo-title-link .ext-arrow {
  font-size: 1.1rem;
  color: var(--text-dim);
  transition: transform 0.18s ease, color 0.18s ease;
}

.repo-title-link:hover .ext-arrow {
  color: var(--link-hover);
  transform: translate(2px, -2px);
}

.status-pill {
  color: #22c55e;
  font-size: 0.78rem;
  font-weight: 500;
  background: rgba(34, 197, 94, 0.1);
  border: 1px solid rgba(34, 197, 94, 0.25);
  padding: 2px 7px;
  border-radius: 9999px;
  display: inline-block;
  vertical-align: middle;
}



.btn-link .btn-icon {
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
  transition: transform 0.18s ease;
}

.btn-link:hover .btn-icon {
  transform: scale(1.1);
}

.hero-subtitle .sub-sep {
  margin: 0 1rem;
  color: var(--text-accent);
  font-size: 1.1em;
  vertical-align: middle;
}

/* ============================================================
   LANDING PAGE  —  hero additions
   ============================================================ */

/* Rotating role + blinking caret */
/* Three-column grid keeps the bullet pinned to the centre, so characters
   appearing and disappearing on the right never nudge the whole line. */
.hero-subtitle {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: 1.9em;
}
.hero-subtitle .sub-fixed { justify-self: end; }
.sub-rotate-wrap {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.type-caret {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  background: var(--text-accent);
  margin-left: 3px;
  vertical-align: text-bottom;
  animation: caretBlink 1.05s steps(1) infinite;
}
@keyframes caretBlink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* ============================================================
   PORTRAIT
   ============================================================ */
.hero-portrait {
  position: relative;
  width: 200px;
  height: 200px;
  margin-bottom: 1.8rem;
  flex-shrink: 0;
  pointer-events: auto;
}

.hero-portrait img {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  /* the cutout is transparent, so the disc behind it follows the theme */
  background: var(--bg-color);
  /* The inner ring of --bg-color separates the photo from the live mesh */
  box-shadow:
    0 0 0 5px var(--bg-color),
    0 0 0 6px var(--border-line),
    0 14px 44px rgba(0, 0, 0, 0.45);
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.4s ease;
}

.hero-portrait:hover img {
  transform: scale(1.04);
  box-shadow:
    0 0 0 5px var(--bg-color),
    0 0 0 6px var(--border-hover),
    0 14px 54px rgba(0, 0, 0, 0.5);
}

/* Two counter-rotating rings, echoing the orbit lines drawn on the canvas */
.portrait-ring {
  position: absolute;
  inset: -14px;
  border-radius: 50%;
  border: 1px dashed var(--border-hover);
  opacity: 0.45;
  animation: ringSpin 30s linear infinite;
}
.portrait-ring-outer {
  inset: -38px;
  border-style: dotted;
  border-color: var(--border-line);
  opacity: 0.7;
  animation: ringSpin 46s linear infinite reverse;
}
@keyframes ringSpin {
  to { transform: rotate(360deg); }
}

/* ============================================================
   ORBITING CONSTITUTIVE EQUATIONS
   ============================================================ */
.orbit-layer {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  transition: opacity 0.4s ease;
}
.orbit-layer.hidden { opacity: 0; }

.orbit-eq {
  position: absolute;
  top: 0;
  left: 0;
  white-space: nowrap;
  font-size: 0.98rem;
  color: var(--text-accent);
  opacity: 0;
  will-change: transform, opacity;
  /* transform and opacity are written every frame by background.js */
}

/* The two widest expressions are set smaller so their orbits stay on screen.
   Orbit radius is derived from measured width, so this directly controls how
   far Jupiter and Saturn throw their equations. */
.orbit-eq[data-body="Jupiter"] { font-size: 0.86rem; }
.orbit-eq[data-body="Saturn"]  { font-size: 0.88rem; }

/* Small monospace tag under each equation, e.g. "J2 yield" */
.orbit-eq::after {
  content: attr(data-label);
  display: block;
  margin-top: 3px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  text-align: center;
}

/* Below 1100px the two widest expressions cannot orbit without running off
   both edges at once (the virtual-work integral alone renders ~430px wide), so
   they are dropped and the remaining eight shrink. A hidden element measures
   zero wide, and the orbit loop already skips anything it cannot measure, so
   this rule alone is enough to take them out of the simulation. */
@media (max-width: 1100px) {
  .orbit-eq[data-body="Jupiter"],
  .orbit-eq[data-body="Saturn"] { display: none; }

  .orbit-eq { font-size: 0.72rem; }
  /* The captions are wider than the equations they label at this size */
  .orbit-eq::after { display: none; }
}

@media (max-width: 700px) {
  .orbit-eq { font-size: 0.62rem; }
}


@media (max-width: 768px) {
  .hero-portrait {
    width: 148px;
    height: 148px;
    margin-bottom: 1.5rem;
  }
  .portrait-mode { inset: -25px; }
  .portrait-ring-outer { inset: -32px; }
  .hero-subtitle {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    font-size: 1.1rem;
  }
  .hero-subtitle .sub-fixed { justify-self: auto; }
  .hero-subtitle .sub-sep { display: none; }
  .sub-rotate-wrap { justify-self: auto; }
  footer { flex-direction: column; gap: 0.6rem; text-align: center; }
  .section-header { flex-direction: column; align-items: flex-start; gap: 0.5rem; }

  /* Mobile navigation: reveal the hamburger and drop the menu below it */
  .mobile-menu-toggle { display: flex; }

  .top-nav {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    min-width: 190px;
    padding: 8px;
    border-radius: 10px;
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.35);
  }
  .top-nav.open { display: flex; }
  .top-nav-link { padding: 9px 12px; }
}


/* ============================================================
   MECHANICS DETAILING
   ============================================================ */

/* --- Nav underline drawn as a quadratic Lagrange shape function --- */
.top-nav-link { position: relative; }
.top-nav-link::after {
  content: '';
  position: absolute;
  left: 9px;
  right: 9px;
  bottom: 1px;
  height: 7px;
  background: currentColor;
  opacity: 0;
  transform: scaleY(0.35);
  transform-origin: bottom center;
  transition: opacity 0.18s ease, transform 0.18s ease;
  pointer-events: none;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 12' preserveAspectRatio='none'%3E%3Cpath d='M0.0 11.00 L3.1 9.91 L6.2 8.89 L9.4 7.94 L12.5 7.06 L15.6 6.25 L18.8 5.52 L21.9 4.85 L25.0 4.25 L28.1 3.72 L31.2 3.27 L34.4 2.88 L37.5 2.56 L40.6 2.32 L43.8 2.14 L46.9 2.04 L50.0 2.00 L53.1 2.04 L56.2 2.14 L59.4 2.32 L62.5 2.56 L65.6 2.88 L68.8 3.27 L71.9 3.72 L75.0 4.25 L78.1 4.85 L81.2 5.52 L84.4 6.25 L87.5 7.06 L90.6 7.94 L93.8 8.89 L96.9 9.91 L100.0 11.00' fill='none' stroke='white' stroke-width='1.5'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 12' preserveAspectRatio='none'%3E%3Cpath d='M0.0 11.00 L3.1 9.91 L6.2 8.89 L9.4 7.94 L12.5 7.06 L15.6 6.25 L18.8 5.52 L21.9 4.85 L25.0 4.25 L28.1 3.72 L31.2 3.27 L34.4 2.88 L37.5 2.56 L40.6 2.32 L43.8 2.14 L46.9 2.04 L50.0 2.00 L53.1 2.04 L56.2 2.14 L59.4 2.32 L62.5 2.56 L65.6 2.88 L68.8 3.27 L71.9 3.72 L75.0 4.25 L78.1 4.85 L81.2 5.52 L84.4 6.25 L87.5 7.06 L90.6 7.94 L93.8 8.89 L96.9 9.91 L100.0 11.00' fill='none' stroke='white' stroke-width='1.5'/%3E%3C/svg%3E");
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
.top-nav-link:hover::after,
.top-nav-link.active::after {
  opacity: 0.85;
  transform: scaleY(1);
}

/* --- Section rules: a plain hairline under every section heading --- */
.section-header {
  position: relative;
  border-bottom: 1px solid var(--border-line);
  padding-bottom: 1rem;
}

/* --- Portrait: n = 3 ring eigenmode replacing the inner dashed ring --- */
.portrait-mode {
  position: absolute;
  inset: -28px;              /* path radius is 0.44 of the box, so this inset
                                holds a ~13px gap outside a 200px portrait */
  color: var(--border-hover);
  opacity: 0.55;
  overflow: visible;
  pointer-events: none;
}

/* ============================================================
   CANVAS INTERACTION HINT (bottom-right)
   ============================================================ */
.canvas-hint {
  position: fixed;
  right: 22px;
  bottom: 20px;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.85rem;
  border-radius: 8px;
  border: 1px solid var(--toggle-border);
  background: var(--toggle-bg);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.72rem;
  color: var(--text-dim);
  letter-spacing: 0.02em;
  pointer-events: none;
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.canvas-hint.hidden {
  opacity: 0;
  transform: translateY(10px);
}
.canvas-hint kbd {
  font-family: inherit;
  font-size: 0.68rem;
  color: var(--text-accent);
  background: var(--badge-bg);
  border: 1px solid var(--badge-border);
  border-radius: 4px;
  padding: 0.1rem 0.42rem;
}
.canvas-hint .hint-sep { color: var(--border-line); }

@media (max-width: 900px) {
  .canvas-hint { display: none; }
}
