/* Shared chrome only. Research figures, photographs and data colors stay page-owned. */
:root {
  --site-gutter: clamp(16px, 3vw, 40px);
  --site-width: 1344px;
}
html { scrollbar-gutter: stable; }
html:not([data-theme="light"]) { color-scheme: dark; }
body { -webkit-font-smoothing: antialiased; }
:where(button, input, select, textarea) { font: inherit; }
:where(button, a) { -webkit-tap-highlight-color: transparent; }
:where(h1, h2, h3) { text-wrap: balance; }
:where(p, figcaption) { text-wrap: pretty; }
.skip {
  position: fixed; top: -100px; left: 16px; z-index: 1100;
  padding: 12px 18px; border-radius: 8px;
  background: var(--ink, var(--text)); color: var(--bg);
}
.skip:focus { top: 12px; }
.theme-toggle {
  min-height: 44px;
  bottom: max(20px, env(safe-area-inset-bottom));
}
.project-page .wrap {
  width: 100%; max-width: var(--site-width);
  padding-inline: var(--site-gutter);
}
.project-page .topnav {
  position: relative; inset: auto; transform: none;
  width: calc(100% - 2 * var(--site-gutter)); max-width: 1264px;
  margin: 16px auto 0; padding: 10px 0;
  display: flex; align-items: center; gap: 24px;
  border: 0; border-bottom: 1px solid var(--border);
  border-radius: 0; box-shadow: none; background: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
html[data-theme="light"] .project-page .topnav {
  background: transparent !important; box-shadow: none;
}
.project-page .brand { min-width: 0; margin-right: auto; }
.project-page .monogram { flex-shrink: 0; }
.project-page .topnav :is(.navlink, .contact) {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; flex-shrink: 0; font-size: 12px;
  transition: color .18s ease, background .18s ease, border-color .18s ease;
}
.project-page .contact { padding: 8px 16px; font-weight: 500; }
.project-page .topnav .navlink:hover { color: var(--ink); }
.project-page .topnav .contact:hover { border-color: var(--accent); }
.project-page .brand { letter-spacing: -.015em; }
.project-page .monogram { width: 34px; height: 34px; border-radius: 10px; }
.project-page :is(.intro-line, .section-heading) > * { min-width: 0; }
.project-page .intro-meta { flex-wrap: wrap; row-gap: 8px; font-size: 11px; }
.project-page .intro h1 { overflow-wrap: anywhere; }
.project-page .intro .lede { text-wrap: pretty; }
.project-page .section-heading h2 { letter-spacing: -.035em; line-height: 1.2; }
.project-page .rail {
  display: flex; gap: 24px; margin: 0 0 24px; padding: 0;
  border-block: 1px solid var(--border);
  min-width: 0; max-width: 100%; flex-wrap: wrap;
  overflow-x: visible; justify-content: flex-start;
  scrollbar-width: thin; scrollbar-color: var(--border2, #666) transparent;
  scroll-padding-inline: 8px;
}
.project-page .rail a {
  flex: 0 0 auto; min-height: 44px;
  display: inline-flex; align-items: center; padding: 10px 0;
  font: 500 12px/1.5 'DM Sans', sans-serif;
  color: var(--muted); text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.project-page .rail a:hover { color: var(--ink); border-bottom-color: var(--border2, var(--muted)); }
.project-page .rail a[aria-current="true"] { color: var(--ink); border-bottom-color: var(--accent); }
.project-page .case-section { scroll-margin-top: 24px; }
.project-page .rail ~ section { scroll-margin-top: 24px; }
.project-page :is(.back, .source-link, .source-row a, footer a) {
  min-height: 44px; display: inline-flex; align-items: center;
}
.project-page :is(.back, .source-link, .source-row a, footer a):hover {
  text-decoration: underline; text-underline-offset: 5px;
}
.project-page footer { flex-wrap: wrap; gap: 16px 24px; padding-bottom: 88px; }
.project-page :is(.context-line, .source-row) { flex-wrap: wrap; }
.project-page :is(.intro-meta, .context-line, .section-heading, footer) { overflow-wrap: anywhere; }
.project-page :is(th, td, dd, .stat, .metric) { font-variant-numeric: tabular-nums; }

/* Let content shrink inside grid/flex tracks instead of widening the page.
   Do not constrain Leaflet's internal canvases or the deliberately zoomed viewer. */
.project-page .wrap :where(section, article, div, figure, aside, dl),
.portfolio-home :where(.bottom-grid, .skills-panel, .timeline-content) { min-width: 0; }
.project-page :where(p, li, dd, dt, figcaption, h2, h3, h4, a),
.portfolio-home :where(.badge, .timeline-role, .timeline-place, .card-footer-small) { overflow-wrap: anywhere; }
.project-page :where(input, select, textarea, button) { max-width: 100%; min-width: 0; }
.project-page :where(.context-line, .source-row, .rail) > a { max-width: 100%; white-space: normal; }
.project-page .rail { column-gap: clamp(12px, 2.2vw, 30px); row-gap: 0; }
.project-page .topnav { flex-wrap: wrap; }
.project-page .brand { overflow-wrap: anywhere; }
.project-page .wrap :where(figure > img, figure > a > img, video, iframe) { max-width: 100%; }
.project-page .nmd-viewer[data-zoom='true'] .viewer-image-wrap img { max-width: none; }

/* Keep real table headers and comfortable columns instead of mobile pseudo-labels. */
.project-page .evidence-scroll { min-width: 0; max-width: 100%; overflow-x: auto; scrollbar-width: thin; }
.project-page .evidence-scroll table { width: 100%; min-width: 640px; }
.project-page .evidence-scroll td::before { content: none; }
.table-scroll-hint { display: none; color: var(--muted); font: 11px/1.6 'DM Mono', monospace; }
@media (max-width: 850px) { .table-scroll-hint { display: block; margin-top: 8px; } }

/* Scientific plots keep their coordinates and readable labels. Only the plot
   scrolls; captions, controls, readouts and the document remain fluid. */
.project-page .plot-scroll { max-width: 100%; min-width: 0; overflow-x: auto; padding-block: 8px; scrollbar-width: thin; }
.project-page .plot-scroll > svg { display: block; width: 100%; min-width: 720px; height: auto; }
.project-page .plot-scroll > #allocation-chart { min-width: 620px; }
.project-page .plot-scroll > #community-sweep { min-width: 440px; }
.project-page .plot-scroll > :is(#activity-chart, #net-chart) { min-width: 540px; }
.project-page .plot-scroll:has(> svg[hidden]),
.project-page .plot-scroll:has(> svg[hidden]) + .plot-scroll-hint { display: none; }
.project-page .plot-scroll-hint { margin: 8px 0 12px; color: var(--muted); font: 11px/1.6 'DM Sans', sans-serif; }
.project-page .plot-scroll:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
/* These plots no longer scale down to the mobile viewport: reset the old
   viewport-based text enlargement, which would now overlap adjacent labels. */
.project-page .plot-scroll > #chart text,
.project-page .plot-scroll > #chart > text:first-of-type { font-size: 14px; }
.project-page .plot-scroll > :is(#allocation-chart, #activity-chart, #net-chart,
  #contrast-chart, #concentration-chart, #kcore-chart, #ccdf-chart,
  #centrality-scatter, #community-sweep, #resilience-chart, #exposure-chart) text { font-size: 14px; }
.project-page .plot-scroll > :is(#ccdf-chart, #centrality-scatter, #kcore-chart,
  #community-sweep, #resilience-chart) :is(.axis-title, .centrality-label) { font-size: 14px; }

/* Compact homepage: content determines height, not a viewport or JS measurement. */
.portfolio-home .bento { grid-template-rows: auto; gap: 16px; }
.portfolio-home .bottom-grid { height: auto; gap: 16px; }
.portfolio-home .card {
  border-color: rgba(255,255,255,.13);
  background: linear-gradient(145deg, rgba(255,255,255,.035), transparent 65%), rgba(18,18,18,.8);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 12px 32px rgba(0,0,0,.22);
}
.portfolio-home .card-label { color: var(--muted2); font-size: 11px; font-weight: 500; letter-spacing: .09em; }
.portfolio-home .hero-name { font-size: clamp(25px, 2.2vw, 30px); letter-spacing: -.045em; }
.portfolio-home .hero-text { font-size: 13px; line-height: 1.7; }
.portfolio-home .hero-avatar img { border-radius: 16px; }
.portfolio-home .card-profile .hero-gif img { height: 120px; }
.portfolio-home .project-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.portfolio-home .project-box { min-height: 112px; padding: 12px; gap: 14px; background: rgba(255,255,255,.025); border-color: rgba(255,255,255,.09); }
.portfolio-home .project-box-name { justify-content: space-between; font-size: 14px; letter-spacing: -.02em; line-height: 1.35; }
.portfolio-home .project-box-name > span { transition: transform .18s ease, color .18s ease; }
.portfolio-home .project-box-meta { font-size: 11px; line-height: 1.5; }
.portfolio-home .project-emoji { width: 31px; height: 31px; background: transparent; }
.portfolio-home .project-box:hover { transform: none; border-color: var(--accent-border); background: var(--accent-soft); }
.portfolio-home .project-box:hover .project-box-name > span { transform: translate(2px, -2px); }
.portfolio-home .skills-grid { grid-auto-rows: minmax(30px, auto); align-content: start; }
.portfolio-home .skill-item { font-size: 11px; }
.portfolio-home .skills-tabs { gap: 4px; padding-bottom: 10px; border-bottom: 1px solid var(--card-border); }
.portfolio-home .skills-tab { font-size: 11px; border-radius: 8px; }
.portfolio-home :is(.skills-tab, .lang-btn) { min-height: 36px; }
.portfolio-home .skills-tab.active { box-shadow: inset 0 -2px 0 currentColor; }
.portfolio-home .lang-btn.active { font-weight: 500; }
.portfolio-home .timeline-role { font-size: 12.5px; }
.portfolio-home .timeline-content { padding-bottom: 10px; }
.portfolio-home .timeline-year { letter-spacing: -.02em; }
.portfolio-home .social-btn { min-width: 44px; min-height: 44px; }
.portfolio-home .lang-toggle { top: 12px; }
@media (min-width: 721px) {
  .portfolio-home .project-grid { flex: 1; grid-auto-rows: minmax(112px, 1fr); }
}

@media (max-width: 700px) {
  .project-page .topnav { margin-top: 8px; gap: 12px; }
  .project-page .topnav .navlink { display: none; }
  .project-page .brand { font-size: 11px; gap: 8px; }
  .project-page .rail { gap: 0 20px; }
  .project-page .rail a { font-size: 12px; }
  .project-page .intro-meta { font-size: 11px; }
  .project-page .context-line { font-size: 11px; line-height: 1.8; }
  .portfolio-home .project-box { padding: 11px; }
  .portfolio-home .project-box-name { font-size: 13px; }
  .portfolio-home :is(.skills-tab, .lang-btn) { min-height: 44px; }
  .portfolio-home .lang-toggle { top: 8px; }
}
/* Reflow compact cards when their own available width is narrow. */
.portfolio-home :is(.project-index, .card-skills) { container-type: inline-size; }
@container (max-width: 220px) {
  .portfolio-home :is(.project-grid, .skills-grid) { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 380px) {
  .portfolio-home .hero-top { flex-wrap: wrap; }
  .portfolio-home .badge { max-width: 100%; }
  .portfolio-home .badge-dot { flex-shrink: 0; }
  .project-page .intro-line { flex-wrap: wrap; }
}
@media (max-height: 500px) {
  .project-page .rail { position: static; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto !important; }
  .portfolio-home *, .portfolio-home *::before, .portfolio-home *::after {
    animation: none !important; transition: none !important;
  }
  .portfolio-home :is(.project-box, .social-btn):hover,
  .theme-toggle:hover { transform: none; }
  .portfolio-home .project-box:hover .project-box-name > span { transform: none; }
  .project-page .topnav :is(.navlink, .contact), .project-page .rail a { transition: none; }
  /* The decorative GIF cannot be paused by CSS. Keep it out of reduced-motion views. */
  .portfolio-home .hero-gif { display: none; }
}
