/* Portfolio. Tokens and base reset come from tokens.css. */

/* ---------- hero ---------- */
.hero { background:var(--band); }
.hero__in { max-width:var(--wrap); margin:0 auto; padding:clamp(1.6rem,4vw,2.9rem) var(--pad);
            display:flex; gap:clamp(1rem,3vw,2.1rem); align-items:center; flex-wrap:wrap; }
.hero__pt { flex:none; width:clamp(68px,10vw,128px); height:clamp(68px,10vw,128px);
            object-fit:cover; border-radius:50%; border:clamp(3px,.4vw,5px) solid var(--on-band); }
.hero__stack { flex:1 1 20rem; min-width:0; display:flex; flex-direction:column; gap:.85rem; }
.hero__name { font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800; letter-spacing:-.035em; line-height:.9;
              font-size:clamp(2rem,5.4vw,3.5rem); color:var(--on-band); }
.hero__claim { font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800; letter-spacing:-.035em; line-height:.94;
               font-size:clamp(1.62rem,3vw,1.875rem); color:var(--on-band); }
.hero__long { max-width:38rem; font-size:clamp(.94rem,1.5vw,1.03rem); line-height:1.45;
              color:var(--on-band); opacity:.86; text-wrap:pretty; }
.hero__acts { flex:none; display:flex; gap:.6rem; align-items:center; align-self:flex-start; }
.hero__cta { display:inline-flex; align-items:center; gap:.55rem; min-height:44px; padding:0 1.35rem;
             border:1.5px solid var(--on-band); border-radius:999px; color:var(--on-band);
             text-decoration:none; font-size:.875rem; font-weight:700; }
.hero__cta:hover { background:var(--on-band); color:var(--band); }
.hero__theme { width:44px; height:44px; border-radius:999px; border:1.5px solid var(--on-band);
               background:none; color:var(--on-band); cursor:pointer; display:grid; place-items:center; }
.hero__theme:hover { background:var(--on-band); color:var(--band); }

/* ---------- lens chips ---------- */
.lenses { max-width:var(--wrap); margin:0 auto; padding:1.5rem var(--pad) 1.15rem; }
.lenses ul { display:flex; flex-wrap:wrap; gap:.4rem; }
.lenses a { display:inline-block; padding:.45rem .85rem; border-radius:999px; border:1px solid var(--edge);
            font-size:.8rem; font-weight:500; color:var(--ink); text-decoration:none; }
.lenses a:hover { border-color:var(--accent); color:var(--accent); }
.lenses a[aria-current="page"] { background:var(--accent); border-color:var(--accent); color:var(--paper); font-weight:700; }

/* ---------- start here ---------- */
main { max-width:var(--wrap); margin:0 auto; padding:0 var(--pad) 2rem; }
/* Was a filled, rounded, 2px-bordered card. The page reads as an editorial
   document now, so this is a ruled section like any other: no fill, no box,
   one terracotta rule to mark where it starts. */
.start { margin-top:2rem; padding:1.4rem 0 0; border-top:3px solid var(--accent); }
/* The first shift on a lens page sits right under Start here, and .sh draws a
   rule in --ink, which is near-white in the dark theme. Two headed sections in
   a row do not need a divider between them. */
.start + .filterbar + .sh { border-top:0; }
.start__h { font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800; letter-spacing:-.025em; font-size:1.25rem; }
.start__p { margin-top:.25rem; font-size:.85rem; line-height:1.5; color:var(--strong); max-width:44rem; }
.start__grid { margin-top:1rem; display:grid; grid-template-columns:repeat(auto-fill,minmax(11rem,1fr)); gap:.7rem; }
.start__c a, .start__c > span { display:flex; flex-direction:column; gap:.4rem; padding:.6rem;
  background:none; border:1px solid var(--edge); border-radius:6px; text-decoration:none; color:var(--ink); height:100%; }
.start__c a:hover { border-color:var(--accent); }
.start__c .th { width:100%; height:auto; aspect-ratio:16/9; }
.start__tt { font-size:.83rem; font-weight:700; line-height:1.25; }
.start__me { font-size:.75rem; font-weight:700; color:var(--accent); }

/* ---------- filter bar ---------- */
.filterbar { position:sticky; top:0; z-index:9; margin-top:1.2rem; display:flex; gap:1rem;
  align-items:center; justify-content:space-between; padding:.7rem 1rem; border-radius:9px;
  background:var(--tint); border:1px solid var(--accent-edge); font-size:.85rem; }
.filterbar b { color:var(--accent); }
.filterbar button { border:1px solid var(--accent); background:none; color:var(--accent);
  border-radius:999px; padding:.35rem .9rem; font:inherit; font-size:.8rem; font-weight:700; cursor:pointer; min-height:34px; }

/* ---------- shifts ---------- */
.sh { padding:1.9rem 0 1.6rem; border-top:2px solid var(--ink); }
.sh--origin { border-top:1px solid var(--edge); }
.sh__head { display:flex; gap:clamp(.75rem,2vw,1.6rem); align-items:flex-start; }
.sh__num { flex:none; width:auto; min-width:clamp(2.6rem,6vw,4.6rem); padding-right:clamp(.4rem,1vw,.9rem);
           white-space:nowrap; font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800;
           font-size:clamp(1.15rem,2.7vw,1.75rem); line-height:1.05; letter-spacing:-.02em; color:var(--accent); }
.sh__num--o { color:var(--quiet); }
.sh__body { flex:1; min-width:0; }
.sh__yrs { font-size:.72rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
.sh__arrow { margin-top:.55rem; font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800; letter-spacing:-.028em;
             line-height:1.16; font-size:clamp(1.25rem,2.6vw,1.8rem); max-width:46rem; text-wrap:pretty; }
.sh__a { color:var(--quiet); }
.sh__x { margin:0 .7rem; color:var(--accent); display:inline-block; }
.sh__b { color:var(--ink); }
.sh__ind { margin-top:.8rem; max-width:44rem; font-size:.9rem; line-height:1.55; color:var(--strong); text-wrap:pretty; }
.sh__mine { margin-top:.55rem; max-width:44rem; font-size:.9rem; line-height:1.55; text-wrap:pretty; }
.sh__mine strong { color:var(--accent); }
/* One comfortable column rather than two, capped at a 50rem measure, with a
   rule down the side so the eye reads it as a single block to take or skip
   rather than as two competing panels. */
.blanks, .sh__filled { display:grid; grid-template-columns:1fr; gap:1rem;
                       margin-top:1.1rem; max-width:50rem;
                       border-left:4px solid var(--accent); padding-left:clamp(.9rem,2vw,1.4rem); }
.blank { padding:.7rem .85rem .75rem; border:2px dashed var(--edge); border-radius:9px; background:var(--sunk); }
.blank__l, .sh__lab { display:flex; align-items:center; gap:.5rem; font-size:.68rem; font-weight:700;
                      letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.blank__tag { padding:.12rem .45rem; border-radius:999px; background:var(--rule); color:var(--muted); font-size:.6rem; letter-spacing:.06em; }
.blank__t { margin-top:.45rem; font-size:.78rem; line-height:1.5; color:var(--quiet); font-style:italic; text-wrap:pretty; }
.sh__filled p + p { margin-top:.4rem; font-size:.88rem; line-height:1.55; color:var(--strong); }

/* ---------- rows ---------- */
.rows { margin-top:1.1rem; }
.sh .rows { margin-left:clamp(0px,4vw,5.5rem); }
.row { border-top:1px solid var(--rule); }
.row__hit { width:100%; display:grid; gap:clamp(.6rem,1.6vw,1rem); align-items:center; text-align:left;
  grid-template-columns:5.1rem 7rem minmax(0,1fr) 11rem 1.9rem;
  padding:.5rem .6rem; margin:0; border:0; border-radius:7px; background:none; color:inherit;
  font:inherit; cursor:pointer; min-height:52px; }
.row__hit:hover, .row__hit[aria-expanded="true"] { background:var(--sunk); box-shadow:inset 3px 0 0 var(--accent); }
.row__yr { font-size:.72rem; font-weight:700; color:var(--muted); }
.row__tt { font-size:.97rem; font-weight:700; line-height:1.25; letter-spacing:-.008em; }
.row__me { text-align:right; font-size:.875rem; font-weight:700; color:var(--accent); line-height:1.3; }
.row__aff { display:grid; place-items:center; width:26px; height:26px; border-radius:999px;
            border:1.5px solid var(--accent); color:var(--accent); opacity:0; transition:opacity .15s; }
.row__hit:hover .row__aff, .row__hit:focus-visible .row__aff, .row__hit[aria-expanded="true"] .row__aff { opacity:1; }
.row__hit[aria-expanded="true"] .row__aff svg path { d:path("M5 12h14"); }
.row__d { background:var(--sunk); box-shadow:inset 3px 0 0 var(--accent); border-radius:0 0 7px 7px; }
.row__dinner { padding:.9rem 1.1rem 1.1rem clamp(1rem,7vw,10.5rem); }
.row__role { font-size:.72rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.row__body { margin-top:.4rem; max-width:42rem; font-size:.92rem; line-height:1.6; text-wrap:pretty; }
.row__lab { margin-top:.8rem; font-size:.68rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.row__links { margin-top:.8rem; display:flex; flex-wrap:wrap; gap:1rem; }
.row__links a { display:inline-flex; align-items:center; gap:.35rem; font-size:.85rem; font-weight:700; min-height:44px; }

/* ---------- thumbnails + the seven primitives ---------- */
.th { position:relative; display:block; width:7rem; height:3.95rem; border-radius:5px;
      overflow:hidden; background:var(--band); flex:none; }
.th img { width:100%; height:100%; object-fit:cover; opacity:1; transition:opacity .25s; }
.th--ph { display:grid; place-items:center; background:var(--tint); }
.th__i { font-size:.72rem; font-weight:700; letter-spacing:.05em; color:var(--accent); }
.ov { position:absolute; inset:0; width:100%; height:100%; fill:none; stroke:var(--on-band);
      stroke-width:6; stroke-linecap:round; stroke-linejoin:round; opacity:0; transition:opacity .2s; }
.ov circle { fill:var(--on-band); stroke:none; }
.ov .blk rect, .ov .stbox, .ov .fillbox { fill:none; stroke:var(--on-band); }
.ov .filllevel { fill:var(--on-band-a); stroke:none; }
.ov .fitline, .ov .cln { stroke:var(--on-band-a); }

.d { stroke-dasharray:100; stroke-dashoffset:100; }
.p { opacity:0; transform-box:fill-box; transform-origin:center; }
.fitline { opacity:0; transform-origin:120px 69px; }
.blk { opacity:0; }
.st { opacity:0; } .stbox { opacity:0; fill:none; }
.fillbox { opacity:0; } .filllevel { opacity:0; }
.rgh { opacity:0; } .cln { stroke-dasharray:100; stroke-dashoffset:100; opacity:0; }
.sp { opacity:0; transform-box:fill-box; transform-origin:left center; } .hub { opacity:0; }

.s2{animation-delay:.07s}.s3{animation-delay:.14s}.s4{animation-delay:.21s}.s5{animation-delay:.28s}.s6{animation-delay:.35s}
.p2{animation-delay:.035s}.p3{animation-delay:.07s}.p4{animation-delay:.105s}.p5{animation-delay:.14s}
.p6{animation-delay:.175s}.p7{animation-delay:.21s}.p8{animation-delay:.245s}.p9{animation-delay:.28s}.p10{animation-delay:.315s}
.b-m{animation-delay:.06s}.b-r{animation-delay:.12s}
.st2{animation-delay:.14s}.st3{animation-delay:.28s}.st4{animation-delay:.42s}
.sp2{animation-delay:.09s}.sp3{animation-delay:.18s}

/* ---------- candidates, credentials ---------- */
.cands, .creds, .comps { padding:1.9rem 0 1.4rem; border-top:2px solid var(--ink); }
.cands__note { margin-top:.35rem; font-size:.85rem; color:var(--quiet); max-width:42rem; }
.cand { margin-top:.9rem; padding:1rem 1.1rem; border:2px dashed var(--accent-edge); border-radius:12px; background:var(--tint); }
.cand__l { font-size:.68rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--accent); }
.cand__t { margin-top:.2rem; font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800; font-size:1.15rem; letter-spacing:-.02em; }
.cand__n { margin-top:.4rem; max-width:42rem; font-size:.85rem; line-height:1.5; color:var(--strong); }
.cand .rows { margin-top:.5rem; margin-left:0; }
.creds__grid { margin-top:1rem; display:grid; grid-template-columns:repeat(auto-fit,minmax(14rem,1fr)); gap:1.4rem; }
.cred__h { font-size:.68rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--accent); }
.cred ul { margin-top:.5rem; display:flex; flex-direction:column; gap:.45rem; }
.cred li { font-size:.85rem; line-height:1.4; font-weight:700; }
.cred li span { display:block; font-weight:400; color:var(--muted); font-size:.8rem; }
.cred__award { margin-top:.45rem; font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800; font-size:1.05rem; letter-spacing:-.02em; }
.cred__org { font-size:.8rem; font-weight:700; color:var(--accent); }
.cred__note { margin-top:.4rem; font-size:.82rem; line-height:1.5; color:var(--strong); }

/* ---------- competencies ---------- */
.comps__top { display:flex; gap:2rem; align-items:flex-start; flex-wrap:wrap; }
.comps__lede { margin-top:.5rem; max-width:40rem; font-size:.9rem; line-height:1.55; color:var(--strong); text-wrap:pretty; }
.comps__sub { margin-top:.4rem; max-width:40rem; font-size:.82rem; line-height:1.5; color:var(--quiet); }
.legend { display:flex; flex-wrap:wrap; gap:.5rem 1.3rem; margin-top:1rem; padding:.75rem 1rem;
          border:1px solid var(--rule); border-radius:10px; background:var(--sunk); }
.legend li { display:flex; align-items:center; gap:.5rem; font-size:.78rem; color:var(--strong); }
.mk { display:inline-flex; gap:.15rem; flex:none; }
.mk i, .legend i { font-style:normal; font-size:.6rem; font-weight:700; letter-spacing:.03em; line-height:1; padding:.2rem .26rem; border-radius:3px; }
/* The origin mark reads as one of the set. It was gray on gray, which made the
   one section that is not a shift look like a disabled version of the others
   rather than a peer. Only the thread mark stays apart, and that is deliberate:
   it is outlined because it runs through all of them. */
.mk--shift, .legend .mk--shift,
.mk--origin, .legend .mk--origin { background:var(--tint); color:var(--accent); }
.mk--thread, .legend .mk--thread { background:none; border:1px solid var(--accent-edge); color:var(--accent); padding:.13rem .2rem; }
.comps__cols { margin-top:1.2rem; columns:2; column-gap:2.2rem; }
@media (max-width:52rem) { .comps__cols { columns:1; } }
.cg { break-inside:avoid; margin-bottom:1.3rem; }
.cg__h { display:flex; align-items:baseline; gap:.55rem; margin-bottom:.5rem; font-size:.68rem;
         font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--accent); }
.cg__n { font-size:.65rem; color:var(--quiet); }
.chips { display:flex; flex-wrap:wrap; gap:.35rem; margin-top:.85rem; }
.chip { display:inline-flex; align-items:center; gap:.4rem; padding:.28rem .55rem .28rem .65rem;
        border-radius:999px; background:none; border:1px solid var(--edge); color:var(--muted);
        font-size:.78rem; line-height:1.2; }
.chip--dim { border-style:dashed; border-color:var(--edge); background:none; color:var(--quiet); padding:.28rem .65rem; }
.chip__b { border:0; background:none; padding:0; margin:0; font:inherit; color:inherit; cursor:pointer; text-align:left; }
.chip:has(.chip__b):hover { border-color:var(--accent); }
.chip[aria-pressed="true"] { border-color:var(--accent); color:var(--accent); background:var(--tint); }

/* ---------- contact ---------- */
/* This was a filled slab with solid cream inputs, the last thing left from the
   design before this one. Everything else on the page is hollow: a rule, a thin
   border, ink on paper. The form is now built from the same parts, so it reads
   as the end of the document rather than as a widget dropped onto it. */
/* .cf sits outside <main>, which is what carries the horizontal padding, so
   it has to bring its own or it runs to the screen edge on a phone. */
.cf { max-width:var(--wrap); margin:2.4rem auto 3rem; padding:1.6rem var(--pad) 0;
      border-top:3px solid var(--accent); display:grid; gap:clamp(1.2rem,3vw,2.5rem);
      grid-template-columns:minmax(0,.8fr) minmax(0,1fr); }
.cf__h { font-family:var(--disp); font-variation-settings:var(--disp-vf); font-weight:800; font-size:clamp(1.5rem,3.4vw,2.125rem); letter-spacing:-.03em; line-height:1; color:var(--strong); }
.cf__p { margin-top:.7rem; font-size:.95rem; line-height:1.5; color:var(--ink); text-wrap:pretty; }
.social { display:flex; gap:.6rem; margin-top:1rem; }
.social a { display:grid; place-items:center; width:44px; height:44px; border-radius:999px;
            border:1px solid var(--edge); color:var(--ink); }
.social a:hover { border-color:var(--accent); color:var(--accent); }
.cf__form { display:flex; flex-direction:column; gap:.7rem; }
.cf__pair { display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr)); gap:.7rem; }
.cf__form label { display:block; font-size:.66rem; font-weight:700; letter-spacing:.11em;
                  text-transform:uppercase; color:var(--muted); margin-bottom:.35rem; }
.cf__form input, .cf__form textarea { width:100%; min-height:44px; padding:.55rem .7rem;
  border:1px solid var(--edge); border-radius:7px; background:var(--sunk); color:var(--ink);
  font:inherit; font-size:.92rem; }
.cf__form input:focus-visible, .cf__form textarea:focus-visible {
  outline:none; border-color:var(--accent); box-shadow:inset 2px 0 0 var(--accent); }
.cf__form textarea { min-height:6rem; resize:vertical; }
.cf__gotcha { position:absolute; left:-9999px; }
.cf__send { display:flex; align-items:center; gap:.9rem; flex-wrap:wrap; margin-top:.2rem; }
.cf__send button { min-height:44px; padding:0 1.6rem; border:1px solid var(--accent); border-radius:999px;
  background:none; color:var(--accent); font:inherit; font-size:.9rem; font-weight:700; cursor:pointer; }
.cf__send button:hover { background:var(--accent); color:var(--paper); }
.cf__send button[disabled] { opacity:.55; cursor:not-allowed; }
.cf__send button[disabled]:hover { background:none; color:var(--accent); }
.cf__no { font-size:.75rem; color:var(--quiet); }
.cf__status { font-size:.82rem; color:var(--accent); }
.foot { max-width:var(--wrap); margin:0 auto; padding:0 var(--pad) 2.5rem; font-size:.78rem; color:var(--quiet); }

/* ---------- narrow ---------- */
@media (max-width:60rem) { .cf { grid-template-columns:1fr; } }
@media (max-width:46rem) {
  .hero__in { gap:.9rem; }
  .hero__stack { flex-basis:100%; order:3; }
  .hero__acts { order:2; margin-left:auto; }
  .sh .rows { margin-left:0; }
  /* The year and the outcome each get a row. They used to share one cell, so
     any outcome longer than a few words ran underneath the year. */
  .row__hit { grid-template-columns:5.5rem minmax(0,1fr); grid-template-areas:"th tt" "th yr" "th me"; row-gap:.1rem; padding:.55rem .4rem; }
  /* The width is the track, not a number repeated from the line above: .th
     carries a fixed 7rem for the desktop grid and would otherwise overhang
     this narrower column and sit on top of the title. */
  .row__hit .th { grid-area:th; width:100%; height:auto; aspect-ratio:16/9; }
  .row__tt { grid-area:tt; font-size:.9rem; }
  .row__yr { grid-area:yr; color:var(--muted); }
  .row__me { grid-area:me; text-align:left; justify-self:start; font-size:.75rem; line-height:1.3; }
  .row__aff { display:none; }
  .row__dinner { padding:.8rem .7rem 1rem; }
  .sh__arrow { display:flex; flex-direction:column; gap:.2rem; }
  .sh__x { margin:0; }
  .sh__x::before { content:"\2193"; }
  .sh__x { font-size:0; }
  .sh__x::before { font-size:1.35rem; }
}

/* ---------- motion off ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration:.001ms !important; animation-iteration-count:1 !important;
                           transition-duration:.001ms !important; scroll-behavior:auto !important; }
  .ov { opacity:0 !important; }
}

/* ---------- the one reveal ---------- */
.js .sh__arrow .sh__x { opacity:0; transform:translateX(-.4rem); }
.js .sh__arrow .sh__b { opacity:.22; }
.js .sh__arrow.is-revealed .sh__x { opacity:1; transform:none; transition:opacity .24s ease-out, transform .24s ease-out; }
.js .sh__arrow.is-revealed .sh__b { opacity:1; transition:opacity .38s ease-out .08s; }
@media (prefers-reduced-motion: reduce) {
  .js .sh__arrow .sh__x { opacity:1; transform:none; }
  .js .sh__arrow .sh__b { opacity:1; }
}
.foot__sub { margin-top:.4rem; font-size:.78rem; color:var(--muted); }

/* Vector icons are square artwork in a 16:9 box: contain them, do not crop. */
/* A single-colour glyph is drawn through a mask rather than shown as an image,
   so it takes --ink and follows the theme. An <img> cannot be recoloured by
   CSS, and a cream glyph baked into the file only worked while the dark box
   was behind it. --ic is set per icon in the markup. */
.th--icon { background:none; border-radius:0; padding:.28rem .4rem; }
.th--icon i { display:block; width:100%; height:100%; background:var(--ink);
  -webkit-mask:var(--ic) center/contain no-repeat; mask:var(--ic) center/contain no-repeat; }
.start__c .th--icon { padding:.5rem; }

/* Brand marks keep their own colors, so they stay images rather than masks.
   They needed a cream plate while they were drawn for a white page. The files
   now carry no background of their own and read on either ground, so the plate
   is gone too and they sit on the page like the glyphs. */
.th--art { background:none; border-radius:0; }
.th--art img { object-fit:contain; padding:.28rem .4rem; }
.start__c .th--art img { padding:.5rem; }
