/* ==========================================================================
   about.css — About / credentials (merged from about.php + experience.php)
   --------------------------------------------------------------------------
   Requires: tokens.css, base.css (in that order, before this file).

   MERGED 2026-07-15. about.php and experience.php both carried Patents,
   Publications and Recognition. That duplication is why the patent counts
   disagreed across the site — two copies of a fact always drift. One page,
   one copy, drift impossible.

   css/experience.css is now UNUSED and can be deleted once experience.php is
   redirected. Its timeline rules live here.

   Shared from base.css — do not redefine:
     .card / .card--list / .card--wide, .rule, .subhead, .eyebrow, .lbl,
     .stitle, .pill, .btn, .container, .section-header

   Contents:
     1. Hero
     2. Lede
     3. Jump nav
     4. Section shell
     5. Career timeline
     6. Ventures / grid cards
     7. Expertise
     8. Education
     9. Patents
    10. Recognition
    11. Responsive
   ========================================================================== */


/* ==========================================================================
   1. Hero
   ========================================================================== */
.about-hero {
    position: relative;
    padding: 74px var(--space-5) 84px;
    background: var(--gradient-brand-hero);
    color: var(--color-text-inverse);
    text-align: center;
    overflow: hidden;
}

.about-hero__portrait {
    width: 210px;
    height: 210px;
    margin: 0 auto;
    object-fit: cover;
    border-radius: var(--radius-round);
    border: 4px solid var(--color-accent);
    box-shadow: var(--shadow-glow);
    position: relative;
    z-index: var(--z-base);
}

.about-hero h1 {
    font-size: var(--text-display);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-display);
    letter-spacing: var(--tracking-tight);
    color: var(--color-text-inverse);
    margin: var(--space-6) 0 0;
}

.about-hero__kicker {
    margin: var(--space-3) 0 0;
    font-family: var(--font-display);
    font-style: italic;
    font-size: 14px;
    letter-spacing: var(--tracking-wide);
    color: var(--color-accent-soft);
}


/* ==========================================================================
   2. Lede
   ========================================================================== */
.about-lede {
    max-width: var(--measure);
    margin: 0 auto;
    padding: var(--space-12) var(--container-padding-x) var(--space-6);
}

.about-lede p {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--text-lede);
    font-weight: var(--weight-medium);
    line-height: var(--leading-snug);
    color: var(--color-brand);
    text-align: center;
}


/* ==========================================================================
   2c. Back to top
   --------------------------------------------------------------------------
   The jump nav takes you down; this brings you back. It's the longest page on
   the site and had no way up.

   scroll-behavior lives on :root rather than html so it applies to the whole
   document's scrolling box, and it's scoped by the media query below so it
   never overrides someone's OS-level motion preference. Doing this in CSS
   rather than JS means the browser owns the animation and honours that
   preference for free.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
    :root {
        scroll-behavior: smooth;
    }
}

.to-top {
    position: fixed;
    right: var(--space-6);
    bottom: var(--space-6);
    z-index: var(--z-sticky);

    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);

    background: var(--gradient-brand);
    border: 1px solid var(--color-accent);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-card-hover-sm);

    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-inverse);
    text-decoration: none;

    transition:
        transform var(--duration-base) var(--ease),
        box-shadow var(--duration-base) var(--ease),
        border-color var(--duration-base) var(--ease);
}

/* [hidden] is set by the script until you've scrolled past the hero. Stated
   explicitly because `display: inline-flex` above would otherwise beat the
   browser's default [hidden] { display: none } — a class rule and the UA
   sheet aren't equal, but the property IS declared here, so it wins. This is
   the same trap as the padding shorthand in speaker.css: if you declare a
   property, you own it everywhere. */
.to-top[hidden] {
    display: none;
}

.to-top:hover,
.to-top:focus-visible {
    transform: var(--lift-sm);
    box-shadow: var(--shadow-card-hover);
    border-color: var(--color-accent-soft);
    color: var(--color-text-inverse);
}

.to-top:focus-visible {
    outline: 2px solid var(--color-accent-soft);
    outline-offset: 3px;
}

.to-top__arrow {
    font-size: 15px;
    line-height: 1;
}

@media (prefers-reduced-motion: reduce) {
    .to-top,
    .to-top:hover {
        transition: none;
        transform: none;
    }
}

/* On a phone the label costs width the thumb wants. Arrow only, circular,
   clear of the bottom edge. */
@media (max-width: 600px) {
    .to-top {
        right: var(--space-4);
        bottom: var(--space-4);
        padding: var(--space-3);
        border-radius: var(--radius-round);
    }

    .to-top__label {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}


/* ==========================================================================
   3. Jump nav
   The merged page is long — this is what makes that acceptable rather than
   punishing. Sticky under the site header.
   ========================================================================== */
.about-jump {
    position: sticky;
    top: 76px;                       /* clears .main-header */
    z-index: 90;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(8px);
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

/* The defensive block that used to live here — .about-jump { outline:0;
   box-shadow:none } plus ::before/::after { content:none } — is GONE.

   It was aimed at a "thick blue rule on nav" I could see in a screenshot and
   was guessing the source of, because I'd never been shown css/style.css. Now
   I have. There is no nav rule in it. The blue line came from style.css's
   own .about-section rule: border-top 3px solid #00bfff — the cyan top border
   of the SECTION BELOW the jump bar, not the bar itself. I was zeroing
   properties on the wrong element and would have gone on doing it.

   style.css is no longer linked from header.php, so the line is gone at
   source and the guard has nothing left to guard against.

   NO INLINE COMMENT MARKERS IN THIS BLOCK. The first version of it annotated
   that border-top line with a slash-star "style.css" note. CSS comments do
   not nest, so the inner terminator closed this block early, the parser read
   the remaining prose as CSS, and it error-recovered by swallowing the next
   rule — .about-jump ul, the flex layout for the jump bar. The nav broke.

   That is the second time in one session. The first was speaker.css, and this
   one was written INSIDE the comment documenting the first. If a code sample
   in a CSS comment needs annotating, use plain words. */

.about-jump ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-1);
    max-width: var(--container-max);
    margin: 0 auto;
    padding: var(--space-2) var(--container-padding-x);
    list-style: none;
}

.about-jump a {
    display: block;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-xs);
    font-size: 13px;
    font-weight: var(--weight-semibold);
    color: var(--color-text-muted);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--duration-fast) var(--ease),
                background-color var(--duration-fast) var(--ease);
}

.about-jump a:hover,
.about-jump a:focus-visible {
    color: var(--color-action);
    background: rgba(125, 31, 43, 0.06);
}

/* Anchor targets must clear both sticky bars, or a jump lands with the
   heading hidden underneath them. */
[id^="sec-"] {
    scroll-margin-top: 130px;
}


/* ==========================================================================
   4. Section shell
   --------------------------------------------------------------------------
   These three rules are the ONLY definition of .about-section. Keep it that
   way.

   Until 2026-07-15, css/style.css also defined .about-section — a leftover
   from the previous site:

       .about-section       { padding: 30px 20px;
                              background-color: #282c34;      <- charcoal
                              border-top: 3px solid #00bfff;  <- cyan
                              transition: transform .3s; }
       .about-section:hover { transform: scale(1.03); }

   It loaded first, so the background and padding below beat it. But `border-
   top` and `transition`/`:hover` are properties these rules never declare —
   and load order can't beat a property you don't mention. So the career and
   ventures sections carried a cyan top rule and swelled 3% under the cursor,
   from a stylesheet nobody had read.

   That cyan border is also the "thick blue rule under the jump nav" I chased
   in section 3 with an outline/box-shadow/::before guard, blaming <nav>. Wrong
   element entirely. style.css is unlinked now; both are gone at source.
   ========================================================================== */
.about-section {
    padding: var(--section-padding-y-sm) 0;
}

.about-section--tinted { background: var(--color-bg); }
.about-section--surface { background: var(--color-bg-raised); }


/* ==========================================================================
   5. Career timeline
   Ported from css/experience.css. Side is set by an explicit class, never
   :nth-child() — nth-child breaks the moment a role is added or reordered.
   ========================================================================== */
.timeline {
    position: relative;
    max-width: 1000px;
    margin: var(--space-9) auto 0;
    padding: var(--space-5) 0;
}

.timeline::before {
    content: "";
    position: absolute;
    width: 4px;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-left: -2px;
    background: var(--gradient-timeline);
}

.tl-item {
    position: relative;
    width: 50%;
    padding: var(--space-3) var(--space-9);
    margin-bottom: var(--space-12);
}

.tl-item::before {
    content: "";
    position: absolute;
    width: 24px;
    height: 24px;
    top: 15px;
    background: var(--color-bg-raised);
    border: 4px solid var(--color-accent);
    border-radius: var(--radius-round);
    box-shadow: var(--shadow-glow-sm);
    z-index: var(--z-timeline-marker);
}

.tl-item--left  { left: 0;   text-align: right; }
.tl-item--right { left: 50%; text-align: left; }
.tl-item--left::before  { right: -16px; }
.tl-item--right::before { left: -16px; }

.tl-content {
    padding: var(--space-8);
    background: var(--gradient-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    border-left: 4px solid var(--color-accent);
    box-shadow: var(--shadow-card);
    transition:
        transform var(--duration-base) var(--ease),
        box-shadow var(--duration-base) var(--ease),
        border-color var(--duration-base) var(--ease);
}

.tl-content:hover {
    transform: var(--lift-md);
    box-shadow: var(--shadow-card-hover);
    border-left-color: var(--color-action);
}

.tl-date {
    display: inline-block;
    margin-bottom: var(--space-3);
    padding: 6px 15px;
    border-radius: 20px;
    background: rgba(176, 141, 79, 0.12);
    font-size: var(--text-base);
    font-weight: var(--weight-bold);
    color: var(--color-accent);
}

.tl-content h3 {
    margin: 0 0 var(--space-2);
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: var(--weight-semibold);
    color: var(--color-brand);
}

.tl-content h4 {
    margin: 0 0 var(--space-5);
    font-family: var(--font-display);
    font-style: italic;
    font-size: var(--text-lg);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
}

/* Bullets stay left-aligned even in the right-aligned column — ragged-left
   body copy is genuinely hard to read. */
.tl-content ul {
    list-style: none;
    padding: 0;
    margin: 0;
    text-align: left;
}

.tl-content li {
    position: relative;
    padding-left: var(--space-7);
    margin-bottom: var(--space-3);
    color: var(--color-text-body);
    line-height: var(--leading-relaxed);
    font-size: 15px;
}

.tl-content li::before {
    content: "\25B8";
    position: absolute;
    left: 0;
    color: var(--color-accent);
    font-weight: var(--weight-bold);
    font-size: 1.2rem;
}

.tl-content li strong { color: var(--color-brand); }

/* Scroll reveal. [data-reveal] does the hiding; JS strips it if
   IntersectionObserver is missing, so a script failure can't hide your
   career. */
.tl-item[data-reveal] {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity var(--duration-slow) var(--ease),
        transform var(--duration-slow) var(--ease);
}

.tl-item[data-reveal].is-revealed {
    opacity: 1;
    transform: translateY(0);
}


/* ==========================================================================
   6. Ventures / grid cards
   ========================================================================== */
.about-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: var(--space-6);
    margin-top: var(--space-9);
}


/* ==========================================================================
   7. Expertise
   ========================================================================== */
.skills-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-7);
    margin-top: var(--space-9);
}

.skill-group {
    flex: 1 1 300px;
    padding: var(--space-8);
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-top: 4px solid var(--color-accent);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

.skill-group h3 {
    margin: 0 0 var(--space-5);
    padding-bottom: var(--space-3);
    border-bottom: 2px solid var(--color-border);
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: var(--weight-semibold);
    color: var(--color-brand);
}

.skill-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    list-style: none;
    padding: 0;
    margin: 0;
}


/* ==========================================================================
   8. Education
   ========================================================================== */
.edu-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-6);
    margin-top: var(--space-9);
}

.edu-card {
    flex: 1 1 320px;
    max-width: 400px;
    padding: var(--space-7);
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-accent);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    transition: transform var(--duration-base) var(--ease),
                box-shadow var(--duration-base) var(--ease);
}

.edu-card:hover {
    transform: var(--lift-sm);
    box-shadow: var(--shadow-card-hover-sm);
}

.edu-card h3 {
    margin: 0 0 6px;
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: var(--weight-semibold);
    color: var(--color-brand);
}

.edu-card h4 {
    margin: 0 0 var(--space-5);
    font-family: var(--font-display);
    font-style: italic;
    font-size: var(--text-md);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
}

.edu-card ul {
    list-style: none;
    padding: 0;
    margin: var(--space-3) 0 0;
}

.edu-card li {
    position: relative;
    padding-left: var(--space-5);
    margin-bottom: var(--space-3);
    font-size: var(--text-base);
    line-height: var(--leading-snug);
    color: var(--color-text-body);
}

.edu-card li::before {
    content: "\25C6";
    position: absolute;
    left: 0;
    color: var(--color-accent);
    font-size: 0.8rem;
}


/* ==========================================================================
   9. Patents
   ONE copy on the site now. This section is the reason for the merge.
   ========================================================================== */
.patent-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--space-5);
    margin-top: var(--space-5);
}

.patent {
    padding: var(--space-6);
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    transition: transform var(--duration-base) var(--ease),
                box-shadow var(--duration-base) var(--ease);
}

.patent:hover {
    transform: var(--lift-sm);
    box-shadow: var(--shadow-card-hover-sm);
}

/* Granted patents carry the brass edge. Status shouldn't require decoding a
   number format only a patent attorney can read. */
.patent--granted { border-top-color: var(--color-accent); }

.patent__status {
    display: inline-block;
    margin-bottom: var(--space-3);
    padding: 3px 10px;
    border-radius: 2px;
    background: rgba(176, 141, 79, 0.14);
    font-size: 10px;
    font-weight: var(--weight-black);
    letter-spacing: var(--tracking-caps);
    text-transform: uppercase;
    color: var(--color-brand);
}

.patent__status--pending {
    background: transparent;
    border: 1px solid var(--color-border);
    color: var(--color-text-muted);
}

.patent__title {
    margin: 0 0 var(--space-2);
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-tight);
    color: var(--color-brand);
}

.patent__number {
    margin: 0 0 var(--space-3);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--color-accent);
}

.patent__desc {
    margin: 0;
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    color: var(--color-text-body);
}


/* ==========================================================================
   10. Recognition
   ========================================================================== */
.rec-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: var(--space-5);
    margin-top: var(--space-9);
}

.rec {
    padding: var(--space-5);
    background: var(--gradient-surface);
    border-left: 4px solid var(--color-accent);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    transition: transform var(--duration-base) var(--ease),
                box-shadow var(--duration-base) var(--ease);
}

.rec:hover {
    transform: var(--lift-sm);
    box-shadow: var(--shadow-card-hover-sm);
}

.rec h3 {
    margin: 0 0 var(--space-2);
    font-family: var(--font-display);
    font-size: 1.1rem;
    font-weight: var(--weight-semibold);
    color: var(--color-brand);
}

.rec__date {
    display: block;
    margin-bottom: var(--space-3);
    font-family: var(--font-display);
    font-style: italic;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    color: var(--color-text-muted);
}

.rec p {
    margin: 0;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    color: var(--color-text);
}


/* ==========================================================================
   11. Responsive
   ========================================================================== */
@media (max-width: 900px) {
    .about-jump { top: 64px; }
    [id^="sec-"] { scroll-margin-top: 110px; }
}

@media (max-width: 768px) {
    .about-hero__portrait { width: 170px; height: 170px; }

    .about-grid,
    .patent-grid,
    .rec-grid {
        grid-template-columns: 1fr;
    }

    /* Timeline collapses to one column, spine to the left edge. */
    .timeline::before { left: 31px; }

    .tl-item,
    .tl-item--left,
    .tl-item--right {
        width: 100%;
        left: 0;
        text-align: left;
        padding-left: 70px;
        padding-right: var(--space-6);
    }

    .tl-item--left::before,
    .tl-item--right::before {
        right: auto;
        left: 18px;
    }

    .about-jump ul { justify-content: flex-start; }
}