/* ============================================================
   FONTS  self-hosted. Removes the render-blocking third-party
   request to fonts.googleapis.com and its dependency chain.
   latin-ext is fetched only when a character in its range renders
   (the site needs it for the macron in "Manoa").
   ============================================================ */
@font-face{font-family:'Playfair Display';font-style:italic;font-weight:400 600;font-display:swap;
  src:url('fonts/playfair-display-italic-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:'Playfair Display';font-style:italic;font-weight:400 600;font-display:swap;
  src:url('fonts/playfair-display-italic-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Playfair Display';font-style:normal;font-weight:400 800;font-display:swap;
  src:url('fonts/playfair-display-normal-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:'Playfair Display';font-style:normal;font-weight:400 800;font-display:swap;
  src:url('fonts/playfair-display-normal-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:300 600;font-display:swap;
  src:url('fonts/inter-normal-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:'Inter';font-style:normal;font-weight:300 600;font-display:swap;
  src:url('fonts/inter-normal-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* ============================================================
   PALETTE  coastal pastel. Every foreground/background pair was
   checked against WCAG AA 4.5:1. Three tokens are darker than the
   brief's draft values because the drafts failed (see session report).
   ============================================================ */
:root{
  --bg:#fdfcf8; --paper:#ffffff;
  --sun:#f8ecbe; --sky:#d5e7f0; --sky-wash:#e2eef4; --blush:#f2ddd6;
  --ink:#2f444c; --ink-soft:#51636b; --muted:#556369;
  --sea:#226077; --sea-deep:#1a4b5c;
  --sun-ink:#7a611f; --sun-line:#d4b96a;
  /* the one vivid focal accent. --coral for large numerals, rules and
     hover cues; --coral-deep only where a label sits on top of it. */
  --coral:#e8683f; --coral-deep:#c44a22;
  --line:rgba(47,68,76,.14); --line-soft:rgba(47,68,76,.07);
  /* legacy aliases: existing rules re-skin through these without a rewrite */
  --wine:var(--sea); --wine-deep:var(--sea-deep);
  --gold:var(--sun-ink); --gold-soft:var(--sun-line); --gold-ink:var(--sun-ink);
  --serif:"Playfair Display",Georgia,serif;
  --sans:"Inter",system-ui,sans-serif;
  --ease:cubic-bezier(.16,1,.3,1);
  --shadow:rgba(47,68,76,.18);
  --gutter:clamp(22px,5.5vw,72px);
  --rhythm:clamp(4.5rem,11vh,8.5rem);
  --measure:62ch;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--sans);font-weight:400;line-height:1.68;font-size:1.0625rem;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
h1,h2,h3{font-family:var(--serif);font-weight:600;line-height:1.06;letter-spacing:-.015em;margin:0}
p{margin:0}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
::selection{background:var(--wine);color:#fff}
:focus{outline:none}
a:focus-visible,button:focus-visible{outline:2.5px solid var(--coral-deep);outline-offset:3px;border-radius:3px}

/* layout primitives */
.wrap{max-width:1180px;margin:0 auto;padding-inline:var(--gutter)}
.rule{height:1px;background:var(--line);border:0;margin:0}

/* editorial labels */
.kicker{font-family:var(--sans);font-size:.72rem;font-weight:600;letter-spacing:.24em;
  text-transform:uppercase;color:var(--wine);display:flex;align-items:center;gap:.7rem;margin:0}
.kicker .sep{width:26px;height:1px;background:var(--gold-soft);display:inline-block}
.sec-index{font-family:var(--serif);font-style:italic;font-weight:500;font-size:1rem;color:var(--gold-ink);letter-spacing:0}
.sub-label{font-family:var(--sans);font-size:.7rem;font-weight:700;letter-spacing:.2em;
  text-transform:uppercase;color:var(--muted);margin:0 0 1.1rem}
.cap{font-family:var(--sans);font-size:.8rem;color:var(--muted);line-height:1.5}

/* section shell + rhythm */
.feature{padding-block:var(--rhythm)}
.feature + .feature{border-top:1px solid var(--line-soft)}
.sec-head{display:grid;grid-template-columns:auto 1fr;gap:.4rem 1.4rem;align-items:baseline;
  margin-bottom:clamp(2.4rem,5vw,3.8rem)}
.sec-head .kicker{grid-column:2}
.sec-head .sec-index{grid-row:1;grid-column:1;padding-top:.15rem}
.sec-head h2{grid-column:2;font-size:clamp(2rem,4.6vw,3.3rem);max-width:18ch;margin-top:.3rem}
.sec-head h2 em{font-style:italic;color:var(--wine)}

/* reveal + stagger (transform/opacity only) */
.reveal{opacity:0;transform:translateY(20px) scale(.985);
  transition:opacity .8s var(--ease),transform .8s var(--ease)}
.reveal.in{opacity:1;transform:none}
.stagger>.reveal:nth-child(2){transition-delay:.06s}
.stagger>.reveal:nth-child(3){transition-delay:.12s}
.stagger>.reveal:nth-child(4){transition-delay:.18s}
.stagger>.reveal:nth-child(5){transition-delay:.24s}
.stagger>.reveal:nth-child(6){transition-delay:.30s}

/* buttons + editorial links */
.btn{display:inline-flex;align-items:center;gap:.5rem;font-family:inherit;font-weight:600;font-size:.9rem;
  padding:.8rem 1.5rem;border-radius:2px;border:1px solid transparent;cursor:pointer;transition:background .25s,color .25s,border-color .25s}
.btn.solid{background:var(--coral-deep);color:#fff;box-shadow:0 10px 22px -12px rgba(196,74,34,.65)}
.btn.solid:hover{background:var(--sea);box-shadow:0 14px 26px -12px rgba(34,96,119,.6)}
.btn.light{background:var(--paper);color:var(--sea)}
.btn.light:hover{background:var(--sun)}
.link{position:relative;font-weight:600;font-size:.92rem;color:var(--ink);padding-bottom:2px}
.link::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background:var(--coral);
  transform:scaleX(1);transform-origin:left;transition:transform .3s var(--ease)}
.link:hover{color:var(--wine)}
.link.on-wine{color:var(--ink)}.link.on-wine::after{background:var(--coral)}

/* skip link */
.skip{position:absolute;left:-999px;top:0;z-index:100;background:var(--wine);color:#fff;padding:.7rem 1.1rem;border-radius:0 0 4px 0}
.skip:focus{left:0}

/* ============ MASTHEAD ============ */
.mast{position:sticky;top:0;z-index:60;background:rgba(253,252,248,.82);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--line-soft)}
.mast-row{display:flex;align-items:center;justify-content:space-between;height:66px}
.mast-brand{font-family:var(--serif);font-weight:600;font-size:1.22rem;letter-spacing:.01em}
.mast-nav{display:flex;align-items:center;gap:clamp(1.2rem,2.4vw,2.3rem)}
.mast-nav a{font-size:.74rem;font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);transition:color .2s}
.mast-nav a:hover{color:var(--ink)}
.mast-nav a.mast-cta{color:var(--wine)}
.nav-toggle{display:none;background:none;border:none;cursor:pointer;padding:.4rem;color:var(--ink)}

/* ============ HERO ============ */
/* clip, not hidden: hidden would make this a scroll container and break the
   sticky masthead. The hero bloom overhangs the gutter and must not add
   horizontal scroll on a phone. */
.hero{padding-block:clamp(3.2rem,8vh,6.5rem) var(--rhythm);overflow-x:clip}
.hero-grid{display:grid;grid-template-columns:1.12fr .88fr;gap:clamp(2.2rem,5.5vw,5rem);align-items:end}
.hero-kicker{margin-bottom:clamp(1.6rem,4vw,2.6rem)}
.hero-name{font-size:clamp(3rem,7.6vw,6rem);line-height:.98;letter-spacing:-.03em}
.hero-name em{font-style:italic;color:var(--wine);font-weight:500}
.hero-role{font-family:var(--serif);font-style:italic;font-size:clamp(1.15rem,2.1vw,1.6rem);
  color:var(--ink-soft);margin-top:1.3rem;font-weight:400}
.hero-stand{max-width:46ch;color:var(--ink-soft);margin-top:1.5rem;font-size:1.08rem;line-height:1.72}
.hero-actions{display:flex;align-items:center;gap:1.6rem;margin-top:2.1rem;flex-wrap:wrap}
.hero-langs{margin-top:2.4rem;padding-top:1.3rem;border-top:1px solid var(--line);
  font-size:.9rem;color:var(--muted);display:flex;gap:.9rem;flex-wrap:wrap;align-items:baseline}
.hero-langs .cap-label{font-size:.68rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--wine)}
.hero-langs .ll{color:var(--ink-soft)}
.hero-figure{margin:0}
.hero-photo{position:relative;aspect-ratio:4/5;overflow:hidden;border-radius:6px;
  box-shadow:0 2px 6px -2px rgba(47,68,76,.10),0 18px 34px -18px rgba(47,68,76,.20),0 46px 84px -44px rgba(47,68,76,.34);
  background:var(--sky-wash)}
.hero-photo img{width:100%;height:100%;object-fit:cover;object-position:center 18%}
.hero-figure figcaption{margin-top:.85rem;font-size:.8rem;color:var(--muted);line-height:1.5;
  padding-left:1rem;border-left:2px solid var(--gold-soft)}
.hero-figure figcaption b{color:var(--ink);font-weight:600}

/* ============ FIGURES (wine spread) ============ */
.figures{background:linear-gradient(180deg,var(--sky-wash) 0%,#eef6f9 100%);color:var(--ink)}
.figures-inner{padding-block:clamp(3rem,7vh,5rem)}
.figures-top{display:flex;align-items:center;gap:1.2rem;margin-bottom:2.2rem}
.figures-top .lbl{font-size:.7rem;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:var(--sea)}
.figures-top .ln{flex:1;height:1px;background:var(--line)}
.figures-grid{display:grid;grid-template-columns:repeat(4,1fr)}
.fig{padding:.2rem clamp(1rem,2.5vw,2rem);border-left:1px solid var(--line);
  display:flex;flex-direction:column}
.fig:first-child{border-left:0;padding-left:0}
.fig-n{font-family:var(--serif);font-size:clamp(2.4rem,4.6vw,3.6rem);font-weight:600;line-height:1;
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;white-space:nowrap}
/* the revenue range is the widest string; step it down so it holds one line */
.fig.is-wide .fig-n{font-size:clamp(1.8rem,3.2vw,2.5rem)}
.fig-n em{font-style:normal;color:var(--sea)}
.fig-l{display:block;margin-top:auto;padding-top:.7rem;font-size:.82rem;color:var(--muted);line-height:1.5;max-width:22ch}

/* ============ ABOUT (feature open) ============ */
.about-grid{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,7fr);gap:clamp(2rem,5vw,4.5rem)}
.about-rail .pullquote{font-family:var(--serif);font-style:italic;font-weight:500;
  font-size:clamp(1.35rem,2.3vw,1.7rem);line-height:1.32;color:var(--ink);margin:1.4rem 0 0;
  padding-top:1.4rem;border-top:2px solid var(--wine)}
.about-rail .meta{margin:2.2rem 0 0;display:flex;flex-direction:column;gap:0}
.about-rail .meta>div{padding:1rem 0;border-top:1px solid var(--line)}
.about-rail .meta dt{font-size:.68rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-bottom:.35rem}
.about-rail .meta dd{margin:0;font-size:.95rem;color:var(--ink-soft);line-height:1.55}
.about-body h2{font-size:clamp(1.9rem,4.2vw,3rem);max-width:15ch;margin-bottom:1.8rem}
.about-body h2 em{font-style:italic;color:var(--wine)}
.about-body p{color:var(--ink-soft);max-width:var(--measure);margin-bottom:1.2rem;font-size:1.08rem;line-height:1.74}
.about-body p strong{color:var(--ink);font-weight:600}
.about-body p.dropcap::first-letter{font-family:var(--serif);font-weight:600;float:left;
  font-size:3.6rem;line-height:.82;padding:.3rem .6rem 0 0;color:var(--wine)}

/* ============ INDEX LIST (expertise) ============ */
.index-list{list-style:none;margin:0;padding:0}
.index-row{display:grid;grid-template-columns:auto minmax(0,4fr) minmax(0,6fr);gap:clamp(1rem,3vw,3rem);
  align-items:baseline;padding:clamp(1.4rem,3vw,2.1rem) 0;border-top:1px solid var(--line)}
.index-row:last-child{border-bottom:1px solid var(--line)}
.index-row .idx{font-family:var(--serif);font-style:italic;font-size:1.15rem;color:var(--gold-ink);font-variant-numeric:tabular-nums}
.index-row h3{font-size:clamp(1.3rem,2.3vw,1.7rem);letter-spacing:-.01em}
.index-row p{color:var(--muted);font-size:1rem;line-height:1.6;max-width:44ch}
@media (hover:hover){.index-row{transition:background .3s}.index-row:hover{background:rgba(34,96,119,.05)}}

/* ============ EXPERIENCE (résumé spreads) ============ */
.cv-row{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:clamp(1.4rem,4vw,3.5rem);
  padding:clamp(1.8rem,4vw,2.8rem) 0;border-top:1px solid var(--line)}
.cv-row:first-of-type{border-top:1px solid var(--ink)}
.cv-dates{font-size:.72rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);font-variant-numeric:tabular-nums}
.cv-co{font-family:var(--serif);font-size:1.28rem;font-weight:600;color:var(--ink);line-height:1.2;margin-top:.55rem}
.cv-badge{display:inline-block;margin-top:.9rem;font-size:.64rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--sea);border:1px solid rgba(34,96,119,.35);padding:.28rem .6rem;border-radius:2px}
.cv-role{font-size:clamp(1.4rem,2.4vw,1.85rem);margin-bottom:1.1rem}
.cv-role em{font-style:italic;color:var(--wine)}
.cv-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.7rem}
.cv-list li{position:relative;padding-left:1.5rem;color:var(--ink-soft);font-size:1.02rem;line-height:1.58;max-width:64ch}
.cv-list li::before{content:"";position:absolute;left:0;top:.66em;width:6px;height:1px;background:var(--gold)}
.cv-list li b{color:var(--ink);font-weight:600}
.sec-subhead{margin:clamp(3rem,6vw,4.5rem) 0 0;padding-top:1.6rem;border-top:1px solid var(--ink)}
.also{display:grid;grid-template-columns:repeat(3,1fr);gap:0;margin-top:.5rem}
.also-item{padding:1.8rem clamp(1.1rem,2vw,1.8rem) 0.4rem;border-left:1px solid var(--line)}
.also-item:first-child{border-left:0;padding-left:0}
.also-item .ah{display:flex;justify-content:space-between;align-items:baseline;gap:.6rem;margin-bottom:.7rem}
.also-item .co2{font-family:var(--serif);font-weight:600;color:var(--ink);font-size:1.05rem}
.also-item .yr2{font-size:.66rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--gold-ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.also-item h3{font-size:1.02rem;font-weight:600;color:var(--wine);margin-bottom:.5rem;font-family:var(--sans);letter-spacing:0}
.also-item p{color:var(--muted);font-size:.92rem;line-height:1.58}

/* ============ SKILLS (ledger) ============ */
.skills-grid{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(2.2rem,5vw,4.5rem)}
.skill-line{font-size:1.12rem;line-height:1.75;color:var(--ink);max-width:40ch;margin:0 0 2.2rem}
.skill-line .dot{color:var(--gold);margin:0 .4rem}
/* The systems list carries no whitespace between items, so the browser treats it
   as one unbreakable word that blows out the 1fr grid track on a phone (365px in
   a 346px box). A zero-width space after each separator gives the line somewhere
   legal to break, at the dots, without changing visible spacing. min-width:0 stops
   grid items from being sized by their min-content. */
.skill-line .dot::after{content:"\200B"}
.skills-grid>*{min-width:0}
.skill-cols{list-style:none;margin:0;padding:0;columns:2;column-gap:2.4rem}
.skill-cols li{break-inside:avoid;padding:.5rem 0;border-top:1px solid var(--line-soft);color:var(--ink-soft);font-size:.96rem}
.ledger{margin:0}
.ledger-row{display:grid;grid-template-columns:1fr auto;align-items:baseline;gap:1rem;
  padding:.85rem 0;border-top:1px solid var(--line)}
.ledger-row:first-of-type{border-top:1px solid var(--ink)}
.ledger-row .lname{font-family:var(--serif);font-size:1.12rem;color:var(--ink)}
.ledger-row .llvl{font-size:.72rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
/* Language proficiency is a discrete scale, not a percentage. Four steps map to
   Basic / Conversational / Professional / Native, so the mark never claims a
   precision the underlying fact does not have. The level is already stated in
   text next to it, so the scale is aria-hidden decoration. */
.ledger-scale{grid-column:1/-1;display:grid;grid-template-columns:repeat(4,1fr);
  gap:6px;margin-top:.8rem}
.ledger-scale i{position:relative;display:block;height:3px;background:var(--line-soft);overflow:hidden}
.ledger-scale i.on::after{content:"";position:absolute;inset:0;background:var(--sea);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .55s var(--ease)}
.reveal.in .ledger-scale i.on::after{transform:scaleX(1)}
/* stagger down the rows, then across the segments, so it reads as one gesture */
.ledger-row{--rd:0s}
.ledger-row:nth-child(2){--rd:.07s}
.ledger-row:nth-child(3){--rd:.14s}
.ledger-row:nth-child(4){--rd:.21s}
.ledger-row:nth-child(5){--rd:.28s}
.ledger-scale i:nth-child(1).on::after{transition-delay:calc(var(--rd) + .02s)}
.ledger-scale i:nth-child(2).on::after{transition-delay:calc(var(--rd) + .09s)}
.ledger-scale i:nth-child(3).on::after{transition-delay:calc(var(--rd) + .16s)}
.ledger-scale i:nth-child(4).on::after{transition-delay:calc(var(--rd) + .23s)}
@media (prefers-reduced-motion:reduce){
  .ledger-scale i.on::after{transform:scaleX(1);transition:none}
}

/* ============ EDUCATION / AWARDS ============ */
.edu-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:clamp(2.2rem,5vw,4.5rem)}
.edu-item{padding:1.4rem 0;border-top:1px solid var(--line)}
.edu-item:first-child{border-top:1px solid var(--ink)}
.edu-item h3{font-size:1.32rem}
.edu-item .m{color:var(--muted);font-size:.92rem;margin-top:.35rem}
.awards{list-style:none;margin:0;padding:0}
.awards li{display:grid;grid-template-columns:auto 1fr;gap:1.1rem;align-items:start;
  padding:1.05rem 0;border-top:1px solid var(--line);color:var(--ink);font-size:1rem;line-height:1.45}
.awards li:first-child{border-top:1px solid var(--ink)}
/* One restrained Hawai'i cue, placed where the brief suggests it: the credential
   marker. Echoes favicon.svg. Decorative, so aria-hidden and no contrast duty. */
.awards li .plum{width:15px;height:15px;flex:none;margin-top:.34em;color:var(--sun-line)}

/* ============ CLOSING (wine spread) ============ */
.closing{background:linear-gradient(135deg,var(--sun) 0%,var(--blush) 54%,var(--sky) 100%);
  color:var(--ink);padding-block:clamp(4.5rem,11vh,8rem)}
.closing-inner{max-width:760px}
.closing .kicker{color:var(--sea)}
.closing .kicker .sep{background:var(--sea)}
.closing-head{font-size:clamp(2.4rem,5.5vw,4rem);margin:1.4rem 0 0;letter-spacing:-.02em}
.closing-head em{font-style:italic;color:var(--coral-deep)}
.closing-sub{color:var(--ink-soft);max-width:44ch;margin:1.5rem 0 0;font-size:1.08rem;line-height:1.7}
.closing-actions{display:flex;align-items:center;gap:1.8rem;margin-top:2.4rem;flex-wrap:wrap}
.nowrap{white-space:nowrap}
.closing-email{margin-top:1.4rem;font-size:1.02rem}
.closing-email a{color:var(--sea);text-decoration:none;border-bottom:1px solid rgba(34,96,119,.35);padding-bottom:1px}
.closing-email a:hover{border-bottom-color:var(--sea)}
.closing .refs{margin-top:2.6rem;padding-top:1.3rem;border-top:1px solid var(--line);
  font-size:.82rem;color:var(--muted)}

/* ============ FOOTER ============ */
footer{padding-block:2.4rem}
footer .wrap{display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  font-size:.78rem;letter-spacing:.04em;color:var(--muted)}
footer .fn{font-family:var(--serif);color:var(--ink)}

/* ============ RESPONSIVE ============ */
@media (max-width:900px){
  .mast-nav{position:fixed;inset:66px 0 auto 0;background:var(--bg);flex-direction:column;gap:0;
    padding:.4rem 0 .8rem;border-bottom:1px solid var(--line);transform:translateY(-118%);
    transition:transform .38s var(--ease);box-shadow:0 26px 46px -30px var(--shadow)}
  .mast-nav.open{transform:none}
  .mast-nav a{padding:.95rem var(--gutter);width:100%;letter-spacing:.16em}
  .nav-toggle{display:block}
  .hero-grid{grid-template-columns:1fr;gap:clamp(1.8rem,6vw,2.6rem)}
  .hero-figure{order:-1;max-width:340px}
  .figures-grid{grid-template-columns:1fr 1fr;gap:0}
  .fig{border-left:0;border-top:1px solid var(--line);padding:1.4rem 0}
  .fig:nth-child(-n+2){border-top:0}
  .fig:nth-child(2n){padding-left:clamp(1rem,4vw,1.6rem);border-left:1px solid var(--line)}
  .about-grid{grid-template-columns:1fr;gap:2.4rem}
  .index-row{grid-template-columns:auto 1fr;gap:.3rem 1.2rem}
  .index-row p{grid-column:2;margin-top:.4rem}
  .cv-row{grid-template-columns:1fr;gap:1.1rem}
  .also{grid-template-columns:1fr}
  .also-item{border-left:0;border-top:1px solid var(--line);padding:1.5rem 0 .3rem}
  .also-item:first-child{border-top:1px solid var(--ink)}
  .skills-grid{grid-template-columns:1fr;gap:2.6rem}
  .edu-grid{grid-template-columns:1fr;gap:2.4rem}
}
@media (max-width:520px){
  .skill-cols{columns:1}
  .hero-actions{gap:1.1rem}
  .sec-head{grid-template-columns:1fr}
  .sec-head .sec-index{grid-column:1}.sec-head .kicker,.sec-head h2{grid-column:1}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal{opacity:1;transform:none;transition:none}
  .link::after{transition:none}
}

/* ============================================================
   BLOG  (index + article) — shares the system above
   ============================================================ */
/* ---- blog index ---- */
.blog-top{padding-block:clamp(3rem,7vh,5rem) clamp(1.6rem,4vh,2.6rem)}
.blog-top h1{font-size:clamp(2.6rem,6vw,4.4rem);letter-spacing:-.025em;margin-top:1rem}
.blog-top h1 em{font-style:italic;color:var(--wine)}
.blog-top .dek{max-width:54ch;color:var(--ink-soft);font-size:1.12rem;margin-top:1.3rem;line-height:1.72}
.blog-list{border-top:1px solid var(--ink);margin-top:clamp(2rem,5vw,3.2rem)}
.post-row{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,9fr);gap:clamp(1rem,3vw,3rem);
  padding:clamp(1.6rem,3.4vw,2.3rem) 0;border-bottom:1px solid var(--line);align-items:baseline}
@media (hover:hover){.post-row{transition:background .3s}.post-row:hover{background:rgba(34,96,119,.05)}}
.p-meta{display:flex;flex-direction:column;gap:.5rem}
.p-cat{font-size:.66rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--wine)}
.p-date{font-size:.8rem;color:var(--muted);font-variant-numeric:tabular-nums}
.post-row h2{font-size:clamp(1.5rem,2.8vw,2.1rem);line-height:1.12}
.post-row h2 a{transition:color .25s}
.post-row h2 a:hover{color:var(--wine)}
.p-dek{color:var(--muted);margin-top:.7rem;max-width:58ch;font-size:1.02rem;line-height:1.6}
.p-more{display:inline-block;margin-top:1rem;font-size:.8rem;font-weight:600;letter-spacing:.02em;color:var(--wine)}
/* Unpublished rows read as quieter via headline color, not blanket opacity.
   A row-level opacity drags .p-cat/.p-soon/.p-dek below AA contrast. */
.post-row.soon h2{color:var(--ink-soft)}
.p-soon{font-size:.66rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--gold-ink)}
.blog-note{margin-top:2.4rem;font-family:var(--serif);font-style:italic;color:var(--muted);font-size:1.1rem}
@media (max-width:760px){.post-row{grid-template-columns:1fr;gap:.7rem}.p-meta{flex-direction:row;gap:1rem;align-items:baseline}}
/* grouped blog index (8 category clusters) */
.blog-groups{margin-top:clamp(2rem,5vw,3rem)}
.blog-group{margin-top:clamp(2.6rem,6vw,3.8rem)}
.blog-group:first-child{margin-top:0}
.blog-cat-head{font-family:var(--serif);font-size:clamp(1.5rem,3.4vw,2.15rem);letter-spacing:-.015em;display:flex;align-items:baseline;justify-content:space-between;gap:1rem;margin:0}
.blog-cat-head .n{font-family:var(--sans);font-size:.7rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);white-space:nowrap}
.blog-group .blog-list{margin-top:1rem}
.post-row h3{font-size:clamp(1.32rem,2.5vw,1.85rem);line-height:1.14;margin:0}
.post-row h3 a{color:var(--ink);text-decoration:none;transition:color .25s}
.post-row h3 a:hover{color:var(--sea)}
.p-read{font-size:.68rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
/* category picker (topic cards -> filtered posts) */
.blog-picker-wrap{margin-top:clamp(1.4rem,4vw,2.2rem)}
.cat-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.85rem}
@media(max-width:900px){.cat-cards{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:520px){.cat-cards{grid-template-columns:1fr}}
.cat-card{display:flex;flex-direction:column;gap:.22rem;text-align:left;padding:1rem 1.05rem;border:1px solid var(--line);border-radius:12px;background:#fff;cursor:pointer;font-family:inherit;transition:border-color .2s,box-shadow .2s,background .2s,transform .2s}
@media(hover:hover){.cat-card:hover{border-color:var(--sea);box-shadow:0 10px 22px -14px rgba(34,96,119,.4);transform:translateY(-2px)}}
.cat-card:focus-visible{outline:2px solid var(--sea);outline-offset:2px}
.cat-card.is-active{background:var(--sky);border-color:var(--sea);box-shadow:0 8px 20px -14px rgba(34,96,119,.4)}
.cc-name{font-family:var(--serif);font-size:1.06rem;font-weight:600;color:var(--ink);line-height:1.14}
.cc-desc{font-size:.8rem;color:var(--ink-soft);line-height:1.32}
.cc-n{font-size:.64rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--coral-deep);margin-top:.15rem}
.cat-card.is-active .cc-n{color:var(--sea)}
.blog-groups{margin-top:clamp(1.6rem,4vw,2.6rem)}
.blog-group{margin-top:0}

/* ---- article ---- */
.reading{max-width:720px}
.article{padding-block:clamp(2.4rem,6vh,4rem) 0}
.article-back{font-size:.72rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);display:inline-flex;gap:.5rem;transition:color .2s}
.article-back:hover{color:var(--wine)}
.article-head{margin:2rem 0 clamp(2rem,5vw,3rem)}
.article-cat{font-size:.7rem;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:var(--wine);margin-bottom:1.1rem}
.article-head h1{font-size:clamp(2.2rem,5vw,3.4rem);letter-spacing:-.02em;line-height:1.06}
.article-head h1 em{font-style:italic;color:var(--wine)}
.article-dek{font-family:var(--serif);font-style:italic;font-size:clamp(1.15rem,2vw,1.5rem);color:var(--ink-soft);margin-top:1.2rem;line-height:1.42;font-weight:400}
.article-byline{display:flex;flex-wrap:wrap;gap:.4rem .9rem;align-items:baseline;margin-top:1.7rem;padding-top:1.1rem;border-top:1px solid var(--line);font-size:.82rem;color:var(--muted)}
.article-byline b{color:var(--ink);font-weight:600}
.article-byline .sep{color:var(--gold)}
.article-body{font-size:1.12rem;line-height:1.8;color:var(--ink-soft)}
.article-body>p{margin:0 0 1.4rem}
.article-body>p:first-of-type::first-letter{font-family:var(--serif);font-weight:600;float:left;font-size:3.4rem;line-height:.82;padding:.28rem .55rem 0 0;color:var(--wine)}
.article-body h2{font-size:clamp(1.5rem,3vw,2rem);color:var(--ink);margin:2.6rem 0 1rem;letter-spacing:-.01em;line-height:1.15}
.article-body h3{font-size:1.3rem;color:var(--ink);margin:2rem 0 .8rem}
.article-body strong{color:var(--ink);font-weight:600}
.article-body a{color:var(--sea);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;text-decoration-color:var(--coral)}
.article-body a:hover{text-decoration-color:var(--wine)}
.article-body ul,.article-body ol{margin:0 0 1.4rem;padding-left:1.3rem}
.article-body li{margin-bottom:.5rem}
.article-body blockquote.pq{margin:2.2rem 0;padding:.2rem 0 .2rem 1.6rem;border-left:2px solid var(--wine);font-family:var(--serif);font-style:italic;font-size:clamp(1.35rem,2.6vw,1.8rem);line-height:1.35;color:var(--ink)}
.article-body figure{margin:2.2rem 0}
.article-body figure img{width:100%;border-radius:3px}
.article-body figcaption{margin-top:.7rem;font-size:.82rem;color:var(--muted);padding-left:1rem;border-left:2px solid var(--gold-soft)}
/* data tables (comparison / worked examples) */
.article-body .table-wrap{overflow-x:auto;margin:2rem 0;border:1px solid var(--line);border-radius:10px;-webkit-overflow-scrolling:touch}
.article-body table{width:100%;border-collapse:collapse;font-family:var(--sans);font-size:.96rem;line-height:1.4}
.article-body .table-wrap table{margin:0}
.article-body thead th{font-size:.68rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:#fff;background:var(--sea);text-align:left;padding:.72rem .95rem;white-space:nowrap}
.article-body thead th:not(:first-child){text-align:right}
.article-body tbody td{padding:.66rem .95rem;border-top:1px solid var(--line);color:var(--ink-soft);vertical-align:top}
.article-body tbody td:not(:first-child){text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.article-body tbody tr:nth-child(even){background:rgba(34,96,119,.045)}
.article-body tbody td:first-child{color:var(--ink);font-weight:600}
.article-body table caption{caption-side:bottom;text-align:left;font-size:.82rem;font-style:italic;color:var(--muted);padding:.6rem .2rem 0}
/* article visuals: proportion bars, key-term callout, step flow */
.article-body .viz{margin:2rem 0;padding:1.2rem 1.3rem;border:1px solid var(--line);border-radius:12px;background:#fff}
.article-body .viz figcaption{font-size:.7rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--sea);margin-bottom:1rem;font-family:var(--sans)}
.article-body .viz-row{margin-bottom:1.1rem}
.article-body .viz-row:last-of-type{margin-bottom:0}
.article-body .viz-label{display:block;font-size:.82rem;font-weight:600;color:var(--ink);margin-bottom:.4rem}
.article-body .viz-bar{display:flex;align-items:center;height:30px;border-radius:6px;padding:0 .65rem;margin-bottom:.35rem;color:#fff;font-size:.78rem;font-weight:600;white-space:nowrap;min-width:max-content;max-width:100%}
.article-body .viz-bar.a{background:#7a9aa7}
.article-body .viz-bar.b{background:var(--sea)}
.article-body .viz-bar.c{background:var(--coral-deep)}
.article-body .viz-key{display:flex;flex-wrap:wrap;gap:1.2rem;margin-top:.9rem;font-size:.72rem;color:var(--muted)}
.article-body .viz-key i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:.35rem;vertical-align:-1px}
.article-body .keyterm{margin:1.5rem 0;padding:.9rem 1.1rem;background:var(--sky);border-left:3px solid var(--sea);border-radius:0 8px 8px 0}
.article-body .keyterm b{color:var(--sea-deep)}
.article-body .keyterm>span{color:var(--ink-soft)}
.article-body .stepflow{list-style:none;counter-reset:sf;margin:1.7rem 0;padding:0}
.article-body .stepflow>li{position:relative;counter-increment:sf;padding:0 0 1.15rem 1.6rem;border-left:2px solid var(--line);margin-left:1rem}
.article-body .stepflow>li:last-child{border-left-color:transparent;padding-bottom:0}
.article-body .stepflow>li::before{content:counter(sf);position:absolute;left:-1rem;top:-.2rem;width:2rem;height:2rem;border-radius:50%;background:var(--sea);color:#fff;font-family:var(--sans);font-size:.85rem;font-weight:700;display:flex;align-items:center;justify-content:center}
.article-body .stepflow>li b{color:var(--ink);display:block;margin-bottom:.1rem}
.article-body .stepflow>li>span{color:var(--ink-soft)}
.article-foot{margin-top:clamp(2.6rem,6vw,4rem);padding-top:1.6rem;border-top:1px solid var(--ink)}
.article-foot .sig{font-family:var(--serif);font-style:italic;font-size:1.2rem;color:var(--ink)}
.article-foot .sig small{display:block;font-family:var(--sans);font-style:normal;font-size:.8rem;color:var(--muted);margin-top:.3rem;letter-spacing:.02em}

/* ===== article optimization blocks (TL;DR / FAQ / author / related) ===== */
.article-tldr{background:#fff;border:1px solid var(--line);border-left:3px solid var(--sea);border-radius:0 10px 10px 0;padding:1.15rem 1.4rem;margin:0 0 2.4rem}
.article-tldr h2{font-family:var(--sans);font-size:.72rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--sea);margin:0 0 .6rem}
.article-tldr ul{list-style:none;margin:0;padding:0}
.article-tldr li{position:relative;padding-left:1.3rem;margin-bottom:.5rem;font-size:1rem;line-height:1.5;color:var(--ink-soft)}
.article-tldr li::before{content:"\2726";position:absolute;left:0;top:.05rem;color:var(--coral);font-size:.78rem}
.article-faq{margin-top:3.2rem}
.article-faq h2{font-family:var(--serif);font-size:clamp(1.5rem,3vw,2rem);color:var(--ink);margin:0 0 .6rem;letter-spacing:-.01em}
.article-faq details{border-top:1px solid var(--line);padding:1rem 0}
.article-faq summary{font-family:var(--serif);font-weight:600;font-size:1.14rem;color:var(--ink);cursor:pointer;list-style:none;position:relative;padding-right:1.6rem}
.article-faq summary::-webkit-details-marker{display:none}
.article-faq summary::after{content:"+";position:absolute;right:0;top:-.1rem;color:var(--coral);font-size:1.4rem;line-height:1}
.article-faq details[open] summary::after{content:"\2013"}
.article-faq details p{margin:.7rem 0 0;font-size:1.02rem;line-height:1.65;color:var(--ink-soft)}
.article-author{display:flex;gap:1rem;align-items:flex-start;margin-top:2.6rem;padding:1.3rem 1.4rem;background:var(--sky);border-radius:12px}
.article-author .av{width:52px;height:52px;border-radius:50%;background:var(--sea);color:#fff;font-family:var(--serif);font-size:1.5rem;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.article-author b{color:var(--ink);font-size:1.02rem}
.article-author p{font-size:.88rem;color:var(--ink-soft);margin:.25rem 0 0;line-height:1.55}
.article-related{margin-top:2.8rem}
.article-related h2{font-family:var(--sans);font-size:.72rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--sea);margin:0 0 .3rem}
.article-related a{display:block;padding:.85rem 0;border-top:1px solid var(--line);color:var(--ink);text-decoration:none;font-family:var(--serif);font-size:1.08rem}
.article-related a:hover{color:var(--sea)}
.article-related a span{display:block;font-family:var(--sans);font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--coral-deep);margin-bottom:.15rem}


/* ============================================================
   DEPTH  atmospheric wash + grain. Both are fixed, pointer-events
   none, and sit behind content, so they cost no layout and no taps.
   ============================================================ */
body::before{content:"";position:fixed;inset:0;z-index:-2;pointer-events:none;
  background:
    radial-gradient(58% 42% at 12% 4%, rgba(248,236,190,.55) 0%, rgba(248,236,190,0) 62%),
    radial-gradient(52% 40% at 92% 14%, rgba(213,231,240,.60) 0%, rgba(213,231,240,0) 66%),
    radial-gradient(60% 34% at 70% 96%, rgba(242,221,214,.42) 0%, rgba(242,221,214,0) 68%)}
/* grain: one inline SVG turbulence, no network request */
body::after{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:.16;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E")}

/* ============================================================
   ELEVATION  shared lift for cards and rows
   ============================================================ */
.lift{transition:transform .35s var(--ease),box-shadow .35s var(--ease)}
@media (hover:hover){
  .lift:hover{transform:translateY(-3px);
    box-shadow:0 2px 5px -2px rgba(47,68,76,.10),0 14px 28px -14px rgba(47,68,76,.22)}
}

/* ============================================================
   SCROLL PROGRESS  slim coral cue under the masthead
   ============================================================ */
.progress{position:fixed;top:0;left:0;height:2px;width:100%;z-index:80;
  background:var(--coral);transform:scaleX(0);transform-origin:0 50%;
  will-change:transform;pointer-events:none}

/* ============================================================
   HERO  floating layered card with a soft plumeria bloom behind
   ============================================================ */
.hero-figure{position:relative}
.hero-figure::before{content:"";position:absolute;z-index:0;pointer-events:none;
  inset:-12% -10% 22% -14%;border-radius:48% 52% 44% 56%/52% 44% 56% 48%;
  background:radial-gradient(circle at 34% 32%, rgba(248,236,190,.85) 0%, rgba(242,221,214,.55) 44%, rgba(213,231,240,0) 74%);
  filter:blur(6px)}
.hero-photo{position:relative;z-index:1;will-change:transform}

/* ============================================================
   TESTIMONIAL  proof block. Quote is verbatim; never voice-edited.
   ============================================================ */
.quote-wrap{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,4fr);
  gap:clamp(2rem,5vw,4rem);align-items:start}
.tq{margin:0;font-family:var(--serif);font-style:italic;font-weight:500;
  font-size:clamp(1.5rem,3vw,2.25rem);line-height:1.28;color:var(--ink);
  padding-top:1.6rem;border-top:2px solid var(--coral)}
.tq-attr{margin-top:1.6rem;display:flex;align-items:baseline;gap:.7rem;flex-wrap:wrap;
  font-size:.86rem;color:var(--muted)}
.tq-attr b{font-family:var(--sans);font-weight:600;color:var(--ink);font-size:.95rem}
.tq-stat{background:var(--paper);border:1px solid var(--line);border-radius:4px;
  padding:clamp(1.4rem,3vw,2rem);
  box-shadow:0 2px 5px -2px rgba(47,68,76,.08),0 16px 30px -18px rgba(47,68,76,.18)}
.tq-stat .n{display:block;font-family:var(--serif);font-weight:600;line-height:1;
  font-size:clamp(2.6rem,5vw,3.6rem);color:var(--coral);letter-spacing:-.02em;white-space:nowrap}
.tq-stat .l{display:block;margin-top:.7rem;font-size:.84rem;color:var(--muted);line-height:1.5}
.tq-more{margin-top:2.2rem;border-top:1px solid var(--line);padding-top:1.2rem}
.tq-more summary{cursor:pointer;font-size:.78rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--sea);list-style:none}
.tq-more summary::-webkit-details-marker{display:none}
.tq-more summary::after{content:" +";font-weight:600}
.tq-more[open] summary::after{content:" \2013"}
.tq-more p{margin:1.2rem 0 0;color:var(--ink-soft);max-width:var(--measure);
  font-size:1rem;line-height:1.72}
@media (max-width:900px){.quote-wrap{grid-template-columns:1fr;gap:2rem}}

@media (prefers-reduced-motion:reduce){
  .lift,.progress,.hero-photo{transition:none;transform:none}
  .progress{display:none}
}


/* ============================================================
   MOBILE UX PASS  44px touch targets and readable label type.
   Hit areas grow via padding or an invisible ::before, never by
   changing visual size, so the layout is untouched.
   ============================================================ */
@media (max-width:900px){
  .nav-toggle{min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}
  /* dropdown nav links were 11.84px, below the 12px floor used elsewhere */
  .mast-nav a{font-size:.78rem}
  .mast-brand{display:inline-flex;align-items:center;min-height:44px}
  /* .link::after is the coral underline pinned to bottom:0, so padding would
     drag it off the text. Expand the hit area with a transparent ::before. */
  .link::before{content:"";position:absolute;inset:-11px -8px;z-index:0}
  .tq-more summary{padding-block:.75rem;min-height:44px;display:flex;align-items:center}
  /* 11px letterspaced caps are hard to read on a phone */
  .kicker{font-size:.8rem}
  .cap-label,.sub-label,.figures-top .lbl,.about-rail .meta dt,
  .cv-dates,.ledger-row .llvl,.also-item .yr2,.edu-item .m{font-size:.76rem}
  /* .hero-langs .cap-label is (0,2,0) and outranks the bare class above */
  .hero-langs .cap-label,.cv-badge{font-size:.76rem}
  .fig-l,.cap,.hero-figure figcaption{font-size:.88rem}
}

@media (max-width:560px){
  /* Fourteen single-file rows is a lot of phone scrolling. Two denser columns
     shorten the section without losing scannability. Overrides the columns:1
     rule above by source order (media queries add no specificity). */
  .skill-cols{columns:2;column-gap:1.1rem}
  .skill-cols li{padding:.42rem 0;font-size:.88rem;line-height:1.4}
}

/* ============ PROPERTIES MAP (11C) ============
   Hand-drawn SVG, no map library and no network request. Deliberately a
   stylized diagram rather than a survey: it carries the story, and the exact
   properties and dates are stated in the résumé rows above it. */
.map-block{margin-top:clamp(3rem,6vw,4.5rem);padding-top:clamp(1.8rem,4vw,2.6rem);
  border-top:1px solid var(--ink)}
.map-figure{margin:0}
.map-svg{width:100%;height:auto;display:block;border-radius:4px;
  box-shadow:0 2px 5px -2px rgba(47,68,76,.08),0 18px 34px -20px rgba(47,68,76,.18)}
.map-legend{display:flex;gap:clamp(1rem,3vw,2.4rem);flex-wrap:wrap;margin-top:1.1rem;
  font-size:.84rem;color:var(--muted);line-height:1.5}
.map-legend span{display:inline-flex;align-items:flex-start;gap:.55rem}
.map-legend i{width:9px;height:9px;border-radius:50%;flex:none;margin-top:.45em}
.map-legend .now i{background:var(--coral)}
.map-legend .then i{background:var(--sea)}
@media (max-width:560px){.map-legend{flex-direction:column;gap:.6rem}}

/* ============ EXPERTISE as a 2x2 contents spread ============
   Was four stacked full-width rows at 944px, the same shape as every other
   section. A quadrant grid gives it its own form and roughly halves its
   height. Hairlines only, no card fills. */
.index-list{display:grid;grid-template-columns:1fr 1fr;border-top:1px solid var(--ink)}
.index-row{display:block;
  padding:clamp(1.5rem,2.8vw,2.1rem) clamp(1.6rem,3vw,2.6rem) clamp(1.6rem,2.8vw,2.2rem) 0;
  border-top:0;border-bottom:1px solid var(--line)}
.index-row:nth-child(2n){padding-right:0;padding-left:clamp(1.6rem,3vw,2.6rem);
  border-left:1px solid var(--line)}
.index-row:last-child,.index-row:nth-last-child(2){border-bottom:0}
.index-row .idx{display:block;font-size:1.45rem;line-height:1;margin-bottom:.7rem}
.index-row h3{font-size:clamp(1.18rem,1.9vw,1.48rem);margin-bottom:.55rem;max-width:17ch}
.index-row p{max-width:40ch}
@media (max-width:760px){
  .index-list{grid-template-columns:1fr}
  .index-row,.index-row:nth-child(2n){padding-inline:0;border-left:0}
  .index-row:nth-last-child(2){border-bottom:1px solid var(--line)}
}

/* ============ EDUCATION as an institution masthead ============
   Both degrees are from the same school, so the old two-card layout printed
   "University of Hawai'i at Manoa" and "Hospitality Management" twice each.
   One masthead plus two degree rows says the same thing with less repetition
   and gives the section a shape of its own. */
.edu-inst{border-top:1px solid var(--ink);padding-top:1.25rem}
.edu-uni{font-size:clamp(1.3rem,2.2vw,1.68rem);line-height:1.16;margin-bottom:.9rem}
.edu-degrees{list-style:none;margin:0;padding:0}
.edu-degrees li{display:flex;justify-content:space-between;gap:1.2rem;align-items:baseline;
  padding:.8rem 0;border-top:1px solid var(--line)}
.edu-degrees li b{font-family:var(--serif);font-weight:600;font-size:1.06rem;color:var(--ink)}
.edu-degrees li span{font-size:.9rem;color:var(--muted);text-align:right}
@media (max-width:520px){
  .edu-degrees li{flex-direction:column;gap:.15rem;align-items:flex-start}
  .edu-degrees li span{text-align:left}
}

/* ============ MOBILE RHYTHM ============
   Desktop keeps its air; the phone does not have room for it. Section 12
   wants the page shorter, section 10 wants more whitespace, so the
   whitespace stays where there is room for it. */
@media (max-width:760px){
  :root{--rhythm:clamp(3rem,7vh,4.6rem)}
  .sec-head{margin-bottom:clamp(1.7rem,5vw,2.3rem)}
}

/* ============================================================
   VIDEO HERO (§13)
   The poster is painted as a CSS background so it is the LCP element and
   shows instantly; the video fades in on top only once it can play, and is
   never fetched at all on small screens, Save-Data, or reduced motion.
   Scrim alpha is computed, not guessed: the brightest 1% of the footage in
   the text region is rgb(221,223,212), against which white needs ~0.55 to
   clear 4.5:1. The text core sits at 0.74, roughly 7:1 even against the
   single brightest pixel in the frame.
   ============================================================ */
.vhero{position:relative;display:flex;align-items:center;overflow:hidden;
  min-height:min(88vh,780px);
  background:#182228 url('header-poster.jpg') center/cover no-repeat}
.vhero-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  z-index:0;opacity:0;transition:opacity .9s var(--ease)}
.vhero-video.ready{opacity:1}
.vhero-scrim{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(135% 105% at 50% 54%,
    rgba(24,34,40,.74) 0%, rgba(24,34,40,.64) 46%, rgba(24,34,40,.52) 100%)}
.vhero-inner{position:relative;z-index:2;text-align:center;color:#fff;
  padding-block:clamp(4rem,12vh,7rem)}
.vhero-eyebrow{margin:0 0 clamp(1.1rem,3vw,1.6rem);font-size:.76rem;font-weight:600;
  letter-spacing:.26em;text-transform:uppercase;color:rgba(255,255,255,.9);
  text-shadow:0 2px 14px rgba(0,0,0,.5)}
.vhero-name{font-family:var(--serif);font-weight:700;color:#fff;
  font-size:clamp(2.5rem,6.8vw,5.2rem);line-height:1.02;letter-spacing:-.02em;
  text-shadow:0 2px 18px rgba(0,0,0,.55)}
.vhero-name em{font-style:italic;font-weight:600}
/* blur-in is sanctioned by §13 for this element only; everything else in the
   system stays transform/opacity to keep the reveal pass cheap. */
.vhero-phrase{margin:clamp(1.5rem,4vw,2.4rem) auto 0;max-width:22ch;
  font-family:var(--serif);font-weight:700;color:#fff;
  font-size:clamp(1.25rem,3vw,2.15rem);line-height:1.2;letter-spacing:.05em;
  text-shadow:0 2px 14px rgba(0,0,0,.5);
  opacity:0;transform:translateY(10px) scale(.99);filter:blur(7px);
  transition:opacity .6s var(--ease),transform .6s var(--ease),filter .6s var(--ease)}
.vhero-phrase.on{opacity:1;transform:none;filter:blur(0)}
.vhero-cue{position:absolute;left:50%;bottom:clamp(1.2rem,4vh,2.4rem);z-index:2;
  transform:translateX(-50%);width:44px;height:44px;
  display:flex;align-items:flex-end;justify-content:center;padding-bottom:.5rem}
.vhero-cue span{display:block;width:1px;height:26px;
  background:linear-gradient(rgba(255,255,255,0),rgba(255,255,255,.8))}
/* the section below no longer carries the giant name */
.hero-role{margin-top:0}
@media (max-width:760px){
  /* phones paint this at <=430 CSS px; the 1280px poster was the LCP element
     and cost ~0.4s. 860px covers 2x DPR. */
  .vhero{min-height:min(74vh,620px);background-image:url('header-poster-sm.jpg')}
  /* tracking, not size: the 12px floor still applies. Keeps the eyebrow on
     one line instead of breaking mid-phrase at "SAN / FRANCISCO". */
  .vhero-eyebrow{letter-spacing:.15em}
}
@media (prefers-reduced-motion:reduce){
  .vhero-video{display:none}
  .vhero-phrase{opacity:1;transform:none;filter:none;transition:none}
}

/* ============================================================
   SECTION 14 LIVE-REVIEW FIXES
   ============================================================ */

/* A1 ROOT CAUSE: .vhero-inner is a flex item of .vhero, so with flex-grow:0
   it sized to its CONTENT (919px) instead of filling the wrap (1180px). The
   name defined the container rather than the container constraining the name,
   so at narrower widths it overflowed symmetrically and clipped both edges. */
.vhero-inner{width:100%}
.vhero-name{
  /* vw term reduced so the name never outgrows the gutter; balance keeps a
     two-line wrap even rather than stranding "Zhang". */
  font-size:clamp(2.1rem,5.6vw,4.6rem);
  text-wrap:balance;overflow-wrap:normal;max-width:100%}

/* A2: the longest phrase is "Creating Unforgettable Moments" at ~569px.
   The old max-width:22ch was ~374px, narrower than the phrase, which is what
   forced the mid-phrase break. */
.vhero-phrase{max-width:min(100%,36ch);text-wrap:balance;
  display:grid;justify-items:center;
  /* the container no longer animates; the two layers inside do */
  opacity:1;transform:none;filter:none;transition:none}
.vhero-phrase .ph{grid-area:1/1;
  opacity:0;transform:translateY(14px);filter:blur(9px);
  transition:opacity .85s var(--ease),transform .85s var(--ease),filter .85s var(--ease)}
.vhero-phrase .ph.on{opacity:1;transform:none;filter:blur(0)}

/* A3: no stranded last word in any headline */
.sec-head h2,.closing-head,.blog-top h1,.edu-uni,.index-row h3{text-wrap:balance}

/* P0: the mailto handoff is inert when the OS has no mail client, so the
   visible address is the reliable path. Copy makes a click always do
   something. */
.closing-email{display:flex;align-items:center;gap:.85rem;flex-wrap:wrap}
.copy-email{font-family:var(--sans);font-size:.72rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--sea);background:none;cursor:pointer;
  border:1px solid var(--line);border-radius:2px;padding:.5rem .8rem;
  min-height:44px;display:inline-flex;align-items:center;
  transition:background .25s,border-color .25s}
.copy-email:hover{background:var(--paper);border-color:var(--sea)}
.copy-email.done{color:var(--coral-deep);border-color:var(--coral-deep)}
/* the address itself is a tap target too, and the button must clear the 12px
   floor on a phone like every other label */
.closing-email a{display:inline-flex;align-items:center;min-height:44px}
@media (max-width:900px){.copy-email{font-size:.76rem}}

@media (prefers-reduced-motion:reduce){
  .vhero-phrase .ph{transition:none}
  .vhero-phrase .ph.on{opacity:1;transform:none;filter:none}
}

/* ============================================================
   BRAND LOGO + MASTHEAD SCROLL FADE (§14 F, §14 D9)
   Transparent bar with a soft top scrim over the video, turning solid once
   the hero is behind you. The wordmark crossfades white -> black with it.
   ============================================================ */
.mast{background:transparent;border-bottom-color:transparent;
  backdrop-filter:none;-webkit-backdrop-filter:none;
  transition:background .4s var(--ease),border-color .4s var(--ease)}
/* dark scrim so white nav type clears AA against the bright footage */
/* Alpha is computed, not guessed. The footage behind the bar reads ~252, and
   white needs ~0.61 alpha of this ink to clear 4.5:1 against it. The gradient
   therefore never drops below .64 inside the bar, and fades out below it. */
.mast::before{content:"";position:absolute;left:0;right:0;top:0;bottom:-30px;pointer-events:none;
  /* the element runs 30px past the bar so the scrim can fade out gradually;
     two stops at 100% produced a visible hard band. 0-69% is the bar itself. */
  background:linear-gradient(180deg,rgba(24,34,40,.84) 0%,rgba(24,34,40,.74) 40%,
    rgba(24,34,40,.66) 69%,rgba(24,34,40,.28) 86%,rgba(24,34,40,0) 100%);
  transition:opacity .4s var(--ease)}
.mast.solid{background:rgba(253,252,248,.9);border-bottom-color:var(--line-soft);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
.mast.solid::before{opacity:0}
.mast-row{position:relative;z-index:1}

.mast-brand{position:relative;display:block;line-height:0;flex:none}
.mast-brand img{display:block;width:auto;height:42px;transition:opacity .4s var(--ease)}
.mast-brand .brand-b{position:absolute;left:0;top:0;opacity:0}
.mast.solid .brand-w{opacity:0}
.mast.solid .brand-b{opacity:1}

/* nav sits on the dark scrim until the bar goes solid */
.mast:not(.solid) .mast-nav a{color:rgba(255,255,255,.94)}
.mast:not(.solid) .mast-nav a:hover,
.mast:not(.solid) .mast-nav a.mast-cta{color:#fff}
.mast:not(.solid) .nav-toggle{color:#fff}
/* the open mobile dropdown has its own light panel, so put the ink back */
.mast:not(.solid) .mast-nav.open a{color:var(--muted)}
.mast:not(.solid) .mast-nav.open a:hover{color:var(--ink)}

footer .foot-logo{height:56px;width:auto;display:block}
@media (max-width:900px){
  .mast-brand img{height:34px}
  footer .foot-logo{height:44px}
}

/* ============================================================
   SECTION 14 F / B / D
   ============================================================ */

/* F: the lead block under the video now opens with her name and reads bigger */
.hero-lede-name{font-family:var(--serif);font-weight:600;color:var(--ink);
  font-size:clamp(2rem,4.4vw,3.4rem);line-height:1.04;letter-spacing:-.02em;
  margin:clamp(1rem,2.5vw,1.5rem) 0 .5rem;text-wrap:balance}
.hero-lede-name em{font-style:italic;color:var(--sea);font-weight:500}
.hero-role{font-size:clamp(1.05rem,1.8vw,1.4rem)}
.hero-stand{font-size:clamp(1.08rem,1.5vw,1.22rem);max-width:50ch;line-height:1.7}

/* F: About headline was capped at 15ch, forcing three lines */
.about-body h2{max-width:20ch}

/* F + D: the closing block read as a narrow centred column while every other
   section is left-aligned editorial. .closing-inner IS the .wrap, so killing
   its auto margin threw it outside the gutter; instead keep the standard
   1180 wrap and left-align its CONTENTS to the same rhythm as the rest. */
.closing-inner{max-width:1180px}
.closing-inner>*{max-width:62ch;margin-left:0;margin-right:auto}
.closing-inner .closing-head{max-width:18ch}

/* D9: soften the hard edge where the page meets the sunrise band */
.closing{position:relative}
.closing::before{content:"";position:absolute;left:0;right:0;top:0;height:clamp(48px,7vw,96px);
  background:linear-gradient(180deg,var(--bg),rgba(253,252,248,0));pointer-events:none}
.closing-inner{position:relative;z-index:1}

/* B6: one restrained marker per section. A honey wash behind the words, not a
   neon highlight, and it sits behind text so contrast is unchanged. */
.mark{background:linear-gradient(180deg,rgba(212,185,106,0) 58%,rgba(212,185,106,.38) 58%);
  padding-bottom:.05em}

/* B5: Experience stops reading like a CV. The role leads, the company is
   secondary, the dash bullets become hairline-ruled statements, and each row
   lifts on hover. */
.cv-row{transition:background .3s var(--ease)}
@media (hover:hover){.cv-row:hover{background:rgba(34,96,119,.035)}}
.cv-co{font-family:var(--sans);font-size:.98rem;font-weight:600;color:var(--ink-soft);
  letter-spacing:0;margin-top:.5rem}
.cv-role{font-size:clamp(1.55rem,2.8vw,2.15rem);letter-spacing:-.015em}
.cv-list{gap:0}
.cv-list li{padding:.85rem 0 .85rem 0;border-top:1px solid var(--line-soft);
  max-width:66ch;transition:color .25s}
.cv-list li:first-child{border-top:0;padding-top:.2rem}
.cv-list li::before{display:none}
.cv-list li b{color:var(--ink);font-weight:600}

/* B7: About gets a shape no other section has. The quote rail stays with you
   while the body scrolls past it. */
@media (min-width:901px){
  .about-rail{position:sticky;top:96px;align-self:start}
  .about-grid{align-items:start}
}

/* ============================================================
   SECTION 14 E  DESKTOP AUDIT
   Twelve sessions of audits ran at 390px only. On desktop the small caps
   labels sat at 10.6-11.8px and nav links were ~20px tall against WCAG 2.2's
   24px target minimum. Floor the label type at 12px and give every
   interactive element a real target, without changing the editorial look.
   ============================================================ */
.kicker,.sub-label,.cv-dates,.ledger-row .llvl,.also-item .yr2,
.p-cat,.p-soon,.cv-badge,.figures-top .lbl,.hero-langs .cap-label,
.about-rail .meta dt,.copy-email,.tq-more summary,.edu-item .m{font-size:.75rem}
.map-legend{font-size:.84rem}

/* interactive targets: 24px minimum everywhere, 44px on touch (set earlier) */
/* scoped to desktop: unscoped, this appended rule overrode the mobile
   dropdown's .95rem padding and collapsed those links from 44px to 34px */
@media (min-width:901px){.mast-nav a{padding-block:.42rem}}
.mast-nav a{font-size:.75rem}
.mast-brand{min-height:24px}
@media (max-width:900px){.mast-brand{min-height:44px;display:flex;align-items:center}}
/* .link::after is the coral underline pinned to bottom:0, so the hit area is
   grown with a transparent ::before rather than padding */
.link::before{content:"";position:absolute;inset:-9px -6px;z-index:0}
.vhero-cue{min-width:44px;min-height:44px}
@media (min-width:901px){.copy-email{min-height:36px}}
/* the summary only had a 44px rule under the mobile block */
.tq-more summary{min-height:28px;display:inline-flex;align-items:center}
