/* ==========================================================================
   Cinematic portfolio design system
   Tokens -> base -> navigation -> hero -> sections -> cards -> overlays
   Shared by index.html and dashboards.html.
   ========================================================================== */

/* ==========================================================================
   1. DESIGN TOKENS — midnight blue/near-black with cyan + violet accents
   ========================================================================== */
:root {
    /* Surfaces */
    --bg-color: #060a14;
    --band-surface: rgba(9, 14, 26, 0.72);
    --navbar-bg: rgba(6, 10, 20, 0.72);
    --card-bg: rgba(14, 21, 38, 0.66);
    --card-bg-hover: rgba(19, 29, 52, 0.82);
    --panel-solid: #0b1120;
    /* Native bed for the contained featured artwork: stays dark navy in both
       themes so light mode never shows white letterbox bands around it. */
    --featured-art-bg: #060a14;
    --modal-bg: #0b1120;
    --keyboard-bg: #26324c;
    --keyboard-notch: #3b4a68;
    --screen-border: #121b2e;
    --toast-bg: rgba(8, 13, 24, 0.96);
    --toast-color: #e8f0ff;

    /* Text */
    --text-primary: #e8f0ff;
    --text-secondary: #93a3c0;
    --text-muted: #6d7d9c;

    /* Accents */
    --accent-color: #38bdf8;
    --accent-hover: #0ea5e9;
    --accent-2: #a78bfa;
    --accent-2-strong: #8b5cf6;
    --on-accent: #04101f;

    /* Lines, lattices and glows */
    --hairline: rgba(148, 176, 226, 0.14);
    --glass-border: 1px solid rgba(148, 176, 226, 0.16);
    --grid-line: rgba(120, 160, 220, 0.05);
    --field-line: rgba(120, 165, 230, 0.10);
    --ambient-cyan: rgba(56, 189, 248, 0.11);
    --ambient-violet: rgba(139, 92, 246, 0.11);
    --glow-cyan: rgba(56, 189, 248, 0.32);
    --glow-violet: rgba(139, 92, 246, 0.30);
    --shadow-card: 0 22px 50px -28px rgba(2, 8, 23, 0.95);

    /* Shape, type and motion */
    --font-main: 'Inter', sans-serif;
    --radius-lg: 22px;
    --radius-md: 16px;
    --radius-sm: 10px;
    --ease-out: cubic-bezier(.22, .8, .28, 1);
}

html[data-theme="light"] {
    --bg-color: #f4f7fc;
    --band-surface: rgba(255, 255, 255, 0.66);
    --navbar-bg: rgba(246, 249, 255, 0.78);
    --card-bg: rgba(255, 255, 255, 0.78);
    --card-bg-hover: rgba(255, 255, 255, 0.96);
    --panel-solid: #ffffff;
    --modal-bg: #ffffff;
    --keyboard-bg: #c3cede;
    --keyboard-notch: #93a3bd;
    --screen-border: #b9c6da;
    --toast-bg: rgba(255, 255, 255, 0.97);
    --toast-color: #0a1224;

    --text-primary: #0a1224;
    --text-secondary: #4a5975;
    --text-muted: #6b7c9b;

    --accent-color: #0284c7;
    --accent-hover: #0369a1;
    --accent-2: #7c3aed;
    --accent-2-strong: #6d28d9;
    --on-accent: #ffffff;

    --hairline: rgba(15, 30, 60, 0.10);
    --glass-border: 1px solid rgba(15, 30, 60, 0.10);
    --grid-line: rgba(15, 40, 80, 0.045);
    --field-line: rgba(20, 50, 100, 0.09);
    --ambient-cyan: rgba(2, 132, 199, 0.10);
    --ambient-violet: rgba(124, 58, 237, 0.08);
    --glow-cyan: rgba(2, 132, 199, 0.22);
    --glow-violet: rgba(124, 58, 237, 0.18);
    --shadow-card: 0 22px 50px -32px rgba(15, 30, 60, 0.40);
}

/* ==========================================================================
   2. BASE
   ========================================================================== */
html {
    scroll-behavior: smooth;
    scroll-padding-top: 86px;
    background-color: var(--bg-color);
    transition: background-color 0.35s;
}

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

body {
    font-family: var(--font-main);
    color: var(--text-primary);
    line-height: 1.6;
    overflow-x: hidden;
    /* Technical lattice shared by both pages, very low contrast */
    background-color: var(--bg-color);
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 76px 76px, 76px 76px;
    transition: background-color 0.35s, color 0.35s;
}

img {
    max-width: 100%;
}

a:focus-visible,
button:focus-visible {
    outline: 2px solid var(--accent-color);
    outline-offset: 3px;
}

::selection {
    background: var(--glow-cyan);
    color: var(--text-primary);
}

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

section {
    padding: 5.5rem 0;
}

/* ==========================================================================
   3. NAVBAR
   ========================================================================== */
.navbar {
    padding: 0.7rem 0;
    position: fixed;
    width: 100%;
    top: 0;
    z-index: 1000;
    background: var(--navbar-bg);
    backdrop-filter: blur(16px) saturate(140%);
    border-bottom: 1px solid var(--hairline);
    box-shadow: 0 20px 40px -34px rgba(0, 0, 0, 0.9);
    /* Motion: condensed state is toggled by app.js once the page is scrolled */
    transition: padding 0.35s var(--ease-out), box-shadow 0.35s;
}

.navbar::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent-color), var(--accent-2), transparent);
    opacity: 0.45;
    /* Motion: reading progress written as --page-progress by app.js.
       The fallback of 1 keeps the original full-width hairline whenever
       motion is reduced or JS is unavailable. */
    transform-origin: left center;
    transform: scaleX(calc(0.04 + 0.96 * var(--page-progress, 1)));
}

.navbar .container {
    display: flex;
    align-items: center;
    gap: 0;
}

.logo {
    font-weight: 700;
    color: var(--text-primary);
    text-decoration: none;
    display: flex;
    align-items: center;
    flex-shrink: 0;
    margin-right: auto;
}

.nav-logo {
    height: 46px;
    width: auto;
    display: block;
}

/* Text nav links */
.nav-links-text {
    display: flex;
    align-items: center;
}

.nav-links-text a {
    color: var(--text-secondary);
    text-decoration: none;
    margin-left: 2rem;
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    transition: color 0.3s;
    position: relative;
    white-space: nowrap;
}

.nav-links-text a::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 0;
    width: 100%;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-color), var(--accent-2));
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.28s var(--ease-out);
}

.nav-links-text a:hover {
    color: var(--accent-color);
}

.nav-links-text a:hover::after {
    transform: scaleX(1);
}

/* Action items: socials + toggle buttons */
.nav-links-actions {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.nav-divider {
    display: inline-block;
    width: 1px;
    height: 22px;
    background-color: var(--hairline);
    margin: 0 1rem 0 1.75rem;
    flex-shrink: 0;
}

.nav-social {
    color: var(--text-secondary);
    text-decoration: none;
    margin-left: 1rem;
    font-size: 1.2rem;
    transition: color 0.3s, transform 0.3s;
    display: inline-flex;
    align-items: center;
}

.nav-social:hover {
    color: var(--accent-color);
    transform: translateY(-2px);
}

/* Toggle buttons (theme + lang) */
.nav-toggle-btn {
    background: transparent;
    border: 1px solid var(--hairline);
    color: var(--text-secondary);
    border-radius: 8px;
    padding: 0.3rem 0.7rem;
    cursor: pointer;
    font-family: var(--font-main);
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    transition: color 0.3s, border-color 0.3s, background-color 0.3s;
    margin-left: 0.75rem;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
    white-space: nowrap;
}

html[data-theme="light"] .nav-toggle-btn {
    border-color: rgba(0, 0, 0, 0.15);
}

/* Theme toggle: amber in light mode, blue tint in dark mode */
.theme-toggle {
    color: #93c5fd;
}

html[data-theme="light"] .theme-toggle {
    color: #f59e0b;
    border-color: rgba(245, 158, 11, 0.4);
}

html[data-theme="light"] .theme-toggle:hover {
    color: #d97706;
    border-color: #d97706;
}

.nav-toggle-btn:hover {
    color: var(--accent-color);
    border-color: var(--accent-color);
    background: var(--card-bg);
}

/* Hamburger (mobile only) */
.hamburger {
    display: none;
    background: transparent;
    border: 1px solid var(--hairline);
    border-radius: 8px;
    color: var(--text-primary);
    font-size: 1.2rem;
    cursor: pointer;
    padding: 0.35rem 0.55rem;
    transition: color 0.3s, border-color 0.3s;
    flex-shrink: 0;
    margin-left: 0.75rem;
}

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

/* ==========================================================================
   4. HERO
   ========================================================================== */
.hero {
    position: relative;
    padding: 9.5rem 0 7rem;
    text-align: center;
    overflow: hidden;
}

/* Aurora wash behind the hero */
.hero::before {
    content: '';
    position: absolute;
    inset: -10% -20% auto -20%;
    height: 130%;
    background:
        radial-gradient(45% 45% at 78% 12%, var(--ambient-violet), transparent 68%),
        radial-gradient(50% 50% at 16% 22%, var(--ambient-cyan), transparent 66%),
        radial-gradient(60% 55% at 50% 100%, var(--ambient-cyan), transparent 70%);
    pointer-events: none;
    animation: aurora-drift 26s ease-in-out infinite alternate;
}

/* Fading floor line that closes the hero block */
.hero::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--hairline), var(--accent-color), var(--hairline), transparent);
    opacity: 0.5;
}

.hero .container {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.hero h1 {
    font-size: 3.2rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.06;
    margin-bottom: 0.85rem;
    background: linear-gradient(105deg, var(--text-primary) 30%, var(--accent-color) 68%, var(--accent-2));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.hero h2 {
    font-size: 1.35rem;
    font-weight: 400;
    color: var(--accent-color);
    margin-bottom: 1.25rem;
    letter-spacing: 0.01em;
}

.hero-text {
    color: var(--text-secondary);
    max-width: 560px;
    margin: 0 auto 2.5rem;
    font-size: 1.05rem;
}

.hero-logo {
    height: 280px;
    width: auto;
    margin-bottom: 1.5rem;
    filter: drop-shadow(0 0 28px var(--glow-cyan));
    display: inline-block;
    animation: logo-entrance 0.9s var(--ease-out), float 4.5s ease-in-out 0.9s infinite;
}

/* Entrance choreography for the centred hero (dashboards.html) */
.hero:not(.hero--split) .container > * {
    animation: rise-in 0.85s var(--ease-out) both;
}

.hero:not(.hero--split) .container > *:nth-child(2) { animation-delay: 0.1s; }
.hero:not(.hero--split) .container > *:nth-child(3) { animation-delay: 0.2s; }

/* ── Split hero layout (index.html) ── */
.hero--split {
    padding: 10rem 0 7.5rem;
}

.hero--split .container {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
    align-items: center;
    gap: clamp(2rem, 4.5vw, 4.5rem);
    text-align: left;
}

.hero--split .hero-copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    max-width: 40rem;
}

.hero--split .hero-logo {
    height: 120px;
    margin-bottom: 1.25rem;
}

.hero--split h1 {
    font-size: clamp(2.6rem, 5.2vw, 4.5rem);
}

.hero--split h2 {
    font-size: clamp(1.05rem, 1.55vw, 1.4rem);
    max-width: 30ch;
}

.hero--split .hero-text {
    max-width: 46ch;
    margin: 0 0 2.5rem;
}

.hero--split .cta-buttons {
    justify-content: flex-start;
}

/* Staggered first-load entrance for the copy column */
.hero--split .hero-copy > .opportunity-badge,
.hero--split .hero-copy > h1,
.hero--split .hero-copy > h2,
.hero--split .hero-copy > .hero-text,
.hero--split .hero-copy > .cta-buttons {
    animation: rise-in 0.85s var(--ease-out) both;
}

.hero--split .hero-copy > .opportunity-badge { animation-delay: 0.1s; }
.hero--split .hero-copy > h1 { animation-delay: 0.18s; }
.hero--split .hero-copy > h2 { animation-delay: 0.26s; }
.hero--split .hero-copy > .hero-text { animation-delay: 0.34s; }
.hero--split .hero-copy > .cta-buttons { animation-delay: 0.42s; }

/* ── Native SVG story: business sources → one model → one decision ──
   The geometry is inline in both hero blocks (index.html and dashboards.html
   deliberately keep a copy); every paint and every timed step lives in this
   one file so the two pages cannot drift apart. */
.hero-visual {
    position: relative;
    width: min(100%, 460px);
    aspect-ratio: 47 / 32;   /* matches the 940 × 640 story viewBox */
    margin-inline: auto;
    display: grid;
    place-items: center;
    animation: fade-scale-in 1.1s var(--ease-out) 0.15s both;
}

/* Motion: scroll-linked parallax (no transition, follows the frame loop) */
.hero-parallax {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    transform: translate3d(0, var(--hero-scroll, 0px), 0);
    opacity: var(--hero-fade, 1);
}

/* Motion: pointer depth, smoothed so it never fights the parallax owner */
.hero-depth {
    width: 100%;
    height: 100%;
    display: grid;
    place-items: center;
    transform: perspective(900px)
        translate3d(var(--hero-shift-x, 0px), var(--hero-shift-y, 0px), 0)
        rotateX(var(--hero-tilt-x, 0deg))
        rotateY(var(--hero-tilt-y, 0deg));
    transition: transform 0.55s var(--ease-out);
}

.hero-field {
    position: absolute;
    inset: 3% 2%;
    border-radius: 28px;
    background-image:
        repeating-linear-gradient(90deg, var(--field-line) 0 1px, transparent 1px 14px),
        repeating-linear-gradient(0deg, var(--field-line) 0 1px, transparent 1px 14px);
    -webkit-mask-image: radial-gradient(ellipse at 50% 50%, #000 12%, transparent 76%);
    mask-image: radial-gradient(ellipse at 50% 50%, #000 12%, transparent 76%);
    animation: field-drift 24s linear infinite;
}

.flow-art {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
    overflow: visible;
}

/* Surfaces: the model shell and the three source tiles share one treatment */
.flow-plate,
.flow-src-plate {
    fill: var(--panel-solid);
    stroke: var(--hairline);
    stroke-width: 2;
}

/* A source wakes up: its tile takes an accent tint and rim */
.flow-src-live {
    fill: var(--accent-color);
    fill-opacity: 0.1;
    stroke: var(--accent-color);
    stroke-width: 2;
    opacity: 0;
    filter: drop-shadow(0 0 10px var(--glow-cyan));
}

.flow-port { fill: var(--accent-color); }

.flow-ripple {
    fill: none;
    stroke: var(--accent-color);
    stroke-width: 3;
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
}


/* Icons: bold flat glyphs that stay readable at the mobile width */
.flow-shape { fill: var(--text-primary); }
.flow-cut { fill: var(--panel-solid); }
.flow-accent { fill: var(--accent-color); }
.flow-accent--line,
.flow-accent--axis {
    fill: none;
    stroke: var(--accent-color);
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.flow-icon--fleet .flow-accent--line { stroke-width: 2.6; stroke-dasharray: 8 6; opacity: 0.85; }
.flow-icon--doc .flow-accent--line { stroke-width: 3.4; }
.flow-icon--chart .flow-accent--axis { stroke-width: 3.6; }
.flow-icon--chart .flow-bar--1 { opacity: 0.5; }
.flow-icon--chart .flow-bar--2 { opacity: 0.75; }

/* Resting wires and the dim model mesh */
.flow-rail {
    fill: none;
    stroke: var(--accent-color);
    stroke-width: 2;
    stroke-linecap: round;
    opacity: 0.26;
}
.flow-rail--reject { stroke: var(--accent-2); opacity: 0.2; }
.flow-rail--selected { stroke-width: 3; opacity: 0.3; }

.flow-net-edge {
    stroke: var(--text-muted);
    stroke-width: 1.5;
    opacity: 0.3;
}

/* Travelling light: one short dash per wire, placed by the motion layer */
.flow-pulse {
    fill: none;
    stroke-width: 4;
    stroke-linecap: round;
    stroke-dasharray: 12 100;
    stroke-dashoffset: -46;
    stroke-opacity: 0;
    opacity: 0.95;
}
.flow-pulse--soft { stroke-width: 3; opacity: 0.4; }

/* Nodes, their activation ripple, and the committed decision */
.flow-dot {
    fill: var(--accent-color);
    opacity: 0.5;
    transform-box: fill-box;
    transform-origin: center;
}

.flow-halo {
    fill: none;
    stroke: var(--accent-2);
    stroke-width: 2;
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
}

.flow-chip {
    fill: var(--panel-solid);
    stroke: var(--hairline);
    stroke-width: 2;
}

.flow-chip-live {
    fill: var(--accent-color);
    fill-opacity: 0.12;
    stroke: var(--accent-color);
    stroke-width: 3;
    opacity: 0;
    filter: drop-shadow(0 0 14px var(--glow-cyan));
}

.flow-chip-halo {
    fill: none;
    stroke: var(--accent-color);
    stroke-width: 3;
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
}

.flow-check {
    fill: none;
    stroke: var(--accent-color);
    stroke-width: 9;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
}

.flow-reject-dot {
    fill: none;
    stroke: var(--accent-2);
    stroke-width: 3;
    opacity: 0.35;
}

.flow-stop-a { stop-color: var(--accent-color); }
.flow-stop-b { stop-color: var(--accent-2); }


/* Opportunity badge */
.opportunity-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.38rem 1rem;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-radius: 20px;
    font-size: 0.82rem;
    color: var(--accent-color);
    margin-bottom: 1.25rem;
    letter-spacing: 0.02em;
    font-weight: 600;
}

.opportunity-badge .pulse-dot {
    width: 7px;
    height: 7px;
    background: var(--accent-color);
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 10px var(--glow-cyan);
    animation: pulse-dot 2.2s ease-in-out infinite;
}

/* CTA buttons */
.cta-buttons {
    display: flex;
    gap: 1rem;
    justify-content: center;
    align-items: flex-start;
    flex-wrap: wrap;
}

.cv-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
}

.cv-hint {
    font-size: 0.72rem;
    color: var(--text-muted);
    letter-spacing: 0.02em;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.85rem 2rem;
    border-radius: 12px;
    border: 1px solid transparent;
    font-family: var(--font-main);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.3s var(--ease-out), box-shadow 0.3s, background-color 0.3s,
        border-color 0.3s, color 0.3s;
}

.btn-primary {
    background-image: linear-gradient(135deg, var(--accent-color), var(--accent-hover));
    color: var(--on-accent);
    box-shadow: 0 16px 34px -18px var(--glow-cyan);
}

.btn-primary:hover {
    transform: translateY(-3px);
    box-shadow: 0 24px 44px -18px var(--glow-cyan);
}

.btn-secondary {
    background-color: transparent;
    border-color: var(--hairline);
    color: var(--text-primary);
}

.btn-secondary:hover {
    border-color: var(--accent-color);
    color: var(--accent-color);
    transform: translateY(-3px);
    box-shadow: 0 16px 34px -22px var(--glow-cyan);
}

/* ==========================================================================
   5. SECTION HEADINGS
   ========================================================================== */
.section-title {
    font-size: clamp(1.7rem, 3.1vw, 2.4rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 3.25rem;
    text-align: center;
    color: var(--text-primary);
}

.section-title::after {
    content: '';
    display: block;
    width: 78px;
    height: 3px;
    background: linear-gradient(90deg, var(--accent-color), var(--accent-2));
    margin: 1.15rem auto 0;
    border-radius: 3px;
    box-shadow: 0 0 18px var(--glow-cyan);
}

.section-subtitle {
    text-align: center;
    color: var(--text-secondary);
    margin-bottom: 3rem;
    margin-top: -2rem;
}

/* ==========================================================================
   6. ARCHITECTURE
   ========================================================================== */
.architecture {
    position: relative;
    background-color: var(--band-surface);
    border-block: 1px solid var(--hairline);
    overflow: hidden;
}

.architecture::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 56px 56px, 56px 56px;
    -webkit-mask-image: radial-gradient(70% 80% at 50% 45%, #000, transparent 76%);
    mask-image: radial-gradient(70% 80% at 50% 45%, #000, transparent 76%);
    pointer-events: none;
    /* Motion: ambient band drifts with scroll (--section-shift written by app.js) */
    transform: translate3d(0, var(--section-shift, 0px), 0);
}

.arch-panel {
    position: relative;
    max-width: 760px;
    margin: 0 auto;
    padding: 3rem 2.5rem;
    text-align: center;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-lg);
    backdrop-filter: blur(12px);
    box-shadow: var(--shadow-card);
}

/* Corner brackets */
.arch-panel::before,
.arch-panel::after {
    content: '';
    position: absolute;
    width: 26px;
    height: 26px;
    border: 1px solid var(--accent-color);
    opacity: 0.6;
    pointer-events: none;
}

.arch-panel::before {
    top: -1px;
    left: -1px;
    border-right: none;
    border-bottom: none;
    border-radius: var(--radius-lg) 0 0 0;
}

.arch-panel::after {
    right: -1px;
    bottom: -1px;
    border-left: none;
    border-top: none;
    border-radius: 0 0 var(--radius-lg) 0;
}

.arch-lead {
    color: var(--text-secondary);
    font-size: 1.02rem;
    max-width: 52ch;
    margin: 0 auto 2rem;
}

/* ==========================================================================
   7. PROJECTS
   ========================================================================== */
.projects {
    position: relative;
    overflow: hidden;
}

.projects::before {
    content: '';
    position: absolute;
    top: -12%;
    right: -10%;
    width: 46rem;
    height: 36rem;
    background: radial-gradient(circle at 50% 50%, var(--ambient-violet), transparent 66%);
    pointer-events: none;
    /* Motion: ambient glow drifts with scroll (--section-shift written by app.js) */
    transform: translate3d(0, var(--section-shift, 0px), 0);
}

/* ── Featured project card ── */
.featured-project {
    position: relative;
    display: grid;
    grid-template-columns: 1.05fr 1.25fr;
    gap: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    background:
        linear-gradient(var(--panel-solid), var(--panel-solid)) padding-box,
        linear-gradient(125deg, var(--accent-color), var(--accent-2) 52%, transparent 90%) border-box;
    overflow: hidden;
    margin-bottom: 3.25rem;
    box-shadow: var(--shadow-card);
    transition: transform 0.45s var(--ease-out), box-shadow 0.45s;
    /* Motion: pointer depth on fine pointers (vars written by app.js) */
    transform: perspective(1400px) translateY(0)
        rotateX(var(--tilt-x, 0deg))
        rotateY(var(--tilt-y, 0deg));
}

.featured-project:hover {
    transform: perspective(1400px) translateY(-6px)
        rotateX(var(--tilt-x, 0deg))
        rotateY(var(--tilt-y, 0deg));
    box-shadow: 0 42px 80px -40px var(--glow-cyan), var(--shadow-card);
}

.featured-project .card-image {
    height: 100%;
    min-height: 320px;
    /* The 16:9 artwork is contained, so the tall column keeps a dark navy bed
       under it in both themes; light mode would otherwise show white bands. */
    background-color: var(--featured-art-bg);
}

/* The featured illustration tells its story across the full width (depot ->
   routes -> delivery points), so a `cover` crop inside the narrow two-column
   box would cut both ends of that story. `contain` keeps the whole composition
   visible and lets the card panel fill the leftover space above and below it. */
.featured-project .card-image img {
    object-fit: contain;
}

.featured-project .card-image::after {
    content: '';
    position: absolute;
    inset: 0;
    /* Only the right edge blends, because the artwork underneath is now
       contained: the last 3% is empty margin in every source illustration. */
    background: linear-gradient(90deg, transparent 97%, var(--featured-art-bg));
}

.featured-project .card-content {
    padding: 2.25rem 2.5rem;
    display: flex;
    flex-direction: column;
}

.featured-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.28rem 0.85rem;
    background: linear-gradient(120deg, var(--ambient-cyan), var(--ambient-violet));
    border: 1px solid var(--hairline);
    border-radius: 20px;
    font-size: 0.7rem;
    color: var(--accent-color);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-bottom: 0.85rem;
    align-self: flex-start;
}

.featured-project h3 {
    font-size: 1.7rem;
    letter-spacing: -0.02em;
    margin-bottom: 0.55rem;
    color: var(--text-primary);
}

.featured-project .card-header {
    font-size: 1.3rem;
    margin-bottom: 1rem;
}

.featured-project .tag {
    font-size: 0.76rem;
    margin-bottom: 1rem;
}

.featured-project p {
    flex-grow: 1;
    margin-bottom: 1.75rem;
    line-height: 1.75;
    color: var(--text-secondary);
}

/* ── Project grid ── */
.projects-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
    gap: 2rem;
}

.project-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-md);
    overflow: hidden;
    backdrop-filter: blur(12px);
    transition: transform 0.4s var(--ease-out), box-shadow 0.4s, border-color 0.4s,
        background-color 0.4s;
    /* Motion: pointer depth on fine pointers (vars written by app.js) */
    transform: perspective(1100px) translateY(0)
        rotateX(var(--tilt-x, 0deg))
        rotateY(var(--tilt-y, 0deg));
}

.project-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent-color), var(--accent-2), transparent);
    opacity: 0.35;
    transition: opacity 0.4s;
}

.project-card::after {
    content: '';
    position: absolute;
    inset: auto -20% -40% auto;
    width: 70%;
    aspect-ratio: 1 / 1;
    background: radial-gradient(circle at 50% 50%, var(--ambient-cyan), transparent 68%);
    opacity: 0;
    transition: opacity 0.45s, transform 0.45s var(--ease-out);
    pointer-events: none;
    /* Motion: glow offset follows the pointer without touching layout */
    transform: translate3d(var(--glow-x, 0px), var(--glow-y, 0px), 0);
}

.project-card:hover {
    transform: perspective(1100px) translateY(-8px)
        rotateX(var(--tilt-x, 0deg))
        rotateY(var(--tilt-y, 0deg));
    border-color: var(--accent-color);
    background: var(--card-bg-hover);
    box-shadow: 0 34px 64px -34px var(--glow-cyan), var(--shadow-card);
}

.project-card:hover::before,
.project-card:hover::after {
    opacity: 1;
}

.card-image {
    position: relative;
    width: 100%;
    height: 200px;
    overflow: hidden;
}

.card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s var(--ease-out);
}

/* Brain DS uses the project's branding illustration instead of a screenshot,
   so the whole artwork stays inside the frame; the white backdrop matches the
   illustration's own background. Scoped to this card only. */
.card-image--brand {
    background: #ffffff;
}

.card-image--brand img {
    object-fit: contain;
}

.project-card:hover .card-image img {
    transform: scale(1.06);
}

.card-content {
    padding: 1.6rem;
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    position: relative;
    z-index: 1;
}

.card-header {
    display: flex;
    gap: 1.1rem;
    margin-bottom: 1rem;
    font-size: 1.15rem;
    color: var(--accent-color);
    opacity: 0.9;
}

.project-card h3 {
    margin-bottom: 0.5rem;
    font-size: 1.2rem;
    letter-spacing: -0.01em;
    color: var(--text-primary);
}

.tag {
    display: inline-block;
    font-size: 0.72rem;
    padding: 0.24rem 0.75rem;
    background: var(--ambient-cyan);
    border: 1px solid var(--hairline);
    color: var(--accent-color);
    border-radius: 20px;
    margin-bottom: 0.95rem;
    align-self: flex-start;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.project-card p {
    color: var(--text-secondary);
    margin-bottom: 1.6rem;
    font-size: 0.91rem;
    flex-grow: 1;
    line-height: 1.65;
}

.btn-card {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 1.15rem;
    background-color: transparent;
    color: var(--text-primary);
    text-decoration: none;
    border-radius: var(--radius-sm);
    font-size: 0.87rem;
    font-weight: 600;
    border: 1px solid var(--hairline);
    align-self: flex-start;
    cursor: pointer;
    font-family: var(--font-main);
    transition: background-color 0.3s, color 0.3s, border-color 0.3s, transform 0.3s var(--ease-out);
}

.btn-card:hover {
    background-image: linear-gradient(135deg, var(--accent-color), var(--accent-hover));
    color: var(--on-accent);
    border-color: transparent;
    transform: translateY(-2px);
}

/* ==========================================================================
   8. DASHBOARDS / LAPTOP MOCKUP
   ========================================================================== */
.dashboards {
    position: relative;
    background-color: var(--band-surface);
    border-block: 1px solid var(--hairline);
    overflow: hidden;
}

.dashboards::before {
    content: '';
    position: absolute;
    inset: auto -10% -30% -10%;
    height: 70%;
    background: radial-gradient(40% 60% at 50% 100%, var(--ambient-cyan), transparent 70%);
    pointer-events: none;
    /* Motion: ambient glow drifts with scroll (--section-shift written by app.js) */
    transform: translate3d(0, var(--section-shift, 0px), 0);
}

.laptop-mockup {
    position: relative;
    max-width: 880px;
    margin: 0 auto;
}

.laptop-mockup::before {
    content: '';
    position: absolute;
    left: 6%;
    right: 6%;
    bottom: -3.5rem;
    height: 6rem;
    background: radial-gradient(50% 100% at 50% 0%, var(--glow-cyan), transparent 72%);
    filter: blur(22px);
    z-index: 0;
}

.laptop-mockup .screen {
    position: relative;
    z-index: 1;
}

.screen {
    background: #000;
    border-radius: 14px 14px 0 0;
    border: 12px solid var(--screen-border);
    border-bottom: none;
    position: relative;
    overflow: hidden;
    aspect-ratio: 16 / 10;
    box-shadow: 0 44px 80px -46px rgba(0, 0, 0, 0.95), 0 0 0 1px var(--hairline);
}

.screen img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.6s var(--ease-out);
}

.screen:hover img {
    transform: scale(1.04);
}

.screen a {
    display: block;
    width: 100%;
    height: 100%;
    position: relative;
    cursor: pointer;
}

.screen-overlay {
    font-family: var(--font-main);
    font-weight: 700;
    position: absolute;
    inset: 0;
    background: rgba(6, 10, 20, 0.68);
    display: flex;
    justify-content: center;
    align-items: center;
    color: var(--accent-color);
    font-size: 1.25rem;
    opacity: 0;
    transition: opacity 0.3s ease;
    backdrop-filter: blur(3px);
    pointer-events: none;
}

.screen a:hover .screen-overlay,
.screen a:focus-visible .screen-overlay {
    opacity: 1;
}

.keyboard {
    height: 22px;
    background: var(--keyboard-bg);
    border-radius: 0 0 14px 14px;
    position: relative;
    box-shadow: 0 20px 40px -30px rgba(0, 0, 0, 0.9);
}

.keyboard::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 110px;
    height: 7px;
    background: var(--keyboard-notch);
    border-radius: 0 0 6px 6px;
}

/* ==========================================================================
   9. CONNECT / CONTACT
   ========================================================================== */
.connect {
    position: relative;
    overflow: hidden;
}

.connect::before {
    content: '';
    position: absolute;
    inset: -20% -10% auto -10%;
    height: 120%;
    background:
        radial-gradient(38% 50% at 20% 30%, var(--ambient-violet), transparent 68%),
        radial-gradient(40% 50% at 82% 70%, var(--ambient-cyan), transparent 68%);
    pointer-events: none;
    /* Motion: ambient glow drifts with scroll (--section-shift written by app.js) */
    transform: translate3d(0, var(--section-shift, 0px), 0);
}

.connect .container {
    position: relative;
    z-index: 1;
}

.social-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1.75rem;
    margin-top: 2rem;
}

.social-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.7rem;
    padding: 2.25rem 2rem;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-md);
    text-align: center;
    text-decoration: none;
    color: var(--text-primary);
    backdrop-filter: blur(12px);
    overflow: hidden;
    transition: transform 0.4s var(--ease-out), border-color 0.4s, box-shadow 0.4s,
        background-color 0.4s;
    /* Motion: pointer depth on fine pointers (vars written by app.js) */
    transform: perspective(1100px) translateY(0)
        rotateX(var(--tilt-x, 0deg))
        rotateY(var(--tilt-y, 0deg));
}

.social-card::before {
    content: '';
    position: absolute;
    inset: -30% -10% auto -10%;
    height: 90%;
    background: radial-gradient(50% 60% at 50% 0%, var(--ambient-cyan), transparent 70%);
    opacity: 0;
    transition: opacity 0.4s, transform 0.4s var(--ease-out);
    /* Motion: glow offset follows the pointer without touching layout */
    transform: translate3d(var(--glow-x, 0px), var(--glow-y, 0px), 0);
}

.social-card:hover::before {
    opacity: 1;
}

.social-card i {
    font-size: 2.4rem;
    transition: transform 0.35s var(--ease-out), color 0.35s;
    z-index: 1;
}

.social-card span {
    font-size: 1.05rem;
    font-weight: 700;
    z-index: 1;
}

.social-card p {
    color: var(--text-secondary);
    font-size: 0.87rem;
    z-index: 1;
    margin-bottom: 0;
}

.social-card:hover {
    transform: perspective(1100px) translateY(-6px)
        rotateX(var(--tilt-x, 0deg))
        rotateY(var(--tilt-y, 0deg));
    border-color: var(--accent-color);
    background: var(--card-bg-hover);
    box-shadow: 0 30px 60px -34px var(--glow-cyan), var(--shadow-card);
}

.social-card:hover i {
    transform: scale(1.12);
    color: var(--accent-color);
}

.social-card.linkedin:hover i { color: #0077b5; }
.social-card.github:hover i { color: var(--text-primary); }
.social-card.gmail:hover i { color: #ea4335; }

/* ==========================================================================
   10. FOOTER
   ========================================================================== */
footer {
    padding: 2.25rem 0;
    text-align: center;
    border-top: 1px solid var(--hairline);
    color: var(--text-muted);
    font-size: 0.88rem;
    margin-top: 2rem;
    position: relative;
}

.footer-logo {
    width: 48px;
    height: 48px;
    object-fit: contain;
    opacity: 0.7;
    margin-bottom: 0.6rem;
    display: block;
    margin-left: auto;
    margin-right: auto;
}

/* Small footer copy needs AA contrast against the light page surface. */
html[data-theme="light"] footer { color: var(--text-secondary); }

footer::before {
    content: '';
    position: absolute;
    top: -1px;
    left: 50%;
    transform: translateX(-50%);
    width: min(420px, 70%);
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent-color), var(--accent-2), transparent);
    opacity: 0.6;
}

/* ==========================================================================
   11. MODALS
   ========================================================================== */
.modal {
    display: none;
    position: fixed;
    z-index: 2000;
    inset: 0;
    overflow: auto;
    background-color: rgba(3, 6, 14, 0.78);
    backdrop-filter: blur(8px);
}

/* Backdrop fade; the dialog itself animates through .modal-content */
.modal.is-open {
    animation: modalBackdropIn 0.3s var(--ease-out) both;
}

.modal-content {
    background-color: var(--modal-bg);
    margin: 5% auto;
    padding: 2.25rem;
    border: 1px solid var(--hairline);
    border-radius: var(--radius-lg);
    width: 88%;
    max-width: 980px;
    box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.95), 0 0 0 1px var(--hairline);
    position: relative;
    animation: modalFadeIn 0.3s var(--ease-out);
    overflow-x: auto;
}

.modal-content::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    background: linear-gradient(90deg, transparent, var(--accent-color), var(--accent-2), transparent);
}

.modal-logo {
    text-align: center;
    margin-bottom: 1.25rem;
}

.modal-logo img {
    height: 68px;
    width: auto;
    display: inline-block;
    filter: drop-shadow(0 0 18px var(--glow-cyan));
}

.modal-content h2 {
    color: var(--text-primary);
    margin-bottom: 1.5rem;
    text-align: center;
    font-size: 1.35rem;
    letter-spacing: -0.01em;
}

.close-modal {
    color: var(--text-secondary);
    font-size: 22px;
    font-weight: bold;
    cursor: pointer;
    position: absolute;
    right: 16px;
    top: 14px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--hairline);
    border-radius: 50%;
    transition: color 0.25s, border-color 0.25s, background-color 0.25s;
    line-height: 1;
    background: none;
    /* It is a real <button> now: reset the UA padding/font so the circle holds */
    padding: 0;
    font-family: var(--font-main);
}

.close-modal:hover {
    color: var(--accent-color);
    border-color: var(--accent-color);
    background: var(--card-bg);
}

/* ── Modal tabs (Causal Fillups) ── */
.modal-tabs {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--hairline);
    padding-bottom: 0.75rem;
}

.modal-tab {
    background: transparent;
    border: 1px solid var(--hairline);
    color: var(--text-secondary);
    padding: 0.45rem 1.1rem;
    border-radius: 8px;
    font-size: 0.85rem;
    font-family: var(--font-main);
    cursor: pointer;
    transition: color 0.2s, border-color 0.2s, background-color 0.2s;
    font-weight: 500;
}

.modal-tab:hover {
    border-color: var(--accent-color);
    color: var(--accent-color);
}

.modal-tab.active {
    background: var(--ambient-cyan);
    border-color: var(--accent-color);
    color: var(--accent-color);
    font-weight: 600;
}

.modal-detail-img {
    width: 100%;
    border-radius: var(--radius-sm);
    display: block;
    box-shadow: 0 20px 40px -26px rgba(0, 0, 0, 0.8);
}

.mermaid-container {
    background: var(--card-bg);
    border: var(--glass-border);
    border-radius: var(--radius-md);
    padding: 2rem;
    display: flex;
    justify-content: center;
    overflow-x: auto;
    box-shadow: var(--shadow-card);
}

.mermaid {
    width: 100%;
    display: flex;
    justify-content: center;
    min-height: 40px;
}

/* The diagram box is a keyboard-operable scroll region, so it needs a visibly
   attached focus ring; the outline is painted outside the border box and is
   therefore not clipped by this element's own scroll overflow. */
.mermaid:focus-visible {
    outline: 2px solid var(--accent-color);
    outline-offset: 6px;
    border-radius: var(--radius-sm);
}

/* ==========================================================================
   12. FLOATING CTA
   ========================================================================== */
.floating-cta {
    position: fixed;
    bottom: 2rem;
    right: 2rem;
    z-index: 900;
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.4s, transform 0.4s;
    pointer-events: none;
}

.floating-cta.visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.floating-cta-btn {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.8rem 1.4rem;
    background-image: linear-gradient(135deg, var(--accent-color), var(--accent-hover));
    color: var(--on-accent);
    border-radius: 50px;
    text-decoration: none;
    font-weight: 700;
    font-size: 0.88rem;
    box-shadow: 0 18px 34px -16px var(--glow-cyan);
    transition: transform 0.3s var(--ease-out), box-shadow 0.3s;
    white-space: nowrap;
}

.floating-cta-btn:hover {
    transform: scale(1.05);
    box-shadow: 0 24px 44px -16px var(--glow-cyan);
}

/* ==========================================================================
   13. SCROLL REVEAL
   ========================================================================== */
.reveal {
    opacity: 0;
    /* Individual transform properties (not `transform`) so the reveal can never
       override the card transforms used by hover lift and pointer depth */
    translate: 0 26px;
    scale: 0.995;
    transition: opacity 0.7s var(--ease-out), translate 0.7s var(--ease-out),
        scale 0.7s var(--ease-out);
    /* Motion: JS may sequence elements that enter in the same batch */
    transition-delay: var(--reveal-delay, 0s);
}

.reveal.visible {
    opacity: 1;
    translate: 0 0;
    scale: 1;
}

/* Existing static stagger, exposed as a variable so JS can reuse the same path */
.reveal-d1 { --reveal-delay: 0.1s; }
.reveal-d2 { --reveal-delay: 0.2s; }
.reveal-d3 { --reveal-delay: 0.3s; }

/* ==========================================================================
   14. TOAST
   ========================================================================== */
.toast {
    visibility: hidden;
    min-width: 230px;
    background-color: var(--toast-bg);
    color: var(--toast-color);
    text-align: center;
    border-radius: var(--radius-sm);
    padding: 13px 20px;
    position: fixed;
    z-index: 3000;
    left: 50%;
    bottom: 30px;
    transform: translateX(-50%) translateY(10px);
    font-size: 0.93rem;
    opacity: 0;
    transition: opacity 0.3s, transform 0.3s, bottom 0.3s;
    border: 1px solid var(--hairline);
    box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.6);
}

.toast.show {
    visibility: visible;
    opacity: 1;
    bottom: 48px;
    transform: translateX(-50%) translateY(0);
}

/* ==========================================================================
   15. DASHBOARDS PAGE (dashboards.html)
   ========================================================================== */
.dashboards-list {
    position: relative;
}

/* ── Intro panel with the in-page dashboard index ── */
.dash-intro {
    position: relative;
    max-width: 860px;
    margin: 0 auto 4rem;
    padding: 2.5rem 2.5rem 2.25rem;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-lg);
    backdrop-filter: blur(12px);
    box-shadow: var(--shadow-card);
}

/* Corner brackets: the same framing detail used by the architecture panel */
.dash-intro::before,
.dash-intro::after {
    content: '';
    position: absolute;
    width: 26px;
    height: 26px;
    border: 1px solid var(--accent-color);
    opacity: 0.6;
    pointer-events: none;
}

.dash-intro::before {
    top: -1px;
    left: -1px;
    border-right: none;
    border-bottom: none;
    border-radius: var(--radius-lg) 0 0 0;
}

.dash-intro::after {
    right: -1px;
    bottom: -1px;
    border-left: none;
    border-top: none;
    border-radius: 0 0 var(--radius-lg) 0;
}

.dash-lead {
    color: var(--text-secondary);
    font-size: 1.02rem;
    line-height: 1.75;
}

.dash-hint {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin-top: 0.9rem;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.6;
}

.dash-hint i {
    color: var(--accent-color);
    margin-top: 0.28rem;
    flex-shrink: 0;
}

.dash-jump {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 0.85rem;
    margin-top: 1.9rem;
}

.dash-chip {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.85rem 1.05rem;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    text-decoration: none;
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.4;
    transition: transform 0.3s var(--ease-out), border-color 0.3s, box-shadow 0.3s,
        background-color 0.3s;
}

.dash-chip:hover {
    transform: translateY(-3px);
    border-color: var(--accent-color);
    background: var(--card-bg-hover);
    box-shadow: 0 18px 34px -22px var(--glow-cyan);
}

.dash-chip-index,
.dashboard-index {
    font-variant-numeric: tabular-nums;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--accent-color);
    background: var(--ambient-cyan);
    border: 1px solid var(--hairline);
    border-radius: 999px;
    padding: 0.2rem 0.5rem;
    flex-shrink: 0;
}

/* ── Framed embeds ── */
.dashboard-item {
    position: relative;
    margin-bottom: 5rem;
    /* In-page jump links have to clear the fixed navbar */
    scroll-margin-top: 96px;
}

.dashboard-item:last-of-type {
    margin-bottom: 3rem;
}

/* Floor glow under each frame, mirroring the homepage laptop mockup */
.dashboard-item::after {
    content: '';
    position: absolute;
    left: 8%;
    right: 8%;
    bottom: -2.25rem;
    height: 5.5rem;
    background: radial-gradient(50% 100% at 50% 0%, var(--glow-cyan), transparent 72%);
    filter: blur(24px);
    opacity: 0.7;
    pointer-events: none;
    z-index: 0;
}

.dashboard-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    margin-bottom: 1.35rem;
}

.dashboard-head::before {
    content: '';
    display: block;
    width: 4px;
    height: 26px;
    background: linear-gradient(180deg, var(--accent-color), var(--accent-2));
    border-radius: 2px;
    box-shadow: 0 0 14px var(--glow-cyan);
    flex-shrink: 0;
}

.dashboard-title-custom {
    color: var(--text-primary);
    font-size: clamp(1.3rem, 2.4vw, 1.8rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
    margin: 0;
    /* Long dashboard names must wrap instead of pushing the header wider */
    min-width: 0;
    overflow-wrap: break-word;
}

.dashboard-source {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    white-space: nowrap;
    flex-shrink: 0;
}

.tableau-container {
    position: relative;
    z-index: 1;
    padding: 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    /* Gradient frame; the glassy fill stays on the padding box */
    background:
        linear-gradient(var(--card-bg), var(--card-bg)) padding-box,
        linear-gradient(135deg, var(--accent-color), var(--accent-2) 48%, var(--hairline) 88%) border-box;
    box-shadow: var(--shadow-card);
    backdrop-filter: blur(12px);
    /* Wide Tableau views keep their own reading scale inside this bounded
       scroll region instead of being squeezed to fit; the page itself never
       pans sideways. The region is labelled and focusable so the horizontal
       overflow is reachable by keyboard and by touch. */
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    transition: box-shadow 0.4s;
}

.tableau-container:focus-visible {
    outline: 2px solid var(--accent-color);
    outline-offset: 4px;
}

.dashboard-item:hover .tableau-container {
    box-shadow: 0 40px 74px -40px var(--glow-cyan), var(--shadow-card);
}

/* Wide-mode embeds make their own box the overflowing one.
   The third view sizes itself from the placeholder's measured width: its inline
   script switches to the wide branch above 500px and then asks the viz for
   `min-width: 1320px` (min-height 587px, max-width 1420px, max-height 887px).
   Tableau marks that placeholder `overflow: hidden` when the embed boots, so the
   1320px canvas was clipped inside the frame instead of overflowing it: 218px
   lost at desktop and 598px at tablet, with nothing for the wrapper to scroll.
   Raising the placeholder itself to the same 1320px minimum turns it into the
   box that overflows `.tableau-container`, which is already the labelled,
   focusable, horizontally scrollable region, so the full legend is reachable by
   keyboard and touch pan and the page itself still never pans sideways.

   The 587px floor keeps that to the widths where the script really chooses the
   wide branch. Measured placeholder width is the frame's inner width
   (viewport - 2rem .container padding - frame padding - 1px borders), so the
   placeholder passes 500px from 599px up with the desktop 1rem frame padding,
   and from 587px up under 768px where that padding is 0.65rem. Below the floor
   the script still picks its <=500px stacked mobile branch (100% / 827px), which
   is why the rule is never applied to phones. */
@media (min-width: 587px) {
    #viz1732851694255 {
        min-width: 1320px;
    }
}

.dash-back {
    margin-top: 1rem;
    text-align: center;
}

/* ==========================================================================
   16. ANIMATIONS
   ========================================================================== */
@keyframes logo-entrance {
    from { opacity: 0; transform: scale(0.85) translateY(18px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes rise-in {
    from { opacity: 0; transform: translateY(22px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes fade-scale-in {
    from { opacity: 0; transform: scale(0.94); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-10px); }
}

@keyframes pulse-dot {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: 0.45; transform: scale(0.75); }
}

@keyframes aurora-drift {
    from { transform: translate3d(-2%, -1%, 0) scale(1); }
    to   { transform: translate3d(2%, 2%, 0) scale(1.08); }
}

@keyframes field-drift {
    from { background-position: 0 0, 0 0; }
    to   { background-position: 14px 14px, -14px 14px; }
}

/* ══ Story motion: one 12s loop in six timed steps ═════════════════════
   Every step is a 12s animation whose activity stays inside its own cycle and
   whose position comes from --flow-delay, so the whole sequence restarts
   together instead of drifting apart:

     0.00s  the three sources wake and their ports fire
     0.05s  the first signal leaves a source and travels to the model
     1.40s  the network reacts, node by node, along the chosen path
     4.60s  three candidate paths leave the model
     5.70s  the chosen rail and the decision chip commit, the check draws
     11.4s  the story releases and the loop starts again

   Only opacity, stroke-dashoffset and transform are animated. */
@keyframes flow-src-wake {
    0%   { opacity: 0; }
    3%   { opacity: 0.95; }
    82%  { opacity: 0.95; }
    90%  { opacity: 0; }
    100% { opacity: 0; }
}

@keyframes flow-port-pop {
    0%   { opacity: 0.9; transform: scale(0.6); }
    6%   { opacity: 0;   transform: scale(3.4); }
    100% { opacity: 0;   transform: scale(3.4); }
}

@keyframes flow-send {
    0%   { stroke-dashoffset: 10;   stroke-opacity: 0; }
    3%   { stroke-opacity: 1; }
    12%  { stroke-opacity: 1; }
    15%  { stroke-dashoffset: -100; stroke-opacity: 0; }
    100% { stroke-dashoffset: -100; stroke-opacity: 0; }
}

@keyframes flow-send-soft {
    0%   { stroke-dashoffset: 10;   stroke-opacity: 0; }
    4%   { stroke-opacity: 0.9; }
    14%  { stroke-opacity: 0.9; }
    18%  { stroke-dashoffset: -100; stroke-opacity: 0; }
    100% { stroke-dashoffset: -100; stroke-opacity: 0; }
}

@keyframes flow-node-lit {
    0%   { opacity: 0.5; transform: scale(1); }
    3%   { opacity: 1;   transform: scale(1.3); }
    9%   { opacity: 1;   transform: scale(1.3); }
    24%  { opacity: 0.5; transform: scale(1); }
    100% { opacity: 0.5; transform: scale(1); }
}

@keyframes flow-node-react {
    0%   { opacity: 0; transform: scale(0.7); }
    2%   { opacity: 0.75; }
    7.5% { opacity: 0; transform: scale(2.6); }
    100% { opacity: 0; transform: scale(2.6); }
}

@keyframes flow-rail-lit {
    0%   { opacity: 0.3; }
    8%   { opacity: 1; }
    34%  { opacity: 1; }
    46%  { opacity: 0.3; }
    100% { opacity: 0.3; }
}

@keyframes flow-chip-lit {
    0%   { opacity: 0; }
    8%   { opacity: 1; }
    34%  { opacity: 1; }
    46%  { opacity: 0; }
    100% { opacity: 0; }
}

@keyframes flow-check {
    0%   { stroke-dashoffset: 100; }
    10%  { stroke-dashoffset: 0; }
    34%  { stroke-dashoffset: 0; }
    46%  { stroke-dashoffset: 100; }
    100% { stroke-dashoffset: 100; }
}


/* Sources wake; their ports fire as the first signal leaves */
.flow-src-live {
    animation: flow-src-wake 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}
.flow-ripple,
.flow-chip-halo {
    animation: flow-port-pop 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}

/* Signals and network activations travel as one short dash of light */
.flow-pulse {
    animation: flow-send 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}
.flow-pulse--soft { animation-name: flow-send-soft; }

/* Node reactions: the dot swells and brightens, a violet ripple leaves it */
.flow-node--live .flow-dot {
    animation: flow-node-lit 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}
.flow-node--live .flow-halo {
    animation: flow-node-react 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}

/* The decision: chosen rail, chip and check commit together, then release */
.flow-rail--selected {
    animation: flow-rail-lit 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}
.flow-chip-live {
    animation: flow-chip-lit 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}
.flow-check {
    animation: flow-check 12s linear infinite;
    animation-delay: var(--flow-delay, 0s);
}

/* ── Timeline: where each element sits in the 12s loop ── */
.flow-pulse--n1 { --flow-delay: 0.05s; }
.flow-pulse--n2 { --flow-delay: 0.35s; }
.flow-pulse--n3 { --flow-delay: 0.65s; }
.flow-src--a { --flow-delay: 0s; }
.flow-src--b { --flow-delay: 0.35s; }
.flow-src--c { --flow-delay: 0.7s; }
.flow-pulse--net1 { --flow-delay: 1.4s; }
.flow-node--in1 { --flow-delay: 1.5s; }
.flow-pulse--net2 { --flow-delay: 1.5s; }
.flow-node--in2 { --flow-delay: 1.8s; }
.flow-node--in3 { --flow-delay: 2.1s; }
.flow-node--h2 { --flow-delay: 2.8s; }
.flow-node--h3 { --flow-delay: 2.95s; }
.flow-pulse--net3 { --flow-delay: 3s; }
.flow-pulse--net4 { --flow-delay: 3.1s; }
.flow-node--o2 { --flow-delay: 4.5s; }
.flow-pulse--out { --flow-delay: 4.6s; }
.flow-pulse--rej1 { --flow-delay: 4.7s; }
.flow-pulse--rej2 { --flow-delay: 4.75s; }
.flow-rail--selected,
.flow-chip-live { --flow-delay: 5.7s; }
.flow-check { --flow-delay: 5.9s; }
.flow-chip-halo { --flow-delay: 6s; }


@keyframes modalFadeIn {
    from { opacity: 0; transform: translateY(-16px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes modalBackdropIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes slideDown {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   17. RESPONSIVE — TABLET
   ========================================================================== */
@media (max-width: 1024px) {
    .hero h1 { font-size: 2.8rem; }
    .hero--split h1 { font-size: clamp(2.3rem, 4.6vw, 3.1rem); }
    .nav-links-text a { margin-left: 1.35rem; }
    .nav-divider { margin: 0 0.85rem 0 1.1rem; }
    .featured-project .card-content { padding: 1.9rem; }

    /* Mermaid diagrams: below this width the dialog is narrower than the
       diagram's reading width, so shrinking it to fit renders labels at a
       squinting 6-7px. Instead the diagram keeps a coherent minimum width
       inside its own horizontal scroll box and the user pans the diagram
       itself: the dialog, its heading and the close button never move, and
       because the overflow is contained by this box the document never
       scrolls sideways. Desktop (>1024px) keeps the original fit-to-width
       rendering and is deliberately left untouched. */
    .modal .mermaid {
        display: block;
        width: 100%;
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 0.35rem;
    }

    /* `min-width` (not `width`) is what holds the scale: it outranks both
       mermaid's inline `width="100%"` attribute and its inline
       `max-width`, while the viewBox keeps the aspect ratio intact. */
    .modal .mermaid > svg {
        display: block;
        min-width: 900px;
    }
}

/* ==========================================================================
   18. RESPONSIVE — MOBILE
   ========================================================================== */
@media (max-width: 900px) {
    .hero--split .container {
        grid-template-columns: 1fr;
        text-align: center;
        gap: 2.5rem;
    }

    .hero--split .hero-copy {
        align-items: center;
        margin-inline: auto;
    }

    .hero--split .hero-text {
        margin-inline: auto;
    }

    .hero--split .cta-buttons {
        justify-content: center;
    }

    .hero-visual {
        width: min(100%, 420px);
    }
}

@media (max-width: 768px) {
    html { scroll-padding-top: 68px; }

    .navbar { padding: 0.55rem 0; }

    .navbar .container {
        flex-wrap: wrap;
        align-items: center;
    }

    .nav-logo { height: 38px; }

    /* Show hamburger on mobile */
    .hamburger { display: flex; }

    /* Hide desktop nav blocks */
    .nav-links-text,
    .nav-links-actions {
        display: none;
        width: 100%;
    }

    /* Show when menu is open */
    .nav-open .nav-links-text {
        display: flex;
        flex-direction: column;
        padding: 0.6rem;
        margin-top: 0.55rem;
        border: 1px solid var(--hairline);
        border-radius: var(--radius-md);
        background: var(--card-bg);
        backdrop-filter: blur(16px);
        box-shadow: var(--shadow-card);
        animation: slideDown 0.2s ease;
    }

    .nav-open .nav-links-actions {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 0.75rem;
        padding: 0.85rem 0.6rem 0.4rem;
    }

    .nav-open .nav-divider { display: none; }

    .nav-links-text a {
        margin: 0;
        padding: 0.65rem 0.4rem;
        font-size: 1rem;
        border-radius: 8px;
        text-align: center;
    }

    .nav-links-text a::after { display: none; }

    .nav-social { margin-left: 0; font-size: 1.4rem; }

    .nav-toggle-btn { margin-left: 0; font-size: 0.85rem; }

    /* Hero */
    .hero { padding: 7.5rem 0 4.5rem; }
    .hero--split { padding: 7.5rem 0 4.5rem; }

    .hero--split .hero-logo,
    .hero-logo {
        height: 165px;
        max-width: 74%;
        object-fit: contain;
    }

    .hero--split .hero-logo { height: 92px; }

    .hero h1 { font-size: 1.95rem; }
    .hero h2 { font-size: 1.1rem; }

    /* Kept explicit because .hero--split selectors outrank the base rules above */
    .hero--split h1 { font-size: clamp(2rem, 8.5vw, 2.6rem); }
    .hero--split h2 { font-size: 1.05rem; }

    /* Wide enough that the three business glyphs stay legible on phones;
       100% keeps it inside the container, so it can never overflow. */
    .hero-visual { width: min(100%, 340px); }

    .cta-buttons {
        flex-direction: column;
        width: 100%;
        padding: 0 0.75rem;
    }

    .btn { width: 100%; text-align: center; }
    .cv-wrapper { width: 100%; }

    /* Sections */
    section { padding: 4rem 0; }
    .section-title { margin-bottom: 2.5rem; }

    .arch-panel { padding: 2rem 1.25rem; }

    /* Projects */
    .featured-project {
        grid-template-columns: 1fr;
        margin-bottom: 2rem;
    }

    .featured-project .card-image { min-height: 220px; }

    /* No bottom fade override here: the contained artwork stops above the card
       edge, so it keeps the shared right-edge blend from the rules above. */

    .featured-project .card-content { padding: 1.5rem; }
    .featured-project h3 { font-size: 1.3rem; }
    .projects-grid { grid-template-columns: 1fr; }

    /* Dashboard mockup */
    .laptop-mockup::before { bottom: -2.5rem; }

    /* Dashboards page */
    .dash-intro {
        padding: 1.75rem 1.25rem 1.5rem;
        margin-bottom: 2.5rem;
    }

    .dash-jump {
        grid-template-columns: 1fr;
        margin-top: 1.5rem;
    }

    .dashboard-item {
        margin-bottom: 3.5rem;
        scroll-margin-top: 76px;
    }

    .dashboard-item:last-of-type { margin-bottom: 2rem; }

    .dashboard-head {
        gap: 0.7rem;
        margin-bottom: 1rem;
    }

    /* The intro panel already names the source, so the chip can go */
    .dashboard-source { display: none; }

    .tableau-container { padding: 0.65rem; }

    /* Modal */
    .modal-content {
        width: 95%;
        margin: 8% auto;
        padding: 1.25rem;
    }

    /* The scrollable Mermaid treatment lives in the <=1024px query above so
       phones and tablets share one reading scale through the whole modal. */

    /* Floating CTA — icon only on mobile */
    .floating-cta { bottom: 1.25rem; right: 1.25rem; }
    .floating-cta-btn .cta-label { display: none; }
    .floating-cta-btn { padding: 0.85rem; border-radius: 50%; }
}

/* ==========================================================================
   19. MOTION & INTERACTION LAYER
   Progressive scroll choreography and pointer depth.

   Everything here is transform/opacity only: no layout property is animated,
   and every scroll-linked value comes from custom properties written by app.js
   inside a single requestAnimationFrame pass. When motion is reduced, when JS
   is unavailable, or on coarse pointers, the declared fallbacks keep the static
   design identical to the pre-motion state.
   ========================================================================== */

/* Promote the hero layer only while the frame loop is actually writing to it */
html.motion-ok .hero-parallax {
    will-change: transform, opacity;
}

/* Promote a section band only while that section is on screen */
section.is-inview::before {
    will-change: transform;
}

/* Fast, responsive tilt while the pointer is inside a card; the slower base
   transition still owns the hover lift and the release back to rest. */
.project-card.is-tilting,
.social-card.is-tilting,
.featured-project.is-tilting {
    transition: transform 0.14s var(--ease-out), box-shadow 0.4s, border-color 0.4s,
        background-color 0.4s;
    will-change: transform;
}

/* Condensed navbar once the page has scrolled (class toggled by app.js) */
html.is-scrolled .navbar {
    padding: 0.5rem 0;
    box-shadow: 0 26px 54px -32px rgba(0, 0, 0, 0.95);
}

/* Background tabs: the frame loop stops and the decorative loops are paused */
html.is-tab-hidden .hero::before,
html.is-tab-hidden .hero-field,
html.is-tab-hidden .hero-logo,
html.is-tab-hidden .pulse-dot,
html.is-tab-hidden .flow-art * {
    animation-play-state: paused;
}

/* Modal open: freeze the page behind the dialog */
html.modal-open {
    overflow: hidden;
}

/* Tabbed modal panels are toggled through the `hidden` attribute */
.modal-tab-content[hidden] {
    display: none;
}

/* ==========================================================================
   20. ACCESSIBILITY — REDUCED MOTION
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    /* Decorative motion is fully removed, not merely shortened */
    .hero::before,
    .hero-visual,
    .hero-field,
    .hero-logo,
    .opportunity-badge .pulse-dot,
    .hero:not(.hero--split) .container > *,
    .hero--split .hero-copy > *,
    .flow-art,
    .flow-art * {
        animation: none !important;
    }

    .hero-visual,
    .hero--split .hero-copy > * {
        opacity: 1;
        transform: none;
    }

    /* Scroll-linked and pointer-linked transforms are dropped entirely, so a
       live preference change cannot leave a frozen offset behind */
    .hero-parallax,
    .hero-depth {
        opacity: 1;
        transform: none;
    }

    .navbar::after {
        transform: none;
    }

    .project-card,
    .social-card,
    .featured-project {
        transform: none;
    }

    /* The story keeps a complete final frame: light resting in every wire,
       the chosen path through the network lit and the decision taken, with no
       staged timing left to wait for. */
    .flow-pulse {
        stroke-opacity: 1;
        stroke-dashoffset: -46;
    }
    .flow-pulse--soft { opacity: 0.4; }
    .flow-src-live { opacity: 1; }
    .flow-ripple,
    .flow-chip-halo { opacity: 0; }
    .flow-node--live .flow-dot { opacity: 1; }
    .flow-node--live .flow-halo { opacity: 0.35; transform: scale(1.8); }
    .flow-rail--selected,
    .flow-chip-live { opacity: 1; }
    .flow-check { stroke-dashoffset: 0; }

    .reveal {
        opacity: 1;
        translate: none;
        scale: none;
        transform: none;
    }

    .navbar,
    .dash-intro,
    .dash-chip,
    .tableau-container,
    .hero-depth,
    .project-card,
    .social-card,
    .featured-project,
    .screen img,
    .btn,
    .btn-card,
    .close-modal,
    .modal-tab,
    .floating-cta,
    .floating-cta-btn,
    .nav-social,
    .modal-content {
        transition: none;
    }
}

/* ==========================================================================
   21. CAREER STORY / PROFILE (index.html)
   Composition A: one compact narrative lead, the current role as the primary
   panel with its three practice domains, then the earlier roles on a single
   connective rail. Everything here is static geometry plus the shared scroll
   reveal, so section 20 (prefers-reduced-motion) already renders the story
   complete and still: no keyframes, no scroll-linked value, no pointer depth.

   The education and credential column is the second child of .profile-layout,
   so the grid reserves that adjacent track from 1024px up and `> :only-child`
   keeps the timeline on the full width whenever the column is absent.
   ========================================================================== */
.profile {
    position: relative;
    overflow: hidden;
}

/* Ambient depth for this band. Deliberately not scroll-linked: the section
   needs no --section-shift entry to stay identical when motion is off. */
.profile::before {
    content: '';
    position: absolute;
    inset: -15% -10% auto -10%;
    height: 120%;
    background:
        radial-gradient(36% 46% at 16% 22%, var(--ambient-cyan), transparent 68%),
        radial-gradient(40% 50% at 86% 74%, var(--ambient-violet), transparent 70%);
    pointer-events: none;
}

.profile .container {
    position: relative;
    z-index: 1;
}

.profile-lead {
    max-width: 68ch;
    margin: -1.5rem auto 3.25rem;
    text-align: center;
    color: var(--text-secondary);
    font-size: 1.05rem;
    line-height: 1.8;
}

.profile-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 2.5rem;
    align-items: start;
}

.profile-timeline {
    /* Rail geometry. The node offset is derived from these two values, so a
       breakpoint only moves the rail and never repositions each node. */
    --profile-gutter: 40px;
    --profile-rail-x: 11px;
    position: relative;
    list-style: none;
    max-width: 860px;
    margin: 0 auto;
    padding: 0 0 0 var(--profile-gutter);
    display: grid;
    gap: 1.4rem;
}

/* The connective rail, one continuous line behind every role */
.profile-timeline::before {
    content: '';
    position: absolute;
    left: var(--profile-rail-x);
    top: 0.9rem;
    bottom: 0.9rem;
    width: 1px;
    background: linear-gradient(180deg, var(--accent-color), var(--accent-2) 55%, transparent);
    opacity: 0.35;
    pointer-events: none;
}

.profile-entry {
    position: relative;
    padding: 1.5rem 1.75rem 1.6rem;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-md);
    backdrop-filter: blur(12px);
    box-shadow: var(--shadow-card);
}

/* Timeline node, centred on the rail for both marker sizes */
.profile-entry::before {
    content: '';
    position: absolute;
    top: 1.8rem;
    left: calc(var(--profile-rail-x) - var(--profile-gutter) - 5.5px);
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--panel-solid);
    border: 1px solid var(--text-muted);
}

/* Current role: same rail, but the panel carries the emphasis */
.profile-entry--current {
    padding: 1.85rem 2rem 1.9rem;
    background: var(--card-bg-hover);
    border-color: var(--accent-color);
    box-shadow: 0 30px 66px -38px var(--glow-cyan), var(--shadow-card);
}

.profile-entry--current::before {
    top: 2.05rem;
    left: calc(var(--profile-rail-x) - var(--profile-gutter) - 6.5px);
    width: 13px;
    height: 13px;
    background: var(--accent-color);
    border-color: var(--accent-color);
    box-shadow: 0 0 0 5px var(--ambient-cyan), 0 0 16px var(--glow-cyan);
}

.profile-entry-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.55rem 0.75rem;
    margin-bottom: 0.85rem;
}

.profile-date {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--text-secondary);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
}

.profile-date-sep {
    color: var(--text-muted);
    font-weight: 400;
}

.profile-current {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.24rem 0.7rem;
    border-radius: 999px;
    background: var(--ambient-cyan);
    border: 1px solid var(--hairline);
    color: var(--accent-hover);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    white-space: nowrap;
}

.profile-current::before {
    content: '';
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent-color);
    flex-shrink: 0;
}

.profile-role {
    color: var(--text-primary);
    font-size: clamp(1.15rem, 1.5vw, 1.35rem);
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.25;
}

.profile-entry--current .profile-role {
    font-size: clamp(1.35rem, 2vw, 1.6rem);
}

.profile-org {
    margin-top: 0.2rem;
    color: var(--text-secondary);
    font-size: 0.95rem;
    font-weight: 600;
}

.profile-desc {
    max-width: 64ch;
    margin-top: 0.7rem;
    color: var(--text-secondary);
    font-size: 0.95rem;
    line-height: 1.75;
}

.profile-domains {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-top: 1.15rem;
}

.profile-domains li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.85rem;
    background: var(--band-surface);
    border: 1px solid var(--hairline);
    border-radius: 999px;
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.3;
}

.profile-domains li::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent-color), var(--accent-2));
    flex-shrink: 0;
}

/* T2 — education + credential column. It reuses the same glass panel, type
   scale and focus treatment as the timeline, but each record is a compact
   entry instead of a rail node, so the two tracks read as one family. The
   credential card is the only gradient-edged accent inside the column. */
.profile-aside {
    display: grid;
    gap: 1.4rem;
    align-content: start;
    width: 100%;
    max-width: 860px;
    margin: 0 auto;
}

.profile-aside-title {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.profile-education {
    list-style: none;
    display: grid;
    gap: 1rem;
}

.profile-edu-entry {
    position: relative;
    padding: 1.25rem 1.4rem 1.35rem;
    background: var(--card-bg);
    border: 1px solid var(--hairline);
    border-left: 3px solid var(--hairline);
    border-radius: var(--radius-md);
    backdrop-filter: blur(12px);
    box-shadow: var(--shadow-card);
}

/* In-progress degree: same accent as the current role, quieter surface */
.profile-edu-entry--current {
    background: var(--card-bg-hover);
    border-left-color: var(--accent-color);
    box-shadow: 0 30px 66px -38px var(--glow-cyan), var(--shadow-card);
}

.profile-edu-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.7rem;
    margin-bottom: 0.7rem;
}

.profile-edu-degree {
    color: var(--text-primary);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.35;
}

.profile-edu-entry--current .profile-edu-degree {
    font-size: 1.1rem;
}

.profile-edu-org {
    margin-top: 0.3rem;
    color: var(--text-secondary);
    font-size: 0.88rem;
    font-weight: 600;
}

/* Credential card: locally hosted official badge linked to its verification
   page. The card is the whole target, so the badge, title and issuer all read
   as one clickable credential. */
.profile-credential {
    position: relative;
    border-radius: var(--radius-md);
    border: 1px solid var(--accent-color);
    background: var(--card-bg-hover);
    box-shadow: 0 30px 66px -40px var(--glow-cyan), var(--shadow-card);
}

.profile-credential-link {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 1.1rem;
    padding: 1.25rem 1.4rem;
    border-radius: inherit;
    color: inherit;
    text-decoration: none;
    transition: background 0.3s var(--ease-out);
}

.profile-credential-link:hover,
.profile-credential-link:focus-visible {
    background: var(--ambient-cyan);
}

.profile-credential-badge {
    display: block;
    width: 84px;
    height: 84px;
    flex-shrink: 0;
    filter: drop-shadow(0 12px 24px var(--glow-violet));
}

.profile-credential-copy {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.profile-credential-kind {
    color: var(--accent-hover);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.profile-credential-name {
    margin-top: 0.28rem;
    color: var(--text-primary);
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
}

.profile-credential-issuer {
    margin-top: 0.2rem;
    color: var(--text-secondary);
    font-size: 0.82rem;
    line-height: 1.45;
}

.profile-credential-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.7rem;
    color: var(--accent-hover);
    font-size: 0.82rem;
    font-weight: 700;
}

.profile-credential-cta i {
    font-size: 0.7rem;
}

/* From 1024px the education + credential column takes the adjacent track
   beside the rail. `> :only-child` keeps the timeline on the full width if the
   column is ever absent, so the layout never depends on this exact child
   count. */
@media (min-width: 1024px) {
    .profile-layout {
        grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    }

    .profile-layout > :only-child {
        grid-column: 1 / -1;
    }
}

/* A fourth text link now shares the navbar, so the tablet range tightens a
   little before the hamburger takes over at 768px. The mobile disclosure panel
   is excluded on purpose: it keeps its own spacing. */
@media (min-width: 769px) and (max-width: 900px) {
    .nav-links-text a {
        margin-left: 1rem;
        font-size: 0.9rem;
    }

    .nav-divider {
        margin: 0 0.7rem 0 1rem;
    }
}

@media (max-width: 768px) {
    .profile-lead {
        margin-bottom: 2.5rem;
        font-size: 1rem;
    }

    .profile-timeline {
        --profile-gutter: 30px;
        --profile-rail-x: 9px;
        gap: 1.2rem;
    }

    .profile-entry {
        padding: 1.35rem 1.4rem 1.45rem;
    }

    .profile-entry::before {
        top: 1.62rem;
    }

    .profile-entry--current {
        padding: 1.6rem 1.5rem 1.65rem;
    }

    .profile-entry--current::before {
        top: 1.85rem;
    }

    .profile-entry--current .profile-role {
        font-size: 1.35rem;
    }

    .profile-aside {
        gap: 1.2rem;
    }

    .profile-edu-entry {
        padding: 1.15rem 1.25rem 1.25rem;
    }

    .profile-credential-link {
        padding: 1.15rem 1.25rem;
    }
}

@media (max-width: 480px) {
    .profile-timeline {
        --profile-gutter: 26px;
        --profile-rail-x: 8px;
    }

    .profile-entry,
    .profile-entry--current {
        padding: 1.25rem 1.2rem 1.3rem;
    }

    .profile-lead {
        font-size: 0.98rem;
    }

    /* Narrow chips read better stacked than wrapped mid-label */
    .profile-domains {
        flex-direction: column;
    }

    .profile-domains li {
        width: 100%;
    }

    .profile-credential-badge {
        width: 72px;
        height: 72px;
    }
}
