/* Reset and Base Styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --primary-color: #6366f1;
    --primary-dark: #4f46e5;
    --primary-light: #818cf8;
    --secondary-color: #22d3ee;
    --accent-color: #a78bfa;
    --text-primary: #f1f5f9;
    --text-secondary: rgba(255, 255, 255, 0.65);
    /* Bumped 0.38 → 0.62 to clear WCAG AA 4.5:1 contrast on the #060d1a /
       #0f172a backgrounds. axe-core flagged the previous value at 3.52:1
       (footer copyright, small disclaimer text). 0.62 measures ~6.1:1 —
       comfortably above AA. */
    --text-light: rgba(255, 255, 255, 0.62);
    --background: #0f172a;
    --background-alt: #1e293b;
    --background-dark: #0f172a;
    --border-color: rgba(255, 255, 255, 0.1);
    --border-hover: rgba(255, 255, 255, 0.2);
    --card-bg: rgba(255, 255, 255, 0.05);
    --card-bg-hover: rgba(255, 255, 255, 0.08);
    --success-color: #34d399;
    --shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
    --shadow-sm: 0 4px 20px rgba(0, 0, 0, 0.3);
    --gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    --gradient-secondary: linear-gradient(135deg, #4f46e5 0%, #06b6d4 100%);
    --water-mid:       #0891b2;
    --water-surface:   #22d3ee;
    --water-highlight: #67e8f9;
    --gradient-water-text: linear-gradient(135deg, #818cf8 0%, #0891b2 30%, #22d3ee 55%, #67e8f9 75%, #818cf8 100%);
    --gradient-water-flow: linear-gradient(90deg, #4f46e5, #0891b2, #22d3ee, #67e8f9, #22d3ee, #0891b2, #4f46e5);
    --dot-pattern: url('data:image/svg+xml,<svg width="60" height="60" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="dots" width="60" height="60" patternUnits="userSpaceOnUse"><circle cx="30" cy="30" r="1.5" fill="rgba(255,255,255,0.04)"/></pattern></defs><rect width="60" height="60" fill="url(%23dots)"/></svg>');
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    line-height: 1.7;
    color: var(--text-primary);
    background-color: var(--background);
}

/* ─── Skip-to-content link (a11y) ──────────────────────────────
   Pattern: visually hidden until focused. Lives off-screen at top:-40px
   so it doesn't take layout space, but reveals as a high-contrast pill
   pinned to the top-left when a keyboard user tabs into the page.
   Required by WCAG 2.4.1 (Bypass Blocks) — gives keyboard users a way to
   skip the 7-link navbar and jump straight to <section id="home">. */
.skip-link {
    position: absolute;
    top: -48px;
    left: 12px;
    z-index: 10000; /* above navbar (z-index ~1000) and chatbot FAB */
    padding: 0.65rem 1rem;
    background: var(--secondary-color);
    color: #0f172a;
    font-weight: 600;
    text-decoration: none;
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
    /* Snap into view when focused — :focus-visible gates this so a mouse
       click on the link doesn't make it appear (only keyboard nav does). */
    transition: top 0.18s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
    top: 12px;
    outline: 2px solid #0f172a;
    outline-offset: 2px;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

/* ─── Logo Circuit Mark ────────────────────────────────────── */
.logo {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.logo-circuit {
    color: var(--secondary-color);
    flex-shrink: 0;
    opacity: 0.85;
}

.logo-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.55rem;
    border-radius: 50px;
    border: 1px solid rgba(34, 211, 238, 0.35);
    background: rgba(34, 211, 238, 0.07);
    color: var(--secondary-color);
    font-size: 0.85em;
    font-weight: 700;
    letter-spacing: 0.5px;
    margin-right: 0.35rem;
}

/* ─── Navigation ──────────────────────────────────────────── */
.navbar {
    position: fixed;
    top: 0;
    width: 100%;
    /* Default — semi-transparent at the very top of the page so the hero gradient
       peeks through. JS adds .scrolled once the user scrolls past 50px and we
       swap to fully opaque to prevent body text from being visible through the
       navbar during scroll (was a major mobile-readability issue). */
    background-color: rgba(15, 23, 42, 0.78);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-bottom: 1px solid transparent;
    z-index: 1000;
    transition: background-color 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.navbar.scrolled {
    background-color: rgba(15, 23, 42, 0.98);
    border-bottom-color: var(--border-color);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
}

/* Wordmark "Sam Bobo" — visible by default at tablet+ widths, hidden on phones
   so the navbar collapses to circuit icon + SB chip + Resume + hamburger. The
   SB chip alone is enough branding on a phone. white-space: nowrap prevents
   "Sam Bobo" from breaking into two lines when the navbar gets crowded with
   nav links at narrow desktop widths (~1100–1280px). */
.logo-wordmark {
    margin-left: 0.35rem;
    white-space: nowrap;
}

/* Drawer-only Resume entry. Hidden by default (desktop) — the dedicated
   .resume-btn pill on the right side of the navbar is the desktop affordance.
   This <li> is only revealed inside the @media (max-width: 900px) block where
   .resume-btn is correspondingly hidden, keeping a single Resume action at
   any viewport. */
.nav-resume-item {
    display: none;
}

.navbar .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    max-width: none;
    padding: 0.75rem 2.5rem;
    /* Keeps the navbar at a predictable height. Both the JS scroll-class trigger
       and the mobile drawer's `top` calc rely on this being stable. */
    min-height: 64px;
}

.logo {
    font-size: 1.5rem;
    font-weight: 700;
    background: var(--gradient-water-text);
    background-size: 200% 200%;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.nav-menu {
    display: flex;
    list-style: none;
    gap: 2.5rem;
    /* line-height set on the <ul> so the <li> children inherit it. The
       previous fix put line-height on .nav-link (the <a> inside the <li>),
       but because the <a> is `display: inline`, the LINE-BOX height for
       wrapped lines is determined by the LARGEST line-height in the line —
       which was the <li>'s inherited body line-height of 1.7 (27.2px), not
       the <a>'s 1.25 (15.6px). That's the gap that was visibly persisting
       even after the previous edit. Setting it on the <ul> makes the entire
       inheritance chain (ul → li → a) use the same tight 1.25 value, so the
       line-boxes themselves shrink and wrapped labels visually collapse. */
    line-height: 1.25;
}

.nav-link {
    text-decoration: none;
    color: var(--text-secondary);
    font-weight: 500;
    font-size: 0.78rem;
    /* line-height tightened from the inherited body 1.7 to 1.25.
       Applies in both modes:
         - Desktop (>900px): inline nav with 7 items + Resume pill. At
           viewport widths roughly 900–1180 px the navbar is too narrow for
           every label to stay single-line, so multi-word labels like
           "AI PM Approach" / "Core Competencies" / "Writing, Speaking & Press"
           wrap. Without this, wrapped lines have ~22px of leading between
           them, making the navbar visually balloon to ~115 px tall.
         - Drawer (≤900px): same value as the @media override later in this
           file — kept here so the drawer rule becomes redundant but harmless. */
    line-height: 1.25;
    transition: color 0.3s ease;
    position: relative;
}

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

.nav-link.active {
    color: var(--primary-light);
}

.nav-link::after {
    content: '';
    position: absolute;
    bottom: -5px;
    left: 0;
    width: 0;
    height: 2px;
    background: var(--gradient-secondary);
    transition: width 0.3s ease;
}

.nav-link:hover::after,
.nav-link.active::after {
    width: 100%;
}

.resume-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.9rem;
    border-radius: 50px;
    border: 1px solid rgba(34, 211, 238, 0.4);
    background: rgba(34, 211, 238, 0.07);
    color: var(--secondary-color);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.3px;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
    flex-shrink: 0;
}

.resume-btn:hover {
    background: rgba(34, 211, 238, 0.15);
    border-color: rgba(34, 211, 238, 0.7);
    color: white;
}

/* Hamburger is now a real <button> (was a <div>). Tap target is 44x44 to satisfy
   WCAG 2.5.5 AAA — visual icon stays small inside the larger hit area via padding.
   Visible only on phones; the .scrolled-active style flips the bars to an X. */
.hamburger {
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.15s ease;
}
.hamburger:hover { background: rgba(255, 255, 255, 0.06); }
.hamburger:focus-visible {
    outline: 2px solid var(--secondary-color);
    outline-offset: 2px;
}

.hamburger span {
    display: block;
    width: 22px;
    height: 2.5px;
    background-color: var(--text-primary);
    margin: 3px 0;
    transition: transform 0.25s ease, opacity 0.2s ease;
    border-radius: 2px;
}

/* X transform when the menu is open — top bar rotates down, middle bar fades,
   bottom bar rotates up, forming a clean X. */
.hamburger.active span:nth-child(1) { transform: translateY(8.5px) rotate(45deg); }
.hamburger.active span:nth-child(2) { opacity: 0; }
.hamburger.active span:nth-child(3) { transform: translateY(-8.5px) rotate(-45deg); }

/* ─── Hero Section ─────────────────────────────────────────── */
.hero {
    min-height: 100vh;
    display: flex;
    align-items: center;
    background: var(--gradient-primary);
    position: relative;
    overflow: hidden;
    padding-top: 80px;
}

.hero::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: url('data:image/svg+xml,<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse"><path d="M 100 0 L 0 0 0 100" fill="none" stroke="rgba(255,255,255,0.05)" stroke-width="1"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
    opacity: 0.3;
}

.hero-content {
    color: white;
    position: relative;
    z-index: 1;
    width: 100%;
    display: flex;
    align-items: center;
    gap: 4rem;
    animation: fadeInUp 1s ease;
}

.hero-text {
    flex: 1;
    min-width: 0;
    text-align: left;
}

/* ─── Hero Photo ───────────────────────────────────────────── */
.hero-photo-wrap {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.hero-photo-frame {
    position: relative;
    width: 300px;
    height: 300px;
}

.hero-photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    border-radius: 50%;
    border: 2px solid rgba(34, 211, 238, 0.3);
    box-shadow: 0 0 0 6px rgba(34, 211, 238, 0.06), 0 0 60px rgba(34, 211, 238, 0.15), 0 20px 50px rgba(0, 0, 0, 0.5);
    display: block;
}

.hero-photo-circuit {
    position: absolute;
    inset: -10px;
    pointer-events: none;
    animation: rotateSlow 30s linear infinite;
}

@keyframes rotateSlow {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* ─── Hero Role Badge ──────────────────────────────────────── */
.hero-role-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-bottom: 1.25rem;
    padding: 0.45rem 0.9rem;
    background: rgba(34, 211, 238, 0.08);
    border: 1px solid rgba(34, 211, 238, 0.25);
    border-radius: 50px;
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.75);
    font-weight: 500;
    letter-spacing: 0.2px;
}

.hero-role-badge strong {
    color: var(--secondary-color);
    font-weight: 700;
}

.hero-role-badge svg {
    color: var(--secondary-color);
    opacity: 0.8;
    flex-shrink: 0;
}

.role-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #34d399;
    box-shadow: 0 0 6px rgba(52, 211, 153, 0.7);
    flex-shrink: 0;
    animation: dotPulse 2.5s ease-in-out infinite;
}

@keyframes dotPulse {
    0%, 100% { box-shadow: 0 0 4px rgba(52, 211, 153, 0.6); }
    50%       { box-shadow: 0 0 10px rgba(52, 211, 153, 0.9); }
}

.role-currently {
    font-weight: 700;
    font-size: 0.7rem;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: #34d399;
}

.role-sep {
    color: var(--secondary-color);
    opacity: 0.4;
    font-weight: 700;
    font-size: 0.7rem;
}

.role-at {
    opacity: 0.5;
    font-size: 0.75rem;
}

/* ─── Hero chatbot nudge ───────────────────────────────────── */
.hero-chatbot-nudge {
    margin-top: 1.5rem !important;
    font-size: 0.8rem !important;
    opacity: 0.5;
    letter-spacing: 0.3px;
    cursor: default;
    margin-bottom: 0 !important;
}

.nudge-arrow {
    display: inline-block;
    animation: bounceY 2s ease-in-out infinite;
}

@keyframes bounceY {
    0%, 100% { transform: translateY(0); }
    50%       { transform: translateY(4px); }
}

.hero-label {
    display: inline-block;
    padding: 0.5rem 1.25rem;
    background-color: rgba(255, 255, 255, 0.2);
    border-radius: 50px;
    font-size: 0.875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 1.5rem;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.hero-title {
    font-size: 3.75rem;
    font-weight: 800;
    line-height: 1.2;
    margin-bottom: 1.5rem;
    background: var(--gradient-water-flow);
    background-size: 300% 300%;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    -webkit-text-stroke: 0.5px rgba(103, 232, 249, 0.15);
    animation: waterDrift 14s ease infinite;
    transition: filter 0.4s ease;
}

.hero-title:hover {
    filter: url(#water-distort);
}

.highlight {
    background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    -webkit-text-stroke: 0;
}

.hero-description {
    font-size: 1.25rem;
    line-height: 1.8;
    margin-bottom: 2.5rem;
    opacity: 0.9;
    max-width: 600px;
}

.hero-buttons {
    display: flex;
    gap: 1rem;
    justify-content: flex-start;
    flex-wrap: wrap;
}

/* ─── Buttons ──────────────────────────────────────────────── */
.btn {
    padding: 1rem 2.25rem;
    border-radius: 8px;
    text-decoration: none;
    font-weight: 600;
    transition: all 0.3s ease;
    display: inline-block;
    font-size: 1rem;
}

.btn-primary {
    background-color: white;
    color: var(--primary-dark);
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 30px rgba(255, 255, 255, 0.15), 0 0 20px rgba(99, 102, 241, 0.3);
}

.btn-secondary {
    background-color: transparent;
    color: white;
    border: 2px solid rgba(255, 255, 255, 0.5);
}

.btn-secondary:hover {
    background-color: rgba(255, 255, 255, 0.1);
    border-color: white;
}

/* Tertiary "Chat with My AI" hero CTA. Visually distinct from the two existing
   buttons via a cyan/indigo gradient (matches the chatbot brand) plus an inline
   SVG icon. <button> not <a>, so we re-add the missing browser defaults: cursor,
   font inheritance, and tap-target sizing. The icon flex-aligns with the label.
*/
.btn-chat {
    /* Cyan→indigo gradient pulled from --gradient-secondary so the button reads
       as part of the chatbot system at a glance. */
    background: var(--gradient-secondary);
    color: white;
    /* Transparent 2px border matches .btn-secondary's border thickness so
       all three hero buttons share the same total height when stacked
       vertically on phones (the existing 480px media query forces width:100%
       which makes any height drift visible). */
    border: 2px solid transparent;
    cursor: pointer;
    font-family: inherit;
    /* Flex layout so the SVG icon and label center-align with a small gap.
       inline-flex so the button still flows inline with sibling .btn elements;
       justify-content: center keeps the icon+label centered when the button
       expands to full width on mobile. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    box-shadow: 0 4px 18px rgba(34, 211, 238, 0.25);
}
.btn-chat:hover {
    transform: translateY(-2px);
    /* Stronger glow on hover — same trick the other .btn variants use. */
    box-shadow: 0 10px 30px rgba(34, 211, 238, 0.35), 0 0 20px rgba(99, 102, 241, 0.3);
}
.btn-chat:focus-visible {
    outline: 2px solid var(--secondary-color);
    outline-offset: 3px;
}
.btn-chat svg {
    /* Subtle pulse animation on the icon — draws the eye without being noisy.
       Skipped for users who request reduced motion (covered in script.js
       guardrail block — animations honor prefers-reduced-motion). */
    flex-shrink: 0;
}

/* ─── Authority / Metrics Strip ───────────────────────────── */
.authority-strip {
    background: rgba(15, 23, 42, 0.95);
    border-top: 1px solid rgba(34, 211, 238, 0.15);
    border-bottom: 1px solid rgba(34, 211, 238, 0.15);
    padding: 0.875rem 0;
    overflow: hidden;
    position: relative;
    z-index: 1;
}

.authority-strip-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.authority-chip {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.75);
    letter-spacing: 0.3px;
    white-space: nowrap;
    padding: 0.35rem 0.85rem;
    border-radius: 50px;
    border: 1px solid rgba(34, 211, 238, 0.25);
    background: rgba(34, 211, 238, 0.05);
    transition: border-color 0.2s ease, background 0.2s ease;
}

.authority-chip:hover {
    border-color: rgba(34, 211, 238, 0.45);
    background: rgba(34, 211, 238, 0.1);
}

.authority-icon {
    color: var(--secondary-color);
    opacity: 0.75;
    flex-shrink: 0;
}

@media (max-width: 768px) {
    .authority-strip-inner {
        gap: 0.5rem;
    }
    .authority-chip {
        font-size: 0.7rem;
        padding: 0.3rem 0.7rem;
    }
}

/* ─── Shared Section Styles ────────────────────────────────── */
section {
    padding: 6rem 0;
    position: relative;
    overflow: hidden;
}

/* Subtle dot pattern overlay on all non-hero sections */
.philosophy::before,
.expertise::before,
.products::before,
.media::before,
.contact::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--dot-pattern);
    pointer-events: none;
    z-index: 0;
}

.philosophy .container,
.expertise .container,
.products .container,
.media .container,
.contact .container {
    position: relative;
    z-index: 1;
}

.section-title {
    font-size: 2.75rem;
    font-weight: 800;
    text-align: center;
    margin-bottom: 1rem;
    background: var(--gradient-water-text);
    background-size: 250% 250%;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    letter-spacing: 0.02em;
}

.section-subtitle {
    text-align: center;
    font-size: 1.125rem;
    color: var(--text-secondary);
    margin-bottom: 3rem;
    max-width: 700px;
    margin-left: auto;
    margin-right: auto;
}

/* ─── Philosophy Section ───────────────────────────────────── */
.philosophy {
    background-color: var(--background-alt);
}

.philosophy-intro {
    max-width: 800px;
    margin: 0 auto 4rem;
    text-align: center;
}

.philosophy-intro .lead {
    font-size: 1.35rem;
    line-height: 1.8;
    color: var(--text-secondary);
    font-weight: 400;
}

/* ─── Philosophy Carousel ──────────────────────────────────── */
.philosophy-carousel {
    margin-top: 3rem;
}

.carousel-track-outer {
    overflow: hidden;
    border-radius: 16px;
}

.carousel-track {
    display: flex;
    transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}

.philosophy-card {
    min-width: 100%;
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 16px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 300px;
    box-sizing: border-box;
}

.card-main {
    padding: 2.5rem;
    border-right: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    flex-direction: column;
}

.card-why {
    padding: 2.5rem;
    background: rgba(99, 102, 241, 0.04);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.why-label {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--secondary-color);
    opacity: 0.8;
    margin: 0 0 0.25rem;
}

.card-why p:not(.why-label) {
    font-size: 0.88rem;
    line-height: 1.78;
    color: rgba(255, 255, 255, 0.65);
    margin: 0;
}

.carousel-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 1.5rem;
}

.carousel-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid rgba(34, 211, 238, 0.3);
    background: rgba(34, 211, 238, 0.06);
    color: var(--secondary-color);
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.carousel-btn:hover {
    background: rgba(34, 211, 238, 0.14);
    border-color: rgba(34, 211, 238, 0.6);
}

.carousel-dots {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.carousel-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.2);
    cursor: pointer;
    transition: background 0.2s ease, transform 0.2s ease;
    padding: 0;
}

.carousel-dot.active {
    background: var(--secondary-color);
    transform: scale(1.3);
}

.card-expand-inner {
    margin-top: 1.5rem;
    padding: 1.5rem 2.5rem 2rem;
    background: linear-gradient(145deg, rgba(79, 70, 229, 0.18) 0%, rgba(15, 23, 42, 0.6) 100%);
    border-top: 1px solid rgba(99, 102, 241, 0.25);
    border-radius: 0 0 12px 12px;
    position: relative;
}

.card-expand-inner::before {
    content: '';
    position: absolute;
    top: -6px;
    left: 2.5rem;
    width: 10px;
    height: 10px;
    background: rgba(79, 70, 229, 0.35);
    border-left: 1px solid rgba(99, 102, 241, 0.3);
    border-top: 1px solid rgba(99, 102, 241, 0.3);
    transform: rotate(45deg);
}

.card-expand-inner p:not(.back-eyebrow) {
    font-size: 0.88rem;
    line-height: 1.78;
    color: rgba(255, 255, 255, 0.7);
}

.card-inline-link {
    color: var(--secondary-color);
    text-decoration: underline;
    text-decoration-color: rgba(34, 211, 238, 0.35);
    text-underline-offset: 3px;
    transition: text-decoration-color 0.2s ease, color 0.2s ease;
}

.card-inline-link:hover {
    color: white;
    text-decoration-color: rgba(34, 211, 238, 0.8);
}

/* Shared between expand panel and expertise card-back */
.back-eyebrow {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--primary-light);
    opacity: 0.65;
    margin-bottom: 0.75rem;
}

/* Flip system — used only by expertise cards */
.card-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform 0.65s cubic-bezier(0.4, 0, 0.2, 1);
}

.card-front,
.card-back {
    position: absolute;
    inset: 0;
    padding: 2.5rem;
    border-radius: 12px;
    border: 1px solid var(--border-color);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.card-front {
    background: var(--card-bg);
}

.card-back {
    background: linear-gradient(145deg, rgba(79, 70, 229, 0.2) 0%, rgba(15, 23, 42, 0.96) 100%);
    border-color: rgba(99, 102, 241, 0.3);
    transform: rotateY(180deg);
}

.card-back p:not(.back-eyebrow) {
    font-size: 0.88rem;
    line-height: 1.78;
    color: rgba(255, 255, 255, 0.72);
}

.flip-hint {
    display: block;
    margin-top: auto;
    padding-top: 1rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    color: var(--primary-light);
    opacity: 0.45;
    transition: opacity 0.3s ease;
    user-select: none;
}

.philosophy-number {
    display: inline-block;
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--primary-light);
    background-color: rgba(99, 102, 241, 0.2);
    padding: 0.5rem 1rem;
    border-radius: 50px;
    margin-bottom: 1.5rem;
    border: 1px solid rgba(99, 102, 241, 0.3);
}

.philosophy-card h3 {
    font-size: 1.5rem;
    margin-bottom: 1rem;
    color: var(--water-highlight);
    font-weight: 700;
    position: relative;
    overflow: hidden;
}

.philosophy-card p {
    color: var(--text-secondary);
    line-height: 1.8;
}

/* ─── AI Journey Timeline Section ─────────────────────────── */
.journey {
    background-color: var(--background-dark);
    position: relative;
    height: 100vh;
    min-height: 680px;
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.journey .container {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding-top: 5.5rem;
    padding-bottom: 1.25rem;
}

.journey .section-title  { margin-bottom: 0.4rem; flex-shrink: 0; }
.journey .section-subtitle {
    margin-bottom: 1.25rem;
    flex-shrink: 0;
}

.journey .section-title {
    color: white;
}

.journey .section-subtitle {
    color: rgba(255, 255, 255, 0.55);
    margin-bottom: 4rem;
}

.journey::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--dot-pattern);
    pointer-events: none;
}

/* Timeline wrapper */
.timeline {
    position: relative;
    max-width: 1000px;
    margin: 0 auto;
}

.timeline::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 2px;
    transform: translateX(-50%);
    background: linear-gradient(
        to bottom,
        rgba(100, 116, 139, 0.4) 0%,
        rgba(6, 182, 212, 0.6) 35%,
        rgba(6, 182, 212, 0.6) 65%,
        rgba(79, 70, 229, 0.8) 100%
    );
}

/* Era blocks */
.timeline-era {
    padding: 3rem 0;
    position: relative;
}

/* Era header */
.era-header {
    text-align: center;
    margin-bottom: 3rem;
    position: relative;
    z-index: 1;
}

.era-badge {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    padding: 0.4rem 1rem;
    border-radius: 50px;
    margin-bottom: 0.75rem;
}

.era-rules .era-badge {
    background: rgba(100, 116, 139, 0.2);
    color: #94a3b8;
    border: 1px solid rgba(100, 116, 139, 0.3);
}

.era-conversational .era-badge {
    background: rgba(6, 182, 212, 0.15);
    color: #22d3ee;
    border: 1px solid rgba(6, 182, 212, 0.3);
}

.era-generative .era-badge {
    background: rgba(99, 102, 241, 0.2);
    color: #a5b4fc;
    border: 1px solid rgba(99, 102, 241, 0.4);
}

.era-title {
    font-size: 2rem;
    font-weight: 800;
    color: white;
    margin-bottom: 0.4rem;
}

.era-years {
    font-size: 0.9rem;
    font-weight: 600;
    margin-bottom: 1rem;
}

.era-rules .era-years { color: #94a3b8; }
.era-conversational .era-years { color: #22d3ee; }
.era-generative .era-years { color: #a5b4fc; }

.era-description {
    max-width: 600px;
    margin: 0 auto;
    font-size: 1rem;
    line-height: 1.8;
    color: rgba(255, 255, 255, 0.55);
    font-style: italic;
}

/* Timeline items */
.timeline-items {
    position: relative;
}

.timeline-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 2.5rem;
    position: relative;
}

.timeline-item.item-left {
    flex-direction: row;
    padding-right: calc(50% + 2.5rem);
}

.timeline-item.item-right {
    flex-direction: row-reverse;
    padding-left: calc(50% + 2.5rem);
}

/* Connector dot on the spine */
.timeline-connector {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
    top: 1.25rem;
}

.timeline-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 3px solid var(--background-dark);
    flex-shrink: 0;
    transition: transform 0.3s ease;
}

.era-rules .timeline-dot { background: #64748b; box-shadow: 0 0 0 3px rgba(100,116,139,0.3); }
.era-conversational .timeline-dot { background: #06b6d4; box-shadow: 0 0 0 3px rgba(6,182,212,0.3); }
.era-generative .timeline-dot { background: #6366f1; box-shadow: 0 0 0 3px rgba(99,102,241,0.3); }

.timeline-dot.dot-current {
    width: 18px;
    height: 18px;
    background: #6366f1;
    box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.4), 0 0 20px rgba(99, 102, 241, 0.6);
    animation: pulseGlow 2s ease-in-out infinite;
}

@keyframes pulseGlow {
    0%, 100% { box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.4), 0 0 20px rgba(99, 102, 241, 0.4); }
    50% { box-shadow: 0 0 0 6px rgba(99, 102, 241, 0.2), 0 0 30px rgba(99, 102, 241, 0.7); }
}

/* Timeline card */
.timeline-card {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    padding: 1.5rem;
    width: 100%;
    transition: all 0.3s ease;
    position: relative;
}

.timeline-card:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.2);
    transform: translateY(-3px);
}

.era-rules .timeline-card:hover { border-color: rgba(100, 116, 139, 0.5); }
.era-conversational .timeline-card:hover { border-color: rgba(6, 182, 212, 0.5); }
.era-generative .timeline-card:hover { border-color: rgba(99, 102, 241, 0.5); }

.timeline-card.card-current {
    background: rgba(99, 102, 241, 0.1);
    border-color: rgba(99, 102, 241, 0.35);
}

/* Industry milestone cards */
.timeline-card.card-industry {
    border: 1px dashed rgba(251, 191, 36, 0.38);
    background: rgba(251, 191, 36, 0.03);
}

.timeline-card.card-industry:hover {
    border-color: rgba(251, 191, 36, 0.62) !important;
    background: rgba(251, 191, 36, 0.06) !important;
    box-shadow: 0 8px 30px rgba(251, 191, 36, 0.08);
}

.industry-badge {
    display: inline-block;
    font-size: 0.63rem;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(251, 191, 36, 0.7);
    background: rgba(251, 191, 36, 0.1);
    border: 1px solid rgba(251, 191, 36, 0.22);
    padding: 0.2rem 0.65rem;
    border-radius: 50px;
    margin-bottom: 0.5rem;
}

/* Arrow connector from card to spine */
.item-left .timeline-card::after {
    content: '';
    position: absolute;
    right: -8px;
    top: 1.5rem;
    width: 0;
    height: 0;
    border-top: 8px solid transparent;
    border-bottom: 8px solid transparent;
    border-left: 8px solid rgba(255, 255, 255, 0.1);
}

.item-right .timeline-card::after {
    content: '';
    position: absolute;
    left: -8px;
    top: 1.5rem;
    width: 0;
    height: 0;
    border-top: 8px solid transparent;
    border-bottom: 8px solid transparent;
    border-right: 8px solid rgba(255, 255, 255, 0.1);
}

.timeline-year {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    margin-bottom: 0.5rem;
}

.era-rules .timeline-year { color: #94a3b8; }
.era-conversational .timeline-year { color: #22d3ee; }
.era-generative .timeline-year { color: #a5b4fc; }

.timeline-card h4 {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--water-highlight);
    margin-bottom: 0.6rem;
    line-height: 1.4;
}

.timeline-card p {
    font-size: 0.9rem;
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.65);
    margin-bottom: 1rem;
}

.timeline-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.timeline-tags span {
    font-size: 0.75rem;
    font-weight: 600;
    padding: 0.3rem 0.75rem;
    border-radius: 50px;
}

.era-rules .timeline-tags span {
    background: rgba(100, 116, 139, 0.2);
    color: #94a3b8;
}

.era-conversational .timeline-tags span {
    background: rgba(6, 182, 212, 0.15);
    color: #22d3ee;
}

.era-generative .timeline-tags span {
    background: rgba(99, 102, 241, 0.2);
    color: #a5b4fc;
}

/* Era dividers */
.era-divider {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    padding: 1rem 0;
    position: relative;
    z-index: 1;
}

.era-divider-line {
    flex: 1;
    height: 1px;
    background: rgba(255, 255, 255, 0.1);
}

.era-divider-label {
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.3);
    white-space: nowrap;
}

/* ─── Timeline Tab Panels ─────────────────────────────────── */
.tab-panel {
    display: none;
}

.tab-panel.active {
    display: block;
    animation: tabFadeIn 0.35s ease;
}

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

/* ─── Journey Two-Column Layout ───────────────────────────── */
.journey-layout {
    display: flex;
    flex: 1;
    min-height: 0;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 16px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.02);
}

/* Left nav column */
.journey-nav {
    width: 240px;
    flex-shrink: 0;
    background: rgba(255, 255, 255, 0.025);
    border-right: 1px solid rgba(255, 255, 255, 0.07);
    padding: 1.75rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.journey-nav-header {
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 2.5px;
    text-transform: uppercase;
    /* Bumped 0.22 → 0.62 — small uppercase labels need ≥4.5:1 (not "large text"
       since they're 0.62rem/9.9px, well under the 18.66px AA-large threshold). */
    color: rgba(255, 255, 255, 0.62);
    padding-left: 0.25rem;
}

.journey-chapters {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.journey-chapter {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.875rem 1rem;
    border-radius: 10px;
    border: 1px solid transparent;
    background: transparent;
    cursor: pointer;
    text-align: left;
    width: 100%;
    transition: background 0.2s ease, border-color 0.2s ease;
    color: inherit;
}

.journey-chapter:hover {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.09);
}

.journey-chapter.active {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.13);
}

.chapter-num {
    font-size: 1.4rem;
    font-weight: 800;
    line-height: 1;
    flex-shrink: 0;
    color: rgba(255, 255, 255, 0.18);
    transition: color 0.2s ease;
    font-variant-numeric: tabular-nums;
}

.chapter-conversational.active .chapter-num { color: #22d3ee; }
.chapter-rules.active       .chapter-num { color: #94a3b8; }
.chapter-generative.active  .chapter-num { color: #a5b4fc; }

.chapter-conversational:hover:not(.active) .chapter-num { color: rgba(34,  211, 238, 0.45); }
.chapter-rules:hover:not(.active)          .chapter-num { color: rgba(148, 163, 184, 0.45); }
.chapter-generative:hover:not(.active)     .chapter-num { color: rgba(165, 180, 252, 0.45); }

.chapter-meta {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    flex: 1;
}

.chapter-name {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chapter-years {
    font-size: 0.7rem;
    color: var(--text-light);
}

.chapter-arrow {
    font-size: 0.85rem;
    color: var(--text-light);
    opacity: 0;
    transition: opacity 0.2s ease, transform 0.2s ease;
    flex-shrink: 0;
}

.journey-chapter.active   .chapter-arrow { opacity: 1; }
.journey-chapter:hover    .chapter-arrow { opacity: 0.6; }

/* Field evolution indicator at bottom of nav */
.journey-evolution {
    margin-top: auto;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.journey-evolution-label {
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.2);
    margin-bottom: 0.75rem;
}

.journey-evolution-track {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.evo-pill {
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.2rem 0.6rem;
    border-radius: 50px;
    display: inline-block;
    width: fit-content;
}

.evo-pill.step-rules         { background: rgba(100,116,139,0.18); color: #94a3b8; }
.evo-pill.step-conversational{ background: rgba(6,182,212,0.12);   color: #22d3ee; }
.evo-pill.step-generative    { background: rgba(99,102,241,0.18);  color: #a5b4fc; }

.evo-connector {
    color: rgba(255, 255, 255, 0.15);
    font-size: 0.65rem;
    padding-left: 0.5rem;
    line-height: 1;
}

/* Right scrollable content */
.journey-content {
    flex: 1;
    min-width: 0;
    overflow-y: auto;
    padding: 1.5rem 2rem 2rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.12) transparent;
}

.journey-content::-webkit-scrollbar       { width: 5px; }
.journey-content::-webkit-scrollbar-track { background: transparent; }
.journey-content::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.12); border-radius: 3px; }
.journey-content::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.22); }

/* Continuous scroll: all panels always visible inside the pane */
.journey-content .tab-panel,
.journey-content .tab-panel.active {
    display: block;
    animation: none;
}

/* ─── Journey compact text (right-column only) ────────────── */
.journey-content .timeline-era      { padding: 0.75rem 0 1rem; }
.journey-content .era-header        { margin-bottom: 1.25rem; padding-top: 0.5rem; }
.journey-content .era-badge         { font-size: 0.62rem; padding: 0.25rem 0.7rem; margin-bottom: 0.5rem; }
.journey-content .era-title         { font-size: 1.25rem; margin-bottom: 0.25rem; }
.journey-content .era-years         { font-size: 0.8rem; margin-bottom: 0.6rem; }
.journey-content .era-description   { font-size: 0.82rem; line-height: 1.65; }
.journey-content .timeline-item     { margin-bottom: 1.25rem; }
.journey-content .timeline-card     { padding: 0.9rem 1.1rem; }
.journey-content .timeline-card h4  { font-size: 0.88rem; margin-bottom: 0.35rem; line-height: 1.35; }
.journey-content .timeline-card p   { font-size: 0.78rem; line-height: 1.6; margin-bottom: 0.6rem; }
.journey-content .timeline-year     { font-size: 0.68rem; margin-bottom: 0.3rem; }
.journey-content .industry-badge    { font-size: 0.58rem; padding: 0.15rem 0.5rem; margin-bottom: 0.3rem; }
.journey-content .timeline-tags     { gap: 0.35rem; }
.journey-content .timeline-tags span{ font-size: 0.62rem; padding: 0.2rem 0.55rem; }

/* Era divider between continuous sections */
.journey-content .timeline-era + .timeline-era {
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    margin-top: 0.5rem;
    padding-top: 1.25rem;
}

/* ─── Journey Responsive ───────────────────────────────────── */
@media (max-width: 768px) {
    .journey {
        height: 100svh; /* use small viewport height on mobile to avoid address bar issues */
        min-height: 600px;
    }

    .journey .container {
        padding-top: 4.5rem;
        padding-bottom: 0.75rem;
    }

    .journey-layout {
        flex-direction: column;
    }

    .journey-nav {
        width: 100%;
        flex-shrink: 0;
        border-right: none;
        border-bottom: 1px solid rgba(255, 255, 255, 0.07);
        padding: 0.875rem 1rem;
        gap: 0.5rem;
    }

    .journey-chapters {
        flex-direction: row;
        gap: 0.5rem;
        overflow-x: auto;
        padding-bottom: 0.25rem;
        scrollbar-width: none;
    }

    .journey-chapters::-webkit-scrollbar { display: none; }

    .journey-chapter {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
        padding: 0.6rem 0.75rem;
        min-width: 110px;
        flex-shrink: 0;
    }

    .chapter-num  { font-size: 1.1rem; }
    .chapter-name { font-size: 0.78rem; }
    .chapter-years{ font-size: 0.65rem; }
    .chapter-arrow { display: none; }
    .journey-evolution { display: none; }

    .journey-content {
        flex: 1;
        min-height: 0;
        padding: 0.875rem 0.875rem 1rem;
    }
}

/* ─── Field Evolution Bar ──────────────────────────────────── */
.field-evolution {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    padding: 1.25rem 2rem;
    margin-bottom: 1.5rem;
    text-align: center;
    position: relative;
    z-index: 100;
    max-width: 1000px;
    margin-left: auto;
    margin-right: auto;
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);
}

.field-evolution-label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    /* Bumped 0.22 → 0.62 (WCAG AA 4.5:1) — see field-evolution-label rationale. */
    color: rgba(255, 255, 255, 0.62);
    margin-bottom: 0.875rem;
}

.field-evolution-track {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.875rem;
    flex-wrap: wrap;
}

.field-evolution-step {
    font-size: 0.78rem;
    font-weight: 600;
    padding: 0.35rem 0.875rem;
    border-radius: 50px;
    letter-spacing: 0.3px;
    opacity: 0.45;
    cursor: pointer;
    transition: opacity 0.4s ease, background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
    user-select: none;
}

.field-evolution-step:hover {
    opacity: 0.75;
}

.field-evolution-step.active {
    opacity: 1;
}

.step-rules {
    background: rgba(100, 116, 139, 0.15);
    color: #94a3b8;
    border: 1px solid rgba(100, 116, 139, 0.25);
}

.step-rules.active {
    background: rgba(100, 116, 139, 0.28);
    border-color: rgba(100, 116, 139, 0.6);
    box-shadow: 0 0 14px rgba(100, 116, 139, 0.22);
}

.step-conversational {
    background: rgba(6, 182, 212, 0.1);
    color: #22d3ee;
    border: 1px solid rgba(6, 182, 212, 0.25);
}

.step-conversational.active {
    background: rgba(6, 182, 212, 0.18);
    border-color: rgba(6, 182, 212, 0.6);
    box-shadow: 0 0 14px rgba(6, 182, 212, 0.22);
}

.step-generative {
    background: rgba(99, 102, 241, 0.15);
    color: #a5b4fc;
    border: 1px solid rgba(99, 102, 241, 0.3);
}

.step-generative.active {
    background: rgba(99, 102, 241, 0.28);
    border-color: rgba(99, 102, 241, 0.6);
    box-shadow: 0 0 14px rgba(99, 102, 241, 0.22);
}

/* ── Agentic AI era (Chapter 04) ──────────────────────────────
   Lavender/violet accent (#a78bfa / #c4b5fd) — distinct from Generative's
   indigo, signalling the newest era. Mirrors the era-* / chapter-* / step-*
   patterns used by the other three eras. */
.era-agentic .era-badge {
    background: rgba(167, 139, 250, 0.18);
    color: #c4b5fd;
    border: 1px solid rgba(167, 139, 250, 0.4);
}
.era-agentic .era-years { color: #c4b5fd; }
.era-agentic .timeline-dot { background: #a78bfa; box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.3); }
.era-agentic .timeline-card:hover { border-color: rgba(167, 139, 250, 0.5); }
.era-agentic .timeline-year { color: #c4b5fd; }
.era-agentic .timeline-tags span {
    background: rgba(167, 139, 250, 0.15);
    color: #c4b5fd;
}
.chapter-agentic.active .chapter-num { color: #c4b5fd; }
.chapter-agentic:hover:not(.active) .chapter-num { color: rgba(196, 181, 253, 0.45); }
.evo-pill.step-agentic {
    background: rgba(167, 139, 250, 0.18);
    color: #c4b5fd;
}
.step-agentic {
    background: rgba(167, 139, 250, 0.15);
    color: #c4b5fd;
    border: 1px solid rgba(167, 139, 250, 0.3);
}
.step-agentic.active {
    background: rgba(167, 139, 250, 0.28);
    border-color: rgba(167, 139, 250, 0.6);
    box-shadow: 0 0 14px rgba(167, 139, 250, 0.22);
}

/* Agentic era placeholder — shown while the chapter has no milestone cards yet. */
.timeline-items--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 140px;
    padding: 2rem 1.5rem;
    border: 1px dashed rgba(167, 139, 250, 0.25);
    border-radius: 12px;
}
.era-placeholder-note {
    margin: 0;
    color: rgba(255, 255, 255, 0.5);
    font-size: 0.95rem;
    font-style: italic;
    text-align: center;
}

.field-evolution-connector {
    color: rgba(255, 255, 255, 0.18);
    font-size: 1rem;
    transition: opacity 0.4s ease;
}

/* Career path divider */
.career-path-header {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    margin: 1.5rem auto 2.5rem;
    max-width: 1000px;
    position: relative;
    z-index: 1;
}

.career-path-line {
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.12), transparent);
}

.career-path-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    /* Bumped 0.38 → 0.62 (WCAG AA 4.5:1). */
    color: rgba(255, 255, 255, 0.62);
    white-space: nowrap;
}

/* ─── Expertise Section ────────────────────────────────────── */
.expertise {
    background-color: var(--background);
}

.expertise-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
    margin-top: 2rem;
}

.expertise-card {
    perspective: 1200px;
    height: 260px;
    cursor: pointer;
}

.expertise-card:hover .card-inner,
.expertise-card.flipped .card-inner {
    transform: rotateY(180deg);
}

.expertise-card .card-front,
.expertise-card .card-back {
    padding: 2rem;
}

.expertise-card .card-front {
    justify-content: flex-start;
}

.expertise-card:hover .flip-hint {
    opacity: 0;
}

.expertise-icon {
    color: var(--primary-light);
    margin-bottom: 1.5rem;
}

.expertise-card h3 {
    font-size: 1.25rem;
    margin-bottom: 0.75rem;
    color: var(--water-highlight);
    font-weight: 700;
    position: relative;
}

.expertise-card p {
    color: var(--text-secondary);
    line-height: 1.7;
    font-size: 0.95rem;
}

/* ─── The Glossary (Capability Depth, dictionary-entry cards) ───
   Sits between #expertise and #lab. Visual concept: clean architectural
   cards (no tilt — the glossary should feel reference-grade, distinct
   from The Lab's playful sticky-note treatment). Each card has a 3px
   colored left-edge stripe encoding category (Voice/Speech/Entity/
   Loops/Emotion), with a REDUNDANT text label in the corner ("Voice ·
   TTS") so visitors who can't perceive color (1.4.1) still get the
   grouping signal.

   <dl> semantics: AT users hear "definition list, 6 terms" and can
   navigate term-by-term via screen-reader shortcuts. Visual cards are
   created by wrapping each <dt>/<dd> trio in a <div> — HTML5 explicitly
   permits this child of <dl> for layout, without breaking the dl's
   semantic role. */
.glossary {
    background-color: var(--background);
    border-top: 1px solid rgba(125, 211, 252, 0.06);
    border-bottom: 1px solid rgba(125, 211, 252, 0.06);
}

/* ── Filter pill row ──────────────────────────────────────────
   Visual: cyan-outlined pills, active state filled with cyan.
   Active is signaled by BOTH background fill (color cue) AND a
   thicker border + bolder text (non-color cue) so colorblind
   visitors can identify the active filter without relying on
   the cyan tint alone (WCAG 1.4.1). */
.glossary-filters {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem 0.75rem;
    margin: 0 auto 1.75rem;
    max-width: 1100px;
}
.glossary-filter {
    /* Real <button>, so keyboard focus + native click are free. */
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid rgba(125, 211, 252, 0.25);
    color: rgba(255, 255, 255, 0.78);
    padding: 0.45rem 1rem;
    font-size: 0.82rem;
    font-weight: 500;
    font-family: inherit;
    border-radius: 999px;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
    /* min-height ensures pill is a 44px-friendly tap target on mobile. */
    min-height: 36px;
}
.glossary-filter:hover {
    background: rgba(34, 211, 238, 0.12);
    border-color: rgba(125, 211, 252, 0.5);
    color: var(--text-primary);
}
.glossary-filter:focus-visible {
    outline: 2px solid var(--secondary-color);
    outline-offset: 3px;
}
.glossary-filter.is-active,
.glossary-filter[aria-pressed="true"] {
    /* Active filter — cyan fill + bold weight (color + non-color signal). */
    background: rgba(34, 211, 238, 0.22);
    border-color: var(--secondary-color);
    border-width: 1.5px;
    color: var(--secondary-color);
    font-weight: 700;
}

/* Count suffix inside each filter pill — appended at runtime by
   initGlossary() in script.js as " · N". Styled as a secondary
   metadata fragment via a child <span class="glossary-filter__count">.
   Lighter, slightly smaller; signals "metadata about the label" not
   "part of the label." */
.glossary-filter__count {
    margin-left: 0.4rem;
    font-weight: 500;
    font-size: 0.78rem;
    opacity: 0.65;
    /* When the pill is active, brighten the count so it inherits the
       cyan tone of the active label. */
}
.glossary-filter[aria-pressed="true"] .glossary-filter__count {
    opacity: 0.9;
}

/* ── aria-live status (announces filter result count to AT) ──
   Sighted users don't see this — it's purely for screen readers.
   .visually-hidden is the standard "off-screen but accessible" pattern
   (vs display:none which removes from a11y tree entirely). */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Scrollable rail ─────────────────────────────────────────
   Outer container holds the dl + scroll-arrow buttons. The rail
   itself (.glossary-list) scrolls horizontally; arrow buttons sit
   absolutely positioned over the left/right edges with a fade gradient
   to hint at off-screen content. */
.glossary-rail {
    position: relative;
    /* tabindex="0" on this element (set in HTML) makes the rail itself
       keyboard-focusable so visitors can Tab to it then arrow-scroll.
       focus-visible outline tells them they're focused. */
    border-radius: 8px;
    /* Padding-bottom leaves room for visual scroll affordance — without
       it, the cards' shadows clip against the rail edge. */
}
.glossary-rail:focus-visible {
    outline: 2px solid var(--secondary-color);
    outline-offset: 3px;
}

.glossary-list {
    /* Switch from grid to horizontal-scrollable flex row. The <dl>
       semantics survive the visual change — AT users still hear
       "definition list, 6 terms" and navigate term-by-term. */
    display: flex;
    flex-wrap: nowrap;
    gap: 1.25rem;
    overflow-x: auto;
    overflow-y: hidden;
    /* scroll-snap-type: makes cards "click into place" as the user
       scrolls, so the rail always lands aligned to a card edge.
       proximity (not mandatory) so trackpad/momentum scrolling stays
       smooth — avoids the over-aggressive "snap back" feel. */
    scroll-snap-type: x proximity;
    /* No CSS scroll-behavior here. CSS `scroll-behavior: smooth` combined
       with scroll-snap-type creates a browser quirk where JS-driven
       scrollTo/scrollBy with `behavior: 'smooth'` silently fails when the
       target is at a snap-edge. Removing the CSS rule lets JS pass
       behavior: 'smooth' explicitly per call. Native user scroll (wheel,
       swipe, arrow keys) animates smoothly anyway via OS/browser
       defaults — we don't need CSS scroll-behavior to get that. */
    /* Side padding + scroll-padding combine to: cards never touch the
       rail edge, AND scroll-snap targets the inset (so a snap-aligned
       card sits 1.5rem from the edge, not flush). */
    padding: 0.5rem 1.5rem 1.25rem;
    scroll-padding-left: 1.5rem;
    margin: 0 auto;
    max-width: 1100px;
    /* Visually hide the scrollbar without removing scroll capability —
       the cards themselves + the snap behavior provide the scroll cue. */
    scrollbar-width: thin;
    scrollbar-color: rgba(125, 211, 252, 0.3) transparent;
}
.glossary-list::-webkit-scrollbar {
    height: 6px;
}
.glossary-list::-webkit-scrollbar-thumb {
    background: rgba(125, 211, 252, 0.3);
    border-radius: 3px;
}

/* When a filter hides cards, [hidden] removes them from the DOM
   for layout purposes — flex collapses smoothly so the rail
   re-flows to just the visible cards. */
.glossary-card[hidden] {
    display: none !important;
}

/* ── Scroll arrow buttons (◀ ▶) ──────────────────────────────
   Pointer-only convenience — keyboard users have native arrow-key
   scrolling on the focused rail. aria-hidden + tabindex="-1" hides
   them from AT (screen readers traverse the dl directly without
   needing arrows). */
.glossary-scroll-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(15, 23, 42, 0.92);
    border: 1px solid rgba(125, 211, 252, 0.32);
    color: var(--secondary-color);
    font-size: 1.5rem;
    line-height: 1;
    font-weight: 600;
    cursor: pointer;
    z-index: 2;
    transition: background 0.2s ease, opacity 0.2s ease;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    /* Hide arrows entirely on touch devices — touch users get swipe.
       Detected via @media (hover: none) at the bottom of this block. */
}
.glossary-scroll-btn:hover {
    background: rgba(34, 211, 238, 0.2);
}
.glossary-scroll-btn--prev { left: -10px; }
.glossary-scroll-btn--next { right: -10px; }
@media (hover: none) {
    /* Touch devices: hide arrows, swipe is the affordance. */
    .glossary-scroll-btn { display: none; }
}

.glossary-card {
    /* Each card is a <div> wrapping <dt>/<dd> pairs (HTML5-valid layout
       child of <dl>). position: relative is for the absolutely-positioned
       category badge in the top-right corner. */
    position: relative;
    /* Fixed width inside the horizontal rail. flex-shrink: 0 prevents
       cards from squeezing when the rail tries to fit them all.
       380px feels right — wide enough for the term + 3-line definition
       without cramping, narrow enough that 3 cards peek into a 1280
       viewport (signals "more to scroll"). */
    flex: 0 0 380px;
    /* Snap-align targets the start of each card so the rail always
       lands flush to a card edge as the user swipes/scrolls. */
    scroll-snap-align: start;
    background: rgba(15, 23, 42, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-left: 3px solid var(--secondary-color); /* default; per-category override below */
    border-radius: 4px;                            /* gentle, not card-y */
    padding: 1.5rem 1.5rem 1.5rem 1.75rem;         /* extra left to clear the accent stripe */
    transition: background 0.25s ease, border-color 0.25s ease, transform 0.25s ease;
    /* Subtle elevation shift on hover — signals interactivity even though
       the card itself isn't a link (keeps the dl/dt/dd semantics clean).
       If we later add per-card "Read more" links, those can sit inside .__usage. */
}
.glossary-card:hover {
    background: rgba(15, 23, 42, 0.78);
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}

/* ── Category accent stripes ──────────────────────────────────
   Color encodes category, but text label in .__category does the
   actual a11y-conformant communication. Color is decorative only. */
/* Category accent stripes — color is decorative; the inline category
   text label inside each card carries the actual a11y signal (1.4.1). */
.glossary-card--tts            { border-left-color: rgba(34, 211, 238, 0.7); }   /* cyan */
.glossary-card--recognition    { border-left-color: rgba(245, 158, 11, 0.7); }   /* amber — combines former speech (sky) + entity (amber) under one umbrella */
.glossary-card--loops          { border-left-color: rgba(99, 102, 241, 0.7); }   /* indigo — now also covers Constraint-in-LLMs (formerly LLM Tuning) */
.glossary-card--emotion        { border-left-color: rgba(217, 70, 239, 0.7); }   /* fuchsia */
.glossary-card--responsible-ai { border-left-color: rgba(132, 204, 22, 0.7); }   /* lime — Transparency Notes lives here now */

/* ── Inner content elements ───────────────────────────────────
   Note: WCAG AA contrast verified for each color against the card's
   rgba(15, 23, 42, 0.55) background. .__category sits at ~6.1:1, well
   above the 4.5:1 floor for body text. */
.glossary-card__category {
    /* Category pill — sits ABOVE the term as the first inline-block element
       inside the <dt>. Previously it was absolute-positioned in the
       top-right corner, which overlapped the term whenever the category
       label was wider than the reserved 5.5rem margin (e.g. "Affective
       Computing", "Voice · Localization"). Block-display + width:fit-content
       breaks it onto its own line and sizes it to its content — no overlap
       possible regardless of category-label length.

       gradient text-fill on the parent dt would otherwise inherit through;
       -webkit-text-fill-color resets it back to the slate color this pill
       expects. background:none similarly defeats the dt's gradient
       background-clip from leaking into this child. */
    display: block;
    width: fit-content;
    margin-bottom: 0.75rem;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
    -webkit-text-fill-color: rgba(255, 255, 255, 0.7);
    padding: 0.2rem 0.55rem;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.18);
    background-clip: border-box;
}

.glossary-card__term {
    /* The definition-list term — large, gradient-text reusing the site's
       water-text gradient for brand continuity with section headings.
       Override <dt>'s default font-weight (browsers default to bold but
       not consistently; declaring keeps the look stable cross-browser).
       margin-right: 0 (was 5.5rem) since the category pill no longer sits
       absolute-positioned in the top-right — it now flows inline above
       the term so the term has the full card width. */
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text-primary);
    margin: 0 0 0.75rem 0;
    /* Cyan gradient text — same vocabulary as section-title but tuned
       for body-scale type. Matches the aesthetic of .logo-wordmark. */
    background: var(--gradient-water-text);
    background-size: 200% 200%;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.glossary-card__pos {
    /* Part-of-speech / classification label — italicized, smaller, muted.
       Reads like a dictionary's "(noun)" or "(verb, transitive)" marker. */
    display: inline-block;
    margin-left: 0.4rem;
    font-size: 0.78rem;
    font-weight: 400;
    font-style: italic;
    color: rgba(255, 255, 255, 0.55);
    -webkit-text-fill-color: rgba(255, 255, 255, 0.55); /* override gradient on parent */
    background: none;
}

.glossary-card__def {
    /* The definition body. Reset <dd>'s user-agent default margin
       (browsers indent <dd> 40px) and line-height for readability. */
    margin: 0 0 1rem 0;
    font-size: 0.95rem;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.82);
}

.glossary-card__usage {
    /* "How I use it →" pull-quote section. Visually demarcated by a
       subtle top border so it reads as an evidentiary follow-up to the
       definition above. Slightly smaller font + muted color tones it
       down so the term + definition lead the eye. */
    margin: 0;
    padding-top: 0.875rem;
    border-top: 1px solid rgba(255, 255, 255, 0.07);
    font-size: 0.88rem;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.72);
}
.glossary-card__usage-label {
    /* "How I use it →" — the cyan accent label that opens each anecdote.
       Matches the citation-chip and CTA arrow vocabulary used elsewhere
       on the site. */
    display: block;
    margin-bottom: 0.4rem;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    color: var(--secondary-color);
}

/* ── Mobile tightening (≤540px) ──────────────────────────────── */
@media (max-width: 540px) {
    .glossary-filters {
        gap: 0.4rem 0.5rem;
        margin-bottom: 1.25rem;
    }
    .glossary-filter {
        font-size: 0.78rem;
        padding: 0.4rem 0.85rem;
    }
    .glossary-list {
        gap: 1rem;
        padding: 0.5rem 1rem 1rem;
        scroll-padding-left: 1rem;
    }
    .glossary-card {
        /* Tighter card width on phones — each card takes ~88% of the
           viewport so a sliver of the next card peeks in, signaling
           "more to swipe to". Reflow tip from 1.4.10: horizontal
           scroll is acceptable here because the swipe affordance is
           native on touch devices. */
        flex: 0 0 calc(100vw - 4rem);
        max-width: 340px;
        padding: 1.25rem 1.25rem 1.25rem 1.5rem;
    }
    .glossary-card__term {
        /* Phone-only term sizing — pill is already block-flow above the
           term at all viewport sizes (no positional reflow needed). */
        font-size: 1.1rem;
    }
}

/* Reduced-motion: disable hover lift/transition. */
@media (prefers-reduced-motion: reduce) {
    .glossary-card,
    .glossary-card:hover {
        transition: none;
        transform: none;
    }
}

/* ─── The Lab (Personal Projects, sticky-note board) ───────────
   Sits between #expertise and #products. Visual concept: a corkboard /
   project bench where each project is a slightly-tilted "sticky note"
   themed to the site's dark-navy palette (cyan / indigo / slate tints
   instead of yellow Post-it). Card-as-link pattern: each note is a
   single <a target="_blank"> so the whole tile is one focus stop with
   one large tap area, and AT users hear one announcement per project
   ("Personal Chatbot, link, opens in new tab").

   Layout: auto-fit grid, 280px minimum tile width. At <540px, the grid
   collapses to a single column and tilt animations relax (less visual
   noise on a phone screen). */
.lab {
    background-color: var(--background);
    /* Subtle horizontal rule above + below to delineate from neighboring
       sections without a heavy background swap. */
    border-top: 1px solid rgba(125, 211, 252, 0.06);
    border-bottom: 1px solid rgba(125, 211, 252, 0.06);
}

.lab-board {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 2rem 1.75rem;
    /* perspective lets the tilt feel slightly 3D (subtle Z translation on
       hover) without adding another transform layer per card. */
    perspective: 1200px;
    /* Center the grid when fewer cards than columns — avoids a lonely
       left-aligned card on tablet widths. */
    margin: 0 auto;
    max-width: 1100px;
}

/* ── Sticky note base ────────────────────────────────────────── */
.sticky-note {
    /* Tile dimensions feel roughly square-ish (a real Post-it shape). The
       min-height keeps tiles aligned even when pitches vary in length. */
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 2.25rem 1.5rem 1.5rem; /* extra top padding leaves room for the tape */
    min-height: 220px;
    border-radius: 4px;            /* almost-square corners — paper, not card */
    color: var(--text-primary);
    text-decoration: none;
    /* --tilt is set inline per card (e.g. style="--tilt: -1.6deg") so
       each note has a deterministic, designer-chosen lean. Defaulting to
       0deg here means a card without --tilt simply renders flat. */
    transform: rotate(var(--tilt, 0deg));
    /* Translation + scale on hover are the "lift" — combined with a
       cyan-tinted shadow for the glow. transition covers all three so
       the lift animates rather than snapping. */
    transition:
        transform 0.28s cubic-bezier(0.2, 0.8, 0.3, 1.2),
        box-shadow 0.28s ease,
        border-color 0.2s ease;
    /* Slight inner shadow + paper-grain via a subtle gradient. The
       gradient is barely-there — just enough to keep the surface from
       feeling like a flat rectangle of color. */
    background-image:
        linear-gradient(135deg, rgba(255, 255, 255, 0.04), rgba(0, 0, 0, 0.04));
    background-color: rgba(15, 23, 42, 0.55); /* fallback tint, overridden by variants */
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow:
        0 6px 20px rgba(0, 0, 0, 0.35),
        inset 0 1px 0 rgba(255, 255, 255, 0.03);
    /* Smooth out subpixel-rotation jaggies on transformed text. */
    will-change: transform;
}

/* HOVER ↔ FOCUS-VISIBLE PARITY (a11y).
   Same straighten + lift state for both pointer hover and keyboard focus.
   This is the rule that keeps the section WCAG-compliant — without it,
   keyboard users would never see the affordance reveal pointer users get. */
.sticky-note:hover,
.sticky-note:focus-visible {
    transform: rotate(0deg) translateY(-6px) scale(1.015);
    box-shadow:
        0 14px 38px rgba(0, 0, 0, 0.45),
        0 0 24px rgba(34, 211, 238, 0.12),
        inset 0 1px 0 rgba(255, 255, 255, 0.05);
    border-color: rgba(125, 211, 252, 0.32);
}
.sticky-note:focus-visible {
    /* Distinct keyboard outline so focus is unambiguous even when the
       hover style happens to share visuals with another card. */
    outline: 2px solid var(--secondary-color);
    outline-offset: 4px;
}
.sticky-note:active {
    /* Press feedback — a tiny "pressing the note flat" effect. */
    transform: rotate(0deg) translateY(-2px) scale(1.005);
    transition-duration: 0.1s;
}

/* ── Tile color variants ─────────────────────────────────────── */
/* Cyan tint — voice / audio category. Highest saturation so voice work
   visually pops as a distinct theme on the board. */
.sticky-note--cyan {
    background-color: rgba(6, 75, 95, 0.55);
    border-color: rgba(34, 211, 238, 0.22);
}
/* Indigo tint — LLM / agent category. Matches the chatbot brand color. */
.sticky-note--indigo {
    background-color: rgba(35, 28, 77, 0.6);
    border-color: rgba(99, 102, 241, 0.22);
}
/* Slate tint — developer tooling. Most neutral; signals "utility." */
.sticky-note--slate {
    background-color: rgba(30, 41, 59, 0.6);
    border-color: rgba(148, 163, 184, 0.18);
}

/* ── Tape strip at top of each note ───────────────────────────── */
/* Implemented as a ::before pseudo-element so it doesn't pollute the
   semantic content. aria-hidden on the tape <span> wrapper in the HTML
   keeps screen readers from announcing it. The tape's own rotation is
   intentionally OPPOSITE the note's tilt so it looks like real washi
   tape was applied separately — a small detail that sells the metaphor. */
.sticky-note__tape {
    position: absolute;
    top: -8px;
    left: 50%;
    width: 80px;
    height: 18px;
    /* counter-rotate slightly so tape angle differs from note angle */
    transform: translateX(-50%) rotate(calc(var(--tilt, 0deg) * -0.6));
    background: linear-gradient(
        180deg,
        rgba(125, 211, 252, 0.32),
        rgba(125, 211, 252, 0.18)
    );
    border-left: 1px dashed rgba(255, 255, 255, 0.12);
    border-right: 1px dashed rgba(255, 255, 255, 0.12);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    pointer-events: none;
}

/* ── Inner content elements ───────────────────────────────────── */
.sticky-note__category {
    display: inline-block;
    width: fit-content;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    /* Above WCAG AA 4.5:1 against the tile tints — verified against the
       darkest variant (rgba(35,28,77,0.6) over #060d1a). */
    color: rgba(255, 255, 255, 0.7);
    padding: 0.2rem 0.55rem;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.18);
}
.sticky-note__title {
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text-primary);
    margin: 0;
    /* Slight gradient text matches the .section-title vocabulary
       elsewhere on the site, but tone-down to avoid competing with
       section headings. */
}
.sticky-note__pitch {
    font-size: 0.92rem;
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.78);
    margin: 0;
    flex-grow: 1; /* pushes the CTA to the bottom of the tile */
}
.sticky-note__cta {
    /* Bottom-of-card "View project ↗" cue. Not a separate link — the whole
       card is the link — but visually telegraphs the destination. */
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--secondary-color);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.25rem;
}
.sticky-note__arrow {
    /* Literal Unicode ↗ — same character used in citation chips and the
       "How this works" pill for consistency across the site's external-
       link vocabulary. */
    transition: transform 0.2s ease;
}
.sticky-note:hover .sticky-note__arrow,
.sticky-note:focus-visible .sticky-note__arrow {
    transform: translate(2px, -2px); /* arrow leans further on hover */
}

/* ── Placeholder cards ───────────────────────────────────────── */
/* In-progress projects: rendered as <div>, not <a>, so they're not
   focusable. Visual treatment: dimmer, no hover lift. The "🚧 In progress"
   pill makes status legible to all users (not just sighted hover users). */
.sticky-note--placeholder {
    opacity: 0.62;
    cursor: default;
    /* Defeat the hover/focus lift for placeholder cards by holding their
       transform at the static tilt. */
}
.sticky-note--placeholder:hover {
    transform: rotate(var(--tilt, 0deg));
    box-shadow:
        0 6px 20px rgba(0, 0, 0, 0.35),
        inset 0 1px 0 rgba(255, 255, 255, 0.03);
    border-color: rgba(255, 255, 255, 0.06);
}
.sticky-note__cta--placeholder {
    color: rgba(255, 255, 255, 0.55);
    font-style: italic;
}

/* ── "Needs URL" cards (Speech Coach, Grammar Import Tool) ─────
   These ARE links semantically (so Sam can swap href in one place
   later), but href="#" + aria-disabled="true" tells AT they're not
   currently functional. Visual treatment matches the placeholder
   dimming so visitors don't tap into a broken state. */
.sticky-note--needs-url {
    opacity: 0.78;
}
.sticky-note--needs-url[aria-disabled="true"] {
    /* Block the click-through entirely to avoid the "#" hash navigating
       to top-of-page on click. JS not needed — `pointer-events: none`
       on hover descendants would also fix this but breaks focus-visible. */
    pointer-events: none;
    cursor: not-allowed;
}

/* ── Mobile tightening (≤540px) ──────────────────────────────── */
@media (max-width: 540px) {
    .lab-board {
        gap: 1.5rem;
    }
    .sticky-note {
        /* Reduce the tilt magnitude on phones — strong angles look
           messy when stacked single-column; subtle is enough. */
        transform: rotate(calc(var(--tilt, 0deg) * 0.4));
    }
    .sticky-note:hover,
    .sticky-note:focus-visible {
        transform: rotate(0deg) translateY(-4px) scale(1.01);
    }
}

/* Reduced-motion: keep the static tilt (it's brand, not animation) but
   disable the hover lift transition. WCAG 2.3.3 doesn't strictly require
   this for hover transforms, but it's a courteous default. */
@media (prefers-reduced-motion: reduce) {
    .sticky-note,
    .sticky-note__arrow {
        transition: none;
    }
    .sticky-note:hover,
    .sticky-note:focus-visible {
        transform: rotate(var(--tilt, 0deg));
    }
}

/* ─── Products Section ─────────────────────────────────────── */
.products {
    background-color: var(--background-alt);
}

.products-grid {
    display: grid;
    gap: 2.5rem;
}

.product-card {
    background: var(--card-bg);
    border-radius: 16px;
    overflow: hidden;
    border: 1px solid var(--border-color);
    transition: all 0.3s ease;
}

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

.product-header {
    background: var(--gradient-secondary);
    padding: 1.25rem 1.5rem 1rem;
    color: white;
    position: relative;
    overflow: hidden;
}

.product-header-svg {
    display: block;
    width: 100%;
    height: 72px;
    margin-bottom: 0.5rem;
    opacity: 0.9;
}

.product-type {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    background-color: rgba(255, 255, 255, 0.2);
    padding: 0.3rem 0.75rem;
    border-radius: 50px;
    margin-bottom: 0.6rem;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.product-header h3 {
    font-size: 1.3rem;
    font-weight: 700;
    margin: 0;
}

.product-content {
    padding: 1.25rem 1.5rem;
}

.product-challenge,
.product-solution {
    margin-bottom: 1rem;
    line-height: 1.65;
    color: var(--text-secondary);
    font-size: 0.875rem;
}

.product-challenge strong,
.product-solution strong {
    color: var(--text-primary);
    font-weight: 600;
}

.product-metrics {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    margin: 1rem 0;
    padding: 1rem;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 10px;
    border: 1px solid var(--border-color);
}

.metric {
    text-align: center;
}

.metric-value {
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--primary-light);
    margin-bottom: 0.2rem;
}

.metric-label {
    font-size: 0.75rem;
    color: var(--text-light);
    font-weight: 500;
}

.product-tags {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.product-tags span {
    background: rgba(99, 102, 241, 0.2);
    color: var(--primary-light);
    padding: 0.3rem 0.7rem;
    border-radius: 6px;
    font-size: 0.78rem;
    font-weight: 600;
    border: 1px solid rgba(99, 102, 241, 0.3);
}

.product-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--secondary-color);
    text-decoration: none;
    transition: gap 0.2s ease, color 0.2s ease;
}

.product-link:hover {
    gap: 0.6rem;
    color: white;
}

/* ─── Media Section (Writing, Speaking & Press) ────────────── */
.media {
    background-color: var(--background);
}

.media-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
    align-items: stretch;
}

.media-col {
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 16px;
    padding: 1.75rem;
    display: flex;
    flex-direction: column;
    gap: 0;
}

.media-col-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
    color: var(--secondary-color);
}

.media-col-title {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--secondary-color);
    margin: 0;
}

.media-items {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.media-item {
    padding: 1rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.media-item:last-child {
    border-bottom: none;
}

.media-item h4 {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.4;
    margin: 0.25rem 0 0.3rem;
}

.media-item-label {
    display: inline-block;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--secondary-color);
    background: rgba(34, 211, 238, 0.08);
    border: 1px solid rgba(34, 211, 238, 0.2);
    padding: 0.15rem 0.5rem;
    border-radius: 50px;
    margin-bottom: 0.25rem;
}

.media-item-outlet {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--primary-light);
    margin-bottom: 0.25rem;
}

.media-item-meta {
    font-size: 0.75rem;
    color: var(--text-light);
    margin: 0.2rem 0 0.35rem;
}

.media-item-desc {
    font-size: 0.8rem;
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0.25rem 0 0.4rem;
}

.media-item-link {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--primary-light);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    transition: gap 0.2s ease, color 0.2s ease;
    margin-top: 0.3rem;
}

.media-item-link:hover {
    gap: 0.55rem;
    color: white;
}

.media-col-cta {
    display: inline-block;
    margin-top: 1.25rem;
    font-size: 0.8rem;
    text-align: center;
    text-decoration: none;
}

/* ─── Contact Section ──────────────────────────────────────── */
.contact {
    background-color: var(--background);
}

.contact-wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    max-width: 1100px;
    margin: 0 auto;
}

.contact-intro {
    font-size: 1.1rem;
    line-height: 1.8;
    color: var(--text-secondary);
    margin-bottom: 2rem;
}

.contact-methods {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.contact-item {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
}

.contact-icon {
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(99, 102, 241, 0.15);
    border: 1px solid rgba(99, 102, 241, 0.3);
    border-radius: 10px;
    color: var(--primary-light);
    flex-shrink: 0;
}

.contact-item h3 {
    font-size: 1.1rem;
    margin-bottom: 0.25rem;
    color: var(--text-primary);
}

.contact-item p {
    color: var(--text-secondary);
}

.contact-form {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.form-group label {
    font-weight: 600;
    color: var(--text-primary);
    font-size: 0.95rem;
}

.form-group input,
.form-group textarea,
.form-group select {
    width: 100%;
    padding: 0.875rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    font-family: inherit;
    font-size: 1rem;
    transition: all 0.3s ease;
    background: var(--card-bg);
    color: var(--text-primary);
    color-scheme: dark;
}

.form-group input::placeholder,
.form-group textarea::placeholder {
    color: var(--text-light);
}

.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
    outline: none;
    border-color: var(--primary-color);
    background: var(--card-bg-hover);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
}

.contact-form .btn {
    cursor: pointer;
    border: none;
    font-size: 1rem;
}

/* ─── Currently Active ─────────────────────────────────────── */

.currently-active {
    padding: 3rem 0;
    background: transparent;
}

.active-section-title {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--secondary-color);
    text-transform: uppercase;
    margin-bottom: 1.5rem;
    opacity: 0.8;
}

.active-cards {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.active-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
    padding: 1.5rem 2rem;
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--secondary-color);
    border-radius: 12px;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.25s ease, background 0.25s ease, transform 0.25s ease;
}

.active-card:hover {
    background: rgba(34, 211, 238, 0.05);
    border-color: rgba(34, 211, 238, 0.4);
    border-left-color: var(--secondary-color);
    transform: translateX(4px);
}

.active-card-left {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.active-category {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--secondary-color);
    opacity: 0.75;
}

.active-card h3 {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--text-primary);
    margin: 0;
}

.active-card p {
    font-size: 0.875rem;
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0;
    max-width: 640px;
}

.active-card-right {
    flex-shrink: 0;
}

.active-arrow {
    font-size: 1.25rem;
    color: var(--secondary-color);
    opacity: 0.5;
    transition: opacity 0.2s ease, transform 0.2s ease;
    display: block;
}

.active-card:hover .active-arrow {
    opacity: 1;
    transform: translateX(4px);
}

@media (max-width: 600px) {
    .active-card {
        flex-direction: column;
        align-items: flex-start;
        gap: 1rem;
    }
    .active-card-right { display: none; }
}

/* ── Active card variant: two-link card (no card-as-link) ──────
   Used when a venture has multiple destinations to surface (e.g.
   All In Ascent → game site + rulebook). The wrapping element is
   a <div>, not an <a>, so the whole-card-hover-translate from
   .active-card:hover does NOT fire on this variant — we suppress
   the transform here and let the inner h3 link carry the affordance.

   The active-card itself keeps its border/background hover (still
   useful as a tile-level affordance), but skips the translateX so
   nothing visually "lifts" when there are interactive children. */
.active-card--has-secondary:hover {
    transform: none;
}

/* Primary title link inside .active-card--has-secondary's <h3>. Reuses
   the h3 typographic styling; just changes color behavior on hover. */
.active-card-title-link {
    color: var(--text-primary);
    text-decoration: none;
    transition: color 0.2s ease;
}
.active-card-title-link:hover {
    color: var(--secondary-color);
}
.active-card-title-link:focus-visible {
    outline: 2px solid var(--secondary-color);
    outline-offset: 3px;
    border-radius: 2px;
}
.active-card-title-arrow {
    /* Inline ↗ arrow on the title — small, slightly muted, brightens
       on hover so the link reads as the primary navigational element. */
    font-size: 0.85em;
    margin-left: 0.2rem;
    opacity: 0.55;
    transition: opacity 0.2s ease, transform 0.2s ease;
    display: inline-block;
}
.active-card-title-link:hover .active-card-title-arrow {
    opacity: 1;
    transform: translate(2px, -2px);
}

/* Secondary link inside the description paragraph (e.g. "Read the
   rulebook ↗"). Smaller, cyan-tinted, underlined on hover. Reads as
   "second destination" rather than competing with the title link. */
.active-card-secondary-link {
    color: var(--secondary-color);
    text-decoration: none;
    font-weight: 500;
    border-bottom: 1px solid rgba(34, 211, 238, 0.3);
    padding-bottom: 1px;
    transition: border-bottom-color 0.2s ease, color 0.2s ease;
}
.active-card-secondary-link:hover {
    color: var(--secondary-light, #67e8f9);
    border-bottom-color: rgba(34, 211, 238, 0.8);
}
.active-card-secondary-link:focus-visible {
    outline: 2px solid var(--secondary-color);
    outline-offset: 3px;
    border-radius: 2px;
}

/* ─── Footer ───────────────────────────────────────────────── */
.footer-disclaimer {
    border-top: 1px solid rgba(255, 255, 255, 0.07);
    padding: 1.25rem 2.5rem;
    text-align: center;
}

.footer-disclaimer p {
    font-size: 0.72rem;
    color: var(--text-light);
    /* Dropped opacity: 0.6 — it was multiplying with --text-light's 0.62 alpha,
       producing an effective 0.37 alpha → 3.42:1 contrast (axe AA failure).
       --text-light is already tuned for AA on this background. */
    max-width: 780px;
    margin: 0 auto;
    line-height: 1.6;
}

.footer {
    background-color: #060d1a;
    color: white;
    padding: 3rem 0 2rem;
    border-top: 1px solid var(--border-color);
}

.footer-content {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 3rem;
}

.footer-logo {
    font-size: 1.5rem;
    font-weight: 700;
    background: var(--gradient-secondary);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    margin-bottom: 0.5rem;
}

.footer-left p {
    color: var(--text-light);
    font-size: 0.9rem;
}

.footer-links {
    display: flex;
    gap: 3rem;
}

.footer-column {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.footer-column h4 {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-secondary);
    margin-bottom: 0.5rem;
}

.footer-column a {
    color: var(--text-light);
    text-decoration: none;
    font-size: 0.9rem;
    transition: color 0.3s ease;
}

.footer-column a:hover {
    color: var(--text-primary);
}

/* ─── Animations ───────────────────────────────────────────── */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ─── Water Typography ─────────────────────────────────────── */

/* Slow gradient drift — the primary water-flow effect */
@keyframes waterDrift {
    0%, 100% { background-position: 0% 50%; }
    50%       { background-position: 100% 50%; }
}

/* Caustic shimmer — diagonal light-through-water sweep on hover */
@keyframes causticShimmer {
    0%   { transform: translateX(-100%) skewX(-20deg); opacity: 0; }
    15%  { opacity: 0.6; }
    85%  { opacity: 0.6; }
    100% { transform: translateX(250%) skewX(-20deg); opacity: 0; }
}

/* Surface pulse — very subtle brightness oscillation for navbar logo */
@keyframes surfacePulse {
    0%, 100% { filter: brightness(1); }
    50%       { filter: brightness(1.12) drop-shadow(0 0 6px rgba(34, 211, 238, 0.3)); }
}

/* Shimmer pseudo-element for card headings */
.philosophy-card h3::after,
.expertise-card h3::after,
.article-title::after,
.category-title::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    height: 100%;
    background: linear-gradient(
        90deg,
        transparent,
        rgba(103, 232, 249, 0.3),
        transparent
    );
    transform: translateX(-100%) skewX(-20deg);
    pointer-events: none;
}

/* Trigger shimmer on parent card hover — expertise cards only */
.expertise-card:hover h3::after {
    animation: causticShimmer 0.9s ease forwards;
}

/* Section title hover glow */
.section-title:hover {
    filter: brightness(1.1) drop-shadow(0 0 8px rgba(34, 211, 238, 0.2));
    transition: filter 0.5s ease;
}

/* ─── Responsive Design ────────────────────────────────────── */
@media (max-width: 968px) {
    .philosophy-card {
        grid-template-columns: 1fr;
    }

    .card-main {
        border-right: none;
        border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    }

    .expertise-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .media-grid {
        grid-template-columns: 1fr;
    }

    .contact-wrapper {
        grid-template-columns: 1fr;
        gap: 3rem;
    }

    .footer-content {
        flex-direction: column;
    }
}

@media (max-width: 968px) {
    .hero-content {
        flex-direction: column-reverse;
        text-align: center;
        gap: 2.5rem;
    }
    .hero-text {
        text-align: center;
    }
    .hero-buttons {
        justify-content: center;
    }
    .hero-description {
        margin-left: auto;
        margin-right: auto;
    }
    .hero-photo-frame {
        width: 220px;
        height: 220px;
    }
}

/* The mobile-nav breakpoint — hamburger appears, desktop Resume button hides,
   drawer takes over. Set to 900 because the full nav has 7 menu items + branding
   + a Resume button, which only fits comfortably at desktop widths. iPads + small
   laptops get the drawer. Threshold tested: at 900px the full nav fits cleanly;
   at 768 (iPad Mini) it wraps to two lines and looks broken. */
@media (max-width: 900px) {
    .hamburger {
        display: flex;
    }

    /* Hide the desktop Resume pill on phones — the Resume entry inside the drawer
       (.nav-resume-item) takes over instead. Saves horizontal real estate so the
       navbar collapses to: circuit icon + SB chip + hamburger. */
    .resume-btn {
        display: none;
    }

    /* Mobile drawer — slides in from the right and fills the viewport below the
       navbar. Uses calc() with a CSS var so the drawer top always matches the
       navbar height regardless of how that height changes per design tweak.
       Previous implementation hardcoded `top: 70px` which clipped under the
       115px-tall ballooned navbar (when "Sam Bobo" was wrapping). */
    .nav-menu {
        position: fixed;
        right: -100%;
        top: var(--nav-height-mobile, 56px);
        flex-direction: column;
        background-color: rgba(15, 23, 42, 0.98);
        backdrop-filter: blur(16px);
        -webkit-backdrop-filter: blur(16px);
        width: 100%;
        max-width: 320px;
        height: calc(100vh - var(--nav-height-mobile, 56px));
        overflow-y: auto;
        text-align: left;
        transition: right 0.3s ease;
        border-left: 1px solid var(--border-color);
        padding: 1.5rem 1.5rem 3rem;
        gap: 1.25rem;
        align-items: stretch;
        box-shadow: -10px 0 40px rgba(0, 0, 0, 0.4);
    }
    .nav-menu.active { right: 0; }

    /* Drawer-only Resume entry — revealed inside the drawer (was display:none
       at desktop). Styled like a primary action so it stands out in the drawer
       list without a background. */
    .nav-resume-item {
        display: list-item;
    }
    .nav-resume-item .nav-link-resume {
        font-weight: 600;
        color: var(--secondary-color);
    }

    /* Drawer nav links — bigger tap targets (44 px tall via padding).
       line-height tightened to 1.25 (override the inherited body line-height
       of 1.7) so multi-word labels like "Writing, Speaking & Press" that
       wrap to a second line on narrow phones (≤330px viewports, accessibility
       large-text mode, etc.) don't have ~26px of empty leading between the
       wrapped lines. 1.25 keeps wrapped lines visually grouped as a single
       menu item rather than reading like two stacked items. */
    .nav-menu .nav-link {
        display: block;
        padding: 0.75rem 0.25rem;
        font-size: 0.95rem;
        line-height: 1.25;
        border-bottom: 1px solid var(--border-color);
    }
    .nav-menu .nav-link:last-child,
    .nav-menu .nav-resume-item .nav-link {
        border-bottom: none;
    }

    /* On tablet (640–900) the wordmark stays visible — there's plenty of room
       since the nav links collapsed into the drawer. The wordmark only hides on
       narrow phones via the nested @media query below. */

    .hero-title {
        font-size: 2.5rem;
        /* text-wrap: balance distributes characters across lines so titles like
           "Building Products at the Intersection of AI & Human Experience" don't
           strand "AI" or "of" on lines by themselves. Modern browsers only — older
           browsers fall back to default wrapping which is fine. */
        text-wrap: balance;
    }

    .hero-description {
        font-size: 1.1rem;
    }

    .section-title {
        font-size: 2rem;
    }

    .expertise-grid {
        grid-template-columns: 1fr;
    }

    .product-metrics {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    .footer-links {
        flex-direction: column;
        gap: 2rem;
    }

    /* Responsive timeline */
    .timeline::before {
        left: 20px;
    }

    .timeline-item.item-left,
    .timeline-item.item-right {
        flex-direction: row;
        padding-left: 3.5rem;
        padding-right: 0;
    }

    .timeline-connector {
        left: 20px;
        transform: none;
    }

    .item-left .timeline-card::after,
    .item-right .timeline-card::after {
        left: -8px;
        right: auto;
        border-right: 8px solid rgba(255, 255, 255, 0.1);
        border-left: none;
    }

    .era-header {
        text-align: left;
        padding-left: 3.5rem;
    }

    .era-description {
        margin: 0;
        max-width: 100%;
    }
}

/* Phone-only tightening (≤540px).
   Tablets in the 541–900px range keep the wordmark and looser navbar padding
   because the drawer already collapsed the nav links — there's plenty of room
   for the SB chip + "Sam Bobo" wordmark. We only strip those down on actual
   phones where every horizontal pixel counts. */
@media (max-width: 540px) {
    /* Re-declare --nav-height-mobile so the drawer's `top` calc (see the
       @media (max-width: 900px) block where .nav-menu uses
       `top: var(--nav-height-mobile, 56px)`) lands flush with the navbar's
       new shorter height. Without this the drawer would have a 4–8px gap
       at the top on phones.
       NOTE: custom-property declarations inside a media query MUST be inside
       a selector rule (here :root) — naked declarations at the top of an
       @media block are invalid CSS and cause the parser to drop subsequent
       sibling rules until it recovers. */
    :root {
        --nav-height-mobile: 52px;
    }

    .navbar .container {
        /* Vertical padding pulled in from 0.5rem (8px) → 0.25rem (4px) so the
           navbar isn't taller than it needs to be on phones. The 44px hamburger
           is the floor: 44 + 4 + 4 = 52px total. We can't go lower without
           shrinking the tap target below the WCAG 2.5.5 AAA threshold. */
        padding: 0.25rem 1rem;
        min-height: 52px;
    }

    /* Hide the "Sam Bobo" wordmark text on phones — the SB chip alone serves
       as the home affordance. The wordmark stays in the DOM for screen
       readers / SEO; only its visual rendering is suppressed. */
    .logo-wordmark {
        display: none;
    }

    /* Tighten the SB chip + circuit icon container so they hug the navbar
       vertically. Without this the .logo flex container can leave a few px
       of phantom whitespace from line-height. */
    .navbar .logo {
        line-height: 1;
    }
}

@media (max-width: 480px) {
    .hero-title {
        font-size: 2rem;
    }

    .hero-buttons {
        flex-direction: column;
        width: 100%;
    }

    .btn {
        width: 100%;
    }
}

/* ─── Back-to-Top Button ───────────────────────────────────────
   Floating circular button that appears once the user has scrolled past
   ~400px (toggle handled in script.js). Positioned bottom-LEFT so it
   doesn't compete with the chatbot FAB on the right side — the two
   floating actions now live on opposite corners and won't overlap at any
   viewport size, even when the chatbot panel opens (which expands from
   the right).

   Visibility pattern: pointer-events:none + opacity:0 + translateY(8px) by
   default so the button is fully out of the way (can't accidentally tab
   into it, can't intercept clicks). Adding .is-visible reverses all three. */
.back-to-top {
    position: fixed;
    bottom: 30px;
    left: 30px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(34, 211, 238, 0.4);
    /* Same dark navy as the navbar so the button feels part of the chrome
       rather than the page content. */
    background: rgba(15, 23, 42, 0.92);
    color: var(--secondary-color);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    /* z-index just below the chatbot panel (1000) but above page content. */
    z-index: 999;
    /* Default = hidden state. transform offset makes the reveal animation
       feel like the button "rises" into place rather than just fading. */
    opacity: 0;
    transform: translateY(8px);
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease, background 0.2s ease, border-color 0.2s ease;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}
.back-to-top.is-visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto; /* re-enable clicks/focus once visible */
}
.back-to-top:hover {
    background: rgba(15, 23, 42, 1);
    border-color: var(--secondary-color);
    /* Slight lift on hover, matching the .btn pattern above. */
    transform: translateY(-2px);
}
.back-to-top:focus-visible {
    outline: 2px solid var(--secondary-color);
    outline-offset: 3px;
}
.back-to-top svg {
    /* Subtle drop shadow under the arrow so it stays legible against the
       semi-transparent background regardless of what's behind the button. */
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
}

/* Phone offsets — both floating action buttons get pushed UP from the
   visual bottom edge to clear iOS Safari's bottom toolbar (~50px tall when
   the address bar is showing). At `bottom: 20px` the buttons sit half-
   under that toolbar on iPhone 12 mini and similar small Safari viewports,
   making them un-tappable as the user scrolls — exactly the symptom that
   reads like "section content is overlaying the FAB" but is really iOS
   chrome covering the bottom slice of the layout viewport.
   The `env(safe-area-inset-bottom)` addend handles the home indicator on
   notch-era iPhones (~34px). Falling back to 0 when env() isn't supported
   means non-iOS browsers just get the static 80px lift, which is harmless. */
@media (max-width: 540px) {
    .back-to-top {
        bottom: calc(80px + env(safe-area-inset-bottom, 0px));
        left: 20px;
    }
    /* NOTE: .chatbot-toggle has the same lift-on-phones override applied in
       its own ≤540 media query later in the file (placed AFTER the
       .chatbot-toggle's ≤768 / ≤480 blocks so it can override them by source
       order — same selector specificity, source-order wins). */
}

/* ─── Chatbot Widget ───────────────────────────────────────── */
.chatbot-toggle {
    position: fixed;
    bottom: 30px;
    right: 30px;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background: var(--gradient-secondary);
    border: none;
    cursor: pointer;
    box-shadow: 0 4px 20px rgba(79, 70, 229, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    transition: all 0.3s ease;
    color: white;
}

.chatbot-toggle:hover {
    transform: scale(1.1);
    box-shadow: 0 6px 30px rgba(79, 70, 229, 0.5);
}

.chatbot-container {
    position: fixed;
    bottom: 100px;
    right: 30px;
    width: 400px;
    height: 600px;
    background: #0f172a;
    border: 1px solid var(--border-color);
    border-radius: 16px;
    box-shadow: 0 10px 50px rgba(0, 0, 0, 0.5);
    display: none;
    flex-direction: column;
    z-index: 999;
    overflow: hidden;
    animation: slideUp 0.3s ease;
}

.chatbot-container.active {
    display: flex;
}

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

.chatbot-header {
    background: var(--gradient-secondary);
    color: white;
    padding: 1.25rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.chatbot-header-content {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.chatbot-avatar {
    width: 40px;
    height: 40px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.3);
}

.chatbot-title h4 {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
}

.chatbot-title p {
    margin: 0;
    font-size: 0.75rem;
    opacity: 0.85;
}

.chatbot-close {
    background: none;
    border: none;
    color: white;
    cursor: pointer;
    padding: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.3s ease;
}

.chatbot-close:hover {
    opacity: 0.7;
}

.chatbot-messages {
    flex: 1;
    padding: 1.5rem;
    overflow-y: auto;
    background: #1e293b;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.chatbot-messages::-webkit-scrollbar {
    width: 6px;
}

.chatbot-messages::-webkit-scrollbar-track {
    background: #1e293b;
}

.chatbot-messages::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.15);
    border-radius: 3px;
}

.chatbot-messages::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.25);
}

.chatbot-message {
    display: flex;
    gap: 0.75rem;
    animation: fadeIn 0.3s ease;
}

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

.message-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.bot-message .message-avatar {
    background: var(--gradient-secondary);
    color: white;
}

.user-message {
    flex-direction: row-reverse;
}

.user-message .message-avatar {
    background: rgba(99, 102, 241, 0.2);
    color: var(--primary-light);
    border: 1px solid rgba(99, 102, 241, 0.4);
}

.message-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.message-content p {
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid var(--border-color);
    padding: 0.875rem;
    border-radius: 12px;
    margin: 0;
    line-height: 1.6;
    color: var(--text-primary);
}

.user-message .message-content p {
    background: var(--primary-dark);
    border-color: transparent;
    color: white;
}

.suggested-questions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.suggestion-btn {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border-color);
    padding: 0.75rem;
    border-radius: 8px;
    font-size: 0.875rem;
    cursor: pointer;
    transition: all 0.3s ease;
    text-align: left;
    color: var(--text-secondary);
    font-weight: 500;
}

.suggestion-btn:hover {
    border-color: var(--primary-color);
    color: var(--primary-light);
    background: rgba(99, 102, 241, 0.1);
}

.chatbot-input-container {
    padding: 1rem;
    background: #0f172a;
    border-top: 1px solid var(--border-color);
    display: flex;
    gap: 0.75rem;
}

.chatbot-input {
    flex: 1 1 0;
    /* min-width: 0 lets the flex item shrink below its content's intrinsic width.
       Without this, long placeholder text forces the input to overflow its
       allotted flex space and clip on narrow phones. */
    min-width: 0;
    padding: 0.875rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    font-family: inherit;
    font-size: 0.95rem;
    transition: all 0.3s ease;
    background: var(--card-bg);
    color: var(--text-primary);
    text-overflow: ellipsis;
}

.chatbot-input::placeholder {
    color: var(--text-light);
}

.chatbot-input:focus {
    outline: none;
    border-color: var(--primary-color);
    background: var(--card-bg-hover);
}

.chatbot-send {
    width: 44px;
    height: 44px;
    border-radius: 8px;
    background: var(--gradient-secondary);
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    transition: all 0.3s ease;
}

.chatbot-send:hover {
    transform: scale(1.05);
    box-shadow: 0 4px 15px rgba(79, 70, 229, 0.4);
}

.chatbot-send:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    transform: none;
}

.typing-indicator {
    display: flex;
    gap: 0.25rem;
    padding: 0.875rem;
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    width: fit-content;
}

.typing-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--text-light);
    animation: typing 1.4s infinite;
}

.typing-dot:nth-child(2) {
    animation-delay: 0.2s;
}

.typing-dot:nth-child(3) {
    animation-delay: 0.4s;
}

@keyframes typing {
    0%, 60%, 100% {
        transform: translateY(0);
        opacity: 0.4;
    }
    30% {
        transform: translateY(-10px);
        opacity: 1;
    }
}

/* ─── Responsive Chatbot ───────────────────────────────────── */
@media (max-width: 768px) {
    .chatbot-container {
        width: calc(100vw - 40px);
        right: 20px;
        bottom: 90px;
        height: 500px;
    }

    .chatbot-toggle {
        right: 20px;
        bottom: 20px;
    }
}

@media (max-width: 480px) {
    .chatbot-container {
        width: 100vw;
        height: 100vh;
        right: 0;
        bottom: 0;
        border-radius: 0;
    }

    .chatbot-toggle {
        width: 56px;
        height: 56px;
    }
}

/* Phone-only lift for the chatbot FAB (paired with the same lift on
   .back-to-top earlier in this file). Placed at the END of the file so it
   wins over the ≤768 and ≤480 .chatbot-toggle rules above by source order
   (same selector specificity). Reasoning: iOS Safari's bottom toolbar
   covers ~50px of the visual viewport during scroll, leaving the FAB at
   `bottom: 20px` half un-tappable on iPhone 12 mini. The 80px lift +
   env(safe-area-inset-bottom) keeps the FAB clear of both the toolbar
   and the home indicator. */
@media (max-width: 540px) {
    .chatbot-toggle {
        bottom: calc(80px + env(safe-area-inset-bottom, 0px));
    }
}
