/*
Theme Name: Stephanie-Bacon
Theme URI: https://example.com
Author: GDD
Description: Minimal custom WordPress theme
Version: 1.0
Text Domain: stephanie-bacon
*/

/* Dr. Stephanie Bacon, PhD - site stylesheet
   NOTE: url() here resolves against THIS FILE, not the page. Image paths
   are ../images/, not assets/images/. They were the latter while this CSS
   lived inline in the page, and the quote photograph silently 404d for a
   while after it was extracted.
   Extracted from the approved homepage build, 18 Aug 2026.
   Every page loads this. Page specific rules go in that page's own style block. */

/* ============================================================
   FOUNDATIONS
   Rounded page container on a taupe ground · pill nav ·
   deep blue dark sections · floating cards · big stat panels.
   Colour is taken from the logo itself, both blues plus the tan,
   sampled from the vector fills in SB_PhD - LOGO.pdf, not eyeballed.
   ============================================================ */
:root{
  --ground:#D8D1C4;
  --cream:#FBF8F2;
  --cream-2:#F2ECE1;
  --white:#FFFFFF;
  /* Both logo blues, sampled from the vector fills in SB_PhD - LOGO.pdf.
     NAVY  #14274B, the "S" and wordmark: authority, dark grounds.
     TEAL  #538A8F, the "B": the accent/companion, used for highlights,
                     gradient partner and interactive states.
     TAN   #A68C71, the "PhD" and rule.                                  */
  --navy:#14274B;        /* dark sections, primary buttons */
  --navy-2:#0E1C37;      /* pressed / hover, gradient end */
  --navy-3:#1F3254;      /* the logo's secondary navy, gradient midpoint */
  --teal:#538A8F;        /* second logo blue, accent + gradient partner */
  --teal-3:#3E6E73;      /* deepened teal for contrast on light */
  --teal-4:#356065;      /* teal shaded down far enough to carry body text */
  --teal-5:#2A4E52;      /* deepest teal, gradient end on the CTA band */
  --tint:#E3EBEC;        /* teal-derived light wash */
  --tint-2:#F1F6F6;
  --ink:#161A18;
  --ink-2:#333A36;
  --muted:#6E736E;
  --brown:#8A6A52;
  --tan:#A68C71;
  --tan-2:#C0A183;       /* tan lifted to clear AA on the navy grounds */
  --clay:#BC6B49;
  /* aliases so existing rules keep resolving */
  --deep:var(--navy);
  --deep-2:var(--navy-2);
  --deep-3:var(--navy-3);
  --line:rgba(22,26,24,.10);
  --line-2:rgba(22,26,24,.07);
  --on-dark:#F1EDE3;

  --h:"Inter Tight",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --b:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --s:"Instrument Serif",Georgia,serif;

  --pad:clamp(1.4rem,3.6vw,3.4rem);
  /* Container width, deliberately in px rather than rem so it is NOT carried
     along by the large screen root scale further down. Tying the two together
     meant the only way to widen the page was to enlarge the type, and past
     about 1900px that produced a container filling 95% of the screen with a
     headline to match. Separating them lets the type settle at a comfortable
     size while the layout keeps opening up.

     1240 is the floor, so every laptop width is exactly as it was. 82vw takes
     over above roughly 1510px, and 2000 caps it: past that the page would stop
     being a page and become a band. */
  --max:clamp(1240px, 82vw, 2000px);

  /* Two column splits.
     Nine different ratios were in use across My Work, The Research and
     Speaking for what is the same shape twice over: something short on the
     left, prose on the right. Nine ratios read as nine accidents. There are
     two now, and the difference between them carries meaning.

       --split-row  a label or a kicker beside its prose, inside a row
       --split-sec  a section's own heading beside the body of the section

     One documented exception: research.html .fig stays at .22, because that
     column holds a display numeral rather than words and a wider column just
     puts air around it. */
  --split-row:minmax(0,.34fr) minmax(0,.66fr);
  --split-sec:minmax(0,.42fr) minmax(0,.58fr);
  --sy:clamp(5rem,10vw,10rem);
  --r:1.25rem;
  --e:cubic-bezier(.22,.61,.36,1);
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0 !important;background:var(--ground) !important;color:var(--ink);
  font-family:var(--b);font-size:1rem;line-height:1.7;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}

/* Keyboard focus. There was none: 40 interactive elements and nothing at all
   marking where you were. :focus-visible rather than :focus, so it appears for
   keyboard and never flashes on a mouse click. */
:focus-visible{
  outline:2px solid var(--teal-3);
  outline-offset:3px;
  border-radius:3px;
}
/* teal disappears into the dark bands; cream reads on all of them */
.dark :focus-visible,
.quote :focus-visible{outline-color:var(--on-dark)}

/* visible only when tabbed to */
.skip{
  position:absolute;left:1rem;top:-3rem;z-index:200;
  background:var(--navy);color:var(--on-dark);
  padding:.7rem 1.1rem;border-radius:0 0 10px 10px;
  font-size:.9rem;font-weight:500;transition:top .2s var(--e);
}
.skip:focus{top:0}

.page{
  /* clip, not hidden. overflow:hidden makes this a scroll container, and a
     sticky child then sticks to THIS box, which never scrolls, so the nav
     just rode down the page. overflow:clip clips the same way (radius and
     the ripple bleed) without creating a scrollport. */
  background:var(--cream);border-radius:1.625rem; 
  margin:clamp(.5rem,1.1vw,1rem);
}
.w{max-width:var(--max);margin:0 auto;padding:0 var(--pad)}

h1,h2,h3{font-family:var(--h);font-weight:500;margin:0;letter-spacing:-.008em;line-height:1.08}
h1{font-size:clamp(2.3rem,4.4vw,3.7rem)}
h2{font-size:clamp(1.8rem,3.1vw,2.65rem);line-height:1.12}
h3{font-size:clamp(1.1rem,1.5vw,1.28rem);letter-spacing:0;line-height:1.34;font-weight:600}
p{margin:0 0 1.05rem}
.ital{font-family:var(--s);font-style:italic;font-weight:400;letter-spacing:-.004em}

.eyebrow{
  font-size:.74rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--teal-3);margin:0 0 1.3rem;
}
/* hero subhead only. Sits between the headline and the reading copy, so it
   stays a touch above body size without competing with the h1 above it. */
.lead{color:var(--muted);font-size:1rem;line-height:1.72}
.body{color:var(--muted);font-size:1.06rem;line-height:1.76}

/* Pill, but a fuller one. With the arrow gone the label has to carry the
   button on its own, so it gets the heading face, a heavier weight and more
   room around it. The hover is a small lift with a shadow tinted to the
   button's own colour, the same gesture the cards use, one tenth the size,
   and nothing that changes the text or the layout. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--h);font-size:.93rem;font-weight:600;letter-spacing:-.004em;
  padding:1.05rem 2.05rem;border-radius:999px;line-height:1;
  border:1px solid transparent;cursor:pointer;
  transition:background .32s var(--e),border-color .32s var(--e),
             transform .32s var(--e),box-shadow .32s var(--e);
}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0)}
.btn-fst{background:var(--deep);color:var(--on-dark)}
.btn-fst:hover{background:var(--deep-2);box-shadow:0 14px 26px -14px rgba(20,39,75,.6)}
.btn-line{border-color:var(--line);color:var(--ink)}
.btn-line:hover{border-color:var(--deep);box-shadow:0 14px 26px -16px rgba(20,39,75,.4)}
.btn-cream{background:var(--cream);color:var(--deep)}
.btn-cream:hover{background:var(--cream);box-shadow:0 14px 28px -14px rgba(10,18,38,.55)}
.btn-ghost{border-color:rgba(241,237,227,.34);color:var(--on-dark)}
.btn-ghost:hover{background:rgba(241,237,227,.12);border-color:rgba(241,237,227,.66)}

/* ============================ NAV ============================ */
/* Three separate navy capsules floating on the cream, not one bar: a round
   logo badge, the links, and the CTA. --navh keeps all three the same height
   so the row reads as one object with two gaps cut out of it. */
/* Sticky, so the glass has to work over every section that passes beneath
   it, cream, the navy ripple band, the teal CTA band, white cards. Light
   glass cannot: dark type dies over the dark bands. Navy-tinted glass can,
   because it only ever gets darker. Sampled against the lightest possible
   backdrop (pure white) the cream type still clears 5.14:1, and 28% of
   whatever is behind still reads through the blur. */
.nav{
  position:sticky;top:0;z-index:80;background:transparent;
  padding:clamp(.7rem,1.4vw,1.1rem) 0;--navh:3.5rem;
  --glass:rgba(255,255,255,.68);
  --glass-blur:blur(12px) saturate(150%) brightness(1.02);
  --glass-shadow:0 14px 34px -18px rgba(22,26,24,.4);
  /* dispersion: the edge splits warm and cool the way a real bevel does.
     Teal and tan rather than a literal rainbow, so it stays on palette. */
  --glass-edge:linear-gradient(115deg,
     rgba(143,186,190,.95) 0%, rgba(255,255,255,.98) 26%,
     rgba(232,216,190,.92) 52%, rgba(255,255,255,.96) 76%,
     rgba(143,186,190,.8) 100%);
}
.nav-in{
  max-width:var(--max);margin:0 auto;padding:0 var(--pad);
  display:flex;align-items:center;justify-content:center;gap:.45rem;
}

/* The 1px edge is a masked ring, not a border, because a border cannot take
   a gradient. inset 0 + padding:1px + xor mask leaves only the frame. */
.navmark::after,.pillnav::after,.nav-in > .nav-cta::after,.navtog::after{
  content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:var(--glass-edge);pointer-events:none;z-index:2;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
}

/* round badge. The <img> is a slot for the logo mark, drop the file in and
   it appears; until then the conic dot stands in. :has() retires the
   placeholder the moment a real mark is present. */
/* Logo-icon.svg became a finished lockup (white disc, monogram, double tan
   ring baked in at the site's own --tan-2) rather than a bare mark, so the
   badge no longer builds its surface in CSS: no frosted glass fill or blur,
   and no CSS-drawn ring, since the artwork now carries both. Kept: the soft
   drop shadow every nav element shares, so the badge still reads as
   floating rather than flat. */
.navmark{
  position:relative;flex:none;display:grid;place-items:center;
  width:var(--navh);height:var(--navh);border-radius:50%;overflow:hidden;
  box-shadow:var(--glass-shadow);
}
.navmark::before{
  content:"";width:24px;height:24px;border-radius:50%;
  background:conic-gradient(from 180deg,var(--navy) 0deg 180deg,var(--teal) 180deg 360deg);
}
/* Full bleed rather than 58% inset: the artwork's own ring is meant to sit at
   the badge's edge, not floating inside a second, larger ring drawn by CSS. */
.navmark img{position:absolute;inset:0;margin:auto;width:100%;height:100%;object-fit:contain}
/* The footer mark used to draw its own ring in a box-shadow, because the
   plain monogram it carried had none. The artwork supplies its own now, so
   this is just the image at its footer size. */
.fmark{position:relative}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:-1px;padding:0;border:0}
.navmark .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

/* links capsule */
.pillnav{
  display:flex;align-items:center;height:var(--navh);
  border-radius:999px;padding:0 .35rem;position:relative;
  background:var(--glass);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  box-shadow:var(--glass-shadow),inset 0 1px 0 rgba(255,255,255,.8);
}
.pillnav a{
  position:relative;padding:0 1.1rem;font-size:.87rem;line-height:1;
  color:var(--ink-2);transition:color .3s var(--e);
}
/* hairline between links, not around them */
.pillnav a + a::before{
  content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:1px;height:15px;background:rgba(22,26,24,.18);
}
.pillnav a:hover{color:var(--ink)}
.pillnav a.on{color:var(--deep);font-weight:600}

/* CTA capsule, tinted glass rather than clear, so it still reads as the
   one action in the row without breaking the material */
.nav-cta{
  display:inline-flex;align-items:center;flex:none;height:var(--navh);
  padding:0 1.7rem;border-radius:999px;
  font-size:.87rem;font-weight:600;letter-spacing:-.004em;
  position:relative;background:rgba(20,39,75,.9);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  box-shadow:var(--glass-shadow),inset 0 1px 0 rgba(255,255,255,.22);
  color:var(--on-dark);white-space:nowrap;transition:background .3s var(--e);
}
.nav-cta:hover{background:rgba(14,28,55,.97)}

/* ---- scroll collapse ----
   At the top of the page the full row shows. Once the reader moves, the
   links and the CTA fold inward and the badge is left alone in the middle.
   .nav-in is already centre-justified, so collapsing the two side capsules
   to zero width leaves the badge centred without moving it, the fold reads
   as the row closing into the logo rather than the logo sliding across.
   Hover or keyboard focus brings it back, so nothing is unreachable. */
@media (min-width:1025px){
  .pillnav,.nav-in > .nav-cta{
    overflow:hidden;max-width:46rem;
    transition:max-width .55s var(--e),opacity .3s var(--e),
               padding .55s var(--e),transform .55s var(--e);
  }
  .nav-in{transition:gap .55s var(--e)}
  .nav.collapsed:not(:hover):not(:focus-within) .nav-in{gap:0}
  .nav.collapsed:not(:hover):not(:focus-within) .pillnav,
  .nav.collapsed:not(:hover):not(:focus-within) .nav-in > .nav-cta{
    max-width:0;opacity:0;padding-left:0;padding-right:0;
    transform:scale(.92);pointer-events:none;
  }
  /* the badge is the affordance once it is alone, so give it one */
  .nav.collapsed .navmark{cursor:pointer}
  .nav.collapsed:not(:hover) .navmark{box-shadow:0 14px 30px -14px rgba(10,18,38,.7)}
}

/* No bar behind the collapsed mark.
   There was one: a full bleed frosted strip that faded in with the collapse,
   added because the badge otherwise floated loose over whatever happened to
   be under it. Removed on request. The badge is not left bare by it - it
   carries its own glass fill, blur and shadow - so on scroll it reads as a
   frosted disc over the page rather than a mark sitting on nothing. */

/* drawer-only pieces: inert on desktop, switched on by the queries below */
.drawer-cta{display:none}
.navtog{
  display:none;place-items:center;gap:5px;flex:none;
  width:var(--navh);height:25px;padding:14px 0 30px;
  border:0;border-radius:50%;position:relative;
  background:var(--glass);cursor:pointer;
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  box-shadow:var(--glass-shadow),inset 0 1px 0 rgba(255,255,255,.8);
}
.navtog span{
  display:block;width:17px;height:2px;background:var(--ink);border-radius:2px;
  transition:transform .32s var(--e),opacity .2s var(--e);
}
.nav.open .navtog span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav.open .navtog span:nth-child(2){opacity:0}
.nav.open .navtog span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ============================ HERO ============================ */
.hero{padding:clamp(2.5rem,5vw,4.5rem) 0 clamp(3.6rem,7vw,6.5rem)}
/* Weighted to the copy, not split evenly. Measured on the real string: at
   59.2px this headline needs a 600px column to break at three lines, 540
   gives four and 480 gives five. An even split handed it 532, so it fell to
   four, and four stacked on a four-line subhead is what made this read as a
   wall. 1.34fr buys 609px, clearing the threshold with room to spare. */
.hero-g{
  display:grid;grid-template-columns:minmax(0,1.34fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
/* the column governs the measure now, so this is just a ceiling */
.hero h1{margin-bottom:1.5rem;max-width:19ch}
.hero .lead{max-width:46ch;margin-bottom:2.1rem}
.hero-btns{display:flex;flex-wrap:wrap;gap:.65rem}

/* Portraits: real photo when present, gradient placeholder until then.
   The <img> removes itself on error, revealing the placeholder beneath. */
.ph{position:relative;overflow:hidden}
.ph > img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;z-index:2;
}
/* Each portrait file is already cut to the exact ratio of the box it sits
   in (hero .84, the two framed ones .78), so object-fit has nothing left to
   crop and the framing is baked into the file, not guessed here. Centre is
   correct for all three; only change these if a photo is swapped for one
   that is not pre-cropped. */
.ph-hero  > img,
.ph-about > img,
.ph-cta   > img{object-position:50% 50%}

/* photo + floating card */
.shot{position:relative}
.shot-img{
  width:100%;aspect-ratio:.84;border-radius:var(--r);overflow:hidden;
  background-image:
    radial-gradient(120% 85% at 30% 8%,rgba(255,255,255,.4) 0%,rgba(255,255,255,0) 58%),
    linear-gradient(168deg,#CFBBA0 0%,#C2BAA6 34%,#A9BDB1 68%,#94B4BB 100%);
  background-size:auto,190% 190%;background-position:0 0,50% 36%;
  display:grid;place-items:center;
  animation:drift 22s ease-in-out infinite alternate;
}
@keyframes drift{to{background-position:0 0,50% 64%}}
.shot-img b{font-size:.58rem;font-weight:600;letter-spacing:.32em;color:rgba(255,255,255,.66)}

/* ============================ LOGOS ============================ */
.logos{border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2)}
.logos-in{
  max-width:var(--max);margin:0 auto;padding:0 var(--pad);
  display:grid;grid-template-columns:auto repeat(3,1fr);
}
.logos-in span{
  padding:1.5rem clamp(.6rem,1.6vw,1.4rem);text-align:center;
  font-family:var(--h);font-weight:500;font-size:clamp(.85rem,1.15vw,1rem);
  letter-spacing:-.012em;color:var(--ink-2);line-height:1.35;
  display:flex;align-items:center;justify-content:center;
}
/* Locked to two lines' worth of height. The names are different lengths and
   some wrap, so without this the whole strip would jump every time one
   flipped in. */
.lslot{min-height:calc(2 * 1.35em + 3rem);perspective:420px}
.lslot b{
  display:block;font-weight:inherit;backface-visibility:hidden;
  transition:transform .48s var(--e),opacity .48s var(--e);
}
/* held edge-on while the text is swapped, then rotated back */
.lslot b.out{transform:rotateX(90deg);opacity:0}
.logos-in span + span{border-left:1px solid var(--line-2)}
/* label lives in the strip as its own cell */
.logos-in .lbl{
  font-family:var(--b);font-weight:600;font-size:.72rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--muted);
  padding-right:clamp(1rem,2.4vw,2rem);white-space:nowrap;
}

/* ============================ RIPPLE (dark) ============================ */
/* The two logo blues are never blended together. Each owns its own part of
   the page: NAVY holds the ripple section, the clarity tile and the primary
   buttons; TEAL holds the closing CTA band and every accent on a light ground
   (eyebrows, tier numbers, link hovers). Within a section the gradient only
   ever shades its own blue, navy shades to navy, teal to teal. The one place
   they meet is the logo dot, and there they sit as two hard halves, the way
   the monogram itself does. */
.dark{
  background:var(--deep);
  background:linear-gradient(155deg,var(--navy-3) 0%,var(--navy) 55%,var(--navy-2) 100%);
  color:var(--on-dark);
  --glow:rgba(166,140,113,.14);   /* tan halo, the accent navy pairs with */
}
/* The diagram is anchored to the SECTION, not to the 1240px container, and
   its centre sits exactly on the section's right edge, so the right half
   falls outside and .ripple's overflow:hidden cuts it. --stageW drives both
   the circle and the section's min-height, because a circle centred on the
   mid-line needs at least its own diameter of room or it clips top and
   bottom too and stops reading as concentric. */
.ripple{
  padding:var(--sy) 0;position:relative;overflow:hidden;
  /* 90vw wide, half of it past the edge, so the visible arc is 45vw, which
     holds at ~46% of the section at every desktop width because both scale
     with the viewport. A px cap would break that on wide screens. */
  --stageW:90vw;
  min-height:clamp(560px,86vh,980px);
  display:flex;align-items:center;
}
.ripple-g{
  display:grid;grid-template-columns:minmax(0,1fr);
  align-items:center;width:100%;
}
/* copy stays clear of the rings and sits above them */
.ripple > .w{position:relative;z-index:2}
.ripple-g > div{max-width:33rem}
.ripple .eyebrow{color:var(--tan-2)}
.ripple h2{color:var(--on-dark);max-width:15ch;margin-bottom:1.8rem}
.ripple-note{
  font-family:var(--s);font-size:clamp(1.15rem,1.85vw,1.48rem);line-height:1.42;
  color:var(--on-dark);max-width:26ch;margin:0;
  padding-top:1.7rem;border-top:1px solid rgba(241,237,227,.17);
}
.ripple-note em{font-style:italic;color:var(--tan-2)}

.stage{
  position:absolute;top:50%;right:0;transform:translate(50%,-50%);
  width:var(--stageW);max-width:none;margin:0;z-index:1;pointer-events:none;
}
.stage::before{
  content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:150%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(166,140,113,.22) 0%,rgba(166,140,113,.06) 44%,rgba(20,39,75,0) 70%);
}
.stage svg{position:relative;width:100%;height:auto;display:block;overflow:hidden}
/* rings gain weight toward the centre, depth, and emphasis on the
   leader where the copy puts it. Gradient stroke gives them a light
   direction; no rotation, no drift. */
.ring{
  fill:none;stroke:url(#ringGrad);stroke-width:1.1;
  stroke-dasharray:var(--c);stroke-dashoffset:var(--c);
}
.r3{opacity:.42}
.r2{opacity:.56}
.r1{opacity:.76}
.stage.on .ring{animation:draw 1.8s var(--e) forwards}
.stage.on .r1{animation-delay:.05s}
.stage.on .r2{animation-delay:.3s}
.stage.on .r3{animation-delay:.55s}
@keyframes draw{to{stroke-dashoffset:0}}

/* labels sit in the open space inside each ring, so they need no
   stroke mask, the old paint-order trick left chunky blobs */
/* Labels sit OUTSIDE their arc, in the open space to its left, right-aligned
   so each one runs up to its own leader line. Nothing is trapped between two
   hairlines, which is what made the in-band versions feel crowded, the bands
   are only 80 units wide and the labels needed most of that.
   `left` is the label's RIGHT edge as a % of the stage box, taken straight off
   the viewBox (x/600, y/600), 3 units clear of where each leader line starts. */
.rlabel{
  position:absolute;transform:translate(-100%,-50%);white-space:nowrap;
  font-family:var(--b);font-size:.66rem;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:#E8D8BE;
}
.l3{left:10%;    top:31.7%}   /* points at the system ring */
.l2{left:20.3%;  top:41.7%}   /* the team ring */
.l1{left:32.8%;  top:53.3%}   /* the leader ring */
.rlead{stroke:#E8D8BE;stroke-width:1;stroke-opacity:.45}
/* each leader line arrives with the label it belongs to */
.stage.arm .rlabel,.stage.arm .rlead{opacity:0}
.stage.arm.on .rlabel,.stage.arm.on .rlead{animation:fade 1s var(--e) forwards}
.stage.on .l1,.stage.on .ld1{animation-delay:.8s}
.stage.on .l2,.stage.on .ld2{animation-delay:1s}
.stage.on .l3,.stage.on .ld3{animation-delay:1.2s}
@keyframes fade{to{opacity:1}}

.seed{fill:#F5E9D5}
.seed-halo{fill:#F5E9D5;opacity:.14}
/* the origin brightens each time a wave launches */
.stage.on .seed{animation:beat 3s var(--e) infinite}
@keyframes beat{0%{opacity:1}30%{opacity:.55}100%{opacity:.55}}

/* three waves travelling leader → team → system, each dying just as
   it reaches the system ring. 9s cycle, 3s stagger, a breath, not
   an effect. vector-effect keeps the stroke hairline as it scales. */
/* three waves travelling leader → team → system, each dying just as
   it reaches the system ring. 9s cycle, 3s stagger, a breath. */
.pulse{fill:none;stroke:#C0A183;stroke-width:1.2;transform-origin:300px 300px;opacity:0}
.stage.on .pulse{animation:out 9s var(--e) infinite}
.stage.on .p2{animation-delay:3s}
.stage.on .p3{animation-delay:6s}
@keyframes out{
  0%{transform:scale(1);opacity:0}
  12%{opacity:.55}
  72%{opacity:.16}
  100%{transform:scale(2.78);opacity:0}
}

/* ============================ ABOUT ============================ */
.about{padding:0 0 var(--sy)}
.about{padding:var(--sy) 0}
.about-g{
  display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
/* framed portrait */
.frame{background:var(--cream);padding:12px;border-radius:6px;box-shadow:0 20px 44px -28px rgba(22,26,24,.32)}
.frame .im{
  aspect-ratio:.78;border-radius:3px;display:grid;place-items:center;
  background:linear-gradient(168deg,#C8B49A 0%,#AFB6AB 52%,#98AEB4 100%);
}
.frame b{font-size:.56rem;font-weight:600;letter-spacing:.3em;color:rgba(255,255,255,.6)}
.about h2{margin-bottom:1.5rem;max-width:19ch}
.about .body{max-width:56ch}
.about .body strong{color:var(--ink);font-weight:600}
.sig{font-family:var(--s);font-style:italic;font-size:1.22rem;color:var(--brown);margin:1.7rem 0 0}

/* ============================ STAT PANEL ============================ */
/* Full navy band. Breaks roughly 3100px of unbroken cream between the ripple
   and the quote, and gives the evidence the weight it was missing. The panel
   inside stays flat white by request, which now reads as a card on navy. */
/* Asymmetric on purpose. Full breathing room above, because a heading
   follows it. Half below, because the section ends on a card and a full
   stop of empty navy under it reads as a gap rather than as space. */
.stats{padding:var(--sy) 0 calc(var(--sy) * .5)}
.stats h2{color:var(--on-dark);max-width:20ch}
.stats .eyebrow{color:var(--tan-2)}
.stats-head{
  display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;
  gap:1.2rem;margin-bottom:clamp(1.6rem,3vw,2.4rem);
}
.stats-head h2{max-width:20ch}
/* Centred variant. The wrapper div went so .headmid can reach the eyebrow
   and the heading as direct children, which means the flex row has to stand
   down here. Wider cap than the left-aligned version: a 20ch measure that
   was balanced against a button on the right looks pinched with nothing
   beside it. */
.stats-head.headmid{display:block;margin-inline:auto}
.stats-head.headmid h2{max-width:26ch}
/* flat white, the panel is set off by its border and radius, not a wash */
.panel{
  background:var(--cream);
  border:1px solid rgba(18,58,79,.07);
  border-radius:var(--r);padding:clamp(1.8rem,3vw,2.8rem);
}
.panel-g{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(1.2rem,2.4vw,2.2rem)}
.sv{position:relative;padding-left:clamp(1.2rem,2.4vw,2.2rem)}
.sv:first-child{padding-left:0}
.sv + .sv::before{
  content:"";position:absolute;left:0;top:.2rem;bottom:.2rem;width:1px;
  background:rgba(18,58,79,.16);
}
.sv .n{
  font-family:var(--h);font-weight:600;letter-spacing:-.038em;
  font-size:clamp(2.1rem,3.4vw,2.85rem);line-height:1;color:var(--deep);
  margin-bottom:.7rem;font-variant-numeric:tabular-nums;
}
.sv p{color:#4B5A63;font-size:.95rem;line-height:1.62;margin:0 0 .9rem}
.sv cite{
  font-style:normal;font-size:.7rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:rgba(75,90,99,.72);
}

/* ============================ IS / IS NOT ============================ */
/* Full top padding, unlike its cream neighbours. Those sit directly under the
   previous section and share its bottom gap. This one now follows the navy
   band, and spacing cannot be borrowed across a colour change: the band ends,
   so this section has to open its own. */
.clarity{padding:var(--sy) 0}
.clarity h2{margin-bottom:clamp(1.8rem,3.4vw,2.6rem);max-width:18ch}
.cl-g{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(.7rem,1.2vw,1rem)}
.cl{border-radius:var(--r);padding:clamp(1.7rem,2.6vw,2.2rem);display:flex;flex-direction:column;gap:.9rem}
.cl .mk{
  width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  font-size:.78rem;line-height:1;
}
.cl-yes{
  background:linear-gradient(152deg,var(--navy-3) 0%,var(--navy) 55%,var(--navy-2) 100%);
  color:var(--on-dark);
}
.cl-yes h3{color:var(--on-dark)}
.cl-yes p{color:rgba(241,237,227,.76);margin:0;font-size:1rem;line-height:1.72}
.cl-yes .mk{background:rgba(241,237,227,.15);color:var(--on-dark)}
.cl-no{background:var(--cream);border:1px solid var(--line)}
.cl-no h3{color:var(--muted);font-weight:500}
.cl-no p{color:var(--muted);margin:0;font-size:1rem;line-height:1.72}
.cl-no .mk{background:var(--cream);color:var(--muted)}

/* ============================ QUOTE ============================ */
/* A full-bleed photograph rather than a wash. This is the one on the river,
   which is the ripple metaphor as an actual place, not a texture standing in
   for it. Note the earlier note about not banding this section still holds,
   what she objected to was two near-identical creams reading as a mistake. A
   photograph is unmistakably deliberate, which is a different thing. */
.quote{
  background:var(--navy);padding:clamp(5.4rem,9.5vw,9.5rem) 0;text-align:center;
  position:relative;overflow:hidden;color:var(--on-dark);
}
.quote::before{
  content:"";position:absolute;inset:0;
  background:url("https://stephaniebaconphd.com/wp-content/uploads/2026/09/quote-bg.jpg") center 42%/cover no-repeat;
}
/* The scrim is set by the photo's brightest pixel, not by eye, her white top
   and the water highlights run to (246,246,244). Sampled every pixel against
   the gradient: at .80 the worst case lands on (65,80,109), where the cream
   quote clears 6.9:1. Lighter than .80 and the attribution stops clearing. */
.quote::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,
    rgba(20,39,75,.86) 0%,rgba(20,39,75,.80) 45%,rgba(20,39,75,.90) 100%);
}
.quote > .w{position:relative;z-index:1}
.quote blockquote{
  /* 36ch measured to break 8/8/9 words, 34ch orphans "dysregulation."
     onto its own line, 46ch does the same. Re-measure if the copy changes. */
  margin:0 auto;max-width:36ch;font-family:var(--s);
  font-size:clamp(1.45rem,3vw,2.3rem);line-height:1.32;letter-spacing:-.008em;
}
/* The marker still lands on the line that carries the point. The heading
   version of .hl is inline-block, which would stop the phrase breaking and
   reflow the tuned 8/8/9 measure, so in here it is a background wash, which
   wraps safely. Held at .30: any denser and it lifts the ground enough that
   the cream loses AA against its own highlight. */
.quote .hl{
  display:inline;z-index:auto;
  background-image:linear-gradient(to top,rgba(192,161,131,.30) .34em,transparent .34em);
  background-repeat:no-repeat;background-size:100% 100%;
}
.quote .hl::after{display:none}
/* #E8D8BE, not --tan-2. The logo tan only reaches 3.3:1 over the bright water
   even at a .88 scrim, so it can never carry small caps here. This is the same
   warm light the ripple diagram's labels use, and it clears at 5.76:1. */
.quote .by{
  margin:1.6rem 0 0;font-size:.72rem;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:#E8D8BE;
}

/* Under the attribution, for the reader whose sector is not the one in the
   quote. Sentence case and lighter than .by so it reads as context rather
   than a second attribution. */
.quote .quote-sect{
  margin:.75rem auto 0;max-width:46ch;
  font-size:.92rem;line-height:1.65;color:rgba(241,237,227,.82);
}

/* ============================ SERVICES ============================ */
.svcs{padding:var(--sy) 0}
/* Was a flex row with the heading left and a button pushed to the right.
   The button now sits under the four cards, so this is a plain centred block
   like the other section heads. */
.svcs-head{
  text-align:center;margin:0 auto clamp(1.8rem,3.4vw,2.6rem);
}
.svcs-head h2{max-width:24ch;margin-inline:auto}
.svcs-foot{
  display:flex;justify-content:center;
  margin-top:clamp(1.6rem,3vw,2.4rem);
}
.svcs-g{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(.7rem,1.2vw,1rem)}
.svc{
  background:var(--cream);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(1.7rem,2.5vw,2.2rem);display:flex;flex-direction:column;
  transition:transform .38s var(--e),box-shadow .38s var(--e);
}
.svc:hover{transform:translateY(-4px);box-shadow:0 22px 44px -26px rgba(22,26,24,.26)}
.svc .no{
  font-family:var(--h);font-weight:600;font-size:.78rem;letter-spacing:.1em;
  color:var(--teal-3);margin-bottom:1.4rem;
}
.svc h3{margin-bottom:.65rem}
.svc > p{color:var(--muted);font-size:1rem;line-height:1.72;margin-bottom:1.3rem}
.svc .best{
  margin-top:auto;padding-top:1rem;border-top:1px solid var(--line-2);
  color:var(--muted);font-size:.9rem;line-height:1.6;
}
.svc .go{
  display:inline-flex;align-items:center;gap:.45rem;margin-top:1rem;
  font-size:.9rem;font-weight:500;color:var(--teal-3);transition:gap .3s var(--e);
}
.svc:hover .go{text-decoration:underline;text-underline-offset:3px}

/* ============================ SHARED: image cards ============================ */
/* warm highlight behind a key word, hand-marked, not corporate */
/* The emphasis line under a phrase in a heading. It was a marker pen block
   behind the words, which works on cream and turns to a grey smudge on any
   coloured ground. As a rule underneath it reads the same everywhere, which
   is what makes it usable as the site's H2 accent rather than a homepage
   flourish. */
.hl{position:relative;display:inline-block;z-index:0}
.hl::after{
  content:"";position:absolute;left:0;right:0;bottom:-.04em;height:.1em;
  background:var(--tan);opacity:.9;border-radius:2px;z-index:-1;
}
/* on the dark grounds the tan has to lift to stay visible */
.dark .hl::after{background:var(--tan-2);opacity:.95}
.g-a{background:linear-gradient(160deg,#B9C9D4 0%,#8FA9B8 55%,#6E8C9E 100%)}
.g-b{background:linear-gradient(160deg,#D3C3AC 0%,#B8A188 60%,#9A8268 100%)}


/* ============================ HERO SUBHEAD AND CLAIM ============================
   Her reviewed hero is four blocks, not two: headline, an italic positioning
   line, the reading copy, then the claim it all pays off. The italic line uses
   the serif the headline's own emphasis uses, so it reads as part of the
   headline's voice rather than as a second paragraph. */
.hero-sub{
  font-family:var(--s);font-style:italic;font-size:clamp(1.08rem,1.6vw,1.3rem);
  line-height:1.5;color:var(--teal-4);margin:0 0 1.1rem;max-width:44ch;
}
.hero-claim{
  font-family:var(--h);font-weight:500;font-size:clamp(1.02rem,1.3vw,1.12rem);
  line-height:1.6;color:var(--ink);margin:0 0 2.1rem;max-width:46ch;
}
/* The lead loses its own bottom margin here: the claim below it now carries
   the gap down to the buttons. */
.hero .lead{margin-bottom:1.1rem}

/* ============================ WHO THIS IS FOR ============================
   Three entry points, each named by the cost it is already charging. Text
   cards rather than image cards: there is no photograph that says "the thing
   nobody said in the meeting", and a decorative one would be filler. */
.funnel{padding:var(--sy) 0}
.funnel-head{margin-bottom:clamp(2rem,4vw,3rem)}
.funnel-head h2{max-width:24ch}
.funnel-head .sec-p{max-width:68ch;margin-top:1rem;color:var(--muted);line-height:1.75}
.funnel-g{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(.9rem,1.6vw,1.3rem)}
.fcard{
  display:flex;flex-direction:column;
  background:var(--cream);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(1.5rem,2.4vw,2.1rem);
  transition:transform .38s var(--e),box-shadow .38s var(--e);
}
.fcard:hover{transform:translateY(-5px);box-shadow:0 24px 46px -26px rgba(18,58,79,.3)}
.fno{
  font-family:var(--b);font-size:.66rem;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--teal-3);margin:0 0 .9rem;
}
.fcard h3{
  font-size:clamp(1.18rem,1.7vw,1.38rem);line-height:1.2;
  color:var(--navy);margin:0 0 .9rem;
}
.fcard p{color:var(--muted);font-size:.99rem;line-height:1.72;margin:0 0 1rem}
/* The link sits on the bottom edge whatever the card above it does, so the
   three read as a row rather than three different heights of paragraph. */
.fcard .go{
  margin-top:auto;display:inline-flex;align-items:center;gap:.45rem;
  font-size:.9rem;font-weight:500;color:var(--deep);transition:gap .3s var(--e);
}
.fcard .go::after{content:"\2192"}
.fcard:hover .go{gap:.8rem}

/* ============================ RESULTS ============================
   Four participant figures. Not the .panel treatment the research stats use:
   that panel is a cream card carrying cited third party research, and these
   are her own unsourced numbers, so they are set as plain figures on the
   ground rather than borrowed authority. */
.results{padding:var(--sy) 0}
.results-g{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(1.4rem,2.6vw,2.4rem);margin-top:clamp(2rem,4vw,3rem);
}
.rfig .n{
  font-family:var(--h);font-weight:600;letter-spacing:-.038em;
  font-size:clamp(2.4rem,4.4vw,3.4rem);line-height:1;color:var(--tan-2);
  margin-bottom:.7rem;font-variant-numeric:tabular-nums;
}
.rfig p{color:rgba(241,237,227,.84);font-size:.98rem;line-height:1.62;margin:0}

@media (max-width:980px){
  .funnel-g{grid-template-columns:minmax(0,1fr)}
  .results-g{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:620px){
  .results-g{grid-template-columns:minmax(0,1fr)}
}

/* ============================ VIDEO ============================ */
/* Its own top padding, because the section above it is now a colour.
   A section can only borrow the gap above it while its neighbour shares its
   background: the moment that neighbour becomes a band, the space sits inside
   the band and this section starts hard against the edge. */
.vid{padding:var(--sy) 0}
.vid-head{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:.9rem;margin:0 auto clamp(1.6rem,3vw,2.3rem);max-width:none;
}
.vid-head h2{max-width:26ch}
.vid-head p{color:var(--muted);max-width:68ch;margin:0;font-size:1rem;line-height:1.7}
.player{
  position:relative;border-radius:var(--r);overflow:hidden;aspect-ratio:2/1;
  /* cursor stays default while this is a still, not a control */
  background:linear-gradient(150deg,#9FB4C0 0%,#77939F 50%,#4E6E7E 100%);
}
.player > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:1}
.player::after{
  content:"";position:absolute;inset:0;z-index:2;
  background:linear-gradient(180deg,rgba(13,44,61,.12) 0%,rgba(13,44,61,.55) 100%);
}
.play{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;
  width:78px;height:78px;border-radius:50%;background:rgba(255,255,255,.94);
  display:grid;place-items:center;
  box-shadow:0 12px 34px -10px rgba(13,44,61,.5);
  transition:transform .35s var(--e),background .35s var(--e);
  opacity:0.7;
}
.player:hover .play{transform:translate(-50%,-50%) scale(1.07);background:#fff}
.play::before{
  content:"";width:0;height:0;margin-left:5px;
  border-left:19px solid var(--deep);
  border-top:12px solid transparent;border-bottom:12px solid transparent;
}
.vid-cap{
  position:absolute;left:0;right:0;bottom:0;z-index:3;
  padding:clamp(1.2rem,2.4vw,2rem);color:#fff;
}
.vid-cap strong{display:block;font-family:var(--h);font-weight:600;font-size:1.1rem;letter-spacing:-.01em}
.vid-cap span{font-size:.9rem;color:rgba(255,255,255,.78)}

/* ============================ FREE RESOURCES ============================ */
.res{padding:0 0 var(--sy)}


.res-head{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:.9rem;margin:0 auto clamp(1.6rem,3vw,2.3rem);max-width:none;
}
.res-head h2{max-width:26ch}
.res-head p{color:var(--muted);max-width:68ch;margin:0;font-size:1rem;line-height:1.7}
/* Two resources now, not three, so two equal .rfeat cards rather than one
   lead and a stack of supporting ones. .res-side is gone with the card it
   used to wrap; nothing left to stack. */
.g-c{background:linear-gradient(160deg,#A7BCC7 0%,#7C99A9 55%,#4E7188 100%)}
.res-g{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1rem,1.8vw,1.5rem);align-items:stretch;
}
/* Three cards in this row now, matching the three funnels. Below .res-g, not
   above it: same specificity, so source order is the only thing deciding it,
   and placed first this lost to the two column rule it exists to override. */
/* Two books across the top at half width each, the audit spanning the full
   row beneath them. The audit is the odd one out on purpose: it is the only
   resource with no cover artwork, so as an equal third it was a blank
   gradient panel pretending to be a book. Given the whole row it becomes a
   banner instead, which is a shape that does not need artwork. */
.res-g3{grid-template-columns:repeat(2,minmax(0,1fr))}
.res-g3 .rcard-wide{grid-column:1/-1}
@media (max-width:980px){.res-g3{grid-template-columns:minmax(0,1fr)}}

/* All three keep the stock side-by-side card. The stacked version this
   replaced existed only to rescue the text at three across, where each card
   was 363px and the copy broke to one word a line. At half width there is
   room for both again, so the exception is no longer earning anything. */
.res-g3 .rbody{display:flex;flex-direction:column;height:100%}
.res-g3 .rcta{margin-top:auto}

/* The banner's block is squarer and larger than a book cover slot, because
   it is a ground rather than artwork and a portrait sliver of flat gradient
   reads as a missing image. */
.res-g3 .rcard-wide .cover{
  width:clamp(150px,20vw,240px);aspect-ratio:1;align-self:center;
}
.res-g3 .rcard-wide .rbody > p{max-width:62ch}
/* Image stage on top, padded copy below, CTA pinned to the bottom edge. The
   covers are real designed artwork now rather than 240x360 placeholders, so
   they lead the card instead of sitting in a 102px slot beside the text. */
/* Small and centred, not a hero image. The first version filled the whole
   card width with a *contained* cover, so a portrait image only occupied a
   narrow strip in the middle and the g-a / g-b tint filled the rest as a
   thick colour gutter on both sides, which read as an oversized card with a
   picture frame rather than a subtle one. A fixed, modest thumbnail with
   object-fit:cover removes the gutter outright, since there is no leftover
   space for a tint to fill. */
/* Horizontal again, cover on the right. The markup still puts .cover before
   .rbody (it was written for the original left-cover layout and nothing
   about the image being real artwork now depends on its position), so the
   mirror is done with order rather than touching eight pages' worth of
   markup: order actually works this cleanly here because it is plain
   two-column auto-placement, no explicit grid-column lines to fight. */
.rcard{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(1.1rem,2vw,1.6rem);align-items:stretch;
  background:var(--cream);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(1.4rem,2.2vw,1.9rem);
  transition:transform .3s var(--e),box-shadow .3s var(--e);
}
.rcard:hover{transform:translateY(-3px);box-shadow:0 18px 34px -22px rgba(20,39,75,.26)}
/* .75 matches both covers closely (.773 and .783), so cover crops each by
   about 3-4% rather than force-fitting the old .667 placeholder ratio. */
.rcard .cover{
  order:2;align-self:center;position:relative;overflow:hidden;flex:none;
  width:clamp(112px,13vw,164px);aspect-ratio:.75;border-radius:8px;
  box-shadow:0 10px 22px -12px rgba(20,39,75,.5);
}
.rcard .cover img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
}
/* order:1 alongside the cover's order:2 is what actually moves it to the
   right; stretch (the grid default, inherited from .rcard) is what lets the
   CTA below pin to the card's own bottom edge rather than the text's. */
.rbody{order:1;min-width:0;display:flex;flex-direction:column}

/* ---- typography, unchanged from the lead card it used to be ---- */
.rfeat h3{font-size:clamp(1.15rem,1.6vw,1.35rem);margin:0 0 .5rem}
.rfeat p{font-size:.96rem;line-height:1.62;margin:0 0 1.3rem;max-width:40ch}
/* margin-top:auto pins the button to the bottom of the card, so both read
   along one line however long the copy above them runs. */
.rcta{margin-top:auto;align-self:flex-start;font-size:.84rem;padding:.72rem 1.3rem}
.rfeat:hover .rcta{background:var(--deep-2)}
.rkind{
  display:block;font-size:.68rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--teal-3);margin:0 0 .5rem;
}
.rcard h3{font-size:1.12rem;margin:0 0 .45rem}
.rcard p{color:var(--muted);font-size:.95rem;line-height:1.62;margin:0 0 .8rem}

/* ============================ VOICES ============================ */
/* Plain on purpose. The pull-quote band earlier already gives the page its
   one big testimonial moment; this section's job is volume, not a second
   feature. Three voices, one alignment, no boxes and no rules - the space
   between the columns does the separating. */
/* Its own top padding, because the section above it is now a colour.
   A section can only borrow the gap above it while its neighbour shares its
   background: the moment that neighbour becomes a band, the space sits inside
   the band and this section starts hard against the edge. */
.voices{padding:var(--sy) 0}
.voices h2{max-width:16ch;margin-bottom:clamp(2.2rem,4.5vw,3.4rem)}
/* Set as an editorial quote wall rather than three more cards. The card
   pattern already carries paths, services and resources; a fourth run of it
   here is what makes the middle of the page read as one template. No boxes,
   no fills - the words sit on the page and hairlines do the dividing. The
   aqua wash that was on the middle card is gone with it. */
/* One voice at a time, with the three names as an index beside it. The
   quotes cross-fade on a slow timer and the index marks who is speaking.
   .rot is added by JS, so with no script (or reduced motion) this degrades
   to all three simply stacked and readable - nothing is hidden behind an
   animation that might never run. */
.vc{background:none;border:0;border-radius:0;padding:0;margin:0}
.vc + .vc{margin-top:clamp(1.6rem,3vw,2.1rem);padding-top:clamp(1.6rem,3vw,2.1rem);border-top:1px solid var(--line)}
.vc .st{color:var(--tan);letter-spacing:.22em;font-size:.86rem;margin-bottom:1.1rem}
.vc p{
  font-family:var(--s);font-size:clamp(1.35rem,2.15vw,1.95rem);line-height:1.36;
  letter-spacing:-.006em;color:var(--ink);margin:0 0 1.2rem;
}
.vc .who{
  font-size:.7rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);
}

/* --- enhanced: rotator --- */
.v-wrap.rot{
  display:grid;grid-template-columns:minmax(0,1.28fr) minmax(0,.72fr);
  gap:clamp(2.4rem,5.5vw,5rem);align-items:start;
}
.rot .v-g{display:grid}
/* :not(.on) rather than a bare .vc so this cannot lose a specificity fight
   with the reveal system, which also animates opacity on nested elements. */
.v-wrap.rot .vc:not(.on){
  grid-area:1/1;margin:0;padding:0;border:0;
  opacity:0;transform:translateY(12px);pointer-events:none;
  transition:opacity .7s var(--e),transform .7s var(--e);
}
.v-wrap.rot .vc.on{
  grid-area:1/1;margin:0;padding:0;border:0;
  opacity:1;transform:none;pointer-events:auto;
  transition:opacity .7s var(--e),transform .7s var(--e);
}

.v-idx{list-style:none;margin:0;padding:0}
.v-idx button{
  position:relative;display:block;width:100%;text-align:left;cursor:pointer;
  background:none;border:0;border-top:1px solid var(--line);
  padding:.95rem 0 .95rem 1.3rem;
  font-family:var(--b);font-size:.92rem;color:var(--muted);
  transition:color .35s var(--e),padding-left .35s var(--e);
}
.v-idx li:last-child button{border-bottom:1px solid var(--line)}
.v-idx button::before{
  content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:0;height:1px;background:var(--tan);transition:width .45s var(--e);
}
.v-idx button:hover{color:var(--ink)}
.v-idx button[aria-current="true"]{color:var(--ink);font-weight:500}
.v-idx button[aria-current="true"]::before{width:.8rem}
.v-idx .role{display:block;font-size:.72rem;color:var(--muted);margin-top:.15rem}

/* ============================ CTA (dark, framed portrait) ============================ */
/* The closing band is the one place TEAL owns the ground. Shaded to
   --teal-4/-5 so body copy clears AA; the logo teal itself is too light
   to carry text. No navy in here, that blue has the ripple section. */
.cta{padding:var(--sy) 0}
.cta.dark{
  background:var(--teal-4);
  background:linear-gradient(152deg,var(--teal-4) 0%,var(--teal-5) 100%);
  --glow:rgba(143,186,190,.16);
}
/* A section head lifted out of a two column grid.
   Same job as .cta-head below, for the content sections rather than the
   closing panels: About, the story, the credentials and the workshops all
   paired a heading with content beside it, so the heading centred on its own
   column. The head is a full width block above the grid now.

   margin-inline on the h2 as well as text-align, because several of these
   sections set their own h2 with a `margin` shorthand and a narrow ch cap,
   and a shorthand wipes the auto side margins - which leaves the box pinned
   left with only its text centred inside it. */
.sec-head{text-align:center;margin-bottom:20px;}
.sec-head h2{max-width:26ch;margin:.55rem auto 0}
/* A lead under a centred heading. Page level .sec-p sets a 60ch cap and
   zero side margins for the left aligned case, and loads after this sheet,
   so this needs the extra class to win rather than !important. */
.sec-head .sec-p{max-width:62ch;margin:1rem auto 0}
.dark .sec-head h2{color:var(--on-dark)}
.dark.teal .sec-head .eyebrow{color:var(--cream)}
.dark:not(.teal) .sec-head .eyebrow{color:var(--tan-2)}
/* the sections' own narrow caps have to stand down for the centred head */
.about .sec-head h2,.story .sec-head h2,
.creds .sec-head h2,.shops .sec-head h2{max-width:26ch;margin-inline:auto}

/* The closing panels' head, lifted out of the text column.
   All seven pages end on a two column panel and the heading used to live in
   whichever column held the copy, so it centred on half the page. It sits
   above the grid now, so it centres on the page like every other section
   heading, and the lead and the buttons stay where they were. */
.cta-head{text-align:center;margin-bottom:clamp(1.8rem,3.4vw,2.6rem)}
.cta-head h2{color:var(--on-dark);max-width:24ch;margin:.55rem auto 0}
.cta-head .eyebrow{color:var(--cream)}
/* The panels set their own h2 rules for a narrow column, and two things in
   them fight the centred head: a 13ch to 15ch max-width, and in one case a
   full `margin` shorthand that wipes the auto side margins and leaves the
   box pinned left with only its text centred inside. Both are answered here
   with a selector specific enough to win wherever the panel's own rule sits
   in the cascade. */
.cta .cta-head h2,.close .cta-head h2{max-width:24ch;margin-inline:auto}

.cta-g{
  display:grid;grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.cta .frame{background:var(--on-dark)}
/* the cream button sits inside teal's band, so it reads teal, not navy */
.cta .btn-cream{color:var(--teal-5)}
.cta .eyebrow{color:var(--cream)}
/* The text column here is 705px wide and the type was capped at 350 and 467,
   so half of the column was doing nothing. Both caps widened to sit just
   inside it: the heading now breaks into two lines rather than four, and the
   paragraph stops laddering. */
.cta h2{color:var(--on-dark);max-width:19ch;margin-bottom:1.3rem}
.cta > .w > .cta-g p.cta-p{color:rgba(241,237,227,.87);max-width:60ch;margin-bottom:1.9rem}
.cta-btns{display:flex;flex-wrap:wrap;gap:.65rem;margin-bottom:1.9rem}
.assure{display:flex;flex-wrap:wrap;gap:.6rem 1.8rem;margin:0}
.assure span{
  display:inline-flex;align-items:center;gap:.5rem;
  font-size:.9rem;color:rgba(241,237,227,.85);
}
.assure span::before{
  content:"";width:5px;height:5px;border-radius:50%;background:var(--cream);flex:none;
}

/* ============================ FOOTER ============================
   Editorial: a "next step" block on the left, ruled link lists on
   the right, and a slim identity bar underneath.                  */
.foot{padding:clamp(5rem,9.5vw,9.5rem) 0 clamp(1.8rem,3vw,2.6rem)}
/* Link columns are fixed and narrow, pinned flush right. The NEXT
   track takes the slack but .fnext is capped at its original 530px,
   so the left block does not move or grow. */
.foot-top{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,180px) minmax(0,180px);
  gap:clamp(2rem,7vw,5.75rem);align-items:start;
}

/* small ruled section label, shared by all three columns */
.fh{
  font-size:.7rem;font-weight:500;letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted);margin:0 0 .35rem;padding-bottom:.7rem;
  border-bottom:1px solid var(--line);
}

/* next step */
.fnext{
  display:grid;grid-template-columns:minmax(0,auto) minmax(0,1fr);
  gap:clamp(1.5rem,3vw,2.5rem);align-items:start;max-width:530px;
}
.fnext h2{
  font-size:clamp(1.25rem,1.9vw,1.6rem);letter-spacing:-.025em;
  margin:0 0 .6rem;white-space:nowrap;
}
.fnext p{color:var(--muted);font-size:.9rem;line-height:1.6;margin:0;max-width:28ch}
/* If a page's next-step block has no image, collapse to one column.
   Without this the grid holds an empty 1fr and the footer reads as broken. */
.fnext-img{
  position:relative;overflow:hidden;width:100%;aspect-ratio:1.5;border-radius:2px;
  background:linear-gradient(160deg,#C6D2DA 0%,#9FB4C0 55%,#7B95A4 100%);
}
.fnext-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:2}
.fnext-img b{
  position:absolute;inset:0;display:grid;place-items:center;
  font-size:.55rem;font-weight:600;letter-spacing:.26em;color:rgba(255,255,255,.7);
}
.fnext:hover .fnext-img img{transform:scale(1.04)}

/* ruled link lists */
.fcol a{
  display:flex;align-items:center;justify-content:space-between;
  padding:.58rem 0;border-bottom:1px solid var(--line);
  font-size:.95rem;line-height:1.55;color:var(--ink);
  transition:color .3s var(--e),padding-left .3s var(--e);
}
.fcol a:hover{color:var(--teal-3);padding-left:.35rem}
.fcol a::after{
  content:"↗";font-size:.75rem;opacity:0;transform:translateX(-4px);
  transition:opacity .3s var(--e),transform .3s var(--e);
}
.fcol a:hover::after{opacity:.55;transform:none}
.fcol.plain a::after{content:none}

/* identity bar */
/* The identity bar was separated from the columns above it by nothing but a
   large gap, which on a short page read as one loose block rather than two
   zones. A hairline in --line-2 rather than --line: the footer already uses
   --line for its list rules and its column labels, and this divides zones
   rather than items, so it sits one step lighter and does not compete with
   them. The old margin is split into margin above the rule and padding below
   it, so the total gap is roughly unchanged and the line has air on both
   sides instead of being pinned to the text. */
.foot-base{
  display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:.8rem 2rem;
  margin-top:clamp(3rem,6vw,5rem);
  padding-top:clamp(1.5rem,2.6vw,2.1rem);
  border-top:1px solid var(--line-2);
  font-size:.82rem;color:var(--ink);
}
/* identity lockup: the mark sits bare on the cream rather than in a badge -
   the badge in the nav only exists to hold it against the glass */
/* deliberately NOT inline-flex: an inline-flex box takes its baseline from
   its first flex item, and that is the image, which has none - so the whole
   lockup rode 10px above the tagline and copyright beside it. Left inline,
   the span keeps the text baseline and the row lines up. */
.fmark img{width:28px;height:28px;vertical-align:-.55em;margin-right:.55rem}
/* --muted only reaches 4.56:1 on cream, which is fine for 15px body copy and
   not fine for a 12px legal line. --ink-2 clears 11:1 and the size step keeps
   these subordinate to the name without making them faint. */
.foot-base .mid{color:var(--ink-2);font-size:.8rem}
.foot-base .yr{color:var(--ink-2);font-size:.8rem}

/* ============================ RESPONSIVE ============================
   The scale is already proportional: every type size, gap and section
   pad in this file is a clamp() against vw, so the page shrinks with the
   viewport on its own. What follows only does the things a proportional
   scale cannot, change column counts, collapse the nav, and relax the
   handful of fixed ratios, nowraps and ch-measures that were set for a
   two-column desktop and would otherwise overflow or strand.
   Breakpoints sit where this content actually breaks, not at device names.
   ==================================================================== */

/* --- 1180: the pill nav is the first thing to run out of room --- */
@media (max-width:1180px){
  .pillnav a{padding:.52rem .78rem;font-size:.83rem}
  .foot-top{gap:clamp(1.4rem,3.6vw,3rem)}
}

/* --- 1024: nav becomes a drawer, and 4 stats across gets too tight --- */
@media (max-width:1024px){
  .navtog{display:grid}
  .nav-in{gap:.45rem}
  /* the drawer is a fourth navy capsule dropped under the row, not a bar
     spanning the window, same language as the three above it */
  .pillnav{
    display:none;position:absolute;top:calc(100% + .45rem);
    left:var(--pad);right:var(--pad);height:auto;
    flex-direction:column;align-items:stretch;gap:.1rem;
    padding:.6rem;border-radius:1.625rem;
    background:rgba(255,255,255,.86);border:0;
    -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
    box-shadow:0 26px 44px -26px rgba(22,26,24,.45),inset 0 1px 0 rgba(255,255,255,.9);
  }
  .nav.open .pillnav{display:flex}
  .pillnav a{padding:.8rem 1.1rem;font-size:.95rem;border-radius:999px}
  /* the vertical hairline only makes sense in a row */
  .pillnav a + a::before{display:none}
  .pillnav a.on{background:rgba(20,39,75,.08)}
  /* 4 → 2. The rules between stats are drawn on the left edge of each
     cell, so they have to be re-hung on the new second column. */
  .panel-g{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:clamp(1.5rem,3vw,2.2rem)}
  .sv{padding-left:clamp(1.2rem,2.4vw,2.2rem)}
  .sv:nth-child(2n+1){padding-left:0}
  .sv + .sv::before{display:none}
  .sv:nth-child(2n)::before{display:block}
}

/* --- 880: the two-column sections stack --- */
@media (max-width:880px){
  .hero-g,.ripple-g,.about-g,.cta-g{grid-template-columns:minmax(0,1fr)}
  /* measures were cut narrow to sit beside an image; once stacked they
     strand the line unless they are let out */
  .hero h1{max-width:19ch}
  .hero .lead{max-width:54ch}
  .ripple h2{max-width:24ch}
  .ripple-note{max-width:44ch;max-inline-size:44ch}
  .about h2{max-width:26ch}
  .cta h2{max-width:20ch}
  .svcs-head h2,.res-head h2,.vid-head h2,.stats-head h2,
  .clarity h2,.voices h2{max-width:24ch}
  /* portraits keep their ratio but stop being full-bleed tall */
  .shot{max-width:430px;margin-inline:auto}
  .about-g .frame,.cta-g .frame{max-width:390px;margin-inline:auto}
  /* The bleed only works while there is room to its left. Once the column
     narrows the rings run under the headline, so below this the diagram
     goes back into the flow beneath the copy at its normal size. */
  .ripple{
    /* the labels are a fixed size now, so the circle has to be big enough
       for them: below ~340px "The Leader" spans the inner ring exactly */
    --stageW:min(92vw,460px);min-height:0;
    display:flex;flex-direction:column;align-items:stretch;
  }
  /* .stage is the first child in source (it has to be, to anchor the bleed
     against the section rather than the 1240px container) so it needs
     re-ordering once it rejoins the flow */
  .ripple > .w{order:1}
  .stage{
    order:2;position:relative;top:auto;right:auto;transform:none;
    width:var(--stageW);margin:clamp(2rem,5vw,3rem) auto 0;
  }
  .ripple-g > div{max-width:none}
  /* Whole circle is visible again and the stage is only ~345px wide, so a
     label hung off the left of an arc would run past the section edge and be
     clipped. Back to centred, where each ring is at its widest, and the
     leader lines retire, there is nothing for them to point across. */
  .rlabel{transform:translate(-50%,-50%)}
  .l3{left:50%;top:13.7%}
  .l2{left:50%;top:27%}
  .l1{left:50%;top:44.7%}
  .rlead{display:none}
  /* 3 across → 2 */
  .cl-g{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* the index needs a column of its own; below this it drops under the quote */
  .v-wrap.rot{grid-template-columns:minmax(0,1fr);gap:clamp(1.8rem,4vw,2.4rem)}
  .voices h2{max-width:22ch}
  /* lead card over the pair, rather than beside it */
  .res-g{grid-template-columns:minmax(0,1fr)}
  /* logo strip: vertical dividers can't survive a wrap, so it becomes a grid */
  .logos-in{grid-template-columns:repeat(2,minmax(0,1fr))}
  .logos-in .lbl{
    grid-column:1/-1;justify-content:flex-start;
    padding:1.2rem 0 .1rem;border-bottom:1px solid var(--line-2);
  }
  .logos-in span + span{border-left:none}
  .logos-in span:not(.lbl){padding:1.1rem clamp(.6rem,1.6vw,1.4rem)}
  .logos-in span:nth-child(2n+1):not(.lbl){border-left:1px solid var(--line-2)}
  /* footer: next-step block full width, link lists side by side beneath */
  .foot-top{grid-template-columns:repeat(2,minmax(0,1fr))}
  .foot-top > :first-child{grid-column:1/-1}
  .fnext{max-width:560px}
}

/* --- 680: single column throughout --- */
@media (max-width:680px){
  .mw100{
    width:100%;
  }
  .svcs-g,.cl-g{grid-template-columns:minmax(0,1fr)}
  .panel-g{grid-template-columns:minmax(0,1fr)}
  /* the divider turns from a left rule into a rule above */
  .sv,.sv:nth-child(2n+1){padding-left:0;padding-top:1.5rem}
  .sv:first-child{padding-top:0}
  .sv + .sv::before,.sv:nth-child(2n)::before{
    display:block;left:0;right:0;top:0;bottom:auto;width:auto;height:1px;
  }
  .logos-in{grid-template-columns:minmax(0,1fr)}
  .logos-in span:nth-child(2n+1):not(.lbl){border-left:none}
  .logos-in span:not(.lbl){border-top:1px solid var(--line-2);padding:1rem 0}
  .logos-in .lbl{border-bottom:none;padding-bottom:.3rem}
  /* a 2:1 player is a letterbox sliver on a phone */
  .player{aspect-ratio:16/10}
  .play{width:60px;height:60px}
  .play::before{border-left-width:15px;border-top-width:10px;border-bottom-width:10px}
  .foot-top{grid-template-columns:minmax(0,1fr);gap:2.4rem}
  .fnext{grid-template-columns:minmax(0,1fr);gap:1.4rem}
  .fnext h2{white-space:normal}
  .fnext-img{max-width:240px}
}

/* --- 560: the header pill moves into the drawer; phone paddings --- */
@media (max-width:560px){
  :root{--pad:1.2rem;--r:1rem}
  .page{margin:.4rem;border-radius:18px}
  .nav-in > .nav-cta{display:none}
  .drawer-cta{
    display:flex;justify-content:center;margin-top:.5rem;
    padding:.8rem 1rem;border-radius:999px;
    background:var(--deep);color:var(--on-dark);font-size:.9rem;font-weight:500;
  }
  .nav{--navh:3rem}
  /* stacked buttons read as one column rather than a ragged wrap */
  .hero-btns .btn,.cta-btns .btn{width:100%;justify-content:center}
  .quote blockquote{max-width:none}
  .stats-head,.res-head,.vid-head{align-items:flex-start}
}

/* ============================ MOTION ============================
   Opacity and transform only, nothing here can reflow the layout.
   All of it is gated behind .arm, which JS adds and then strips
   after 4s, so a blocked script leaves the page fully visible.
   ================================================================= */
.arm .rv{opacity:0;transform:translateY(26px);transition:opacity .85s var(--e),transform .85s var(--e)}
.arm .rv.in{opacity:1;transform:none}
.d1{transition-delay:.09s}.d2{transition-delay:.18s}.d3{transition-delay:.27s}

/* Images don't fade, they fill from the bottom like a waterline,
   and settle out of a slight over-scale as they arrive.
   :where() keeps specificity at 0 so hover rules below can win. */
.arm :where(.rv) img{
  transform:scale(1.06);clip-path:inset(100% 0 0 0);
  transition:transform 1.7s var(--e),clip-path 1.25s var(--e);
}
.arm :where(.rv.in) img{transform:none;clip-path:inset(0 0 0 0)}

/* Headings resolve out of focus rather than sliding up, reads as
   something coming into clarity, which is the whole pitch. */
.arm :is(h1,h2).rv{
  filter:blur(9px);transform:translateY(10px);
  transition:opacity .95s var(--e),transform .95s var(--e),filter .95s var(--e);
}
.arm :is(h1,h2).rv.in{filter:blur(0);transform:none}

/* Hairline rules draw themselves left to right */
.arm .fh{border-bottom-color:transparent;position:relative}
.arm .fh::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--line);transform:scaleX(0);transform-origin:left;
  transition:transform 1s var(--e) .15s;
}
.arm .rv.in .fh::after{transform:scaleX(1)}

/* Dark sections breathe on an 11s cycle, roughly the paced
   inhale/exhale the whole method is built on. */
.dark{position:relative}
.dark > .w{position:relative;z-index:1}
.dark::after{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(58% 48% at 50% 42%,var(--glow),transparent 70%);
  /* animation:breathe 11s ease-in-out infinite; */
}
@keyframes breathe{
  0%,100%{opacity:.3;transform:scale(1)}
  45%{opacity:.75;transform:scale(1.07)}
}

/* hover zoom on picture cards */
/* clip-path added alongside transform. This rule has real specificity, and
   the reveal system's own transition (.arm :where(.rv) img) is deliberately
   :where()-zeroed so a hover rule can win on transform. Declaring only
   transform here did not just add a hover override, it replaced the whole
   transition list for every image matching this selector, silently dropping
   clip-path from it: the reveal image starts fully clipped and is meant to
   open like a waterline, and instead it was snapping open instantly, with
   nothing revealed at all until that snap fired. Same duration the reveal
   rule uses for clip-path, so this does not fight it a second time. */
.rcard .cover img,.player img{
  transition:transform 1.5s var(--e),clip-path 1.25s var(--e);
}
/* Faster here specifically. 1.5s/1.25s reads fine on a full width hero
   image; on a 130px thumbnail the same duration just looks slow to arrive.
   .res-g qualifies the selector so this outranks the shared rule above
   without changing player, which still gets the slower pair. */
.res-g .rcard .cover img{transition:transform .5s var(--e),clip-path .45s var(--e)}
.rcard:hover .cover img{transform:scale(1.06)}
.player:hover img{transform:scale(1.03)}

/* the tan marker wipes in beneath the word */
.hl::after{transform-origin:left center}
.arm .hl::after{transform:scaleX(0);transition:transform .75s var(--e) .32s}
.arm .rv.in .hl::after{transform:scaleX(1)}
/* same wipe for the quote's wash-based marker, driven off background-size */
.arm .quote .hl{background-size:0% 100%;transition:background-size .85s var(--e) .38s}
.arm .quote .rv.in .hl{background-size:100% 100%}

/* ripple photograph behind the quote drifts to rest */
.arm .quote::before{transform:scale(1.1);transition:transform 2.6s var(--e)}
.arm .quote.in::before{transform:scale(1)}

/* play button breathes one ring */
.play::after{
  content:"";position:absolute;inset:-12px;border-radius:50%;
  border:1px solid rgba(255,255,255,.5);pointer-events:none;
  animation:ppulse 3s ease-out infinite;
}
@keyframes ppulse{0%{transform:scale(.92);opacity:.6}100%{transform:scale(1.5);opacity:0}}

/* scroll progress hairline */
.prog{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:120;
  background:var(--tan);transform:scaleX(0);transform-origin:left;
  will-change:transform;
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
  .arm .rv{opacity:1;transform:none}
  .arm .hl::after{transform:scaleX(1)}
  .arm .quote .hl{background-size:100% 100%}
  .ring{stroke-dashoffset:0}
  .rlabel{opacity:1}
  .pulse{display:none}
  .play::after{display:none}
  .prog{display:none}
  .dark::after{animation:none;opacity:.4}
  .arm :where(.rv) img{clip-path:none;transform:none}
  .arm :is(h1,h2).rv{filter:none;transform:none}
  .arm .fh{border-bottom-color:var(--line)}
  .arm .fh::after{display:none}
}

/* ==================== LARGE SCREEN SCALE ====================
   Every size on this site is a clamp, and by roughly 1400px all of them have
   reached their ceiling: the container pins at its maximum and the type stops
   growing. Measured, a 2519px viewport used 49% of its width and showed the
   same 59px headline as a 1400px laptop. The page did not get bigger, it just
   got more margin.

   Rather than re-tuning several dozen clamps, the root itself grows past that
   point. Everything downstream is expressed in rem, so the container, the
   gutters, the section rhythm and the type all scale together and the design
   keeps its proportions instead of stretching one part of itself.

   Written in rem, not px. On the root element rem resolves against the user's
   own default font size, so someone browsing at 20px keeps their 20px and gets
   the large screen scale on top of it. A px value here would silently override
   that preference.

   Reading measure is unaffected: paragraph widths are set in ch, which scales
   with the font, so line lengths stay where they were and only the drawing
   gets larger. The ceiling is reached at about 2250px. */
@media (min-width:1440px){
  :root{
    /* Driven by the smaller governing dimension, not by width alone. Several
       heroes are sized to fill exactly one viewport, so scaling type off width
       on a wide but short window grows the content past a fold that did not
       move: measured, a 1920 window only 900 tall pushed the Work With Me hero
       193px below the bottom edge. Treating height as a proxy for width at
       16:9 means a normally proportioned display gets the full scale, and a
       short one quietly gets almost none of it. */
    font-size:clamp(
      1rem,
      calc(1rem + (min(100vw, 100vh * 1.9) - 1440px) * 0.0062),
      1.3125rem);
  }
}

/* ============================ PAGE TRANSITIONS ============================
   Two halves of one gesture. The page you leave sinks; the page you arrive
   at rises. They are the same keyframe read in opposite directions, which is
   why they feel like one movement rather than two effects.

   The exit used to be a different idea entirely: the page receded while a
   circle of the ground colour opened from wherever you clicked, then the
   monogram held in the middle before the hand-over. Two things were wrong
   with it. It took roughly 700ms, all of which is time between asking for a
   page and getting it, and covering the whole screen in flat colour reads as
   a loading screen no matter how well it is drawn. It is now 300ms and it
   never covers anything: the page simply fades back and the mark it was
   sitting on top of is revealed underneath.

   Transform and opacity only. They are the two properties the compositor can
   animate without waking the main thread, which is what keeps this smooth on
   a surface the size of a whole page. */

/* The one keyframe both halves are built from. */
@keyframes pt-rise{
  from{ opacity:0; transform:scale(.9925) translateY(6px) }
}

/* Arriving. Runs on every load, not just an internal navigation, so a page
   opened from a bookmark or a search result gets the same entrance.

   Fill is backwards, not both. Backwards applies the from-state before the
   animation starts, which is what stops the flash. Both would leave the
   animation in effect after it finishes, and an element with a live
   transform animation is a containing block for fixed descendants forever
   after. */
.page{
  animation:pt-rise .5s cubic-bezier(.22,.61,.36,1) backwards;
}

/* The mark sits behind the page, not over it. Negative z-index puts it under
   .page's cream background while still clearing the ground the whole site is
   painted on, so it is invisible until the page fades off the top of it.
   Nothing is ever covered, which is the difference between a transition and
   a loading screen. */
.vt-mark{
  position:fixed; inset:0; z-index:-1; display:grid; place-items:center;
  pointer-events:none; opacity:0; will-change:transform,opacity;
}
.vt-mark img{ width:clamp(58px,8vw,94px); height:auto; display:block }

/* Reduced motion gets neither half. The script checks the same preference
   and navigates straight away: the transition is decoration, not
   information. */
@media (prefers-reduced-motion:reduce){
  .page{ animation:none }
}

/* ==================== MORE COLOUR ====================
   Navy and teal are the two blues in the logo, so they are kept on different
   kinds of section rather than alternated at random. Navy takes the sections
   that assert something: evidence, mechanism, method. Teal takes the ones
   that invite: proof, promotion, the closing ask. Used that way a reader
   picks up the difference without being told; used interchangeably they
   would just read as two blues.
   ==================================================== */
/* The introduction, on teal.
   It went here rather than onto the quote wall lower down, which sits
   directly above the closing band: two teal sections with nothing between
   them stopped reading as two sections and became one very long block.

   Every colour below is measured on the teal ground rather than carried over
   from a navy one. Teal is much the lighter of the two, so anything that
   worked on navy has to be lifted: the signature is --brown, which manages
   1.55:1 here and is effectively invisible. */
/* Tighter than --sy, which is tuned for cream. Measured, this band carried
   193px above and below a 711px photograph, and on a coloured ground that
   empty space is not page any more, it is a visible rectangle. The same value
   that reads as breathing room on cream reads as a gap here. */
.about.dark{padding:calc(var(--sy) * .62) 0}
.about.dark h2{color:var(--on-dark)}
.about.dark .eyebrow{color:var(--cream)}
.about.dark .body{color:rgba(241,237,227,.88)}          /* 5.47:1 */
.about.dark .body strong{color:var(--on-dark)}          /* 6.53:1 */
.about.dark .sig{color:#E8D8BE}                         /* 5.45:1, tan lifted off teal */
/* The photograph keeps its white mount. A print sitting in a paper frame is
   the point of that treatment, and it reads better against teal than it did
   against cream. */

/* Teal as a ground anywhere, not only on the closing band. Kept separate from
   .cta on purpose: that class carries the closing band's own layout, a 13ch
   cap on its heading included, and borrowing it for a general purpose section
   quietly reshapes the type. */
.dark.teal{
  background:var(--teal-4);
  background:linear-gradient(152deg,var(--teal-4) 0%,var(--teal-5) 100%);
  --glow:rgba(143,186,190,.16);
  padding:var(--sy) 0;
}
.dark.teal .eyebrow{color:var(--cream)}

/* ---- free resources, on navy ----
   The three cards stay white and read as objects sitting on the ground rather
   than panels cut into it, so only the section's own type inverts. .res
   carries no top padding by default because it borrows the gap from the
   section above; on a colour of its own it needs both sides. */
.res.dark{padding:var(--sy) 0}
.res.dark h2{color:var(--on-dark)}
.res.dark .eyebrow{color:var(--tan-2)}
.res.dark .res-head p{color:rgba(241,237,227,.86)}
/* The cards stay white, so everything inside them has to be told to stay
   dark. .dark sets the section's colour to cream and .rcard h3 never declared
   one of its own, so the three titles inherited cream onto a white card and
   disappeared. Only the elements without an explicit colour are affected. */
.res.dark .rcard,.res.dark .rcard h3{color:var(--ink)}

/* ==================== CENTRED SECTION HEADERS ====================
   A heading that shares its row with an image or a second column belongs on
   the left: the left edge is what ties it to the thing beside it. A heading
   that is alone on its row does not have that anchor, and left aligning it
   just leaves an empty right half above a full width list. Measured across
   the site, twenty headings were in that position, most of them capped at
   16ch and so filling barely a third of the row.

   Only direct children are targeted. Body copy inside the cards and lists
   below keeps its own alignment, which is what makes this safe to apply to a
   whole section. */
.headmid > .eyebrow,
.headmid > h2,
.headmid > .sec-p,
.headmid > p{
  text-align:center;
  margin-left:auto;
  margin-right:auto;
}
/* The per section caps were chosen for left aligned wrapping, where a tight
   measure gives a clean ragged right. Centred, the same cap strands the last
   word on a line of its own: "Four numbers, one / problem." at 16ch. Two
   classes here so this outranks the page-local `.figs h2` rules, which load
   after this sheet and would otherwise win on source order. */
.w.headmid > h2{max-width:30ch}
.w.headmid > .sec-p{max-width:62ch}

/* the reference list is capped at 68ch, so it needs centring as a block or it
   sits left under a centred heading. The rows inside stay left aligned. */
.headmid > .ref-list{margin-left:auto;margin-right:auto}

/* ==================== WIDOWS ====================
   A last line carrying a single word. Measured from real line boxes across
   both common desktop widths, there were 45 of them, and they cannot be
   fixed in the source: where a line breaks depends on the rendered width,
   the font and the container, none of which are visible in the HTML. Tying
   the last two words together with a non-breaking space fixes one width and
   creates a new problem at another.

   The browser is better placed to decide. `balance` evens the line lengths
   of a short block, which is what headings are. `pretty` leaves the line
   breaking alone but refuses to strand a single word at the end, which is
   what body copy needs: balancing a long paragraph would rewrite every line
   to solve the last one.

   Both degrade to ordinary wrapping where they are not supported, so there
   is nothing to feature-detect and no fallback to write. */
h1,h2,h3,.loop-h,.bring-h{ text-wrap:balance }
p,li,dd,dt,blockquote,figcaption,.lead,.sec-p{ text-wrap:pretty }

/*Media Speaking Page css*/
.fntfmlyset {font-family: "Instrument Serif", Sans-serif; font-style: italic !important;}
.undrlineset {   text-decoration: underline 3px rgb(195, 160, 128) !important; text-underline-offset: 8px !important;}
