/* ── Self-hosted fonts (latin subsets, from Google Fonts v13/v16) ──
   Served same-origin so first paint doesn't wait on the old
   fonts.googleapis.com → fonts.gstatic.com request chain. Above-fold faces
   are additionally <link rel="preload">ed in index.html. */
@font-face {
    font-family: "Barlow";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("assets/fonts/barlow-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Barlow";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("assets/fonts/barlow-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Barlow";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("assets/fonts/barlow-600-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Barlow Condensed";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("assets/fonts/barlow-condensed-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Barlow Condensed";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("assets/fonts/barlow-condensed-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Barlow Condensed";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("assets/fonts/barlow-condensed-600-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Barlow Condensed";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("assets/fonts/barlow-condensed-700-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Bebas Neue";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("assets/fonts/bebas-neue-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "DM Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("assets/fonts/dm-mono-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}
html {
    scroll-behavior: smooth;
    /* 1rem tracks the user's own browser font-size setting × --font-scale,
       so page zoom / accessibility text-size prefs and our design scale both
       apply — every font-size in this file is in rem, so this one rule is
       the single place that scales the whole page uniformly. Note: the
       --font-scale breakpoint overrides below (max-width: 760px /
       min-width: 1440px) take precedence over this base value whenever
       their media condition matches — edit those instead if changes here
       don't seem to have an effect at a given viewport width. */
    font-size: calc(100% * var(--font-scale));
}

/* In-page anchor jumps must land clear of the fixed nav (44px tall on
   desktop), otherwise the bar covers the section heading. The 760px media
   query overrides this to 90px for the taller mobile bar. (#hero is exempt:
   it's the top of the page and the nav is hidden there.) */
#leadership,
#experience,
#projects,
#contact {
    scroll-margin-top: 72px;
}

:root {
    --logo-size: 74vmin;

    /* Palette */
    --peach: #f9a788;
    --peach-dim: rgba(249, 167, 136, 0.55);
    --mint: #a5e4c8;
    --teal: #338a65;
    --blue: #acf6f7;
    --indigo: #202253;

    /* Semantic roles */
    --body: #eaeef3;
    --dim: #6f7192;
    --heading: #f4f2f7;
    --rule: rgba(255, 255, 255, 0.09);
    --font-scale: 1.2;
    --scrim-alpha: 0.46;

    /* Gradients */
    --grad-flame: linear-gradient(
        100deg,
        #f9a788 0%,
        #a5e4c8 52%,
        #acf6f7 100%
    );
    --grad-cool: linear-gradient(100deg, #a5e4c8 0%, #338a65 55%, #acf6f7 100%);
    --grad-warm: linear-gradient(100deg, #f9a788 0%, #338a65 100%);
}

/* ─────────────────────────────────────────
   BASE
───────────────────────────────────────── */
body {
    color: var(--body);
    font-family: "Barlow", system-ui, sans-serif;
    font-size: 0.9063rem;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
    background-color: #16172d;
}

/* Aurora backdrop on a fixed pseudo-element instead of
   background-attachment: fixed — same visual, but the gradients never
   repaint during scroll. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background-image:
        radial-gradient(
            1200px 820px at 8% -8%,
            rgba(51, 138, 101, 0.4),
            transparent 58%
        ),
        radial-gradient(
            1000px 720px at 102% 8%,
            rgba(249, 167, 136, 0.3),
            transparent 55%
        ),
        radial-gradient(
            1000px 900px at 88% 104%,
            rgba(172, 214, 247, 0.26),
            transparent 60%
        ),
        radial-gradient(
            820px 680px at -4% 102%,
            rgba(165, 228, 200, 0.22),
            transparent 56%
        ),
        linear-gradient(158deg, #202253 0%, #14152b 46%, #191a34 100%);
}

/* ─────────────────────────────────────────
   HERO
───────────────────────────────────────── */
#hero {
    position: relative;
    height: 60svh;
    overflow: hidden;
}

/* Shader canvas — fills 100% of the hero, masked to the logo shape */
#shader {
    display: block;
    width: 100%;
    height: 100%;
    max-height: 60svh;
    opacity: 0; /* GSAP fades this in */
    -webkit-mask: url("assets/emlogo.svg") no-repeat center / var(--logo-size);
    mask: url("assets/emlogo.svg") no-repeat center / var(--logo-size);
}

.contact__label {
    display: inline-block;
    position: relative;
    z-index: 2;
}

/* ─────────────────────────────────────────
   RESUME — inherits aurora from body
───────────────────────────────────────── */
/*.resume-wrap {
}*/

/* Dark readability scrim over the aurora for the three main regions */
.resume-grid,
#siteHeader,
.cta-section,
.clients-section {
    position: relative;
}
#siteHeader::before,
.resume-grid::before,
.cta-section::before,
.clients-section::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background: rgba(14, 15, 32, var(--scrim-alpha, 0.46));
    pointer-events: none;
}
#siteHeader > *,
.resume-grid > *,
.cta-section > *,
.clients-section > * {
    position: relative;
    z-index: 1;
}

/* ─────────────────────────────────────────
   LAYOUT — header + résumé grid
───────────────────────────────────────── */
#siteHeader {
    z-index: 10;
    border-bottom: 1px solid var(--rule);
}
.header-inner-grid,
.resume-grid {
    max-width: 1100px;
    margin-inline: auto;
    display: grid;
    grid-template-columns: 256px 1fr;
}
.header-logo-col {
    display: flex;
    align-items: center;
    padding: 32px 20px 32px 32px;
    background: rgba(255, 255, 255, 0.028);
}
.header-logo-col > div {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 98px;
}
.header-logo-col img {
    width: 100%;
    height: auto;
    padding: 12%;
    filter: invert(1);
}
.header-name-col {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    padding: 32px 44px;
    border-left: 1px solid var(--rule);
}
.header-links {
    display: flex;
    flex-wrap: wrap;
    column-gap: 20px;
    row-gap: 4px;
    font-family: "DM Mono", monospace;
    font-size: 0.75rem;
}
.sidebar {
    display: flex;
    flex-direction: column;
    gap: 36px;
    padding: 36px 24px 56px 32px;
    background: rgba(255, 255, 255, 0.028);
    border-right: 1px solid var(--rule);
}
.skill-groups {
    display: flex;
    flex-direction: column;
    gap: 22px;
}
.main-col {
    padding: 36px 44px 56px;
}
#profile {
    margin-bottom: 36px;
}
.metrics-bar,
#leadership,
#experience {
    margin-bottom: 48px;
}

/* Visually hidden but readable by screen readers */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Section header: ALL CAPS + gradient rule ── */
.sec-head {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 1.1rem;
    font-weight: 700;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    background: var(--grad-flame);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--peach);
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 22px;
}
.sec-head::after {
    content: "";
    display: block;
    flex: 1;
    height: 1.5px;
    -webkit-text-fill-color: initial;
    background: linear-gradient(
        to right,
        rgba(249, 167, 136, 0.6),
        rgba(51, 138, 101, 0.22) 68%,
        transparent
    );
}

/* ── Header typography ── */
.header-loc {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: var(--dim);
    margin-bottom: 2px;
}
.header-name {
    font-family: "Bebas Neue", sans-serif;
    font-size: clamp(2.625rem, 6vw, 4.5rem);
    letter-spacing: 0.04em;
    color: var(--heading);
    line-height: 0.95;
    margin-bottom: 6px;
}
.header-title {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.9375rem;
    font-weight: 400;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--peach);
}

/* ── Link hover helpers (replace onmouseover JS) ── */
.header-link {
    color: var(--blue);
    text-decoration: none;
    transition: color 0.2s;
}
.header-link:hover {
    color: var(--peach);
}

.sidebar-link {
    color: var(--body);
    text-decoration: none;
    transition: color 0.2s;
}
.sidebar-link:hover {
    color: var(--peach);
}

.footer-link {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.75rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--peach);
    text-decoration: none;
    transition: color 0.2s;
}
.footer-link:hover {
    color: var(--mint);
}

/* ── Sidebar category label ── */
.sidebar-cat {
    font-family: "Barlow", sans-serif;
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--mint);
    margin-bottom: 8px;
}

/* ── Skill groups: <details>/<summary> accordion, same on desktop and
   mobile — only "Core Web" ships open. `.skill-group:not([open])` beats
   the plain `.skill-list` rule below on specificity, so closed groups
   collapse; open ones just fall through to that rule's normal
   `display: flex`. ── */
.skill-group:not([open]) > .skill-list {
    display: none;
}
.skill-group summary.sidebar-cat {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    list-style: none;
    position: relative;
    padding-right: 20px;
}
.skill-group summary.sidebar-cat::-webkit-details-marker {
    display: none;
}
.skill-group summary.sidebar-cat::marker {
    content: "";
}
.skill-group summary.sidebar-cat::after {
    content: "+";
    position: absolute;
    right: 0;
    top: -1px;
    font-family: "Barlow", sans-serif;
    font-size: 1rem;
    font-weight: 400;
    color: var(--peach);
    transition: transform 0.25s;
}
.skill-group[open] > summary.sidebar-cat::after {
    content: "\2212";
}
.skill-count {
    display: none;
}

/* ── Experience entry typography ── */
.co-role {
    font-family: "Barlow", sans-serif;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    background: var(--grad-flame);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--peach);
}
.co-date {
    font-family: "DM Mono", monospace;
    font-size: 0.6875rem;
    color: var(--blue);
    letter-spacing: 0.08em;
}

.co-header {
    display: flex;
    align-items: center;
    gap: 8px;
}

.co-name {
    font-family: "Bebas Neue", sans-serif;
    font-size: 1.5rem;
    letter-spacing: 0.06em;
    color: var(--heading);
    margin-right: 8px;
}

.co-link {
    font-family: "DM Mono", monospace;
    font-size: 0.8rem;
    color: var(--peach);
    letter-spacing: 0.08em;
}

.co-link:hover,
.co-link:focus {
    color: var(--peach);
}

/* ── Metrics bar ── */
.metrics-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    border: 1px solid var(--rule);
    border-radius: 10px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.02);
}
.metric {
    flex: 1 1 0;
    min-width: 108px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    padding: 18px 10px;
    border-right: 1px solid var(--rule);
}
.metric:last-child {
    border-right: none;
}
.metric-num {
    font-family: "Bebas Neue", sans-serif;
    font-size: 2rem;
    letter-spacing: 0.02em;
    line-height: 1;
    background: var(--grad-flame);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--peach);
}
.metric-label {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.6563rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--dim);
}

/* ── Leadership accordion ──
   Each row is its own flex container (not a shared grid track) so a card
   opening in row 1 can grow/shrink independently of row 2 — CSS Grid
   columns are shared across every row in the container, which would force
   both rows to resize together. */
.lead-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.lead-row {
    display: flex;
    gap: 12px;
}
.lead-card {
    flex: 1 1 0;
    min-width: 0;
    border: 1px solid var(--rule);
    border-radius: 8px;
    padding: 14px 16px;
    background: rgba(255, 255, 255, 0.02);
    box-shadow: 0 0 20px rgba(249, 167, 136, 0);
}
/* Specificity bump (.reveal.lead-card > .reveal) so this transition list
   wins outright — .reveal's own `transition` shorthand would otherwise
   fully replace this one instead of merging with it. */
.reveal.lead-card {
    transition:
        opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
        transform 0.6s cubic-bezier(0.16, 1, 0.3, 1),
        border-color 0.3s ease,
        background 0.3s ease,
        box-shadow 0.3s ease;
    /* flex-grow is deliberately NOT transitioned: script.js measures
       scrollHeight synchronously right after toggling [open] to compute the
       height-animation target, and needs the width (hence text wrap) to
       already be at its final value at that instant — a transitioned
       flex-grow would still be mid-animation then, so the measured height
       would be wrong (based on the pre-resize width) and visibly snap once
       the real layout takes over. Height still animates smoothly via WAAPI;
       only the width snap is instant. */
}
/* When exactly one card in a row is open, it takes the majority of the row
   and its sibling shrinks. If both or neither are open, they stay even. */
@media (min-width: 761px) {
    .lead-row:has(> .lead-card[open]):has(> .lead-card:not([open]))
        .lead-card[open] {
        flex-grow: 3;
    }
    .lead-row:has(> .lead-card[open]):has(> .lead-card:not([open]))
        .lead-card:not([open]) {
        flex-grow: 1;
    }
}
.lead-card[open] {
    border-color: var(--peach-dim);
    background: rgba(255, 255, 255, 0.04);
}
.lead-card:hover {
    border-color: var(--peach);
    background: rgba(255, 255, 255, 0.08);
    box-shadow: 0 0 20px rgba(249, 167, 136, 0.2);
}
.lead-card__trigger {
    cursor: pointer;
    list-style: none;
    font-family: "Barlow", sans-serif;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--heading);
    position: relative;
    padding-right: 22px;
}
.lead-card__trigger::-webkit-details-marker {
    display: none;
}
.lead-card__trigger::after {
    content: "+";
    position: absolute;
    right: 0;
    top: -1px;
    font-family: "Barlow", sans-serif;
    font-size: 1rem;
    color: var(--peach);
    transition: transform 0.25s;
}
.lead-card[open] .lead-card__trigger::after {
    content: "\2212";
}
.lead-card__body {
    margin-top: 10px;
    font-size: 0.875rem;
    line-height: 1.65;
    color: var(--body);
}

/* ── Project card layout ── */
.project-item {
    padding: 14px 0;
    border-bottom: 1px solid var(--rule);
}
.project-item:last-child {
    border-bottom: none;
}
/* Title row: project name left, tech tags right */
.project-item > div:first-child {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 4px;
}

/* ── Project card typography ── */
.proj-name {
    font-family: "Barlow", sans-serif;
    font-size: 0.9688rem;
    font-weight: 600;
    letter-spacing: 0.005em;
    color: var(--heading);
}
.proj-tags {
    font-family: "DM Mono", monospace;
    font-size: 0.6875rem;
    color: var(--mint);
}
.proj-desc {
    font-size: 0.875rem;
    color: var(--body);
    line-height: 1.65;
}

/* ── Project card expand ── */
.proj-more {
    margin-top: 8px;
}
.proj-more__trigger {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--blue);
    transition: color 0.2s;
}
.proj-more__trigger::-webkit-details-marker {
    display: none;
}
.proj-more__trigger::before {
    content: "+";
    font-size: 0.8125rem;
    color: var(--peach);
}
.proj-more[open] > .proj-more__trigger::before {
    content: "\2212";
}
.proj-more__trigger:hover {
    color: var(--heading);
}
.proj-more__body {
    margin-top: 8px;
    padding-left: 2px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.proj-more__body p {
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--body);
    padding-left: 12px;
}
.proj-more__label {
    font-family: "DM Mono", monospace;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mint);
    margin-right: 6px;
}

/* ── Inline highlight (strong elements) ── */
.strong-highlight {
    color: var(--heading);
    font-weight: 500;
}

/* ── Inline accent link (within body copy) ── */
.body-link {
    color: var(--peach);
    border-bottom: 1px solid rgba(249, 167, 136, 0.3);
    text-decoration: none;
}

/* ── Profile body text ── */
.profile-text {
    font-size: 0.875rem;
    line-height: 1.75;
    color: var(--body);
}

/* ── Timeline ── */
.timeline-entry {
    margin-bottom: 28px;
    padding-bottom: 28px;
    border-bottom: 1px solid var(--rule);
}
.timeline-entry:last-child {
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: none;
}
/* First row: role | date. Second row: company name | link. */
.timeline-entry > div:first-child {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 3px;
}
/* Pipe separator drawn in CSS — safe for co-date since it's a plain span,
   not a link, so there's nothing to leak styling from. */
.timeline-entry .co-date::before {
    content: "|";
    color: var(--rule);
    font-size: 0.75rem;
    margin-right: 10px;
}
/* co-link's pipe is a real span instead (see index.html), not a ::before on
   the anchor itself — a pseudo-element there would sit inside the <a>'s box
   and inherit its link styling (underline, hover color, hit area). */
.co-link__sep {
    color: var(--rule);
    font-size: 0.75rem;
}
.tl-line {
    position: relative;
    padding-left: 22px;
}
.tl-line::before {
    content: "";
    position: absolute;
    left: 0;
    top: 6px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--grad-flame);
    box-shadow: 0 0 10px rgba(249, 167, 136, 0.75);
    z-index: 1;
}
.tl-line::after {
    content: "";
    position: absolute;
    left: 4px;
    top: 18px;
    height: calc(100% - 40px);
    width: 1px;
    background: linear-gradient(
        to bottom,
        rgba(249, 167, 136, 0.45),
        rgba(51, 138, 101, 0.08)
    );
}
.timeline-entry:last-child::after {
    display: none;
}

/* ── Skill list ── */
.skill-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.skill-list li {
    position: relative;
    padding-left: 18px;
    font-family: "Barlow", sans-serif;
    font-size: 0.75rem;
    color: var(--body);
}
.skill-list li::before {
    content: "◦";
    position: absolute;
    left: 0;
    top: 0;
    color: var(--peach-dim);
    font-size: 0.75rem;
}

/* Tags/items pop in on open, each slightly after the last — same
   animation for the desktop bullet list and the mobile tag pills.
   script.js intercepts the summary click and sets [open] + adds
   .pop-in in the same synchronous handler, so the "hidden while
   waiting for its delay" state can safely live in the animation's own
   backwards fill — there's no gap left for the browser to paint an
   unanimated frame in between. `backwards` only (not `forwards`) so
   the animation stops owning opacity once done, instead of holding a
   stale value across a later close/reopen. */
@keyframes skillTagPop {
    from {
        opacity: 0;
        transform: scale(0.85);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}
.skill-list.pop-in li {
    animation: skillTagPop 0.15s ease-out backwards;
}
.skill-list.pop-in li:nth-child(1) {
    animation-delay: 0ms;
}
.skill-list.pop-in li:nth-child(2) {
    animation-delay: 25ms;
}
.skill-list.pop-in li:nth-child(3) {
    animation-delay: 50ms;
}
.skill-list.pop-in li:nth-child(4) {
    animation-delay: 75ms;
}
.skill-list.pop-in li:nth-child(5) {
    animation-delay: 100ms;
}
.skill-list.pop-in li:nth-child(6) {
    animation-delay: 125ms;
}

/* ── Experience bullets ── */
.exp-bullets {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 10px;
}
.exp-bullets li {
    position: relative;
    padding-left: 18px;
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--body);
}
.exp-bullets li::before {
    content: "◦";
    position: absolute;
    left: 0;
    top: 0;
    color: var(--peach-dim);
}

/* ── Fixed nav — hidden until user scrolls ── */
.nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 200;
    padding: 10px 48px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    opacity: 0;
    pointer-events: none;
    transition:
        opacity 0.3s,
        background 0.4s,
        border-color 0.4s;
    border-bottom: 1px solid transparent;
    overflow: hidden;
}
.nav.visible {
    opacity: 1;
    pointer-events: auto;
}
.nav.scrolled {
    background: rgba(5, 5, 5, 0.92);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border-bottom-color: var(--rule);
}
.nav__logo {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: "DM Mono", monospace;
    font-size: 0.75rem;
    letter-spacing: 0.16em;
    color: var(--body);
    text-decoration: none;
    transition: color 0.2s;
    z-index: 9;
}
.nav__logo:hover {
    color: var(--peach);
}
.nav__logo-mark {
    position: relative;
    width: 30px;
    height: 22px;
    margin-right: 16px;
    filter: invert(1);
    opacity: 0.85;
    z-index: 1;
}
.nav__links {
    display: flex;
    gap: 28px;
    list-style: none;
}
.nav__links a {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.75rem;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--body);
    text-decoration: none;
    transition: color 0.2s;
}
.nav__links a:hover {
    color: var(--peach);
}

/* ── Hamburger menu trigger (shown ≤760px, see mobile breakpoint) ── */
.nav__menu-btn {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 32px;
    height: 32px;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    z-index: 210;
}
.nav__menu-btn-bar {
    display: block;
    width: 100%;
    height: 2px;
    background: var(--heading);
    border-radius: 2px;
    transition:
        transform 0.3s,
        opacity 0.3s;
}
.nav__menu-btn[aria-expanded="true"] .nav__menu-btn-bar:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
}
.nav__menu-btn[aria-expanded="true"] .nav__menu-btn-bar:nth-child(2) {
    opacity: 0;
}
.nav__menu-btn[aria-expanded="true"] .nav__menu-btn-bar:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
}

/* ── Full-screen mobile menu overlay ── */
.mobile-menu {
    position: fixed;
    inset: 0;
    z-index: 205;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 40px;
    background: rgba(8, 8, 18, 0.98);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition:
        opacity 0.35s ease,
        transform 0.35s ease,
        visibility 0s linear 0.35s;
}
.mobile-menu.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition:
        opacity 0.35s ease,
        transform 0.35s ease;
}
.mobile-menu__close {
    position: absolute;
    top: 20px;
    right: 20px;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--body);
    font-size: 2rem;
    line-height: 1;
    transition: color 0.2s;
}
.mobile-menu__close:hover,
.mobile-menu__close:focus-visible {
    color: var(--peach);
}
.mobile-menu__brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}
.mobile-menu__mark {
    width: 40px;
    height: 40px;
    filter: invert(1);
    opacity: 0.9;
}
.mobile-menu__name {
    font-family: "Bebas Neue", sans-serif;
    font-size: 2rem;
    letter-spacing: 0.04em;
    color: var(--heading);
}
.mobile-menu__site {
    font-family: "DM Mono", monospace;
    font-size: 0.75rem;
    letter-spacing: 0.16em;
    color: var(--dim);
}
.mobile-menu__links {
    list-style: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 28px;
}
.mobile-menu__links a {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 1.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--body);
    text-decoration: none;
    transition: color 0.2s;
}
.mobile-menu__links a:hover,
.mobile-menu__links a:focus-visible {
    color: var(--peach);
}

/* Links fade up staggered, starting just as the overlay itself
   (0.35s opacity/transform transition above) finishes settling in.
   Gated on the ancestor .is-open class rather than the menu's own
   opacity/visibility, so — unlike a display:none-based reveal — the
   animation genuinely starts/stops on each toggle with no stale state
   to race against. */
@keyframes mobileMenuLinkIn {
    from {
        opacity: 0;
        transform: translateY(14px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}
.mobile-menu__links li {
    opacity: 0;
}
.mobile-menu.is-open .mobile-menu__links li {
    animation: mobileMenuLinkIn 0.4s ease-out both;
}
.mobile-menu.is-open .mobile-menu__links li:nth-child(1) {
    animation-delay: 0.3s;
}
.mobile-menu.is-open .mobile-menu__links li:nth-child(2) {
    animation-delay: 0.38s;
}
.mobile-menu.is-open .mobile-menu__links li:nth-child(3) {
    animation-delay: 0.46s;
}
.mobile-menu.is-open .mobile-menu__links li:nth-child(4) {
    animation-delay: 0.54s;
}

body.no-scroll {
    overflow: hidden;
}

/* ── Client logo marquee ── */
.clients-section {
    border-top: 1px solid var(--rule);
    padding: 56px 0;
}
.clients-section > p {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    text-align: center;
    color: var(--peach);
    margin-bottom: 32px;
}
.clients-track {
    overflow: hidden;
    -webkit-mask-image: linear-gradient(
        to right,
        transparent,
        #000 10%,
        #000 90%,
        transparent
    );
    mask-image: linear-gradient(
        to right,
        transparent,
        #000 10%,
        #000 90%,
        transparent
    );
}
.clients-track__row {
    display: flex;
    align-items: center;
    gap: 64px;
    width: max-content;
    list-style: none;
    padding: 16px 64px 16px 0;
    animation: clients-marquee 36s linear infinite;
}
.clients-track:hover .clients-track__row {
    animation-play-state: paused;
}
/* Each logo links to the client's site (the marquee pauses on hover, so the
   target holds still). The aria-hidden duplicate row repeats the links with
   tabindex="-1" so keyboard users aren't tabbed through everything twice. */
.clients-track__row li > a {
    display: block;
}
.clients-track__row li > a:focus-visible {
    outline: 2px solid var(--peach);
    outline-offset: 6px;
    border-radius: 4px;
}
.client-logo {
    position: relative;
    display: block;
    background: var(--heading);
    -webkit-mask-image: var(--logo-mask);
    mask-image: var(--logo-mask);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-position: center;
    mask-position: center;
    opacity: 0.55;
    transition:
        opacity 0.3s,
        transform 0.3s;
}
.client-logo::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--grad-flame);
    -webkit-mask-image: var(--logo-mask);
    mask-image: var(--logo-mask);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-position: center;
    mask-position: center;
    opacity: 0;
    transition: opacity 0.3s;
}
.clients-track__row li:hover .client-logo {
    opacity: 1;
    transform: scale(1.12);
}
.clients-track__row li:hover .client-logo::after {
    opacity: 1;
}

/* Per-client logo mark + proportioned size */
.logo-wildbrine {
    width: 115px;
    height: 26px;
    --logo-mask: url("assets/clients/wildbrine-logo.webp");
}
.logo-marin {
    width: 107px;
    height: 46px;
    --logo-mask: url("assets/clients/marin-french-cheese.webp");
}
.logo-gunbun {
    width: 71px;
    height: 48px;
    --logo-mask: url("assets/clients/gunbun.webp");
}
.logo-jordan {
    width: 88px;
    height: 38px;
    --logo-mask: url("assets/clients/jordan.webp");
}
.logo-cbdfx {
    width: 68px;
    height: 38px;
    --logo-mask: url("assets/clients/cbdfx.webp");
}
.logo-v13 {
    width: 61px;
    height: 48px;
    --logo-mask: url("assets/clients/v13.webp");
}
.logo-jmb {
    width: 83px;
    height: 38px;
    --logo-mask: url("assets/clients/jmb-logo.webp");
}
.logo-roe {
    width: 48px;
    height: 48px;
    --logo-mask: url("assets/clients/roe-seafood-logo-whit.webp");
}
@keyframes clients-marquee {
    from {
        transform: translateX(-50%);
    }
    to {
        transform: translateX(0%);
    }
}
@media (prefers-reduced-motion: reduce) {
    .clients-track__row {
        animation: none;
    }
}

/* ── CTA section ── */
.cta-section {
    border-top: 1px solid var(--rule);
    text-align: center;
    padding: 80px 40px;
}
.cta-section > p:first-of-type {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: var(--peach);
    margin-bottom: 16px;
}
.cta-section h2 {
    font-family: "Bebas Neue", sans-serif;
    font-size: clamp(3rem, 8vw, 6.25rem);
    letter-spacing: 0.04em;
    line-height: 1;
    color: var(--heading);
    margin-bottom: 12px;
}
.cta-section h2 + p {
    font-size: 0.9375rem;
    color: var(--body);
    margin-bottom: 44px;
}

/* ── CTA contact button ── */
.cta-section .magnetic {
    padding: 1.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ── Résumé download (secondary CTA, sits above the email button) ── */
.resume-download {
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.8125rem;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--heading);
    padding: 0.9rem 2.4rem;
    border: 1px solid var(--peach-dim);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.04);
    transition:
        border-color 0.25s,
        background 0.25s,
        box-shadow 0.25s;
}
.resume-download:hover {
    border-color: var(--peach);
    background: rgba(255, 255, 255, 0.08);
    box-shadow: 0 0 20px rgba(249, 167, 136, 0.2);
}

.contact {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.8125rem;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--heading);
    padding: 0.9rem 2.4rem;
    border-radius: 999px;
    background: var(--grad-warm);
    box-shadow:
        inset 0 1px 2px rgba(255, 255, 255, 0.3),
        0 0 20px rgba(249, 167, 136, 0.28);
    transition:
        transform 0.3s,
        box-shadow 0.3s;
}
.contact:hover {
    box-shadow:
        inset 0 1px 4px rgba(255, 255, 255, 0.55),
        0 0 32px rgba(249, 167, 136, 0.6),
        0 0 64px rgba(51, 138, 101, 0.4);
}

/* Shared icon sizing for the CTA buttons — currentColor so each icon
   just inherits its button's text color (and hover-color changes) for
   free, no separate fill rules needed per button. */
.contact svg,
.cta-social__link svg {
    width: 16px;
    height: 16px;
    fill: currentColor;
    flex-shrink: 0;
}

/* ── CTA social links (mobile-only, sidebar Contact is hidden there).
   Styled to match .resume-download's pill so all three CTA buttons —
   résumé, email, socials — read as one consistent family. ── */
.cta-social {
    display: none;
    gap: 16px;
    justify-content: center;
    margin-top: 18px;
}
.cta-social__link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: "Barlow Condensed", sans-serif;
    font-size: 0.75rem;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--heading);
    text-decoration: none;
    padding: 0.65rem 1.4rem;
    border: 1px solid var(--peach-dim);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.04);
    transition:
        border-color 0.25s,
        background 0.25s,
        box-shadow 0.25s;
}
.cta-social__link:hover {
    border-color: var(--peach);
    background: rgba(255, 255, 255, 0.08);
    box-shadow: 0 0 20px rgba(249, 167, 136, 0.2);
}

/* ── Footer ── */
.resume-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 44px;
    border-top: 1px solid var(--rule);
}
.resume-footer p {
    font-family: "DM Mono", monospace;
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    color: var(--mint);
}

/* ── Scroll reveal ── */
.reveal {
    transition:
        opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
        transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
/* The hidden state is gated on html.js (added by reveal.js AFTER it marks
   above-fold elements .is-visible). Content is therefore never hidden for
   no-JS visitors, and — critically — the LCP paragraph paints with first
   render instead of waiting for script parse/execute. The :not() keeps this
   from ever out-competing .is-visible on specificity. */
html.js .reveal:not(.is-visible) {
    opacity: 0;
    transform: translateY(14px);
}
.reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* ─────────────────────────────────────────
   RESPONSIVE
───────────────────────────────────────── */
@media (max-width: 760px) {
    :root {
        --font-scale: 1.2;
    }
    .nav {
        padding: 10px 20px;
    }
    .nav__links {
        display: none;
    }
    .nav__menu-btn {
        display: flex;
    }
    #hero {
        height: 40svh;
    }
    #leadership,
    #experience,
    #projects,
    #contact {
        scroll-margin-top: 90px;
    }
    .header-inner-grid {
        grid-template-columns: 1fr;
    }
    .header-logo-col {
        display: none;
    }
    .header-name-col {
        border-left: none;
        padding: 32px 22px;
    }

    /* Reorder: Profile → Metrics → Skills → Experience → Leadership → Selected Work */
    .resume-grid {
        display: flex;
        flex-direction: column;
        gap: 36px;
        padding: 36px 22px 56px;
    }
    .sidebar,
    .main-col {
        display: contents;
    }
    #sidebar-contact {
        display: none;
    }
    #profile,
    .metrics-bar,
    #skills,
    #leadership,
    #experience,
    #projects {
        margin-bottom: 0;
    }
    #profile {
        order: 1;
    }
    .metrics-bar {
        order: 2;
    }
    #skills {
        order: 3;
    }
    #experience {
        order: 4;
    }
    #leadership {
        order: 5;
    }
    #projects {
        order: 6;
    }

    .metrics-bar {
        flex-wrap: wrap;
    }
    .metric {
        flex: 1 1 50%;
        border-right: none;
        border-bottom: 1px solid var(--rule);
    }
    .lead-row {
        flex-direction: column;
    }
    /* .lead-card's flex: 1 1 0 (flex-basis: 0, flex-grow: 1) is meant for
       the desktop row, where it splits width evenly between two side-by-
       side cards. In this column layout that same flex-basis now targets
       height instead, so the open/closed cards get their heights
       redistributed by flex-grow (roughly an even split) instead of each
       sizing to its own content — which clips the open card's text and
       is exactly the size script.js's resize() measures via scrollHeight,
       causing the animation to jump. Cards should just stack at their
       natural content height here. */
    .lead-card {
        flex: none;
    }
    .cta-social {
        display: flex;
    }
    /* ── Skills: collapsed tag cloud. Each category is a full-width
       row (native <details>/<summary>, no JS) with its skills shown
       as tags underneath; tapping the row collapses it. ── */
    .skill-groups {
        display: flex;
        flex-direction: column;
        gap: 8px;
    }
    .skill-group {
        border: 1px solid var(--rule);
        border-radius: 6px;
        background: rgba(255, 255, 255, 0.03);
    }
    .skill-group[open] {
        border-color: var(--peach-dim);
    }
    .skill-group summary.sidebar-cat {
        margin-bottom: 0;
        padding: 12px 34px 12px 12px;
    }
    .skill-group[open] > summary.sidebar-cat {
        border-bottom: 1px solid var(--rule);
    }
    .skill-group summary.sidebar-cat::after {
        content: "+";
        position: absolute;
        right: 12px;
        top: 50%;
        transform: translateY(-52%);
        font-family: "Barlow", sans-serif;
        font-size: 1.1rem;
        font-weight: 400;
        color: var(--peach);
        transition: transform 0.25s;
    }
    .skill-group[open] > summary.sidebar-cat::after {
        content: "\2212";
    }
    .skill-count {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 1.4em;
        padding: 2px 4px;
        border-radius: 999px;
        background: rgba(0, 0, 0, 0.3);
        color: var(--body);
        font-family: "DM Mono", monospace;
        font-size: 0.85rem;
        font-weight: 400;
        letter-spacing: 0;
    }
    .skill-list {
        display: none;
    }
    .skill-group[open] .skill-list {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        gap: 6px;
        padding: 10px 12px 12px;
    }
    .skill-group .skill-list li {
        padding: 4px 10px;
        border: 1px solid rgba(165, 228, 200, 0.35);
        border-radius: 999px;
        background: rgba(165, 228, 200, 0.12);
        color: var(--mint);
    }
    .skill-group .skill-list li::before {
        content: none;
    }
    .co-role {
        width: 100%;
    }
    .co-date:before {
        display: none;
    }
    .co-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 0;
    }
    .co-name {
        width: 100%;
    }
    .co-link__sep {
        display: none;
    }
    .co-link {
        width: 100%;
        padding: 4px 0;
    }
    .project-item > div:first-child {
        flex-direction: column;
        align-items: flex-start;
        gap: 2px;
    }
    /* Client logos ~35% bigger — each keeps its own aspect ratio, so
       every logo is scaled individually rather than via one shared
       transform. */
    .logo-wildbrine {
        width: 155px;
        height: 35px;
    }
    .logo-marin {
        width: 144px;
        height: 62px;
    }
    .logo-gunbun {
        width: 96px;
        height: 65px;
    }
    .logo-jordan {
        width: 119px;
        height: 51px;
    }
    .logo-cbdfx {
        width: 92px;
        height: 51px;
    }
    .logo-v13 {
        width: 82px;
        height: 65px;
    }
    .logo-jmb {
        width: 112px;
        height: 51px;
    }
    .logo-roe {
        width: 65px;
        height: 65px;
    }
}

/* Modest bump for large desktop monitors — nothing above desktop width
   scaled up before this. */
@media (min-width: 1440px) {
    :root {
        --font-scale: 1.3;
    }
}

/* ─────────────────────────────────────────
   PRINT
───────────────────────────────────────── */
@page {
    size: letter portrait;
    margin: 0.4in 0.5in;
}
@media print {
    * {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
    #hero,
    .nav,
    .cta-section,
    .resume-footer {
        display: none !important;
    }
    .resume-wrap {
        background: #fff !important;
    }
    body {
        background: #fff !important;
        color: #1a1816 !important;
    }
    body::before,
    #siteHeader::before,
    .resume-grid::before {
        display: none !important;
    }
    .logo-fallback {
        display: block !important;
    }
    .sidebar {
        background: #f7f4f0 !important;
        border-right: 1pt solid #e0dcd6 !important;
    }
    .sec-head {
        background: none !important;
        -webkit-text-fill-color: #c85c10 !important;
        color: #c85c10 !important;
    }
    .sec-head::after {
        background: #e0dcd6 !important;
    }
    .tl-line::before {
        background: #c85c10 !important;
        box-shadow: none !important;
    }
    .tl-line::after {
        background: #ddd8d2 !important;
    }
    .exp-bullets li,
    .skill-list li {
        color: #2a2826 !important;
    }
    .co-name {
        color: #1a1816 !important;
    }
    .co-role {
        background: none !important;
        -webkit-text-fill-color: #c85c10 !important;
        color: #c85c10 !important;
    }
    .co-date {
        color: #5a5652 !important;
    }
    .proj-name {
        color: #1a1816 !important;
    }
    .proj-desc {
        color: #3a3632 !important;
    }
    .proj-tags {
        color: #7a7570 !important;
    }
    .sidebar-cat {
        color: #9a6040 !important;
    }
    .resume-grid {
        grid-template-columns: 200pt 1fr !important;
    }
    .timeline-entry,
    .project-item {
        break-inside: avoid;
    }
    .header-name {
        color: #1a1816 !important;
    }
    .header-title {
        color: #c85c10 !important;
    }
}

/* ─────────────────────────────────────────
   REDUCED MOTION
───────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    #shader {
        opacity: 1;
    }
    .skill-list.pop-in li {
        animation: none;
    }
    .mobile-menu__links li {
        opacity: 1;
        animation: none;
    }
}
