:root {
  /* Light theme — the hero's resting state, before any section theme class
     lands on <body>. Only THREE visual states exist (see the scrollTheme
     IntersectionObserver in script.js): :root/body.theme-about (light —
     shared by the hero, 핵심역량, 경력사항, AND 활동사항, so there's no
     color change at all crossing those section boundaries), body.theme-dark
     (Skills only), and body.theme-research (darkest, the final section).
     경력사항/활동사항 were previously dark (grouped with Skills) but were
     moved onto theme-about per an explicit ask to keep 01→02→03 one
     unbroken light block and only go dark starting at Skills — see the
     comment on body.theme-about for what had to change to make that work.
     --text/--text-dim are verified ≥4.5:1 (WCAG AA body-text) against their
     own step's --bg; --text-faint (meta labels: dates, venues) is
     best-effort ≥3:1 only, matching this site's pre-existing baseline where
     even the original light theme's faint tone never cleared 4.5:1 against
     white either. */
  --bg: #ffffff;
  --bg-alt: #f9fafb;
  --card: #ffffff;
  --elevated: #f2f4f7;
  --border: #f2f4f6;
  --border-strong: #e5e8eb;
  --text: #191f28;
  --text-dim: #4e5968;
  --text-faint: #8b95a1;
  --primary: #3182f6;
  --primary-hover: #1b64da;
  --primary-tint: #eaf2ff;
  --tint-blue: #eaf2ff;
  --tint-green: #e3f9ee;
  --tint-purple: #f1ecff;
  --tint-orange: #fff2e0;
  --tint-pink: #ffe8f1;
  --tint-teal: #e2f8fa;
  --accent-green: #12b76a;
  --radius-lg: 24px;
  --radius-md: 16px;
  --shadow-sm: 0 2px 10px rgba(15, 23, 42, 0.05);
  --shadow-md: 0 8px 28px rgba(15, 23, 42, 0.08);
  --shadow-card: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 20px -6px rgba(15, 23, 42, 0.08);
  --shadow-card-hover: 0 20px 40px -12px rgba(15, 23, 42, 0.18), 0 4px 10px -2px rgba(15, 23, 42, 0.08);
  --nav-bg: rgba(255, 255, 255, 0.85);
  --sans: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', sans-serif;
}

/* About: light gray, dark text (near-identical to :root, since #e8e9eb is
   barely darker than white) — also now covers 경력사항 (Experience) and
   활동사항 (Activities), which used to be dark. Moving those two onto this
   palette meant re-checking every timeline component that had only ever
   been designed/verified against a dark background:
   - `.tl-role`/`.tl-date` (e.g. "AI Research Engineer", the company/period
     pill) render as `var(--primary)` text — but this section's --bg/--card
     only gave #3182f6 ~3.1–3.7:1, short of AA. Rather than darkening
     --primary globally (it's the site's signature Toss-blue, used
     everywhere from nav links to buttons), `.tl-role`/`.tl-date` are
     hardcoded to a darker `#1c4ed8` instead — both classes render
     exclusively inside Experience/Activities, so hardcoding doesn't cost
     theme-reactivity anywhere else. Verified 6.7:1 against this section's
     --bg (now pure white — see below).
   - The `#experience`/`#activities` category timeline-dot colors (further
     below) were originally tuned for a dark background and measured only
     ~1.8–2.8:1 here — nowhere close to WCAG 1.4.11's 3:1 non-text minimum.
     Replaced with a darker green (`#0e8a4a`, 4.4:1) and darker blue
     (`#1c4ed8`, 6.7:1 — reusing the same blue as `.tl-role`/`.tl-date`
     above, so there's only one "timeline blue" in this context).
   - `.badge` ("공동 개발, 기여도 60%") went back to `var(--bg-alt)` +
     `var(--text-faint)` (4.6:1) instead of the translucent-white dark chip
     it had before — a light chip on a light background is the same
     `.tag`/`.award-item` pattern used elsewhere on this page.
   - `.stat-badge` ("62%→74%") and the timeline's own `--primary`-tinted
     `.tl-date` pill background needed no changes — both are already proven
     on this exact palette elsewhere in 핵심역량. */
body.theme-about {
  /* --bg/--bg-alt/--card/--elevated were a light gray (#e8e9eb family)
     until an explicit ask to make this stretch "아예 흰색" — now byte-for-
     byte the same white-family values :root already used pre-theme-system,
     i.e. this section's cards go back to the original "flat white, shadow-
     only elevation" Toss look instead of a slightly-off-white card floating
     on a slightly-more-off-white page. Every fixed/tuned accent color above
     (text-faint, the timeline blue/green, badge) was re-verified against
     pure white and all improved or held steady — nothing needed retuning. */
  --bg: #ffffff;
  --bg-alt: #f9fafb;
  --card: #ffffff;
  --elevated: #f2f4f7;
  /* --border kept well above :root's original (near-invisible) #f2f4f6 —
     with About/Experience/Activities all sharing one flat white page now,
     this 1px `.section` border-top is the ONLY signal marking a new
     section (no color change to lean on), and pure white makes a subtle
     border even harder to see than the previous off-white did — bumped
     further (0.16→0.32) to compensate, verified visually via screenshot. */
  --border: rgba(25, 31, 40, 0.32);
  --border-strong: rgba(25, 31, 40, 0.42);
  --text: #191f28;
  --text-dim: #4e5968;
  --text-faint: #6b7280;
}

/* Skills only now (see body.theme-about above for why Experience/Activities
   moved off this block). --primary reuses the existing dark-theme blue
   (#5b9df5) — clears 4.92:1 against this --bg. */
body.theme-dark {
  --bg: #2c2e31;
  --bg-alt: #34373b;
  --card: #34373b;
  --elevated: #3c4045;
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.14);
  --text: #f5f5f5;
  --text-dim: #c9ccd1;
  --text-faint: #8b8f96;
  --primary: #5b9df5;
  --primary-hover: #4785e0;
  --primary-tint: rgba(91, 157, 245, 0.16);
  --tint-blue: rgba(91, 157, 245, 0.18);
  --tint-green: rgba(95, 214, 148, 0.18);
  --tint-purple: rgba(167, 139, 235, 0.2);
  --tint-orange: rgba(255, 175, 94, 0.18);
  --tint-pink: rgba(240, 128, 178, 0.18);
  --tint-teal: rgba(78, 209, 197, 0.18);
  --accent-green: #5fd694;
  --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 8px 28px rgba(0, 0, 0, 0.4);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 8px 20px -6px rgba(0, 0, 0, 0.45);
  --shadow-card-hover: 0 20px 40px -12px rgba(0, 0, 0, 0.55), 0 4px 10px -2px rgba(0, 0, 0, 0.4);
  --nav-bg: rgba(44, 46, 49, 0.85);
}

/* Research: the darkest gray — one step further than body.theme-dark,
   kept byte-for-byte identical to the old body.scroll-dark palette this
   whole system replaces, per the original ask ("기존 다크 변수 유지"). */
body.theme-research {
  --bg: #121417;
  --bg-alt: #1a1d21;
  --card: #1a1d21;
  --elevated: #22262b;
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.14);
  --text: #f5f5f5;
  --text-dim: #c9ccd1;
  --text-faint: #8b8f96;
  --primary: #5b9df5;
  --primary-hover: #4785e0;
  --primary-tint: rgba(91, 157, 245, 0.16);
  --tint-blue: rgba(91, 157, 245, 0.18);
  --tint-green: rgba(95, 214, 148, 0.18);
  --tint-purple: rgba(167, 139, 235, 0.2);
  --tint-orange: rgba(255, 175, 94, 0.18);
  --tint-pink: rgba(240, 128, 178, 0.18);
  --tint-teal: rgba(78, 209, 197, 0.18);
  --accent-green: #5fd694;
  --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 8px 28px rgba(0, 0, 0, 0.4);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 8px 20px -6px rgba(0, 0, 0, 0.45);
  --shadow-card-hover: 0 20px 40px -12px rgba(0, 0, 0, 0.55), 0 4px 10px -2px rgba(0, 0, 0, 0.4);
  --nav-bg: rgba(18, 20, 23, 0.82);
}

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

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.5s ease, color 0.5s ease;
}

nav#nav {
  position: sticky;
  top: 0;
  z-index: 100;
  backdrop-filter: blur(12px);
  background: var(--nav-bg);
  border-bottom: 1px solid var(--border);
  transition: box-shadow 0.25s ease, backdrop-filter 0.25s ease, background-color 0.5s ease, border-color 0.5s ease;
}
nav#nav.nav-scrolled {
  backdrop-filter: blur(16px);
  box-shadow: 0 4px 20px rgba(15, 23, 42, 0.08);
}
.nav-inner {
  max-width: 1000px;
  margin: 0 auto;
  padding: 18px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.logo {
  font-weight: 800;
  color: var(--text);
  text-decoration: none;
  letter-spacing: -0.5px;
  font-size: 1.05rem;
}
.logo .dot { color: var(--primary); }
.nav-links { display: flex; gap: 28px; }
.nav-links a {
  color: var(--text-dim);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  transition: color 0.2s;
}
.nav-links a:hover { color: var(--primary); }

.hero {
  position: relative;
  overflow: hidden;
  min-height: calc(100vh - 64px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 100px 24px 60px;
  background:
    radial-gradient(at 12% 18%, rgba(59, 92, 246, 0.28), transparent 55%),
    radial-gradient(at 85% 12%, rgba(139, 92, 246, 0.25), transparent 50%),
    radial-gradient(at 22% 88%, rgba(219, 39, 119, 0.14), transparent 45%),
    radial-gradient(at 92% 82%, rgba(37, 99, 235, 0.22), transparent 55%),
    linear-gradient(160deg, #4a5578 0%, #5b6191 45%, #4f4a80 100%);
}
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
  pointer-events: none;
  object-fit: cover;
  z-index: 0;
  filter: brightness(1.15) saturate(1.05);
}
.hero-video-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(20, 22, 40, 0.3);
}
.hero-inner { position: relative; max-width: 780px; z-index: 2; }
.hero-inner-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  align-items: center;
  text-align: left;
  max-width: 1100px;
  width: 100%;
  background: rgba(20, 20, 30, 0.45);
  backdrop-filter: blur(28px);
  -webkit-backdrop-filter: blur(28px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  padding: 48px;
}
.hero-left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding-right: 40px;
}
.hero-left > * {
  opacity: 0;
  animation: heroFadeUp 0.7s ease forwards;
}
.hero-left > *:nth-child(1) { animation-delay: 0.05s; }
.hero-left > *:nth-child(2) { animation-delay: 0.15s; }
.hero-left > *:nth-child(3) { animation-delay: 0.28s; }
.hero-left > *:nth-child(4) { animation-delay: 0.4s; }
.hero-left > *:nth-child(5) { animation-delay: 0.5s; }
.hero-right {
  opacity: 0;
  animation: heroFadeUp 0.7s ease forwards;
  animation-delay: 0.3s;
  padding-left: 40px;
  border-left: 1px solid rgba(255, 255, 255, 0.12);
}
.hero-mini-group + .hero-mini-group {
  margin-top: 32px;
  padding-top: 28px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.hero-mini-title {
  display: inline-block;
  font-size: 0.76rem;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 999px;
  margin-bottom: 14px;
}
.hero-mini-group:nth-child(1) .hero-mini-title { color: #a8c8f5; background: rgba(96, 150, 230, 0.16); }
.hero-mini-group:nth-child(2) .hero-mini-title { color: #9adcb8; background: rgba(52, 199, 129, 0.16); }
.hero-mini-group:nth-child(3) .hero-mini-title { color: #cdb8f2; background: rgba(168, 116, 235, 0.18); }
.hero-mini-item + .hero-mini-item { margin-top: 14px; }
.hero-mini-main { font-size: 0.92rem; font-weight: 700; color: rgba(255, 255, 255, 0.92); line-height: 1.4; word-break: keep-all; }
.hero-mini-sub { font-size: 0.78rem; color: rgba(255, 255, 255, 0.55); margin-top: 3px; }
@keyframes heroFadeUp {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (max-width: 860px) {
  .hero-inner-split { grid-template-columns: 1fr; gap: 0; padding: 36px 28px; }
  .hero-left { padding-right: 0; }
  .hero-right {
    padding-left: 0;
    padding-top: 32px;
    margin-top: 32px;
    border-left: none;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
  }
}
.eyebrow {
  display: inline-block;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.3);
  font-size: 13px;
  font-weight: 700;
  padding: 7px 16px;
  border-radius: 999px;
  margin-bottom: 24px;
  letter-spacing: -0.2px;
}
.hero h1 {
  font-size: clamp(2.4rem, 7vw, 3.8rem);
  font-weight: 800;
  letter-spacing: -1.5px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: #ffffff;
}
.hero h1 .eng-name {
  font-size: 0.32em;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
  letter-spacing: -0.5px;
}
.tagline {
  margin-top: 28px;
  font-size: clamp(1rem, 2.2vw, 1.15rem);
  color: rgba(255, 255, 255, 0.88);
  line-height: 1.7;
}
.tagline .highlight {
  color: #ffffff;
  font-weight: 800;
}
.tagline-line1 { white-space: nowrap; }
.hero-contact {
  margin-top: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.hero-contact-line {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.58);
  display: flex;
  align-items: center;
  gap: 10px;
}
.hero-contact-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  line-height: 1;
  color: rgba(255, 255, 255, 0.7);
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  padding: 5px 9px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.hero-contact-copy:hover { background: rgba(255, 255, 255, 0.22); color: #ffffff; }
.hero-contact-copy.copied {
  font-size: 0.74rem;
  font-weight: 600;
  padding: 5px 11px;
  background: var(--accent-green);
  border-color: var(--accent-green);
  color: #ffffff;
}
/* Below the hero's stacked single-column breakpoint (860px), the nowrap
   above would force the span to demand ~435px regardless of viewport width
   — wider than the screen on a phone. Verified via headless-browser
   measurement that this clips text at that width without it (this rule
   must stay AFTER the unconditional .tagline-line1 rule above: equal-
   specificity CSS resolves ties by source order, so a media query placed
   earlier in the file loses to a later plain rule even when it matches).
   The explicit <br> in the markup still forces the same line break; only
   the "don't wrap mid-line" constraint is relaxed here. */
@media (max-width: 860px) {
  .tagline-line1 { white-space: normal; }
}
.type-cursor {
  display: inline-block;
  width: 2px;
  height: 0.9em;
  margin-left: 2px;
  background: currentColor;
  vertical-align: -0.05em;
  animation: heroTypeCursorBlink 0.85s steps(1) infinite;
}
@keyframes heroTypeCursorBlink {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .type-cursor { animation: none; opacity: 0; }
}
.hero-actions {
  margin-top: 36px;
  display: flex;
  gap: 12px;
  justify-content: flex-start;
  flex-wrap: wrap;
}
.btn {
  padding: 15px 26px;
  border-radius: 16px;
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  transition: all 0.15s ease;
  display: inline-block;
  border: 1px solid transparent;
}
.btn-primary {
  background: var(--primary);
  color: #ffffff;
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover { background: var(--primary-hover); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn-ghost {
  color: #ffffff;
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.35);
}
.btn-ghost:hover { background: rgba(255, 255, 255, 0.22); color: #ffffff; }

.scroll-cue {
  position: absolute;
  bottom: 36px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
}
.scroll-cue span {
  display: block;
  width: 2px;
  height: 36px;
  border-radius: 1px;
  background: linear-gradient(var(--primary), transparent);
  animation: scrollPulse 1.8s ease-in-out infinite;
}
@keyframes scrollPulse {
  0%, 100% { opacity: 0.2; }
  50% { opacity: 1; }
}

main { position: relative; z-index: 1; }
.section-inner { max-width: 1000px; margin: 0 auto; padding: 0 24px; }

.section {
  padding: 100px 0;
  border-top: 1px solid var(--border);
  transition: background-color 0.5s ease, border-color 0.5s ease;
}
.section:first-child { border-top: none; }

.section-title {
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-bottom: 40px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.section-title .num {
  font-size: 0.85rem;
  color: var(--primary);
  background: var(--primary-tint);
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 8px;
  transition: background-color 0.5s ease;
}
.section-sub { color: var(--text-dim); margin-bottom: 32px; margin-top: -20px; max-width: 640px; }
a.section-sub {
  display: block;
  text-decoration: none;
  cursor: pointer;
  transition: color 0.15s;
}
a.section-sub:hover { color: var(--primary); }

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}
.card {
  background: var(--card);
  /* Deliberately its own lighter border, not var(--border) — that token was
     bumped up (0.16→0.32) so the 01/02/03 section dividers stay visible now
     that they all share one flat white background, but these 6 card
     borders are a separate, purely decorative edge that reads better soft. */
  border: 1px solid rgba(25, 31, 40, 0.08);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.25s ease, transform 0.25s cubic-bezier(.2,.8,.2,1), border-color 0.25s ease, background-color 0.5s ease;
}
.card:hover { box-shadow: var(--shadow-card-hover); background-color: var(--elevated); transform: translateY(-6px); border-color: transparent; }
.card-icon {
  font-size: 1.3rem;
  margin-bottom: 14px;
  width: 44px; height: 44px;
  border-radius: 12px;
  background: var(--primary-tint);
  display: flex; align-items: center; justify-content: center;
  transition: background-color 0.5s ease;
}
.card-grid .card:nth-child(6n+1) .card-icon { background: var(--tint-blue); }
.card-grid .card:nth-child(6n+2) .card-icon { background: var(--tint-green); }
.card-grid .card:nth-child(6n+3) .card-icon { background: var(--tint-purple); }
.card-grid .card:nth-child(6n+4) .card-icon { background: var(--tint-orange); }
.card-grid .card:nth-child(6n+5) .card-icon { background: var(--tint-pink); }
.card-grid .card:nth-child(6n+6) .card-icon { background: var(--tint-teal); }
.card h3 { font-size: 1.02rem; font-weight: 700; margin-bottom: 8px; }
.card p { font-size: 0.9rem; color: var(--text-dim); }

.timeline { display: flex; flex-direction: column; gap: 48px; position: relative; }
.timeline::before {
  content: '';
  position: absolute;
  left: 8px;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--primary) 0%, rgba(49, 130, 246, 0.15) 45%, rgba(49, 130, 246, 0.15) 100%);
}
.timeline-item { position: relative; padding-left: 42px; }
.timeline-dot {
  position: absolute;
  left: 0; top: 3px;
  width: 19px; height: 19px;
  border-radius: 50%;
  background: var(--primary);
  border: 3px solid var(--card);
  box-shadow: 0 0 0 4px var(--primary-tint), 0 4px 10px rgba(49, 130, 246, 0.35);
  transition: border-color 0.5s ease, box-shadow 0.5s ease;
}

/* Category accent system, carried over from the hero card's 학력=blue /
   경력=green / 연구=purple color-coding so 경력사항's timeline reads as the
   same "career" color as the hero, and 활동사항 gets its own (blue, reusing
   the hero's 학력 hue since there's no dedicated "활동" hero color) instead
   of both timelines defaulting to the same plain --primary line/dot. These
   are decorative graphics, not body text, so WCAG 1.4.11's 3:1 non-text
   minimum applies (not 4.5:1) — but these two sections now sit on
   body.theme-about (light), and the original dark-tuned hues only cleared
   ~1.8–2.8:1 against a light --bg/--card, well under even that lower bar.
   Replaced with darker variants that keep the same green/blue identity:
   #0e8a4a (was #34c781, verified 3.6–4.1:1) and #1c4ed8 (was #6096e6,
   verified 5.5–6.2:1 — also reused as the shared "timeline blue" for
   .tl-role/.tl-date below, so there's only one blue in this context). */
#experience .timeline::before {
  background: linear-gradient(180deg, #0e8a4a 0%, rgba(14, 138, 74, 0.15) 45%, rgba(14, 138, 74, 0.15) 100%);
}
#experience .timeline-dot {
  background: #0e8a4a;
  box-shadow: 0 0 0 4px rgba(14, 138, 74, 0.18), 0 4px 10px rgba(14, 138, 74, 0.35);
}
#activities .timeline::before {
  background: linear-gradient(180deg, #1c4ed8 0%, rgba(28, 78, 216, 0.15) 45%, rgba(28, 78, 216, 0.15) 100%);
}
#activities .timeline-dot {
  background: #1c4ed8;
  box-shadow: 0 0 0 4px rgba(28, 78, 216, 0.18), 0 4px 10px rgba(28, 78, 216, 0.35);
}
.tl-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 4px;
}
.tl-header h3 { font-size: 1.1rem; font-weight: 700; }
/* .tl-date/.tl-role are hardcoded to #1c4ed8 (not var(--primary)) — both
   classes render exclusively inside Experience/Activities, which now sit
   on body.theme-about, where the site's regular --primary (#3182f6) only
   clears 3.06–3.43:1 against this section's --bg/--card (short of AA).
   Darkening --primary itself was avoided since it's the site's signature
   Toss-blue used everywhere else (nav, buttons, badges); hardcoding here
   costs nothing since neither class appears outside these two sections. */
.tl-date {
  font-size: 0.78rem;
  color: #1c4ed8;
  background: var(--primary-tint);
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 999px;
  white-space: nowrap;
  transition: background-color 0.5s ease;
}
.tl-role { color: #1c4ed8; font-size: 0.9rem; font-weight: 700; margin-bottom: 12px; }
.tl-project { margin-top: 18px; margin-bottom: 8px; font-weight: 700; font-size: 0.92rem; }
.badge {
  font-size: 0.72rem;
  color: var(--text-faint);
  font-weight: 500;
  margin-left: 8px;
  background: var(--bg-alt);
  padding: 2px 8px;
  border-radius: 6px;
  transition: background-color 0.5s ease, color 0.5s ease;
}
.timeline-content ul { padding-left: 18px; color: var(--text-dim); font-size: 0.9rem; }
.timeline-content li { margin-bottom: 6px; }
.timeline-content li strong { color: var(--text); }

.skills-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 28px;
}
.skill-group h4 {
  font-size: 0.85rem;
  color: var(--text-faint);
  margin-bottom: 14px;
  font-weight: 700;
}
.tags { display: flex; flex-wrap: wrap; gap: 8px; }
.tag {
  font-size: 0.83rem;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  color: var(--text-dim);
  transition: background-color 0.5s ease, border-color 0.5s ease, color 0.5s ease;
}

.awards { margin-top: 24px; display: flex; flex-direction: column; gap: 10px; }
.award-item {
  display: block;
  font-size: 0.9rem;
  color: var(--text-dim);
  text-decoration: none;
  padding: 14px 18px;
  background: var(--bg-alt);
  border-radius: 12px;
  transition: background 0.2s ease, transform 0.2s ease;
  cursor: default;
}
a.award-item { cursor: pointer; }
.award-item:hover { background: var(--primary-tint); transform: translateX(3px); }
.award-item strong { color: var(--text); font-weight: 700; }
.award-detail { margin-top: 6px; font-size: 0.82rem; color: var(--text-faint); }
.award-detail-highlight { color: var(--primary); }
.award-year {
  color: var(--text-faint);
  margin-right: 12px;
  font-size: 0.8rem;
  font-weight: 700;
}

.chat-box {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  background: var(--card);
}
.chat-messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: var(--bg-alt);
}
.msg { display: flex; gap: 12px; max-width: 92%; }
.msg-bot { align-self: flex-start; }
.msg-user { align-self: flex-end; flex-direction: row-reverse; }
.msg-avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--card);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
  flex-shrink: 0;
}
.msg-bubble {
  background: var(--card);
  border: 1px solid var(--border);
  padding: 14px 18px;
  border-radius: 16px;
  font-size: 0.98rem;
  line-height: 1.7;
  white-space: pre-wrap;
  color: var(--text);
}
.msg-user .msg-bubble { background: var(--primary); border-color: var(--primary); color: #ffffff; }
.msg-bubble.error { color: #ff8a8a; border-color: rgba(255, 107, 107, 0.35); background: rgba(255, 107, 107, 0.1); }
.msg-bubble .cite {
  display: block;
  margin-top: 8px;
  font-size: 0.72rem;
  color: var(--text-faint);
}
.msg-bubble strong { font-weight: 700; }
.msg-bubble ul { margin: 4px 0; padding-left: 20px; }
.msg-bubble li { margin: 2px 0; }
.msg-user .msg-bubble .cite { color: rgba(255,255,255,0.75); }

.typing-dots { display: inline-flex; gap: 4px; align-items: center; padding: 4px 0; }
.typing-dots span {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-faint);
  animation: typingBounce 1.2s infinite ease-in-out;
}
.typing-dots span:nth-child(2) { animation-delay: 0.15s; }
.typing-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-4px); opacity: 1; }
}

.chat-category-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  background: var(--bg-alt);
}
.chat-category-row label {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
}
.chat-category-row select {
  flex: 1;
  max-width: 260px;
  background: var(--card);
  border: 2px solid var(--primary);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 0.88rem;
  font-family: var(--sans);
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.chat-category-row select:hover { border-color: var(--primary-hover); }
.chat-category-row select:focus { outline: none; border-color: var(--primary-hover); }
.chat-category-row select.error {
  border-color: #ff6b6b;
  box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.18);
}

.category-hint {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 0.82rem;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.category-hint strong { color: var(--primary); }
.category-hint .hint-switch {
  border: none;
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s;
  background: var(--primary);
  color: #ffffff;
}
.category-hint .hint-switch:hover { background: var(--primary-hover); }

.chat-form {
  display: flex;
  border-top: 1px solid var(--border);
  background: var(--card);
}
.chat-form input {
  flex: 1;
  background: transparent;
  border: none;
  padding: 18px 20px;
  color: var(--text);
  font-size: 0.92rem;
  font-family: var(--sans);
}
.chat-form input:focus { outline: none; }
.chat-form input::placeholder { color: var(--text-faint); }
.chat-form button {
  background: var(--primary);
  color: #ffffff;
  border: none;
  padding: 0 28px;
  font-weight: 700;
  font-size: 0.88rem;
  cursor: pointer;
  transition: background 0.15s;
}
.chat-form button:hover { background: var(--primary-hover); }
.chat-form button:disabled { opacity: 0.4; cursor: not-allowed; }

.chat-suggestions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 14px 20px 18px;
  border-top: 1px solid var(--border);
  background: var(--card);
}
.suggestion {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 0.8rem;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.15s;
}
.suggestion:hover { background: var(--primary-tint); border-color: var(--primary-tint); color: var(--primary); }

.footer { border-top: 1px solid var(--border); padding: 32px 24px; position: relative; z-index: 1; background: var(--bg-alt); transition: background-color 0.5s ease, border-color 0.5s ease; }
.footer-inner {
  max-width: 1000px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 0.85rem;
  color: var(--text-faint);
}
.footer-links a { color: var(--text-faint); text-decoration: none; font-weight: 600; }
.footer-links a:hover { color: var(--primary); }
.footer .sep { margin: 0 8px; }

/* ── AI Q&A floating widget ─────────────────────────────────────────── */

.chat-launcher {
  position: fixed;
  right: 28px;
  bottom: 28px;
  z-index: 999;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 17px 26px;
  border-radius: 999px;
  border: none;
  background: var(--primary);
  color: #ffffff;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 14px 32px rgba(49, 130, 246, 0.4), var(--shadow-md);
  transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease, visibility 0s linear 0s;
}
.chat-launcher-icon { position: relative; z-index: 1; display: flex; }
.chat-launcher-icon svg { width: 22px; height: 22px; }
.chat-launcher-text { position: relative; z-index: 1; }
.chat-launcher::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--primary);
  opacity: 0.55;
  animation: launcherPulse 2.6s ease-out infinite;
  z-index: 0;
}
@keyframes launcherPulse {
  0% { transform: scale(1); opacity: 0.5; }
  100% { transform: scale(1.22); opacity: 0; }
}
.chat-launcher:hover { transform: scale(1.05); box-shadow: 0 16px 36px rgba(49, 130, 246, 0.5), var(--shadow-md); }
.chat-launcher.hidden {
  opacity: 0;
  visibility: hidden;
  transform: scale(0.8);
  transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease, visibility 0s linear 0.2s;
}

.chat-proactive {
  position: fixed;
  right: 28px;
  bottom: 106px;
  z-index: 998;
  max-width: 240px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px 16px 4px 16px;
  padding: 14px 34px 14px 16px;
  box-shadow: var(--shadow-md);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--text);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(0.96);
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s linear 0.35s;
}
.chat-proactive.show {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s linear 0s;
}
.chat-proactive-close {
  position: absolute;
  top: 6px;
  right: 8px;
  border: none;
  background: transparent;
  color: var(--text-faint);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  padding: 4px;
}
.chat-proactive-close:hover { color: var(--text); }

.chat-panel {
  position: fixed;
  right: 28px;
  bottom: 28px;
  z-index: 999;
  width: 440px;
  height: 700px;
  max-height: calc(100vh - 56px);
  background: var(--card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform-origin: bottom right;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.9) translateY(16px);
  transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0.25s, width 0.25s ease, height 0.25s ease;
}
.chat-panel.open {
  opacity: 1;
  visibility: visible;
  transform: scale(1) translateY(0);
  transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0s, width 0.25s ease, height 0.25s ease;
}
.chat-panel.expanded {
  width: min(760px, 92vw);
  height: min(860px, calc(100vh - 56px));
}

.chat-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  background: var(--primary);
  color: #ffffff;
  flex-shrink: 0;
}
.chat-panel-title { display: flex; align-items: center; gap: 10px; }
.chat-panel-emoji {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem;
  flex-shrink: 0;
}
.chat-panel-title-text { display: flex; flex-direction: column; line-height: 1.3; }
.chat-panel-title-text strong { font-size: 0.95rem; font-weight: 700; }
.chat-panel-title-text span { font-size: 0.74rem; opacity: 0.85; }
.chat-panel-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.chat-panel-icon-btn {
  border: none;
  background: transparent;
  color: #ffffff;
  font-size: 1.05rem;
  width: 32px; height: 32px;
  border-radius: 8px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s;
  flex-shrink: 0;
}
.chat-panel-icon-btn:hover { background: rgba(255, 255, 255, 0.18); }
.chat-panel-icon-btn .icon-shrink { display: none; }
.chat-panel.expanded .chat-panel-icon-btn .icon-expand { display: none; }
.chat-panel.expanded .chat-panel-icon-btn .icon-shrink { display: block; }

@media (max-width: 640px) {
  .nav-links { display: none; }
  .section { padding: 70px 0; }
  .hero { padding: 90px 20px 50px; min-height: auto; }

  .chat-launcher { right: 16px; bottom: 16px; padding: 14px 18px; font-size: 0.88rem; }
  .chat-launcher-icon svg { width: 20px; height: 20px; }
  .chat-proactive { right: 16px; left: 16px; bottom: 92px; max-width: none; }
  .chat-panel, .chat-panel.expanded {
    right: 0; left: 0; top: 0; bottom: 0;
    width: 100%; height: 100%; max-height: 100%;
    border-radius: 0;
  }
  #chat-panel-expand { display: none; }
}
