/* Layout: bold uppercase display over white, alternating text/image blocks,
   one saturated accent, a hand-drawn ring on the word that carries the claim. */
:root{
  --paper:#FAF6EF; --ink:#113C45; --ink-2:#1F525C; --mute:#5F858D;
  --rule:#E8E0D4; --wash:#F3EBDF;
  --band-a:#2A7F8F; --band-b:#0E4452; --band-fg:#FFFFFF; --band-dim:#CBE6EA;
  --brand:#6FC1CD; --brand-fade:rgba(111,193,205,.82); --accent:#10707F; --accent-deep:#FFE500; --accent-ink:#0F4C5A;
  --highlight:#FFFFFF; --deep:#0F4C5A; --book:#3EB0C9;
  --sky:#DCEFF2; --blush:#F5EDE1; --band-grey:#DBE2DF;
  --gutter:clamp(1rem,5vw,4rem); --maxw:76rem; --mast-h:5.2rem;
  --dsp:"Outfit","Helvetica Neue",Arial,sans-serif;
  --bdy:"Nunito","Helvetica Neue",Arial,sans-serif;
  color-scheme:light;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --paper:#0A1E22; --ink:#EEF8F9; --ink-2:#D2E7EA; --mute:#88ACB3;
  --rule:#1D3B42; --wash:#102D33;
  --band-a:#2B7E8D; --band-b:#0E444F; --band-fg:#FFFFFF; --band-dim:#CBE6EA;
  --brand:#6FC1CD; --brand-fade:rgba(111,193,205,.82); --accent:#7FD3DF; --accent-deep:#FFE500; --accent-ink:#0F4C5A;
  --highlight:#FFFFFF; --deep:#0F4C5A;
  --sky:#0F2A31; --blush:#143840; color-scheme:dark;
}}
:root[data-theme="dark"]{
  --paper:#0A1E22; --ink:#EEF8F9; --ink-2:#D2E7EA; --mute:#88ACB3;
  --rule:#1D3B42; --wash:#102D33;
  --band-a:#2B7E8D; --band-b:#0E444F; --band-fg:#FFFFFF; --band-dim:#CBE6EA;
  --brand:#6FC1CD; --brand-fade:rgba(111,193,205,.82); --accent:#7FD3DF; --accent-deep:#FFE500; --accent-ink:#0F4C5A;
  --highlight:#FFFFFF; --deep:#0F4C5A;
  --sky:#0F2A31; --blush:#143840; color-scheme:dark;
}
*{box-sizing:border-box}
body{background:var(--paper);color:var(--ink-2);font-family:var(--bdy);font-weight:300;
  font-size:clamp(1rem,.95rem + .3vw,1.2rem);line-height:1.42;margin:0;
  -webkit-font-smoothing:antialiased}
.wrap{max-width:76rem;margin:0 auto;padding-inline:clamp(1rem,5vw,4rem);padding-block:0}
h1,h2,h3,.dsp{font-family:var(--dsp);font-weight:700;text-transform:uppercase;
  letter-spacing:.04em;line-height:1.06;color:var(--ink);margin:0;text-wrap:balance}
a{color:inherit}
a:focus-visible,button:focus-visible{outline:3px solid var(--accent);outline-offset:3px}

/* header: transparent over the hero image, solid once scrolled or on inner pages */
.mast{position:fixed;top:0;left:0;right:0;z-index:30;background:transparent;
  transition:background-color .28s ease,box-shadow .28s ease}
.mast-in{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:1rem;
  padding:.85rem var(--gutter);transition:padding-block .28s ease}
.mast.shrunk .mast-in{padding-block:.45rem}
body.inner{padding-top:var(--mast-h)}

.mark{display:flex;align-items:center;gap:.7rem;text-decoration:none;justify-self:start}
.logo{position:relative;display:block;flex:none;line-height:0}
.logo img{display:block;width:clamp(2.3rem,4.2vw,3rem);height:auto;
  transition:width .28s ease,opacity .28s ease}
.logo .m-dark{position:absolute;left:0;top:0;opacity:0}
.mast.shrunk .logo img,.mast.solid .logo img{width:clamp(1.8rem,3.2vw,2.3rem)}
.mast.shrunk .logo .m-light,.mast.solid .logo .m-light{opacity:0}
.mast.shrunk .logo .m-dark,.mast.solid .logo .m-dark{opacity:1}

.who{display:flex;flex-direction:column;gap:.18rem;line-height:1.15}
.who b{font-family:var(--dsp);font-weight:700;font-size:.98rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--highlight);transition:color .28s ease}
.pill{justify-self:center;display:flex;gap:.2rem;padding:.25rem;border-radius:999px;
  background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.34);
  font-family:var(--dsp);font-weight:700;font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;transition:background-color .28s ease,border-color .28s ease}
.pill a{text-decoration:none;color:rgba(255,255,255,.88);padding:.45rem 1.05rem;
  border-radius:999px;transition:background-color .2s ease,color .2s ease}
.pill a:hover{color:#fff}
.pill a[aria-current]{background:var(--accent-deep);color:var(--accent-ink)}
.out{justify-self:end;margin:0;font-family:var(--dsp);font-weight:700;font-size:.7rem;
  letter-spacing:.1em;text-transform:uppercase}
.out a{color:rgba(255,255,255,.92);text-decoration:none;transition:color .28s ease}
.out a:hover{color:#fff}

.mast.shrunk,.mast.solid{background:rgba(250,246,239,.62);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  box-shadow:0 1px 0 var(--rule)}
.mast.shrunk .who b,.mast.solid .who b{color:#111418}
.mast.shrunk .pill,.mast.solid .pill{background:var(--blush);border-color:var(--rule)}
.mast.shrunk .pill a,.mast.solid .pill a{color:#3C4649}
.mast.shrunk .pill a:hover,.mast.solid .pill a:hover{color:#111418}
.mast.shrunk .pill a[aria-current],.mast.solid .pill a[aria-current]{
  background:var(--accent-deep);color:var(--accent-ink)}
.mast.shrunk .out a,.mast.solid .out a{color:#3C4649}
.mast.shrunk .out a:hover,.mast.solid .out a:hover{color:#111418}

@media (max-width:760px){
  .mast-in{grid-template-columns:1fr auto}
  .out{display:none}
}

/* hero: a browser window on a teal desk */
.stage{position:relative;overflow:hidden;
  /* amber blended into the photo warms the midtones; the teal wash below
     stays on the shadows, so the hero is split toned rather than one flat cast */
  background-color:var(--deep);
  background-image:linear-gradient(rgba(216,140,72,.42),rgba(216,140,72,.42)),
    url("img/hero-lake.jpg");
  background-position:0 0,18% 70%;
  background-size:auto,130% auto;
  background-repeat:no-repeat,no-repeat;
  background-blend-mode:soft-light,normal;
  padding:calc(var(--mast-h) + clamp(.4rem,1.5vw,1.2rem)) var(--gutter) 0}
.stage::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(11,58,70,.34) 0%,rgba(9,45,56,.42) 45%,
    rgba(5,33,42,.56) 100%)}
.stage::after{content:"";position:absolute;inset:0;pointer-events:none;
  -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
  -webkit-mask-image:linear-gradient(180deg,transparent 63%,#000 67.5%,#000 72%,transparent 77%);
  mask-image:linear-gradient(180deg,transparent 63%,#000 67.5%,#000 72%,transparent 77%)}
.stage > *{position:relative;z-index:1}
.win-wrap{will-change:transform}
/* 2026-10-24, her call: the hero sheet is white rather than the cream
   --paper, and its two accent words take the same #3B9CAA as "Human." on
   About, so the two pages match. On white the blue measures 3.22:1, which
   clears the 3:1 large-text minimum; where the yellow highlighter runs under
   the lower part of each word it is 2.78:1. The words are 88px at desktop,
   so they stay legible, but the highlighter band is the weak spot. The old
   teal --band-a was 4.63:1 on white, 4.00:1 on the highlighter. */
.win .lede em,.win .lede i{color:#3B9CAA}
/* the sheet rises into place on load, then the scroll parallax takes the wrapper */
@keyframes winRise{from{transform:translate3d(0,78px,0);opacity:0}
  to{transform:none;opacity:1}}
.win{animation:winRise 1.05s cubic-bezier(.16,.84,.26,1) .1s both;
  position:relative;max-width:72rem;margin:0 auto;background:#FFFFFF;
  border-radius:16px;overflow:hidden;display:flex;flex-direction:column;
  min-height:clamp(24rem,63vh,38rem);
  box-shadow:0 2px 0 rgba(255,255,255,.3) inset,0 34px 80px rgba(0,0,0,.45),
    0 2px 10px rgba(0,0,0,.3);
  /* smoothstep, so the fade begins at zero slope: a linear mask kinks at its
     first stop and the eye reads that kink as a line (Mach band) */
  -webkit-mask-image:linear-gradient(180deg,#000 68%,
    rgba(0,0,0,0.957) 72%,
    rgba(0,0,0,0.844) 76%,
    rgba(0,0,0,0.684) 80%,
    rgba(0,0,0,0.500) 84%,
    rgba(0,0,0,0.316) 88%,
    rgba(0,0,0,0.156) 92%,
    rgba(0,0,0,0.043) 96%,
    transparent 100%);
  mask-image:linear-gradient(180deg,#000 68%,
    rgba(0,0,0,0.957) 72%,
    rgba(0,0,0,0.844) 76%,
    rgba(0,0,0,0.684) 80%,
    rgba(0,0,0,0.500) 84%,
    rgba(0,0,0,0.316) 88%,
    rgba(0,0,0,0.156) 92%,
    rgba(0,0,0,0.043) 96%,
    transparent 100%)}
.win-bar{flex:none;display:flex;align-items:center;gap:.55rem;height:2.5rem;
  padding-inline:1.05rem;background:linear-gradient(#F5F6F6,#E1E4E5);
  border-bottom:1px solid #D2D6D7}
.dot{width:.72rem;height:.72rem;border-radius:50%}
.dot.r{background:#FF5F57}.dot.y{background:#FEBC2E}.dot.g{background:#28C840}
.win-body{flex:1;display:flex;flex-direction:column;justify-content:center;
  will-change:opacity;
  padding:clamp(1rem,2vw,1.5rem) clamp(1.4rem,5vw,4.2rem) clamp(6rem,14vw,10.5rem)}
.lede{font-size:clamp(2.1rem,.6rem + 6.6vw,5.4rem);line-height:1.04;letter-spacing:-.035em;
  font-weight:800;
  text-transform:none;color:#3C4649}
/* Hero entrance. Every base state below is the finished state, so with
   prefers-reduced-motion (which kills animation) the type still renders. */
@keyframes lineUp{from{opacity:0;transform:translate3d(0,22px,0)}
  to{opacity:1;transform:none}}
@keyframes swipe{from{background-size:0% .56em}to{background-size:100% .56em}}
.lede span{display:block;animation:lineUp .9s cubic-bezier(.16,.84,.26,1) both}
.lede .l1{animation-delay:.32s}
.lede .l2{animation-delay:.45s}
.sub{animation:lineUp .9s cubic-bezier(.16,.84,.26,1) .62s both}
.scroll{animation:lineUp .9s cubic-bezier(.16,.84,.26,1) .78s both}
/* the marker is drawn across each word, left to right */
.lede em{animation:swipe .5s cubic-bezier(.32,.72,.4,1) .88s both}
.lede i{animation:swipe .5s cubic-bezier(.32,.72,.4,1) 1s both}
.lede em,.lede i{font-family:"Bodoni Moda",Didot,"Times New Roman",serif;font-style:italic;
  letter-spacing:0;font-size:1.02em;
  /* the browser picks the display cut at this size, whose hairlines all but vanish.
     Pin the optical size to the text cut and add weight so the thin strokes survive. */
  font-optical-sizing:none;font-variation-settings:"opsz" 11,"wght" 500}
.lede em,.lede i{color:var(--band-a);
  /* highlighter swipe across the lower two thirds of the word */
  background:linear-gradient(rgba(255,229,0,.52),rgba(255,229,0,.52)) no-repeat;
  background-size:100% .56em;background-position:0 .62em;
  padding-inline:.05em;box-decoration-break:clone;
  -webkit-box-decoration-break:clone}
.sub{align-self:flex-end;max-width:34rem;margin:clamp(1.8rem,5vw,3rem) 0 0;
  font-size:clamp(.98rem,.93rem + .25vw,1.1rem);line-height:1.6}
.sub b{font-weight:600;color:var(--ink)}
.sub span{color:var(--mute)}
.scroll{align-self:center;margin-top:clamp(1.8rem,5vh,3rem);color:var(--mute);
  line-height:0;text-decoration:none;transition:color .2s ease,transform .2s ease}
.scroll svg{width:1.7rem;height:1.7rem;display:block;animation:nudge 2.4s ease-in-out infinite}
.scroll:hover{color:var(--accent)}
@keyframes nudge{0%,100%{transform:translateY(0)}50%{transform:translateY(5px)}}
.btn{display:inline-block;background:var(--accent-deep);color:var(--accent-ink);
  font-family:var(--dsp);font-weight:700;font-size:.82rem;letter-spacing:.1em;
  text-transform:uppercase;text-decoration:none;padding:1rem 1.9rem;margin-top:.6rem;
  border-radius:999px}
.btn:hover{filter:brightness(.92)}
/* a button in a client's own colour. The mark's orange leaves white at only
   2.52:1, so the label is near-black, which measures 7.32:1. */
.btn-brand{background:#FE7F40;color:#111418;
  border-radius:3px;padding:.85rem 1.6rem}
body.casepage .live-cta{margin:1.4rem 0 0 !important}
body.casepage .live-cta .btn{
  font-family:var(--dsp) !important;
  font-size:.82rem !important;
  font-weight:700 !important;
  letter-spacing:.1em !important;
  text-transform:uppercase !important;
  color:#111418 !important;
  line-height:1 !important}



/* inner-page hero band (about, case study) */
.heroband{background:linear-gradient(135deg,var(--sky),var(--paper) 62%)}
/* About sits on plain white rather than the cream the rest of the site uses,
   and its hero loses the sky gradient with it. Her call 2026-10-24. The body
   type is --ink-2, which measures 8.68:1 on white, so nothing needs
   recolouring. */
body.aboutpage{background:#FFFFFF}
body.aboutpage .heroband{background:#FFFFFF}
.hero{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(1.5rem,4vw,4rem);
  align-items:end;padding-block:clamp(2.5rem,7vw,5rem) clamp(2.5rem,6vw,4.5rem)}
.hero h1{font-size:clamp(2.3rem,1rem + 6.4vw,5.6rem)}
/* the About hero carries the same statement as the home page, in the same
   display type with the same highlighter swipe. It sits in a 1.15fr column
   rather than a full-width window, so it is set a size below the home lede
   and the two lines are allowed to break on their own at narrow widths. */
/* The credentials band on About: a title in a hairline that runs the width
   of the content, then the four items as cards on the band. The band's own
   .wrap is a grid for the old four-column layout, so it goes back to a plain
   block here and the cards get their own grid. */
body.aboutpage .band .wrap{display:block}
body.aboutpage .cred-rule{margin:0 0 clamp(1.8rem,4vw,2.8rem)}
/* About drops both dividers she pointed at, 2026-10-24: the hairline either
   side of "Education & Credentials" (and the line above it on a phone), and
   the rule under the last Experience row. The band's colour change already
   separates the two sections, so the lines were saying it twice. With the
   flex pseudo-elements gone the title is centred by the container. */
body.aboutpage .cred-rule{justify-content:center;border-top:0;padding-top:0}
body.aboutpage .cred-rule::before,
body.aboutpage .cred-rule::after{display:none}
body.aboutpage .rows .row:last-child{border-bottom:0}
/* the About intro's right-hand column is a colour card instead of the
   portrait, her call 2026-10-24. #F1E4D7 is sampled from the swatch she sent;
   12px radius, as the credential cards. It was empty at 3:4 at first, then
   the same day took her four Career Highlights, so its height now follows
   its content. Later that day she swapped the cream for a paler warm white
   from a second swatch, #F6F2EE (the swatch has a faint grain; this is its
   most common pixel). On it: #3C4649 8.71:1, the kicker blue 2.89:1. It sits
   only 1.11:1 off the white page, so the card reads as a soft panel rather
   than a block.
   Each highlight is three tiers: the figure, large, for the reader who only
   scans; a small-caps label; then one line for the reader who stops. On the
   cream: #3C4649 measures 7.77:1. The kicker keeps the blue of "About my
   journey" beside it, #3B9CAA, which on this cream is only 2.58:1. */
body.aboutpage .tone-card{width:100%;background:#F6F2EE;border-radius:12px;
  padding:clamp(1.2rem,2.2vw,1.6rem)}
body.aboutpage .highlights .kicker{margin:0 0 .4rem}
body.aboutpage .hl-item{padding-block:.55rem}
body.aboutpage .hl-item + .hl-item{border-top:1px solid #DDC9B4}
body.aboutpage .hl-item:last-child{padding-bottom:0}
body.aboutpage .highlights p{margin:0;max-width:none;color:#3C4649}
body.aboutpage .highlights .hl-num{font-family:var(--dsp);font-weight:800;
  font-size:clamp(1.7rem,1.2rem + 1.2vw,2.2rem);line-height:1;letter-spacing:-.02em}
body.aboutpage .highlights .hl-lbl{margin-top:.4rem;font-family:var(--dsp);
  font-weight:700;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase}
body.aboutpage .highlights .hl-txt{margin-top:.35rem;font-size:.84rem;line-height:1.45}
/* Tablet: below 53.8rem the intro stacks and the card runs the full width,
   which left the four figures in one narrow column with empty space to the
   right (673px wide at 768). Two by two there instead; the phone keeps one
   column. The dividers move to between the rows. */
@media (min-width:36rem) and (max-width:53.75rem){
  body.aboutpage .highlights{display:grid;grid-template-columns:1fr 1fr;
    column-gap:clamp(1.5rem,4vw,2.5rem)}
  body.aboutpage .highlights .kicker{grid-column:1 / -1}
  body.aboutpage .hl-item + .hl-item{border-top:0}
  body.aboutpage .hl-item:nth-of-type(n+3){border-top:1px solid #DDC9B4}
  body.aboutpage .hl-item:nth-last-of-type(-n+2){padding-bottom:0}}
body.aboutpage .cred-rule h2{
  flex:0 1 auto;text-align:center;margin:0;
  font-size:clamp(1.4rem,1.1rem + 1.6vw,2.2rem)}
body.aboutpage .cred-grid{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(.9rem,2vw,1.4rem);align-items:stretch}
@media (max-width:34rem){body.aboutpage .cred-grid{grid-template-columns:1fr}}
/* the card is plain white on the band's warm off-white, which is the only
   contrast it needs; a border as well would make four boxes compete with the
   hairline above them */
body.aboutpage .cred-card{
  background:#FFFFFF;border-radius:12px;
  padding:clamp(1.2rem,2.4vw,1.8rem)}
body.aboutpage .cred-card .unit{margin-top:.5rem}
/* the subject and the institution are two separate lines, not one sentence
   left to wrap wherever it lands. text-wrap:balance evens each of them when
   it does need more than one line. */
/* two degrees are two lines by design. Left to wrap on its own the BBA line
   put "and" alone at the end of line one; a second .unit makes the break the
   one the content actually wants. */
body.aboutpage .cred-card .unit + .unit{margin-top:0}
body.aboutpage .cred-card .unit,
body.aboutpage .cred-card .school{text-wrap:balance}
body.aboutpage .cred-card .school{
  display:block;margin-top:.35rem;
  font-family:var(--dsp);font-weight:700;font-size:.8rem;letter-spacing:.02em;
  line-height:1.35;color:#111418}
/* the four marks come in four shapes: a tall shield, two circles and a
   square. Fitting them into one fixed-height box with object-fit:contain
   makes them read as one row rather than four different sizes. */
/* the mark sits beside the abbreviation, not above it, so the two read as
   one lockup: logo then name, the way an institution signs itself. */
body.aboutpage .cred-head{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(.7rem,1.6vw,1.1rem);
  margin-bottom:clamp(.7rem,1.6vw,1rem)}
body.aboutpage .cred-logo{
  flex:none;height:clamp(2.4rem,4vw,3rem);width:auto;
  object-fit:contain;object-position:center;margin:0}
body.aboutpage .cred-head .fig{margin:0;line-height:1}
/* the whole card centres with the marks */
body.aboutpage .cred-card{text-align:center}


/* The About credentials band is a warm off-white rather than the teal
   gradient, so everything in it inverts to dark type. Measured on #F2E8DB:
   the degree abbreviations and the heading at 15.25:1, the descriptions
   8.01:1, the qualifiers in the accent teal 4.76:1. */
/* 2026-10-24: the band is now the SF logo blue #6FC1CD at 50% over white,
   #B7E0E6, her call (was the warm off-white #F2E8DB, whose figures are in the
   comment above). The only type sitting on the band itself is the title,
   #3C4649 at 6.85:1; everything else is on the white cards, which stand
   1.42:1 off the blue. */
body.aboutpage .band{background:#B7E0E6;color:#3C4649}
body.aboutpage .band h2{text-align:center}
/* the four abbreviations match the headings' #3C4649, her call 2026-10-24
   (were near-black); 8.01:1 on the band. */
body.aboutpage .band .fig{color:#3C4649}
body.aboutpage .band .unit{color:#3C4649}
body.aboutpage .band .src{color:var(--accent);opacity:1}
/* a one-line qualifier like "Active" can carry the uppercase label styling;
   a full sentence cannot, so an award line keeps the accent colour and the
   small size but reads as a sentence */
body.aboutpage .band .src.award{
  text-transform:none;letter-spacing:.01em;line-height:1.45;font-weight:600;
  font-size:.78rem}

/* Let's Connect, between the credentials band and the footer. Built from the
   reference she sent 2026-10-24: centred title and one line of copy, a solid
   button for email, a pill with a line icon.
   Set on dark grey, her call the same day, lighter than the footer's
   #17191C so the two read as separate bands. First #33383D (1.49:1 above the
   footer), then lightened at her request to #4B5157, 2.19:1 above it.
   The line of copy under the title was cut the same day. The email button
   was first the SF logo blue #6FC1CD, then, the same day, the yellow of the
   active nav pill so it matches "About" in the masthead: #FFE500 with the
   pill's #0F4C5A label, 7.48:1, standing 6.3:1 off the grey. The
   site's own rule is that this yellow is the one clickable colour.
   The title in white measures 8.03:1. A white LinkedIn button sat beside it
   until she cut it the same day: the masthead and the footer icon already
   link there, and the footer icon is still there on a phone. */
.connect{text-align:center;background:#4B5157}
.connect .wrap{padding-block:clamp(3rem,7vw,5rem)}
.connect h2{color:#FFFFFF;font-size:clamp(1.6rem,1.2rem + 1.8vw,2.4rem);margin:0}
.connect-btns{display:flex;flex-wrap:wrap;justify-content:center;gap:.75rem;
  margin-top:clamp(1.4rem,3vw,1.9rem)}
.cbtn{display:inline-flex;align-items:center;gap:.55rem;
  font-family:var(--dsp);font-weight:600;font-size:.95rem;text-decoration:none;
  padding:.8rem 1.5rem;border-radius:999px;border:1px solid #FFFFFF;
  transition:background .2s,color .2s,border-color .2s}
.cbtn svg{width:1.1em;height:1.1em;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.cbtn-solid{background:#FFE500;color:#0F4C5A;border-color:#FFE500}
.cbtn-solid:hover{background:#F0D700;border-color:#F0D700}

/* About's intro and Experience Snapshot drop the teal for dark grey, her call
   2026-10-24, so the page reads in the same neutrals as the credentials band
   and Let's Connect below it. Headings and job titles take the structure
   colour, copy and the employer line the body grey, the years a lighter grey
   so they sit back. Measured on white: #111418 18.47:1, #3C4649 9.70:1,
   #6B7275 4.90:1. The accent word in the hero keeps its teal. */
/* the headings were near-black #111418 until she compared them by eye with
   the hero, 2026-10-24, and preferred the hero's #3C4649: the section titles,
   the job titles and the credentials title all take it now. 9.70:1 on
   white, 8.01:1 on the band's #F2E8DB. */
body.aboutpage .block h2,
body.aboutpage .case h2,
body.aboutpage .case h3,
body.aboutpage .band h2{color:#3C4649}
body.aboutpage .block p,
body.aboutpage .case p{color:#3C4649}
/* the line above once also held the kicker; removing it on 2026-10-24 (v348)
   ran the two selectors into the years' rule below, and every paragraph on
   the page turned #6B7275 until v370. Keep them as two rules. */
body.aboutpage .case .yr{color:#6B7275}
/* Logo blue as an accent, her call 2026-10-24: three small touches, all
   decoration, none carrying text. #6FC1CD is the SF mark's own colour. On
   white it is only 2.06:1, which is why it marks things here rather than
   colouring any words: the text beside each touch stays grey.
   1. the rule under "Experience Snapshot" was blue here too, until she moved
      it to the heading grey #3C4649 the same day, so the heading and its
      rule read as one. The blue now lives in the dots, the kicker and the
      full-width rule under the hero. */
body.aboutpage .rows{border-top-color:#3C4649;border-top-width:1.5px}
/* and a touch lighter than the base 2px, her call the same day: 1.5px draws
   as a true 1.5 on a high-density screen and rounds to 1 or 2 elsewhere. */
/* 2. a dot before each year, a node on the timeline */
body.aboutpage .case .yr::before{content:"";display:inline-block;
  width:.5rem;height:.5rem;border-radius:50%;background:#6FC1CD;
  margin-right:.55rem;vertical-align:.08em}
/* 3. "About my journey" itself in blue. It began as a short logo-blue line
   before grey text; she swapped that for colour on the words, the same day,
   then asked for it slightly darker than the logo's #6FC1CD (2.06:1).
   #3B9CAA is the logo's hue and saturation at lightness .45, 3.22:1 on
   white: still under the 4.5:1 text minimum, which she knows. #31808C
   (lightness .37) is the first step of the same hue that passes, 4.57:1. */
body.aboutpage .block .kicker{color:#3B9CAA}
/* the employer line's own colour is set at body.aboutpage .row .org below,
   which comes later in the file, so it is changed there rather than here */

/* the About block gives its copy the wider half, so the section title lands
   on two lines rather than three; text-wrap:balance then evens the two. */
/* only in the two-column layout: below 860px the base stylesheet collapses
   .block to one column, and an unscoped override here kept the portrait
   beside the copy on a phone. */
@media (min-width:53.8rem){
  body.aboutpage .block{grid-template-columns:1.1fr .9fr}}
/* The two columns are one height, her call 2026-10-24: with the Career
   Highlights card beside it at 1.25fr/.75fr the card stood 70px taller than
   the copy and read as a mismatch. Measured: at 1.1fr/.9fr and the tighter
   card below, the two land within a few px at 1024 and up (the copy is held
   to 52ch, so above ~1100 it stops growing). Stretch makes them exactly one
   height; the copy centres in its column, the card spreads its four figures
   evenly down its own. Two-column layout only. */
@media (min-width:53.8rem){
  body.aboutpage .block{align-items:stretch}
  body.aboutpage .block .bd{display:flex;flex-direction:column;justify-content:center}
  body.aboutpage .block .media{display:flex}
  body.aboutpage .highlights{flex:1;display:flex;flex-direction:column;justify-content:space-between}}
body.aboutpage .block h2{text-wrap:balance}

/* the About hero carries the statement on its own: one centred column, two
   lines, no second column beside it */
.hero.hero-solo{grid-template-columns:1fr;justify-items:center;text-align:center}
/* three one-word sentences rather than two clauses: the line is shorter, so
   it carries a size up, and it is allowed to sit on one line where it fits */
.hero h1.about-lede.three .l1{display:inline}
/* "Creative. Strategic." is held together, so the only place the headline can
   break is before "Human." The size floor drops with it: at the old 2.2rem
   floor the held phrase was wider than a 320px screen and would have pushed
   the page sideways. */
.hero h1.about-lede.three{font-size:clamp(1.75rem,.8rem + 4.6vw,4.8rem)}
/* .lede span is display:block site-wide, for the home page's stacked lines,
   so the held phrase has to be put back inline or it becomes its own line and
   the headline never fits on one. */
.hero h1.about-lede.three .nb{display:inline;white-space:nowrap}

.hero h1.about-lede{
  font-size:clamp(2.1rem,.9rem + 5.2vw,4.4rem);
  letter-spacing:-.035em;line-height:1.04;font-weight:800;color:#3C4649;
  margin:0}
/* the home page animates these in on load behind a window that rises; here
   there is no window, so the lines simply appear */
.about-lede span{animation:none}
/* "Human." on About takes the same blue as the "About my journey" kicker,
   #3B9CAA, her call 2026-10-24, so the two blue words on the page match. At
   display size the large-text minimum is 3:1 and this measures 3.22:1, so
   here it passes. The home page's accent words keep --band-a. */
.hero h1.about-lede i{color:#3B9CAA}
.hero .say{color:var(--ink-2);max-width:52ch;font-size:clamp(1rem,.95rem + .3vw,1.12rem)}
.hero .say p{margin:0 0 1.1rem;line-height:1.68}
.hero .say p:last-child{margin-bottom:0}
@media (max-width:820px){.hero{grid-template-columns:1fr}}



/* page head + work filter bar */
.pagehead{padding-block:clamp(2.2rem,6vw,4rem) clamp(1.2rem,3vw,2rem)}
.pagehead h1{font-size:clamp(2.2rem,1rem + 4.6vw,4rem);text-transform:none;
  letter-spacing:-.03em;color:#111418}
.pagehead p{margin:1rem 0 0;max-width:42rem;color:var(--ink-2)}
.filterbar{position:sticky;top:var(--mast-h);z-index:20;
  /* glass, like the masthead: a solid block would cut a hard edge across the
     cards passing behind it */
  background:rgba(111,193,205,.9);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  padding-block:.55rem}
.filters{display:flex;flex-wrap:wrap;gap:.4rem}
.chip{font-family:var(--dsp);font-weight:700;font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;color:#0B3038;background:transparent;
  border:1px solid rgba(6,35,42,.24);border-radius:999px;padding:.55rem 1.05rem;
  cursor:pointer;text-decoration:none;display:inline-block;line-height:1;
  transition:background-color .2s ease,color .2s ease,border-color .2s ease}
.chip:hover{color:#06232A;border-color:rgba(6,35,42,.5)}
.chip[aria-pressed="true"],.chip[aria-current]{background:var(--accent-deep);
  color:var(--accent-ink);border-color:var(--accent-deep)}
.noresult{margin:2rem 0 0;color:var(--mute)}
.seeall{margin:clamp(1.6rem,3vw,2.4rem) 0 0;text-align:right}
.card[hidden]{display:none}



/* the case study runs on white, so artwork sits on a neutral ground */
body.casepage{background:var(--highlight)}
body.casepage .panel.plain{background:var(--wash);border-color:transparent}
/* the case page keeps the cream so the bar still reads against white */
body.casepage .mast.solid{background:rgba(250,246,239,.62)}

/* `[!]` TEMPORARY RESET, 2026-10-15 — every piece of type on the case study
   flattened to one size, one face, one colour, so the hierarchy can be rebuilt
   deliberately rather than inherited. Delete this block when that is done. */
body.casepage .case-hero, body.casepage .case-hero *,
body.casepage .sec, body.casepage .sec *,
body.casepage .halfsplit, body.casepage .halfsplit *,
body.casepage .sec-banner h2,
body.casepage .sec-rule h2{
  font-family:var(--bdy) !important;
  font-size:17.6px !important;
  line-height:1.6 !important;
  font-weight:400 !important;
  letter-spacing:normal !important;
  text-transform:none !important;
  /* was var(--deep), the dark teal #0F4C5A; the About grey since 2026-10-24 */
  color:#3C4649 !important;
}
/* the bands are light now, so the titles are dark */
body.casepage .sec-banner h2{color:#111418 !important}

/* --- rebuilt on top of the reset, one piece at a time --- */
body.casepage .case-hero h1{
  font-family:var(--dsp) !important;
  font-size:clamp(2.2rem,1rem + 5vw,4.4rem) !important;
  font-weight:800 !important;
  letter-spacing:-.03em !important;
  line-height:1.04 !important;
  color:#111418 !important;
}
/* the reset above hits `.case-hero *`, which includes any inline span inside
   the title. A plain span in an h1 is markup, not a style change, so it
   inherits the heading instead of dropping to body type. The italic rule
   below still wins for <i>, since it comes after this. */
body.casepage .case-hero h1 *{
  font:inherit !important;
  color:inherit !important;
  letter-spacing:inherit !important;
  line-height:inherit !important}

/* A book title takes the serif italic, the same face the home page uses for its
   accent words. Pin the optical size, or the display cut's hairlines vanish. */
body.casepage .case-hero h1 i{
  font-family:"Bodoni Moda",Didot,"Times New Roman",serif !important;
  font-style:italic !important;
  font-size:1.02em !important;
  letter-spacing:0 !important;
  color:inherit !important;
  font-optical-sizing:none;
  font-variation-settings:"opsz" 11,"wght" 600;
}
/* the title block runs straight into the study; the dashed rule above My role
   is the only divider on the page now */
body.casepage .case-hero{
  padding-bottom:clamp(1.6rem,3.5vw,2.6rem);
  margin-bottom:clamp(.6rem,1.6vw,1.2rem);
}
body.casepage .case-hero .role{
  font-family:var(--dsp) !important;
  font-size:.74rem !important;
  font-weight:700 !important;
  letter-spacing:.14em !important;
  text-transform:uppercase !important;
  text-align:center;
  color:var(--mute) !important;
}
/* Overview / My role / Challenge / Result */
body.casepage .prose2 h4,
body.casepage .prose3 h4,
body.casepage .role-block h4,
body.casepage .case-h,
body.casepage .panel h3{
  font-family:var(--dsp) !important;
  font-size:1.45rem !important;
  font-weight:800 !important;
  letter-spacing:.02em !important;
  text-transform:uppercase !important;
  line-height:1.15 !important;
  color:#111418 !important;
  margin:0 0 1rem !important;
}
/* hold a phrase on one line, but only where it fits. "Marketing
   communications" needs about 720px of band width at this type size, so below
   50rem it is allowed to break rather than force a horizontal scrollbar. */
@media (min-width:50rem){
  body.casepage .sec-banner h2 .nb,
  body.casepage .sec-rule h2 .nb,
  /* a case-study title keeps its phrase on one line only where the line is
     wide enough to hold it. A hard &nbsp; in the markup cannot be undone at
     narrow widths, and "Brand Transformation" at the display size is wider
     than a 320px phone, so it forced the page sideways. */
  body.casepage .case-hero h1 .nb{white-space:nowrap}}

/* the three full-bleed section titles */
body.casepage .sec-banner h2,
body.casepage .sec-rule h2{
  font-family:var(--dsp) !important;
  font-size:clamp(1.8rem,1rem + 3.4vw,3.4rem) !important;
  font-weight:800 !important;
  letter-spacing:.02em !important;
  text-transform:uppercase !important;
  line-height:1.08 !important;
}
/* the same column gap as .prose2, so all three players are identical in size
   and line up with the text columns above */
/* Every auto-fit grid below uses minmax(min(Nrem,100%),1fr) rather than
   minmax(Nrem,1fr). A bare rem floor is a hard minimum: on a viewport
   narrower than the floor the track stays at the floor and pushes past the
   screen, which is why the case studies scrolled sideways at 320px and at
   360px with a desktop scrollbar showing. min(Nrem,100%) keeps the same
   wrapping behaviour at every width where the floor fits, and lets the track
   shrink to the container when it does not. Fixed 2026-10-23. */
.videopair{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(18rem,100%),1fr));
  gap:clamp(2rem,6vw,5.5rem);margin-top:clamp(2rem,6vw,5.5rem)}

/* a stand-in for the player until the real video is dropped in */
.videobox{position:relative;aspect-ratio:16/9;overflow:hidden;border-radius:4px;
  background:#2A3034}
.videobox{margin:0}
.videobox img,.videobox video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
/* the scrim and the fake controls only belong on the empty stand-in */
.videobox:not(:has(video))::before{content:"";position:absolute;inset:0;
  background:rgba(10,20,24,.22)}
.videobox:has(video) .vplay,.videobox:has(video) .vbar{display:none}
.vplay{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;
  width:4.4rem;height:4.4rem;border-radius:50%;background:rgba(18,22,26,.52);
  display:grid;place-items:center}
.vplay::before{content:"";border-left:1.1rem solid #fff;border-top:.7rem solid transparent;
  border-bottom:.7rem solid transparent;margin-left:.26rem}
.vbar{position:absolute;left:0;right:0;bottom:0;z-index:2;display:flex;align-items:center;
  gap:.8rem;padding:.9rem;color:#fff;
  background:linear-gradient(transparent,rgba(8,14,18,.6))}
body.casepage .vbar span{font-size:.72rem !important;color:#fff !important;
  font-family:var(--bdy) !important}
.vbar .track{flex:1;height:3px;background:rgba(255,255,255,.35);border-radius:2px}
.vbar .track i{display:block;height:100%;width:58%;background:#fff;border-radius:2px}

/* the two halves of My role */
/* the small italic line that introduces the players */
body.casepage .vid-note{
  font-size:.84rem !important;
  font-style:italic;
  letter-spacing:.03em !important;
  color:var(--mute) !important;
  margin:1.3rem 0 0 !important;
}
body.casepage .lyr{
  font-family:var(--dsp) !important;
  font-weight:700 !important;
  color:var(--accent) !important;
}

/* case study */
.case-hero{text-align:center;padding-block:clamp(2.4rem,6vw,4.5rem) clamp(1.4rem,3vw,2.2rem)}
.case-hero .role{margin:0 0 1rem;font-family:var(--dsp);font-weight:600;font-size:.72rem;
  letter-spacing:.14em;text-transform:uppercase;color:var(--mute)}
.case-hero h1{font-size:clamp(2.2rem,1rem + 5vw,4.4rem);text-transform:none;
  letter-spacing:-.03em;color:#111418;margin:0}

/* Challenge and Result carrying the client's own two colours.
   The logo red is #E03F45, which only reaches 4.23:1 against white and fails
   AA for body text, so the panel uses #D6383E: the same red one step deeper,
   at 4.67:1. The logo teal passes untouched at 6.03:1. */
body.casepage .panel.tone-red{background:#D6383E;border-color:transparent}
body.casepage .panel.tone-teal{background:#256C76;border-color:transparent}
body.casepage .panel.tone-red,
body.casepage .panel.tone-teal,
body.casepage .panel.tone-red *,
body.casepage .panel.tone-teal *{color:#FFFFFF !important}
/* PCPC Challenge: her magenta #CF1C8A at 50%, read as a 50% tint over white.
   The full-strength colour sits at 3.68:1 against near-black and 5.02:1
   against white, so neither text colour is comfortable on it; the tint lifts
   near-black to 7.95:1 and keeps the panel in her hue. */
/* PCPC Result: her blue #379DC5 at the same 50% tint as the Challenge beside
   it, so the pair reads as one set. Near-black measures 10.84:1 on it. */
body.casepage .panel.tone-sky{background:#9BCEE2;border-color:transparent}
body.casepage .panel.tone-sky,
body.casepage .panel.tone-sky *{color:#111418 !important}
body.casepage .panel.tone-sky li::marker{color:rgba(17,20,24,.55)}
/* Alzheimer's Challenge and Result. The amber is her swatch as given; the
   periwinkle is her swatch at 50%, which also lifts it to roughly the amber's
   weight so the pair reads as a set. Body copy measures 8.23:1 on the amber
   and 6.83:1 on the periwinkle, headings 15.66:1 and 13.01:1. */
body.casepage .panel.tone-amber{background:#FFECA7;border-color:transparent}
body.casepage .panel.tone-peri{background:#CBD9F6;border-color:transparent}
body.casepage .panel.tone-amber li::marker,
body.casepage .panel.tone-peri li::marker{color:rgba(17,20,24,.55)}
body.casepage .panel.tone-pink{background:#E78EC4;border-color:transparent}
body.casepage .panel.tone-pink,
body.casepage .panel.tone-pink *{color:#111418 !important}
body.casepage .panel.tone-pink li::marker{color:rgba(17,20,24,.55)}

body.casepage .panel.tone-red li::marker,
body.casepage .panel.tone-teal li::marker{color:rgba(255,255,255,.65)}
body.casepage .panel.tone-red a,
body.casepage .panel.tone-teal a{text-decoration-color:rgba(255,255,255,.55)}

/* a case-study title sitting on the client's own banner art */
.case-hero.banner{
  padding-block:clamp(3rem,7vw,5rem) !important;
  margin-bottom:clamp(2rem,4.5vw,3.4rem) !important;
  border-bottom:0}
body.casepage .case-hero.banner h1{color:#FFFFFF !important}
body.casepage .case-hero.banner .role{color:rgba(255,255,255,.9) !important}

/* Heart valve: the campaign's own tiled icon. White on this red is 5.03:1,
   which clears AA for the small role line as well as the heading. */
.case-hero.banner.hv{
  background:#CE3340 url("img/hv-banner.jpg") center/cover no-repeat}

/* Human Calling: the antique map the book sits on in the hero still, so the
   title block and the opening image are the same paper. The map is pale
   (2nd-percentile luminance .577), so white would land at 0.7:1 and be
   unreadable. This banner keeps the dark title instead: #111418 measures
   11.03:1 on the darkest 2% of the artwork, and the deep teal role line 9:1. */
.case-hero.banner.hc{
  background:#E7DFD2 url("img/hc-banner.jpg") center/cover no-repeat}
body.casepage .case-hero.banner.hc h1{color:#111418 !important}
body.casepage .case-hero.banner.hc .role{color:var(--ink) !important}

/* PCPC: petri dishes and leaves on white, from the series' own art. Bright,
   so it keeps the dark title. Measured in the band the type actually sits in
   (centre 80% of the width, upper two thirds) the darkest 2% gives #111418
   5.05:1, past AA for the small role line as well. Across the whole image it
   drops to 4.41:1 because of the dark leaves at the far left and right, which
   fall outside the 76rem text column at wide widths and crop away at narrow
   ones. The deep teal --ink would not clear it, so the role line takes the
   same near-black rather than the site's usual accent. */
.case-hero.banner.pcpc{position:relative;isolation:isolate;overflow:hidden;
  background:#F1F2F0}
/* the artwork is blurred on its own layer so the title stays sharp. The layer
   is inset past the edges because a blur samples outside itself and would
   otherwise leave a soft, pale fringe on all four sides. */
.case-hero.banner.pcpc::before{content:"";position:absolute;inset:-28px;z-index:0;
  background:url("img/pcpc-banner.jpg") center/cover no-repeat;
  filter:blur(10px)}
.case-hero.banner.pcpc > .wrap{position:relative;z-index:1}
body.casepage .case-hero.banner.pcpc h1,
body.casepage .case-hero.banner.pcpc .case-sub,
body.casepage .case-hero.banner.pcpc .role{color:#111418 !important}

/* Alzheimer's: the campaign's own abstract artwork. It runs from deep blue on
   the left to white and yellow in the middle, so bare it fails both ways:
   near-black bottoms out at 2.08:1 against the dark corner and white at
   1.06:1 against the bright centre. A 45% white wash lifts the whole frame
   without flattening the colour, and dark type then measures 6.44:1 at its
   worst point. A dark wash was the other option and was rejected: it needs
   65% before white clears AA for the small role line, by which point the
   artwork is gone. */
.case-hero.banner.nps{
  background:
    linear-gradient(rgba(255,255,255,.45),rgba(255,255,255,.45)),
    url("img/nps-banner.jpg") center/cover no-repeat;
  background-color:#CFE3EC}
body.casepage .case-hero.banner.nps h1,
body.casepage .case-hero.banner.nps .role{color:#111418 !important}

/* Legal Council: the Capitol at dusk. The brightest pixel in the photograph is
   #7D7B8D, which would leave white at 4.13:1 and fail the role line, so a thin
   wash carries it to about 5.6:1 without flattening the image. */
.case-hero.banner.tlc{
  background:
    linear-gradient(rgba(22,24,44,.28),rgba(22,24,44,.28)),
    url("img/tlc-banner.jpg") center/cover no-repeat;
  background-color:#3A3A55}

/* the opening still of a case study, never enlarged past its own pixels */
.col-shot{display:block;width:100%;height:auto;margin:0;
  border-radius:4px;box-shadow:0 1px 3px rgba(17,60,69,.10),0 10px 26px -16px rgba(17,60,69,.32)}
/* each study caps its still at the width of the file it was given */
.col-shot.w772{max-width:48.25rem}
.col-shot.w751{max-width:46.9rem}
.col-shot.w937{max-width:58.6rem}
.col-shot.w1057{max-width:66.1rem}
.col-shot.w784{max-width:49rem}
.col-shot.w1400{max-width:87.5rem}
/* widen a column image until it lines up with the Challenge and Result cards
   above it: those sit in a grid with a tighter gap, so the image reclaims half
   the difference between the two gaps on its left edge. */
.col-shot.flush-panels{
  --ofs:calc((clamp(2rem,6vw,5.5rem) - clamp(.9rem,2vw,1.4rem)) / 2);
  width:calc(100% + var(--ofs));max-width:none;
  margin-left:calc(-1 * var(--ofs))}
/* a section title sitting inside a hairline that runs the full width of the
   page. The rule is two flex fillers, so the gap each side of the text is
   even and the line never passes behind it. */
.sec-rule{display:flex;align-items:center;
  gap:clamp(1.1rem,2.6vw,2.4rem);
  /* a third more room above than below: a section title belongs to what
     follows it, so the larger gap goes on the side it is separating from */
  margin-top:clamp(6rem,12vw,12rem);
  margin-bottom:clamp(4.5rem,9vw,9rem)}
/* the rule owns all the space around itself, so the gap above and below is
   identical no matter what kind of block it sits between */
.sec:has(+ .sec-rule){padding-bottom:0}
.sec-rule + .sec{padding-top:0}
.sec-rule::before,.sec-rule::after{
  /* the logo blue until 2026-10-24, then the heading grey, her call, so the
     rule and the title it carries read as one, as on About */
  content:"";flex:1 1 2rem;min-width:1.25rem;height:1px;background:#3C4649}
body.casepage .sec-rule h2{
  flex:0 1 auto;text-align:center;color:#111418 !important;
  /* a notch down from the banner size: the hairline does the separating now,
     so the type does not have to. At this size every title on the page holds
     one line down to about 640px. */
  font-size:clamp(1.5rem,.8rem + 2.4vw,2.5rem) !important}
/* on a phone the rule goes above the title instead of through it, since a
   wrapped title would leave the line sitting between its two lines */
@media (max-width:50rem){
  .sec-rule{display:block;text-align:center;
    border-top:1px solid #3C4649;
    padding-top:clamp(1.3rem,4vw,2rem)}
  .sec-rule::before,.sec-rule::after{display:none}}

/* a photograph running the full width of the page, edge to edge */
.fullbleed{display:block;line-height:0}
.fullbleed img{display:block;width:100%;height:auto}

/* a band that is half image, half copy, with the image running to the page's
   left edge and to both band edges above and below. The minimum height is the
   image's own ratio at half the page width, so nothing is cropped until the
   copy forces the row taller. */
.halfsplit{display:grid;grid-template-columns:1fr 1fr;align-items:stretch;
  min-height:var(--hs-min,25.4vw)}
/* the mirrored version: copy on the left, media running off the right edge */
.halfsplit.flip .hs-copy{
  padding-inline:calc(var(--gutter) + max(0px,(200% - var(--maxw)) / 2))
    clamp(1.4rem,3vw,2.4rem)}
.hs-media{position:relative;overflow:hidden;background:var(--wash)}
/* The emails image is a two-up composition: a phone hard against the left
   edge and the full-width invitation on the right. Nothing in it can be
   cropped off a side without losing one of the two.
   With object-fit:cover the media box is a grid cell whose height is set by
   the copy beside it, and that copy is three long paragraphs, so the box gets
   taller as the window narrows and cover starts eating the sides instead of
   the top and bottom. Measured 2026-10-23: 0.4% a side at 1680px, 6.6% at
   1280, 9.9% at 1180, 17.7% at 1024, 25.7% at 900. The phone begins 6.4% in
   from the left, so from about 1280px down its edge was being sliced off.
   Pinning the box to the file's own ratio and centring it in the half means
   the crop is always zero. The cost is white space above and below the image
   at the widths where the copy runs taller, which is the right trade: a
   deliverable shown whole beats a deliverable shown edge to edge.
   The logos image is milder but has the same shape of problem: under 1% at
   most widths, but 5.9% a side in the narrow band just above the breakpoint,
   where the copy beside it runs tallest. It gets the same treatment.
   Scoped to the two-column layout only: below 52rem the halfsplit becomes a
   flex column, where align-self:center collapses the media to zero width. */
@media (min-width:52.0625rem){
  .halfsplit .hs-media{align-self:center;height:auto}
  .halfsplit .hs-media{aspect-ratio:1200 / 609}
  .halfsplit.flip .hs-media{aspect-ratio:1400 / 1112}}

.hs-media img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center}
.hs-copy{display:flex;flex-direction:column;justify-content:center;
  padding-block:clamp(2rem,4vw,3rem);
  /* the copy column is half the page, so 200% of it is the page width: that
     gives the same right edge, and the same measure, as the text columns in
     the sections above. A plain 100% here would resolve against the column
     and let the lines run about 25px long. */
  padding-inline:clamp(1.4rem,3vw,2.4rem)
    calc(var(--gutter) + max(0px,(200% - var(--maxw)) / 2))}
.hs-copy p{margin:0 0 1rem;line-height:1.68}
.hs-copy p:last-child{margin-bottom:0}
@media (max-width:52rem){
  .halfsplit{grid-template-columns:1fr;min-height:0}
  .hs-media{aspect-ratio:1396/709}
  .halfsplit.flip .hs-media{aspect-ratio:1400/1112}
  .halfsplit.flip{display:flex;flex-direction:column-reverse}
  .hs-copy,
  .halfsplit.flip .hs-copy{padding-inline:var(--gutter)}}

/* run a column image off the left edge of the page. The corner and the shadow
   are dropped on that side, since there is no edge there to describe. */
.col-shot.bleed-l{
  width:calc(100% + var(--gutter) + max(0px,(100vw - var(--maxw)) / 2));
  max-width:none;
  margin-left:calc(-1 * (var(--gutter) + max(0px,(100vw - var(--maxw)) / 2)));
  border-radius:0 4px 4px 0;
  box-shadow:0 1px 3px rgba(17,60,69,.10),10px 10px 26px -16px rgba(17,60,69,.32)}
@media (max-width:52rem){
  .col-shot.bleed-l{width:calc(100% + 2 * var(--gutter));
    margin-right:calc(-1 * var(--gutter));border-radius:0}}

/* the same trick for an image in the left column: it reclaims the gap on its
   right edge instead, so it lines up with the Challenge card */
.col-shot.flush-panels-l{
  --ofs:calc((clamp(2rem,6vw,5.5rem) - clamp(.9rem,2vw,1.4rem)) / 2);
  width:calc(100% + var(--ofs));max-width:none}
@media (max-width:52rem){
  .col-shot.flush-panels,
  .col-shot.flush-panels-l{--ofs:0px}}

/* the opening still and the Overview copy share the top row; My role sits
   underneath, split across the same two columns */
.role-block{margin-top:clamp(2.2rem,5vw,3.4rem);
  border-top:1px dashed var(--rule);padding-top:clamp(1.8rem,4vw,2.8rem)}
.role-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(20rem,100%),1fr));
  gap:clamp(2rem,6vw,5.5rem);align-items:start}
.role-block p{margin:0 0 1rem;line-height:1.68;color:var(--ink-2)}
/* a My role band carrying one paragraph rather than two labelled halves.
   Settled 2026-10-22 after trying 62ch, then 80ch, then full width: the full
   width read best as a block but its lines were too long to track, so the
   paragraph now runs the full content width and is flowed into two columns.
   That keeps the measure short and the band wide at the same time. */
.role-solo{max-width:none;
  /* one paragraph, flowed across two columns rather than split into two
     elements, so the text stays a single sentence sequence and rebalances by
     itself when the window changes. The gap matches .role-cols, so a solo
     band and a two-part band line up with each other down the site. */
  columns:2;column-gap:clamp(2rem,6vw,5.5rem)}
.role-solo p{margin:0}
/* one column again once there is no room for two */
@media (max-width:46rem){.role-solo{columns:1}}
/* the reset flattened every weight, which also killed the <b> lead-ins in the
   Challenge list and the figures in Result. Give them back. */
body.casepage .panel li b,
body.casepage .hl li b,
body.casepage .sec p b{font-weight:700 !important}

/* one PSA, centred and large, with the copy sitting above it on a readable
   measure rather than beside it */
/* before / after wipe.
   The reveal is a clip-path on the top image, never a width change: at
   object-fit:cover a narrower box re-crops the photograph, so the two halves
   would slide against each other instead of staying registered.
   Both screenshots are the same pixel width and are anchored to the top, so
   cover scales them identically and the same slice of each page is shown.
   The slider is a real range input, so keyboard and screen readers get it for
   free; it is laid over the whole frame and made invisible. */
.ba{position:relative;overflow:hidden;border-radius:6px;
  aspect-ratio:3/2;margin:0;
  background:var(--wash);
  box-shadow:0 1px 3px rgba(17,60,69,.10),0 14px 34px -18px rgba(17,60,69,.34);
  touch-action:pan-y}
.ba img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:top center;user-select:none;-webkit-user-drag:none}
/* the old site is the top layer, clipped to the left of the handle, so the
   page reads before-on-the-left and after-on-the-right like the labels */
.ba-over{clip-path:inset(0 calc(100% - var(--ba,50%)) 0 0)}
.ba-handle{position:absolute;top:0;bottom:0;left:var(--ba,50%);width:2px;
  margin-left:-1px;background:#fff;box-shadow:0 0 0 1px rgba(17,60,69,.25);
  pointer-events:none}
.ba-handle::after{content:"";position:absolute;top:50%;left:50%;
  width:2.1rem;height:2.1rem;transform:translate(-50%,-50%);
  border-radius:50%;background:#fff;
  box-shadow:0 1px 3px rgba(17,60,69,.2),0 6px 18px -6px rgba(17,60,69,.45)}
.ba-handle::before{content:"";position:absolute;top:50%;left:50%;z-index:1;
  width:.95rem;height:.55rem;transform:translate(-50%,-50%);
  background:var(--deep);
  clip-path:polygon(0 50%,38% 0,38% 100%, 100% 50%,62% 0,62% 100%)}
.ba-range{position:absolute;inset:0;width:100%;height:100%;margin:0;z-index:3;
  opacity:0;cursor:ew-resize;-webkit-appearance:none;appearance:none;background:none}
.ba-range::-webkit-slider-thumb{-webkit-appearance:none;width:3rem;height:100%;cursor:ew-resize}
.ba-range::-moz-range-thumb{width:3rem;height:100%;border:0;cursor:ew-resize}
.ba-range:focus-visible ~ .ba-handle::after{outline:3px solid var(--accent);outline-offset:3px}
body.casepage .ba-hint{
  font-size:.84rem !important;font-style:italic;letter-spacing:.03em !important;
  color:var(--mute) !important;margin:.8rem 0 0 !important}
@media (max-width:40rem){.ba{aspect-ratio:4/3}}

/* a window onto a full page: the screenshot keeps its own height and the frame
   scrolls over it. Scroll chaining is left on, so reaching the bottom hands the
   wheel back to the page instead of trapping it. */
.scrollframe{
  height:clamp(20rem,52vh,32rem);
  overflow-y:auto;overflow-x:hidden;
  max-width:60rem;margin:0 auto;
  border-radius:6px;background:var(--wash);
  box-shadow:0 1px 3px rgba(17,60,69,.10),0 14px 34px -18px rgba(17,60,69,.34);
  scrollbar-width:thin;scrollbar-color:rgba(17,60,69,.3) transparent}
.scrollframe img{display:block;width:100%;height:auto}
.scrollframe::-webkit-scrollbar{width:10px}
.scrollframe::-webkit-scrollbar-track{background:transparent}
.scrollframe::-webkit-scrollbar-thumb{
  background:rgba(17,60,69,.28);border-radius:6px;
  border:3px solid transparent;background-clip:content-box}
.scrollframe::-webkit-scrollbar-thumb:hover{background:rgba(17,60,69,.45);
  border:3px solid transparent;background-clip:content-box}
body.casepage .scroll-hint{
  font-size:.84rem !important;font-style:italic;letter-spacing:.03em !important;
  color:var(--mute) !important;text-align:center;
  margin:clamp(2.2rem,4.5vw,3.2rem) 0 .8rem !important}

/* a standalone section heading, same weight as Overview and My role */
.case-h{margin:0 0 clamp(1.1rem,2.4vw,1.6rem) !important}

/* a titled block of copy introducing a single film */
body.casepage .psa-head{text-align:center;margin:0 0 clamp(1rem,2.2vw,1.5rem) !important}
/* the same width as the player below it, so the block and the film share one
   left and right edge instead of the copy floating narrower in the middle */
.psa-copy{max-width:60rem;margin:0 auto clamp(2rem,4vw,3rem)}
body.casepage .psa-copy p{margin:0 0 1rem;line-height:1.68}
body.casepage .psa-copy p:last-child{margin-bottom:0}

.psa-intro{max-width:62ch;margin:0 auto clamp(1.6rem,3.5vw,2.6rem)!important;text-align:center}
/* the films band on the PCPC page: her green #51B83F, tinted further than the
   50% used on the Challenge and Result cards. A card is a small block and can
   carry more colour; this band runs the full width of the page, so the same
   mix read as too heavy behind six players. 68% is the floor: the band exists
   to carry the client's brand colour, and tinted past this the green stops
   being identifiable and the band becomes empty width. Her call, 2026-10-23,
   after seeing 50%, 68% and 80%. Type stays dark: near-black captions measure
   13.88:1 and the deep teal italic note 8.99:1. The note still needs its own
   colour because --mute would sit near 1.4:1. */
.sec.band-green{
  background:#C7E8C2;
  padding-block:clamp(2.6rem,6vw,4.4rem)}
body.casepage .band-green .vid-note{color:#3C4649 !important}

/* three phase blocks stacked in one band. Each one opens with the same
   centred title-in-a-hairline used for section titles elsewhere, so the three
   phases read as peers and the eye has a clear break between them. They take
   the same type as a page-level section title, her call on 2026-10-23. The
   margins stay smaller than a page-level .sec-rule: these divide blocks
   inside one band, not whole sections of the page, and the band supplies its
   own padding above the first and below the last. */
/* the copy-and-mockup row that opens a phase, above its films */
.split.phase-split{margin-bottom:clamp(2rem,4vw,3rem)}
.films-eyebrow + .sec-rule.films-rule{margin-top:0}
.sec-rule.films-rule{
  margin-top:clamp(4.5rem,9vw,7.5rem);
  /* doubled from clamp(2rem,4vw,3.2rem), her call 2026-10-24: at 32-51px the
     copy under each phase title sat too tight against it */
  margin-bottom:clamp(4rem,8vw,6.4rem);
  /* the rule runs the full screen, not the 76rem content column, so the three
     phases read as full-width breaks in the band. The title stays centred,
     because .sec-rule's two fillers simply grow; only the line gets longer.
     The section already clips, for the rail, which also trims the few pixels
     100vw adds for the scrollbar. */
  margin-inline:calc(-1 * (var(--gutter) + max(0px,(100vw - var(--maxw)) / 2)))}
/* "(Excerpts)" rides with the title but is not part of the name, so it is a
   step down in size and weight rather than another line */
body.casepage .sec-rule.films-rule h2 .ph-ex{
  font-size:.62em !important;
  font-weight:600 !important;
  color:var(--ink-2) !important;
  white-space:nowrap}
/* The title needs side padding only in the narrow layout, where .sec-rule
   becomes a block with a border on top and the text would otherwise sit
   against the glass. Above that it is a flex row, and padding here pushes
   the two hairlines out by up to 64px a side on top of the flex gap, which
   is what left them stranded away from the type. The fillers' own min-width
   keeps the text off the edge. */
@media (max-width:50rem){
  body.casepage .sec-rule.films-rule h2{padding-inline:var(--gutter)}}
.films-eyebrow:first-child{margin-top:0 !important}
/* Phase 3 as a full-bleed strip rather than a grid: the six films are one
   set, so a row you scroll reads better than a page you read. The rail
   breaks the wrap with the same calc the other full-bleed pieces use, and
   the band clips the scrollbar-width excess that 100vw leaves. */
/* .post-rail sets the margin shorthand further down the file, which would
   reset margin-inline back to 0, so this carries both classes to win on
   specificity rather than relying on order. */
.post-rail.film-rail{
  margin-inline:calc(-1 * (var(--gutter) + max(0px,(100vw - var(--maxw)) / 2)));
  margin-top:clamp(1.6rem,3.5vw,2.6rem)}
.sec:has(.film-rail){overflow-x:clip}
/* The films are landscape, so the tiles are 16:9 and three fit across rather
   than six: six would put each player near 190px wide, which is the size the
   TLC video was already sent back from. Three across at 76rem is about
   400x225, and the rail still scrolls to the other three. */
.film-rail .rail-track{--rail-gap:14px;
  grid-auto-columns:calc((100% - 2 * var(--rail-gap)) / 3);
  padding-inline:var(--gutter)}
.film-rail .videobox.vtile{aspect-ratio:16 / 9}
.film-rail .film{margin:0}
@media (max-width:64rem){
  .film-rail .rail-track{grid-auto-columns:calc((100% - 1 * var(--rail-gap)) / 2)}}
@media (max-width:46rem){
  .film-rail .rail-track{grid-auto-columns:calc(100% - 2.5rem)}}

/* The phase number and year sit ABOVE the rule, not inside the h2. Inside,
   the hairline centred on the two-line block and landed between the two
   lines; out here the rule holds one line and the hairline sits on the
   middle of the big type, which is where it reads as a divider.
   --mute would be 4.02:1 on this white band and fails AA at this size, so
   the eyebrow takes --ink-2 at 8.68:1. */
body.casepage .films-eyebrow{
  font-family:var(--dsp) !important;
  /* a fixed size now that it is no longer a fraction of the title */
  font-size:clamp(.7rem,.62rem + .26vw,.84rem) !important;
  font-weight:700 !important;
  letter-spacing:.16em !important;
  text-transform:uppercase !important;
  color:var(--ink-2) !important;
  text-align:center;
  margin:clamp(4.5rem,9vw,7.5rem) 0 .6rem !important}
.sec-rule.films-rule + .vid-note{
  margin:0 auto !important;max-width:62ch;text-align:center}

/* six films, fixed at two columns and three rows. auto-fit with a 20rem floor
   was resolving to three across inside the 76rem wrap, which is the ~380px
   player the TLC video was already sent back from. Two columns are explicit
   here so the count cannot drift with the wrap width: about 590px each. The
   gap is tighter than .videopair because three rows of the wider gap left the
   band looking like six unrelated items rather than one series. */
.filmgrid{display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(1.6rem,3.4vw,2.8rem);margin-top:clamp(1.8rem,4vw,3rem)}
@media (max-width:44rem){.filmgrid{grid-template-columns:1fr}}
.film{margin:0}
/* The Alzheimer's film captions are film titles, not labels, so they are set
   in sentence case. Scoped to this page's two contexts (the rail and the
   phase splits) rather than changed globally; the PCPC captions are short
   topic labels and keep the uppercase treatment. */
body.casepage .film-rail .film figcaption,
body.casepage .phase-split .film figcaption{
  font-size:.92rem !important;
  font-weight:700 !important;
  letter-spacing:.01em !important;
  text-transform:none !important}

/* "(Excerpts)" qualifies the caption without being part of the film's name,
   so it drops the uppercase and the letterspacing the caption carries */
body.casepage .film figcaption .cap-ex{
  /* the caption is uppercase, so lowercase set at the same size reads larger
     than the name beside it; a step down evens them out */
  font-size:.85em !important;
  font-weight:600 !important;
  letter-spacing:.02em !important;
  text-transform:none !important;
  color:#3C4649 !important}
body.casepage .film figcaption{
  font-family:var(--dsp) !important;
  font-size:.74rem !important;
  font-weight:700 !important;
  letter-spacing:.11em !important;
  text-transform:uppercase !important;
  color:#111418 !important;
  margin-top:.85rem}

.videobox-wide{max-width:60rem;margin-left:auto;margin-right:auto}
/* a full-bleed grey band behind a lone player, the same grey the section
   title frames use */
.sec.band-grey{background:var(--band-grey);
  padding-block:clamp(2.6rem,6vw,4.4rem)}
/* the same band on plain white, for a page whose artwork already carries the
   colour and where a grey ground muddied it */
.sec.band-white{background:#FFFFFF;
  padding-block:clamp(2.6rem,6vw,4.4rem)}
/* the italic note sits in --mute, which is only 4.02:1 on white and fails AA
   for text this size. On this band it takes --ink-2 instead, at 8.68:1. */
body.casepage .band-white .vid-note{color:#3C4649 !important}

/* a My role band that opens with a lead sentence, then splits into phases */
.role-lede{margin:0 0 clamp(1.5rem,3.2vw,2.3rem)}
.phase-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(15rem,100%),1fr));
  gap:clamp(.9rem,2vw,1.4rem);align-items:stretch}
/* her blue at the same 50% tint the PCPC cards use. Only the Human Calling
   two-up row takes it; the Alzheimer's phase cards keep the neutral card.
   Tinted to 68% rather than the 50% used on the cards elsewhere, her call on
   2026-10-23 after seeing both. At 68% the body copy measures 7.99:1 and the
   site's own --accent teal clears AA at 4.74:1, so the labels no longer need
   a darker substitute. */
.phase-row.two-up .phase{background:#C8F0F6;border-color:transparent}
/* a phase row pinned to two across rather than letting auto-fit decide: four
   cards of running text want 2x2, not a row of four narrow columns. */
.phase-row.two-up{grid-template-columns:repeat(2,1fr)}
@media (max-width:44rem){.phase-row.two-up{grid-template-columns:1fr}}
.phase{padding:clamp(1.2rem,2.2vw,1.7rem);border-radius:12px;
  background:var(--highlight);border:1px solid var(--rule)}
.phase p:last-child{margin-bottom:0}
body.casepage .phase-n{
  font-family:var(--dsp) !important;
  font-size:.7rem !important;
  font-weight:800 !important;
  letter-spacing:.16em !important;
  text-transform:uppercase !important;
  color:var(--mute) !important;
  margin:0 0 .5rem !important;}
/* a notch down and slightly tighter, so the longest phase title holds one line */
body.casepage .phase .lyr{
  font-size:16px !important;
  letter-spacing:-.01em !important;
  margin:0 0 .9rem !important}
/* an award that links out to its own citation */
body.casepage .panel li a{color:inherit !important;text-decoration:underline;
  text-underline-offset:3px;text-decoration-thickness:1px;
  text-decoration-color:var(--mute)}
body.casepage .panel li a:hover{text-decoration-color:currentColor}

/* a sentence of context above the numbers in a panel */
.panel-lede{margin:0 0 1.1rem}
.role-cols p:last-child{margin-bottom:0}

/* a study with no artwork: the two columns sit side by side with no image
   slot, so the top row needs no special case */
body.casepage .prose2.top-row:not(:has(img)):not(:has(.ph-note)){
  align-items:start}

/* a subtitle under a case-study title, for a named piece of work whose
   subject needs a second line */
/* Human Calling sets its title as a serif-italic name followed by a plain-sans
   line at the same size. Pages that carry the name and the kind of work as two
   separate elements get the identical treatment: the sub is a second line of
   the h1, not a caption, so it matches it in face, size, weight and colour and
   sits on the next baseline. */
body.casepage .case-sub{
  font-family:var(--dsp) !important;
  font-size:clamp(2.2rem,1rem + 5vw,4.4rem) !important;
  font-weight:800 !important;
  letter-spacing:-.03em !important;
  line-height:1.04 !important;
  color:#111418 !important;
  text-align:center;
  margin:.08em 0 0 !important}

.sec{padding-block:clamp(2rem,5vw,3.4rem)}
/* Overview, My role and Challenge sit side by side */
.prose3{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(17rem,100%),1fr));
  gap:clamp(1.4rem,3vw,2.4rem);align-items:start}
.prose2{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(20rem,100%),1fr));
  gap:clamp(2rem,6vw,5.5rem);align-items:start}
/* One body size for every block of case-study prose. The only deviation is the
   context column, which is deliberately quieter. */
.sec{--case-txt:clamp(1rem,.96rem + .25vw,1.1rem)}
/* a two-column row where the media deserves more room than the copy beside
   it. The text column still clears a comfortable measure at this ratio. */
@media (min-width:52rem){
  .prose2.media-wide{grid-template-columns:1.35fr 1fr}}

.prose2 p,.prose3 p,.split-bd p,.hl li,.panel li{font-size:var(--case-txt)}
.prose2 p,.prose3 p{margin:0 0 1rem;line-height:1.68}
.prose3 .ctx p,.prose2 .ctx p{font-size:clamp(.9rem,.87rem + .14vw,.97rem);color:var(--mute)}
.prose3 .lead-col p,.prose2 .lead-col p{font-weight:400;color:var(--ink-2)}
.prose2 p:last-child{margin-bottom:0}
.prose2 h4{font-family:var(--dsp);font-weight:700;font-size:.72rem;letter-spacing:.12em;
  text-transform:uppercase;color:#111418;margin:0 0 .8rem}
/* the two halves of My role sit under it, not beside it */
.lyr{font-family:var(--dsp);font-weight:700;font-size:.68rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent);margin:0 0 .5rem}
.lyr.gap{margin-top:1.7rem}
/* image one side, everything else the other */
.split{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(21rem,100%),1fr));
  gap:clamp(1.6rem,4vw,3.2rem);align-items:center}
.split-media img{display:block;width:100%;height:auto}
/* the mockup runs off the left edge of the page so it fills that half of the
   band. The text column keeps its grid position; only the image grows. */
.split-media.bleed-l{
  margin-left:calc(-1 * (var(--gutter) + max(0px, (100vw - var(--maxw)) / 2)));
}
@media (max-width:52rem){
  .split-media.bleed-l{margin-left:calc(-1 * var(--gutter));margin-right:calc(-1 * var(--gutter))}
}
/* A bleed is sized from 100vw, which counts the scrollbar, so on a desktop
   window it lands about 8px past the real viewport and adds a sideways
   scroll. Clipping the section that holds one trims exactly that excess and
   nothing of the image. overflow-x:clip, not hidden: clip does not create a
   scroll container. */
.sec:has(.split-media.bleed-l),
.sec:has(.split-media.bleed-r){overflow-x:clip}

/* the mirror of bleed-l: the image runs off the RIGHT edge of the page and
   fills that half of the band, with the copy keeping its grid position on the
   left. Used where the copy reads first and the artefact answers it. */
.split-media.bleed-r{
  margin-right:calc(-1 * (var(--gutter) + max(0px, (100vw - var(--maxw)) / 2)));
}
@media (max-width:52rem){
  .split-media.bleed-r{margin-left:calc(-1 * var(--gutter));margin-right:calc(-1 * var(--gutter))}
}
/* a caption under a bled image, set as a quiet note rather than a label: the
   uppercase, letterspaced caption the film tiles use was reading as a title
   for the image. Small italic, sentence case, centred on the image. */
body.casepage .bleed-cap{
  font-family:var(--bdy) !important;
  font-size:.84rem !important;
  font-style:italic !important;
  font-weight:400 !important;
  letter-spacing:.01em !important;
  text-transform:none !important;
  color:var(--ink-2) !important;
  text-align:center;
  padding-inline:var(--gutter)}
.split-bd p{margin:0 0 1.2rem;line-height:1.68}
.split-bd h4{font-family:var(--dsp);font-weight:700;font-size:.72rem;letter-spacing:.12em;
  text-transform:uppercase;color:#111418;margin:0 0 .8rem}
/* an audio player for a radio spot. Radio has no frame to show, so the piece
   is labelled rather than illustrated: a kicker that says what it is and a
   line that says where it ran, with the native player underneath. The native
   control is deliberate. It is keyboard reachable, it reads correctly to a
   screen reader, and it already looks like audio on every platform, which a
   custom one has to earn. */
/* three square cuts in a row, each under its own label. The count is fixed
   rather than auto-fit, which has twice resolved to a column count that made
   the players too small. */
.audioset{display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(1.2rem,2.6vw,2rem);margin-top:clamp(1.8rem,4vw,2.8rem);
  align-items:start}
@media (max-width:58rem){.audioset{grid-template-columns:repeat(2,1fr)}}
@media (max-width:38rem){.audioset{grid-template-columns:1fr}}
.videobox.sq{aspect-ratio:1 / 1}
.audiobox{margin:0}
.audiobox figcaption{margin:0 0 .75rem}
body.casepage .audiobox .audio-k{
  display:block;
  font-family:var(--dsp) !important;
  font-size:.68rem !important;
  font-weight:700 !important;
  letter-spacing:.1em !important;
  text-transform:uppercase !important;
  color:#3C4649 !important;
  margin-bottom:.3rem}
/* the caption sits above its player, so three captions of different lengths
   would start the three players at three different heights. Holding the
   description to two lines keeps the row of players level. */
body.casepage .audiobox .audio-t{display:block;color:#3C4649 !important;
  min-height:3.2em}
@media (max-width:38rem){body.casepage .audiobox .audio-t{min-height:0}}
.audiobox audio{display:block;width:100%}

/* a full-bleed rail of square posts. Six fit across on a wide screen; the rest
   are reached by the arrows, by swiping, or by a trackpad swipe. */
.post-rail{position:relative;margin:clamp(1.6rem,4vw,2.8rem) 0 0}
.rail-track{
  --rail-gap:10px;
  display:grid;grid-auto-flow:column;
  grid-auto-columns:calc((100% - 5 * var(--rail-gap)) / 6);
  gap:var(--rail-gap);
  margin:0;padding:0;list-style:none;
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-behavior:smooth;
  scrollbar-width:none;-ms-overflow-style:none}
.rail-track::-webkit-scrollbar{display:none}
.rail-track li{scroll-snap-align:start}
.rail-track img{display:block;width:100%;height:auto;aspect-ratio:1/1;object-fit:cover}

.rail-btn{position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:2.9rem;height:2.9rem;border:0;border-radius:50%;cursor:pointer;
  display:grid;place-items:center;padding:0;
  background:rgba(255,255,255,.92);color:var(--deep);
  box-shadow:0 1px 3px rgba(17,60,69,.16),0 6px 18px -6px rgba(17,60,69,.38);
  transition:opacity .25s ease,background .2s ease,transform .2s ease}
.rail-btn svg{width:1.35rem;height:1.35rem}
.rail-btn:hover{background:#fff}
.rail-btn.prev{left:clamp(.5rem,1.6vw,1.1rem)}
.rail-btn.next{right:clamp(.5rem,1.6vw,1.1rem)}
.rail-btn[disabled]{opacity:0;pointer-events:none}
@media (prefers-reduced-motion:reduce){.rail-track{scroll-behavior:auto}}

@media (max-width:60rem){
  .rail-track{grid-auto-columns:calc((100% - 2 * var(--rail-gap)) / 3)}
}
@media (max-width:34rem){
  .rail-track{--rail-gap:6px;grid-auto-columns:calc((100% - 1 * var(--rail-gap)) / 2)}
  .rail-btn{width:2.4rem;height:2.4rem}
}

.hl{margin:0;padding-left:1.1rem}
/* a highlights list standing on its own rather than beside a column of copy.
   Its lines are long, so it keeps a measure instead of running the full
   76rem, and the items get more air than the two-column version needs. */
ul.hl.lead-col{max-width:62rem}
ul.hl.lead-col li{margin-bottom:.9rem}
.hl li{margin-bottom:.55rem;line-height:1.6}
.ph-note{color:var(--mute);font-style:italic}

/* the section title sits on its own full-bleed frame */
.sec-banner{position:relative;min-height:clamp(13rem,30vh,20rem);overflow:hidden;
  display:grid;place-items:center}
.sec-banner img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.sec-banner::after{content:"";position:absolute;inset:0;background:rgba(235,234,230,.9)}
/* the grid centres the heading box, but a wrapped heading fills the band, so
   the lines themselves have to be centred too */
.sec-banner h2{position:relative;z-index:1;color:#111418;text-transform:uppercase;
  font-size:clamp(1.8rem,1rem + 3.4vw,3.4rem);letter-spacing:.02em;margin:0;
  text-align:center;padding-inline:var(--gutter)}

/* a section band in a flat brand colour instead of the washed photograph.
   White on this slate is 6.78:1; the usual near-black title would be 2.72:1
   and would fail even the large-text threshold, so the title inverts. */
.sec-banner.tone-slate{background:#585A6D}
.sec-banner.tone-slate img,
.sec-banner.tone-slate::after{display:none}
body.casepage .sec-banner.tone-slate h2{color:#FFFFFF !important}

/* a band keeping its photograph, with the pale default wash swapped for a dark
   one. Unused at the moment: the Legal Council page went back to flat colour. The brightest pixel in the art is #757383, so white already clears AA
   at 4.63:1; the wash takes it to 5.95:1 and matches the title banner's tone. */
.sec-banner.art-dark::after{background:rgba(22,24,44,.2)}
body.casepage .sec-banner.art-dark h2{color:#FFFFFF !important}

/* near-black. White sits at 13.77:1, the strongest pairing on the page. */
.sec-banner.tone-charcoal{background:#2D2D2D}
.sec-banner.tone-charcoal img,
.sec-banner.tone-charcoal::after{display:none}
body.casepage .sec-banner.tone-charcoal h2{color:#FFFFFF !important}

/* the mark's orange, kept for reference. White on it is only 2.52:1, so it
   would need a near-black title, which measures 7.32:1.
.sec-banner.tone-orange{background:#FE7F40}
.sec-banner.tone-orange img,
.sec-banner.tone-orange::after{display:none}
body.casepage .sec-banner.tone-orange h2{color:#111418 !important}
*/

/* a near-white band. The title stays near-black at 16.62:1; white would be
   1.11:1 and invisible. */
.sec-banner.tone-mist{background:#F3F3F1}
.sec-banner.tone-mist img,
.sec-banner.tone-mist::after{display:none}
body.casepage .sec-banner.tone-mist h2{color:#111418 !important}

.panels{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(19rem,100%),1fr));
  gap:clamp(.9rem,2vw,1.4rem);margin-top:clamp(2rem,4vw,3rem)}
/* Result sits on a warm light grey, a shade cooler and darker than the cream
   page so all three surfaces (page, white Challenge, grey Result) read apart. */
.panel{padding:clamp(1.4rem,2.6vw,2rem);border-radius:12px;background:var(--wash);
  color:#3C4649}
.panel.plain{background:var(--highlight);color:var(--ink-2);
  border:1px solid var(--rule)}
.panel.plain h3{color:#111418}
.panel h3{font-family:var(--dsp);font-weight:700;font-size:.78rem;letter-spacing:.14em;
  text-transform:uppercase;margin:0 0 1rem;color:#111418}

.panel ul{margin:0;padding-left:1.1rem}
.panel li{margin-bottom:.7rem;line-height:1.58}
.panel li:last-child{margin-bottom:0}


/* quote wall */
.says{background:var(--wash)}
.quote-wall{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(20rem,100%),1fr));
  gap:clamp(.9rem,2vw,1.4rem);align-items:start}
.quote{margin:0;padding:clamp(1.3rem,2.4vw,1.8rem);background:var(--paper);
  border:1px solid var(--rule);border-radius:10px;position:relative}
.quote blockquote{margin:0}
.quote p{margin:0;font-size:clamp(.96rem,.92rem + .2vw,1.06rem);line-height:1.62;
  color:var(--ink-2)}
.quote figcaption{margin-top:1.1rem;font-family:var(--dsp);font-weight:700;
  font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:#111418}
.quote figcaption span{display:block;margin-top:.25rem;font-weight:600;
  letter-spacing:.06em;text-transform:none;color:var(--mute)}
/* unmistakably a slot, never a quote someone could mistake for real */
.quote.empty{border-style:dashed;background:transparent}
.quote.empty p{color:var(--mute);font-style:italic}

/* section headings and the trailing link rise; cards slide in from the right */
.cards-h,.seeall,.quote{transition:transform .65s cubic-bezier(.16,.84,.26,1),
    opacity .9s ease}
.rise-pre{opacity:0;transform:translate3d(0,26px,0)}
.quote.rise-pre{transform:translate3d(0,38px,0)}

/* home cards slide in from the right; inner pages rise instead */
/* the home cards slide in from the right, so before they reveal they sit 74px
   past the content edge and widen the page. Every card below the fold is in
   this state on load, which gave the home page a sideways scroll at every
   width. Clip the row rather than drop the animation; overflow-x:clip does
   not create a scroll container, so it cannot break position:sticky. */
.cards{overflow-x:clip}
.card.pre{opacity:0;transform:translate3d(74px,0,0)}
body.inner .card.pre{transform:translate3d(0,74px,0)}
/* work grid: title only, the card itself is the link */
.card-row.titles-only .card p,
.card-row.titles-only .card .more{display:none}

/* capability cards: tall image, title on the image, detail on hover */
.cards{padding-block:clamp(2.2rem,6vw,4rem) clamp(3rem,8vw,6rem)}
.cards-h{font-size:clamp(1.5rem,1rem + 2.1vw,2.6rem);text-align:center;
  margin-bottom:clamp(1.8rem,4vw,3rem)}
/* two across, 16:9, so footage drops in without being cropped */
.card-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(26rem,100%),1fr));
  gap:clamp(.9rem,2vw,1.6rem)}
.card{position:relative;display:block;overflow:hidden;text-decoration:none;color:#fff;
  aspect-ratio:16/9;border-radius:6px 6px 0 0;
  border-bottom:6px solid #111418;
  transition:transform .6s cubic-bezier(.16,.84,.26,1),box-shadow .4s ease,
    opacity .6s ease}
.card img{position:absolute;left:0;right:0;top:-9%;width:100%;height:118%;
  object-fit:cover;will-change:transform}
/* the loop lies over the still and only shows once it is actually running,
   so a slow connection never leaves a black rectangle */
.card-loop{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .45s ease;pointer-events:none}
.card.playing .card-loop{opacity:1}
.card::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(6,35,42,0) 38%,rgba(6,35,42,.74) 100%);
  transition:background .4s ease}
.card-txt{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;
  justify-content:flex-end;padding:clamp(1.1rem,2.1vw,1.7rem)}
.card h3{color:#fff;font-size:clamp(1rem,.88rem + .46vw,1.3rem);line-height:1.24}
.card p,.card .more{max-height:0;opacity:0;overflow:hidden;margin:0;
  transition:max-height .45s cubic-bezier(.2,.75,.3,1),opacity .3s ease,margin .45s ease}
.card p{font-family:var(--bdy);font-weight:300;font-size:clamp(.86rem,.82rem + .16vw,.96rem);
  line-height:1.58;color:rgba(255,255,255,.93)}
.card .more{display:block;font-family:var(--dsp);font-weight:700;font-size:.7rem;
  letter-spacing:.1em;text-transform:uppercase;color:#fff}
.card:hover,.card:focus-visible{transform:scale(1.055);z-index:4;
  box-shadow:0 26px 58px rgba(6,35,42,.42)}
.card:hover::after,.card:focus-visible::after{
  background:linear-gradient(180deg,rgba(6,35,42,.52),rgba(6,35,42,.9) 55%,rgba(6,35,42,.93))}
/* That darkening exists so revealed copy stays readable. A titles-only card has
   no copy to reveal, so it keeps the light bottom gradient and the image, or the
   loop, stays visible. */
.card-row.titles-only .card:hover::after,
.card-row.titles-only .card:focus-visible::after{
  background:linear-gradient(180deg,rgba(6,35,42,0) 38%,rgba(6,35,42,.74) 100%)}
.card:hover p,.card:focus-visible p{max-height:26rem;opacity:1;margin-top:.9rem}
.card:hover .more,.card:focus-visible .more{max-height:3rem;opacity:1;margin-top:1.1rem}
@media (max-width:860px){
  .card-row{grid-template-columns:1fr;gap:1rem}
  .card:hover,.card:focus-visible{transform:none}
  .card p,.card .more{max-height:none;opacity:1}
  .card p{margin-top:.9rem}
  .card .more{margin-top:1.1rem}
  .card::after{background:linear-gradient(180deg,rgba(6,35,42,.42),rgba(6,35,42,.86))}
}
@media (hover:none){
  .card p,.card .more{max-height:none;opacity:1}
  .card p{margin-top:.9rem}
  .card .more{margin-top:1.1rem}
  .card::after{background:linear-gradient(180deg,rgba(6,35,42,.42),rgba(6,35,42,.86))}
}

/* content blocks */
.block{display:grid;grid-template-columns:1fr 1.1fr;gap:clamp(1.5rem,4vw,4rem);
  align-items:center;padding-block:clamp(2.5rem,7vw,5rem)}
.block.flip > .bd{order:2}
.block h2{font-size:clamp(1.7rem,1.1rem + 2.8vw,3.3rem);margin-bottom:1.1rem}
.block .bd p{margin:0 0 1rem;max-width:52ch}
.block .bd p:last-child{margin-bottom:0}
.kicker{font-family:var(--dsp);font-weight:700;font-size:.72rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);margin:0 0 .7rem}
.media{min-width:0}
.ph{border:2px dashed var(--rule);background:var(--wash);aspect-ratio:4/3;
  display:flex;align-items:center;justify-content:center;text-align:center;padding:1.4rem;
  font-family:var(--dsp);font-weight:700;font-size:.72rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--mute);max-width:100%}
.ph.wide{aspect-ratio:16/9}
.media img{display:block;width:100%;max-width:100%;height:auto}
.tags{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;padding:0;margin:1.2rem 0 0}
.tags li{font-family:var(--dsp);font-weight:700;font-size:.72rem;letter-spacing:.06em;
  text-transform:uppercase;border:2px solid var(--ink);padding:.42rem .7rem;
  font-variant-numeric:tabular-nums}

/* numbers band */
.band{background:linear-gradient(135deg,var(--band-a),var(--band-b));color:var(--band-fg)}
.band .wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(12rem,100%),1fr));
  gap:2rem clamp(1.5rem,4vw,3rem);padding-block:clamp(2.4rem,6vw,4rem)}
.band h2{color:var(--band-fg);grid-column:1/-1;font-size:clamp(1.4rem,1.1rem + 1.6vw,2.2rem);
  margin-bottom:.4rem}
.band .fig{display:block;font-family:var(--dsp);font-weight:700;
  font-size:clamp(2rem,1.3rem + 2.6vw,3.4rem);line-height:1;letter-spacing:.01em;
  color:var(--highlight);font-variant-numeric:tabular-nums}
.band .unit{display:block;margin-top:.6rem;font-size:.98rem;line-height:1.4;color:var(--band-dim)}
.band .src{display:block;margin-top:.4rem;font-family:var(--dsp);font-weight:700;
  font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:var(--band-dim);opacity:.8}

/* case study long form */
.case{padding-block:clamp(2.2rem,6vw,4rem)}
.case h2{font-size:clamp(1.8rem,1.2rem + 3vw,3.4rem);margin-bottom:.4rem}
.case .meta{font-family:var(--dsp);font-weight:700;font-size:.72rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--mute);margin:0 0 1.8rem}
.case .grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.5rem,4vw,3.5rem)}
.case h3{font-size:1rem;letter-spacing:.1em;margin-bottom:.6rem;color:var(--accent)}
.case p{margin:0 0 1rem;max-width:56ch}
.case ul.chan{list-style:none;padding:0;margin:0}
.case ul.chan li{padding-block:.55rem;border-bottom:1px solid var(--rule)}
.case ul.chan li:first-child{border-top:1px solid var(--rule)}

/* list of entries */
.rows{border-top:2px solid var(--ink)}
.row{display:grid;grid-template-columns:10rem 1fr;gap:.4rem 2.5rem;padding-block:1.7rem;
  border-bottom:1px solid var(--rule)}
.row .yr{font-family:var(--dsp);font-weight:700;font-size:.74rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--mute);padding-top:.3rem;min-width:0}
.row .bd{min-width:0}
.row h3{font-size:clamp(1.05rem,1rem + .6vw,1.4rem);margin-bottom:.5rem;letter-spacing:.02em}
/* the Experience rows run to the full column rather than the 58ch the other
   case rows keep: these are one-sentence summaries, not paragraphs, and at
   58ch a single sentence broke over three short lines with a wide gap of
   empty page beside it */
body.aboutpage .row p{max-width:none}

/* the employer and place, between the role and what it covered */
body.aboutpage .row .org{
  font-family:var(--dsp);font-weight:700;font-size:.78rem;letter-spacing:.06em;
  color:#3C4649;margin:0 0 .5rem}
.row p{margin:0 0 .6rem;max-width:58ch}
.row p:last-child{margin-bottom:0}

/* columns */
.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(14rem,100%),1fr));
  gap:2rem clamp(1.5rem,4vw,3rem)}
.cols h3{font-size:.86rem;letter-spacing:.12em;margin-bottom:.8rem}
.cols ul{list-style:none;padding:0;margin:0}
.cols li{padding-block:.42rem;border-bottom:1px solid var(--rule);font-size:.96rem}

/* contact */
/* the footer is the one band that repeats on every page, so it is a flat
   near-black rather than the teal gradient: it reads as the end of the page
   instead of competing with whatever coloured band sits above it. White on
   it measures 17.6:1. Settled 2026-10-22. */
.contact{background:#17191C;color:#FFFFFF}
.contact .wrap{padding-block:clamp(1.6rem,3.5vw,2.4rem)}
.contact h2{color:var(--band-fg);font-size:clamp(1.7rem,1.1rem + 2.8vw,3.3rem);
  max-width:18ch;margin-bottom:1.4rem}
.contact .foot{margin-top:1.6rem;font-size:.92rem;color:var(--band-dim)}
.contact .foot a{color:var(--band-fg)}

@media (max-width:860px){
  .hero{grid-template-columns:1fr;align-items:start}
  .block,.case .grid{grid-template-columns:1fr}
  .block.flip > .bd{order:0}
}
@media (max-width:560px){
  .row{grid-template-columns:1fr}
  .row .yr{padding-top:0}
}
/* Touch targets. Checked at 390px on 2026-10-23: the nav pills measured
   72x30 and the footer LinkedIn link 228x23, both under the 44px minimum a
   finger needs. Only the hit area grows; the type, the pill shape and the
   desktop layout are unchanged, because the padding is added on pointer
   devices that are coarse rather than at a width breakpoint. */
@media (pointer:coarse){
  .pill a{padding-block:.85rem}
  .out a,.li{display:inline-flex;align-items:center;min-height:44px}
  .scroll{width:44px;height:44px}
}

@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* portfolio tiles */
.tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(15rem,100%),1fr));
  gap:clamp(1rem,2.5vw,1.8rem);padding-block:clamp(1.8rem,5vw,3rem)}
.tile{position:relative;display:block;aspect-ratio:1;overflow:hidden;background:var(--wash);
  border-radius:2px;text-decoration:none;color:inherit;min-width:0}
.tile img{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .4s ease}
.tile:hover img{transform:scale(1.04)}
.tile .cap{position:absolute;inset:auto 0 0 0;padding:1rem;
  background:linear-gradient(to top,rgba(10,49,57,.92),rgba(10,49,57,.55) 60%,transparent);
  color:#FFFFFF;opacity:0;transition:opacity .28s ease}
.tile:hover .cap,.tile:focus-visible .cap{opacity:1}
.tile .cap b{display:block;font-family:var(--dsp);font-weight:700;font-size:.9rem;
  letter-spacing:.03em;text-transform:uppercase;line-height:1.2}
.tile .cap span{display:block;margin-top:.3rem;font-size:.84rem;opacity:.9}
.tile.pending{border:2px dashed var(--rule);background:var(--paper);display:flex;
  align-items:flex-end;padding:1.1rem;cursor:default}
.tile.pending .lbl{font-family:var(--dsp);font-weight:700;font-size:.86rem;
  letter-spacing:.03em;text-transform:uppercase;line-height:1.25;color:var(--ink)}
.tile.pending .lbl em{display:block;font-style:normal;font-weight:400;font-size:.74rem;
  letter-spacing:.1em;color:var(--mute);margin-top:.45rem;font-family:var(--dsp)}
.tile.pending .num{position:absolute;top:1rem;left:1.1rem;font-family:var(--dsp);
  font-weight:700;font-size:.72rem;letter-spacing:.12em;color:var(--accent)}

.li{display:inline-flex;align-items:center;gap:.7rem;text-decoration:none;
  color:var(--band-fg);font-family:var(--dsp);font-weight:700;font-size:.84rem;
  letter-spacing:.04em}
.li svg{width:1.35rem;height:1.35rem;flex:none;fill:currentColor}
.li span{border-bottom:2px solid transparent;padding-bottom:2px}
.li:hover span{border-bottom-color:currentColor}
/* The footer is the copyright on the left and LinkedIn as an icon alone on
   the right. Her call 2026-10-24: the masthead already names LinkedIn, so the
   spelled-out URL read as a repeat. The icon stays because the masthead link
   is hidden below 760px, which leaves this as the only LinkedIn link on a
   case study on a phone. The copyright in #B8BEC3 measures 9.39:1 on #17191C. */
.contact .wrap{display:flex;align-items:center;justify-content:space-between;
  gap:1rem;flex-wrap:wrap}
.contact .copy{margin:0;font-family:var(--dsp);font-weight:400;font-size:.82rem;
  letter-spacing:.03em;color:#B8BEC3}
.contact .li{transition:opacity .2s}
.contact .li:hover{opacity:.75}


/* full-bleed feature: copy left on the page grid, image running to the edge */
.feature{display:grid;align-items:center;
  grid-template-columns:max(var(--gutter),calc((100% - var(--maxw))/2 + var(--gutter))) minmax(0,1fr) 50%}
.feature > .feature-bd{grid-column:2;grid-row:1}
.feature > .feature-media{grid-column:3;grid-row:1;align-self:stretch}
.feature-bd{padding-block:clamp(2rem,4vw,3.2rem);
  padding-inline:0 clamp(1.5rem,4vw,3.5rem)}
.feature-bd h2{font-size:clamp(1.05rem,.7rem + 1.6vw,1.8rem);margin-bottom:1.1rem}
.feature-bd p{margin:0 0 1rem;max-width:46ch}
.feature-bd p:last-child{margin-bottom:0}
.feature-media{position:relative;overflow:hidden;min-width:0;
  min-height:clamp(19rem,44vh,30rem)}
.feature-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.feature-media .ph{position:absolute;inset:0;aspect-ratio:auto;height:auto;border-width:2px}
@media (max-width:860px){
  .feature,.feature.flip{grid-template-columns:1fr}
  .feature > .feature-bd,.feature.flip > .feature-bd{grid-column:1;grid-row:1;
    padding-inline:var(--gutter);padding-block:clamp(2rem,6vw,3rem) 1.4rem}
  .feature > .feature-media,.feature.flip > .feature-media{grid-column:1;grid-row:2;min-height:0}
  .feature-media .ph{aspect-ratio:4/3}
}

/* mirrored feature: image bleeds off the left, copy right */
.feature.flip{
  grid-template-columns:50% minmax(0,1fr) max(var(--gutter),calc((100% - var(--maxw))/2 + var(--gutter)))}
.feature.flip > .feature-media{grid-column:1;grid-row:1;align-self:stretch}
.feature.flip > .feature-bd{grid-column:2;grid-row:1;padding-inline:clamp(1.5rem,4vw,3.5rem) 0}
.feature.tint{background:var(--wash)}


/* centred intro over a pair of images */
.duo{padding-block:clamp(2.6rem,6vw,4.6rem)}
.duo-head{max-width:46rem;margin:0 0 clamp(1.6rem,3.5vw,2.4rem)}
.duo-head h2{font-size:clamp(1.05rem,.7rem + 1.6vw,1.8rem);margin-bottom:1rem}
.duo-head p{margin:0 0 1rem;max-width:58ch}
.duo-head p:last-child{margin-bottom:0}
.duo-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(16rem,100%),1fr));
  gap:clamp(.8rem,2vw,1.4rem)}
.duo-grid .ph{aspect-ratio:3/4}
.duo-grid img{display:block;width:100%;height:auto;aspect-ratio:3/4;object-fit:cover}
@media (max-width:560px){.duo-grid .ph,.duo-grid img{aspect-ratio:4/3}}

/* statement-only hero */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.hero.statement{grid-template-columns:minmax(0,1.14fr) minmax(0,.86fr);
  align-items:end;padding-block:clamp(3rem,8vw,5.6rem) clamp(2.4rem,6vw,4.5rem)}
.hero.statement h1{font-size:clamp(1.9rem,1.2rem + 3.2vw,3.6rem);max-width:none;
  line-height:1.08;margin:0}
.hero.statement h1 .big{font-size:1.45em;letter-spacing:.01em}
.hero.statement .say{max-width:44ch}
.hero.statement .say p{margin:0 0 1.2rem;color:var(--ink-2);
  font-size:clamp(1rem,.96rem + .25vw,1.12rem);line-height:1.72}
.hero.statement .say p:last-child{margin-bottom:0}

.tiles img{display:block;width:100%;height:auto;aspect-ratio:1;object-fit:cover}
.case .media img{display:block;width:100%;height:auto}

/* full-bleed opening image with the line over it */
.herofull{position:relative;min-height:clamp(20rem,62vh,38rem);display:flex;
  align-items:flex-end;overflow:hidden;background:var(--band-b)}
.herofull > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.herofull .scrim{position:relative;width:100%;padding-block:clamp(2rem,5vw,3.4rem) clamp(1.6rem,4vw,2.8rem);
  background:linear-gradient(to top,rgba(8,40,48,.86),rgba(8,40,48,.42) 58%,rgba(8,40,48,.06))}
.herofull .who{font-family:var(--dsp);font-weight:700;font-size:.74rem;letter-spacing:.16em;
  text-transform:uppercase;color:#FFFFFF;opacity:.82;margin:0 0 .7rem}
.herofull h1{color:#FFFFFF;font-size:clamp(1.45rem,1rem + 2.4vw,2.7rem);max-width:24ch;margin:0}

/* One size and one colour for every section title on Home and About, her
   call 2026-10-24. Before this they ran from 35px to 54px at 1280 and the
   home title was the teal ink #113C45. All now take Selected Work's own
   scale, clamp(1.5rem,1rem + 2.1vw,2.6rem), about 42px at 1280, and the
   hero grey #3C4649 (9.70:1 on white, 6.85:1 on the Education blue).
   Let's Connect keeps white type on its dark band; only its size joins.
   Kept last in the file so it wins over each title's original rule above.
   The case-study pages' .sec-rule titles are a separate system and are not
   touched here. */
.cards-h,
body.aboutpage .block h2,
body.aboutpage .case h2,
body.aboutpage .cred-rule h2,
body.aboutpage .connect h2{font-size:clamp(1.5rem,1rem + 2.1vw,2.6rem)}
.cards-h{color:#3C4649}

/* Back to top, on every case study, her call 2026-10-24. A see-through grey
   pill fixed bottom right: the hero grey #3C4649 at 72% with a light blur, so
   the page shows through it, and white type. Its contrast depends on what is
   behind it; at the worst case, plain white, the type measures 4.37:1, and
   over the darker photos and videos it is higher. It was the nav yellow,
   then the logo blue, then this, all the same day. Set in the nav's own
   small caps so it reads as part of the same navigation. It began as an arrow-only circle; she could not
   tell what it was, so a word went on it: first "Back to top", then just
   "Top" beside the arrow, which halves its width on a phone. Screen readers
   still hear the full "Back to top" from the aria-label. It is a plain link to #top,
   so it works with no script; site.js hides it until the reader is a screen
   down and fades it in from there. 2.75rem tall, the 44px touch minimum.
   z-index sits under the masthead's 30. */
.totop{position:fixed;z-index:25;
  right:max(1rem,env(safe-area-inset-right));
  bottom:calc(max(1.25rem,env(safe-area-inset-bottom)) + var(--lift,0px));
  height:2.75rem;padding:0 1.1rem 0 .95rem;border-radius:999px;
  display:inline-flex;align-items:center;gap:.45rem;
  font-family:var(--dsp);font-weight:700;font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap;
  background:rgba(60,70,73,.72);color:#FFFFFF;text-decoration:none;
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  box-shadow:0 4px 14px rgba(17,20,24,.14);
  transition:opacity .3s ease,transform .3s ease,background .2s}
.totop:hover{background:rgba(60,70,73,.9)}
.totop svg{flex:none;width:1rem;height:1rem;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.totop.off{opacity:0;transform:translateY(.6rem);pointer-events:none}
/* --lift is set by site.js while the footer is on screen: the button rides
   up with the footer's top edge instead of sitting on the LinkedIn icon. */

/* Back to work, at the foot of every case study: smaller and centred, her
   call 2026-10-24. It was 163 x 60px and right-aligned. The case-page type
   reset sets its face and size with !important, so the size here has to
   match that weight to win. Same face, colours and yellow as before; the
   padding keeps it at the 44px touch minimum. */
body.casepage .seeall{text-align:center}
body.casepage .seeall .btn{
  font-size:.95rem !important;
  padding:.7rem 1.45rem}

/* A rule under the About hero, her call 2026-10-24, dividing the statement
   from the page it introduces. Logo blue, 2px like the rule under Experience
   Snapshot, and edge to edge across the screen: it sits outside the .wrap,
   directly in the full-width hero band. First drawn at 1px across the content
   width; she asked for heavier and full width the same day. Decoration only
   (2.06:1 on white), so nothing depends on seeing it. */
body.aboutpage .hero-rule{display:block;border:0;height:2px;width:100%;margin:0;
  background:#6FC1CD}

/* Case-study type in the About neutrals, her call 2026-10-24: "every blue
   word in the case studies to the About page's black and grey". Body copy
   comes from the reset above (#3C4649). These are the pieces that set their
   own teal: the small-caps labels (#10707F), the role lines, captions and
   eyebrows (#113C45 / #1F525C) all take #3C4649; the muted hints (#5F858D)
   take the About years' #6B7275. Banner role lines on the dark TLC and heart
   valve banners stay white, and coloured panels keep their own rules, which
   are more specific than these. The yellow Back to work button keeps the
   nav pill's #0F4C5A label so it still matches the masthead. */
html body.casepage .lyr,
html body.casepage .audio-k,
html body.casepage .audio-t,
html body.casepage .cap-ex,
html body.casepage .vid-note,
html body.casepage .films-eyebrow,
html body.casepage .case-hero:not(.banner) .role,
html body.casepage .case-hero.banner.hc .role{color:#3C4649 !important}
html body.casepage .ba-hint,
html body.casepage .phase-n,
html body.casepage .scroll-hint{color:#6B7275 !important}
html body.casepage .seeall .btn,
html body.casepage .seeall .btn *{color:#0F4C5A !important}
/* and a link's underline inside case-study copy follows the grey, so a link
   reads as grey text with a softer grey rule rather than a teal one. */
html body.casepage .sec a:not(.btn){text-decoration-color:rgba(60,70,73,.45)}
html body.casepage .sec a:not(.btn):hover{text-decoration-color:currentColor}

/* "View my full experience on LinkedIn" under the last Experience row, her
   wording 2026-10-24. Small and grey like the rest of the page, set in the
   description column so it lines up with the text above it; on a phone,
   where the rows stack, it starts at the left edge with them. A plain link
   that leaves the site, so it opens a new tab like every other. */
body.aboutpage .exp-more{margin:1.1rem 0 0;padding-left:calc(10rem + 2.5rem);
  font-size:.88rem}
body.aboutpage .exp-more a{color:#3C4649;text-decoration:underline;
  text-decoration-color:rgba(60,70,73,.45);text-underline-offset:.2em}
body.aboutpage .exp-more a:hover{text-decoration-color:currentColor}
@media (max-width:560px){body.aboutpage .exp-more{padding-left:0}}

/* ---- Mobile pass, 2026-10-24 -------------------------------------------
   Every live page checked by eye at 375px and by script at 320-1920. The
   brief was "on mobile, things are centred". Headings, labels, lone buttons,
   lone links and the hint captions centre below 46rem; running paragraphs
   and lists stay left-aligned, because centred body text is hard to read
   (every line starts somewhere new) and would be the one thing on the page
   that is not left-aligned on desktop either. */
@media (max-width:46rem){
  body.aboutpage .block .kicker,
  body.aboutpage .block h2,
  body.aboutpage .case > h2{text-align:center}
  body.aboutpage .exp-more{text-align:center;padding-left:0}
  body.casepage .live-cta,
  html body.casepage .ba-hint,
  html body.casepage .scroll-hint,
  html body.casepage .vid-note{text-align:center !important}}
/* the long section titles ("Multichannel marketing", "Social media
   engagement") ran to within a few px of both screen edges on a phone */
@media (max-width:50rem){
  body.casepage .sec-rule:not(.films-rule) h2{padding-inline:var(--gutter)}}
/* the PCPC My role box was built for one paragraph (.role-solo p{margin:0})
   and now holds two; the second had no gap above it */
.role-solo p + p{margin-top:1rem}
/* Phase 3 film rail: the track has gutter padding, but scroll-snap aligned
   the first film to the very edge and ignored it, so on a phone the first
   player and its caption touched the screen edge. Snap to the padding. */
.film-rail .rail-track{scroll-padding-inline:var(--gutter)}
/* "Heart Valve Disease 2026 PSA" wrapped with "PSA" alone on a phone; the
   year and "PSA" now stay together */
body.casepage .psa-head .nb{white-space:nowrap}

/* ---- Client Growth: "How the engagement grew" ----------------------------
   Her call 2026-10-24. The page had no visual, and there is no client artwork
   it could show (the client is unnamed), so the engagement itself is drawn:
   five steps, every line taken from the page's own copy. It sits on the same
   warm card as About's Career Highlights (#F6F2EE, 12px radius) and uses the
   same blue dots as About's timeline.
   Measured on #F6F2EE: titles #111418 16.58:1, labels and text #3C4649
   8.71:1, the kicker #3B9CAA 2.89:1 (as on About, her choice). The dots
   (logo blue) and connectors (#8A9096) are decoration.
   The case-page type reset sets face, size, weight, case and colour with
   !important on everything in .sec, so each of those is restated here with
   !important to win. */
body.casepage .engage{margin:0 0 clamp(2.5rem,5vw,4rem);background:#F6F2EE;
  border-radius:12px;padding:clamp(1.4rem,3vw,2.4rem)}
body.casepage .engage .eg-kicker{margin:0 0 clamp(1.2rem,2.4vw,1.8rem);
  font-family:var(--dsp) !important;font-size:.7rem !important;font-weight:700 !important;
  letter-spacing:.14em !important;text-transform:uppercase !important;
  line-height:1.3 !important;color:#3B9CAA !important}
.eg-steps{--eg-gap:clamp(1rem,2vw,1.6rem);list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  column-gap:var(--eg-gap);row-gap:.4rem}
/* each step shares the list's three rows (label, title, text) through
   subgrid, so a label that wraps to two lines ("Integrated communications")
   pushes all five titles down together and they stay on one line */
.eg-step{position:relative;display:grid;grid-row:span 3;grid-template-rows:subgrid;
  align-content:start;padding-top:1.6rem}
/* the dot that marks each step */
.eg-step::after{content:"";position:absolute;top:0;left:0;width:.7rem;height:.7rem;
  border-radius:50%;background:#6FC1CD}
/* the connector from this step's dot to the next one, ending in a small
   arrowhead drawn by the second gradient */
.eg-step:not(:last-child)::before{content:"";position:absolute;top:.3rem;
  left:1.1rem;right:calc(-1 * var(--eg-gap) + .4rem);height:.45rem;
  background:
    linear-gradient(#8A9096,#8A9096) left center / calc(100% - .3rem) 1px no-repeat,
    conic-gradient(from -135deg at 100% 50%,#8A9096 90deg,transparent 0) right center / .45rem .45rem no-repeat}
body.casepage .engage .eg-lbl{font-family:var(--dsp) !important;font-size:.64rem !important;
  font-weight:700 !important;letter-spacing:.1em !important;text-transform:uppercase !important;
  line-height:1.35 !important;color:#3C4649 !important}
body.casepage .engage .eg-title{margin-top:0;font-family:var(--dsp) !important;
  font-size:1.02rem !important;font-weight:700 !important;letter-spacing:0 !important;
  text-transform:none !important;line-height:1.25 !important;color:#111418 !important}
body.casepage .engage .eg-txt{margin-top:0;font-size:.86rem !important;
  line-height:1.5 !important;color:#3C4649 !important}
/* below 64rem five columns are too narrow to read, so the steps run down the
   page instead: a rail on the left with the dots on it, the connector turned
   vertical, the text beside it */
@media (max-width:64rem){
  .eg-steps{grid-template-columns:1fr;--eg-gap:1.4rem;row-gap:var(--eg-gap)}
  .eg-step{grid-row:auto;grid-template-rows:none;row-gap:.4rem;
    padding-top:0;padding-left:1.9rem}
  .eg-step::after{top:.3rem}
  .eg-step:not(:last-child)::before{top:1.35rem;left:.32rem;right:auto;
    bottom:calc(-1 * var(--eg-gap) + .2rem);width:.45rem;height:auto;
    background:
      linear-gradient(#8A9096,#8A9096) center top / 1px calc(100% - .3rem) no-repeat,
      conic-gradient(from 135deg at 50% 100%,#8A9096 90deg,transparent 0) center bottom / .45rem .45rem no-repeat}}
/* phones centre their labels, as everywhere else on the site */
@media (max-width:46rem){
  body.casepage .engage .eg-kicker{text-align:center}}
