/* ─────────────────────────────────────────────────────────────
   About page (template-about.php) — 2026-08-10 rebuild onto the
   site's dark Barlow Condensed system (hero pattern copied from
   archive-project.php, headshot/chart row + badge row new).
   Scoped to body.page-template-template-about-php (confirmed against the live
   site's actual rendered body class) so it can never collide with
   the older serif/light-mode About Me rules still sitting in
   style.css — those stay unscoped/global, but this file's scoped
   selectors always win on specificity regardless of load order.
   Always dark, not toggled by the site's light-mode setting —
   matches home-alt/archive-project.
   ───────────────────────────────────────────────────────────── */

body.page-template-template-about-php {
    background-color: #07030b;
}

/* CORRECTED, 2026-08-10: the previous version of this background was a
   fixed-height (620px) div — itself a second "restricted height
   container" with its own hard-coded color, the exact same shape of
   problem being fixed on #career-constellation. Its own bottom edge (a
   flat color meeting whatever's below it, at an arbitrary 620px down
   the page) was reading as a hard stripe/seam — user: "look at this
   ugly ass black stripe now that we have in the middle of this
   section." Direct user spec: "the constellation content can flow
   upward as much as it needs to. The only area where it should be
   clipped or framed by design would be the baseline. Everything else,
   let it flow."
   Fixed by anchoring this background to .about-hero-visual itself
   (which wraps #career-constellation with no bottom padding, so its own
   bottom edge IS the real baseline) via top/bottom offsets instead of a
   fixed height — bottom: 0 always lands exactly on that real baseline
   however tall the hero heading/paragraph above happens to render at
   any given viewport, and top: -100vh reaches generously far up past
   the header with no fixed cutoff of its own to create a new seam.
   Two pseudo-elements, not one: mask-image (needed for the gradient's
   falloff shape) applies to the WHOLE element it's on, so the solid
   base color and the masked animated gradient can't be one background
   layer set sharing a single mask — the solid black needs to stay fully
   opaque everywhere while only the gradient itself fades out. */
body.page-template-template-about-php .about-hero-visual {
    position: relative;
    padding: 20px 0 0;
}

body.page-template-template-about-php .about-hero-visual::before {
    content: '';
    position: absolute;
    top: -100vh;
    left: 0;
    right: 0;
    bottom: 0;
    background: #0d0713;
    z-index: -2;
    pointer-events: none;
}

/* Same animated home-alt gradient treatment used elsewhere on this page
   (see #career-constellation's own ::before for the full origin story)
   — anchored bottom-right so it's weighted toward where the real chart
   actually sits and tapers off gradually going up, rather than
   centering on an arbitrary point partway up this now-unbounded layer. */
body.page-template-template-about-php .about-hero-visual::after {
    content: '';
    position: absolute;
    top: -100vh;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(135deg, #e8321f, #a428d4, #0d5fa3, #0a9e73, #f56000, #e8321f);
    background-size: 400% 400%;
    animation: colorFlow 20s ease infinite;
    -webkit-mask-image: radial-gradient(ellipse at right bottom, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 75%);
    mask-image: radial-gradient(ellipse at right bottom, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 75%);
    opacity: 0.18975;
    z-index: -1;
    pointer-events: none;
}

/* ── Hero: heading left, deck paragraph right — same pattern as
   archive-project.php's .archive-hero ─────────────────────────── */

body.page-template-template-about-php .about-hero {
    /* Top cut to 0 (2026-08-10 user request, "lose the site-wide hero
       padding") — paired with .site-header's own height cut in style.css
       to close up the clear space above the headline. */
    padding: 0 0 20px;
    /* Originally forced this above .about-hero-visual/#career-constellation
       in paint order, REGARDLESS of DOM order (2026-08-10 fix — the
       headshot bleeding upward was rendering ON TOP of this heading
       text, not behind it, which read as broken at the time). Root cause:
       #career-constellation is position: relative AND has contain:
       layout on it, which makes IT establish its own real stacking
       context even at z-index: auto — a positioned, stacking-context-
       establishing element always paints above plain non-positioned
       in-flow content in the same containing context, regardless of
       which one comes first in the DOM. .about-hero was plain
       non-positioned content, so it always lost that comparison no
       matter what order it appeared in. Making this positioned too with
       an explicit z-index higher than #career-constellation's (auto,
       effectively 0) is what actually wins the comparison — position:
       relative alone (z-index: auto) would still have lost, since two
       z-index: auto stacking contexts break ties by DOM order, and this
       section comes BEFORE .about-hero-visual in the markup.
       .about-hero/.about-hero-inner have no background color of their
       own (confirmed) — the extended dark bg + gradient show straight
       through behind this text, nothing to clear there.
       CORRECTION, 2026-08-14: the user now wants the opposite — the
       primary headshot deliberately overlapping ON TOP of this heading.
       #career-constellation's own z-index was bumped to 3 (see its own
       comment) specifically to win against this element's z-index: 2
       again, flipping the original fix back. Left at 2 here rather than
       removed, so the win/lose comparison stays explicit and documented
       on both sides instead of silently falling back to DOM-order
       tiebreak rules. */
    position: relative;
    z-index: 2;
}

body.page-template-template-about-php .about-hero-inner {
    display: flex;
    align-items: flex-end;
    align-items: last baseline;
    justify-content: space-between;
    /* 60px -> 50px (2026-08-14 user request). justify-content:space-between
       usually distributes more space than this on wide viewports (gap
       only acts as a floor there), but gap is what the browser's own
       wrap-or-not decision is computed against — this genuinely lowers
       the combined-width threshold that forces .about-deck to wrap onto
       its own line, not just a cosmetic change to the visible spacing on
       an already-single-line row. */
    gap: 50px;
    flex-wrap: wrap;
    padding: 0 55px;
}

body.page-template-template-about-php .about-heading {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 800;
    /* 15vw -> min(7vw, 220px) (2026-08-14, superseding the 768-1366px-only
       12vw tablet tier below, which still wasn't safe at every width in
       that range — 2026-08-16 user report, .about-deck forced below the
       heading at 1280px). 1280px sits exactly where .about-deck's own
       width: min(576px, 45%) switches from its 45%-of-viewport regime to
       its flat 576px cap — a real structural pinch point, not a fluke —
       and a vw value tuned to "just barely fits" at one width can still
       fail at another untested one (1440px, 1536px, ...) with no way to
       verify every width without live measurement. The fix: one
       continuous formula for the whole >=768px range instead of tiered
       jumps, calibrated to the WORST case (narrowest width, 768px, right
       where the phone breakpoint hands off) rather than any single
       observed failure. Available width for heading+suffix relative to
       viewport width w works out to (0.55w - 160) for w <= 1280 and
       (w - 736) above it (from .about-deck's own width formula + the
       fixed 55px/side padding + 50px gap) — and critically,
       available(w)/w is monotonically increasing across the whole range
       (the fixed 160px overhead shrinks as a fraction of w; past 1280 the
       deck stops growing at all), so a vw value sized to safely fit at
       w=768 mathematically fits at every w above it too, without needing
       a tablet-only tier at all. 7vw solves comfortably under that 768px
       floor with real margin, not right at the edge of it — deliberately
       conservative since there's no way to verify the exact glyph metrics
       here without a live render. The 220px cap is a cosmetic ceiling
       only (available space grows faster than the heading past ~3100px
       viewport width, so this can never cause a wrap) — keeps it from
       ballooning on very wide/4K monitors. User's explicit call
       (2026-08-16): keep this side-by-side at every width down to the
       phone breakpoint rather than switching to a stacked layout in this
       uncertain range — "zero sense to stack if it's a device being
       viewed horizontally." */
    font-size: min(7vw, 220px);
    line-height: 0.85;
    color: #e6a533;
    text-transform: uppercase;
    margin: 0;
}

body.page-template-template-about-php .about-heading-suffix {
    /* Same 5:1 ratio to .about-heading as the old 15vw/3vw pair, scaled
       down with it — see .about-heading's own comment for the full
       derivation. */
    font-size: min(1.4vw, 44px);
    color: #f9f5ed;
    text-transform: uppercase;
    vertical-align: bottom;
    /* vertical-align: bottom sits it slightly below the big word's own
       baseline (2026-08-10 user correction) — same issue on the portfolio
       archive's .archive-heading-suffix, nudged there too. */
    position: relative;
    top: -5px;
    /* Barlow Condensed's "T" glyph carries real right-side bearing (empty
       space baked into the glyph past its visible stroke), so "ABOUT"'s
       box-edge sits well past where the "T" actually looks like it ends —
       the suffix read as floating too far away as a result (2026-08-10
       user correction). Pulled in specifically here — "WORK" on the
       portfolio page ends in "K", which doesn't have the same trailing
       whitespace, so archive-heading-suffix is left alone.
       -25px -> -12px (2026-08-14, scaled down with the heading's own
       15vw -> 7vw cut) — the pull-in amount is tuned to the "T" glyph's
       trailing whitespace at a given font-size, so it has to shrink
       proportionally with the heading or it overshoots and drags the
       suffix into the main word, same bug already hit once before at the
       phone breakpoint. */
    margin-left: -12px;
}

body.page-template-template-about-php .about-deck {
    font-family: var(--font-body);
    font-size: 20px;
    font-weight: 300;
    line-height: 1.6;
    color: #f9f5ed;
    /* Widened (2026-08-10 user correction) — the original 480px/42% cap
       was wrapping into too many short lines with an orphaned last line.
       No equivalent grid column below to track exactly (unlike the
       portfolio archive's deck, which tracks its featured row), so this
       stays a tuned fixed cap rather than a derived value.
       Cut 10% (2026-08-14 user request): at some viewport widths this was
       wide enough to force .about-hero-inner's flex-wrap (heading + deck +
       60px gap exceeding the row's width) to drop the deck to its own
       line, adding a full extra line of height to .about-hero and pushing
       the whole hero section below the fold. 640px/50% -> 576px/45%. */
    width: min(576px, 45%);
    text-align: right;
    margin: 0;
}

/* ── Headshot + Career Constellation — one unified visual
   (2026-08-10 rebuild: single section, not two side-by-side boxes —
   the chart canvas fills it and stays confined to the right-most
   portion via the JS layout's own seeding; the masked headshot PNG
   floats on top, bottom-left, on a transparent background so the
   dark section shows through around it) ─────────────────────────── */

body.page-template-template-about-php .career-constellation {
    position: relative;
    /* Side margin removed (2026-08-10 user request) — exploring running
       this full-bleed edge-to-edge, toward a possible future direction
       of making this whole section the page's above-the-fold hero. */
    /* Cut from min(620px, 62vh) (2026-08-13 user request): the section ran
       taller than the fold on a 1920x1080 display (where the flat 620px
       cap was binding) and on iPad landscape (where 62vh was binding
       instead, ~476-517px depending on model) — too tall either way to
       let the connection row/badges below peek above the fold without
       scrolling. Both terms cut by roughly the same proportion so the fix
       holds on both cited devices, not just the one the flat cap governs:
       500px is a 120px cut on 1920x1080 (was 620); 50vh is close to a
       100px cut on iPad landscape's ~820-834px viewport heights (was 62vh).
       User: fine with the headshots overlapping the H1 above as a result —
       don't add compensating clearance for that. */
    height: min(500px, 50vh);
    /* background: #0d0713 removed (2026-08-10 user request) — this was
       the actual black background the user identified directly in
       DevTools as the cause of the section still reading as boxed-in/
       framed instead of flowing continuously. */
    /* Radius matches the site-wide project-tile radius (.ha-card on
       home-alt and the portfolio archive), 2026-08-10 user request —
       border removed same request, no longer wanted now the section
       reads as a rounded tile rather than an outlined panel. */
    border-radius: 5px;
    /* overflow: hidden + contain: strict (which includes paint
       containment) removed (2026-08-10) so the headshot's scale()/
       translate() transforms can bleed past this box's edges upward.
       Real side effect: this box's own 5px
       border-radius no longer clips anything either — a headshot
       bleeding past a rounded corner shows its own square edge at the
       exact point it exits, not a rounded one. Doesn't affect the
       canvas-drawn chart nodes at all — those are bounded by the
       <canvas> element's own pixel buffer regardless of overflow, so
       this only ever un-clips the two <img> headshots.
       CORRECTION, same day: removing overflow entirely let the headshot
       bleed on ALL FOUR sides, including DOWN into the connection-row/
       badges below — user only wanted upward bleed. Plain overflow
       can't express "clip bottom/left/right but not top" (it's an
       all-sides toggle per axis), so clip-path does the asymmetric job
       instead: inset(top right bottom left), top -100vh effectively
       removes the top boundary (huge negative inset = clip starts way
       above the box, i.e. no visible clipping from above), right/bottom/
       left 0 clip hard at this box's own edges — which, now that the
       side margins are gone, are the actual browser edges. */
    clip-path: inset(-100vh 0 0 0);
    contain: layout size style;
    /* 2026-08-14 user request: the primary headshot should paint on top of
       the "ABOUT + PHILOSOPHY" heading it bleeds upward into, not behind
       it. This already establishes its own stacking context (contain:
       layout, see .about-hero's own z-index:2 comment for the full
       mechanics) — its z-index only needs to beat .about-hero's 2 to flip
       which one wins. This raises the WHOLE section (canvas, both
       headshots, ambient glow) above the heading as one atomic unit —
       stacking contexts can't be split, so there's no way to bring only
       the primary headshot forward without also lifting its siblings. In
       practice this is fine: the canvas and glow are either confined
       below where the heading text sits or faint enough (opacity ~0.18)
       not to visibly compete with it. */
    z-index: 3;
}

/* Ambient glow, EXPERIMENTAL preview (2026-08-10 user request: "what
   would it look like with the same gradient cycle as the home page
   background?") — swaps the previous flat amber radial-gradient for
   home-alt's actual animated .ha-orb-bg gradient + colorFlow keyframes
   (duplicated here rather than sharing home-alt.css, same "separate
   scoped copy per page" convention this theme already uses for
   archive-project.css/about.css relative to home-alt). mask-image
   keeps the same right-side falloff shape the flat-amber version had —
   an animated linear-gradient alone would just fill the whole box, so
   the radial mask is what keeps this reading as a glow near the chart
   rather than a wash across the entire container. Lives on a ::before
   (not the element's own background) specifically so it can sit BEHIND
   the canvas/headshots via z-index: -1 — .career-constellation's own
   base #0d0713 background still paints first regardless (an element's
   own background always precedes any descendant, negative z-index
   included), so the ordering ends up base color → this glow → canvas →
   headshot images, exactly as intended. opacity is low (0.15) since
   these are much more saturated/varied colors than flat amber even at
   partial mask alpha — tune freely, this is explicitly a first pass to
   look at, not tuned to a final value. */
body.page-template-template-about-php .career-constellation::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(135deg, #e8321f, #a428d4, #0d5fa3, #0a9e73, #f56000, #e8321f);
    background-size: 400% 400%;
    animation: colorFlow 20s ease infinite;
    -webkit-mask-image: radial-gradient(ellipse at right center, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 70%);
    mask-image: radial-gradient(ellipse at right center, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 70%);
    /* +10% on top of the prior +15% (2026-08-10 user request, to bring
       this closer to the full gradient sweep intensity behind home-alt's
       own hero/video canvas): 0.1725 * 1.1 = 0.18975. */
    opacity: 0.18975;
    pointer-events: none;
}

/* Duplicated from home-alt.css's own colorFlow keyframes verbatim — see
   that file's own extensive comment on why these exact 5 waypoints (not
   a simpler symmetric loop) are what make the sweep hit its full color
   range instead of leaving warm tones stuck out of reach in one corner. */
@keyframes colorFlow {
    0%   { background-position: 20% 20%; }
    20%  { background-position: 80% 15%; }
    40%  { background-position: 97% 93%; }
    60%  { background-position: 50% 90%; }
    80%  { background-position: 10% 70%; }
    100% { background-position: 20% 20%; }
}

body.page-template-template-about-php .career-constellation canvas {
    display: block;
    width: 100%;
    height: 100%;
}

body.page-template-template-about-php .about-headshot-bg {
    /* Ambient blown-up duplicate of the same masked headshot, sitting
       behind the sharp foreground copy (z-index 0 vs. its 1) — 1.7x
       scale (2026-08-10, cut from an initial 2x per user request), low
       opacity, panning gently opposite the cursor (js/about-
       constellation.js's headshot-bg parallax block, "cursor as camera")
       so it reads as ambient depth rather than a second real photo.
       Uses the exact same box/sizing rules as .about-headshot-masked
       below (left/bottom/height/max-width/object-fit/object-position all
       identical) so both copies of the photo render at the same size and
       position before any transform — anchoring the scale's own
       transform-origin to a specific point in the image (his right ear,
       2026-08-10 user request) only works because both boxes are
       pixel-identical to start; if this box's sizing rules ever drift
       from the primary headshot's, the anchor point drifts with it. left
       is 200px, not 0, to match .about-headshot-masked's own 200px
       (2026-08-10 user request, "move the headshots as a group right
       100px" — nudged the prior 100px right by that much). */
    position: absolute;
    left: 200px;
    bottom: 0;
    height: 100%;
    width: auto;
    max-width: 55%;
    object-fit: contain;
    object-position: bottom left;
    opacity: 0.18;
    z-index: 0;
    pointer-events: none;
    /* RESET to center (2026-08-10) — the prior 69%/33% was hand-tuned to
       the previous version of jbd-headshot-masked-2.png (728x821,
       portrait-ish). The user replaced that file with a re-extended-
       sides version (588x495, much more landscape) so the old percentage
       points at a totally different part of the image now. Starting
       clean at dead-center rather than guessing new coordinates blind —
       expect this to need the same live-tuning pass as before. */
    transform-origin: 50% 50%;
    /* Static -230px/50px (2026-08-10 user request, "nudge left 70px"
       moved the prior -160px left by that much). --hb-x/--hb-y (px)
       are still written every frame by the JS parallax loop on top of
       this. */
    --hb-x: 0px;
    --hb-y: 0px;
    /* Scale cut 5% (2026-08-10 user request): 1.445 * 0.95 = 1.37275. */
    transform: translate(calc(-230px + var(--hb-x)), calc(50px + var(--hb-y))) scale(1.37275);
}

body.page-template-template-about-php .about-headshot-masked {
    position: absolute;
    /* 200px, not 0 — 2026-08-10 user request to slide both headshots
       right as a group (100px, then another 100px same-day follow-up);
       .about-headshot-bg's own left is kept matching at 200px. */
    left: 200px;
    bottom: 0;
    height: 100%;
    width: auto;
    max-width: 55%;
    object-fit: contain;
    object-position: bottom left;
    z-index: 1;
    /* +15% (2026-08-14 user request). Origin is the box's own bottom-left
       corner (matching object-position: bottom left, where the figure's
       feet are already planted) so the scale grows the image up and to
       the right from that fixed point, rather than lifting it off the
       floor the way a default center-origin scale would. Explicitly
       reset in the mobile breakpoint below — this rule isn't scoped to
       desktop, and the mobile layout switches this element to
       position: static in normal flow, where an inherited scale would
       just enlarge it in place rather than doing nothing useful. */
    transform-origin: left bottom;
    transform: scale(1.15);
    /* Mouse events pass through to the canvas underneath even where the
       image is opaque — the chart's own nodes stay clear of this area
       anyway, but this is a free safety net. */
    pointer-events: none;
    /* drop-shadow (not box-shadow) follows the PNG's actual alpha
       silhouette rather than its rectangular box — a real shadow behind
       the person, not behind a transparent square (2026-08-10 user
       request). blur(0.4px) runs first in the filter chain, so the
       drop-shadow is computed from the already-softened result — a mild
       attempt at the hair-edge question below, not a real fix (see
       comment underneath): it takes the harshest edge of the jagged
       cutout mask down a notch, but it can't add back hair detail the
       matte itself lost. If the hair edges still read as too hard-cut
       once this is live, the actual fix has to happen at the image
       level (better edge refinement in the original matte/rotoscope,
       not more CSS layered on top of it). */
    filter: blur(0.4px) drop-shadow(0 12px 28px rgba(0, 0, 0, 0.45));
}

/* Mobile fallback list — hidden by default, shown by JS in place of the
   canvas below the 768px breakpoint used for other desktop-only site
   features (see home-alt.css/archive-project.css). */
body.page-template-template-about-php .constellation-fallback-list {
    display: none;
}

/* ── Connection caption — separate row below the chart. The amber bar
   grows to match the current caption text's own rendered width (set
   inline by JS on every hover-state change), animated at the same
   0.3s ease-out timing as the site's existing badge/logo hover-wobble
   system (2026-08-10 user request: new motion should match the
   established system, not invent new easing). ─────────────────────── */

body.page-template-template-about-php .about-connection-row {
    /* 20px 0 40px -> 18px 0 26px (2026-08-14 user request) — tighter
       clearance above and below so the row reads more connected to the
       chart above it and the badges below, and brings more of the badges
       above the fold. */
    padding: 18px 0 26px;
}

body.page-template-template-about-php .about-connection-inner {
    /* Bar and text are independently anchored (left/right) via absolute
       positioning, not flex siblings (2026-08-10 fix — see below for why).
       Height comes from min-height since absolutely-positioned children
       don't contribute to flow height on their own. */
    position: relative;
    /* 48px = .connection-text's own line-height (1.5 * 32px) now that
       it's Barlow Condensed 32px, not Inter 16px (2026-08-10) — was 24px
       to match the old text's shorter line box. */
    min-height: 48px;
    padding: 0 55px;
    /* Hard guarantee against page-level horizontal scroll (2026-08-10
       user-reported bug) — nothing inside this row can ever visually
       spill past its own edge, no matter what the width math below
       computes. */
    overflow: hidden;
}

body.page-template-template-about-php .connection-bar {
    display: block;
    /* Absolutely positioned and pinned to the row's own left edge, fully
       independent of the text's position (2026-08-10 fix — see
       .connection-text below for the bug this solves). Free to grow/
       shrink via the width transition without moving anything else.
       left/top offsets for an absolutely-positioned child measure from
       the ancestor's padding EDGE (its outer boundary) — not from where
       that padding pushes content in — so this has to match the 55px
       inset explicitly (`left: 0` here would sit flush with the true
       page edge, ignoring .about-connection-inner's own padding: 0 55px
       entirely; same real bug just fixed in .connection-text below). */
    position: absolute;
    left: 55px;
    top: 50%;
    transform: translateY(-50%);
    height: 18px;
    width: 0;
    background: #e6a533;
    border-radius: 999px;
    transition: width 0.3s ease-out;
}

body.page-template-template-about-php .connection-text {
    /* Barlow Condensed Light, 32px (2026-08-10 user request, up from
       Inter 16px) — weight 300 now actually loads Light rather than
       silently falling back to whatever weight was enqueued (see the
       jacefolio-barlow-condensed enqueue in functions.php). */
    font-family: 'Barlow Condensed', sans-serif;
    font-size: 32px;
    font-weight: 300;
    line-height: 1.5;
    color: #f9f5ed;
    text-align: right;
    margin: 0;
    /* Pinned to the row's right edge via absolute positioning, never a
       flex sibling of the bar (2026-08-10 fix). Previously the bar and
       text were flex siblings sharing one row — animating the bar's
       width (transition: width 0.3s) physically pushed/pulled the text
       along with it as the row reflowed, which read as the caption text
       "sliding in from off screen" every time the hovered node changed.
       Anchoring both independently means the bar can grow/shrink freely
       while the text stays pixel-locked to the right edge. Offset is
       55px, not 0 — matches .connection-bar's own left offset, see its
       comment for why this can't just be 0 against the padding. */
    position: absolute;
    right: 55px;
    top: 50%;
    transform: translateY(-50%);
    /* Single line — the JS measures this element's own rendered width
       every time its text changes to compute how much space the bar
       should fill; wrapping to a second line would break that math. A
       max-width is set inline by JS (2026-08-10 fix for a real overflow
       bug: long text was pushing the row past the page's own edge,
       causing horizontal scroll) — truncates with an ellipsis instead of
       ever exceeding its allotted space. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── Discipline badge row ──────────────────────────────────────── */

body.page-template-template-about-php .about-badge-row {
    padding: 0 0 60px;
}

body.page-template-template-about-php .about-badge-inner {
    display: flex;
    /* wrap + center (2026-08-16), was: justify-content: space-between; no
       flex-wrap; padding: 0 155px. Same failure mode as .about-heading's
       own fix above: 8 badges at up to max-width:135px each + 7 gaps
       needs ~1192px, which the 155px/side padding can eat past on
       ordinary laptop widths, not just narrow tablets — this had already
       needed a wrap+center override at the 768-1366px tablet tier
       (2026-08-14) for a different reported symptom ("right aligned"),
       which was really the same underlying no-wrap overflow. Wrapping is
       a genuinely safe fix here (unlike the heading/paragraph case) — an
       icon row breaking into two centered rows still reads as
       intentional, there's no text-reading-order concern — so this is
       just made universal instead of re-deriving another width-specific
       threshold. */
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 16px;
    padding: 0 40px;
}

body.page-template-template-about-php .about-badge {
    flex: 1 1 0;
    width: 100%;
    max-width: 135px;
    height: auto;
    filter: saturate(0.45) brightness(0.65);
    transition: transform 0.2s ease, filter 0.3s ease;
    cursor: default;
}

/* Same wobble keyframes/timings as home-alt's logo hover wobble
   (ha-icon-wobble-in, 0.3s ease-out, holds on hover, eases back via the
   transition above on mouseleave) — duplicated here rather than shared,
   same pattern archive-project.css already uses for its own copies.
   badge-wobble-in is also the same class already toggled by JS whenever
   this badge's discipline is hovered via the chart node directly (not
   just the badge itself), so keying full color off it covers both
   hover paths for free — no separate node->badge color hook needed. */
body.page-template-template-about-php .about-badge.badge-wobble-in {
    filter: saturate(1) brightness(1);
    animation: about-icon-wobble-in 0.3s ease-out forwards;
}

@keyframes about-icon-wobble-in {
    0%   { transform: scale(1) rotate(0deg); }
    60%  { transform: scale(1.12) rotate(-4deg); }
    100% { transform: scale(1.08) rotate(0deg); }
}

/* Bigger "jump wiggle" — only for the two triggers that light up the
   WHOLE badge row at once (Experience badge, Leadership badge/node,
   2026-08-10 user request: "a different type of jump grow pattern...
   only for those two"). badge-jump-in is added alongside badge-wobble-in
   (not instead of) so it wins on specificity (3 classes > 2) while
   badge-wobble-in still carries the color/brightness reveal for both
   cases. JS staggers each badge's own animation-delay so the row jumps
   in sporadically, not in lockstep.
   2026-08-10 correction: the first version of this used independent
   scaleX/scaleY squash-stretch plus a sharp translateY spike (0 to -24px
   back to -4px within 20% of the duration) on a cubic-bezier "back out"
   timing function that itself overshoots — two stacked overshoots plus
   several axes reversing direction abruptly read as glitchy/rigid, not
   fluid. User: "it needs to be gloopy and fluid... never any jerkiness,"
   pointing at the sticky-header logo's own drop-in wobble
   (ha-icon-wobble in home-alt.css) as the reference for what reads as
   smooth. Rebuilt on that same shape: ONE uniform `scale()` (no
   independent X/Y squash), a single continuous `ease-out` timing
   function (no back-out bezier compounding the keyframe overshoot),
   and every peak (scale, rotate, and the new translateY jump) decaying
   smoothly toward the resting value like a settling spring, instead of
   snapping between unrelated extremes. */
body.page-template-template-about-php .about-badge.badge-wobble-in.badge-jump-in {
    animation: about-badge-jump-in 0.65s ease-out forwards;
}

@keyframes about-badge-jump-in {
    0%   { transform: translateY(0) scale(1) rotate(0deg); }
    28%  { transform: translateY(-20px) scale(1.22) rotate(-7deg); }
    48%  { transform: translateY(-4px) scale(1.08) rotate(5deg); }
    68%  { transform: translateY(-10px) scale(1.14) rotate(-3deg); }
    86%  { transform: translateY(-1px) scale(1.03) rotate(1deg); }
    100% { transform: translateY(0) scale(1.08) rotate(0deg); }
}

/* ── Philosophy grid — restyled onto the dark Barlow Condensed
   system, same PHP loop/data as before ──────────────────────────── */

body.page-template-template-about-php .philosophy-section {
    padding: 40px 0 80px;
}

body.page-template-template-about-php .philosophy-inner {
    /* Narrower than the hero/badge row above (2026-08-09 user request) —
       everything below the badges reads as a centered content column, not
       the full 55px-bleed edge the hero/badges keep. First pass reused the
       site's existing --container-width (1430px) — correction, 2026-08-10:
       that's barely narrower than a wide viewport, so it didn't read as
       "reduced" at all. This is a real content-reading width instead, not
       a borrowed sitewide constant. Bumped 1100px -> 1280px (2026-08-10
       follow-up user request — the philosophy-grid's two columns were
       reading too narrow at 1100px). */
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 24px;
}

body.page-template-template-about-php .philosophy-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    column-gap: 4rem;
    row-gap: 3rem;
}

body.page-template-template-about-php .philosophy-item {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

body.page-template-template-about-php .philosophy-heading {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 800;
    text-transform: uppercase;
    font-size: 43px;
    line-height: 1;
    color: #f9f5ed;
    margin: 0;
}

body.page-template-template-about-php .philosophy-keywords {
    font-family: 'Barlow Condensed', sans-serif;
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #e6a533;
    margin: 0;
}

body.page-template-template-about-php .philosophy-body {
    font-family: var(--font-body);
    font-size: 17px;
    font-weight: 300;
    line-height: 1.6;
    color: rgba(249, 245, 237, 0.85);
    margin: 0;
}

body.page-template-template-about-php .philosophy-body a {
    color: #f9f5ed;
    text-decoration-color: #e6a533;
}

body.page-template-template-about-php .philosophy-body a:hover {
    color: #e6a533;
}

/* ── Partner logos ──────────────────────────────────────────────── */

body.page-template-template-about-php .logos-section {
    /* Top bumped 0 -> 100px (2026-08-14 user request: too close to the
       philosophy columns above). CORRECTION: a same-day earlier attempt
       added this 100px to the unscoped .logos-section rule in style.css
       instead — .logos-section is only actually used on this page, but
       this scoped selector (body + two classes) still beats that
       unscoped one (one class) on specificity regardless, so the
       style.css edit was silently overridden here and never rendered.
       Reverted that edit; this is the rule that actually controls it. */
    padding: 100px 0 100px;
}

body.page-template-template-about-php .logo-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4rem;
    /* Same centered content-column width as .philosophy-inner (2026-08-10
       user request) — logos and philosophy content share one edge.
       Bumped 1100px -> 1280px alongside .philosophy-inner's own same-day
       follow-up change, to keep the two in sync. */
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 24px;
    align-items: center;
}

body.page-template-template-about-php .logo-cell {
    display: flex;
    align-items: center;
    justify-content: center;
}

body.page-template-template-about-php .partner-logo {
    max-width: 100%;
    height: auto;
    opacity: 0.6;
    filter: grayscale(100%);
}

/* ── Tablet range, 768px–1366px (iPad portrait and landscape, all
   generations up through 12.9" Pro) — 2026-08-14 user request.
   CORRECTION, 2026-08-16: this used to also carry .about-heading/
   .about-heading-suffix/.about-badge-inner overrides — both have since
   been made universal (safe at every width >=768px, not just this tablet
   range) instead, see their own base-rule comments for why a tiered
   width-specific value couldn't be trusted to hold at an untested width
   in between. Only the headshot scale below still genuinely belongs to
   this specific range. */
@media (min-width: 768px) and (max-width: 1366px) {
    /* Primary headshot cut 15% (2026-08-14 user request), relative to the
       desktop rule's own scale(1.15) that this range would otherwise
       inherit unchanged: 1.15 * 0.85 = 0.9775. transform-origin (left
       bottom, from the base rule) carries over unchanged, so this still
       scales from the same planted-feet anchor point. */
    body.page-template-template-about-php .about-headshot-masked {
        transform: scale(0.9775);
    }
}

/* ── Real desktop, 1367px and up — 2026-08-21 user request: "the about
   page's header is so small compared to the work page's header... desktop
   should have the same size and positioning as the other pages." The
   min(7vw, 220px) base rule above was deliberately capped small to solve a
   real bug (.about-deck forced onto its own line at 1280px) — but that
   fix's own proof showed the danger zone is specifically the NARROW end of
   the >=768px range: available(w)/w increases monotonically, and past
   1280px .about-deck stops growing at all (flat 576px cap), so the gap
   between the heading and the available space only WIDENS as the viewport
   grows from there — reverting to the portfolio archive's own uncapped
   15vw at a comfortably-past-1280px breakpoint (1367px, where the tablet
   tier above already ends) is provably safe by that same proof, not a
   guess. Values copied exactly from .archive-heading/.archive-heading-
   suffix for true cross-page consistency, including reverting the
   suffix's pull-in to its own pre-shrink value (-25px, from the same
   2026-08-14 change that scaled it down to -12px alongside the heading —
   see .about-heading-suffix's own comment) — this is about the "T" glyph's
   trailing whitespace at THIS font-size, unrelated to why archive's own
   suffix (ending in "K") needs no pull-in at all. */
@media (min-width: 1367px) {
    body.page-template-template-about-php .about-heading {
        font-size: 15vw;
    }
    body.page-template-template-about-php .about-heading-suffix {
        font-size: 3vw;
        margin-left: -25px;
    }
}

/* ── Mobile (below the theme's standard 768px desktop breakpoint) ─── */

@media (max-width: 767px) {
    body.page-template-template-about-php .about-hero-inner {
        flex-direction: column;
        align-items: flex-start;
        gap: 20px;
        padding: 0 16px;
    }

    body.page-template-template-about-php .about-heading {
        font-size: 20vw;
    }

    body.page-template-template-about-php .about-heading-suffix {
        font-size: 5vw;
        /* The desktop rule's negative margin-left (originally -25px,
           tuned for "T"'s trailing glyph whitespace at the old ~15vw
           desktop font-size — now -12px after the 2026-08-16 rescale, see
           .about-heading-suffix's own comment) becomes a proportionally
           massive pull-back at mobile's much smaller heading size either
           way, dragging "PHILOSOPHY" back into "ABOUT" itself (2026-08-12
           mobile bug fix — confirmed live, not a guess: the screenshot
           showed them visually merged). Small positive gap instead, same
           reasoning as .archive-heading-suffix's own mobile-only
           spacing. */
        margin-left: 4px;
    }

    body.page-template-template-about-php .about-deck {
        width: 100%;
        text-align: left;
    }

    body.page-template-template-about-php .career-constellation {
        margin: 0 12px;
        height: auto;
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 20px 0;
    }

    body.page-template-template-about-php .about-headshot-masked {
        position: static;
        height: auto;
        max-width: 70%;
        margin: 0 auto 16px;
        /* Reset the desktop rule's +15% scale — this layout is static/
           in-flow, not the absolute-positioned bottom-left-anchored one
           that scale was tuned for. */
        transform: none;
    }

    body.page-template-template-about-php .career-constellation canvas {
        display: none;
    }

    /* Cursor-driven parallax has no mobile equivalent (no persistent
       hover, same reasoning as the canvas itself going display:none
       here) — drop the ambient layer rather than show it static/inert. */
    body.page-template-template-about-php .about-headshot-bg {
        display: none;
    }

    body.page-template-template-about-php .constellation-fallback-list {
        display: flex;
        flex-direction: column;
        width: 100%;
        gap: 10px;
        padding: 16px;
        margin: 0;
        list-style: none;
        font-family: var(--font-body);
        font-size: 14px;
        color: #f9f5ed;
    }

    body.page-template-template-about-php .constellation-fallback-list li {
        border-bottom: 1px solid rgba(249, 245, 237, 0.1);
        padding-bottom: 10px;
    }

    body.page-template-template-about-php .constellation-fallback-list .cfb-role {
        font-family: 'Barlow Condensed', sans-serif;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.02em;
    }

    body.page-template-template-about-php .constellation-fallback-list .cfb-tags {
        display: block;
        color: #e6a533;
        font-size: 12px;
        text-transform: uppercase;
        letter-spacing: 0.06em;
        margin-top: 2px;
    }

    /* about-constellation.js returns early on mobile right after
       populating the fallback list (isMobile branch, top of the file) —
       updateConnectionRow() (which sets this text's inline max-width so
       CSS ellipsis can truncate it) never runs as a result, so the
       caption rendered at its full natural width instead, right-
       anchored and extending far past the left edge (2026-08-12 mobile
       bug fix, confirmed live via the actual computed rect — width kept
       coming back ~780px with an empty inline max-width). The "hover a
       discipline" copy doesn't apply on a touch device anyway (the
       fallback list replaces the hoverable chart entirely), so hiding
       the row outright is correct here, not just a truncation patch. */
    body.page-template-template-about-php .about-connection-row {
        display: none;
    }

    body.page-template-template-about-php .about-badge-inner {
        flex-wrap: wrap;
        justify-content: center;
        padding: 0 16px;
    }

    body.page-template-template-about-php .about-badge {
        max-width: 90px;
        flex: 0 0 auto;
    }

    body.page-template-template-about-php .philosophy-inner,
    body.page-template-template-about-php .logo-grid {
        padding: 0 16px;
    }

    body.page-template-template-about-php .philosophy-grid {
        grid-template-columns: 1fr;
        row-gap: 2.5rem;
    }

    body.page-template-template-about-php .logo-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}
