/* Professional theme — bright, calm, resume-first. */
.theme-professional {
  --bg: #ffffff;
  --surface: #f5f6f8;
  --text: #1b1f24;
  --muted: #5b6572;
  --accent: #1d4ed8;
  --border: #e3e6ea;
  /* Wider than the shared 780px: a resume reads better with a proper
     two-column split (see .resume-columns) than as one narrow, tall
     scroll. Scoped to this theme only — the other pages using the
     780px default haven't been redesigned for extra width. */
  --max-width: 1100px;

  background: var(--bg);
  color: var(--text);
}

.theme-professional a {
  color: var(--accent);
}

/* The pill nav itself (position/shape/glass) is shared sitewide — see
   tokens.css. It's fixed now, so it no longer pushes page content down the
   way the old in-flow bordered header did; main#main needs its own top
   clearance instead (verified in-browser against the nav's real height). */
.theme-professional main#main {
  padding-top: 6.5rem;
}

.theme-professional .site-header nav a {
  text-decoration: none;
  color: var(--muted);
  font-size: 0.95rem;
}

.theme-professional .site-header nav a:hover,
.theme-professional .site-header nav a[aria-current="page"] {
  color: var(--text);
}

.theme-professional .site-footer {
  border-top: 1px solid var(--border);
  color: var(--muted);
}

.theme-professional .site-footer a {
  color: var(--muted);
}

/* Galaxy button — moved here from the homepage hero, in the nav bar instead
   of the plain "The Chaos" keycap-btn it replaces. Structurally identical to
   the hero version (see git history for the full port writeup): one
   --active custom property every child reads, a genuinely 3D-tilted star
   ring, a two-layer masked spark, JS-randomized per-star orbit/drift
   (assets/js/galaxy-button.js). Two things changed for the nav context:
   --hue back to 205 (the personal theme's own accent, #6ec1ff) instead of
   the homepage's — this button always leads to /life/, so it should read as
   that page's own blue, the same convention .keycap-btn already used. And
   everything is sized down to nav scale (matching .site-header .offset-btn's
   font-size/padding) rather than the hero's much larger footprint — the
   star ring's orbit radius is tuned down to match in galaxy-button.js, since
   this is now its only use site-wide. */
.galaxy-button {
  --transition: 0.25s;
  --spark: 1.8s;
  --hue: 205;
  position: relative;
  display: inline-block;
  text-decoration: none;
}

.galaxy-btn-face {
  --cut: 0.08em;
  --active: 0;
  --bg:
    radial-gradient(
      120% 120% at 126% 126%,
      hsl(var(--hue) calc(var(--active) * 97%) 98% / calc(var(--active) * 0.9)) 40%,
      transparent 50%
    ) calc(100px - (var(--active) * 100px)) 0 / 100% 100% no-repeat,
    radial-gradient(
      120% 120% at 120% 120%,
      hsl(var(--hue) calc(var(--active) * 97%) 70% / var(--active)) 30%,
      transparent 70%
    ) calc(100px - (var(--active) * 100px)) 0 / 100% 100% no-repeat,
    hsl(var(--hue) calc(var(--active) * 100%) calc(12% - (var(--active) * 8%)));
  background: var(--bg);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.25em;
  isolation: isolate;
  overflow: hidden;
  white-space: nowrap;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  transform-style: preserve-3d;
  perspective: 100vmin;
  min-height: 44px;
  scale: calc(1 + (var(--active) * 0.06));
  box-shadow:
    0 0 calc(var(--active) * 2.5em) calc(var(--active) * 1.2em) hsl(var(--hue) 97% 61% / 0.5),
    0 0.05em 0 0 hsl(var(--hue) calc(var(--active) * 97%) calc((var(--active) * 50%) + 30%)) inset,
    0 -0.05em 0 0 hsl(var(--hue) calc(var(--active) * 97%) calc(var(--active) * 10%)) inset;
  transition: box-shadow var(--transition), scale var(--transition), background var(--transition);
}

.galaxy-button:hover .galaxy-btn-face,
.galaxy-button:focus-visible .galaxy-btn-face {
  --active: 1;
}

.galaxy-button:active .galaxy-btn-face {
  scale: 1;
}

.galaxy-btn-face .text {
  position: relative;
  translate: 2% -6%;
  color: hsl(0 0% calc(60% + (var(--active) * 26%)));
}

.galaxy-btn-face .star {
  height: calc(var(--size, 3) * 1px);
  aspect-ratio: 1;
  background: #fff;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  opacity: var(--alpha, 0.6);
  transform: translate(-50%, -50%) rotate(10deg) translateY(calc(var(--distance, 60) * 1px));
  animation: galaxy-orbit calc(var(--duration, 12) * 1s) calc(var(--delay, 0) * -1s) infinite linear;
}

@keyframes galaxy-orbit {
  to { transform: translate(-50%, -50%) rotate(370deg) translateY(calc(var(--distance, 60) * 1px)); }
}

.galaxy__container {
  position: absolute;
  inset: 0;
  opacity: var(--active);
  transition: opacity var(--transition);
  mask: radial-gradient(#fff, transparent);
  pointer-events: none;
}

.galaxy-btn-face .star--static {
  top: 50%;
  left: 50%;
  max-height: 4px;
  filter: brightness(4);
  transform: translate(0, 0);
  animation:
    galaxy-drift-x calc(var(--duration, 12) * 0.1s) calc(var(--delay, 0) * -0.1s) infinite linear,
    galaxy-drift-y calc(var(--duration, 12) * 0.2s) calc(var(--delay, 0) * -0.2s) infinite linear;
}

.galaxy-button:hover .star--static,
.galaxy-button:focus-visible .star--static {
  animation-play-state: paused;
}

@keyframes galaxy-drift-x {
  from { translate: -24px 0; }
  to { translate: 24px 0; }
}

@keyframes galaxy-drift-y {
  from { transform: translate(0, -14px); }
  to { transform: translate(0, 14px); }
}

.galaxy {
  position: absolute;
  width: 100%;
  aspect-ratio: 1;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  overflow: hidden;
  opacity: var(--active);
  transition: opacity var(--transition);
  pointer-events: none;
}

.galaxy__ring {
  position: absolute;
  height: 200%;
  width: 200%;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  transform: translate(-28%, -40%) rotateX(-24deg) rotateY(-30deg) rotateX(90deg);
  transform-style: preserve-3d;
}

.galaxy-btn-face .spark {
  position: absolute;
  inset: 0;
  z-index: -2;
  border-radius: inherit;
  overflow: hidden;
  mask: linear-gradient(#fff, transparent 50%);
  animation: galaxy-flip calc(var(--spark) * 2) infinite steps(2, end);
}

@keyframes galaxy-flip {
  to { rotate: 360deg; }
}

.galaxy-btn-face .spark::before {
  content: "";
  position: absolute;
  width: 200%;
  aspect-ratio: 1;
  top: 0;
  left: 50%;
  translate: -50% -15%;
  transform: rotate(-90deg);
  opacity: calc(var(--active) + 0.4);
  background: conic-gradient(from 0deg, transparent 0 340deg, hsl(var(--hue) 90% 70%) 360deg);
  transition: opacity var(--transition);
  animation: galaxy-rotate var(--spark) linear infinite both;
}

@keyframes galaxy-rotate {
  to { transform: rotate(90deg); }
}

.galaxy-btn-face .backdrop {
  position: absolute;
  inset: var(--cut);
  z-index: -1;
  border-radius: inherit;
  background: var(--bg);
  transition: background var(--transition);
}

.galaxy-button:focus-visible .galaxy-btn-face {
  outline: 2px solid #6ec1ff;
  outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
  .galaxy-btn-face .star,
  .galaxy-btn-face .star--static,
  .galaxy-btn-face .spark,
  .galaxy-btn-face .spark::before {
    animation: none;
  }
}

/* Resume-specific structure */
.resume-header {
  padding-top: var(--space-4);
  border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-5);
}

.resume-header h1 {
  /* Browser default h1 margin-top was stacking on top of .resume-header's
     own padding-top, so the name sat ~76px below the header edge but only
     ~5px above the title line — reset it to 0 and let padding-top be the
     only source of top space, then match margin-bottom to it so the name
     has equal room above and below. */
  margin-top: 0;
  margin-bottom: var(--space-4);
  font-size: clamp(2.2rem, 5vw, 3.4rem);
}

/* Text Fall — a canvas particle title (assets/js/text-fall.js), ported from
   a React/canvas component the user supplied. .text-fall-plain is the real
   heading text and stays visible by default; only once the script confirms
   it actually set up (adding .text-fall-ready) does CSS swap to the canvas
   and visually hide the plain text — off-screen via clip, not display:none,
   so it's still the h1's accessible name for screen readers/SEO either way.
   No JS, reduced-motion, or a script error all just leave the plain heading
   showing, same as it always did. */
.text-fall-root {
  display: none;
}

.text-fall-heading.text-fall-ready .text-fall-plain {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.text-fall-heading.text-fall-ready .text-fall-root {
  display: block;
  position: relative;
  width: 100%;
  height: clamp(100px, 12vw, 180px);
}

/* text-fall.js forces "BHAVESH" / "NAKUM" onto two lines at this same
   640px breakpoint (see the mobileName check there) — two lines needs
   real height, not the single-line box above. */
@media (max-width: 640px) {
  .text-fall-heading.text-fall-ready .text-fall-root {
    height: clamp(150px, 34vw, 220px);
  }
}

.text-fall-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
}

.resume-header .title-line {
  color: var(--accent);
  font-weight: 500;
  margin-top: 0;
  font-size: 1.05rem;
  /* Same 56ch recalibration as .resume-section (see its comment) — this is
     a <p> too, so it inherited the sitewide 68ch token, which renders wider
     than its name implies. Wasn't an issue until the updated title grew to
     three long, pipe-separated clauses. */
  max-width: 56ch;
}

.resume-header .contact-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  font-size: 0.9rem;
  color: var(--muted);
  margin-top: var(--space-2);
}

/* min-height instead of stretching the whole row: keeps the plain
   "Bengaluru, India" text at its natural size while giving the two real
   links (email, LinkedIn) a comfortable tap target. align-items: center
   above keeps everything on one visual baseline despite the size gap. */
.resume-header .contact-line a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--muted);
}

.resume-header .contact-line a:hover {
  color: var(--accent);
}

.resume-header .contact-note {
  font-size: 0.8rem;
  color: var(--muted);
  max-width: 56ch;
  margin-top: 0;
}

/* Single column until there's room for a real split — narrower than this
   and a sidebar would squeeze Experience's bullets uncomfortably. */
.resume-columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 900px) {
  .resume-columns {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    align-items: start;
    gap: var(--space-5);
  }
}

.resume-section {
  margin-top: var(--space-4);
}

.resume-main .resume-section:first-child,
.resume-aside .resume-section:first-child {
  margin-top: var(--space-3);
}

/* tokens.css caps <p> at 68ch sitewide for readable line length, but that
   rule never reaches <li> — and measured live, even the capped <p> here
   renders ~86 real characters per line, not ~68: Inter's "ch" unit tracks
   the width of "0", which is narrower than this font's average character,
   so 68ch reads much wider than 68 characters in practice. 56ch is
   calibrated against this page's actual rendered text (verified via the
   impeccable detector) to land in the ~65-75 real-character range that
   68ch was supposed to hit. Scoped to .resume-section rather than fixed
   in the shared token, since the other pages using plain 68ch haven't
   been measured against this font/content and shouldn't change as a
   side effect of a résumé-page fix. dd joined this list once the Skills
   category values grew long enough (from the updated master resume) to
   hit the same problem — a few run all the way to the sidebar column's
   full width otherwise. */
.resume-section p,
.resume-section li,
.resume-section dd {
  max-width: 56ch;
}

.resume-section h2 {
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.4rem;
  margin-bottom: var(--space-2);
}

/* FAQ (AEO): native details/summary, no JS needed to expand/collapse and
   nothing to break if it fails to load. */
.faq-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.faq-item {
  border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-2);
}

.faq-item summary {
  cursor: pointer;
  font-weight: 600;
  padding: var(--space-1) 0;
}

.faq-item summary::marker {
  color: var(--accent);
}

.faq-item p {
  margin-top: var(--space-1);
  margin-bottom: 0;
  color: var(--muted);
}

/* Experience timeline — one continuous spine (::before on the wrapper)
   with a dot per entry (::before on each .resume-entry) instead of each
   entry carrying its own disconnected border-left segment. GUTTER below
   must stay in sync with the two numbers derived from it in .resume-entry
   and .resume-entry::before (see their own comments) — all three exist
   because CSS has no "define once, use in three places" for plain values. */
.experience-timeline {
  position: relative;
  padding-left: 24px; /* GUTTER */
}

.experience-timeline::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: 8px;
  left: 11px; /* GUTTER/2 - dot-line-width/2, i.e. (24/2 - 2/2) */
  width: 2px;
  background: var(--border);
}

.resume-entry {
  position: relative;
  margin-bottom: var(--space-3);
}

.resume-entry::before {
  /* Centers a 12px dot on the spine above: spine center sits at 12px from
     the timeline's own left edge (11px + half the 2px line); .resume-entry
     itself starts at the timeline's GUTTER (24px), so the dot's left,
     measured from the entry's own edge, is 12 - 24 - (dot-width/2) = -18px. */
  content: "";
  position: absolute;
  left: -18px;
  top: 6px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--accent);
}

.resume-entry .entry-heading {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  /* Column-gap trimmed from 1rem: at this layout's narrower two-column
     width, "Systems Engineer, Tata Consultancy Services" plus its date
     range came within 1px of the row's full width, wrapping to two lines
     while every other entry stayed on one — this gives it (and any future
     long title/date pairing) real headroom instead of sitting right on
     the edge. */
  gap: 0.25rem 0.6rem;
  font-weight: 600;
  font-size: 1.02rem;
}

.resume-entry .entry-meta {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.9rem;
}

/* One always-visible line of real substance per entry, so a collapsed
   entry reads as more than a title and a button — the two-column balance
   fix (moving Additional Highlights into .resume-main) closed the height
   gap, but a visitor scanning the timeline before opening anything still
   needs something to read. Full sentence, body-text color (not --muted
   like entry-meta) so it carries real weight rather than reading as a
   second metadata line. */
.resume-entry .entry-summary {
  margin: 0.35rem 0 0;
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* Collapsed by default (see assets/js/entry-toggle.js) — the heading and
   summary above are the "high-level summary" until this is deliberately
   opened; nothing here auto-expands on hover or scroll.
   .question-toggle (/questions/, assets/js/interview-questions.js) shares
   every rule below it: same disclosure component, different page. */
.entry-toggle,
.question-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.5rem;
  padding: 0.5rem 0.2rem;
  min-height: 44px;
  border: none;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.entry-toggle:hover,
.entry-toggle:focus-visible,
.question-toggle:hover,
.question-toggle:focus-visible {
  text-decoration: underline;
}

.entry-toggle:focus-visible,
.question-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.entry-chevron {
  transition: transform 0.25s ease;
}

.entry-toggle[aria-expanded="true"] .entry-chevron,
.question-toggle[aria-expanded="true"] .entry-chevron {
  transform: rotate(180deg);
}

/* Animates height via the grid 0fr->1fr trick rather than max-height, so
   entries with very different bullet counts (4 vs. 9) each expand at a
   speed proportional to their own content instead of sharing one fixed
   cap and visibly pausing at the end when short. */
.entry-details-wrap,
.question-answer-wrap {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.35s ease;
}

.resume-entry.is-expanded .entry-details-wrap {
  grid-template-rows: 1fr;
}

/* .question-answer-wrap has no wrapping .resume-entry-style parent to key
   off, so assets/js/interview-questions.js toggles this class directly on
   the wrap instead of on an ancestor. */
.question-answer-wrap.is-expanded {
  grid-template-rows: 1fr;
}

.entry-details-wrap > .entry-details {
  overflow: hidden;
  min-height: 0;
  margin: 0.5rem 0 0;
  padding-left: 1.1rem;
}

.entry-details-wrap > .entry-details > li {
  margin-bottom: 0.3rem;
}

.question-answer-wrap > .question-answer {
  overflow: hidden;
  min-height: 0;
  margin: 0.5rem 0 0;
  padding-left: 1.1rem;
  color: var(--muted);
  font-size: 0.92rem;
}

@media (prefers-reduced-motion: reduce) {
  .entry-details-wrap,
  .question-answer-wrap,
  .entry-chevron {
    transition-duration: 0.01ms;
  }
}

/* Emotion-to-Emoji demo, inside the Projects entry's expanded details. A real
   camera + face-api.js expression model, not a video or a screenshot — see
   assets/js/emoji-detector.js. Lives as the last <li> in .entry-details so it
   inherits the exact same hidden/collapse mechanics as the text bullets above
   it (one accessibility surface, not a second one to keep in sync); the
   bullet marker is stripped since a whole interactive widget reading as one
   list item is a layout choice, not literal list content. */
.entry-demo-item {
  list-style: none;
  margin-top: 0.5rem;
}

.emoji-demo {
  max-width: 320px;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.emoji-demo-stage {
  position: relative;
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: calc(var(--radius) - 4px);
  background: var(--bg);
  border: 1px solid var(--border);
}

.emoji-demo-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Mirrored so it reads like a mirror, not a security feed. */
  transform: scaleX(-1);
  display: none;
}

.emoji-demo-placeholder {
  font-size: 2.25rem;
  opacity: 0.5;
}

.emoji-demo-emoji {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  font-size: 2rem;
  line-height: 1;
  display: none;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35));
}

.emoji-demo[data-state="running"] .emoji-demo-video,
.emoji-demo[data-state="running"] .emoji-demo-emoji {
  display: block;
}

.emoji-demo[data-state="running"] .emoji-demo-placeholder {
  display: none;
}

.emoji-demo-status {
  position: relative;
  margin: 0.75rem 0 0;
  padding-left: 0;
  min-height: 1.2em;
  color: var(--muted);
  font-size: 0.88rem;
}

.emoji-demo[data-state="loading"] .emoji-demo-status {
  padding-left: 1rem;
}

.emoji-demo[data-state="loading"] .emoji-demo-status::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.4em;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent);
  animation: emoji-demo-pulse 1s ease-in-out infinite;
}

/* Reuses the contact form's own established error color (tokens.css
   .contact-status[data-state="error"]) rather than inventing a new hue. */
.emoji-demo[data-state="error"] .emoji-demo-status {
  color: #e0575b;
}

@keyframes emoji-demo-pulse {
  0%,
  100% {
    opacity: 0.3;
  }
  50% {
    opacity: 1;
  }
}

.emoji-demo-actions {
  margin-top: 0.75rem;
}

.emoji-demo .offset-btn {
  padding: 0.5rem 1.1rem;
  min-height: 44px;
  font-size: 0.85rem;
}

.emoji-demo-note {
  margin: 0.6rem 0 0;
  color: var(--muted);
  font-size: 0.76rem;
}

@media (prefers-reduced-motion: reduce) {
  .emoji-demo-status::before {
    animation-duration: 0.01ms;
  }
}

/* Used to go 2-column above 560px via a viewport media query — but this
   grid only ever lives inside .resume-aside now (a fixed ~330px column
   regardless of viewport width), so that rule was cramming label and
   value into ~150px each on every desktop size instead of ever actually
   reaching a wide single column. Stacks label above value instead. */
.skills-grid {
  display: grid;
}

.skills-grid dt {
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* Pills instead of a comma-separated run of text: the same list of tools
   reads as a scannable set of tags rather than another paragraph to read,
   and — the actual reason this changed — packs far tighter than prose
   into this column's width, which was the biggest single contributor to
   the sidebar running much longer than the main column beside it. */
.skills-grid dd {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.5rem 0 1.1rem;
}

.skills-grid dd:last-of-type {
  margin-bottom: 0;
}

.skill-pill {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.2rem 0.65rem;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--text);
}

/* Download Résumé and Interview Questions use the shared .offset-btn
   component (tokens.css) — this wrapper just lays them out. Email and
   LinkedIn used to live here too as duplicate buttons; dropped since the
   contact line right above already links both. */
.resume-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: var(--space-3);
}

/* Same reasoning as .site-header .offset-btn's own override: a row of
   buttons under the résumé header isn't a lone hero CTA, so it shouldn't be
   sized like one (was 47px tall, up to 216px wide, before this). */
.resume-actions .offset-btn {
  padding: 0.5rem 1.1rem;
  font-size: 0.9rem;
  gap: 0.4rem;
}

/* Text Emerge (assets/js/text-emerge.js) — reveals Summary through
   Education as you scroll to each one. .word spans only ever exist if
   that script ran and split some text into them, so their hidden state is
   safe to set unconditionally here — a no-JS visitor never gets a .word
   in the first place. .emerge-pending is different: it's added to real,
   always-present markup (.resume-section, .resume-entry, headings), so
   its hidden state only ever applies once that same script has also
   confirmed it's ready to reveal things — otherwise this content would
   stay invisible for anyone without JS. */
.word {
  display: inline-block;
  opacity: 0;
  transform: scale(0.4);
  filter: blur(4px);
  transition: opacity 0.5s ease-out, transform 0.5s ease-out, filter 0.5s ease-out;
}

.emerge-in .word {
  opacity: 1;
  transform: scale(1);
  filter: blur(0);
}

.emerge-pending {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

.emerge-pending.emerge-in {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .word,
  .emerge-pending {
    transition: none;
  }
}

/* ---------------------------------------------------------------------
   /questions/ — interview question log with faceted filters (company /
   round / tech stack), driven by assets/js/interview-questions.js.
   Reuses this page's own tokens (--bg/--surface/--text/--muted/--accent/
   --border) and .skill-pill for the per-card tech tags, same as
   everything else on this theme.
   --------------------------------------------------------------------- */

.questions-header {
  margin-bottom: var(--space-3);
}

.questions-intro {
  color: var(--muted);
}

.questions-filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.filter-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.filter-group-label {
  flex-shrink: 0;
  width: 90px;
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Same pill shape as .skill-pill, but interactive: a real toggle button
   (aria-pressed), so it needs this project's own ≥44px touch-target floor
   — met via min-height/padding rather than font-size, so the label stays
   readable. */
.filter-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.4rem 0.85rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background-color var(--speed) var(--ease), border-color var(--speed) var(--ease), color var(--speed) var(--ease);
}

.filter-chip:hover {
  border-color: var(--accent);
}

.filter-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.filter-chip[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.filter-reset {
  align-self: flex-start;
  padding: 0.3rem 0.2rem;
  min-height: 44px;
  border: none;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.filter-reset:hover,
.filter-reset:focus-visible {
  text-decoration: underline;
}

.questions-count {
  margin: 0 0 var(--space-2);
  color: var(--muted);
  font-size: 0.85rem;
}

.questions-list {
  display: grid;
  gap: var(--space-2);
}

.question-card {
  padding: var(--space-2) var(--space-3);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.question-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.6rem;
}

.question-tag {
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}

.question-tag-company {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}

.question-tag-round {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--muted);
}

.question-text {
  margin: 0 0 0.6rem;
  font-weight: 600;
  max-width: none;
}

/* Rendered via `{{ q.problem | markdownify }}` (_data/interview_questions.yml)
   — plain paragraph/list/inline-code content, so this just resets the
   default <p>/<ul> margins to sit tightly under .question-text instead of
   the wider spacing kramdown's own output would otherwise carry. */
.question-problem {
  margin-bottom: 0.6rem;
  color: var(--text);
}

.question-problem p,
.question-problem ul,
.question-answer-text p,
.question-answer-text ul,
.question-example p,
.question-example ul {
  margin: 0 0 0.5rem;
  max-width: none;
}

.question-problem :last-child,
.question-answer-text :last-child,
.question-example :last-child,
.question-note :last-child {
  margin-bottom: 0;
}

.question-problem code,
.question-example code,
.question-answer-text code,
.question-note code {
  padding: 0.1em 0.35em;
  background: var(--surface);
  border-radius: 4px;
  font-size: 0.88em;
}

.question-card-stack {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 0.4rem;
}

/* Fenced ``` blocks in `example`/`answer` (the ASCII tree/elevation
   diagrams, the cost matrix, the JSON input) — monospace and `pre` so
   the hand-aligned spacing survives, dark like assets/css/lab.css's own
   .lab-code so a code block reads as one consistent "this is source
   data" treatment sitewide rather than inventing a second style. */
.question-example pre {
  margin: 0 0 0.6rem;
  padding: 0.9rem;
  overflow-x: auto;
  background: #12161c;
  color: #d6dde5;
  border-radius: var(--radius);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
  line-height: 1.55;
}

.question-example pre code {
  padding: 0;
  background: none;
  color: inherit;
  font-size: inherit;
}

.question-note {
  padding-top: 0.4rem;
  color: var(--muted);
  font-size: 0.85rem;
  font-style: italic;
}

.question-links {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.88rem;
}

.questions-empty {
  padding: var(--space-3) 0;
  color: var(--muted);
  text-align: center;
}
