/* ==========================================================================
   S Prajwall Narayana — portfolio stylesheet
   Rewritten 9 Aug 2026: flat, quiet, no gradients.

   What this replaced and why
   --------------------------
   The previous stylesheet had fourteen gradient declarations, an animated
   starfield canvas behind the hero, glow effects on headings and borders, a
   floating profile card, a marquee, 3D tilt on every card and buttons that
   moved toward the cursor. Individually each is a small trick; together they
   competed with the content and read as a template rather than as a person.

   The rules this file follows:
     1. No gradients. Flat surfaces, separated by a single hairline border.
     2. One accent colour, used only for links, focus and the primary button.
        Not for decoration.
     3. Type carries the hierarchy. Size, weight and space do the work that
        glow and colour were doing.
     4. Motion is limited to opacity and a few pixels of travel, and is
        removed entirely under prefers-reduced-motion.
     5. Both themes are first class. Nothing is tuned for dark and inherited
        by light.
   ========================================================================== */

:root {
  /* DARK IS THE DEFAULT, and that is not a style preference — it is the contract
     site.js already implements: it removes the data-theme attribute for dark and sets
     data-theme="light" on <body> for light. The first draft of this stylesheet listened for
     :root[data-theme='dark'] on <html>, which the script never sets, so the toggle changed
     nothing. Match the script; do not "fix" the script to match a stylesheet. */
  --bg: #0E1116;
  --bg-subtle: #151A21;
  --bg-raised: #171C24;
  --border: #262D37;
  --border-strong: #38414E;
  --text: #E8EBEF;
  --text-muted: #A3ADB9;
  --text-faint: #78828E;

  --accent: #7BA2F5;
  --accent-hover: #A2BEFA;
  --accent-wash: #182238;

  --ok: #4FBF9B;
  --warn: #D8A63C;

  --radius: 8px;
  --radius-sm: 5px;
  --maxw: 1080px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);

  --step-1: 0.82rem;
  --step0: 1rem;
  --step1: 1.13rem;
  --step2: 1.4rem;
  --step3: 1.85rem;
  --step4: clamp(2.1rem, 5vw, 3.1rem);

  --speed: 140ms;

  color-scheme: dark;
}

/* Light: set by the toggle on <body>. Declared on body rather than :root because that is
   where the script writes, and body is an ancestor of everything that reads these. */
body[data-theme='light'] {
  --bg: #FFFFFF;
  --bg-subtle: #F7F8FA;
  --bg-raised: #FFFFFF;
  --border: #E3E6EA;
  --border-strong: #CDD3DA;
  --text: #16191D;
  --text-muted: #5B646E;
  --text-faint: #8B939C;

  --accent: #2A5BD7;
  --accent-hover: #1E45A8;
  --accent-wash: #EEF2FC;

  --ok: #17795E;
  --warn: #9A6700;

  color-scheme: light;
}

/* ── Base ────────────────────────────────────────────────────────────────── */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  /* Sora carries no CJK, Devanagari or Kannada glyphs, so the ja, hi, kn and mr
     pages fall through to whatever the OS picks by default. Naming the usual
     system faces makes that choice predictable instead. A font listed here that
     is not installed costs nothing: the browser skips it, and Latin text never
     reaches these entries because Sora already covers it. */
  font-family: 'Sora', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
    'Hiragino Sans', 'Yu Gothic', 'Noto Sans JP', 'Noto Sans CJK JP', Meiryo,
    'Noto Sans Devanagari', 'Noto Sans Kannada', sans-serif;
  font-size: var(--step0);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

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

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

h1, h2, h3, h4 {
  font-family: 'Poppins', 'Sora', ui-sans-serif, system-ui, sans-serif;
  line-height: 1.22;
  letter-spacing: -0.02em;
  margin: 0;
  font-weight: 650;
}

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

ul { margin: 0; padding-left: 1.15rem; }
li { margin-bottom: 0.35rem; }
li:last-child { margin-bottom: 0; }

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

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: #fff;
  padding: 0.6rem 1rem; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

/* The previous design painted an animated starfield behind the hero.
   The canvas element is still emitted; it is simply not shown. */
#particles-canvas { display: none !important; }

/* ── Region bar ──────────────────────────────────────────────────────────── */

.region-bar {
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--border);
  font-size: var(--step-1);
}
.region-bar-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0.55rem var(--gutter);
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.region-bar-text { margin: 0; color: var(--text-muted); }

.region-switcher { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.region-switcher label { color: var(--text-muted); }
.region-switcher select {
  font: inherit;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.22rem 0.5rem;
}

.lang-switcher {
  display: inline-flex; align-items: center; gap: 0.1rem;
  margin-left: 0.75rem; padding-left: 0.75rem;
  border-left: 1px solid var(--border);
  flex-wrap: wrap;
}
.lang-switcher a, .lang-switcher .lang-current {
  padding: 0.12rem 0.42rem;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.lang-switcher a { color: var(--text-muted); text-decoration: none; }
.lang-switcher a:hover { color: var(--accent); background: var(--accent-wash); text-decoration: none; }
.lang-switcher .lang-current { color: var(--text); font-weight: 600; background: var(--bg); border: 1px solid var(--border); }

@media (max-width: 640px) {
  .lang-switcher { margin-left: 0; padding-left: 0; border-left: 0; width: 100%; }
}

/* ── Nav ─────────────────────────────────────────────────────────────────── */

.navbar {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: saturate(1.6) blur(8px);
  border-bottom: 1px solid var(--border);
}
.nav-container {
  max-width: var(--maxw); margin: 0 auto;
  padding: 0.75rem var(--gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.logo { display: flex; align-items: center; gap: 0.5rem; }
.logo-text { font-family: 'Poppins', sans-serif; font-weight: 700; font-size: var(--step1); color: var(--text); letter-spacing: -0.02em; }
.logo:hover { text-decoration: none; }

.nav-links {
  display: flex; align-items: center; gap: clamp(0.85rem, 2vw, 1.5rem);
  list-style: none; margin: 0; padding: 0; flex-wrap: nowrap;
}
.nav-links li { margin: 0; }
.nav-links a {
  color: var(--text-muted);
  font-size: 0.94rem;
  padding: 0.25rem 0;
  border-bottom: 2px solid transparent;
}
.nav-links a:hover { color: var(--text); text-decoration: none; border-bottom-color: var(--border-strong); }
.nav-links a.is-current { color: var(--text); border-bottom-color: var(--accent); }

.theme-toggle, .hamburger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  cursor: pointer; font-size: 0.9rem;
  transition: color var(--speed) ease, border-color var(--speed) ease;
}
.theme-toggle:hover, .hamburger:hover { color: var(--text); border-color: var(--border-strong); }
.hamburger { display: none; }

@media (max-width: 820px) {
  .hamburger { display: inline-flex; }
  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: flex-start; gap: 0;
    background: var(--bg); border-bottom: 1px solid var(--border);
    padding: 0.5rem var(--gutter) 1rem;
    display: none;
  }
  .nav-links.open { display: flex; }
  .nav-links a { padding: 0.6rem 0; width: 100%; border-bottom: 1px solid var(--border); }
}

/* ── Layout ──────────────────────────────────────────────────────────────── */

.section { padding: clamp(3rem, 8vw, 5.5rem) var(--gutter); max-width: var(--maxw); margin: 0 auto; }
.section + .section { border-top: 1px solid var(--border); }

.section-header { margin-bottom: 2.25rem; max-width: 60ch; }
.section-title { font-size: var(--step3); margin: 0 0 0.4rem; }
.section-subtitle { color: var(--text-muted); margin: 0; font-size: var(--step0); }

/* ── Hero ────────────────────────────────────────────────────────────────── */

.hero {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: clamp(2.5rem, 7vw, 4.5rem) var(--gutter);
}
.hero-content {
  max-width: var(--maxw); margin: 0 auto;
  display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 4rem); align-items: center;
}
.hero-greeting {
  color: var(--accent); font-size: var(--step-1);
  font-weight: 600; letter-spacing: 0.02em;
  margin-bottom: 0.5rem;
}
.hero-text h1 { font-size: var(--step4); margin: 0 0 0.5rem; }
.glow-text { color: var(--text); }         /* was a text-shadow glow */
.hero-text .subtitle {
  font-size: var(--step2); color: var(--text); font-weight: 600;
  margin: 0 0 1rem; min-height: 1.6em;
}
.hero-text .subtitle strong { font-weight: 700; }
.typing-cursor { color: var(--accent); font-weight: 400; }
.hero-text .description { color: var(--text-muted); max-width: 62ch; margin-bottom: 1.5rem; }
.hero-text .description strong { color: var(--text); font-weight: 600; }

.work-auth {
  display: flex; gap: 0.6rem;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 0.85rem 1rem;
  font-size: 0.92rem; color: var(--text-muted);
  margin: 0 0 1.5rem;
}
.work-auth i { color: var(--accent); margin-top: 0.25rem; }
.work-auth strong { color: var(--text); }

.hero-buttons { display: flex; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 2rem; }

.hero-stats { display: flex; gap: clamp(1.5rem, 5vw, 3rem); flex-wrap: wrap; }
/* Markup is a definition list: <dt> label, then <dd> number. Visually the number leads,
   so the flex order is reversed rather than the markup, which stays semantic. */
.hero-stats { display: flex; flex-wrap: wrap; gap: clamp(1.5rem, 5vw, 3rem); margin: 0; }
.stat-item { display: flex; flex-direction: column-reverse; min-width: 6rem; }
.stat-item dt, .stat-item dd { margin: 0; }
.stat-number {
  font-family: 'Poppins', sans-serif;
  font-size: var(--step3); font-weight: 700;
  color: var(--text); line-height: 1.15;
}
.stat-item dt { color: var(--text-muted); font-size: var(--step-1); line-height: 1.4; }

/* Profile card — was a floating, tilting, flipping card */
.hero-visual { display: flex; justify-content: center; }
.flip-card { width: 100%; max-width: 270px; }
.flip-card-inner { position: relative; }
.flip-card-front, .flip-card-back {
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.6rem 1.25rem;
  text-align: center;
}
.flip-card-back { margin-top: 0.75rem; }
.profile-image {
  width: 118px; height: 118px; border-radius: 50%;
  object-fit: cover; margin: 0 auto 0.9rem;
  border: 1px solid var(--border-strong);
}
.flip-name { font-family: 'Poppins', sans-serif; font-weight: 650; margin-bottom: 0.15rem; }
.flip-card-front > div:not(.flip-name), .flip-card-back p { color: var(--text-muted); font-size: 0.92rem; }

.status-badge {
  display: inline-flex; align-items: center; gap: 0.45rem;
  margin-top: 0.85rem; padding: 0.28rem 0.7rem;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 999px; font-size: var(--step-1); color: var(--text-muted);
}
.status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex: none; }

@media (max-width: 880px) {
  .hero-content { grid-template-columns: 1fr; }
  .hero-visual { order: -1; justify-content: flex-start; }
  .flip-card { max-width: 220px; }
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.62rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--bg-raised); color: var(--text);
  font: inherit; font-size: 0.95rem; font-weight: 550;
  cursor: pointer; text-decoration: none;
  transition: background var(--speed) ease, border-color var(--speed) ease, color var(--speed) ease;
}
.btn:hover { text-decoration: none; border-color: var(--text-faint); background: var(--bg-subtle); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: #fff; }
.btn-secondary { background: var(--bg-raised); }

/* CV downloads.
   A region can offer more than one document (its own CV, and the shared academic
   one for MSc applications). With a single document the build emits a plain .btn
   and nothing here applies; with several it emits this list instead. Deliberately
   no new visual treatment: the same buttons, continuing the hero row at the same
   gap, because a second CV is a second option and not a second kind of thing. */
.cv-downloads {
  display: flex; flex-wrap: wrap; gap: 0.7rem;
  margin: 0; padding: 0; list-style: none;
}
.cv-downloads li { margin: 0; }

/* CV preview modal.
   Emitted only where a region offers exactly one document, and unhidden by
   site.js, which also points the iframe at the PDF on open. It had no rules at
   all in this sheet until now: no CV PDF was committed, so nothing could open
   it. Flat, like everything else: a panel on a dimmed page, hairline borders,
   no shadow stack. */
.cv-modal {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: var(--gutter);
  background: rgba(14, 17, 22, 0.55);
}
.cv-modal[hidden] { display: none; }
.cv-modal-panel {
  display: flex; flex-direction: column;
  width: min(920px, 100%); max-height: min(86vh, 900px);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  overflow: hidden;
}
.cv-modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.9rem 1.1rem;
  border-bottom: 1px solid var(--border);
}
.cv-modal-head h2 { font-size: var(--step1); margin: 0; }
.cv-modal-close {
  flex: none; width: 34px; height: 34px;
  display: grid; place-items: center;
  background: var(--bg-raised); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font: inherit; cursor: pointer;
}
.cv-modal-close:hover { color: var(--text); border-color: var(--border-strong); }
#cv-frame {
  flex: 1 1 auto; width: 100%; min-height: 55vh;
  border: 0; background: var(--bg-subtle);
}
.cv-modal-actions {
  display: flex; flex-wrap: wrap; gap: 0.7rem;
  padding: 0.9rem 1.1rem;
  border-top: 1px solid var(--border);
}
@media (max-width: 768px) {
  /* site.js loads the PDF into the frame only above 768px. A phone gets the two
     buttons instead of an inline render nobody can read. */
  #cv-frame { display: none; }
  .cv-modal-panel { max-height: none; }
}

/* ── Cards, shared ───────────────────────────────────────────────────────── */

.about-card, .skill-category, .timeline-card, .project-waterfall-card, .pub-item, .contact-item {
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.35rem 1.4rem;
}
.about-card:hover, .skill-category:hover, .project-waterfall-card:hover, .pub-item:hover {
  border-color: var(--border-strong);
}
/* The old sheet animated a moving gradient border on these. */
.glow-border { border: 1px solid var(--border); }

.about-card h3, .skill-category h3, .timeline-card h3, .project-title, .pub-item h3 {
  font-size: var(--step1); margin: 0 0 0.5rem;
}
.about-card i, .skill-category i, .contact-icon i, .project-icon i {
  color: var(--accent); font-size: 1.05rem;
}
.about-card p, .timeline-card p, .pub-item p { color: var(--text-muted); margin: 0; }

/* About */
#about .stagger-children, .about-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem;
}

/* Skills */
.skills-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; }
/* These are <ul>s. Without resetting the list styling they render a disc marker AND the
   pill, which is what the first pass shipped. */
.skill-tags, .project-tags, .timeline-tags {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  margin: 0.8rem 0 0; padding: 0; list-style: none;
}
.skill-tags li, .project-tags li, .timeline-tags li { margin: 0; }
.skill-tag, .project-tag {
  font-size: 0.8rem; color: var(--text-muted);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 999px; padding: 0.16rem 0.6rem;
}

/* Timeline.
   The build reuses .skills-grid as the container for experience and education, so without
   this they render as three columns and the Colligence card — six bullets — towers over two
   short ones. A career history reads top to bottom; force a single column back. */
#experience .skills-grid,
#education .skills-grid { grid-template-columns: 1fr; }

.timeline-card { margin-bottom: 0; }
.timeline-card:last-child { margin-bottom: 0; }
.timeline-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 0.15rem;
}
.timeline-date { color: var(--text-faint); font-size: var(--step-1); white-space: nowrap; }
.timeline-org { color: var(--text-muted); font-size: 0.94rem; margin-bottom: 0.75rem; }
.timeline-card ul { color: var(--text-muted); }
.timeline-card strong { color: var(--text); }

/* Projects */
.projects-waterfall { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 1rem; }
.project-icon { margin-bottom: 0.7rem; }
.project-subtitle { color: var(--text-muted); font-size: 0.94rem; margin: -0.25rem 0 0.6rem; }
.project-description { color: var(--text-muted); font-size: 0.94rem; }
.project-metrics {
  margin-top: 0.85rem; padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  font-size: 0.88rem; color: var(--text-muted);
}
.project-metrics strong { color: var(--text); }
.project-links { display: flex; gap: 1rem; margin-top: 0.9rem; }
.project-link { font-size: 0.9rem; }

/* Publications */
.pub-list { display: grid; gap: 0.85rem; }
.pub-venue { color: var(--text-faint); font-size: 0.9rem; }
.pub-note { color: var(--text-muted); font-size: 0.92rem; margin-top: 1rem; }

/* Contact */
.contact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; }
.contact-item { display: flex; gap: 0.85rem; align-items: flex-start; }
.contact-icon { flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.contact-details strong { display: block; font-size: var(--step-1); color: var(--text-faint); font-weight: 500; }
.contact-details p, .contact-details a { margin: 0; font-size: 0.95rem; }
.contact-info { margin-bottom: 1.5rem; }

.social-links { display: flex; gap: 0.6rem; }
.social-link {
  width: 38px; height: 38px; display: grid; place-items: center;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-muted); background: var(--bg-raised);
}
.social-link:hover { color: var(--accent); border-color: var(--border-strong); text-decoration: none; }

/* ── Footer ──────────────────────────────────────────────────────────────── */

.footer { border-top: 1px solid var(--border); background: var(--bg-subtle); }
.footer-content {
  max-width: var(--maxw); margin: 0 auto;
  padding: 1.75rem var(--gutter);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}
.footer-text { color: var(--text-faint); font-size: var(--step-1); margin: 0; }

.back-to-top {
  position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 30;
  width: 40px; height: 40px; display: grid; place-items: center;
  background: var(--bg-raised); color: var(--text-muted);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  cursor: pointer; opacity: 0; pointer-events: none;
  transition: opacity var(--speed) ease, color var(--speed) ease;
}
.back-to-top.visible { opacity: 1; pointer-events: auto; }
.back-to-top:hover { color: var(--accent); }

/* ── Motion ──────────────────────────────────────────────────────────────── */

/* The observer in site.js adds `active` — not `visible`. Getting that wrong leaves
   every section at opacity 0, which is exactly what happened on the first pass of this
   rewrite. Default is VISIBLE: content must never depend on script to be readable, so the
   hidden start state is only applied where scripting is actually available. */
.reveal, .stagger-children { opacity: 1; transform: none; }

@media (scripting: enabled) {
  .reveal, .stagger-children {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 300ms ease, transform 300ms ease;
  }
  .reveal.active, .stagger-children.active { opacity: 1; transform: none; }
}

/* These classes exist for JS that has been removed; neutralise them. */
.tilt-card { transform: none !important; }
.magnetic-btn { transform: none !important; }
.float { animation: none !important; }

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

/* ── Print ───────────────────────────────────────────────────────────────── */

@media print {
  .region-bar, .navbar, .back-to-top, .theme-toggle, .hamburger, .social-links { display: none; }
  body { color: #000; background: #fff; }
  .section { padding: 1rem 0; break-inside: avoid; }
  a { color: #000; text-decoration: underline; }
}

/* ── Country backdrop ──────────────────────────────────────────────────────
   A faded outline of the region's country behind the hero. Present on the UK,
   US, Japan and Germany pages; India deliberately has none.

   "Neon" here means a thin accent stroke, not a glow stack: one colour, one
   stroke width, low opacity. Anything brighter competes with the text sitting
   on top of it, which is the mistake the flat rewrite existed to undo. It is
   decorative, so it is aria-hidden in the markup and hidden from print. */
.country-map {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* Centred behind the whole hero rather than tucked to one side. Offset to the
     right it sat behind the profile card and only its edges showed, which read
     as a stray shape rather than a country. */
  width: clamp(320px, 46vw, 620px);
  height: auto;
  z-index: 0;
  pointer-events: none;
  opacity: 0.07;
}
.country-map path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* The hero already establishes a stacking context for it, and the content has
   to sit above. */
.hero { position: relative; overflow: hidden; }
.hero-content { position: relative; z-index: 1; }

@media (max-width: 880px) {
  /* On a narrow screen the outline lands underneath the text rather than beside
     it, so it is pushed further back. */
  .country-map { opacity: 0.05; width: 74vw; }
}

@media print { .country-map { display: none; } }

/* ── UI refinements (2026-08) — sharper headings, accent marks, card hover ── */
.section-title { letter-spacing: -0.03em; font-size: clamp(1.55rem, 3.2vw, 2.05rem); line-height: 1.1; }
.section-header { position: relative; }
.section-header::before {
  content: ""; display: block; width: 32px; height: 3px; border-radius: 3px;
  background: var(--accent); margin-bottom: 0.85rem; opacity: 0.9;
}
h1, h2, h3, .flip-name, .logo-text { letter-spacing: -0.025em; }

.about-card, .skill-category, .project-waterfall-card, .timeline-item, .contact-card, .publication-card {
  transition: transform var(--speed) ease, border-color var(--speed) ease, background var(--speed) ease, box-shadow var(--speed) ease;
}
.about-card:hover, .skill-category:hover, .project-waterfall-card:hover, .contact-card:hover {
  transform: translateY(-3px);
  border-color: var(--border-strong);
  box-shadow: 0 8px 28px -12px rgba(0,0,0,0.45);
}
.project-tag, .skill-tag { transition: border-color var(--speed) ease, color var(--speed) ease; }
.project-tag:hover, .skill-tag:hover { border-color: var(--accent); color: var(--text); }
.stat-number { letter-spacing: -0.03em; }
