.ab-page .back-nav,.ab-page main,.ab-footer{animation:.2s ease-out backwards ab-in}@keyframes ab-in{0%{opacity:0}}.ab{--box-ink:#202020;--box-gap:#a0a0a0;--box-fill:#f8f8f8;--u:4px;font-family:var(--font-text);color:var(--text)}.ab :focus-visible,.ab-footer :focus-visible{outline-color:currentColor}.ab-page{overflow-x:clip}.ab-stat__label,.ab-badges__label,.ab-kicker,.ab-quote__cite,.ab-contact__label,.ab-save__when,.ab-status__label,.ab-media__caption{font-family:var(--font-pixel);letter-spacing:.04em;text-transform:uppercase;font-weight:400}.ab-hero{padding:56px var(--gutter) 0}.ab-hero__grid{max-width:var(--wide);gap:40px;margin:0 auto;display:grid}.ab-card{border:var(--u) solid var(--box-ink);box-shadow:inset 0 0 0 var(--u) var(--box-gap), inset 0 0 0 calc(2 * var(--u)) var(--box-ink);background:var(--box-fill);padding:calc(2 * var(--u) + 18px) calc(2 * var(--u) + 18px) calc(2 * var(--u) + 20px);grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"sprite sprite""name name""line line""stats stats""badges badges";align-items:start;column-gap:16px;display:grid}.ab-card__sprite{--k:var(--art-s,2);width:calc(var(--art-w,56px) * var(--k));height:calc(var(--art-h,56px) * var(--k));grid-area:sprite;justify-self:center;margin:0 0 6px;padding:0}.ab-card__sprite img,.ab-card__sprite svg{width:100%;max-width:none;height:100%;image-rendering:pixelated;animation:1s step-end infinite ab-bob;display:block}@keyframes ab-bob{50%{transform:translateY(calc(-1px * var(--k)))}}.ab-card__name{font-family:var(--font-pixel);letter-spacing:0;text-transform:uppercase;text-shadow:.1em .1em #d4d4d4;grid-area:name;margin:10px 0 0;font-size:clamp(18px,4.4vw + 4px,44px);font-weight:400;line-height:1.3}.ab-card__line{grid-area:line;max-width:36em;margin:14px 0 0;font-size:clamp(17px,15px + .4vw,20px);line-height:1.45}.ab-stats{background:linear-gradient(to right, var(--box-ink) 50%, transparent 0) 0 0 / 4px 2px repeat-x;grid-area:stats;gap:16px;margin:26px 0 0;padding:18px 0 0;display:grid}.ab-stat{grid-template-columns:max-content 1fr max-content;align-items:baseline;column-gap:8px;display:grid}.ab-stat__label{color:var(--text-dim);font-size:10px;line-height:1.4}.ab-stat__value{font-family:var(--font-pixel);white-space:nowrap;grid-column:3;margin:0;font-size:clamp(13px,2.6vw + 4px,22px);line-height:1.2}.ab-stat:before{content:"";background:linear-gradient(to right, var(--box-gap) 50%, transparent 0) 0 0 / 6px 2px repeat-x;grid-area:1/2;align-self:center;height:2px}.ab-badges{background:linear-gradient(to right, var(--box-ink) 50%, transparent 0) 0 0 / 4px 2px repeat-x;grid-area:badges;margin-top:26px;padding-top:18px}.ab-badges__label{color:var(--text-dim);margin:0 0 14px;font-size:10px;line-height:1.4}.ab-badges__list{gap:14px 24px;margin:0;padding:0;list-style:none;display:grid}.ab-badge{grid-template-columns:48px 1fr;align-items:center;column-gap:14px;font-size:15px;line-height:1.35;display:grid}.ab-badge__text{flex-direction:column;gap:2px;display:flex}.ab-badge__source{color:var(--text-dim);font-size:13px;line-height:1.35}.ab-badge__icon{width:48px;height:48px;display:block}@media (hover:hover){.ab-badge:hover .ab-badge__icon{transform:translateY(-3px)}}.ab-badges__later{color:var(--text-dim);margin:16px 0 0;font-size:14px;line-height:1.45}@media (width>=560px){.ab-card{--pad:calc(2 * var(--u) + 28px);padding:var(--pad) var(--pad) calc(var(--pad) + 2px);grid-template-areas:"name sprite""line sprite""stats stats""badges badges";column-gap:28px}.ab-card__sprite{--k:var(--art-s-lg,3);grid-row:1/span 2;place-self:center end;margin:0}.ab-card__name{font-size:clamp(22px,2.4vw + 6px,44px)}.ab-badges__list{grid-template-columns:1fr 1fr}}@media (width<=359px){.ab-card{padding-left:calc(2 * var(--u) + 14px);padding-right:calc(2 * var(--u) + 14px)}.ab-stat{grid-template-columns:1fr}.ab-stat:before{display:none}.ab-stat__value{grid-column:1;margin-top:4px;font-size:16px}}@media (width>=900px){.ab-hero{padding-top:72px}.ab-hero__grid{grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);gap:40px}.ab-media--portrait{flex-direction:column;display:flex}.ab-media--portrait .ab-media__frame{flex:1;min-height:0}.ab-media--portrait .ab-media__frame img{aspect-ratio:auto;object-position:50% 30%;height:100%;position:absolute;inset:0}}@media (width>=900px) and (width<=1099px){.ab-card{grid-template-areas:"sprite sprite""name name""line line""stats stats""badges badges"}.ab-card__sprite{--k:var(--art-s,2);grid-row:auto;justify-self:center;margin:0 0 6px}.ab-badges__list{grid-template-columns:1fr}}.ab-media{min-width:0;margin:0}.ab-media__frame{background:#ececec;position:relative;overflow:hidden}.ab-media__frame img,.ab-media__frame video{width:100%;height:auto;display:block}.ab .ab-media--portrait{margin:0}.ab-media--portrait .ab-media__frame img{aspect-ratio:3/4;object-fit:cover;object-position:50% 30%}.ab .ab-media__caption{max-width:none;color:var(--text-dim);margin:10px 0 0;font-size:9px;line-height:1.6}.ab .ab-wide,.ab .ab-gallery{max-width:var(--wide);margin:56px auto 0}.ab-gallery__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.ab-gallery .ab-media__frame{height:100%}.ab-gallery .ab-media__frame img,.ab-gallery .ab-media__frame video{object-fit:cover;height:100%}.ab-g--climb .ab-media__frame img,.ab-g--dogs .ab-media__frame img,.ab-g--snow .ab-media__frame img{position:absolute;inset:0}.ab-gallery--leangap .ab-gallery__grid{grid-template-columns:minmax(0,1fr);gap:24px 16px}.ab-gallery--leangap .ab-media__frame{aspect-ratio:3/2;height:auto}.ab-gallery--leangap .ab-g--group .ab-media__frame{aspect-ratio:5527/3202}.ab-g--feature{grid-column:1/-1}.ab-g--feature .ab-media__frame{aspect-ratio:16/9}.ab-g--third .ab-media__frame,.ab-g--half .ab-media__frame{aspect-ratio:3/2}.ab-gallery--speaking .ab-g--third:nth-child(4){grid-column:1/-1}.ab-gallery--speaking .ab-g--third:nth-child(4) .ab-media__frame{aspect-ratio:16/9}.ab-g--clip{grid-column:1/-1}.ab-g--clip .ab-media__frame{aspect-ratio:16/9}.ab-g--climb .ab-media__frame,.ab-g--dogs .ab-media__frame{aspect-ratio:3/4}.ab-g--mario .ab-media__frame{aspect-ratio:4284/4800}@media (width>=760px){.ab-gallery__grid{grid-template-columns:repeat(12,minmax(0,1fr));gap:12px}.ab-gallery--leangap .ab-gallery__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:28px 16px}.ab-gallery--leangap .ab-g--group{grid-column:1/-1}.ab-gallery--speaking .ab-gallery__grid{grid-template-columns:repeat(6,minmax(0,1fr))}.ab-gallery--speaking .ab-g--third,.ab-gallery--speaking .ab-g--third:nth-child(4){grid-column:span 2}.ab-gallery--speaking .ab-g--third:nth-child(4) .ab-media__frame{aspect-ratio:3/2}.ab-gallery--speaking .ab-g--half{grid-column:span 3}.ab-g--clip{grid-column:1/9}.ab-g--climb{grid-column:9/13}.ab-g--climb .ab-media__frame,.ab-g--dogs .ab-media__frame,.ab-g--snow .ab-media__frame{aspect-ratio:auto}.ab-g--climb .ab-media__frame img{object-position:50% 25%}.ab-g--dogs{grid-column:1/4}.ab-g--mario{grid-column:4/8}.ab-g--snow{grid-column:8/13}}.ab .ab-paintings{margin:40px 0 0}.ab-paintings__row{grid-template-columns:2725fr 3024fr;grid-template-areas:"one three""two two";align-items:start;gap:8px;display:grid}.ab-paintings__item{background:#ececec}.ab-paintings__item img{width:100%;height:auto;display:block}.ab-paintings__item--1{aspect-ratio:2725/4368;grid-area:one}.ab-paintings__item--2{aspect-ratio:1;grid-area:two}.ab-paintings__item--3{aspect-ratio:3024/4032;grid-area:three}.ab .ab-paintings__caption{max-width:none;color:var(--text-dim);margin:14px 0 0;font-size:18px;line-height:1.45}@media (width>=760px){.ab-paintings__row{grid-template-columns:2725fr 4368fr 3276fr;grid-template-areas:"one two three";gap:12px}}.ab-body{padding:0 var(--gutter) 0}.ab-lede{max-width:var(--measure);letter-spacing:-.01em;text-wrap:pretty;margin:64px auto 0;font-size:clamp(28px,34px + .8vw,46px);line-height:1.22}@media (width<=759px){.ab-lede{font-size:clamp(26px,14px + 3.6vw,34px)}}.ab-lede p{margin:0 0 .85em}.ab-lede p:last-child{margin-bottom:0}.ab-lede a,.ab-prose a,.ab-save__list a,.ab-contact a{color:var(--accent-ink);text-underline-offset:2px}.ab-section{max-width:var(--measure);margin:96px auto 0}.ab-section--tail{margin-top:56px}.ab-section--wide{max-width:920px}.ab-kicker{color:var(--text-dim);align-items:center;gap:10px;margin:0 0 10px;font-size:10px;line-height:1.4;display:flex}.ab-kicker:before{content:"";width:6px;height:9px;image-rendering:pixelated;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='9' shape-rendering='crispEdges'%3E%3Cpath fill='%23202020' d='M0 0h2v1H0zM0 1h1v8H0zM2 1h1v1H2zM3 2h1v1H3zM4 3h1v1H4zM5 4h1v1H5zM4 5h1v1H4zM3 6h1v1H3zM2 7h1v1H2zM1 8h1v1H1zM1 1h1v7H1zM2 2h1v5H2zM3 3h1v3H3zM4 4h1v1H4z'/%3E%3C/svg%3E") 0 0/6px 9px no-repeat}.ab-h2{margin:0 0 20px;font-size:32px}@media (width>=760px){.ab-h2{font-size:48px}}.ab-prose{font-size:18px;line-height:1.65}.ab-prose p{margin:0 0 1.1em}.ab-prose p:last-child{margin-bottom:0}@media (width>=760px){.ab-prose{font-size:19px}}.ab-quote blockquote,.ab-quote blockquote p{margin:0}.ab-quote__cite{color:var(--text-dim);align-items:center;gap:10px;margin-top:18px;font-size:10px;line-height:1.4;display:flex}.ab-quote__cite:before{content:"";background:currentColor;width:24px;height:2px}.ab-contact{gap:14px;margin:28px 0 0;display:grid}.ab-contact__row{grid-template-columns:max-content 1fr max-content;align-items:baseline;column-gap:8px;display:grid}.ab-contact__row:before{content:"";background:linear-gradient(to right, var(--box-gap) 50%, transparent 0) 0 0 / 6px 2px repeat-x;grid-area:1/2;align-self:center;height:2px}.ab-contact__label{color:var(--text-dim);grid-area:1/1;font-size:10px;line-height:1.4}.ab-contact__value{overflow-wrap:anywhere;grid-area:1/3;margin:0;font-size:18px;line-height:1.4}.ab-saves{margin:36px 0 0;padding:0;list-style:none}.ab-save{background:linear-gradient(to bottom, var(--box-gap) 50%, transparent 0) 5px 0 / 2px 4px repeat-y;grid-template-columns:1fr;padding:0 0 40px 28px;display:grid;position:relative}.ab-save:last-child{background-repeat:no-repeat;background-size:2px 4px;padding-bottom:0}.ab-save:before{content:"";box-sizing:border-box;border:3px solid var(--box-ink);background:var(--box-fill);width:12px;height:12px;position:absolute;top:2px;left:0}.ab-save:first-child:before{background:var(--box-ink)}.ab-save__when{align-items:baseline;gap:10px;margin:0 0 10px;line-height:1.4;display:flex}.ab-save__start{color:var(--text);font-size:14px}.ab-save__end{color:var(--text-dim);font-size:9px}.ab-save__title{margin:0;font-size:32px}.ab-save__org{color:var(--text-dim);margin:6px 0 0;font-size:16px;line-height:1.4}.ab-save__list{margin:14px 0 0;padding:0;font-size:16px;line-height:1.55;list-style:none}.ab-save__list li{padding-left:18px;position:relative}.ab-save__list li+li{margin-top:8px}.ab-save__list li:before{content:"";background:var(--text);width:4px;height:4px;position:absolute;top:.62em;left:2px}@media (width>=760px){.ab-save{background-position:185px 0;grid-template-columns:148px 1fr;column-gap:32px;padding-bottom:48px;padding-left:0}.ab-save:before{top:6px;left:180px}.ab-save__when{text-align:right;flex-direction:column;align-items:flex-end;gap:8px;margin:4px 0 0}.ab-save__start{font-size:18px}.ab-save__body{padding-left:32px}}.ab-status{gap:16px;margin-top:32px;display:grid}.ab-status__box{border:var(--u) solid var(--box-ink);box-shadow:inset 0 0 0 var(--u) var(--box-gap), inset 0 0 0 calc(2 * var(--u)) var(--box-ink);background:var(--box-fill);padding:calc(2 * var(--u) + 16px) calc(2 * var(--u) + 18px)}.ab-status__label{color:var(--text-dim);margin:0 0 12px;font-size:10px;line-height:1.4}.ab-status__list{margin:0;padding:0;font-size:16px;line-height:1.5;list-style:none}.ab-status__list li+li{margin-top:6px}.ab-langs li{justify-content:space-between;gap:16px;display:flex}.ab-langs__level{color:var(--text-dim)}.ab-chips{flex-wrap:wrap;gap:8px;margin:0;padding:0;list-style:none;display:flex}.ab-chips li{border:2px solid var(--box-ink);background:#fff;padding:5px 10px;font-size:15px;line-height:1.3}.ab-chips li:first-letter{text-transform:uppercase}@media (width>=760px){.ab-status{grid-template-columns:1fr 1fr}}.ab-menu{margin-top:112px}.ab .end-menu__row:focus-visible{outline-offset:-2px;outline:2px solid #3aded6}.ab-footer{max-width:var(--measure);padding:28px var(--gutter) 64px;font-family:var(--font-text);color:var(--text-dim);margin:0 auto;font-size:14px;line-height:1.55}.ab-footer p{margin:0 0 10px}.ab-footer a{color:var(--accent-ink)}

.ab-card{position:relative}
.ab-lanyard{position:absolute;top:-13px;left:50%;transform:translateX(-50%);width:44px;height:26px;pointer-events:none}
.ab-lanyard__strap{position:absolute;top:10px;left:50%;transform:translateX(-50%);width:10px;height:16px;background:var(--accent,#2e8b8b)}
.ab-lanyard__clip{position:absolute;top:0;left:50%;transform:translateX(-50%);width:26px;height:14px;background:#c8c8c0;border:3px solid var(--box-ink);box-sizing:border-box;z-index:1}
.ab-lanyard__clip:after{content:"";position:absolute;top:2px;left:50%;transform:translateX(-50%);width:8px;height:4px;background:var(--box-fill)}
.ab-stripe{position:absolute;top:14px;left:18px;right:18px;margin:0;padding:5px 8px;background:#8a2020;color:#fff;font-family:var(--font-pixel);font-size:10px;letter-spacing:.12em;text-align:center}
.ab-stamp{position:absolute;top:64px;right:16px;margin:0;padding:6px 8px;border:3px solid #8a2020;color:#8a2020;font-family:var(--font-pixel);font-size:10px;letter-spacing:.08em;transform:rotate(-8deg);background:#ffffffcc}
.ab-vitals{grid-template-columns:1fr}
.ab-vitals__row{display:grid;grid-template-columns:130px 1fr;gap:8px 20px;align-items:start;padding:12px 0;border-bottom:2px dashed var(--rule,#d9d6ca)}
.ab-vitals__row:first-child{padding-top:0}.ab-vitals__row:last-child{border-bottom:0;padding-bottom:0}
.ab-vitals__row .ab-status__label{margin:4px 0 0}
.ab-vitals__value{margin:0;font-size:16px;line-height:1.5}
@media (max-width:560px){.ab-vitals__row{grid-template-columns:1fr}}
/* === UI fix campaign 2026-11-08 (About/CHART A1-A6) ===
   Appended overrides. The base rules above are the built output; these win by
   source order at equal specificity, or by higher specificity where noted. */

/* A1: stats and badges were placed by grid-area names (stats/badges) that do
   not exist in .ab-hero__grid, so the browser created implicit tracks and
   landed both blocks in the same box. Give the hero grid real named areas in
   one sequential column: card, then stats, then badges. */
.ab-hero__grid{grid-template-columns:minmax(0,1fr);grid-template-areas:"card" "stats" "badges"}
.ab-card{grid-area:card}
.ab-stats{grid-area:stats}
.ab-badges{grid-area:badges}

/* A2: the card is its own grid. Its template listed stats/badges rows that are
   not card children, and both .ab-card__line paragraphs shared the single
   "line" area, so they printed on top of each other and the text column
   collapsed to 0px. Retemplate with a second line row and no phantom rows,
   and leave room at the top for the absolute MEDICAL STUDENT stripe. */
.ab-card{grid-template-areas:"sprite sprite" "name name" "line line" "line2 line2";padding-top:58px}
.ab-card__line + .ab-card__line{grid-area:line2}
.ab-card__name,.ab-card__line{min-width:0}
@media (width>=560px){
  .ab-card{grid-template-areas:"name sprite" "line sprite" "line2 sprite"}
  .ab-card__sprite{grid-row:1/-1}
}
@media (width>=900px) and (width<=1099px){
  .ab-card{grid-template-areas:"sprite sprite" "name name" "line line" "line2 line2"}
  .ab-card__sprite{grid-row:auto}
}

/* A3: hero media. The shared BaseLayout rules size this hero (data-hero-vh
   0.85) as a 90vw-tall band centred in an 85svh black box, with the video
   wider than the band and the caption in flow far below it. Scoped to the
   About article only: the hero takes the media's natural 16/9 aspect (capped
   at 85svh), the media fills the hero, and the caption sits on the media at
   the bottom, as on the desktop project pages. Specificity (0,5,0) beats the
   shared (0,4,0) rules. */
.cs.ab:not([data-hero-vh="0.6"])>.cs-hero{height:min(85svh,56.25vw);min-height:0;max-height:none}
.cs.ab:not([data-hero-vh="0.6"])>.cs-hero>.cs-hero__media{position:absolute;inset:0;top:0;height:auto}
.cs.ab:not([data-hero-vh="0.6"])>.cs-hero .cs-hero__video{position:absolute;inset:0;left:0;top:0;width:100%;height:100%;max-width:none;transform:none;object-fit:cover}
.cs.ab:not([data-hero-vh="0.6"])>.cs-hero>.cs-hero__caption{position:absolute;bottom:0;left:0;right:0;margin-top:0;background:linear-gradient(0deg,#0f1110d9,#0f1110bf calc(100% - 96px),#0f111000);padding:96px calc(var(--gutter) + 8px) calc(28px + var(--dither-h))}
@media (width<=760px){
  .cs.ab:not([data-hero-vh="0.6"])>.cs-hero>.cs-hero__caption{padding-top:48px;padding-bottom:calc(20px + var(--dither-h))}
}

/* A4: fixed bars. The Game Boy shell's BACK button (fixed, top left) and the
   "Short on time?" fast-lane bar (fixed, bottom left) stay on top while this
   page scrolls under them. Page-side clearance: anchored sections land below
   the BACK button instead of under it, and the page foot gets enough bottom
   padding that the last content can scroll fully clear of the fast-lane bar. */
.ab-hero{scroll-margin-top:104px}
@media (width<=760px){.ab-stats{margin-top:56px}}
.ab-section,.ab .credits{scroll-margin-top:96px}
.ab-footer{padding-bottom:128px}

/* A5: colophon footer links. A link that wraps across two lines ("MIT
   License") reports one union box spanning both lines, which covers the
   "three.js" link beside it and reads as an overlap. Keep colophon links on
   one line so no link box ever spans a neighbour. */
.ab .credits a{white-space:nowrap}

/* A6: pull quote. The blockquote's tight 42/38 line-height let its box
   measure up to 5px shorter than its content (scrollHeight 173 vs
   clientHeight 168 in the docked scan). Give the quote air. */
.ab .ab-quote{padding-bottom:10px}
.ab .ab-quote blockquote{line-height:1.22;padding-block:.1em;overflow:visible}
.ab .ab-quote blockquote p{overflow:visible;padding-block:.15em}
