:root {
  --bg: #0a0a0a;
  --bg-card: #161616;
  --text: #f2f2f2;
  --text-dim: #9a9a9a;
  --border: #2a2a2a;
  --accent: #AC131C;
  --accent-2: #950706;
  --accent-3: #750227;
  --accent-4: #570044;
  --accent-5: #3B005C;
  --accent-gradient: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 25%, var(--accent-3) 50%, var(--accent-4) 75%, var(--accent-5) 100%);
  /* brighter red for text on --bg -- true --accent fails WCAG AA (~2.7:1) as foreground text on near-black, so it's reserved for fills (buttons, borders, bubbles) */
  --accent-text: #ff3b44;
  /* brightened same-hue companion to --accent-gradient, for gradient TEXT-FILL only --
     the true dark palette stops fail contrast even at large-text size when used as
     foreground text color, so text-fill uses these lightened stand-ins instead */
  --accent-gradient-text: linear-gradient(135deg, #ff3b44 0%, #ff4d8d 50%, #b26bff 100%);
  --accent-purple-text: #b26bff;
  --radius: 10px;
  --max-width: 960px;
}

* { box-sizing: border-box; }

/* Long unbroken tokens (URLs, repo slugs, pasted recommendation text) must not
   force horizontal page scroll on narrow viewports. */
p, li, blockquote, h1, h2, h3, h4, td, .repo-name, .cs-deck, .sec-lede {
  overflow-wrap: break-word;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* static grey dot grid (no animation, no red/white) behind every section
     except .hero, which layers its own animated version (canvas + gradient)
     above this in its own stacking context (isolation: isolate) */
  background:
    radial-gradient(circle, rgba(154, 154, 154, 0.08) 1.3px, transparent 1.3px) 0 0 / 32px 32px,
    var(--bg);
  color: var(--text);
  line-height: 1.5;
}

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

.cs-section p a, .story-main p a {
  text-decoration-color: var(--border);
}
.cs-section p a:hover, .story-main p a:hover {
  text-decoration-color: var(--accent-text);
}

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 1.5rem 1rem;
}

.nav .brand {
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--text);
  text-decoration: none;
}

.nav nav a {
  margin-left: 1.5rem;
  color: var(--text-dim);
  text-decoration: none;
}
.nav nav a:hover { color: var(--accent-text); }

main {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 1rem;
}

/* used only inside .hero, to break its background out to full viewport
   width (see .hero below) while keeping the actual content centered at
   the same width main's other children (about.html/projects.html included,
   which share this stylesheet) already use */
.section-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 1rem;
}

main > section + section {
  margin-top: 3rem;
}

main > section h2 {
  font-size: 1.4rem;
  margin-bottom: 0.5rem;
}

.hero {
  position: relative;
  isolation: isolate; /* contains the ::before/canvas z-index:-1/-2 so they stay behind the hero's own content without sinking below the page */
  overflow: hidden; /* clips both layers cleanly to the hero's own bounds */
  /* breaks out of main's centered max-width so the background spans the
     full viewport, without touching main itself (about.html/projects.html
     share this stylesheet and still rely on main's own centering) */
  left: 50%;
  width: 100vw;
  margin-left: -50vw;
  padding: 5rem 0 2.5rem;
}

/* hero's own bottom padding + the generic main>section+section margin-top
   (3rem) stack to ~112px here -- too wide right after the hero's visual
   weight. Override just this adjacency; other section-to-section gaps
   elsewhere on the page are untouched. */
.hero + .story {
  margin-top: 3.25rem;
}

/* static base layer: skewed red glow from each side, fading to black
   (--bg) toward the center. Static -- the animated part is the dot grid
   (.hero-canvas, drawn by js/hero-dots.js) layered on top of this. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(ellipse 45% 85% at 0% 50%, rgba(172, 19, 28, 0.4), transparent 70%),
    radial-gradient(ellipse 45% 85% at 100% 50%, rgba(172, 19, 28, 0.4), transparent 70%);
  pointer-events: none;
}

.hero-canvas {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

.hero-inner {
  display: flex;
  align-items: flex-start;
  gap: 2.5rem;
  flex-wrap: wrap;
}

/* fixed-size circular frame -- border/shadow/sizing live here, NOT on the
   zoomed img, so scaling the photo doesn't balloon the circle itself
   (that was the earlier bug: transform on the bordered element grew the
   whole circle from 140px to ~189px, throwing off alignment and spacing) */
.hero-avatar-frame {
  flex-shrink: 0;
  width: 170px;
  height: 170px;
  border-radius: 50%;
  overflow: hidden;
  border: 3px solid var(--accent);
  box-shadow: 0 0 24px rgba(255, 59, 68, 0.25);
  /* nudges the frame's center down from the top of the row to line up
     with the headline (h1)'s center rather than the greeting line above it --
     measured directly against rendered layout, not guessed */
  margin-top: 3.86rem;
}

.hero-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* source photo is a tall portrait with the face near the top. Zooming
     via transform scales from the CENTER by default, which was pulling
     the top (hair) back out of frame even with object-position biased up --
     anchoring transform-origin to the top instead makes the zoom grow the
     crop downward (into the shoulders) rather than cutting into the head */
  object-position: center top;
  transform-origin: center top;
  transform: scale(1.22);
}

.hero-content {
  min-width: 0;
  flex: 1 1 420px;
}

.hero .greeting {
  color: var(--text-dim);
  font-size: 1.1rem;
  margin-bottom: 0.02rem;
}

.highlight-text {
  background: var(--accent-gradient-text);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent-text);
  font-weight: 800;
}

.hero h1 {
  /* base size covers the sentence line + the merged-in jargon line (was a
     separate .jargon paragraph, now literally h1's 3rd line via <br/>).
     Sized so the ~73-char sentence wraps to exactly 2 lines (not 1, not 3)
     within the hero-content column. .role-typer overrides this to stay
     prominent as the big first line. */
  font-size: 2rem;
  line-height: 1.5;
  font-weight: 600;
  margin-top: 0;
  margin-bottom: 1.25rem;
}

.gradient-text {
  background: var(--accent-gradient-text);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent-text); /* fallback if -webkit-text-fill-color unsupported */
}

/* @revawiki in the greeting links to the about page; keep the gradient fill
   and add a subtle underline so it reads as clickable */
.greeting-link {
  text-decoration: none;
}

.role-typer {
  font-size: 2.3rem;
  font-weight: 700;
}

.cursor {
  color: var(--accent-text);
  animation: cursor-blink 1s step-start infinite;
}

@keyframes cursor-blink {
  50% { opacity: 0; }
}

.hero h1 .term-group {
  margin-top: 0.25rem;
}

.term {
  white-space: nowrap;
}

.term-group {
  position: relative;
  display: inline-block;
  padding: 0.05rem 0.2rem;
}

/* moving-trace overlay around the whole Agentic AI + IaC + O11Y group --
   a short segment continuously travels the rectangle's perimeter, never
   forming a complete static outline */
.term-circle {
  position: absolute;
  left: -2px;
  right: -2px;
  top: -2px;
  bottom: -2px;
  width: calc(100% + 4px);
  height: calc(100% + 4px);
  overflow: visible;
  pointer-events: none;
}

/* registered so --trace-color can be smoothly animated as a color (plain
   custom properties don't interpolate -- they just jump) */
@property --trace-color {
  syntax: '<color>';
  inherits: true;
  initial-value: #b26bff;
}

.term-circle path {
  fill: none;
  stroke-width: 0.85;
  stroke: var(--trace-color);
  /* pathLength="1" normalizes the rect's perimeter to 1 unit, so dashoffset
     below is a fraction of the perimeter, not pixels. */
  /* dash+gap sums to 0.5 (half the perimeter), so the pattern repeats twice
     around the loop -- two shorter segments, evenly spaced, instead of one */
  stroke-dasharray: 0.12 0.38;
  animation: term-circle-trace 6s linear infinite;
}

@keyframes term-circle-trace {
  /* constant pace, no fast/slow phases. The path (index.html) is authored
     to start at bottom-center and trace clockwise, with a perimeter of 264
     units where the bottom/right/top/left edge-midpoints land at exactly
     0%, 25%, 50%, 75% (100% loops back to bottom) -- so color is white
     right at each edge-midpoint and purple at the roughly-halfway points
     between them (near the corners), for the plus-shaped pattern. */
  0%    { stroke-dashoffset: 0;     --trace-color: #ffffff; } /* bottom */
  12.5% { --trace-color: #b26bff; }
  25%   { --trace-color: #ffffff; } /* right */
  37.5% { --trace-color: #b26bff; }
  50%   { --trace-color: #ffffff; } /* top */
  62.5% { --trace-color: #b26bff; }
  75%   { --trace-color: #ffffff; } /* left */
  87.5% { --trace-color: #b26bff; }
  100%  { stroke-dashoffset: -1;    --trace-color: #ffffff; } /* bottom (loop) */
}

@media (prefers-reduced-motion: reduce) {
  .term-circle path { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .term { animation: none; }
}

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.75rem;
}

/* smaller, rounded-rectangle tech-stack chip -- distinct from the pill-shaped
   .badge used for domain/role badges elsewhere */
.tech-chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.25rem 0.55rem;
  font-size: 0.72rem;
  color: var(--text-dim);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.45rem 1.1rem;
  font-size: 1rem;
  color: var(--text-dim);
  transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease,
    box-shadow 0.3s ease, text-shadow 0.3s ease;
}

.badge-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  opacity: 0.85;
}

.badge-active {
  background: rgba(255, 59, 68, 0.16);
  border: 1px solid var(--accent);
  color: #fff;
  box-shadow: 0 0 10px rgba(255, 59, 68, 0.55), inset 0 0 6px rgba(255, 59, 68, 0.35);
  text-shadow: 0 0 6px rgba(255, 59, 68, 0.75);
}

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

.hero-note p {
  color: var(--text-dim);
  max-width: 60ch;
  font-size: 1.05rem;
}

.cta { margin-top: 1.5rem; }

.cta .btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.cta .btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.cta-stretch {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.cta-stretch .btn {
  flex: 1 1 140px;
  justify-content: center;
  margin-right: 0;
}

#projects .cta,
#sharing .cta { text-align: center; }

.btn {
  display: inline-block;
  padding: 0.6rem 1.2rem;
  border-radius: var(--radius);
  background: var(--accent-gradient);
  color: #fff;
  font-weight: 600;
  margin-right: 0.75rem;
  text-decoration: none;
  transition: background 0.15s ease, transform 0.1s ease;
}

/* filled buttons darken on hover and darken further + sink on press, so the
   click reads as a physical button press. Shared with .story-btn-primary
   ("Ask Me") so every solid CTA on the site behaves the same way. */
.btn:not(.btn-outline):hover {
  text-decoration: none;
  color: #fff;
  background: linear-gradient(135deg, #8a0f16 0%, #7a0505 25%, #5e021f 50%, #450036 75%, #2e0049 100%);
}

.btn:not(.btn-outline):active {
  color: #fff;
  background: linear-gradient(135deg, #5c0a0f 0%, #520303 25%, #3f0115 50%, #2e0024 75%, #1f0031 100%);
  transform: translateY(1px);
}

.btn-outline:hover { text-decoration: none; }

.btn-outline {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.24);
  color: var(--text);
}
.btn-outline:hover { background: rgba(255, 59, 68, 0.16); border-color: var(--accent); color: var(--text); }

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

.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 1.25rem;
}

.card h3 { margin-top: 0; }
.card p { color: var(--text-dim); margin-bottom: 0; }

.project-list {
  display: grid;
  gap: 1rem;
  margin-top: 1.5rem;
}

.project {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 1.25rem;
}

.project h3 { margin: 0 0 0.25rem; }
.project .stack { color: var(--text-dim); font-size: 0.9rem; margin-bottom: 0.5rem; }
.project p { margin: 0 0 0.5rem; }

footer {
  text-align: center;
  color: var(--text-dim);
  padding: 2rem 1rem;
  font-size: 0.9rem;
}

/* chat widget */
.chat-widget {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 50;
}

/* launcher is a circular avatar; .is-open (set by chat.js) cross-fades it to
   a close X so the same button both opens and dismisses the panel */
.chat-toggle {
  position: relative;
  display: grid;
  place-items: center;
  width: 74px;
  height: 74px;
  padding: 0;
  background: var(--accent-gradient);
  color: #fff;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.chat-toggle:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(255, 59, 68, 0.35);
}

/* attention ping: an expanding ring radiating from the launcher, looping
   until the panel is opened. Runs on ::before so it never blocks clicks. */
.chat-toggle::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid var(--accent);
  animation: chat-ping 2.2s cubic-bezier(0, 0, 0.2, 1) infinite;
  pointer-events: none;
}
@keyframes chat-ping {
  0% { transform: scale(1); opacity: 0.8; }
  70%, 100% { transform: scale(1.45); opacity: 0; }
}
.chat-widget.is-open .chat-toggle::before { animation: none; opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .chat-toggle::before { animation: none; opacity: 0; }
}

.chat-avatar-wrap {
  position: relative;
  display: block;
  width: 66px;
  height: 66px;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.chat-avatar {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  /* same crop bias as .hero-avatar: the source photo is a tall portrait with
     the face near the top, so the default centre crop cuts through the head */
  object-position: center top;
  display: block;
  border: 2px solid rgba(255, 255, 255, 0.9);
  box-sizing: border-box;
}

/* green "online" dot, bottom-right of the avatar */
.chat-status {
  position: absolute;
  right: 1px;
  bottom: 1px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #22c55e;
  border: 2px solid var(--bg);
  box-sizing: content-box;
}

.chat-close-icon {
  position: absolute;
  width: 22px;
  height: 22px;
  opacity: 0;
  transform: rotate(-90deg);
  transition: opacity 0.18s ease, transform 0.18s ease;
}

/* scoped to .chat-toggle: the panel header reuses .chat-avatar-wrap, so an
   unscoped rule here hid the header avatar whenever the panel was open */
.chat-widget.is-open .chat-toggle .chat-avatar-wrap { opacity: 0; transform: scale(0.6); }
.chat-widget.is-open .chat-close-icon { opacity: 1; transform: rotate(0deg); }

/* smaller avatar reused inside the panel header */
.chat-avatar-sm { width: 38px; height: 38px; }
.chat-avatar-sm .chat-status { width: 9px; height: 9px; border-width: 2px; }

.chat-header {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--accent-gradient);
}

.chat-header .chat-avatar { border-color: rgba(255, 255, 255, 0.9); }
.chat-header .chat-status { border-color: rgba(255, 255, 255, 0.5); }

.chat-header-text { display: flex; flex-direction: column; line-height: 1.3; }
.chat-header-text strong { font-size: 0.95rem; color: #fff; }
.chat-header-text span { color: rgba(255, 255, 255, 0.85); font-size: 0.8rem; }

.chat-panel {
  position: absolute;
  bottom: 5rem;
  right: 0;
  width: 400px;
  max-width: calc(100vw - 2.5rem);
  height: 560px;
  max-height: calc(100vh - 8rem);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 14px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}

.chat-panel.hidden { display: none; }

.chat-log {
  flex: 1;
  overflow-y: auto;
  padding: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  min-height: 0;
}

.chat-msg {
  padding: 0.55rem 0.8rem;
  border-radius: 12px;
  font-size: 0.9rem;
  line-height: 1.5;
  max-width: 85%;
  word-wrap: break-word;
  /* Replies arrive as plain text with \n\n paragraph breaks; without this
     they collapse into one dense wall, which reads terribly in a bubble. */
  white-space: pre-line;
}

.chat-user {
  align-self: flex-end;
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.chat-bot {
  align-self: flex-start;
  background: #232323;
  color: var(--text);
  border-bottom-left-radius: 4px;
}

/* starter-question chips shown while the log is empty */
.chat-starters {
  padding: 0.25rem 0.85rem 0.45rem;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.04);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.chat-starters-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.3rem 0.1rem;
  cursor: pointer;
}
.chat-starters-bar svg {
  width: 14px;
  height: 14px;
  transition: transform 0.2s ease;
}
.chat-starters.collapsed .chat-starters-bar svg { transform: rotate(180deg); }
.chat-starters-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.4rem;
  padding-top: 0.15rem;
}
.chat-starters.collapsed .chat-starters-chips { display: none; }
.chat-starter {
  display: flex;
  width: 100%;
  justify-content: center;
  align-items: center;
  gap: 0.4rem;
  background: var(--bg);
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--text);
  font-size: 0.82rem;
  padding: 0.45rem 0.6rem;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.chat-starter svg {
  width: 14px;
  height: 14px;
  color: var(--accent-text);
  flex-shrink: 0;
}
.chat-starter:hover {
  background: rgba(255, 59, 68, 0.12);
}

.chat-msg a {
  color: var(--accent-text);
  text-decoration: none;
  font-weight: 600;
}
.chat-msg a:hover { text-decoration: underline; text-underline-offset: 2px; }
.chat-msg strong { font-weight: 600; }
.chat-msg em { font-style: italic; }
.chat-msg del { opacity: 0.65; }
.chat-msg code {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 0.82em;
  background: rgba(255, 255, 255, 0.08);
  padding: 0.08em 0.35em;
  border-radius: 5px;
}

/* direct-contact CTA, rendered in the log after repeated deflections */
.chat-cta {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 0.9rem;
  text-align: center;
  margin-top: 0.25rem;
}
.chat-cta p {
  margin: 0 0 0.6rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text);
}
.chat-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: var(--accent-gradient);
  color: #fff;
  text-decoration: none;
  font-size: 0.84rem;
  font-weight: 600;
  padding: 0.5rem 1rem;
  border-radius: 999px;
}
.chat-cta-btn svg {
  width: 14px;
  height: 14px;
}
.chat-cta-btn:hover {
  color: #fff;
  filter: brightness(1.1);
}

/* three-dot typing indicator */
.chat-typing {
  display: flex;
  gap: 4px;
  align-items: center;
}
.chat-typing span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-dim);
  animation: chat-blink 1.2s infinite ease-in-out both;
}
.chat-typing span:nth-child(2) { animation-delay: 0.2s; }
.chat-typing span:nth-child(3) { animation-delay: 0.4s; }
@keyframes chat-blink {
  0%, 80%, 100% { opacity: 0.25; }
  40% { opacity: 1; }
}

#chat-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  border-top: 1px solid var(--border);
  padding: 0.5rem 0.5rem 0.5rem 0.25rem;
}

#chat-input {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--text);
  padding: 0.6rem 0.75rem;
  outline: none;
  font-size: 0.9rem;
}

#chat-form button {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--accent-gradient);
  border: none;
  color: #fff;
  cursor: pointer;
  transition: transform 0.15s ease, opacity 0.15s ease;
}
#chat-form button:hover { transform: scale(1.06); }
#chat-form button svg { width: 18px; height: 18px; display: block; }

.story {
  padding: 0 1rem 2.5rem;
  text-align: center;
}

/* narrative text keeps a narrow reading column; .story-ctas (below) is a
   sibling, NOT nested in this, so the CTA row can use the full section
   width instead of being squeezed into the same 46rem and wrapping */
.story-text {
  max-width: 46rem;
  margin: 0 auto;
}

.story p {
  color: var(--text-dim);
  font-size: 1.25rem;
  line-height: 1.6;
  margin: 0;
}

.story-highlight {
  background: var(--accent-gradient-text);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent-text); /* fallback if -webkit-text-fill-color unsupported */
  font-weight: 700;
}

/* ".story p.x" (element+2 classes) beats ".story p" (element+1 class) on
   specificity, so margin-top actually takes -- learned the hard way earlier
   in this file that a plain ".x" class loses to ".parent element" and
   silently no-ops instead of erroring */
.story p.story-gap {
  margin-top: 1.75rem;
}

.story p.story-proof {
  margin-top: 1.75rem;
  font-size: 1rem;
  max-width: 38rem;
  margin-left: auto;
  margin-right: auto;
}

.story p.story-more {
  margin-top: 1.5rem;
  font-size: 1rem;
}

.story p.story-more a {
  color: var(--accent-text);
  text-decoration: none;
  font-weight: 600;
}
.story p.story-more a:hover { text-decoration: underline; }

.story p.story-bold {
  color: var(--text);
  font-weight: 700;
  font-size: 1.4rem;
}

.story-ctas {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem; /* matches .story-more's margin-top so the gap above and
                          below "Read the full story" reads as symmetric */
}

.story-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: 999px;
  padding: 0.6rem 1.25rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  background: transparent;
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.story-btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.story-btn:hover {
  background: rgba(255, 59, 68, 0.16);
  border-color: var(--accent);
  color: var(--text);
}

.story-btn-primary {
  border: none;
  background: var(--accent-gradient);
  color: #fff;
  transition: background 0.15s ease, transform 0.1s ease;
}

/* matches the filled .btn press behaviour above */
.story-btn-primary:hover {
  background: linear-gradient(135deg, #8a0f16 0%, #7a0505 25%, #5e021f 50%, #450036 75%, #2e0049 100%);
  color: #fff;
}

.story-btn-primary:active {
  color: #fff;
  background: linear-gradient(135deg, #5c0a0f 0%, #520303 25%, #3f0115 50%, #2e0024 75%, #1f0031 100%);
  transform: translateY(1px);
}

/* case study pages (frontend/case-study-*.html) */
.case-study-meta {
  color: var(--text-dim);
  margin-top: 0.5rem;
}

.case-study-section {
  margin-top: 2.5rem;
}

.case-study-section h2 {
  font-size: 1.3rem;
  margin-bottom: 0.75rem;
}

.case-study-section p {
  color: var(--text-dim);
  max-width: 70ch;
  line-height: 1.7;
  margin-bottom: 1rem;
}

.case-study-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1rem;
}

.case-study-stat {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  min-width: 140px;
}

.case-study-stat .num {
  display: block;
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--accent-text);
}

.case-study-stat .label {
  color: var(--text-dim);
  font-size: 0.85rem;
}

.back-link {
  display: inline-block;
  margin-top: 3rem;
}

/* articles listing (frontend/articles.html) + detail pages */
.article-list {
  display: grid;
  gap: 1rem;
  margin-top: 1.5rem;
}

.article-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
}

.article-card h3 { margin: 0 0 0.25rem; }
.article-card h3 a { color: var(--text); text-decoration: none; }
.article-card h3 a:hover { color: var(--accent-text); }

.article-meta {
  color: var(--text-dim);
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}

.article-card p { margin: 0; color: var(--text-dim); }

.article-body {
  max-width: 70ch;
  margin-top: 1.5rem;
}

.article-body p {
  color: var(--text-dim);
  line-height: 1.75;
  margin-bottom: 1.1rem;
}

/* ============================================================
   Homepage content sections (#experience, #projects, #sharing,
   #education, #skills, #contact) -- mirrors the section set the
   reference site (santifer.io) carries on its single-page layout,
   which the earlier scaffold pass skipped entirely.
   ============================================================ */

html {
  scroll-behavior: smooth;
  /* .hero breaks out with width:100vw, which counts the scrollbar while the
     document does not -- that mismatch otherwise leaves ~15px of dead
     horizontal scroll on desktop. No sticky elements in this stylesheet, so
     clipping here is safe (position:fixed is unaffected). */
  overflow-x: hidden;
}

.sec {
  scroll-margin-top: 2rem; /* breathing room when jumped to via anchor */
}

main > section.sec + section.sec,
main > section + section.sec {
  margin-top: 3.5rem;
}

.sec-title {
  font-size: 1.9rem;
  margin: 0 0 0.5rem;
}

.sec-header {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-bottom: 0.5rem;
}

.sec-header .sec-title { margin-bottom: 0; }

/* project-grid/talk-list used to get their top spacing from a sec-lede
   paragraph in between; both sections dropped that lede, so the grid now
   sits flush against the header without this. */
.sec-header + .project-grid,
.sec-header + .talk-list,
.sec-header + .edu-list,
.sec-header + .cert-grid,
.sec-header + .skills-layout,
.sec-title + .project-grid,
.sec-title + .repo-grid,
.sec-title + .project-card,
.sec-title + .talk-list {
  margin-top: 0.875rem;
}

.sec-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 12px;
  background: var(--accent-gradient);
  color: #fff;
}

.sec-icon svg { width: 22px; height: 22px; }

/* section header + lede centered, content below stays left-aligned */
.sec-centered .sec-header,
.sec-centered .sec-lede {
  justify-content: center;
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.sec-lede {
  color: var(--text-dim);
  max-width: 65ch;
  font-size: 1.05rem;
  margin: 0 0 2rem;
}

.sec-lede em {
  color: var(--text);
  font-style: normal;
  font-weight: 600;
}

.sec-lede strong {
  color: var(--text);
}

.sub-title {
  font-size: 1.2rem;
  margin: 2.75rem 0 0.75rem;
}

.sec-note {
  color: var(--text-dim);
  font-size: 0.9rem;
  margin-top: 1rem;
}

.sec-note a { text-decoration: none; }
.sec-note a:hover { text-decoration: underline; }

.inline-link {
  display: inline-block;
  margin-top: 0.75rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--accent-text);
  text-decoration: none;
}
.inline-link:hover { text-decoration: underline; }

/* competencies */
.competency-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
  margin-bottom: 2.5rem;
}

.competency {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.competency:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.competency h4 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.35rem;
  font-size: 1rem;
}
.competency p { margin: 0; color: var(--text-dim); font-size: 0.9rem; line-height: 1.5; }

.competency-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--accent-text);
}

/* role / experience entries */
.role {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
  margin-bottom: 1rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.role:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.role-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

.role-head h3 { margin: 0; font-size: 1.25rem; }

.role-company {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.role-company a {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  color: inherit;
  text-decoration: none;
  transition: color 0.25s ease;
}

.role-company a:hover { color: var(--accent-text); }

.company-logo {
  height: 36px;
  width: auto;
  max-width: 60px;
  transition: filter 0.25s ease;
  object-fit: contain;
  flex-shrink: 0;
  background: #fff;
  border-radius: 8px;
  padding: 5px;
  box-sizing: content-box;
}

.role-title {
  margin: 0.75rem 0 0;
  color: var(--accent-text);
  font-weight: 600;
  font-size: 1.1rem;
}

.role-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  color: var(--text-dim);
  font-size: 0.88rem;
  white-space: nowrap;
}

.role-summary {
  color: var(--text-dim);
  line-height: 1.65;
  margin: 0 0 0.9rem;
}

.role-points {
  margin: 0 0 1rem;
  padding-left: 1.15rem;
  color: var(--text-dim);
}

.role-points li { margin-bottom: 0.4rem; line-height: 1.55; text-align: justify; }
#experience .role-summary,
#experience .award-desc,
#experience .quote-card blockquote {
  text-align: justify;
}

/* single-company career progression (e.g. promoted within the same employer)
   -- a vertical connector line with a dot per position, newest first */
.role-progression {
  position: relative;
  margin-top: 1rem;
  padding-left: 1.25rem;
  border-left: 2px solid var(--border);
}

.role-progression-item {
  position: relative;
  padding-bottom: 1.5rem;
}
.role-progression-item:last-child { padding-bottom: 0; }

.role-progression-divider {
  position: relative;
  margin: -0.5rem 0 1.5rem;
}

.role-progression-item::before {
  content: "";
  position: absolute;
  left: -1.56rem;
  top: 0.4rem;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--bg-card);
}

.role-progression-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

.role-progression-head .role-title { margin: 0; }

.role-progression-unit {
  display: block;
  color: var(--text-dim);
  font-size: 0.8rem;
  margin-top: 0.15rem;
}

.role-progression-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  white-space: nowrap;
}

.role-progression-dates {
  color: var(--accent-text);
  font-weight: 600;
  font-size: 0.85rem;
}

.role-progression-location {
  color: var(--text-dim);
  font-size: 0.8rem;
}

.promoted-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: rgba(255, 59, 68, 0.12);
  color: var(--accent-text);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.promoted-badge svg { width: 11px; height: 11px; }

/* testimonial */
.quote-card {
  /* <figure> has a UA default margin (1em 40px) -- reset the full shorthand,
     not just margin-top, or bottom/left/right leak through unstyled */
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
  margin: 1.5rem 0 0;
}

.quote-linkedin {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #0a66c2;
  border: 1px solid transparent;
  border-radius: 5px;
  color: #fff;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

/* overrides the global a:hover color rule, which would otherwise turn this
   icon red via fill="currentColor" -- stays LinkedIn-blue with a white glow */
.quote-linkedin:hover {
  color: #fff;
  border-color: #fff;
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.5);
}
.quote-linkedin svg { width: 15px; height: 15px; }

.quote-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg);
}

.quote-card blockquote {
  margin: 0 0 1rem;
  color: var(--text);
  font-size: 1.05rem;
  line-height: 1.65;
  font-style: italic;
}


/* smaller variant for nesting directly under a role's job description,
   where a full-size testimonial card would dominate too early in the card */
.quote-card-sm {
  padding: 1.1rem 1.2rem;
  margin: 1rem 0 0;
}
.quote-card-sm blockquote:last-child {
  margin-bottom: 0;
}

.quote-card-sm blockquote {
  font-size: 0.82rem;
  line-height: 1.5;
  margin-bottom: 0.65rem;
}
.quote-card-sm .quote-avatar { width: 44px; height: 44px; }
.quote-card-sm figcaption strong { font-size: 0.85rem; }
.quote-card-sm figcaption span { font-size: 0.74rem; }
.quote-card-sm .quote-linkedin { width: 22px; height: 22px; top: 0.85rem; right: 0.85rem; }
.quote-card-sm .quote-linkedin svg { width: 13px; height: 13px; }

.quote-card footer { display: flex; flex-direction: column; }
.quote-card footer span { color: var(--text-dim); font-size: 0.88rem; }

/* project cards */
.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
}

.project-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 1.35rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.project-card:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

/* card body copy is justified to match the experience section; :not() keeps
   the single-line org/meta lines out of it, where justify does nothing useful */
.project-card > p:not(.project-org) {
  text-align: justify;
}

.project-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.6rem;
}

.project-card-head h3 { margin: 0; font-size: 1.1rem; }
.project-card p { color: var(--text-dim); line-height: 1.6; margin: 0 0 0.9rem; }

.tag {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
  color: var(--text-dim);
  white-space: nowrap;
}

.tag-live {
  border-color: var(--accent);
  color: var(--accent-text);
}

/* repo / fleet grid */
.repo-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
}

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

.repo {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
}

.repo-name {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92rem;
  color: var(--text);
}

.repo-vis {
  margin-left: 0.5rem;
  font-size: 0.7rem;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.1rem 0.45rem;
}

.repo p { margin: 0.45rem 0 0; color: var(--text-dim); font-size: 0.85rem; line-height: 1.45; }

/* sharing */
.share-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
}

.share-card {
  display: block;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  text-decoration: none;
  transition: border-color 0.2s ease;
}

.share-card:hover { border-color: var(--accent); color: inherit; }

.share-meta { color: var(--text-dim); font-size: 0.8rem; margin-bottom: 0.4rem; }
.share-card h4 { margin: 0 0 0.45rem; font-size: 1rem; color: var(--text); }
.share-card p { margin: 0; color: var(--text-dim); font-size: 0.9rem; line-height: 1.5; }

/* matches .project-grid / .project-card so Sharing Sessions reads as the
   same component family as Signature Work */
.talk-list {
  display: grid;
  gap: 1.15rem;
}

.talk {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 1.55rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.talk:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.talk-meta { color: var(--text-dim); font-size: 0.84rem; margin-bottom: 0.35rem; }
.talk h4 { margin: 0 0 0.75rem; font-size: 1.1rem; }
.talk p { margin: 0; color: var(--text-dim); font-size: 0.95rem; line-height: 1.58; }

.talk-list-3col { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) {
  .talk-list-3col { grid-template-columns: 1fr; }
}

/* education + certifications */
.edu-list { display: grid; gap: 1rem; }

.edu {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.edu:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.edu-meta { color: var(--text-dim); font-size: 0.82rem; margin-bottom: 0.3rem; }
.edu h4 { margin: 0 0 0.35rem; font-size: 1.05rem; }
.edu p { margin: 0; color: var(--text-dim); font-size: 0.9rem; }

.edu-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.35rem;
}

.edu p.edu-school {
  margin: 0;
  font-size: 0.82rem;
  color: var(--text-dim);
}

.edu-school a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: inherit;
  text-decoration: none;
  transition: color 0.25s ease;
}

.edu-school a:hover { color: var(--accent-text); }

.edu-logo {
  height: 16px;
  width: auto;
  max-width: 24px;
  object-fit: contain;
  flex-shrink: 0;
  background: #fff;
  border-radius: 4px;
  padding: 2px;
  box-sizing: content-box;
}

.edu-dates { color: var(--accent-text); font-weight: 600; font-size: 0.85rem; white-space: nowrap; }

.edu p.edu-grade { margin-bottom: 0.5rem; font-size: 0.85rem; }
.edu p.edu-thesis { font-size: 0.85rem; line-height: 1.55; }

.cert-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 0.9rem;
}

.cert {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.85rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  text-decoration: none;
  color: inherit;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.cert:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  color: inherit;
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.cert-info { display: flex; flex-direction: column; gap: 0.2rem; }
.cert-name { font-size: 0.95rem; }
.cert-issuer { color: var(--text-dim); font-size: 0.82rem; }

.cert-logo {
  height: 32px;
  width: 32px;
  flex-shrink: 0;
  background: #fff;
  border-radius: 6px;
  padding: 4px;
  box-sizing: content-box;
  object-fit: contain;
}

/* skills */
.skills-layout {
  display: grid;
  grid-template-columns: 175px 1fr;
  gap: 2rem;
  align-items: start;
}

.skills-sidebar { display: flex; flex-direction: column; gap: 2rem; }

.skills-block-title {
  margin: 0 0 0.85rem;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
}

@media (max-width: 860px) {
  .skills-layout { grid-template-columns: 1fr; }
}

.lang-list { display: flex; flex-direction: column; }

.lang-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.45rem 0;
  font-size: 0.93rem;
}

.lang-name { color: var(--text); font-weight: 600; display: inline-flex; align-items: center; gap: 0.45rem; }
.lang-flag { font-size: 1.05rem; line-height: 1; }
.lang-level { color: var(--text-dim); }

.soft-pills { display: flex; flex-direction: column; gap: 0.6rem; }

.soft-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1 1 auto;
  background: rgba(255, 59, 68, 0.12);
  border: 1px solid rgba(255, 59, 68, 0.35);
  color: var(--accent-text);
  border-radius: var(--radius);
  padding: 0.4rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 600;
}

.tech-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  align-items: start;
  gap: 1rem;
}

.tech-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  min-height: 230px;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.tech-card:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.tech-card-label {
  display: block;
  color: var(--accent-text);
  font-weight: 400;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}

.tech-item-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.65rem 0.75rem;
}

.tech-item-list li {
  position: relative;
  padding-left: 1.1rem;
  color: var(--text-dim);
  font-size: 0.78rem;
}

.tech-item-list li.has-icon {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  padding-left: 0;
}

.tech-icon {
  height: 14px;
  width: auto;
  max-width: 22px;
  object-fit: contain;
  flex-shrink: 0;
}

.tech-item-list li:not(.has-icon)::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.1em;
  width: 12px;
  height: 12px;
  background-color: var(--accent);
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
  mask-size: contain;
  mask-repeat: no-repeat;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  -webkit-mask-repeat: no-repeat;
}

@media (max-width: 860px) {
  .skills-layout { grid-template-columns: 1fr; }
}

.stack-grid { display: grid; gap: 0.9rem; }

.stack-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 0.85rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
  text-align: center;
}

.code-sample-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
  margin: 1.5rem 0;
}

.code-sample {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.code-sample-name {
  display: block;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--border);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8rem;
  color: var(--accent-text);
}

.code-sample pre {
  margin: 0;
  padding: 1rem;
  overflow-x: auto;
}

.code-sample code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--text-dim);
  white-space: pre;
}

.stack-row {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 1rem;
  align-items: start;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--border);
}

.stack-label {
  color: var(--accent-text);
  font-weight: 600;
  font-size: 0.92rem;
  padding-top: 0.35rem;
}

/* .badges carries a 1.75rem bottom margin for the hero; inside these cards
   that reads as a dangling gap, so zero it out where it's a trailing element */
.stack-row .badges,
.role .badges,
.project-card .badges,
.skills-col .badges,
.case-study-section .badges { margin-bottom: 0; }

.role .badges { margin-top: 0.25rem; }

@media (max-width: 620px) {
  .stack-row { grid-template-columns: 1fr; gap: 0.5rem; }
  .role-meta { align-items: flex-start; }
}

/* contact */
.contact-sec .cta { margin-top: 1.5rem; }

/* long-form pages (story.html, case studies, articles) */
.kicker {
  color: var(--accent-text);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0 0 0.5rem;
}

.article-body .lede {
  color: var(--text);
  font-size: 1.15rem;
  line-height: 1.7;
}

.timeline {
  list-style: none;
  margin: 0;
  padding: 0 0 0 1rem;
  border-left: 2px solid var(--border);
}

.timeline li {
  display: grid;
  grid-template-columns: 70px 1fr;
  gap: 1rem;
  position: relative;
  padding: 0 0 1.5rem 1rem;
}

.timeline li::before {
  content: "";
  position: absolute;
  left: -1.42rem;
  top: 0.45rem;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
}

.tl-date {
  color: var(--accent-text);
  font-weight: 700;
  font-size: 0.9rem;
  padding-top: 0.1rem;
}

.timeline h4 { margin: 0 0 0.2rem; font-size: 1rem; }
.timeline p { margin: 0; color: var(--text-dim); font-size: 0.92rem; line-height: 1.55; }

@media (max-width: 620px) {
  .timeline li { grid-template-columns: 1fr; gap: 0.25rem; }
}

/* 404 */
.notfound {
  text-align: center;
  padding: 4rem 1rem;
}

.notfound .code {
  font-size: 4rem;
  font-weight: 800;
  background: var(--accent-gradient-text);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent-text);
  margin: 0;
  line-height: 1;
}

.notfound p { color: var(--text-dim); margin: 1rem 0 0; }
.notfound .cta { justify-content: center; margin-top: 1.75rem; }

/* ============================================================
   Homepage v2 -- components added when the site was filled in
   with real CV / GitHub content.
   ============================================================ */

.competency-grid-3 {
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}

.role-list { display: grid; gap: 1rem; }

.role-dates {
  color: var(--accent-text);
  font-weight: 400;
}

.role-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.85rem;
}

.role-links .inline-link { margin-top: 0; }

.signature-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 0.5rem 1.1rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--accent-text);
  text-decoration: none;
  text-shadow: 0 0 8px rgba(255, 59, 68, 0.6);
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
}

.signature-link-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

.signature-link:hover {
  background: rgba(255, 59, 68, 0.12);
  box-shadow: 0 0 10px rgba(255, 59, 68, 0.5), inset 0 0 6px rgba(255, 59, 68, 0.3);
  text-decoration: none;
}

/* award callout inside a role card */
.award {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  background: rgba(255, 59, 68, 0.07);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  margin: 0 0 1rem;
}

.award-icon {
  flex-shrink: 0;
  color: var(--accent-text);
  display: inline-flex;
}
.award-icon svg { width: 20px; height: 20px; }

.award-title {
  margin: 0 0 0.2rem;
  color: var(--text);
  font-weight: 700;
  font-size: 0.95rem;
}

.award-desc {
  margin: 0;
  color: var(--text-dim);
  font-size: 0.92rem;
  line-height: 1.55;
}

/* recognition */
.quote-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
}

.quote-grid .quote-card { margin-top: 0; }

.quote-card figcaption { display: flex; align-items: center; gap: 0.75rem; }
.quote-card figcaption:has(+ blockquote) { margin-bottom: 0.9rem; }
.quote-card figcaption .quote-who { display: flex; flex-direction: column; gap: 0.1rem; }
.quote-card figcaption span { color: var(--text-dim); font-size: 0.88rem; }

.award-strip { margin-top: 1.5rem; }

.award-item {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  text-align: left;
}

.award-year {
  color: var(--accent-text);
  font-weight: 700;
  font-size: 0.9rem;
  padding-top: 0.15rem;
  white-space: nowrap;
}

.award-item h4 { margin: 0 0 0.25rem; font-size: 1.02rem; }
.award-item p { margin: 0; color: var(--text-dim); font-size: 0.9rem; line-height: 1.55; }

.project-org {
  margin: -0.25rem 0 0.75rem !important;
  color: var(--accent-text) !important;
  font-size: 0.85rem !important;
  font-weight: 600;
}

/* inline stat row on project cards */
.stat-inline {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 0 0 0.9rem;
  font-size: 0.88rem;
  color: var(--text-dim);
}
.stat-inline strong { color: var(--accent-text); }

/* repo cards are links now */
a.repo {
  display: block;
  text-decoration: none;
  transition: border-color 0.2s ease;
}
a.repo:hover { border-color: var(--accent); color: inherit; }

.repo-lang {
  margin-left: 0.5rem;
  font-size: 0.7rem;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.1rem 0.45rem;
}

/* talks with event photos */
.talk-with-photo {
  display: grid;
  grid-template-columns: 170px 1fr;
  gap: 1.35rem;
  align-items: start;
  text-align: left;
}

.talk-photo {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  overflow: hidden;
  background: #1c1c1c;
  border: 1px solid var(--border);
}

.talk-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* shown only when the <img> fails to load (onerror adds .no-photo) */
.photo-fallback {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  color: var(--text-dim);
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.talk-with-photo.no-photo img { display: none; }
.talk-with-photo.no-photo .photo-fallback { display: flex; }

.talk-body h4 { margin: 0 0 0.75rem; font-size: 1.1rem; }

@media (max-width: 620px) {
  .talk-with-photo { grid-template-columns: 1fr; }
  .talk-photo { max-width: 220px; }
}

/* flyer image on a session detail page -- capped so a square event poster
   doesn't dominate the fold, hidden entirely if the file is missing */
.session-flyer {
  margin: 2rem 0;
  text-align: center;
}

.session-flyer img {
  max-width: 100%;
  width: auto;
  max-height: 420px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

.cert { text-align: left; }

/* ============================ site footer ============================ */
.site-footer {
  margin-top: 2.5rem;
  padding: 2rem 1rem;
  text-align: center;
}

.footer-bottom {
  max-width: var(--max-width);
  margin: 0 auto;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.footer-bottom p {
  margin: 0;
  color: var(--text-dim);
  font-size: 0.82rem;
}

/* ============================================================
   Long-form case-study / article template.
   Sub-pages have no top nav bar -- .crumb provides the way back.
   ============================================================ */

.crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 1.75rem 0 0;
  font-size: 0.85rem;
  color: var(--text-dim);
}

.crumb a { color: var(--text-dim); text-decoration: none; }
.crumb a:hover { color: var(--accent-text); }
.crumb span[aria-hidden] { opacity: 0.4; }
.crumb-current { color: var(--text); }

.cs-header { padding: 2.5rem 0 0; }

.about-header-row {
  display: flex;
  align-items: flex-start;
  gap: 2rem;
  flex-wrap: wrap;
}

.about-header-row .hero-avatar-frame {
  width: 120px;
  height: 120px;
  margin-top: 0;
}

.cs-header h1 {
  font-size: 2.4rem;
  line-height: 1.2;
  margin: 0 0 0.4rem;
  max-width: 22ch;
}

.cs-role-line {
  font-size: 1.1rem;
  font-weight: 600;
  margin: 0 0 1rem;
}

.text-justify { text-align: justify; }

.cs-deck {
  color: var(--text-dim);
  font-size: 1.15rem;
  line-height: 1.7;
  max-width: 62ch;
  margin: 0 0 1.25rem;
}

.cs-byline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  color: var(--text-dim);
  font-size: 0.88rem;
}

.cs-byline .byline-item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.cs-byline .byline-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.cs-byline-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  /* source photo is a tall portrait with the face near the top -- default
     center-cover crops the head off at this size, same fix as .hero-avatar */
  object-position: center top;
  flex-shrink: 0;
}

.cs-actions { margin-top: 1.5rem; }

/* stat band */
.cs-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1rem;
  margin-top: 2.5rem;
}

.cs-stat {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
}

.cs-stat .num {
  display: block;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--accent-text);
  line-height: 1.2;
}

.cs-stat .label {
  display: block;
  margin-top: 0.3rem;
  color: var(--text-dim);
  font-size: 0.85rem;
  line-height: 1.4;
}

/* table of contents */
.cs-toc {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1rem;
  margin-top: 2.5rem;
  padding: 1rem 1.25rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.cs-toc-label {
  color: var(--text-dim);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-right: 0.25rem;
}

.cs-toc a {
  color: var(--text);
  font-size: 0.9rem;
  text-decoration: none;
}
.cs-toc a:hover { color: var(--accent-text); }

/* story.html's own sidebar TOC: a floating text list + active highlight,
   positioned like .section-rail (fixed, left edge, vertically centered) but
   showing full labels instead of an icon dock -- text needs real width, so
   this only floats on viewports wide enough to fit beside the 960px content
   column without overlapping it; narrower viewports fall back to the plain
   in-flow list. */
.section-nav {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin: 2.5rem 0;
}

.section-nav-link {
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius);
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.88rem;
  line-height: 1.35;
  transition: background 0.15s ease, color 0.15s ease;
}

.section-nav-link:hover { color: var(--text); }

.section-nav-link.is-active {
  background: rgba(255, 59, 68, 0.14);
  color: var(--accent-text);
  font-weight: 600;
}

@media (min-width: 1400px) {
  .section-nav {
    position: fixed;
    left: 1.25rem;
    top: 50%;
    transform: translateY(-50%);
    z-index: 40;
    width: 190px;
    margin: 0;
    padding: 0.85rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: rgba(22, 22, 22, 0.75);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
  }
}

/* body sections */
.cs-section {
  margin-top: 2rem;
  scroll-margin-top: 1.5rem;
}

.cs-section h2 {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 1.5rem;
  line-height: 1;
  margin: 0 0 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}

.cs-section h2 svg {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  color: var(--accent);
}

.cs-section p {
  color: var(--text-dim);
  line-height: 1.75;
  max-width: 68ch;
  margin: 0 0 1.1rem;
}

.cs-section p strong { color: var(--text); }
.cs-section p.text-justify { max-width: none; }

/* story.html reads as one long narrative, so its prose uses the full content
   column instead of the 68ch cap the other cs-section pages keep */
.story-main .cs-header h1 { max-width: none; }
.story-main .cs-section p { max-width: none; text-align: justify; }
.story-main .cs-deck { max-width: none; }
.projects-main .cs-deck { max-width: none; }
.sessions-main .cs-deck { max-width: none; }
.story-main .callout { max-width: none; }

.case-study-main .cs-header h1 { max-width: none; }
.case-study-main .cs-section p { max-width: none; text-align: justify; }
.case-study-main .cs-deck { max-width: none; }
.case-study-main .callout { max-width: none; }
.case-study-main .stack-grid { margin-bottom: 1.5rem; }
.case-study-main .cs-stats { margin-bottom: 1.5rem; }
.case-study-main .step-list li { text-align: center; }
.case-study-main .step-list p { text-align: justify; }
.case-study-main .lesson-list,
.case-study-main .cs-section .stack-grid {
  max-width: none;
}

.case-study-main .step-list {
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
}

.exp-timeline {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.exp-timeline-item {
  display: grid;
  grid-template-columns: minmax(4.5rem, auto) 1fr;
  align-items: start;
  gap: 1rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 1.1rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.exp-timeline-item:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.exp-timeline-date {
  color: var(--accent-text);
  font-weight: 700;
  font-size: 0.82rem;
  white-space: nowrap;
}

.exp-timeline-body strong {
  display: block;
  color: var(--text);
  font-size: 0.92rem;
  margin-bottom: 0.15rem;
}

.exp-timeline-body p {
  margin: 0;
  max-width: none;
  color: var(--text-dim);
  font-size: 0.82rem;
  line-height: 1.45;
}

@media (max-width: 560px) {
  .exp-timeline-item { grid-template-columns: 1fr; gap: 0.35rem; }
}

.cert-groups {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.cert-group {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 1.1rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.cert-group:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(255, 59, 68, 0.45), inset 0 0 8px rgba(255, 59, 68, 0.25);
}

.cert-group strong {
  display: block;
  color: var(--text);
  font-size: 0.92rem;
  margin-bottom: 0.55rem;
}

.cert-tags {
  display: flex;
  flex-wrap: wrap;
  column-gap: 1.5rem;
  row-gap: 0.4rem;
}

.cert-tags span {
  color: var(--text-dim);
  font-size: 0.82rem;
}

.cs-section .stack-grid { max-width: 68ch; }

.cs-figure {
  float: right;
  width: 240px;
  margin: 0.25rem 0 1.25rem 1.75rem;
}
.cs-figure-left {
  float: left;
  margin: 0.25rem 1.75rem 1.25rem 0;
}
.cs-figure-full {
  float: none;
  width: 100%;
  margin: 0.5rem 0 1.5rem;
}
.cs-figure-wide {
  width: 400px;
}
.cs-figure img {
  width: 100%;
  display: block;
  border-radius: var(--radius);
}
.cs-figure figcaption {
  font-size: 0.8rem;
  color: var(--text-dim);
  text-align: center;
  margin-top: 0.5rem;
}
@media (max-width: 620px) {
  .cs-figure {
    float: none;
    width: 55%;
    margin: 0 auto 1.5rem;
  }
}

/* pull-quote / callout */
.callout {
  border-left: 3px solid var(--accent);
  background: var(--bg-card);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 1.1rem 1.35rem;
  margin: 1.5rem 0;
  max-width: 68ch;
}

.callout p {
  margin: 0;
  color: var(--text);
  font-size: 1.05rem;
  font-style: italic;
  line-height: 1.65;
}

.callout-warn { border-left-color: var(--accent-text); }

/* numbered approach steps */
.step-list {
  list-style: none;
  counter-reset: step;
  margin: 1.5rem 0;
  padding: 0;
  display: grid;
  gap: 0.85rem;
  max-width: 68ch;
}

.step-list li {
  counter-increment: step;
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.25rem 1rem 3.25rem;
}

.step-list li::before {
  content: counter(step);
  position: absolute;
  left: 1rem;
  top: 1rem;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-gradient);
  color: #fff;
  font-size: 0.82rem;
  font-weight: 700;
}

.step-list h4 { margin: 0 0 0.3rem; font-size: 1rem; }
.step-list p { margin: 0; font-size: 0.92rem; line-height: 1.6; }

/* lessons */
.lesson-list {
  margin: 0;
  padding-left: 1.15rem;
  max-width: 68ch;
  color: var(--text-dim);
}

.lesson-list li { margin-bottom: 0.85rem; line-height: 1.7; }
.lesson-list strong { color: var(--text); }

/* next / related */
.cs-next {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
  margin-top: 3.5rem;
}

.cs-next-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  text-decoration: none;
  transition: border-color 0.2s ease;
}

.cs-next-card:hover { border-color: var(--accent); color: inherit; }

.cs-next-label {
  color: var(--accent-text);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.cs-next-card strong { color: var(--text); font-size: 1.02rem; }
.cs-next-card span:last-child { color: var(--text-dim); font-size: 0.88rem; line-height: 1.5; }

@media (max-width: 620px) {
  .cs-header h1 { font-size: 1.85rem; }
}

/* ============================================================
   Homepage section rail (fixed left nav) + footer CTA
   ============================================================ */

.section-rail {
  position: fixed;
  left: 0.85rem;
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.6rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.75);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.rail-link {
  position: relative;
  display: flex;
  align-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: var(--text-dim);
  text-decoration: none;
  transition: color 0.2s ease, background-color 0.2s ease;
}

.rail-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
}

.rail-icon svg { width: 17px; height: 17px; }

.rail-link:hover { color: var(--text); background: rgba(255, 255, 255, 0.06); }

.rail-link.is-active {
  color: var(--accent-text);
  background: rgba(255, 59, 68, 0.14);
}

/* label ribbon slides out of the rail on hover/focus */
.rail-label {
  position: absolute;
  left: calc(100% + 0.55rem);
  white-space: nowrap;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.32rem 0.7rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
  opacity: 0;
  transform: translateX(-6px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.rail-link:hover .rail-label,
.rail-link:focus-visible .rail-label {
  opacity: 1;
  transform: translateX(0);
}

.rail-link.is-active .rail-label { border-color: var(--accent); }

/* the rail would overlap content on narrow screens */
@media (max-width: 1180px) {
  .section-rail { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .rail-label { transition: none; }
}

/* ---------- footer CTA (replaces the sitemap footer on the homepage) ---- */
.site-cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-top: 1.5rem;
  padding: 5.5rem 1rem 2.5rem;
  text-align: center;
}

/* same twin bright spots as .hero::before, sitting under the snake canvas */
.site-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(ellipse 45% 85% at 0% 50%, rgba(172, 19, 28, 0.4), transparent 70%),
    radial-gradient(ellipse 45% 85% at 100% 50%, rgba(172, 19, 28, 0.4), transparent 70%);
  pointer-events: none;
}

.footer-canvas {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

.site-cta-inner {
  max-width: 46rem;
  margin: 0 auto;
}

.site-cta h2 {
  margin: 0 0 1.1rem;
  font-size: 3.4rem;
  font-weight: 800;
  color: #fff;
  letter-spacing: -0.02em;
}

.site-cta p {
  margin: 0 auto 2.25rem;
  max-width: 38rem;
  color: rgba(255, 255, 255, 0.82);
  font-size: 1.08rem;
  line-height: 1.7;
}

.site-cta-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-bottom: 3rem;
}

.site-cta-actions .btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-right: 0;
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
}

.site-cta-actions .btn svg { width: 17px; height: 17px; flex-shrink: 0; }

.site-cta-legal {
  margin: 0;
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.86rem;
}

.site-cta-legal a { color: rgba(255, 255, 255, 0.7); text-decoration: none; }
.site-cta-legal a:hover { color: #fff; }
.site-cta-legal span { margin: 0 0.4rem; opacity: 0.5; }

@media (max-width: 620px) {
  .site-cta { padding: 4.5rem 1rem 2.5rem; }
  .site-cta h2 { font-size: 2.2rem; }
  .site-cta p { font-size: 1rem; }
}

/* ---------- FAQ accordion (about.html) ---------- */
.faq-list {
  display: grid;
  gap: 0.6rem;
  margin-top: 1.25rem;
}

.faq {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0 1.15rem;
  transition: border-color 0.2s ease;
}

.faq[open] { border-color: var(--accent); }

.faq summary {
  cursor: pointer;
  padding: 0.95rem 0;
  font-weight: 600;
  font-size: 0.98rem;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* replace the default disclosure triangle with a chevron that rotates */
.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: "";
  width: 9px;
  height: 9px;
  flex-shrink: 0;
  border-right: 2px solid var(--accent-text);
  border-bottom: 2px solid var(--accent-text);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.2s ease;
}

.faq[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }

.faq summary:hover { color: var(--accent-text); }

.faq p {
  margin: 0;
  padding: 0 0 1.05rem;
  /* .cs-section p caps body copy at 68ch for readability; inside a FAQ card
     the card itself already sets the measure, so let the answer fill it */
  max-width: none;
  color: var(--text-dim);
  font-size: 0.93rem;
  line-height: 1.65;
  text-align: justify;
}
