/* ==========================================================================
   Academic Portfolio UI Redesign - Scientific & Academic Aesthetic
   Author: Antigravity AI Codebase Redesigner
   Description: Academic website layout (content: Uman Khalid)
   ========================================================================== */

/* ==========================================================================
   CSS Variables & Design System Tokens
   ========================================================================== */

:root {
  /* Colour palette - light mode.
     One blue carries links and active controls; deep ink carries headings.
     Purple and cyan accents were removed so nothing competes with the blue.
     Status and institutional colours (success, brand marks) stay as they are,
     because there the colour is the information. */
  --primary-color: #183247; /* Deep navy - solid fills and UI accents */
  --primary-color-rgb: 24, 50, 71;
  --secondary-color: #245f87; /* The one blue: links and active controls */
  --secondary-color-rgb: 36, 95, 135;
  --accent-color: #245f87; /* Same blue - kept as a token for existing rules */
  --accent-color-rgb: 36, 95, 135;
  --secondary-hover: #17415e; /* Darker blue for hover and pressed states */
  --success-color: #0d7a6f; /* Meaningful status colour, retained */
  --bg-primary: #f5f7f8; /* Pale grey page */
  --bg-secondary: #ffffff; /* Card surface */
  --bg-tertiary: #edf1f4; /* Inset wells, icon tiles, table stripes */
  --text-primary: #15222d; /* Deep ink - headings and emphasis. Near-black
                               with a navy cast so it sits with the palette
                               instead of punching holes in it. */
  --text-secondary: #465563; /* Slate body copy */
  --text-muted: #6b7a88; /* Labels and captions */
  --border-color: #dce3e8; /* Light grey */
  /* Hover borders are a plain tint now, not a glow */
  --border-glow: rgba(36, 95, 135, 0.38);
  --shadow-color: rgba(24, 50, 71, 0.06);
  --shadow-lg: rgba(24, 50, 71, 0.1);
  --glass-bg: rgba(255, 255, 255, 0.88);
  --glass-border: rgba(255, 255, 255, 0.95);
  /* Navy wash over every cover image, so white titles stay legible */
  --cover-overlay-top: rgba(24, 50, 71, 0.5);
  --cover-overlay-bottom: rgba(24, 50, 71, 0.74);

  /* Categorical palette for the collaboration network: one muted hue per
     organisation or country, in print-like tones rather than neon. */
  --collab-c0: #2b6a99;
  --collab-c1: #c27c2c;
  --collab-c2: #3a8a74;
  --collab-c3: #8b5aa0;
  --collab-c4: #b24f45;
  --collab-c5: #5d7a96;
  --collab-c6: #7d8a36;
  --collab-c7: #a0667a;

  /* Elevation - cards rest almost flat; only overlays cast a real shadow.
     1 = resting card, 2 = raised/active, 3 = overlay (modals, popovers). */
  --elev-1: 0 1px 2px rgba(24, 50, 71, 0.05);
  --elev-2: 0 1px 2px rgba(24, 50, 71, 0.06), 0 4px 10px var(--shadow-color);
  --elev-3: 0 8px 20px rgba(24, 50, 71, 0.12), 0 24px 56px var(--shadow-lg);

  /* Spacing scale - 4px base. Use these instead of literal pixel values. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* Typefaces. A text serif for display headings and titles gives the page
     an academic voice; Inter carries body copy, card headings and UI; the
     mono face is kept for dates, codes and metadata. */
  --font-serif: "Source Serif 4", "Source Serif Pro", Georgia, "Times New Roman", serif;
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Consolas, monospace;

  /* Type scale. Headings use clamp() so they scale with the viewport
     instead of stepping only at breakpoints. */
  --text-xs: 0.75rem;
  --text-sm: 0.85rem;
  --text-base: 0.95rem;
  --text-md: 1.05rem;
  --text-lg: clamp(1.1rem, 0.3vw + 1.03rem, 1.25rem);
  --text-xl: clamp(1.25rem, 0.6vw + 1.1rem, 1.5rem);
  --text-2xl: clamp(1.5rem, 1vw + 1.25rem, 1.9rem);
  --text-3xl: clamp(1.9rem, 2vw + 1.4rem, 2.6rem);

  /* Transitions */
  --transition-fast: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
  --transition-normal: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  --transition-slow: 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  --transition-interactive:
    background-color var(--transition-normal),
    border-color var(--transition-normal), color var(--transition-normal),
    box-shadow var(--transition-normal), opacity var(--transition-normal),
    transform var(--transition-normal);
  --transition-interactive-fast:
    background-color var(--transition-fast),
    border-color var(--transition-fast), color var(--transition-fast),
    box-shadow var(--transition-fast), opacity var(--transition-fast),
    transform var(--transition-fast);

  /* Fixed header height - measured at runtime by script.js, fallback below */
  --header-height: 66px;

  /* Border Radii */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 12px;
  --radius-xl: 16px;
}

[data-theme="dark"] {
  /* Colour palette - dark mode. Slate rather than black, with one muted
     light blue standing in for the light theme's single blue. */
  --primary-color: #8dbcdc; /* Muted light blue */
  --primary-color-rgb: 141, 188, 220;
  --secondary-color: #8dbcdc; /* Links and active controls */
  --secondary-color-rgb: 141, 188, 220;
  --accent-color: #8dbcdc; /* Same blue - no purple in dark mode either */
  --accent-color-rgb: 141, 188, 220;
  --secondary-hover: #b4d5ec; /* Lighter blue for hover and pressed states */
  --success-color: #3fb8a5; /* Meaningful status colour, retained */
  --bg-primary: #14212b; /* Slate page */
  --bg-secondary: #1c2d39; /* Card surface */
  --bg-tertiary: #24394a; /* Inset wells and icon tiles */
  --text-primary: #f1f5f7; /* Off-white */
  --text-secondary: #c3cfd8; /* Body copy */
  --text-muted: #93a3af; /* Labels and captions */
  --border-color: #2c3e4c; /* Dark border */
  --border-glow: rgba(141, 188, 220, 0.42);
  --shadow-color: rgba(0, 0, 0, 0.35);
  --shadow-lg: rgba(0, 0, 0, 0.5);
  --glass-bg: rgba(28, 45, 57, 0.82);
  --glass-border: rgba(255, 255, 255, 0.06);
  --cover-overlay-top: rgba(11, 21, 29, 0.52);
  --cover-overlay-bottom: rgba(11, 21, 29, 0.78);

  /* Lighter tints of the same network hues for the dark surface */
  --collab-c0: #6fa8d6;
  --collab-c1: #e0a55a;
  --collab-c2: #6cc0a6;
  --collab-c3: #b98fd0;
  --collab-c4: #e08378;
  --collab-c5: #93adc6;
  --collab-c6: #b3bf63;
  --collab-c7: #cf95aa;

  /* Same restraint as light mode: flat at rest, depth only for overlays. */
  --elev-1: 0 1px 2px rgba(0, 0, 0, 0.28);
  --elev-2: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 10px var(--shadow-color);
  --elev-3: 0 8px 24px rgba(0, 0, 0, 0.45), 0 24px 56px var(--shadow-lg);
}

/* ==========================================================================
   Reset & Base Styles
   ========================================================================== */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-height);
}

body {
  font-family: var(--font-sans);
  font-feature-settings: "cv11", "ss01";
  line-height: 1.7;
  color: var(--text-secondary);
  background-color: var(--bg-primary);
  min-height: 100vh;
  opacity: 0;
  transition:
    opacity 0.5s ease,
    background-color var(--transition-normal),
    color var(--transition-normal);
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.loaded {
  opacity: 1;
}

/* Static architectural grid, kept behind all page content. */
body {
  isolation: isolate;
}

.grid-background {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background: var(--bg-primary);
}

.grid-background canvas {
  display: block;
  width: 100%;
  height: 100%;
}

@media print {
  .grid-background { display: none; }
}

/* Scrollbar styling */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: var(--bg-primary);
}
::-webkit-scrollbar-thumb {
  background: var(--border-color);
  border-radius: var(--radius-sm);
  border: 2px solid var(--bg-primary);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

/* ==========================================================================
   Typography Rules
   ========================================================================== */

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-serif);
  font-weight: 600;
  font-optical-sizing: auto;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  line-height: 1.25;
}

/* Sub-headings mostly title cards and list items, where the serif gets
   fussy at small sizes; they switch to the UI face. */
h3,
h4,
h5,
h6 {
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: -0.011em;
  line-height: 1.35;
}

strong,
b {
  color: var(--text-primary);
}

h1 {
  font-size: var(--text-3xl);
}
h2 {
  font-size: var(--text-2xl);
}
h3 {
  font-size: var(--text-xl);
}
h4 {
  font-size: var(--text-lg);
}

p {
  color: var(--text-secondary);
  margin-bottom: 1rem;
  text-align: left;
}

/*
  Running prose is capped at roughly 72 characters. Applied to the paragraph
  classes rather than to every <p>, so table cells, captions and chips that
  happen to use <p> keep the width of their container. .bio-text is deliberately
  left out - see below.
*/
.tool-description,
.news-summary,
.activity-description {
  max-width: 72ch;
}

a {
  color: var(--secondary-color);
  text-decoration: none;
  transition: color var(--transition-fast);
}

a:hover {
  color: var(--secondary-hover);
}

/* Underline on hover is for links sitting in running text, where colour alone
   is a weak signal. Buttons, chips and icon links keep their own treatment. */
p a:hover,
.bio-text a:hover,
li a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible {
  outline: 2px solid var(--secondary-color);
  outline-offset: 3px;
}

.bold {
  font-weight: 600;
  color: var(--text-primary);
}

/* ==========================================================================
   Header & Sticky Navigation (Glassmorphic)
   ========================================================================== */

.header-wrapper {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 1000;
  background: var(--glass-bg);
  border-bottom: 1px solid var(--border-color);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

.header-wrapper.scrolled {
  box-shadow: var(--elev-2);
  border-color: var(--border-glow);
}

.header {
  max-width: 1600px;
  margin: 0 auto;
  padding: 12px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
}

/* Logo area */
.site-logo {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  font-family: var(--font-serif);
}

.logo-name {
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--text-primary);
  transition: color var(--transition-fast);
}

.site-logo:hover .logo-name {
  color: var(--secondary-color);
}

/* Nav Menu */
.nav-menu {
  display: flex;
  gap: 4px;
  align-items: center;
}

.nav-btn {
  padding: 8px 14px;
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 500;
  font-size: 0.88rem;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: var(--transition-interactive);
}

.nav-btn i {
  font-size: 0.95rem;
}

.nav-btn:hover {
  background: var(--bg-tertiary);
  color: var(--secondary-color);
}

.nav-btn.active {
  background: var(--bg-tertiary);
  color: var(--secondary-color);
  border-color: var(--border-glow);
  font-weight: 600;
}

/* Mobile Menu Toggle */
.mobile-menu-toggle {
  display: none;
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 1.25rem;
  cursor: pointer;
  padding: 6px;
}

/* Theme Toggle Button */
.theme-toggle {
  display: flex;
  align-items: center;
}

.theme-btn {
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  width: 58px;
  height: 28px;
  border-radius: 20px;
  cursor: pointer;
  position: relative;
  transition: var(--transition-interactive);
  overflow: hidden;
}

.theme-btn:hover {
  border-color: var(--primary-color);
}

.theme-option {
  position: absolute;
  top: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--transition-interactive);
}

.theme-option i {
  font-size: 10px;
}

.theme-option-light {
  left: 4px;
  background: none;
  color: #f59e0b;
}

.theme-option-dark {
  right: 4px;
  left: auto;
  background: none;
  color: var(--primary-color);
}

/* Light mode: sun active, moon dimmed */
.theme-btn:not([aria-pressed="true"]) .theme-option-light {
  opacity: 1;
  transform: scale(1);
  z-index: 2;
}

.theme-btn:not([aria-pressed="true"]) .theme-option-dark {
  opacity: 0.35;
  transform: scale(0.8);
  z-index: 1;
}

/* Dark mode: moon active, sun dimmed */
.theme-btn[aria-pressed="true"] .theme-option-light {
  opacity: 0.35;
  transform: scale(0.8);
  z-index: 1;
}

.theme-btn[aria-pressed="true"] .theme-option-dark {
  opacity: 1;
  transform: scale(1);
  z-index: 2;
}

/* ==========================================================================
   Hero Cover Banner System
   ========================================================================== */

/*
  Every tab carries the same banner. They are short now - tall enough to set
  the scene, short enough that the content starts near the top of the viewport.
  Home gets the taller of the two because it is the landing view.
*/
.tab-cover {
  height: 160px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: var(--space-6);
  box-shadow: var(--elev-1);
  border: 1px solid var(--border-color);
}

.tab-cover.home-cover {
  height: 220px;
}

/*
  Tab cover images (2048x768, compressed JPG copies of the PNG originals in
  assets/images/covers/). The navy colour shows while an image loads.
*/
.tab-cover {
  background-color: #10283d;
  background-size: cover;
  background-position: center;
}

.home-cover {
  background-image: url("../images/covers/home-cover.jpg");
}

.education-cover {
  background-image: url("../images/covers/education-cover.jpg");
}

.experience-cover {
  background-image: url("../images/covers/experience-cover.jpg");
}

.publications-cover {
  background-image: url("../images/covers/publications-cover.jpg");
}

.projects-cover {
  background-image: url("../images/covers/projects-cover.jpg");
}

.skills-cover {
  background-image: url("../images/covers/skills-cover.jpg");
}

.research-cover {
  background-image: url("../images/covers/research-cover.jpg");
}

.certifications-cover {
  background-image: url("../images/covers/awards-cover.jpg");
}

.activities-cover {
  background-image: url("../images/covers/activities-cover.jpg");
}

.contact-cover {
  background-image: url("../images/covers/contact-cover.jpg");
}

/*
  One navy wash across every cover. Light enough to read the photograph
  through, deep enough that the white title still clears contrast against a
  bright patch of image.
*/
.tab-cover::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: linear-gradient(
    180deg,
    var(--cover-overlay-top) 0%,
    var(--cover-overlay-bottom) 100%
  );
  z-index: 1;
}

.cover-overlay {
  position: relative;
  z-index: 2;
  text-align: center;
  color: #ffffff;
  padding: 0 20px;
}

/* The cover carries a single heading, so it needs no bottom spacing. */
.cover-title {
  font-family: var(--font-serif);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #ffffff;
  margin-bottom: 0;
}

/* ==========================================================================
   Home Page Layout & Bio
   ========================================================================== */

/* Sidebar is wide enough to hold the site owner's name on one line. */
.home-content {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 40px;
  align-items: start;
  margin-top: 20px;
}

/* Profile ID Badge Card */
.profile-section {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 24px;
  text-align: center;
  box-shadow: var(--elev-1);
  position: sticky;
  top: 90px;
  transition: border-color var(--transition-normal);
}

.profile-section:hover {
  border-color: var(--border-glow);
}

/* Fluid rather than fixed, so the portrait fills the card at every width
   without overflowing narrow phones. */
.profile-image-container {
  position: relative;
  width: 100%;
  max-width: 292px; /* fills the card between its 24px paddings */
  aspect-ratio: 292 / 307;
  margin: 0 auto 20px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--elev-1);
}

.profile-image {
  /* Both portraits are stacked absolutely so each one always fills the frame
     edge to edge. In normal flow the main image left a sliver at the top that
     let the hover portrait show through. */
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--transition-slow);
}

/* Head-and-shoulders portrait: keep the crop weighted toward the face. */
.profile-image.main {
  object-position: 50% 30%;
}

/* Talk photo is landscape with the speaker on the right; keep him in frame. */
#profileHover1 {
  object-position: 100% 50%;
}

/* Full-length outdoor photo: weight the crop toward the face. */
#profileHover2 {
  object-position: 50% 30%;
}

.profile-image.hover {
  opacity: 0;
}

/* Only the hover photo marked .is-next shows; script.js alternates the mark
   on each hover so visitors see a different photo each time. */
.profile-image-container:hover .profile-image.hover.is-next {
  opacity: 1;
}

.contact-info {
  margin-top: 20px;
  text-align: left;
  font-size: 0.88rem;
  border-top: 1px solid var(--border-color);
  padding-top: 16px;
}

.contact-info p {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  color: var(--text-secondary);
}

.contact-info p i {
  color: var(--secondary-color);
  width: 16px;
}

/* Google Scholar metrics card */
.scholar-metrics[hidden] {
  display: none;
}

.scholar-metrics {
  display: block;
  margin-top: 16px;
  padding: 14px 16px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-tertiary);
  text-decoration: none;
  transition: border-color var(--transition-normal),
    box-shadow var(--transition-normal), transform var(--transition-normal);
}

.scholar-metrics:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.scholar-metrics-header {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
  margin-bottom: 12px;
}

.scholar-metrics-header i {
  color: #4285f4;
}

.scholar-metrics-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.scholar-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.scholar-stat-value {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  line-height: 1.1;
  color: var(--text-primary);
}

.scholar-stat-label {
  font-size: 0.68rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  text-align: center;
}

.scholar-metrics.is-loading .scholar-stat-value {
  opacity: 0.5;
}

/* Name and role, sitting directly beneath the portrait in the profile card.
   Sized for the 232px card interior rather than the old full-width column. */
.profile-identity {
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-color);
}

/* The rule separates the name from the Scholar card; drop it while the card is hidden. */
.profile-identity:has(+ .scholar-metrics[hidden]) {
  padding-bottom: 0;
  border-bottom: none;
}

/* The name is allowed to wrap rather than being held on one line by nowrap,
   which previously capped the size at ~2.2rem to avoid overflow. Balanced
   wrapping keeps the two lines close in length where the browser supports it. */
.profile-identity h1 {
  font-size: 2rem;
  line-height: 1.25;
  margin-bottom: 8px;
  text-wrap: balance;
  overflow-wrap: break-word;
}

.profile-identity .title {
  font-size: 0.95rem;
  line-height: 1.55;
  text-align: center;
  color: var(--secondary-color);
  font-weight: 500;
}

/* Shared prose treatment: About Me, the Contact lead, and the Software tab's
   info sections all render as .bio-text.

   Runs the full width of its section so the text block lines up with the cover
   and the cards around it, and justified so both edges square up with them.
   Hyphenation is on because justifying at this width otherwise opens
   whitespace rivers between words. */
.bio-text {
  font-size: var(--text-md);
  color: var(--text-secondary);
  line-height: 1.7;
  margin-bottom: var(--space-5);
  text-align: justify;
  text-justify: inter-word;
  hyphens: auto;
  -webkit-hyphens: auto;
  -ms-hyphens: auto;
}

.tool-description {
  font-size: var(--text-md);
  color: var(--text-secondary);
  line-height: 1.7;
  margin-bottom: var(--space-5);
  text-align: left;
}

/* About Me reads as a card on the page grid, so the ruling behind the page
   never runs under the prose. */
.about-intro {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 30px;
  box-shadow: var(--elev-1);
  margin-bottom: 50px;
}

.about-intro h3 {
  margin-bottom: var(--space-4);
}

.about-intro .bio-text:last-child {
  margin-bottom: 0;
}

/* Research Interests Blueprint Cards */
.research-interests-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-5);
  margin-top: var(--space-6);
}

.research-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 24px;
  transition: var(--transition-interactive);
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--elev-1);
}

.research-card:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.research-icon {
  width: 48px;
  height: 48px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--secondary-color);
  font-size: 1.35rem;
  transition: var(--transition-interactive);
}

.research-card:hover .research-icon {
  background: var(--primary-color);
  color: var(--bg-secondary);
}

.research-card h4 {
  font-size: 1.1rem;
  color: var(--text-primary);
}

/* One short line under the keyword - the cards are narrow, so the measure is
   set by the grid track rather than needing a cap of its own. */
.research-card p {
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--text-muted);
  margin-bottom: 0;
}

/* Recent News Log Feed */
.news-section {
  margin-top: 50px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 30px;
  box-shadow: var(--elev-1);
}

/* Section titles are marked up as h3 but read as page-level headings, so they
   take the display serif like h1/h2. */
.section-title,
.about-intro h3 {
  font-family: var(--font-serif);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.section-title {
  font-size: 1.6rem;
  margin-bottom: 24px;
  position: relative;
  display: inline-block;
}

.section-title::before {
  content: "";
  position: absolute;
  bottom: -6px;
  left: 0;
  width: 40px;
  height: 3px;
  background: var(--secondary-color);
  border-radius: 20px;
}

.news-bullets {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.news-bullet-item {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding-bottom: 16px;
  border-bottom: 1px dashed var(--border-color);
}

.news-bullet-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.news-date {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  background: var(--bg-tertiary);
  color: var(--text-muted);
  padding: 2px 8px;
  border-radius: var(--radius-xs);
  flex-shrink: 0;
}

.news-icon {
  margin-top: 4px;
  color: var(--secondary-color);
  font-size: 1rem;
}

.news-type-publication .news-icon {
  color: #f39c12; /* Academic Orange */
}

.news-type-phd .news-icon {
  color: #8b5cf6; /* Indigo/purple */
}

.news-type-software-release .news-icon,
.news-type-software .news-icon,
.news-type-patent .news-icon {
  color: #10b981; /* Green */
}

.news-type-award .news-icon,
.news-type-recognition .news-icon {
  color: #d4af37; /* Gold */
}

.news-text {
  font-size: 0.95rem;
  color: var(--text-secondary);
}

.news-text strong {
  color: var(--text-primary);
}

/* News section header (Home preview) */
.news-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

/* ==========================================================================
   Home Highlight Cards
   ========================================================================== */

.highlights-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
  margin-top: 8px;
}

.highlight-card {
  display: flex;
  flex-direction: column;
  text-align: left;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  box-shadow: var(--elev-1);
  transition:
    border-color var(--transition-normal),
    transform var(--transition-normal),
    box-shadow var(--transition-normal);
}

.highlight-card:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.highlight-thumb {
  display: block;
  width: 100%;
  height: 150px;
  overflow: hidden;
  background: var(--bg-secondary);
}

.highlight-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--transition-normal);
}

.highlight-card:hover .highlight-thumb img {
  transform: scale(1.04);
}

.highlight-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 18px 20px 20px;
  flex: 1;
}

.highlight-type {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
}

.highlight-date {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
}

.highlight-card-title {
  font-family: var(--font-sans);
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text-primary);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.highlight-card-detail {
  font-size: 0.86rem;
  color: var(--text-secondary);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.highlight-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: auto;
  padding-top: 6px;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--secondary-color);
}

.highlight-cta i {
  transition: transform var(--transition-normal);
}

.highlight-card:hover .highlight-cta i {
  transform: translateX(3px);
}

/* ==========================================================================
   Home News - Accordion (news entries after the four highlights)
   ========================================================================== */

/* The News header carries the expand-all button; keep it level with the
   title rather than the title's underline. */
#home-news .news-section-header {
  align-items: flex-start;
}

.news-toggle-all {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition:
    border-color var(--transition-normal),
    color var(--transition-normal);
}

.news-toggle-all:hover {
  border-color: var(--border-glow);
  color: var(--text-primary);
}

.news-accordion {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Cards sit on the section panel, so they take the inset tone used by the
   highlight cards instead of the panel's own background. */
.news-section .news-card {
  background: var(--bg-tertiary);
}

.news-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--elev-1);
  transition: border-color var(--transition-normal);
}

.news-card:hover {
  border-color: var(--border-glow);
}

.news-toggle {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  padding: 20px 22px;
  cursor: pointer;
  font-family: inherit;
  color: var(--text-secondary);
}

.news-card .news-icon {
  margin-top: 2px;
}

.news-card-heading {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

.news-card-title {
  font-size: 0.98rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.news-card-title strong {
  color: var(--text-primary);
}

.news-card-summary {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.news-chevron {
  margin-top: 4px;
  color: var(--text-muted);
  transition: transform var(--transition-normal);
  flex-shrink: 0;
}

.news-card.open .news-chevron {
  transform: rotate(180deg);
}

.news-detail {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.35s ease;
}

.news-card.open .news-detail {
  grid-template-rows: 1fr;
}

.news-detail-inner {
  overflow: hidden;
  padding: 0 22px;
}

.news-card.open .news-detail-inner {
  padding-bottom: 22px;
}

.news-detail-text {
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--text-secondary);
  margin: 0 0 16px;
}

.news-media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 18px;
  margin-bottom: 18px;
}

.news-media {
  margin: 0;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--bg-tertiary);
}

.news-media img {
  display: block;
  width: 100%;
  height: 300px;
  object-fit: cover;
}

/* A single image spans the full card width and can be taller */
.news-media-grid:has(.news-media:only-child) .news-media img {
  height: 520px;
  object-fit: contain;
  background: var(--bg-secondary);
}

.news-media figcaption {
  font-size: 0.8rem;
  color: var(--text-muted);
  padding: 8px 12px;
}

/* Live LinkedIn post embed */
.news-embed {
  margin-bottom: 18px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--bg-secondary);
}

.news-embed iframe {
  display: block;
  width: 100%;
  height: 560px;
  border: 0;
}

@media (max-width: 768px) {
  .news-embed iframe {
    height: 620px;
  }
}

.news-detail-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--secondary-color);
  text-decoration: none;
  padding: 8px 14px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-xs);
  transition: border-color var(--transition-normal);
}

.news-detail-link:hover {
  border-color: var(--border-glow);
}

@media (max-width: 768px) {
  .news-media-grid {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   Timelines - Education & Experience Tabs
   ========================================================================== */

.education-container,
#experience-container {
  position: relative;
  padding-left: 44px;
  margin: 20px 0;
}

/*
  Core vertical rail. It fades out at both ends rather than stopping on a hard
  edge, so the column reads as a continuing thread instead of a boxed-in bar.
*/
.education-container::before,
#experience-container::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 13px;
  width: 2px;
  border-radius: 1px;
  background: linear-gradient(
    to bottom,
    transparent 0,
    var(--border-color) 36px,
    var(--border-color) calc(100% - 36px),
    transparent 100%
  );
}

.experience-item {
  position: relative;
  margin-bottom: 30px;
}

.experience-item:last-child {
  margin-bottom: 0;
}

/*
  Timeline node. Scoped to the two timeline containers so the same card markup
  can be reused elsewhere (software feature grids) without picking up a dot.
  A small hollow disc sitting on the rail, punched out of the page background
  so the rail appears to pass behind it.
*/
.education-container .experience-item::before,
#experience-container .experience-item::before {
  content: "";
  position: absolute;
  top: 28px;
  left: -36px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--bg-secondary);
  border: 2px solid var(--border-color);
  box-shadow: 0 0 0 5px var(--bg-primary);
  z-index: 2;
  transition:
    transform var(--transition-normal),
    border-color var(--transition-normal),
    background-color var(--transition-normal);
}

/* Short tick joining the node to the card, so the two do not float apart */
.education-container .experience-item::after,
#experience-container .experience-item::after {
  content: "";
  position: absolute;
  top: 33px;
  left: -19px;
  width: 15px;
  height: 2px;
  background: var(--border-color);
  transition: background-color var(--transition-normal);
}

.education-container .experience-item:hover::before,
#experience-container .experience-item:hover::before {
  transform: scale(1.15);
  border-color: var(--secondary-color);
  background: var(--secondary-color);
}

.education-container .experience-item:hover::after,
#experience-container .experience-item:hover::after {
  background: var(--secondary-color);
  width: 19px;
}

.exp-header {
  display: flex;
  gap: 20px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 24px;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

.exp-header:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.company-logo {
  width: 72px;
  height: 72px;
  background: #ffffff;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
  border: 1px solid var(--border-color);
  padding: 8px;
}

.company-logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.education-container .company-logo {
  width: 180px;
  height: auto;
  align-self: stretch;
}

.education-container .company-logo img {
  width: 100%;
  height: 100%;
}

/* Experience cards list several roles, so the logo keeps the education tab's
   width but sits in the top-left corner instead of stretching down the whole
   card, which would blow it up to the height of the role list. */
#experience-container .company-logo {
  width: 180px;
  height: 130px;
  align-self: flex-start;
}

.company-logo i {
  font-size: 2.2rem;
  color: var(--secondary-color);
}

.exp-details {
  flex: 1;
}

.exp-details h3 {
  font-size: 1.25rem;
  color: var(--text-primary);
  margin-bottom: 4px;
}

.company-name {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--secondary-color);
  display: inline-block;
  margin-bottom: 8px;
}

.exp-duration {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-bottom: 12px;
  display: block;
}

.exp-details p {
  font-size: 0.95rem;
  margin-bottom: 8px;
  color: var(--text-secondary);
}

.exp-details p strong {
  color: var(--text-primary);
}

/* --------------------------------------------------------------------------
   Roles held at one organization
   The card header carries the logo, organization name and shared department;
   every role the person held there is a node on a smaller inner timeline.
   -------------------------------------------------------------------------- */

.exp-details h3 .company-name {
  font-size: inherit;
  font-weight: inherit;
  color: var(--text-primary);
  margin-bottom: 0;
  transition: color var(--transition-normal);
}

.exp-details h3 .company-name:hover {
  color: var(--secondary-hover);
}

.exp-department {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 16px;
}

.role-timeline {
  position: relative;
  padding-left: 22px;
}

.role-timeline::before {
  content: "";
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: 2px;
  border-radius: 1px;
  background: linear-gradient(
    to bottom,
    var(--border-color),
    var(--border-color) calc(100% - 24px),
    transparent 100%
  );
}

.role-entry {
  position: relative;
  padding-bottom: 20px;
}

.role-entry:last-child {
  padding-bottom: 0;
}

/* Node on the inner timeline, sat on the border-left of .role-timeline */
.role-entry::before {
  content: "";
  position: absolute;
  top: 6px;
  left: -26px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--bg-secondary);
  border: 2px solid var(--border-color);
  box-shadow: 0 0 0 3px var(--bg-secondary);
  transition:
    transform var(--transition-normal),
    border-color var(--transition-normal),
    background-color var(--transition-normal);
}

/* An ongoing role reads as filled rather than hollow */
.role-entry.role-current::before {
  background: var(--secondary-color);
  border-color: var(--secondary-color);
}

.role-entry:hover::before {
  transform: scale(1.2);
  border-color: var(--secondary-color);
}

.role-title {
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 2px;
}

.role-entry .exp-duration {
  margin-bottom: 6px;
}

.role-unit {
  display: inline-block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--secondary-color);
  margin-bottom: 6px;
}

a.role-unit:hover {
  color: var(--secondary-hover);
}

.role-entry p {
  margin-bottom: 4px;
}

/* Course list inside a role (the teaching entry) */
.role-courses {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
}

.role-courses li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  padding: 6px 0;
  border-top: 1px solid var(--border-color);
}

.role-courses li:first-child {
  border-top: none;
}

.role-course-level {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  min-width: 112px;
}

.role-course-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-primary);
}

/* ==========================================================================
   Publications Overview Statistics & Listing
   ========================================================================== */

.publication-stats {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 24px;
  margin-bottom: 30px;
  box-shadow: var(--elev-1);
}

.publication-stats h3 {
  font-size: 1.2rem;
  margin-bottom: 20px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 16px;
}

.stat-item {
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  padding: 16px;
  text-align: center;
  transition: var(--transition-interactive);
}

.stat-item:hover {
  border-color: var(--border-glow);
}

/* Cumulative impact factor: a full-width band under the count tiles, with the
   number and label on one line, so it reads apart from the article counts. */
.stat-item-wide {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 16px;
}

.stat-item-wide .stat-number {
  margin-bottom: 0;
}

.stat-number {
  font-family: var(--font-serif);
  font-size: 2.1rem;
  font-weight: 600;
  font-variant-numeric: lining-nums;
  color: var(--primary-color);
  display: block;
  line-height: 1.1;
  margin-bottom: 4px;
}

.stat-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Publications layout: the type selector sits in a sidebar that sticks
   below the header, so it stays in reach however far down the list is read. */
.publications-layout {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.publications-sidebar {
  position: sticky;
  top: calc(var(--header-height) + 16px);
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* Type list and filters together can outgrow a short window; scroll the
     sidebar itself rather than letting its bottom fall out of reach. */
  max-height: calc(100vh - var(--header-height) - 32px);
  overflow-y: auto;
  scrollbar-width: thin;
}

/* Filters panel */
.pub-filters {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-1);
}

.pub-filters-toggle {
  display: none;
}

.pub-filters-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 12px 12px 14px;
}

.pub-filters-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.pub-filters-head .publications-nav-title {
  padding-bottom: 0;
}

.pub-filters-head .pub-filter-reset {
  padding: 2px 8px;
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--secondary-color);
  cursor: pointer;
}

.pub-filters-head .pub-filter-reset:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.pub-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  transition: var(--transition-interactive-fast);
}

.pub-search:focus-within {
  border-color: var(--secondary-color);
  background: var(--bg-secondary);
}

.pub-search i {
  font-size: 0.78rem;
  color: var(--text-muted);
}

.pub-search input {
  flex: 1;
  min-width: 0;
  padding: 8px 0;
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: 0.84rem;
  color: var(--text-primary);
  outline: none;
}

.pub-search input::placeholder {
  color: var(--text-muted);
}

#pub-filter-groups {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pub-filter-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 0;
  padding: 0;
  border: none;
  min-width: 0;
}

.pub-filter-group legend,
.pub-filter-legend {
  padding: 0 8px 6px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.pub-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 6px;
  font-size: 0.84rem;
  line-height: 1.3;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.pub-option:hover {
  background: var(--bg-tertiary);
}

.pub-option input {
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--secondary-color);
  cursor: pointer;
}

.pub-option:has(input:checked) {
  color: var(--text-primary);
  font-weight: 500;
}

.pub-option.is-disabled {
  opacity: 0.45;
  cursor: default;
}

.pub-option.is-disabled:hover {
  background: transparent;
}

.pub-option-label {
  flex: 1;
  min-width: 0;
}

.pub-option-count {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
}

.pub-year-select {
  margin: 0 2px;
  padding: 7px 10px;
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 0.84rem;
  color: var(--text-primary);
  cursor: pointer;
}

.pub-year-select:focus-visible {
  outline: 2px solid var(--secondary-color);
  outline-offset: 1px;
}

/* Results line above the list, while filters are on */
.pub-results {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 16px;
  font-size: 0.88rem;
  color: var(--text-secondary);
}

.pub-results[hidden] {
  display: none;
}

.pub-results strong {
  color: var(--text-primary);
}

.pub-results .pub-filter-reset,
.pub-filter-empty .pub-filter-reset {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--secondary-color);
  cursor: pointer;
  transition: var(--transition-interactive-fast);
}

.pub-results .pub-filter-reset:hover,
.pub-filter-empty .pub-filter-reset:hover {
  border-color: var(--border-glow);
  background: var(--bg-tertiary);
}

.pub-filter-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 32px 16px;
  background: var(--bg-secondary);
  border: 1px dashed var(--border-color);
  border-radius: var(--radius-lg);
}

.pub-filter-empty p {
  margin: 0;
  text-align: center;
  color: var(--text-muted);
}

/* Publications Navigation Filters */
.publications-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-1);
}

.publications-nav-title {
  padding: 2px 8px 8px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.pub-btn {
  width: 100%;
  padding: 10px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
  font-size: 0.88rem;
  line-height: 1.35;
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  transition: var(--transition-interactive);
}

.pub-btn-label {
  min-width: 0;
}

.pub-btn:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.pub-btn.active {
  background: var(--primary-color);
  color: var(--bg-secondary);
  border-color: var(--primary-color);
}

.count-badge {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  padding: 1px 7px;
  border-radius: 10px;
  flex-shrink: 0;
  font-weight: 600;
  transition:
    background var(--transition-normal),
    color var(--transition-normal);
}

.pub-btn.active .count-badge {
  background: rgba(255, 255, 255, 0.2);
  color: white;
}

/* Narrow screens: one column, with the selector as a horizontal strip that
   sticks under the header and scrolls sideways if it runs out of room. */
@media (max-width: 900px) {
  .publications-layout {
    /* minmax(0, ...) so the strip scrolls instead of widening the page */
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
  }

  .publications-sidebar {
    min-width: 0;
    top: var(--header-height);
    z-index: 20;
    gap: 6px;
    max-height: calc(100vh - var(--header-height));
    margin: 0 -8px;
    padding: 8px;
    background: var(--glass-bg);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
  }

  /* Filters collapse to one row under the type strip */
  .pub-filters {
    box-shadow: none;
    border-radius: var(--radius-sm);
  }

  .pub-filters-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--text-primary);
    cursor: pointer;
    list-style: none;
  }

  .pub-filters-toggle::-webkit-details-marker {
    display: none;
  }

  .pub-filters-toggle i {
    margin-right: 6px;
    color: var(--text-muted);
  }

  .pub-filters-toggle::after {
    content: "\25BE";
    margin-left: auto;
    color: var(--text-muted);
    transition: transform var(--transition-fast);
  }

  .pub-filters[open] .pub-filters-toggle::after {
    transform: rotate(180deg);
  }

  .pub-filters-active {
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--secondary-color);
  }

  .pub-filters-body {
    max-height: 55vh;
    overflow-y: auto;
    border-top: 1px solid var(--border-color);
  }

  .publications-nav {
    flex-direction: row;
    gap: 6px;
    padding: 6px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .publications-nav::-webkit-scrollbar {
    display: none;
  }

  .publications-nav-title {
    display: none;
  }

  .pub-btn {
    width: auto;
    flex: 0 0 auto;
    padding: 8px 12px;
    font-size: 0.82rem;
    white-space: nowrap;
  }
}

/* Publications Content Tabs */
.pub-content {
  display: none;
}

.pub-content.active {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* "All publications": every type in its own titled section. Sections the
   filters empty are dropped; the results line reports when nothing is left. */
.publications-list.show-all {
  display: flex;
  flex-direction: column;
  gap: 36px;
}

.publications-list.show-all .pub-results {
  margin-bottom: -20px;
}

.publications-list.show-all .pub-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.publications-list.show-all .pub-content.is-empty {
  display: none;
}

.pub-section-title {
  display: none;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 1.15rem;
}

.publications-list.show-all .pub-section-title {
  display: flex;
}

/* Individual Publication List Card */
.publication-item {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 20px 24px;
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: 8px 16px;
  align-items: start;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

.publication-item:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.publication-number {
  grid-column: 1;
  grid-row: 1 / span 5;
  font-family: var(--font-mono);
  font-size: 1rem;
  font-weight: 700;
  width: 32px;
  height: 32px;
  background: var(--bg-tertiary);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
}

.pub-title,
.pub-authors,
.pub-journal,
.pub-details {
  grid-column: 2;
}

.pub-title {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 6px;
  line-height: 1.35;
}

.pub-authors {
  font-size: 0.92rem;
  color: var(--text-secondary);
  margin-bottom: 4px;
}

.pub-journal {
  font-size: 0.88rem;
  font-style: italic;
  color: var(--text-muted);
  margin-bottom: 12px;
}

.pub-details {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

/* Dynamic publication badges */
.pub-badge {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: var(--radius-xs);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  border: 1px solid var(--border-color);
}

.pub-badge.impact-factor {
  background: rgba(var(--secondary-color-rgb), 0.1);
  color: var(--secondary-color);
  border-color: rgba(var(--secondary-color-rgb), 0.28);
}

/* Google Scholar citation count: the Scholar icon and the number, linking to
   the paper's "Cited by" list. Sized like the other badges in the row. */
.pub-badge.scholar-cites {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  text-decoration: none;
  background: rgba(66, 133, 244, 0.1);
  color: #1a73e8;
  border-color: rgba(66, 133, 244, 0.32);
  transition: var(--transition-interactive-fast);
}

.pub-badge.scholar-cites .ai {
  font-size: 0.9rem;
}

.pub-badge.scholar-cites:hover,
.pub-badge.scholar-cites:focus-visible {
  background: #1a73e8;
  color: #ffffff;
  border-color: #1a73e8;
}

[data-theme="dark"] .pub-badge.scholar-cites {
  color: #8ab4f8;
  border-color: rgba(138, 180, 248, 0.35);
}

[data-theme="dark"] .pub-badge.scholar-cites:hover,
[data-theme="dark"] .pub-badge.scholar-cites:focus-visible {
  background: #8ab4f8;
  color: var(--bg-primary);
  border-color: #8ab4f8;
}

/* Author role, not a status: a filled badge separates it from the outlined
   ones without needing a second hue. */
.pub-badge.corresponding {
  background: var(--secondary-color);
  color: #ffffff;
  border-color: var(--secondary-color);
}

[data-theme="dark"] .pub-badge.corresponding {
  color: var(--bg-primary);
}

/* Editorial status keeps its own colour, because here the colour is the
   information rather than decoration. */
.pub-badge.editor-choice {
  background: rgba(13, 122, 111, 0.12);
  color: var(--success-color);
  border-color: rgba(13, 122, 111, 0.3);
}

.doi-link {
  font-size: 0.86rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  transition: var(--transition-interactive-fast);
  text-decoration: none;
  box-shadow: var(--elev-1);
}

.doi-link:hover,
.doi-link:focus-visible {
  border-color: var(--secondary-color);
  box-shadow: var(--elev-2);
}

/* GitHub Link (Vibrant Green) */
.doi-link[href*="github.com"]:not([href*="sponsors"]) {
  background: rgba(46, 164, 79, 0.1);
  color: #2ea44f;
  border-color: rgba(46, 164, 79, 0.35);
}

.doi-link[href*="github.com"]:not([href*="sponsors"]):hover {
  background: #2ea44f;
  color: #ffffff;
  border-color: #2ea44f;
  box-shadow: 0 4px 12px rgba(46, 164, 79, 0.2);
}

/* Sponsor Link (Heart Red) */
.doi-link.sponsor-link {
  background: rgba(235, 87, 87, 0.1);
  color: #eb5757;
  border-color: rgba(235, 87, 87, 0.35);
}

.doi-link.sponsor-link:hover {
  background: #eb5757;
  color: #ffffff;
  border-color: #eb5757;
  box-shadow: 0 4px 12px rgba(235, 87, 87, 0.2);
}

/* Paper / Publication DOI Link (Scientific Orange) */
.doi-link[href*="doi.org"] {
  background: rgba(243, 156, 18, 0.1);
  color: #f39c12;
  border-color: rgba(243, 156, 18, 0.35);
}

.doi-link[href*="doi.org"]:hover {
  background: #f39c12;
  color: #ffffff;
  border-color: #f39c12;
  box-shadow: 0 4px 12px rgba(243, 156, 18, 0.2);
}

/* Links back to this site (Tech Blue) */
.doi-link[href*="umankhalid.github.io/"] {
  background: rgba(54, 162, 235, 0.1);
  color: #36a2eb;
  border-color: rgba(54, 162, 235, 0.35);
}

.doi-link[href*="umankhalid.github.io/"]:hover {
  background: #36a2eb;
  color: #ffffff;
  border-color: #36a2eb;
  box-shadow: 0 4px 12px rgba(54, 162, 235, 0.2);
}

/* In a publication's badge row the DOI link is sized like the IF and status
   badges beside it, so the row reads as one line of equal-height chips. The
   colour still comes from the doi.org rule above. */
.pub-details .doi-link {
  display: inline-flex;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: inherit;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-xs);
  box-shadow: none;
}

.pub-details .doi-link:hover,
.pub-details .doi-link:focus-visible {
  box-shadow: none;
}

/* Neutralized Tool Keywords / Badges */
.tool-badges .pub-badge {
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  border-color: var(--border-color);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  padding: 3px 8px;
  pointer-events: none;
  cursor: default;
  box-shadow: none;
  opacity: 0.85;
}

/* ==========================================================================
   Projects Timeline
   Cards alternate either side of a centre rail, newest at the top. The year
   pill sitting on the rail is the node - a separate dot would only repeat it.
   ========================================================================== */

.project-timeline {
  position: relative;
  padding: 8px 0;
  /*
    Entries flow in one column, so pulling every right-hand card up by
    --project-stagger interleaves the two sides: each card starts around the
    middle of the one before it instead of below it. Every consecutive pair
    then advances by (card height + gap - stagger), which keeps the rhythm even
    on both sides. Keep the stagger under half a card height or cards on the
    same side start to collide.
  */
  --project-gap: 36px;
  --project-stagger: 150px;
}

/* Centre rail, fading out at both ends so it reads as a continuing thread */
.project-timeline::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: linear-gradient(
    to bottom,
    transparent 0,
    var(--border-color) 40px,
    var(--border-color) calc(100% - 40px),
    transparent 100%
  );
}

/* Half-width minus the centre gutter that holds the year pill */
.project-entry {
  position: relative;
  width: calc(50% - 56px);
  margin-bottom: var(--project-gap);
}

.project-entry.is-right {
  margin-left: auto;
  margin-top: calc(var(--project-stagger) * -1);
  margin-bottom: calc(var(--project-gap) - var(--project-stagger));
}

/* Nothing follows the last card, so it must not pull the container short */
.project-entry:last-child,
.project-entry.is-right:last-child {
  margin-bottom: 0;
}

.project-marker {
  position: absolute;
  top: 18px;
  z-index: 2;
  padding: 3px 10px;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: var(--bg-secondary);
  box-shadow: 0 0 0 5px var(--bg-primary);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
  white-space: nowrap;
  transition:
    color var(--transition-normal),
    border-color var(--transition-normal),
    background-color var(--transition-normal);
}

.project-entry.is-left .project-marker {
  left: calc(100% + 56px);
  transform: translateX(-50%);
}

.project-entry.is-right .project-marker {
  right: calc(100% + 56px);
  transform: translateX(50%);
}

/* Tick joining the card to the pill on the rail */
.project-entry::after {
  content: "";
  position: absolute;
  top: 29px;
  width: 20px;
  height: 2px;
  background: var(--border-color);
  transition: background-color var(--transition-normal);
}

.project-entry.is-left::after {
  left: 100%;
}

.project-entry.is-right::after {
  right: 100%;
}

.project-entry:hover .project-marker {
  color: var(--bg-secondary);
  background: var(--secondary-color);
  border-color: var(--secondary-color);
}

.project-entry:hover::after {
  background: var(--secondary-color);
}

.project-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--elev-1);
  cursor: pointer;
  transition: var(--transition-interactive);
  display: flex;
  flex-direction: column;
}

.project-card:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.project-image {
  height: 140px;
  background: linear-gradient(
    135deg,
    var(--bg-tertiary) 0%,
    var(--border-color) 100%
  );
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 3rem;
  color: var(--secondary-color);
  border-bottom: 1px solid var(--border-color);
  transition: var(--transition-interactive);
  overflow: hidden;
}

.project-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--transition-normal);
}

.project-card-image,
.project-modal-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.project-card:hover .project-image {
  background: var(--secondary-color);
  color: var(--bg-secondary);
}

.project-card:hover .project-image img {
  transform: scale(1.06);
}

.project-info {
  padding: 20px;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.project-title {
  font-family: var(--font-sans);
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 8px;
  line-height: 1.3;
}

.project-role {
  font-size: 0.88rem;
  color: var(--secondary-color);
  font-weight: 600;
  margin-bottom: 4px;
}

.project-duration {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-top: auto;
}

.project-status {
  align-self: flex-start;
  margin-top: 10px;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--bg-tertiary);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* An ongoing project is the one worth spotting at a glance */
.project-status.status-ongoing {
  background: rgba(var(--secondary-color-rgb), 0.12);
  color: var(--secondary-color);
}

/* ==========================================================================
   Skills Level Grid Layout
   ========================================================================== */

.skills-container {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.skill-category {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 24px;
  box-shadow: var(--elev-1);
}

.skill-category h3 {
  font-size: 1.25rem;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--secondary-color);
}

.skills-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}

.skill-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 16px;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

.skill-item:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.skill-header {
  color: var(--text-primary);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  font-size: 0.9rem;
  font-weight: 600;
}

.skill-name {
  color: var(--text-primary);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.skill-logo,
.skill-logo-icon {
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
}

.skill-logo {
  object-fit: contain;
  filter: drop-shadow(0 2px 4px rgba(15, 23, 42, 0.12));
}

.skill-logo[src*="synchro-software-logo"] {
  background: #ffffff;
  border-radius: var(--radius-xs);
  padding: 2px;
}

.skill-logo[src*="img.logokit.com/twinmotion.com"] {
  background: #ffffff;
  border-radius: var(--radius-xs);
  padding: 2px;
}

.skill-logo[src*="Google_Antigravity_Logo"] {
  width: 80px;
  flex-basis: 80px;
}

.skill-logo-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--secondary-color);
  font-size: 1.05rem;
}

.skill-level {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* Four discrete rungs (Basic / Intermediate / Advanced / Expert) instead of a
   percentage bar, so the meter claims only the precision the label does. */
.skill-meter {
  display: flex;
  gap: var(--space-1);
  align-items: center;
}

.skill-meter-seg {
  flex: 1;
  height: 5px;
  border-radius: var(--radius-xs);
  /* Empty rungs sit on the card, which is --bg-tertiary, so the track needs
     the border colour rather than a background token to stay visible. */
  background: var(--border-color);
  transition: background var(--transition-normal);
}

.skill-meter-seg.is-filled {
  background: var(--secondary-color);
}

/* The top rung is a darker blue, so "Expert" is distinguishable at a glance
   without introducing a second hue. */
.skill-meter-seg.is-filled:nth-child(4) {
  background: var(--secondary-hover);
}

.skill-description {
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* ==========================================================================
   Certifications & Awards
   ========================================================================== */

.awards-section {
  margin-bottom: 40px;
}

/* One award per row, stacked as a list rather than a multi-column grid */
.awards-container {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.award-item {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 20px;
  display: flex;
  gap: 16px;
  align-items: center;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

.award-item.clickable-award {
  cursor: pointer;
}

.award-item:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.award-icon {
  width: 48px;
  height: 48px;
  background: rgba(245, 158, 11, 0.1);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #f59e0b;
  font-size: 1.25rem;
  flex-shrink: 0;
}

.award-content strong {
  display: block;
  font-family: var(--font-sans);
  font-size: 1.05rem;
  color: var(--text-primary);
  margin-bottom: 2px;
}

.award-content p {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.award-actions {
  font-size: 0.8rem;
  color: var(--secondary-color);
  font-weight: 600;
}

.certificates-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 20px;
}

.certificate-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--elev-1);
  cursor: pointer;
  transition: var(--transition-interactive);
  text-align: center;
}

.certificate-card:hover {
  transform: scale(1.03);
  border-color: var(--border-glow);
}

.certificate-image {
  height: 140px;
  background: var(--bg-tertiary);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.certificate-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.certificate-image i {
  font-size: 2.5rem;
  color: var(--text-muted);
}

.certificate-caption {
  padding: 12px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-primary);
}

/* ==========================================================================
   Activities Tab
   ========================================================================== */

.activities-container {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.activity-category {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 24px;
  box-shadow: var(--elev-1);
}

.activity-category h3 {
  font-size: 1.25rem;
  margin-bottom: 20px;
  color: var(--secondary-color);
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 8px;
}

.activity-item {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  margin-bottom: 16px;
}

.activity-item:last-child {
  margin-bottom: 0;
}

.activity-icon {
  margin-top: 4px;
  color: var(--secondary-color);
  font-size: 1rem;
}

.activity-content {
  font-size: 0.95rem;
  color: var(--text-secondary);
}

.activity-content strong {
  color: var(--text-primary);
}

/* Nested list under an activity, e.g. the invited lectures of a hosted course */
.activity-sublist {
  margin: 10px 0 0;
  padding-left: 18px;
}

.activity-sublist li {
  margin-bottom: 6px;
}

.activity-sublist li:last-child {
  margin-bottom: 0;
}

.activity-sublist li::marker {
  color: var(--text-muted);
}

/* Seminars & Presentations list (Activities tab) */

.seminars-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.seminar-item {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 16px;
}

.seminar-item.clickable-seminar {
  cursor: pointer;
  transition: var(--transition-interactive);
}

.seminar-item.clickable-seminar:hover,
.seminar-item.clickable-seminar:focus-visible {
  transform: translateY(-2px);
  border-color: var(--border-glow);
  box-shadow: var(--elev-1);
}

.seminar-thumb {
  flex: 0 0 132px;
  width: 132px;
  height: 92px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--secondary-color);
  font-size: 1.6rem;
}

.seminar-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.seminar-info {
  flex: 1;
  min-width: 0;
}

.seminar-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--secondary-color);
  margin-bottom: 6px;
}

.seminar-title {
  display: block;
  font-size: 1rem;
  color: var(--text-primary);
  margin-bottom: 6px;
}

.seminar-meta {
  font-size: 0.85rem;
  color: var(--text-secondary);
  margin: 0 0 4px;
}

.seminar-meta i {
  color: var(--secondary-color);
  margin-right: 6px;
}

.seminar-action {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--secondary-color);
}

.seminars-empty {
  text-align: center;
  padding: 24px;
  color: var(--text-muted);
}

.seminars-empty i {
  font-size: 2em;
  margin-bottom: 10px;
  display: block;
}

@media (max-width: 576px) {
  .seminar-item {
    flex-direction: column;
  }

  .seminar-thumb {
    flex: 0 0 auto;
    width: 100%;
    height: 150px;
  }
}

/* ==========================================================================
   Academic Collaboration Network (co-authorship graph + country map)
   ========================================================================== */

/* Headline figures */
.collab-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}

.collab-summary:empty {
  display: none;
}

.collab-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
}

.collab-stat-value {
  font-family: var(--font-serif);
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: lining-nums;
  color: var(--primary-color);
}

.collab-stat-label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Toolbar: view tabs on the left, 2D/3D and reset on the right */
.collab-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.collab-modes,
.collab-dims {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}

.collab-mode-btn,
.collab-dim-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  padding: 7px 14px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  transition: var(--transition-interactive-fast);
}

.collab-dim-btn {
  padding: 7px 12px;
  font-weight: 600;
  font-size: 0.8rem;
}

.collab-mode-btn i {
  font-size: 0.8rem;
  color: var(--text-muted);
  transition: color var(--transition-fast);
}

.collab-mode-btn:hover,
.collab-dim-btn:hover:not(:disabled) {
  color: var(--text-primary);
}

.collab-mode-btn.active,
.collab-dim-btn.active {
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-weight: 600;
  box-shadow: var(--elev-1);
}

.collab-mode-btn.active i {
  color: var(--secondary-color);
}

.collab-dim-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.collab-toolbar-right {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.collab-reset-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border-color);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: var(--transition-interactive-fast);
}

.collab-reset-btn:hover {
  color: var(--secondary-color);
  border-color: var(--border-glow);
}

/* Graph and ranked list share one framed surface */
.collab-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--bg-secondary);
}

.collab-canvas-wrap {
  position: relative;
  width: 100%;
  height: 620px;
  background: var(--bg-secondary);
}

#collab-canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  touch-action: none;
}

#collab-canvas:active {
  cursor: grabbing;
}

.collab-map {
  position: absolute;
  inset: 0;
  display: none;
  z-index: 1;
  background: var(--bg-tertiary);
}

.collab-canvas-wrap.is-map .collab-map {
  display: block;
}

.collab-canvas-wrap.is-map #collab-canvas,
.collab-canvas-wrap.is-map .collab-controls,
.collab-canvas-wrap.is-map .collab-legend,
.collab-canvas-wrap.is-map .collab-hint,
.collab-canvas-wrap.is-map .collab-tooltip {
  display: none;
}

.collab-hint {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  display: none;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--text-muted);
  background: var(--glass-bg);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  pointer-events: none;
  white-space: nowrap;
}

.collab-canvas-wrap.is-3d .collab-hint {
  display: inline-flex;
}

.collab-controls {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 5;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  box-shadow: var(--elev-1);
  overflow: hidden;
}

.collab-controls button {
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.8rem;
  transition: var(--transition-interactive-fast);
}

.collab-controls button + button {
  border-top: 1px solid var(--border-color);
}

.collab-controls button:hover {
  color: var(--secondary-color);
  background: var(--bg-tertiary);
}

.collab-tooltip {
  position: absolute;
  z-index: 6;
  pointer-events: none;
  max-width: 260px;
  padding: 10px 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  box-shadow: var(--elev-3);
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--text-secondary);
  transform: translate(-50%, calc(-100% - 12px));
}

.collab-tooltip[hidden] {
  display: none;
}

.collab-tooltip .tt-title {
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 4px;
  font-size: 0.88rem;
}

.collab-tooltip .tt-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 2px;
}

.collab-tooltip .tt-row i {
  width: 13px;
  flex-shrink: 0;
  text-align: center;
  font-size: 0.72rem;
  color: var(--text-muted);
}

.collab-legend {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-width: 230px;
  padding: 10px 12px;
  background: var(--glass-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  font-size: 0.74rem;
  color: var(--text-secondary);
  pointer-events: none;
}

.collab-legend[hidden] {
  display: none;
}

.collab-legend .legend-title {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 1px;
}

.collab-legend .legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  line-height: 1.3;
}

.collab-legend .legend-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* Ranked list beside the graph */
.collab-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 620px;
  border-left: 1px solid var(--border-color);
  background: var(--bg-secondary);
}

.collab-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--border-color);
}

.collab-panel-head h4 {
  font-size: 0.95rem;
  margin: 0;
}

.collab-panel-head span {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.collab-list {
  list-style: none;
  margin: 0;
  padding: 6px 0;
  overflow-y: auto;
  flex: 1;
}

.collab-row {
  --row-color: var(--secondary-color);
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto;
  grid-template-areas:
    "dot text count"
    ". bar bar";
  column-gap: 10px;
  row-gap: 6px;
  align-items: center;
  width: 100%;
  padding: 8px 16px;
  border: none;
  background: transparent;
  text-align: left;
  font-family: inherit;
  color: inherit;
  cursor: default;
  transition: background-color var(--transition-fast);
}

.collab-row:hover,
.collab-row:focus-visible,
.collab-row.is-active {
  background: var(--bg-tertiary);
}

.collab-row:focus-visible {
  outline: 2px solid var(--secondary-color);
  outline-offset: -2px;
}

.collab-row-dot {
  grid-area: dot;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--row-color);
}

.collab-row-text {
  grid-area: text;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.collab-row-name {
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.collab-row-meta {
  font-size: 0.74rem;
  color: var(--text-muted);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.collab-row-count {
  grid-area: count;
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--text-primary);
}

.collab-row-bar {
  grid-area: bar;
  display: block;
  height: 4px;
  border-radius: 2px;
  background: var(--bg-tertiary);
  overflow: hidden;
}

.collab-row:hover .collab-row-bar,
.collab-row.is-active .collab-row-bar {
  background: var(--border-color);
}

.collab-row-bar > span {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: var(--row-color);
}

.collab-note {
  margin: 12px 0 0;
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--text-muted);
  max-width: none;
}

/* Leaflet tooltip on the country map, matched to the canvas tooltip */
.leaflet-tooltip.collab-map-tip {
  padding: 8px 11px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  box-shadow: var(--elev-2);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.leaflet-tooltip.collab-map-tip strong {
  font-weight: 600;
  color: var(--text-primary);
}

.leaflet-tooltip-top.collab-map-tip::before {
  border-top-color: var(--border-color);
}

.leaflet-tooltip-bottom.collab-map-tip::before {
  border-bottom-color: var(--border-color);
}

@media (max-width: 960px) {
  .collab-body {
    grid-template-columns: 1fr;
  }

  .collab-panel {
    max-height: 360px;
    border-left: none;
    border-top: 1px solid var(--border-color);
  }
}

@media (max-width: 640px) {
  .collab-canvas-wrap {
    height: 460px;
  }

  .collab-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .collab-toolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .collab-modes {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }

  .collab-mode-btn {
    justify-content: center;
    padding: 7px 8px;
    font-size: 0.8rem;
  }

  .collab-mode-btn i {
    display: none;
  }

  .collab-toolbar-right {
    justify-content: space-between;
  }

  /* The ranked list below carries the same key */
  .collab-legend,
  .collab-canvas-wrap.is-3d .collab-hint {
    display: none;
  }
}

/* ==========================================================================
   Software & Tools Workspace Console (SaaS/IDE style layout)
   ========================================================================== */

.software-container {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 30px;
  align-items: start;
}

.tools-nav-container {
  position: sticky;
  top: 90px;
}

.tools-nav {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 8px;
  box-shadow: var(--elev-1);
}

.tool-nav-btn {
  padding: 10px 14px;
  background: transparent;
  border: none;
  border-radius: var(--radius-xs);
  color: var(--text-secondary);
  font-weight: 500;
  font-size: 0.88rem;
  text-align: left;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: var(--transition-interactive-fast);
}

.tool-nav-btn i {
  font-size: 1rem;
  width: 16px;
}

.tool-nav-btn:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.tool-nav-btn.active {
  background: var(--primary-color);
  color: var(--bg-secondary);
}

.tools-content-container {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 30px;
  box-shadow: var(--elev-1);
  min-height: 500px;
}

.tool-content {
  display: none;
}

.tool-content.active {
  display: block;
  animation: smoothFadeIn 0.35s ease forwards;
}

.tool-header h2 {
  font-size: 1.75rem;
  margin-bottom: 8px;
}

/* .tool-description is styled with .bio-text in the shared prose rule above. */

.tool-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 20px;
}

.tool-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  padding: 12px;
  margin-bottom: 30px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
}

.tool-details {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.tool-info-section {
  border-top: 1px solid var(--border-color);
  padding-top: 24px;
}

.info-title {
  font-size: 1.2rem;
  margin-bottom: 16px;
  color: var(--text-primary);
}

.research-interests {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.research-interests li {
  font-size: 0.9rem;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 10px;
}

.research-interests li i {
  color: var(--secondary-color);
  font-size: 0.8rem;
}

.software-features-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0;
  margin: 20px 0;
}

.software-features-list li {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 14px;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
  font-size: 0.92rem;
  color: var(--text-primary);
  font-weight: 500;
  line-height: 1.4;
}

.software-features-list li:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
}

.software-features-list li i {
  width: 38px;
  height: 38px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--secondary-color);
  font-size: 1.1rem;
  flex-shrink: 0;
  transition: var(--transition-interactive);
}

.software-features-list li:hover i {
  background: var(--secondary-color);
  color: var(--bg-secondary);
  border-color: var(--secondary-color);
}

.capabilities-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 12px;
  margin-top: 16px;
}

.capability-item {
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  padding: 12px;
  text-align: center;
  font-size: 0.8rem;
  font-weight: 600;
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--text-secondary);
}

.capability-item i {
  font-size: 1.2rem;
  color: var(--secondary-color);
}

.video-wrapper {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  border-radius: var(--radius-md);
  box-shadow: var(--elev-1);
  border: 1px solid var(--border-color);
}

.video-wrapper iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.media-wrapper-auto {
  height: auto;
  padding-bottom: 0;
}

.media-image-full,
.media-image-contain {
  width: 100%;
  border-radius: 10px;
}

.media-image-contain {
  position: static;
  height: auto;
  display: block;
}

.install-code-block {
  background: var(--bg-secondary, #1e1e1e);
  color: var(--text-primary, #f5f5f5);
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  overflow-x: auto;
  font-size: 0.9em;
}

/* ==========================================================================
   Contact Tab
   ========================================================================== */

.contact-container {
  display: flex;
  flex-direction: column;
  gap: 56px;
}

.contact-block {
  width: 100%;
}

/* Inherits the justified, full-width prose treatment from .bio-text; only the
   spacing below it differs. */
.contact-lead {
  margin-bottom: var(--space-8);
}

.contact-methods {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}

.contact-item {
  position: relative;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: 22px;
  display: flex;
  gap: 16px;
  align-items: flex-start;
  overflow: hidden;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

/* Accent rail that wipes in on hover. */
.contact-item::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--secondary-color);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--transition-normal);
}

/* Staggered reveal. The hidden state is opt-in via .is-revealing, which only
   JS adds, so the cards stay visible if the script never runs. Transition
   timing comes from the destination state, which keeps the stagger delay off
   :hover. */
.contact-item.is-revealing {
  opacity: 0;
  transform: translateY(16px);
}

.contact-item.is-revealed {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--reveal-delay, 0ms);
}

.contact-item:hover {
  border-color: var(--border-glow);
  box-shadow: var(--elev-2);
  transition-delay: 0s;
}

.contact-item:hover::before {
  transform: scaleY(1);
}

.contact-icon {
  width: 44px;
  height: 44px;
  background: rgba(var(--secondary-color-rgb), 0.1);
  color: var(--secondary-color);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  flex-shrink: 0;
  transition: var(--transition-interactive);
}

.contact-item:hover .contact-icon {
  background: rgba(var(--secondary-color-rgb), 0.18);
}

.contact-text {
  min-width: 0;
  flex: 1;
}

/* Micro-label above the value. */
.contact-text strong {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 6px;
}

.contact-value {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.45;
  word-break: break-word;
  transition: var(--transition-interactive);
}

a.contact-value:hover {
  color: var(--secondary-color);
}

/* Non-link values (e.g. the lab name) read better in the UI face. */
.contact-value--plain {
  font-family: var(--font-sans);
  font-size: 1.05rem;
  font-weight: 600;
}

.contact-note {
  display: block;
  margin-top: 6px;
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.5;
}

/* Copy-to-clipboard button, revealed on hover/focus on pointer devices. */
.contact-copy {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  color: var(--text-muted);
  font-size: 0.85rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: var(--transition-interactive);
}

.contact-item:hover .contact-copy,
.contact-copy:focus-visible {
  opacity: 1;
}

.contact-copy:hover {
  border-color: var(--secondary-color);
  color: var(--secondary-color);
  background: rgba(var(--secondary-color-rgb), 0.08);
}

.contact-copy.is-copied,
.location-btn.is-copied {
  border-color: var(--success-color);
  color: var(--success-color);
  background: rgba(13, 148, 136, 0.1);
  opacity: 1;
}

.contact-copy.is-failed,
.location-btn.is-failed {
  border-color: #dc2626;
  color: #dc2626;
  background: rgba(220, 38, 38, 0.1);
  opacity: 1;
}

/* Touch devices get no hover, so keep the button permanently visible. */
@media (hover: none) {
  .contact-copy {
    opacity: 1;
  }
}

.quick-actions h3 {
  margin-bottom: 16px;
}

.action-buttons {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}

.action-btn {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  padding: 12px;
  text-align: center;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-secondary);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

.action-btn i {
  font-size: 1.35rem;
  color: var(--secondary-color);
}

.action-btn:hover {
  border-color: var(--border-glow);
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

/* Map details */
/* Map beside an address panel; they share a row height so the two
   surfaces line up on desktop. */
.location-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.65fr) minmax(280px, 1fr);
  gap: 24px;
  align-items: stretch;
}

.map-container {
  position: relative;
  min-height: 440px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--elev-1);
  border: 1px solid var(--border-color);
}

/* Absolute fill so Leaflet always resolves a definite height, whatever
   the grid row ends up measuring. */
#map {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.location-panel {
  display: flex;
  flex-direction: column;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-1);
  padding: 28px;
}

.location-eyebrow {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--secondary-color);
  margin-bottom: 10px;
}

.location-name {
  font-family: var(--font-serif);
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.25;
  margin-bottom: 6px;
}

.location-sub {
  font-size: 0.9rem;
  color: var(--text-secondary);
  margin-bottom: 20px;
}

.location-address {
  font-style: normal;
  font-size: 0.92rem;
  line-height: 1.75;
  color: var(--text-secondary);
  padding-top: 20px;
  border-top: 1px solid var(--border-color);
}

.location-address-ko {
  display: block;
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 6px;
}

/* Pin the buttons to the bottom of the panel so they align with the
   lower edge of the map on desktop. */
.location-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: auto;
  padding-top: 24px;
}

.location-btn {
  flex: 1 1 140px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 16px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: 0.86rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: var(--transition-interactive);
}

.location-btn:hover {
  border-color: var(--secondary-color);
  color: var(--secondary-color);
  background: rgba(var(--secondary-color-rgb), 0.08);
}

.location-btn--primary {
  background: var(--secondary-color);
  border-color: var(--secondary-color);
  color: #ffffff;
}

.location-btn--primary:hover {
  background: var(--secondary-hover);
  border-color: var(--secondary-hover);
  color: #ffffff;
}

/* Dark mode's accent colours are light, so flip the button text to dark and
   lighten the error red to keep both legible. */
[data-theme="dark"] .location-btn--primary,
[data-theme="dark"] .location-btn--primary:hover {
  color: #0b1220;
}

[data-theme="dark"] .contact-copy.is-failed,
[data-theme="dark"] .location-btn.is-failed {
  border-color: #f87171;
  color: #f87171;
  background: rgba(248, 113, 113, 0.12);
}

@media (max-width: 1024px) {
  .location-grid {
    grid-template-columns: 1fr;
  }

  .map-container {
    min-height: 360px;
  }

  .location-actions {
    margin-top: 24px;
  }
}

@media (max-width: 640px) {
  .contact-container {
    gap: 40px;
  }

  .contact-item {
    padding: 18px;
  }

  .location-panel {
    padding: 22px;
  }

  .location-actions {
    flex-direction: column;
  }
}

/* ==========================================================================
   Modals & Overlays (Glassmorphic)
   ========================================================================== */

.modal {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2000;
  background: rgba(7, 10, 19, 0.6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  overflow-y: auto;
  padding: 40px 20px;
}

.modal-content {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  max-width: 700px;
  margin: 0 auto;
  padding: 40px;
  position: relative;
  box-shadow: var(--elev-3);
  animation: modalScaleIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

.project-modal-image-frame {
  width: 100%;
  height: 240px;
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: 20px;
  border: 1px solid var(--border-color);
}

.modal-award-image,
.modal-certificate-preview {
  cursor: pointer;
  max-width: 100%;
  max-height: 400px;
  object-fit: contain;
  border-radius: var(--radius-md);
}

.modal-award-image {
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
  transition: transform var(--transition-fast) ease;
}

.modal-award-image:hover {
  transform: scale(1.02);
}

.modal-certificate-preview {
  box-shadow: var(--elev-2);
}

.award-certificate-image-frame > i {
  width: 400px;
  max-width: 100%;
  height: 300px;
  background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%);
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 3em;
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
}

@keyframes modalScaleIn {
  from {
    opacity: 0;
    transform: scale(0.9) translateY(20px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.close {
  position: absolute;
  top: 20px;
  right: 20px;
  font-size: 1.5rem;
  font-weight: 700;
  cursor: pointer;
  color: var(--text-muted);
  transition: color var(--transition-fast);
}

.close:hover {
  color: var(--text-primary);
}


/* Image Zoom overlays */
.image-zoom-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 3000;
  background: rgba(7, 10, 19, 0.9);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.image-zoom-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  position: relative;
}

.zoomed-image {
  max-width: 90%;
  max-height: 90%;
  object-fit: contain;
  border-radius: var(--radius-md);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  animation: zoomFadeIn 0.3s ease forwards;
}

@keyframes zoomFadeIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.close-zoom {
  position: absolute;
  top: 30px;
  right: 30px;
  font-size: 2.5rem;
  color: white;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity var(--transition-fast);
}

.close-zoom:hover {
  opacity: 1;
}

/* ==========================================================================
   Social Media Floating Toolbar (Fixed on Right)
   ========================================================================== */

.social-floating {
  position: fixed;
  right: 24px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  z-index: 900;
}

/*
  Each service wears its own colour at rest, held in a per-icon custom property
  so one rule can apply it. Hover and keyboard focus deepen the icon rather
  than introducing the colour, since the colour is already there.
*/
.social-icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--brand-color, var(--border-color));
  background: var(--brand-color, var(--bg-secondary));
  color: #ffffff;
  box-shadow: var(--elev-1);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  transition: var(--transition-interactive);
}

.social-icon.linkedin {
  --brand-color: #0077b5;
}
.social-icon.github {
  --brand-color: #24292e;
}
.social-icon.scholar {
  --brand-color: #4285f4;
}
.social-icon.orcid {
  --brand-color: #a6ce39;
}
.social-icon.researchgate {
  --brand-color: #00ccb1;
}
.social-icon.scopus {
  --brand-color: #ff6600;
}
.social-icon.lab {
  --brand-color: #9e1b32;
}
.social-icon.email {
  --brand-color: #2563eb;
}
.social-icon.flagcounter {
  --brand-color: #2f855a;
}

/* ORCID's green is light enough that white on it would not carry */
.social-icon.orcid {
  color: #1f2d16;
}

.social-icon:hover,
.social-icon:focus-visible {
  filter: brightness(0.88);
  box-shadow: var(--elev-2);
}

/* Visitor flag counter popover - opens beside its icon without covering the page */
.flag-counter-wrap {
  position: relative;
}

.flag-counter-popover {
  position: absolute;
  right: calc(100% + 12px);
  bottom: 0;
  width: max-content;
  /* The counter image is 578px wide; room for it at full size plus padding */
  max-width: min(620px, calc(100vw - 100px));
  padding: 16px 16px 14px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--elev-3);
  text-align: center;
  transform: translateX(var(--popover-shift, 0px));
  animation: flagPopoverIn 0.18s ease-out;
}

.flag-counter-popover[hidden] {
  display: none;
}

@keyframes flagPopoverIn {
  from {
    opacity: 0;
    translate: 6px 0;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* Sits on the popover's corner so it never covers the counter image */
.flag-counter-popover__close {
  position: absolute;
  top: -12px;
  right: -12px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-color);
  border-radius: 50%;
  background: var(--bg-secondary);
  color: var(--text-muted);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--elev-1);
  transition: var(--transition-interactive);
}

.flag-counter-popover__close:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

/* The counter image has a white background, so it sits on white in dark mode too */
.flag-counter-frame {
  padding: 8px;
  background: #ffffff;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
}

.flag-counter-frame img {
  display: block;
  width: 578px;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
}

.flag-counter-more {
  display: inline-block;
  margin-top: 10px;
  font-size: var(--text-sm);
  font-weight: 500;
}

@media print {
  .flag-counter-popover {
    display: none;
  }
}

/* ==========================================================================
   Scroll to Top
   ========================================================================== */

.scroll-to-top {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 44px;
  height: 44px;
  background: var(--primary-color);
  color: var(--bg-secondary);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  z-index: 900;
  box-shadow: 0 4px 15px rgba(var(--primary-color-rgb), 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  transition: var(--transition-interactive);
}

.scroll-to-top.visible {
  opacity: 1;
  visibility: visible;
}

.scroll-to-top:hover {
  background: var(--secondary-color);
}

/* ==========================================================================
   Global Footer Section
   ========================================================================== */

.site-footer {
  margin-top: 72px;
  padding: 26px 24px;
  border-top: 1px solid var(--border-color);
  background: var(--bg-tertiary);
}

.footer-inner {
  max-width: 1400px; /* aligns with .container */
  margin: 0 auto;
}

/* --- Bottom bar (the footer's only row) --- */
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 24px;
}

.footer-copyright,
.footer-meta {
  font-size: 0.78rem;
  color: var(--text-muted);
}

.footer-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.footer-sep {
  opacity: 0.5;
}

.footer-meta a {
  color: var(--secondary-color);
}

/* Link to the static publication list (publications/index.html) */
.pub-static-link {
  margin: -14px 0 24px;
  text-align: right;
  font-size: 0.88rem;
  font-weight: 600;
}

.pub-static-link a {
  color: var(--secondary-color);
}

.noscript-note {
  margin: 0;
  padding: 12px 16px;
  text-align: center;
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

@media (max-width: 640px) {
  .site-footer {
    margin-top: 56px;
    padding: 24px 20px;
  }

  .footer-bottom {
    justify-content: flex-start;
  }
}

/* ==========================================================================
   Container & General Layout wrapper
   ========================================================================== */

.container {
  max-width: 1400px;
  margin: 0 auto;
  /* Sits flush under the fixed header - no gap above the tab covers */
  padding: var(--header-height) 24px 40px;
}

/* ==========================================================================
   Tab Fade Animations
   ========================================================================== */

.tab-content {
  display: none;
  opacity: 0;
}

.tab-content.active {
  display: block;
  animation: tabFadeInUp 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes tabFadeInUp {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes smoothFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

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

/* ==========================================================================
   Responsive Breakpoints
   ========================================================================== */

/* Between the icon-only nav (<=1024px) and a wide desktop, eleven labelled
   buttons plus icons overrun the header. Drop the icons and tighten padding
   so the labels, logo and theme toggle all fit on one row. */
@media (min-width: 1025px) and (max-width: 1500px) {
  .nav-btn {
    padding: 7px 9px;
    font-size: 0.85rem;
  }

  .nav-btn i {
    display: none;
  }

  .nav-menu {
    gap: 2px;
  }
}

@media (min-width: 1025px) and (max-width: 1180px) {
  .nav-btn {
    padding: 6px 6px;
    font-size: 0.8rem;
  }

  .logo-name {
    font-size: 1.15rem;
  }
}

@media (max-width: 1200px) {
  .home-content {
    grid-template-columns: 300px 1fr;
    gap: 30px;
  }

  .profile-image-container {
    max-width: 252px;
  }

  /* 252px interior here, so ~230px at 1.75rem. */
  .profile-identity h1 {
    font-size: 1.75rem;
  }
}

@media (max-width: 1024px) {
  .container {
    padding: var(--header-height) 20px 40px;
  }

  .software-container {
    grid-template-columns: 190px 1fr;
    gap: 20px;
  }

  .tools-content-container {
    padding: 24px;
  }

  .nav-btn span {
    display: none;
  }

  .nav-btn {
    padding: 10px;
    position: relative;
  }

  /* Labels are hidden in this range, which would otherwise leave eleven
     unlabelled icons. Surface the name on hover and keyboard focus. */
  .nav-btn::after {
    content: attr(data-nav-label);
    position: absolute;
    top: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(-4px);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--primary-color);
    color: var(--bg-secondary);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.01em;
    white-space: nowrap;
    box-shadow: var(--elev-2);
    opacity: 0;
    pointer-events: none;
    z-index: 1200;
    transition:
      opacity var(--transition-fast),
      transform var(--transition-fast);
  }

  .nav-btn:hover::after,
  .nav-btn:focus-visible::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

@media (max-width: 768px) {
  .container {
    padding: var(--header-height) 16px 32px;
  }

  .tab-cover {
    height: 120px;
    margin-bottom: var(--space-6);
  }

  .tab-cover.home-cover {
    height: 160px;
  }

  .header {
    padding: 12px 16px;
    gap: 12px;
  }

  /* Mobile header order: menu button → name → day/night toggle */
  .mobile-menu-toggle {
    display: block;
    z-index: 1001;
    order: 1;
  }

  .site-logo {
    order: 2;
    margin-right: auto;
    gap: 8px;
  }

  .logo-name {
    font-size: 0.9rem;
    letter-spacing: 0.03em;
  }

  .theme-toggle {
    order: 3;
  }

  .nav-menu {
    position: fixed;
    top: 0;
    left: -100%;
    width: 280px;
    height: 100vh;
    background: var(--bg-secondary);
    border-right: 1px solid var(--border-color);
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    padding: 80px 24px;
    gap: 10px;
    transition: left 0.3s cubic-bezier(0.16, 1, 0.3, 1);
    z-index: 1000;
    box-shadow: 10px 0 30px rgba(0, 0, 0, 0.1);
  }

  .nav-menu.active {
    left: 0;
  }

  .nav-btn {
    justify-content: flex-start;
    padding: 12px 16px;
  }

  .nav-btn span {
    display: inline;
  }

  .home-content {
    grid-template-columns: 1fr;
  }

  .profile-section {
    position: relative;
    top: 0;
  }

  /* The card goes full width here, so the identity can scale back up. */
  /* The card goes full width here, so the name can scale back up; it wraps
     rather than overflowing if it still runs out of room. */
  .profile-identity h1 {
    font-size: clamp(1.5rem, 6vw, 2rem);
  }

  .profile-identity .title {
    font-size: 0.95rem;
  }

  /* Software tab: stack sidebar nav above content */
  .software-container {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .tools-nav-container {
    position: relative;
    top: 0;
    margin-bottom: 20px;
  }

  .tools-nav {
    flex-direction: row;
    overflow-x: auto;
    padding: 6px;
    gap: 8px;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--border-color) transparent;
  }

  .tools-nav::-webkit-scrollbar {
    height: 6px;
  }

  .tools-nav::-webkit-scrollbar-thumb {
    background: var(--border-color);
    border-radius: 999px;
  }

  .tool-nav-btn {
    white-space: nowrap;
    flex: 0 0 auto;
    scroll-snap-align: start;
  }

  .tools-content-container {
    padding: 20px 16px;
    border-radius: var(--radius-md);
    min-height: 0;
    min-width: 0;
    max-width: 100%;
  }

  /* Prevent horizontal page drag: let grid/flex items shrink and wrap. */
  .software-container,
  .tools-nav-container,
  .tool-content,
  .tool-header,
  .tool-details,
  .tool-info-section,
  .tool-video-section,
  .tool-features-grid,
  .experience-item,
  .exp-details,
  .capability-item {
    min-width: 0;
    max-width: 100%;
  }

  .tool-content,
  .tool-description,
  .info-title,
  .exp-details h3,
  .company-name,
  .exp-duration,
  .software-features-list li,
  .capability-item span,
  .tool-info-section .bio-text {
    overflow-wrap: break-word;
    word-break: break-word;
  }

  .media-image-full,
  .media-image-contain,
  .video-wrapper,
  .video-wrapper iframe,
  .install-code-block {
    max-width: 100%;
  }

  .tool-header h2 {
    font-size: 1.4rem;
  }

  .tool-description {
    font-size: 0.95rem;
  }

  .tool-actions {
    justify-content: flex-start;
    gap: 8px;
    padding: 10px;
  }

  .tool-details {
    gap: 24px;
  }

  /* Hide the timeline-style dot when feature cards are reused in software */
  .tool-features-grid .experience-item::before {
    display: none;
  }

  .exp-header {
    padding: 18px;
    gap: 16px;
  }

  .education-container,
  #experience-container {
    padding-left: 30px;
  }

  .education-container .experience-item::before,
  #experience-container .experience-item::before {
    left: -22px;
  }

  /* No room for the connector tick once the rail sits this close */
  .education-container .experience-item::after,
  #experience-container .experience-item::after {
    display: none;
  }

  /* Projects timeline folds to a single left-hand rail */
  .project-timeline {
    padding-left: 30px;
  }

  .project-timeline::before {
    left: 13px;
    margin-left: 0;
  }

  .project-entry,
  .project-entry.is-right {
    width: auto;
    margin-left: 0;
    margin-top: 0;
    margin-bottom: var(--project-gap);
  }

  /* The pill no longer fits in the gutter, so it moves above the card and a
     plain dot takes its place on the rail. */
  .project-entry.is-left .project-marker,
  .project-entry.is-right .project-marker {
    position: static;
    transform: none;
    display: inline-block;
    margin-bottom: 10px;
    box-shadow: none;
  }

  .project-entry::after {
    display: none;
  }

  .project-entry::before {
    content: "";
    position: absolute;
    top: 9px;
    left: -22px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--bg-secondary);
    border: 2px solid var(--border-color);
    box-shadow: 0 0 0 5px var(--bg-primary);
  }

  .project-entry:hover::before {
    border-color: var(--secondary-color);
    background: var(--secondary-color);
  }

  .role-timeline {
    padding-left: 18px;
  }

  .role-entry::before {
    left: -22px;
  }

  .software-features-list li {
    padding: 14px 16px;
    font-size: 0.88rem;
  }

  .capabilities-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .contact-methods {
    grid-template-columns: 1fr;
  }

  /* On mobile, drop the fixed floating bar (it blocked content while
     scrolling) and let the icons sit in normal flow before the footer. */
  .social-floating {
    position: static;
    top: auto;
    bottom: auto;
    right: auto;
    left: auto;
    transform: none;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin: 48px auto 0;
    padding: 0 16px;
  }

  /* Icons sit in a row here, so the visitor popover opens above its icon */
  .flag-counter-popover {
    right: auto;
    left: 50%;
    bottom: calc(100% + 12px);
    max-width: calc(100vw - 32px);
    transform: translateX(calc(-50% + var(--popover-shift, 0px)));
  }

  .scroll-to-top {
    bottom: 24px;
    right: 24px;
  }
}

@media (max-width: 480px) {
  .container {
    padding: var(--header-height) 12px 28px;
  }

  /* Keep the name from crowding the menu button + toggle on small phones */
  .logo-name {
    font-size: 0.8rem;
  }

  .cover-title {
    font-size: 1.35rem;
  }

  /* Software tab on small phones */
  .tools-content-container {
    padding: 16px 12px;
  }

  .tool-header h2 {
    font-size: 1.25rem;
  }

  .tool-description {
    font-size: 0.9rem;
  }

  /* Stack the feature-card logo above its text */
  .exp-header {
    flex-direction: column;
    gap: 12px;
    padding: 16px;
  }

  .education-container .company-logo {
    width: 100%;
    height: 140px;
    align-self: auto;
  }

  #experience-container .company-logo {
    width: 140px;
    height: 100px;
    align-self: flex-start;
  }

  /* Action buttons span the full row so they stay tappable */
  .tool-actions .doi-link {
    flex: 1 1 100%;
  }

  .capabilities-grid {
    grid-template-columns: 1fr 1fr;
  }

  .software-features-list li {
    align-items: flex-start;
  }
}
