/* Design Tokens */
:root {
  --bg: #f9f9fb;
  --text: #111215;
  --text-muted: #62646c;
  --border: #e2e4e9;
  --accent: #2563eb;
  --accent-hover: #1d4ed8;
  --card-bg: #ffffff;
  --card-hover-border: #a1a5b3;
  --badge-bg: #eceef2;
  --badge-text: #374151;
  --status-bg: #ecfdf5;
  --status-text: #059669;
  --status-dot: #10b981;
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.02);
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-display: 'Outfit', sans-serif;
  --transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  --container-width: 900px;
  --toc-width: 230px;
}

[data-theme="dark"] {
  --bg: #090a0c;
  --text: #f3f4f6;
  --text-muted: #9ca3af;
  --border: #1f2937;
  --accent: #3b82f6;
  --accent-hover: #60a5fa;
  --card-bg: #111827;
  --card-hover-border: #374151;
  --badge-bg: #1f2937;
  --badge-text: #e5e7eb;
  --status-bg: #064e3b;
  --status-text: #34d399;
  --status-dot: #10b981;
  --shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}

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

body {
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color 0.3s var(--transition), color 0.3s var(--transition);
}

.container {
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 80px 24px;
}

/* Post pages need extra room for the article+ToC grid (see .post-layout below) -
   width = site-wide container width + the ToC sidebar's own width, so the article
   column keeps roughly the same working width as everywhere else instead of being
   squeezed by the sidebar. Applied via .Scratch "isPostSingle" in baseof.html. */
.container-wide {
  max-width: calc(var(--container-width) + var(--toc-width));
}

/* Navigation Container */
.nav-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 48px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 16px;
  flex-wrap: wrap;
  gap: 16px;
}

.nav-menu {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 20px;
}

.btn-control.nav-burger {
  display: none;
}

.nav-avatar-link {
  display: flex;
  align-items: center;
  height: 28px;
}

.nav-avatar-img {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center;
  border: 1px solid var(--border);
  transition: var(--transition);
}

.nav-avatar-link:hover .nav-avatar-img {
  border-color: var(--card-hover-border);
}

.nav-link {
  text-decoration: none;
  color: var(--text-muted);
  font-weight: 500;
  font-size: 0.95rem;
  transition: var(--transition);
  border-bottom: 2px solid transparent;
  padding-bottom: 4px;
}

.nav-link:hover, .nav-link.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.controls {
  display: flex;
  align-items: center;
  gap: 12px;
}

.btn-control {
  background: var(--card-bg);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 14px;
  border-radius: 20px;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  box-shadow: var(--shadow);
  transition: var(--transition);
  user-select: none;
}

.btn-control:hover {
  border-color: var(--card-hover-border);
  transform: translateY(-1px);
}

.btn-control-icon {
  padding: 8px;
  width: 34px;
  height: 34px;
  justify-content: center;
}

.btn-control svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
}

.nav-burger svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

@media (max-width: 767px) {
  .btn-control.nav-burger {
    display: flex;
  }

  .nav-links {
    display: none;
    position: absolute;
    top: calc(100% + 12px);
    left: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 12px;
    box-shadow: var(--shadow);
    min-width: 180px;
    z-index: 20;
  }

  .nav-links.open {
    display: flex;
  }

  .nav-links .nav-link {
    width: 100%;
    padding: 8px 4px;
  }
}

/* Profile Header Info */
.profile-header {
  margin-bottom: 48px;
}

.profile-header-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.profile-header-center .social-links {
  justify-content: center;
}

.profile-header-center > *:last-child {
  margin-bottom: 0;
}

.avatar-wrap {
  width: clamp(96px, 20vw, 160px);
  aspect-ratio: 1 / 1;
  margin-bottom: 24px;
}

.avatar-img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  object-position: center;
  border: 2px solid var(--border);
  box-shadow: var(--shadow);
  display: block;
}

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--status-bg);
  color: var(--status-text);
  padding: 6px 14px;
  border-radius: 30px;
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 20px;
  letter-spacing: 0.02em;
}

.status-dot {
  width: 8px;
  height: 8px;
  background-color: var(--status-dot);
  border-radius: 50%;
  display: inline-block;
  position: relative;
}

.status-dot::after {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: inherit;
  border-radius: 50%;
  animation: pulse 1.8s infinite ease-in-out;
}

@keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 0.8;
  }
  100% {
    transform: scale(2.5);
    opacity: 0;
  }
}

.profile-name {
  font-family: var(--font-display);
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.04em;
  margin-bottom: 12px;
}

.profile-title {
  font-size: 1.25rem;
  color: var(--text-muted);
  font-weight: 500;
  margin-bottom: 24px;
}

.profile-bio {
  font-size: 1.05rem;
  color: var(--text);
  font-weight: 400;
  margin-bottom: 32px;
  max-width: 620px;
}

/* Social Links Grid */
.social-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.btn-social {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 500;
  transition: var(--transition);
  border: 1px solid var(--border);
  background: var(--card-bg);
  color: var(--text);
}

.btn-social:hover {
  border-color: var(--card-hover-border);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

.btn-social svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

.contact-label {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 12px;
}

/* Layout Sections */
section {
  margin-bottom: 56px;
}

h2.section-heading {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 24px;
  display: flex;
  align-items: center;
  gap: 10px;
}

h2.section-heading svg {
  width: 20px;
  height: 20px;
  color: var(--text-muted);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}

/* Timeline style */
.timeline {
  position: relative;
  border-left: 2px solid var(--border);
  padding-left: 24px;
  margin-left: 8px;
}

.timeline-item {
  position: relative;
  margin-bottom: 32px;
}

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

.timeline-dot {
  position: absolute;
  left: -31px;
  top: 6px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: var(--bg);
  border: 2px solid var(--accent);
}

.timeline-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 8px;
  flex-wrap: wrap;
  gap: 4px;
}

.timeline-role {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text);
}

.timeline-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}

.timeline-company {
  color: var(--accent);
  font-weight: 600;
}

.timeline-date {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-weight: 500;
}

.timeline-desc {
  font-size: 0.95rem;
  color: var(--text-muted);
}

/* Cards Grid */
.cards-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

@media (min-width: 600px) {
  .cards-grid {
    grid-template-columns: 1fr;
  }
}

.card {
  border: 1px solid var(--border);
  background: var(--card-bg);
  border-radius: 12px;
  padding: 24px;
  transition: var(--transition);
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.card:hover {
  border-color: var(--card-hover-border);
  transform: translateY(-3px);
  box-shadow: var(--shadow);
}

.card-title-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.card-title {
  font-size: 1.2rem;
  font-weight: 600;
  font-family: var(--font-display);
  letter-spacing: -0.01em;
}

.card-meta {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 12px;
}

.card-description {
  font-size: 0.95rem;
  color: var(--text-muted);
  flex-grow: 1;
}

.show-more-wrap {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}

/* The gap below the button would otherwise collapse with the larger
   section/footer margins (56px/64px) and look bigger than the 24px gap
   above it. Zero out the section's own trailing margin and let the footer's
   margin-top collapse down to the same 24px instead, only for the section
   that ends in a show-more button. */
section:has(.show-more-wrap) {
  margin-bottom: 0;
}

section:has(.show-more-wrap) + footer {
  margin-top: 24px;
}

.btn-show-more {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 28px;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  transition: var(--transition);
  border: 1px solid var(--border);
  background: var(--card-bg);
  color: var(--text);
}

.btn-show-more:hover {
  border-color: var(--card-hover-border);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

/* Skills Grid */
.skills-section {
  border-top: 1px solid var(--border);
  padding-top: 40px;
}

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

.skills-category {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

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

.skills-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tag-pill {
  background-color: var(--badge-bg);
  color: var(--badge-text);
  border-radius: 6px;
  font-weight: 500;
  transition: var(--transition);
  border: 1px solid transparent;
}

.tag-pill:hover {
  background-color: var(--bg);
  border-color: var(--border);
}

.skill-tag {
  font-size: 0.85rem;
  padding: 6px 12px;
}

/* Article View Layout */
.post-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
  margin-top: 32px;
}

/* For regular articles we leave 24px margin for footer */
.post-layout + footer {
  margin-top: 24px;
}

/* 
  But if the article contains a series link and it is shown on mobile
  we remove margin fully in order for that link to look symmetrical
*/
.post-layout:has(.post-series-mobile) + footer {
  margin-top: 0px;
}

/* Sidebar is a fixed var(--toc-width) column, not a proportional fr share -
   that's what makes .container-wide's "container width + toc width" formula
   (see .container-wide above) actually true: every extra pixel of container
   width goes to <article>, not split proportionally with the sidebar. */
@media (min-width: 768px) {
  .post-layout {
    grid-template-columns: 1fr var(--toc-width);
  }
}

/* Grid items default to min-width: auto, i.e. their track can never shrink
   below the content's min-content size. An unbreakable long code line (Chroma
   uses white-space: pre, so it never wraps) has a huge min-content width,
   which without this rule inflates the article track past its 3fr share and
   pushes .toc-sidebar out - the sidebar doesn't just narrow, it visually
   disappears. min-width: 0 lets the track respect its fr share; .chroma's own
   overflow-x: auto then handles the actual long-line scrolling. */
.post-layout > article {
  min-width: 0;
}

.post-header {
  margin-bottom: 32px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 24px;
}

.post-header h1 {
  font-family: var(--font-display);
  font-size: 2.2rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.03em;
  margin-bottom: 12px;
}

.post-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 0.9rem;
  color: var(--text-muted);
}

.post-tag {
  font-size: 0.8rem;
  padding: 3px 10px;
  text-decoration: none;
}

.post-meta .post-date {
  flex-basis: 100%;
}

.post-tag:hover {
  color: var(--accent);
}

.post-series-meta {
  margin-top: 8px;
}

.post-series-link {
  font-size: 0.9rem;
  color: var(--text-muted);
  text-decoration: none;
  transition: var(--transition);
}

.post-series-link:hover {
  color: var(--accent);
}

.post-series-mobile {
  display: none;
  margin-top: 32px;
  padding-top: 24px;
  padding-bottom: 24px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  text-decoration: none;
  text-align: center;
  font-size: 0.95rem;
}

@media (max-width: 767px) {
  .post-series-mobile {
    display: block;
  }
}

.post-cover {
  width: 100%;
  margin-bottom: 32px;
}

.post-cover-img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: center;
  border-radius: 12px;
  box-shadow: var(--shadow);
  display: block;
}

.post-content {
  font-size: 1.05rem;
  color: var(--text);
}

.post-content p {
  margin-bottom: 24px;
}

.post-content img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 24px 0;
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.post-content h2 {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  margin-top: 40px;
  margin-bottom: 16px;
  letter-spacing: -0.01em;
}

.post-content h3 {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
  margin-top: 32px;
  margin-bottom: 12px;
}

.toc-sidebar {
  position: sticky;
  top: 40px;
  align-self: start;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  padding-left: 20px;
  border-left: 2px solid var(--border);
}

.toc-title {
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-bottom: 16px;
}

.toc-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.toc-link {
  text-decoration: none;
  color: var(--text-muted);
  font-size: 0.9rem;
  transition: var(--transition);
  display: block;
}

.toc-link:hover {
  color: var(--accent);
}

.toc-link.active {
  color: var(--accent);
  font-weight: 600;
}

.toc-series {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

@media (max-width: 767px) {
  .toc-sidebar {
    display: none;
  }
}

/* Archives page */
.archive-year-group {
  margin-bottom: 48px;
}

.archive-year {
  font-family: var(--font-display);
  font-size: 1.8rem;
  font-weight: 700;
  margin-bottom: 24px;
  color: var(--text);
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
}

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

.archive-item {
  display: flex;
  align-items: baseline;
  gap: 24px;
}

.archive-date {
  font-size: 0.9rem;
  color: var(--text-muted);
  width: 100px;
  flex-shrink: 0;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.archive-link {
  text-decoration: none;
  color: var(--text);
  font-size: 1.1rem;
  font-weight: 500;
  transition: var(--transition);
}

.archive-link:hover {
  color: var(--accent);
}

/* Footer styling */
footer {
  border-top: 1px solid var(--border);
  padding-top: 32px;
  margin-top: 64px;
  text-align: center;
  font-size: 0.85rem;
  color: var(--text-muted);
}

footer p {
  margin-bottom: 8px;
}

.footer-line {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
}

.footer-divider {
  color: var(--border);
}

footer a {
  color: var(--text-muted);
  text-decoration: underline;
  transition: var(--transition);
}

footer a:hover {
  color: var(--accent);
}

/* Search overlay */
.search-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 12vh 16px 0;
  z-index: 1000;
}

.search-overlay[hidden] {
  display: none;
}

.search-panel {
  width: min(560px, 100%);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  overflow: hidden;
}

.search-input-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}

.search-icon {
  width: 18px;
  height: 18px;
  fill: var(--text-muted);
  flex-shrink: 0;
}

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

.search-close {
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
  transition: var(--transition);
}

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

.search-results {
  max-height: 50vh;
  overflow-y: auto;
}

.search-results-list {
  list-style: none;
}

.search-result-link {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 16px;
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  transition: var(--transition);
}

.search-result-link:last-child {
  border-bottom: none;
}

.search-result-link:hover {
  background: var(--badge-bg);
}

.search-result-title {
  color: var(--text);
  font-weight: 600;
  font-size: 0.95rem;
}

.search-result-desc {
  color: var(--text-muted);
  font-size: 0.85rem;
}

.search-empty {
  padding: 16px;
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* Code modal: same fixed-overlay/click-outside-closes/Escape pattern as
   .search-overlay above, but centered vertically (not top-aligned) and sized
   for code rather than a text input. .code-modal-content carries no
   background/border of its own — code-expand.js clones the code block's own
   .highlight > .chroma into it, so theme colors and font-size come along for
   free without duplicating styles here. */
.code-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 5vh 16px;
  z-index: 1000;
}

.code-modal-overlay[hidden] {
  display: none;
}

.code-modal-panel {
  width: min(var(--container-width), 100%);
  max-height: 90vh;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
}

.code-modal-header {
  display: flex;
  justify-content: flex-end;
  padding: 8px 8px 0;
}

.code-modal-close {
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 6px;
  transition: var(--transition);
}

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

.code-modal-content {
  padding: 0 16px 16px;
  overflow: auto;
}

/* Dynamic fade utility */
.fade-in {
  animation: fadeIn 0.4s ease-out;
}

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

/* Code blocks (Chroma) — vs (light site theme) / vulcan (dark site theme),
   mapped directly to the site's own light/dark theme via [data-theme], same
   mechanism as the design tokens in :root / [data-theme="dark"] at the top of
   this file. Chroma's token class names (.k, .s, .c1, ...) are the same
   regardless of style — only colors differ below — so this is a pure CSS
   swap, no template branching for theme. Regenerate the two blocks below
   with:
     hugo gen chromastyles --style=vs
     hugo gen chromastyles --style=vulcan
   then wrap every selector from the second command in [data-theme="dark"].
   vs defines far fewer token classes than vulcan (it's a plainer, more
   monochrome style by design) — tokens it doesn't color simply inherit
   .chroma's own text color, that's expected, not a gap to fill in. */

/* vs — default (site light theme) */
/* Background */ .bg { background-color:#fff; }
/* PreWrapper */ .chroma { background-color:#fff;-webkit-text-size-adjust:none; }
/* LineLink */ .chroma .lnlinks { outline:none;text-decoration:none;color:inherit }
/* LineTableTD */ .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0; }
/* LineTable */ .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0; }
/* LineHighlight */ .chroma .hl { background-color:#e5e5e5 }
/* LineNumbersTable */ .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f }
/* LineNumbers */ .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f }
/* Line */ .chroma .line { display:flex; }
/* Keyword */ .chroma .k { color:#00f }
/* KeywordConstant */ .chroma .kc { color:#00f }
/* KeywordDeclaration */ .chroma .kd { color:#00f }
/* KeywordNamespace */ .chroma .kn { color:#00f }
/* KeywordPseudo */ .chroma .kp { color:#00f }
/* KeywordReserved */ .chroma .kr { color:#00f }
/* KeywordType */ .chroma .kt { color:#2b91af }
/* NameClass */ .chroma .nc { color:#2b91af }
/* LiteralString */ .chroma .s { color:#a31515 }
/* LiteralStringAffix */ .chroma .sa { color:#a31515 }
/* LiteralStringBacktick */ .chroma .sb { color:#a31515 }
/* LiteralStringChar */ .chroma .sc { color:#a31515 }
/* LiteralStringDelimiter */ .chroma .dl { color:#a31515 }
/* LiteralStringDoc */ .chroma .sd { color:#a31515 }
/* LiteralStringDouble */ .chroma .s2 { color:#a31515 }
/* LiteralStringEscape */ .chroma .se { color:#a31515 }
/* LiteralStringHeredoc */ .chroma .sh { color:#a31515 }
/* LiteralStringInterpol */ .chroma .si { color:#a31515 }
/* LiteralStringOther */ .chroma .sx { color:#a31515 }
/* LiteralStringRegex */ .chroma .sr { color:#a31515 }
/* LiteralStringSingle */ .chroma .s1 { color:#a31515 }
/* LiteralStringSymbol */ .chroma .ss { color:#a31515 }
/* OperatorWord */ .chroma .ow { color:#00f }
/* Comment */ .chroma .c { color:#008000 }
/* CommentHashbang */ .chroma .ch { color:#008000 }
/* CommentMultiline */ .chroma .cm { color:#008000 }
/* CommentSingle */ .chroma .c1 { color:#008000 }
/* CommentSpecial */ .chroma .cs { color:#008000 }
/* CommentPreproc */ .chroma .cp { color:#00f }
/* CommentPreprocFile */ .chroma .cpf { color:#00f }
/* GenericEmph */ .chroma .ge { font-style:italic }
/* GenericHeading */ .chroma .gh { font-weight:bold }
/* GenericPrompt */ .chroma .gp { font-weight:bold }
/* GenericStrong */ .chroma .gs { font-weight:bold }
/* GenericSubheading */ .chroma .gu { font-weight:bold }

/* vulcan — [data-theme="dark"] (site dark theme) */
/* Background */ [data-theme="dark"] .bg { color:#c9c9c9;background-color:#282c34; }
/* PreWrapper */ [data-theme="dark"] .chroma { color:#c9c9c9;background-color:#282c34;-webkit-text-size-adjust:none; }
/* Other */ [data-theme="dark"] .chroma .x { color:#c9c9c9 }
/* Error */ [data-theme="dark"] .chroma .err { color:#cf5967 }
/* LineLink */ [data-theme="dark"] .chroma .lnlinks { outline:none;text-decoration:none;color:inherit }
/* LineTableTD */ [data-theme="dark"] .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0; }
/* LineTable */ [data-theme="dark"] .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0; }
/* LineHighlight */ [data-theme="dark"] .chroma .hl { background-color:#3d4148 }
/* LineNumbersTable */ [data-theme="dark"] .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f }
/* LineNumbers */ [data-theme="dark"] .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f }
/* Line */ [data-theme="dark"] .chroma .line { display:flex; }
/* Keyword */ [data-theme="dark"] .chroma .k { color:#7fbaf5 }
/* KeywordConstant */ [data-theme="dark"] .chroma .kc { color:#cf5967;background-color:#43454f }
/* KeywordDeclaration */ [data-theme="dark"] .chroma .kd { color:#7fbaf5 }
/* KeywordNamespace */ [data-theme="dark"] .chroma .kn { color:#bc74c4 }
/* KeywordPseudo */ [data-theme="dark"] .chroma .kp { color:#bc74c4 }
/* KeywordReserved */ [data-theme="dark"] .chroma .kr { color:#7fbaf5 }
/* KeywordType */ [data-theme="dark"] .chroma .kt { color:#57c7ff;font-weight:bold }
/* NameAttribute */ [data-theme="dark"] .chroma .na { color:#bc74c4 }
/* NameClass */ [data-theme="dark"] .chroma .nc { color:#ecbe7b }
/* NameConstant */ [data-theme="dark"] .chroma .no { color:#ecbe7b }
/* NameDecorator */ [data-theme="dark"] .chroma .nd { color:#ecbe7b }
/* NameEntity */ [data-theme="dark"] .chroma .ni { color:#c9c9c9 }
/* NameException */ [data-theme="dark"] .chroma .ne { color:#cf5967 }
/* NameLabel */ [data-theme="dark"] .chroma .nl { color:#cf5967 }
/* NameNamespace */ [data-theme="dark"] .chroma .nn { color:#c9c9c9 }
/* NameOther */ [data-theme="dark"] .chroma .nx { color:#c9c9c9 }
/* NameTag */ [data-theme="dark"] .chroma .nt { color:#bc74c4 }
/* NameBuiltin */ [data-theme="dark"] .chroma .nb { color:#7fbaf5 }
/* NameBuiltinPseudo */ [data-theme="dark"] .chroma .bp { color:#7fbaf5 }
/* NameVariable */ [data-theme="dark"] .chroma .nv { color:#bc74c4;font-style:italic }
/* NameVariableClass */ [data-theme="dark"] .chroma .vc { color:#57c7ff;font-weight:bold;font-style:italic }
/* NameVariableGlobal */ [data-theme="dark"] .chroma .vg { color:#ecbe7b;font-style:italic }
/* NameVariableInstance */ [data-theme="dark"] .chroma .vi { color:#57c7ff;font-style:italic }
/* NameVariableMagic */ [data-theme="dark"] .chroma .vm { color:#bc74c4;font-style:italic }
/* NameFunction */ [data-theme="dark"] .chroma .nf { color:#57c7ff }
/* NameFunctionMagic */ [data-theme="dark"] .chroma .fm { color:#57c7ff }
/* LiteralDate */ [data-theme="dark"] .chroma .ld { color:#57c7ff }
/* LiteralString */ [data-theme="dark"] .chroma .s { color:#82cc6a }
/* LiteralStringAffix */ [data-theme="dark"] .chroma .sa { color:#82cc6a }
/* LiteralStringBacktick */ [data-theme="dark"] .chroma .sb { color:#57c7ff }
/* LiteralStringChar */ [data-theme="dark"] .chroma .sc { color:#57c7ff }
/* LiteralStringDelimiter */ [data-theme="dark"] .chroma .dl { color:#82cc6a }
/* LiteralStringDoc */ [data-theme="dark"] .chroma .sd { color:#82cc6a }
/* LiteralStringDouble */ [data-theme="dark"] .chroma .s2 { color:#82cc6a }
/* LiteralStringEscape */ [data-theme="dark"] .chroma .se { color:#56b6c2 }
/* LiteralStringHeredoc */ [data-theme="dark"] .chroma .sh { color:#56b6c2 }
/* LiteralStringInterpol */ [data-theme="dark"] .chroma .si { color:#82cc6a }
/* LiteralStringOther */ [data-theme="dark"] .chroma .sx { color:#82cc6a }
/* LiteralStringRegex */ [data-theme="dark"] .chroma .sr { color:#57c7ff }
/* LiteralStringSingle */ [data-theme="dark"] .chroma .s1 { color:#82cc6a }
/* LiteralStringSymbol */ [data-theme="dark"] .chroma .ss { color:#82cc6a }
/* LiteralNumber */ [data-theme="dark"] .chroma .m { color:#56b6c2 }
/* LiteralNumberBin */ [data-theme="dark"] .chroma .mb { color:#57c7ff }
/* LiteralNumberFloat */ [data-theme="dark"] .chroma .mf { color:#56b6c2 }
/* LiteralNumberHex */ [data-theme="dark"] .chroma .mh { color:#57c7ff }
/* LiteralNumberInteger */ [data-theme="dark"] .chroma .mi { color:#56b6c2 }
/* LiteralNumberIntegerLong */ [data-theme="dark"] .chroma .il { color:#56b6c2 }
/* LiteralNumberOct */ [data-theme="dark"] .chroma .mo { color:#57c7ff }
/* Operator */ [data-theme="dark"] .chroma .o { color:#bc74c4 }
/* OperatorWord */ [data-theme="dark"] .chroma .ow { color:#bc74c4 }
/* OperatorReserved */ [data-theme="dark"] .chroma .or { color:#bc74c4 }
/* Punctuation */ [data-theme="dark"] .chroma .p { color:#56b6c2 }
/* Comment */ [data-theme="dark"] .chroma .c { color:#3e4460 }
/* CommentHashbang */ [data-theme="dark"] .chroma .ch { color:#3e4460;font-style:italic }
/* CommentMultiline */ [data-theme="dark"] .chroma .cm { color:#3e4460 }
/* CommentSingle */ [data-theme="dark"] .chroma .c1 { color:#3e4460 }
/* CommentSpecial */ [data-theme="dark"] .chroma .cs { color:#bc74c4;font-style:italic }
/* CommentPreproc */ [data-theme="dark"] .chroma .cp { color:#7fbaf5 }
/* CommentPreprocFile */ [data-theme="dark"] .chroma .cpf { color:#7fbaf5 }
/* GenericDeleted */ [data-theme="dark"] .chroma .gd { color:#cf5967 }
/* GenericEmph */ [data-theme="dark"] .chroma .ge { text-decoration:underline }
/* GenericError */ [data-theme="dark"] .chroma .gr { color:#cf5967;font-weight:bold }
/* GenericHeading */ [data-theme="dark"] .chroma .gh { color:#ecbe7b;font-weight:bold }
/* GenericInserted */ [data-theme="dark"] .chroma .gi { color:#ecbe7b }
/* GenericOutput */ [data-theme="dark"] .chroma .go { color:#43454f }
/* GenericPrompt */ [data-theme="dark"] .chroma .gp { color:#c9c9c9 }
/* GenericStrong */ [data-theme="dark"] .chroma .gs { color:#cf5967;font-weight:bold }
/* GenericSubheading */ [data-theme="dark"] .chroma .gu { color:#cf5967;font-style:italic }
/* GenericTraceback */ [data-theme="dark"] .chroma .gt { color:#c9c9c9 }
/* GenericUnderline */ [data-theme="dark"] .chroma .gl { text-decoration:underline }
/* TextWhitespace */ [data-theme="dark"] .chroma .w { color:#c9c9c9 }

/* Chroma wraps output in .highlight > pre.chroma; .chroma itself already sets
   border-radius via the rule below so the copy button's rounded corner and
   the code block's rounded corner line up. Chroma emits no padding of its
   own - padding-top clears the absolutely positioned .copy-btn so a long
   first line never renders underneath it; overflow-x keeps a long line
   scrolling inside the block instead of widening the page (paired with
   min-width: 0 on .post-layout > article above - without that, the line's
   min-content size still inflates the grid track and pushes .toc-sidebar out
   before overflow-x ever gets a chance to kick in). Border only goes on
   .chroma (the pre that actually has a background) - .highlight is a bare
   wrapper div with no fill, so bordering it too would draw a second, visibly
   offset outline around the same box. */
.highlight,
.chroma {
  border-radius: 8px;
}

.chroma {
  padding: 44px 16px 16px;
  overflow-x: auto;
  border: 1px solid var(--border);
  font-size: 14px;
}

/* vs's stock background (set above, generated by `hugo gen chromastyles`) is
   pure white, same as --card-bg, and the block blends into the page. Override
   background-color only, with an existing design token, so it stays visually
   distinct - re-apply after regenerating the vs block above. vulcan needs no
   such override: its own #282c34 is already lighter than both --bg and
   --card-bg, and several of its own rules (.hl, .kc) set backgrounds relative
   to that exact base color - overriding it here would both undo the
   intentional contrast and desync those relative shades. */
.chroma {
  background-color: var(--badge-bg);
}

.code-block-wrapper {
  position: relative;
  margin: 1.5em 0;
}

/* Groups copy + expand into one positioned element instead of each button
   positioning/hiding itself — .code-block-actions owns the placement and the
   hover/focus reveal, buttons inside are plain flex items. :focus-within
   (rather than :focus-visible per button) reveals the whole group when either
   button is focused, so Tab-ing to one doesn't leave the other invisible.
   Hidden until hover/focus so it doesn't sit on screen permanently; always
   shown below the mobile breakpoint, or on any device that reports no real
   hover/a coarse pointer (e.g. a touch-capable tablet/2-in-1 wider than the
   breakpoint) — width alone isn't a reliable proxy for touch. */
.code-block-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  gap: 8px;
  opacity: 0;
}

.code-block-wrapper:hover .code-block-actions,
.code-block-actions:focus-within {
  opacity: 1;
}

@media (max-width: 767px), (hover: none), (pointer: coarse) {
  .code-block-actions {
    opacity: 1;
  }
}

/* Reuses .btn-control / .btn-control-icon (nav theme/search buttons) for
   sizing, border, shadow and hover-lift — only icon style (stroke-based, like
   .nav-burger, not filled like sun/moon) is new. */
.copy-btn svg,
.expand-btn svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.copy-icon-success {
  color: var(--status-text);
}
