/* ═══════════════════════════════════════════════════════════════════════════
   NICOLE TERRAZAS, LMFT — "THREE COLORS"

   "Therapy is like having three different colors of yarn, all tangled
    together. I help you unravel the knots and put them into little balls so
    you can go deal with your relationships in a healthier way."
                                                                  — Nicole

   Her three colours are the palette: sage, taupe, orchid. They carry the whole
   idea — in the type, the buttons, the hovers, and in the 3:2:1 rule the
   identity is built on.

   They were once ALSO drawn across the page as tangled strands that loosened
   as you read. That was CUT on 2026-08-18. Six appearances in five different
   grammars, showing 2/2/1/2/3/3 of a "three strands" concept that never once
   showed three — and three mapped to nothing countable in the copy (seven
   vignettes, seven outcomes, three services plus three specialties). Unmapped,
   it read as texture pretending to be meaning. DO NOT REINTRODUCE IT.

   What the page does instead: cream plates laid over photographs, and two
   devices that show exactly one thing at a time — the services viewer and the
   outcomes turn.

   ── THE SHUTTERSTOCK LICENCE BAR ──────────────────────────────────────────
   Every stock comp carries a ~100px dark info bar across its foot. It is NOT
   stripped from the source files: the approved framing was tuned against the
   bar-inclusive image ("the visible window at 738/1.15 = 642 source rows").
   It is hidden by an overflow crop instead — .shot img{height:112%}, hero
   115%/119%, .svc-img-col img{height:112%}. EVERY stock photograph on this
   site must therefore render inside a .shot (or .svc-img-col) wrapper, or the
   bar reappears. Nicole's own headshot has no bar.

   ── DO NOT REINTRODUCE ────────────────────────────────────────────────────
   Arches · one-big-rounded-corner (every radius is a single small value) ·
   eyebrows or kicker labels · accent lines above or below headings · left
   vertical stripes · 01/02/03 numbering · the strand motif.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  --sage:#6B8E5A;
  --sage-deep:#47603B;
  --taupe:#8B7B6A;
  --taupe-deep:#655949;
  --taupe-tint:#EDE7DF;
  --orchid:#A0689E;
  --orchid-deep:#7C4B7A;
  --cream:#FAF9F6;
  --cream-warm:#F4F1EA;
  --sage-tint:#E7EDE1;
  --sage-mid:#C8D6BC;
  --sage-pale:#F1F5EE;
  --green-deep:#31402A;
  --clay-mid:#D6CBBC;
  --clay-deep:#4E4437;
  --orchid-tint:#F1E8F0;
  --orchid-mid:#DDC6DB;
  --orchid-pale:#F8F2F7;
  --plum:#5C3459;
  /* the logo's rule, 3:2:1 — declared once so every use is identical */
  --spectrum:linear-gradient(to right,var(--sage) 0 50%,var(--taupe) 50% 83.333%,var(--orchid) 83.333% 100%);
  --ink:#2D2A26;
  --ink-soft:#4F4941;

  --container:1140px;
  --gut:clamp(20px,5vw,40px);

  --f-mark:"Fraunces",Georgia,"Times New Roman",serif;
  --f-head:"Schibsted Grotesk","Helvetica Neue",Arial,sans-serif;
  --f-body:"Literata",Georgia,"Times New Roman",serif;

  --t-h1:clamp(2.1rem,1.28rem + 2.95vw,3.4rem);
  --t-h2:clamp(1.6rem,1.16rem + 1.55vw,2.28rem);
  --t-h3:clamp(1.18rem,1.03rem + .55vw,1.42rem);
  --t-lead:clamp(1.1rem,1.03rem + .34vw,1.28rem);
  --t-body:clamp(1.0rem,.975rem + .13vw,1.06rem);

  --sec:clamp(46px,5.2vw,66px);
  /* inner-page section rhythm — one gap, declared once, applied between
     .svc-block siblings only (see INNER PAGES below) */
  --sec-gap:clamp(46px,7vw,84px);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{
  margin:0;padding-bottom:0;
  background:var(--cream);
  color:var(--ink);
  font-family:var(--f-body);
  font-optical-sizing:auto;
  font-size:var(--t-body);
  line-height:1.72;
  text-wrap:pretty;
  overflow-x:clip;
}
img{max-width:100%}
h1,h2,h3,h4{
  font-family:var(--f-head);
  text-wrap:balance;margin:0;
  line-height:1.09;
  letter-spacing:-0.028em;
  font-weight:700;
}
h1{font-size:var(--t-h1);letter-spacing:-0.038em;line-height:1.02}
h2{font-size:var(--t-h2)}
h3{font-size:var(--t-h3);letter-spacing:-0.02em}
p{margin:0 0 1.1em}
p:last-child{margin-bottom:0}
a{color:inherit}
/* Durable guard: any hand-typed tel:/mailto: link in post_content (e.g. an
   inline "Call me at ..." sentence) renders without a class and would
   otherwise fall back to the browser's default underline. */
a[href^="tel:"],a[href^="mailto:"]{text-decoration:none}
/* Override tpa-base's shared #tpa-thank-you-css (wp_head priority 100,
   `.ty-card a{border-bottom:1px solid currentColor}`) — that inline block is
   fleet-wide, so fix it here per-child rather than in the parent theme.
   !important because the inline block prints after this enqueued stylesheet. */
.ty-card a{border-bottom:none!important}

.wrap{width:min(100% - (var(--gut)*2),var(--container));margin-inline:auto}
.wide{width:min(100% - (var(--gut)*2),1300px);margin-inline:auto}
/* Rule #4 — every inner page template relies on .container for content width */
.container{max-width:1140px;margin:0 auto;padding:0 24px}

/* Shutterstock comps carry a ~100px info bar; an over-tall image inside an
   overflow-hidden frame drops it below the cut. */
.shot{position:relative;overflow:hidden;background:var(--taupe-tint)}
.shot img{display:block;width:100%;height:112%;object-fit:cover;object-position:center top}
.shot--hero img{height:119%}
/* tpa_picture() wraps every <img> in <picture>; without this the picture
   element becomes the flow box and the img's height:112% resolves against
   nothing. */
.shot picture{display:block;position:absolute;inset:0}
.shot picture img{height:112%}
.shot--hero picture img{height:119%}

/* ══════════ BUTTONS — spool label. Squared. No hop. ══════════ */
.btn{
  display:inline-block;position:relative;
  font-family:var(--f-head);font-size:.99rem;font-weight:650;line-height:1.25;
  letter-spacing:-.008em;
  padding:16px 24px;
  border:0;border-radius:2px;
  background:var(--ink);color:var(--cream);
  text-decoration:none;cursor:pointer;
  transition:background .35s cubic-bezier(.22,1,.36,1),color .35s,box-shadow .35s;
}
.btn:hover,.btn:focus-visible{background:var(--sage-deep)}
.btn--light{background:var(--cream);color:var(--ink)}
.btn--light:hover,.btn--light:focus-visible{background:var(--ink);color:var(--cream)}
:focus-visible{outline:2.5px solid var(--orchid);outline-offset:3px}

.skip{
  position:absolute;left:-9999px;top:0;z-index:300;
  background:var(--ink);color:var(--cream);
  font-family:var(--f-head);font-weight:650;font-size:.95rem;
  padding:13px 22px;border-radius:0 0 2px 2px;text-decoration:none;
}
.skip:focus{left:0}

/* ══════════════════ HEADER — own bar, wordmark centred ══════════════════ */
.hdr{
  position:fixed;top:0;left:0;right:0;z-index:70;
  transition:background .4s ease,box-shadow .4s ease,padding .4s ease;
}
.hdr::before{
  content:"";position:absolute;left:0;right:0;top:0;height:235%;
  background:linear-gradient(to bottom,rgba(38,35,31,.86) 0%,rgba(38,35,31,.66) 45%,rgba(38,35,31,0) 100%);
  pointer-events:none;transition:opacity .4s;
}
/* the 1px grey hairline is gone — the spectrum rule replaces it */
.hdr.stuck{background:var(--cream);box-shadow:0 8px 26px -20px rgba(45,42,38,.6)}
.hdr.stuck::before{opacity:0}
.hdr-in{position:relative;z-index:2}
.hdr .nav a,.hdr .mark b{color:var(--cream)}
/* The study set reversed LMFT at #9DB98C against solid ink, where it is 6.5:1.
   This header sits over a SCRIMMED PHOTOGRAPH, which composites to
   rgb(76,76,74) behind the glyphs — #9DB98C measures 4.00:1 there, under AA.
   #B4CDA4 is the same sage a step lighter and measures 4.96:1. */
.hdr .mark span{color:#B4CDA4}
.hdr .tel{color:var(--cream)}
.hdr .burger i{background:var(--cream)}
.hdr.stuck .nav a,.hdr.stuck .mark b{color:var(--ink)}
.hdr.stuck .mark span{color:var(--sage-deep)}
.hdr.stuck .tel{color:var(--orchid-deep)}
.hdr.stuck .burger i{background:var(--ink)}
.hdr-in{display:flex;align-items:center;gap:clamp(12px,1.8vw,26px);padding:12px 0}

.nav{list-style:none;margin:0;padding:0;display:flex;align-items:center;gap:clamp(13px,1.8vw,25px)}
.navwrap{display:flex;align-items:center}
.navwrap--l{margin-right:auto}
.navwrap--r{margin-left:auto}
.nav li{position:relative}
.nav ul{list-style:none;margin:0;padding:0}
.nav a{
  text-decoration:none;font-family:var(--f-head);font-size:.93rem;font-weight:550;color:var(--ink);
  display:inline-flex;align-items:center;gap:6px;padding:9px 0;
  border-bottom:2px solid transparent;transition:border-color .3s,color .3s;
}
.nav a:hover,.nav a:focus-visible{border-bottom-color:var(--orchid)}
.chev{width:9px;height:9px;flex:0 0 auto;transition:transform .3s}
.nav li:hover>a .chev{transform:rotate(180deg)}
.has-sub>a{padding-bottom:16px;margin-bottom:-7px}
/* WordPress emits .menu-item-has-children / .sub-menu; a nav_menu_css_class
   filter in functions.php adds .has-sub / .sub alongside them so the mockup's
   selectors and JS keep working. Both families are listed everywhere. */
.sub,
.nav .sub-menu,
.nav .dropdown-menu{
  position:absolute;top:100%;left:-16px;min-width:214px;
  background:var(--cream);border:1px solid rgba(139,123,106,.4);
  border-radius:2px;padding:7px 0;
  list-style:none;margin:0;
  box-shadow:0 18px 38px -22px rgba(45,42,38,.55);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .28s ease,transform .28s ease,visibility .28s;
}
.sub li,
.nav .sub-menu li,
.nav .dropdown-menu li{list-style:none;margin:0;padding:0}
.has-sub:hover .sub,.has-sub:focus-within .sub,
.menu-item-has-children:hover .sub-menu,.menu-item-has-children:focus-within .sub-menu{opacity:1;visibility:visible;transform:translateY(0)}
.sub a{display:block;padding:8px 18px;font-family:var(--f-body);font-weight:400;font-size:.93rem;border:0}
.sub a:hover,.sub a:focus-visible{background:var(--taupe-tint);color:var(--orchid-deep)}
/* `.hdr .nav a` paints every nav link cream for the overlay header — and the
   dropdown's own ground IS cream, so the submenu was cream-on-cream and only
   appeared on hover. `.sub a` alone (0,1,1) loses to it; this matches its
   specificity and comes later. */
.hdr .sub a,.hdr.stuck .sub a{color:var(--ink)}
.hdr .sub a:hover,.hdr .sub a:focus-visible{color:var(--orchid-deep)}
/* Services and Specialties are grouping labels — there is no services index
   page, so they emit href="#". On desktop that must not be clickable (a bare
   "#" jumps to top); hover and :focus-within still open the submenu, and the
   anchor is still Tab-reachable. On mobile the same anchor IS the accordion
   toggle, so the rule is desktop-only. */
@media (min-width:769px){
  .nav .has-sub > a,
  .nav .menu-item-has-children > a{cursor:default;pointer-events:none}
}

.mark{
  display:flex;flex-direction:row;align-items:baseline;gap:.34em;line-height:1;text-decoration:none;
  flex:0 0 auto;padding:0 clamp(6px,1.4vw,20px);
  min-width:0;
}
/* The wordmark: Fraunces at the identity's own variation settings, with the
   credential tracked out beside it. LMFT runs --sage-deep rather than the
   study's --sage on light grounds: #6B8E5A measures 3.40:1 on cream, which is
   under AA for text this size. --sage-deep is 6.40:1. */
.mark b{
  font-family:var(--f-mark);font-weight:400;font-size:1.34rem;
  letter-spacing:-.015em;line-height:1;
  font-variation-settings:"SOFT" 60,"WONK" 1,"opsz" 96;
}
.mark span{
  font-family:var(--f-head);font-size:.72rem;font-weight:600;
  letter-spacing:.3em;text-transform:uppercase;color:var(--sage-deep);
}

.tel{
  text-decoration:none;font-family:var(--f-head);font-size:.95rem;font-weight:680;
  color:var(--orchid-deep);white-space:nowrap;
  transition:color .3s;
}
.tel:hover,.tel:focus-visible{color:var(--orchid)}
/* .nav a's shared hover-reveal border-bottom would otherwise underline the
   phone number on hover like a text link — the phone CTA stays underline-free
   in every state. */
.nav a.tel,.nav a.tel:hover,.nav a.tel:focus-visible{border-bottom:none}

.burger{display:none;background:none;border:0;padding:10px 9px;cursor:pointer;width:44px;height:44px;margin-left:auto;flex:0 0 auto}
.burger i{display:block;height:2px;min-height:2px;flex-shrink:0;width:24px;background:var(--ink);margin:5px 0;transition:transform .35s cubic-bezier(.22,1,.36,1),opacity .25s}
.burger[aria-expanded="true"] i:nth-child(1){transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] i:nth-child(2){opacity:0}
.burger[aria-expanded="true"] i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* Close button inside the drawer — once the page is scrolled the burger is
   off-screen, so the drawer needs its own way out. */
.nav-close{
  display:none;position:absolute;top:10px;right:14px;width:44px;height:44px;
  background:transparent;border:0;cursor:pointer;padding:0;
  align-items:center;justify-content:center;color:var(--ink);
  transition:transform .25s ease;
}
.nav-close:hover{transform:rotate(90deg)}
.nav-close svg{width:22px;height:22px;display:block}

/* ══════════════════ HERO — the walker keeps her ground ══════════════════
   She stands between 56% and 72% of the frame at every desktop width, so the
   plate is a COLUMN on the container grid, not a slab bled to the viewport
   edge — it stops around 40%, leaving her a clear field of hill to walk into.
   The frame is sized so the crop lands past her feet but short of the
   Shutterstock bar: the picture is height-driven cover at every width ≥768,
   which fixes the visible window at 738/1.15 = 642 source rows. Head to foot
   is 68→605. Nothing of her is ever cut. */
.hero{
  position:relative;background:var(--ink);
  /* Centred rather than pinned to the foot: bottom-anchoring meant the card
     dropped every time its content got shorter, which is how it ended up
     sitting low. Centring holds its place whatever the copy does. */
  display:flex;align-items:center;
  min-height:clamp(560px,63vw,830px);
  padding:clamp(92px,9vw,124px) 0 clamp(70px,8vw,116px);
}
.hero .shot{position:absolute;inset:0;height:100%}
/* x below 50% walks the visible window LEFT through the source, which carries
   her further RIGHT on screen and off the plate. */
.hero .shot img{height:115%;object-position:38% top;filter:brightness(.88) saturate(1.03)}
.hero-grid{
  position:relative;z-index:5;
  width:min(100% - (var(--gut)*2),var(--container));margin-inline:auto;
}
/* ── HERO PLATE · the mount ────────────────────────────────────────────────
   A cream plate sitting on a slightly larger, slightly warmer one — the way a
   print sits on a mount board. The depth comes from two tones and an even
   reveal on all four sides, not from an outline or a cut.

   The reveal is 14px and identical on all four sides — including the angled
   one. Both the mount and the plate are cut at the SAME 3.4 degrees, so the
   reveal stays even as the edge falls away; cutting only the outer one would
   open the gap out into a wedge.

   The bridge's plate is built the same way, so the two cards on this page that
   sit on a photograph are the same object at two sizes. */
.hero-plate{
  container-type:inline-size;position:relative;
  width:min(588px,calc(50vw - var(--gut)));
  padding:14px;
}
.hero-plate::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:var(--cream-warm);
  clip-path:polygon(0 0,100% 0,100% calc(100% - 35px),0 100%);
  filter:drop-shadow(0 26px 46px rgba(45,42,38,.5));
}
.hero-inner{
  position:relative;z-index:1;
  padding:clamp(28px,3vw,36px) clamp(26px,2.9vw,34px) clamp(62px,6.2vw,80px);
}
.hero-inner::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:var(--cream);
  clip-path:polygon(0 0,100% 0,100% calc(100% - 33px),0 100%);
}
.hero h1{font-size:clamp(1.66rem,7.02cqw,2.18rem);line-height:1.08}
.hero h1 u{text-decoration:none;color:var(--sage-deep);display:block}
.hero-who{
  margin:clamp(14px,1.7vw,19px) 0 0;
  font-family:var(--f-head);font-weight:670;letter-spacing:-.018em;line-height:1.2;
  font-size:clamp(1.12rem,1.0rem + .52vw,1.34rem);color:var(--ink);
}
.hero-lead{
  font-size:clamp(1.08rem,.99rem + .4vw,1.24rem);font-weight:440;
  color:var(--ink-soft);line-height:1.55;margin:clamp(13px,1.6vw,18px) 0 0;text-wrap:pretty;
}
.hero-where{
  margin:clamp(16px,1.9vw,22px) 0 0;padding-top:clamp(14px,1.7vw,18px);
  border-top:1px solid rgba(139,123,106,.45);
  font-size:1.04rem;font-weight:460;color:var(--taupe-deep);line-height:1.45;
}
.hero-act{display:flex;flex-wrap:wrap;align-items:center;gap:13px 20px;margin:clamp(22px,2.6vw,30px) 0 0}
.hero-act .btn{flex:1 1 100%;text-align:center}

@media (max-width:768px){
  .hero-plate{width:auto;margin:-58px var(--gut) 0;padding:10px}
  .hero-plate::before{clip-path:polygon(0 0,100% 0,100% calc(100% - 22px),0 100%)}
  .hero-inner{padding:24px 20px 42px}
  .hero-inner::before{clip-path:polygon(0 0,100% 0,100% calc(100% - 20px),0 100%)}
}

/* ══════════════════ THE VIGNETTES — the roster ══════════════════
   Seven names along the top; the chosen one plays out below in full, with its
   photograph. The reader picks the person who sounds like them instead of
   scrolling past six who do not.

   Names, not headlines, on the control — a headline gives the story away and
   makes the row long enough to wrap twice. */
.vgs{background:var(--cream);padding:var(--sec) 0}
.vgs h2{margin:0}
.vgs .turnline{
  font-family:var(--f-body);font-style:italic;color:var(--sage-deep);
  font-size:1.02em;margin-top:1.15em;
}
.vgs p{color:var(--ink-soft)}
/* the person the story is about, named in the accent so the eye finds who it
   is reading about before it reads the sentence */
.vgs .who{font-family:var(--f-head);font-weight:700;letter-spacing:-.018em;color:var(--plum)}
.vgs-head{margin-bottom:clamp(22px,2.6vw,32px)}
/* The row spans the full width of the stage beneath it. The seven shares are
   PROPORTIONAL to each name rather than equal: at equal shares each gets
   154px, and "Sophia & Jackson" and "Elena & Armando" both break to a second
   line, leaving the row two different heights. Growing from natural width
   fills the same span and keeps every name on one line. */
.roster{
  display:flex;flex-wrap:wrap;gap:0;
  border-bottom:1px solid rgba(139,123,106,.4);
}
.roster-name{
  flex:1 1 auto;white-space:nowrap;
  background:none;border:0;cursor:pointer;position:relative;
  padding:clamp(11px,1.3vw,15px) clamp(6px,.8vw,12px);
  font-family:var(--f-head);font-weight:660;letter-spacing:-.014em;
  font-size:clamp(.96rem,.9rem + .3vw,1.12rem);
  color:var(--taupe-deep);transition:color .3s;
}
.roster-name::after{
  content:"";position:absolute;left:clamp(6px,.8vw,12px);right:clamp(6px,.8vw,12px);
  bottom:-1px;height:2px;background:var(--sage-deep);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .38s cubic-bezier(.22,1,.36,1);
}
.roster-name:hover{color:var(--ink)}
.roster-name.on{color:var(--ink)}
.roster-name.on::after{transform:scaleX(1)}
.vg-stage{position:relative;margin-top:clamp(28px,3.4vw,44px)}
.vg-slide{
  display:none;
  grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);
  gap:clamp(26px,3.8vw,58px);align-items:center;
}
.vg-slide.on{display:grid;animation:vgIn .5s cubic-bezier(.22,1,.36,1)}
@keyframes vgIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.vg-slide .shot{aspect-ratio:4/3;border-radius:2px;box-shadow:0 26px 54px -36px rgba(45,42,38,.5)}
.vgs h2{max-width:18ch;margin-bottom:.55em}
@media (prefers-reduced-motion:reduce){.vg-slide.on{animation:none}}
@media (hover:none) and (pointer:coarse){.roster-name{padding-top:14px;padding-bottom:14px}}
@media (max-width:900px){
  .vg-slide{grid-template-columns:1fr;gap:20px}
  .vg-slide .shot{aspect-ratio:16/9}
  /* seven equal columns are unreadable at this width — two rows of names */
  .roster-name{flex:1 1 28%}
}
@media (max-width:520px){
  .roster-name{flex:1 1 44%}
}

/* ══════════════════ BRIDGE — the field ══════════════════
   The garden is painted as a fixed background rather than an <img>, so it
   holds still in the window while the band travels over it — the same
   treatment the closing band uses. It has to be a background: attachment has
   no effect on an <img>. Reverts to scroll on touch, where iOS ignores fixed
   outright and Android janks on it.

   The plate takes the same cut as the hero's, so the two plates that sit on a
   photograph are finished the same way. */
.bridge{position:relative;background:var(--ink);padding:0;overflow:hidden}
.bridge-photo{position:absolute;inset:0;margin:0}
.bridge-photo .shot{
  position:absolute;inset:0;height:100%;border-radius:0;box-shadow:none;
  background-size:cover;background-position:center 48%;background-repeat:no-repeat;
  background-attachment:fixed;
  filter:brightness(.94);
}
/* Below-fold background, loaded only when the section approaches — otherwise
   it competes with the hero for bandwidth during the LCP window. The .webp
   comes first so browsers that support it never fetch the JPEG. */
/* --bg-override is set inline by the template ONLY when the client has
   uploaded her own photograph; otherwise the theme's own file is used, WebP
   first. Either way it loads lazily. */
.bridge-photo.bg-loaded .shot{
  background-image:var(--bg-override,url('../images/bridge-bg-wm.jpg'));
  background-image:var(--bg-override,image-set(url('../images/bridge-bg-wm.webp') type('image/webp'),
                                               url('../images/bridge-bg-wm.jpg')  type('image/jpeg')));
}
.bridge-in{
  position:relative;z-index:2;
  min-height:clamp(480px,48vw,660px);
  display:flex;align-items:center;
  padding:clamp(52px,6vw,86px) 0;
}
/* the same mount, the same angle, one size down */
.bridge-txt{
  position:relative;
  width:min(576px,calc(54vw - var(--gut)));
  padding:14px;
}
.bridge-txt::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:var(--cream-warm);
  clip-path:polygon(0 0,100% 0,100% calc(100% - 34px),0 100%);
  filter:drop-shadow(0 24px 42px rgba(45,42,38,.46));
}
.bridge-inner{
  position:relative;z-index:1;
  padding:clamp(30px,3.2vw,40px) clamp(28px,3vw,36px) clamp(58px,5.6vw,74px);
}
.bridge-inner::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:var(--cream);
  clip-path:polygon(0 0,100% 0,100% calc(100% - 32px),0 100%);
}
/* The two-line break needs 476px and the plate holds exactly 476px — no slack
   at all, so it kept wrapping to three. The cap is gone, balance is off (it
   will happily pick three even lines over two), and the size drops about 5% so
   the longest line clears the measure with room. */
.bridge h2{max-width:none;font-size:clamp(1.5rem,1.08rem + 1.42vw,2.14rem);text-wrap:wrap}
.bridge-lead{font-size:var(--t-lead);line-height:1.6;margin-top:.8em}
.bridge p:not(.bridge-lead){color:var(--ink-soft)}
@media (max-width:768px){
  .bridge{background:var(--taupe-tint)}
  .bridge-photo{position:relative;inset:auto}
  .bridge-photo .shot{position:relative;inset:auto;height:auto;aspect-ratio:5/4}
  .bridge-in{display:block;min-height:0;padding:0 0 var(--sec)}
  .bridge-txt{width:auto;margin:-54px var(--gut) 0;padding:10px}
  .bridge-txt::before{clip-path:polygon(0 0,100% 0,100% calc(100% - 22px),0 100%)}
  .bridge-inner{padding:24px 20px 40px}
  .bridge-inner::before{clip-path:polygon(0 0,100% 0,100% calc(100% - 20px),0 100%)}
}

/* ══════════════════ BIO — prose left, portrait held right ══════════════════ */
.bio{background:var(--cream);padding:var(--sec) 0;position:relative}
/* The tall stack put the portrait, the heading and every paragraph on one
   centred axis, so the section read as a column of unrelated blocks. The prose
   now runs left in its own measure with the portrait held to the right of it,
   and the text is left-justified like the rest of the page. */
.bio-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,368px);
  gap:clamp(28px,4vw,64px);align-items:start;
}
.bio-photo{width:100%;position:sticky;top:clamp(96px,10vw,128px)}
/* photo and nameplate are one object: the shot squares its foot, the plate
   squares its head, and they meet on a shared edge with no ground between */
.bio-photo .shot{aspect-ratio:4/5;border-radius:2px 2px 0 0}
.bio-photo .shot img{object-position:center 12%;height:104%}
.bio-photo .shot picture img{height:104%}
/* Photo credit — small, muted, tucked in the shot's own corner so it reads as
   a caption on the image rather than a line of page copy. */
.photo-credit{
  position:absolute;right:8px;bottom:8px;z-index:1;
  font-size:.68rem;line-height:1;letter-spacing:.01em;
  color:rgba(255,255,255,.85);
  text-shadow:0 1px 3px rgba(0,0,0,.55);
}
/* The nameplate is the foot of the portrait, not a card near it: zero margin,
   squared top corners against the photo's squared bottom, and the warm cream
   one step off the section ground so it reads as the same object in a lighter
   material rather than as a separate taupe tile. */
.bio-cap{
  margin:0;padding:17px 20px 19px;
  background:var(--cream-warm);
  border-radius:0 0 2px 2px;
  display:flex;flex-direction:column;align-items:center;gap:7px;
  text-align:center;
}
/* the credential sits under the name and has to hold ONE line: 37 characters
   in 328px of card means the tracking has to come off */
.bio-cap .card-kind{
  order:2;text-transform:none;letter-spacing:.005em;
  font-size:.82rem;font-weight:600;
  color:var(--sage-deep);max-width:none;line-height:1.4;white-space:nowrap;
}
.bio-cap b{
  order:1;
  font-family:var(--f-mark);font-weight:400;
  font-size:clamp(1.18rem,1.06rem + .5vw,1.44rem);
  letter-spacing:-.015em;line-height:1;color:var(--ink);
  font-variation-settings:"SOFT" 60,"WONK" 1,"opsz" 96;
}
.bio-txt h2{margin:0;max-width:14ch}
/* Drops from --t-lead to the page's body size. It sat a step above every
   paragraph around it while reading as the same kind of prose, which is what
   made it feel odd. It keeps the full ink colour, so it still leads the
   section — by weight of colour rather than by size. */
.bio-lead{max-width:none;margin:clamp(16px,2vw,22px) 0 clamp(20px,2.4vw,28px);
  color:var(--ink);font-size:var(--t-body);line-height:1.72}
.bio-cols{max-width:none}
.bio-cols p{color:var(--ink-soft)}
/* the same heading treatment as "The Tools I'll Put in Your Hands", so the two
   openings in this section are plainly the same kind of thing */
.bio-sub{
  font-family:var(--f-head);font-size:var(--t-h3);font-weight:700;
  letter-spacing:-.02em;line-height:1.09;color:var(--ink);
  margin:0 0 .65em;
}
.tools{
  max-width:none;margin:clamp(28px,3.4vw,40px) 0 0;
  padding-top:clamp(24px,2.8vw,32px);
  border-top:2px solid rgba(107,142,90,.4);
}
.tools h3{margin-bottom:.65em}
.tools-body{max-width:none}
.tools-body p{color:var(--ink-soft)}
.bio-cta{margin-top:clamp(26px,3vw,36px)}

/* ══════════════════ SERVICES — the viewer ══════════════════
   One picture at a time. Pointing at a name brings its page's photograph up in
   the panel; the six images are all in the DOM and cross-fade, so nothing is
   fetched mid-interaction and nothing pops. Below the drawer breakpoint there
   is no hover to drive it, so the panel steps aside and the names run as a
   plain list. */
.svcs{position:relative;background:var(--ink);color:var(--cream);padding:var(--sec) 0;overflow:hidden}
.svcs-in{position:relative;z-index:2}
.set-label{
  margin:0;font-family:var(--f-head);font-size:.72rem;font-weight:700;
  letter-spacing:.2em;text-transform:uppercase;color:rgba(250,249,246,.62);
}
.vwr{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:clamp(24px,4vw,56px);align-items:center;
  margin-top:clamp(20px,2.4vw,30px);
}
.vwr-list{display:flex;flex-direction:column}
.vwr-set+.vwr-set{margin-top:clamp(18px,2vw,26px)}
.vwr-set .set-label{margin-bottom:clamp(8px,1vw,12px)}
.vwr-item{
  display:flex;align-items:baseline;gap:14px;
  padding:clamp(8px,1vw,12px) 0;
  border-top:1px solid rgba(250,249,246,.18);
  font-family:var(--f-head);font-weight:700;letter-spacing:-.03em;line-height:1.1;
  font-size:clamp(1.24rem,.98rem + 1.05vw,1.85rem);
  color:rgba(250,249,246,.62);text-decoration:none;
  transition:color .35s,padding-left .35s cubic-bezier(.22,1,.36,1);
}
.vwr-set:last-child .vwr-item:last-child{border-bottom:1px solid rgba(250,249,246,.18)}
.vwr-item svg{width:.5em;height:.5em;flex:0 0 auto;margin-left:auto;opacity:0;transition:opacity .3s}
.vwr-item.on,.vwr-item:hover,.vwr-item:focus-visible{color:var(--cream);padding-left:12px}
.vwr-item.on svg,.vwr-item:hover svg,.vwr-item:focus-visible svg{opacity:1}
/* The photographs are deliberately abstract — a seedling for Individual, two
   flowers side by side for Couples, eucalyptus shadows for Anxiety. That is
   the right instinct for a therapy practice, but abstract means the swap has
   nothing to say on its own: the picture changes and the visitor cannot tell
   what it changed in answer to. The panel is ~500px from the list it belongs
   to, which is far enough that the connection has to be stated.

   So the picture names itself. It is a PLATE, not a translucent scrim: the
   cream is solid, the type sits on cream rather than on photograph, and it is
   the same object the portrait in the bio uses — photograph above, solid
   nameplate fused to its foot, sharing an edge. */
.vwr-panel{position:relative;overflow:hidden;border-radius:2px;background:rgba(250,249,246,.08);aspect-ratio:4/3}
/* Translucent rather than solid — measured, not guessed. Sampling the strip of
   photograph each plate covers and compositing against the DARKEST pixel in it
   (not the average), cream at .88 holds 6.4:1 on the sentence and 10.7:1 on
   the name across all six pictures. It reads as part of the photograph instead
   of pasted onto it, while still being a defined surface with an edge — which
   is the thing a scrim is not. No backdrop blur: that turns a plate into
   glass. */
.vwr-cap{
  position:absolute;left:0;right:0;bottom:0;z-index:3;
  background:rgba(250,249,246,.88);
  padding:13px clamp(16px,1.8vw,22px) 15px;
  display:block;
}
/* The name alone said what you were looking at but gave no reason to open it.
   The second line is that page's OWN headline, lifted verbatim from its copy
   doc — nothing is invented, and it is the one line most likely to make a
   visitor think "that is me". It is stored on the service page itself
   (ACF: service_overlay_line) so it can never drift from that page's H1. */
.vwr-cap b{
  display:block;
  font-family:var(--f-head);font-weight:700;letter-spacing:-.022em;line-height:1.15;
  font-size:clamp(1.02rem,.94rem + .34vw,1.2rem);color:var(--ink);
}
.vwr-cap em{
  display:block;margin-top:4px;font-style:normal;
  font-family:var(--f-body);font-size:.95rem;line-height:1.42;color:var(--ink-soft);
}
/* it is the door as well as the label */
.vwr-cap .go{
  display:inline-flex;align-items:center;gap:7px;margin-top:9px;
  font-family:var(--f-head);font-size:.8rem;font-weight:700;
  letter-spacing:.06em;color:var(--sage-deep);
}
.vwr-cap .go svg{width:13px;height:13px;transition:transform .3s}
/* it changes with the picture rather than snapping */
.vwr-cap b,.vwr-cap em{transition:opacity .28s ease}
.vwr-cap.swap b,.vwr-cap.swap em{opacity:0}
@media (prefers-reduced-motion:reduce){.vwr-cap b,.vwr-cap em{transition:none}}
@media (max-width:768px){.vwr-cap{padding:11px 16px 13px}}
.vwr-panel .shot{position:absolute;inset:0;height:100%;opacity:0;transition:opacity .55s cubic-bezier(.22,1,.36,1)}
.vwr-panel .shot.on{opacity:1}
@media (prefers-reduced-motion:reduce){
  .vwr-item,.vwr-panel .shot{transition:none}
}

/* ══════════════════ WHERE THESE STORIES LEAD ══════════════════ */
.outs{background:var(--cream);padding:clamp(50px,5.8vw,70px) 0 var(--sec)}
.outs h2{max-width:20ch}

/* The names sit ABOVE the plate, in the same row treatment the stories section
   uses at the top of the page — proportional shares spanning the full width,
   one line each, an underline on the open one. The two sections carry the same
   seven people, so they are steered the same way.

   The stories cross-fade in place rather than sliding a rail, so the plate
   never changes height mid-transition and nothing reflows. */
.turn{margin-top:clamp(22px,2.6vw,32px)}
.turn-names{
  display:flex;flex-wrap:wrap;gap:0;
  border-bottom:1px solid rgba(139,123,106,.4);
  margin-bottom:clamp(20px,2.4vw,30px);
}
.turn-name{
  flex:1 1 auto;white-space:nowrap;
  background:none;border:0;cursor:pointer;position:relative;
  padding:clamp(11px,1.3vw,15px) clamp(6px,.8vw,12px);
  font-family:var(--f-head);font-weight:660;letter-spacing:-.014em;
  font-size:clamp(.96rem,.9rem + .3vw,1.12rem);
  color:var(--taupe-deep);transition:color .3s;
}
.turn-name::after{
  content:"";position:absolute;left:clamp(6px,.8vw,12px);right:clamp(6px,.8vw,12px);
  bottom:-1px;height:2px;background:var(--sage-deep);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .38s cubic-bezier(.22,1,.36,1);
}
.turn-name:hover{color:var(--ink)}
.turn-name.on{color:var(--ink)}
.turn-name.on::after{transform:scaleX(1)}
.turn-stage{
  position:relative;background:var(--taupe-tint);border-radius:2px;border-top:0;
  padding:clamp(30px,4vw,52px) clamp(26px,3.6vw,48px);
  display:grid;
}
.turn-card{
  grid-area:1/1;margin:0;max-width:60ch;
  color:var(--ink-soft);font-size:clamp(1.14rem,1.02rem + .48vw,1.38rem);line-height:1.6;
  opacity:0;transform:translateY(10px);pointer-events:none;
  transition:opacity .5s cubic-bezier(.22,1,.36,1),transform .5s cubic-bezier(.22,1,.36,1);
}
.turn-card.on{opacity:1;transform:none;pointer-events:auto}
.turn-card b{font-family:var(--f-head);font-weight:700;color:var(--ink);letter-spacing:-.022em;font-size:1.06em}
.turn-foot{
  display:flex;justify-content:flex-end;
  margin-top:clamp(18px,2.2vw,26px);
}
.turn-steps{display:flex;gap:9px}
.turn-step{
  width:44px;height:44px;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  background:transparent;color:var(--ink);
  border:1.5px solid rgba(139,123,106,.55);border-radius:2px;
  cursor:pointer;transition:background .3s,border-color .3s,opacity .3s;
}
.turn-step:hover:not(:disabled),.turn-step:focus-visible{background:rgba(139,123,106,.16);border-color:var(--ink)}
.turn-step:disabled{opacity:.32;cursor:default}
.turn-step svg{width:15px;height:15px}
@media (hover:none) and (pointer:coarse){.turn-name{padding-top:14px;padding-bottom:14px}}
/* seven equal columns are unreadable narrow — the row breaks to two, then three */
@media (max-width:900px){.turn-name{flex:1 1 28%;white-space:normal}}
@media (max-width:520px){.turn-name{flex:1 1 44%}}
@media (prefers-reduced-motion:reduce){.turn-card{transition:none}}

/* ══════════════════ FINAL CTA ══════════════════ */
.close{position:relative;background:var(--cream)}
.close-band{position:relative}
/* Parallax: the vineyard is painted as a fixed background so it holds still in
   the viewport while the band scrolls over it. Has to be a background —
   background-attachment has no effect on an <img>. The touch-device block
   below switches this back to `scroll`: iOS ignores `fixed` silently and
   Android janks badly on it. */
.close-band .shot{
  height:clamp(300px,34vw,440px);
  background-size:cover;
  background-position:center 44%;
  background-repeat:no-repeat;
  background-attachment:fixed;
}
.close-band.bg-loaded .shot{
  background-image:var(--bg-override,url('../images/close-bg-wm.jpg'));
  background-image:var(--bg-override,image-set(url('../images/close-bg-wm.webp') type('image/webp'),
                                               url('../images/close-bg-wm.jpg')  type('image/jpeg')));
}
.close-curve{position:absolute;left:0;right:0;bottom:-1px;width:100%;height:clamp(40px,5vw,74px);display:block}
.close-plate{
  position:relative;z-index:3;
  width:min(100% - (var(--gut)*2),760px);margin:clamp(-176px,-12vw,-96px) auto 0;
  background:var(--cream);
  padding:clamp(28px,3.4vw,42px);
  border-radius:2px;
  box-shadow:0 30px 64px -40px rgba(45,42,38,.55);
  text-align:center;
}
.close-plate h2{max-width:18ch;margin-inline:auto}
.close-plate p{color:var(--ink-soft);max-width:56ch;margin-inline:auto}
/* the two sentences hold their own lines rather than wrapping wherever the
   measure happens to run out — spans rather than a <br> so they still behave
   on a narrow screen, where each simply wraps within itself */
.close-lede span{display:block}
.close-plate p:first-of-type{margin-top:.8em}

.frm-wrap{padding:clamp(34px,4vw,50px) 0 var(--sec)}
.frm{width:min(100%,660px);margin-inline:auto}
.reach{
  width:min(100%,660px);margin:clamp(26px,3vw,34px) auto 0;
  padding-top:20px;border-top:1px solid rgba(139,123,106,.4);
  display:flex;flex-wrap:wrap;justify-content:center;gap:9px 26px;align-items:baseline;text-align:center;
}
.reach a{font-family:var(--f-head);font-weight:670;color:var(--ink);text-decoration:none;transition:color .3s}
.reach a:hover,.reach a:focus-visible{color:var(--orchid-deep)}
.reach span{font-size:.9rem;color:var(--taupe-deep)}
/* editor-only notice shown in place of the form when no shortcode is set.
   Never a hand-rolled <form> — a fake form tells a visitor in distress their
   message sent when nothing was sent. */
.form-missing{
  max-width:660px;margin-inline:auto;padding:18px 20px;border-radius:2px;
  background:var(--taupe-tint);color:var(--clay-deep);
  font-family:var(--f-head);font-size:.95rem;
}

/* ══════════════════ FOOTER ══════════════════ */
.ftr{background:var(--ink);color:var(--cream);padding:42px 0 24px}
.ftr-in{display:flex;flex-wrap:wrap;align-items:center;gap:18px 30px}
.ftr .mark{align-items:baseline;padding:0}
.ftr .mark span{color:#9DB98C}
/* the tri-partite rule at full strength — one continuous 3:2:1 bar */
.ends{display:flex;margin-left:14px;width:78px;height:3px;border-radius:2px;overflow:hidden}
.ends i{display:block;height:3px}
.ends i:nth-child(1){flex:3;background:var(--sage)}
.ends i:nth-child(2){flex:2;background:var(--taupe)}
.ends i:nth-child(3){flex:1;background:var(--orchid)}
.pt{
  margin-left:auto;display:inline-flex;align-items:center;gap:8px;
  text-decoration:none;color:var(--cream);
  border:1px solid rgba(250,249,246,.34);border-radius:2px;
  padding:8px 15px;font-family:var(--f-head);font-size:.84rem;font-weight:600;
  transition:border-color .3s,background .3s;
}
.pt:hover,.pt:focus-visible{border-color:var(--orchid);background:rgba(160,104,158,.2)}
.ftr-legal{
  width:100%;margin-top:24px;padding-top:17px;
  border-top:1px solid rgba(250,249,246,.16);
  display:flex;flex-wrap:wrap;gap:8px 24px;align-items:center;
}
.ftr-legal a{color:rgba(250,249,246,.84);text-decoration:none;font-size:.85rem;border-bottom:1px solid transparent;transition:border-color .3s}
.ftr-legal a:hover,.ftr-legal a:focus-visible{border-bottom-color:var(--orchid)}
.ftr-legal small{margin-left:auto;font-size:.85rem;color:rgba(250,249,246,.6)}

/* ══════════════════ REVEALS — three only ══════════════════ */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .95s cubic-bezier(.22,1,.36,1),transform .95s cubic-bezier(.22,1,.36,1)}
.reveal.in{opacity:1;transform:none;animation:none}
/* The safety net is a setTimeout in client.js, NOT `animation:forceVisible 0s
   … 3.5s forwards`. A zero-duration animation WITH a delay is what Chrome
   flags as non-composited, and it costs CLS points. */
@keyframes forceVisible{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none;animation:none}
  *{animation-duration:.001ms!important;transition-duration:.001ms!important}
  .has-sub:hover .sub,.has-sub:focus-within .sub{opacity:1;visibility:visible;transform:none}
}
/* Inner-page wrappers carry no scroll reveal of their own — they only need to
   be visible if something upstream fails. 0.01s (not 0s) so the browser can
   composite it. */
.inner-content,.inner-body,.service-body,.contact-grid{animation:forceVisible .01s 8s forwards}

/* ══════════════════ RESPONSIVE ══════════════════ */
@media (max-width:1024px){
  /* The frame zooms as the viewport narrows, so the same 38% offset that
     clears the plate at desktop walks her backpack off the right edge by iPad
     portrait. Centre the window again — the plate is narrow enough here that
     she still keeps ~110px of clear hill on her left. */
  .hero .shot img{object-position:50% top}
  .bio-grid{grid-template-columns:1fr;gap:26px}
  .bio-photo{position:static;max-width:368px}
}

/* Mobile — the condition also catches a phone in LANDSCAPE (926px wide, which
   clears every max-width:768px gate on its own). The burger and its drawer
   MUST stay on this one condition: split them and the burger appears but opens
   into an unstyled list. */
@media (max-width:768px),
       (hover:none) and (pointer:coarse) and (max-height:500px){
  .burger{display:block}
  .nav-close{display:flex}
  /* client.js seeds Home/About/Services in ABOVE this li, so it ends up mid-list;
     with `.nav li{position:relative}` the X anchored to the Specialties row.
     Static li = the X anchors to the fixed drawer's top-right corner. */
  .nav--r .nav-close-li{position:static}
  /* A landscape phone is >768px wide, so the desktop-only (min-width:769px)
     pointer-events:none on the Services/Specialties labels reached it and the
     accordion toggles were untappable. Same specificity, later = wins. */
  .nav--r .has-sub > a,
  .nav--r .menu-item-has-children > a{cursor:pointer;pointer-events:auto}
  .mark{margin-right:auto;align-items:baseline;padding:0}
  .nav--r{
    position:fixed;top:0;right:0;bottom:0;width:min(86vw,360px);
    height:100vh;height:100dvh;
    background:var(--cream);
    flex-direction:column;align-items:stretch;justify-content:flex-start;
    gap:0;padding:80px 26px 40px;margin:0;
    overflow-y:auto;z-index:80;
    transform:translateX(100%);
    transition:transform .42s cubic-bezier(.22,1,.36,1);
    box-shadow:none;
  }
  .nav--r.open{transform:none;box-shadow:-18px 0 46px -30px rgba(45,42,38,.7)}
  .nav--r a{font-size:1.05rem;padding:13px 0;width:100%;justify-content:space-between;border-bottom:1px solid rgba(139,123,106,.24)}
  /* The drawer is cream, but `.hdr .nav a` / `.hdr .tel` paint the overlay
     header's links cream until .stuck - so a drawer opened at the top of the
     page was cream-on-cream and read as blank. Match their specificity. */
  .hdr .nav--r a,.hdr.stuck .nav--r a{color:var(--ink)}
  .hdr .nav--r .tel,.hdr.stuck .nav--r .tel{color:var(--orchid-deep)}
  .navwrap--l{display:none}
  .navwrap--r{margin-left:0}
  .has-sub>a{padding-bottom:13px;margin-bottom:0}
  .sub,
  .nav--r .sub-menu,
  .nav--r .dropdown-menu{
    position:static;opacity:1;visibility:visible;transform:none;
    background:transparent;border:0;box-shadow:none;padding:0 0 8px 14px;
    max-height:0;overflow:hidden;transition:max-height .38s ease;
    min-width:0;
  }
  .has-sub.open .sub,
  .menu-item-has-children.open .sub-menu,
  .menu-item-has-children.open .dropdown-menu{max-height:340px}
  .sub a{font-size:.97rem;padding:9px 0;border-bottom:1px solid rgba(139,123,106,.14)}
  .tel{margin-top:20px;font-size:1.05rem}
  /* .hdr establishes a stacking context at z-index 70, so the drawer's own
     z-index 80 is scoped INSIDE it and resolves below the scrim's 75. The
     scrim therefore sat on top of the open drawer and swallowed every tap on a
     navigation link. Dropping the scrim beneath the header fixes it; the scrim
     still covers all page content, which is all it is for. */
  .scrim{position:fixed;inset:0;background:rgba(45,42,38,.5);opacity:0;visibility:hidden;transition:opacity .38s,visibility .38s;z-index:65}
  .scrim.on{opacity:1;visibility:visible}

  .hero{min-height:0;display:block;padding:0 0 var(--sec);background:var(--cream)}
  .hero .shot{position:relative;inset:auto;height:auto;aspect-ratio:5/4}
  .hero .shot img{height:119%;object-position:60% top}
  .hero-grid{width:auto;margin:0}
  .hero-plate{width:auto;margin:-58px var(--gut) 0;padding:24px 20px 22px;box-shadow:0 24px 54px -34px rgba(45,42,38,.5)}
  .hero h1{max-width:none}
  .hero-lead{max-width:none}

  .bio-cols,.tools-body{max-width:none}
  .close-plate{margin-top:clamp(-104px,-20vw,-64px);padding:24px 20px}
  .turn-steps{margin-left:0}
  .ftr-legal small{margin-left:0;width:100%}
  .pt{margin-left:0}
  .vwr{grid-template-columns:1fr;gap:0}
  .vwr-panel{display:none}
  .vwr-item.on{color:rgba(250,249,246,.62);padding-left:0}
  .vwr-item.on svg{opacity:0}

  /* inner pages */
  .svc-img-section{grid-template-columns:1fr}
  .svc-img-col img,.svc-img-col picture{position:relative;inset:auto;height:auto}
  .svc-img-col picture img{height:112%}
  .contact-grid{grid-template-columns:1fr}
}

/* A landscape phone is WIDE and SHORT — the shape a two-column layout suits.
   The bio grid collapses at ≤1024px, which would strand the portrait beside
   ~500px of dead space at 926px. Put the two-column form back. */
@media (hover:none) and (pointer:coarse) and (max-height:500px) and (min-width:820px){
  .bio-grid{grid-template-columns:minmax(0,1fr) minmax(0,320px)}
  .bio-photo{max-width:320px}
}

/* Touch devices — accessible minimum type. NEVER a `display` in this block: it
   would resurrect whatever the mobile block hid. Padding only. */
@media (hover:none) and (pointer:coarse){
  .fld label,.reach span,.ftr-legal a,.ftr-legal small,
  .bio-cap,.disclaim,.mark span,.pt,.set-label,.photo-credit{font-size:.9rem}
  /* .bio-cap .card-kind outranks .bio-cap, so it needs naming explicitly */
  .bio-cap .card-kind{font-size:.88rem}
  /* Bare <button> inherits the UA default of 13.33px and fails the 14px floor
     even though no stylesheet ever set a size. No !important and a bare
     element selector (0,0,1) — any real button class beats it, so this is a
     floor for the unstyled, never an override of the designed. */
  button,
  input[type="submit"],
  input[type="button"]{font-size:14px}
  /* Name-agnostic button floor. Every named rule depends on someone
     remembering to rename it; this one cannot be missed. No !important — a
     deliberate larger size on a variant must keep winning. */
  .btn,a.btn,button.btn{font-size:14px;min-height:44px;box-sizing:border-box}
  /* FAQ console controls — the chips and rows are the page's primary
     affordances, so they clear 44px and hold the 14px type floor. */
  .ac-chip{font-size:14px;min-height:44px}
  .ac-q{min-height:44px}
  .ac-tag{font-size:.9rem}
  .ac-field input{font-size:16px}
  /* every tap affordance clears 44px. Padding only. */
  .reach a{padding-top:11px;padding-bottom:11px}
  .ftr-legal a{padding:11px 0}
  .pt{padding-top:12px;padding-bottom:12px}
  .mark,.ftr .mark{padding:7px 0;min-height:44px;align-items:center}
  .vwr-item{padding-top:12px;padding-bottom:12px;min-height:44px}
  /* Blog card "Continue reading" link — reported at 144x28 by the viewport
     sweep, under the 44px tap-target floor. */
  .blog-more{min-height:44px;align-items:center}
  a[href^="tel:"],a[href^="mailto:"]{min-height:44px;padding:12px 0;display:inline-block;box-sizing:border-box}
  .nav a{min-height:44px}
  /* iOS ignores `fixed` silently and Android janks badly on it. One override
     per parallax band, declared separately so each `fixed` above is visibly
     answered here. */
  .bridge-photo .shot{background-attachment:scroll}
  .close-band .shot{background-attachment:scroll}
  /* WPForms — beat its 604-rule modern theme cascade */
  .wpforms-container .wpforms-field-label,
  .wpforms-container .wpforms-field-label.wpforms-field-label{font-size:14px!important;line-height:1.4!important}
  .wpforms-form .wpforms-submit,
  button[type="submit"].wpforms-submit{
    min-height:44px!important;height:auto!important;
    padding-top:12px!important;padding-bottom:12px!important;box-sizing:border-box!important;
  }
  /* Legal pages: inline links to third-party URLs need a real 44px tap box */
  body.page-privacy-policy .inner-body a,
  body.page-terms-and-conditions .inner-body a{
    display:inline-block;min-height:44px;padding:11px 0;line-height:1.4;box-sizing:border-box;
  }
}

@media (max-width:480px){
  .reach{gap:10px 18px}
  .inner-hero-content{padding:22px 18px}
}

/* ══════════════════ COLOUR ══════════════════ */
/* ── the divider, everywhere ───────────────────────────────────────────────
   Every rule that separates one thing from the next is the logo's own
   tri-partite bar: sage, clay, wildflower, hard-stopped at 3:2:1. It is one
   gradient rather than three elements, so the proportion is exact at any width
   and can never drift. */
.tri,
.hero-where,.roster,.turn-names,.tools,.reach,.ftr-legal{position:relative}
.hero-where::after,.roster::after,.turn-names::after,
.tools::after,.reach::after,.ftr-legal::after{
  content:"";position:absolute;left:0;right:0;height:3px;pointer-events:none;
  background:var(--spectrum);
}
.hero-where::after,.tools::after,.reach::after,.ftr-legal::after{top:0}
.roster::after,.turn-names::after{bottom:-1px}
/* the old flat hairlines they replace */
.hero-where{border-top:0}
.roster{border-bottom:0}
.turn-names{border-bottom:0}
.tools{border-top:0}
.reach{border-top:0}
.ftr-legal{border-top:0}

/* the hero closes on the spectrum. What looked like a charcoal rule there was
   the photograph's own shadowed foliage — the licence bar is cropped well
   above it (visible source rows stop at 641 of 738). */
.hero{position:relative}
.hero::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:4px;z-index:6;
  background:var(--spectrum);pointer-events:none;
}

/* and the header carries it once it sticks, in place of the grey hairline the
   box-shadow used to draw. It fades in with the rest of the stuck state. */
.hdr::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;z-index:1;
  background:var(--spectrum);
  opacity:0;transition:opacity .4s ease;pointer-events:none;
}
.hdr.stuck::after{opacity:1}
@media (prefers-reduced-motion:reduce){.hdr::after{transition:none}}

/* ── the button ────────────────────────────────────────────────────────────
   Sage, with the wildflower sweeping across it from the left rather than
   simply swapping colour. The sweep is a pseudo-element on transform only, so
   it stays on the compositor.

   The sweep's leading edge is raked rather than square, so the colour changes
   along a diagonal in the same family as the cut across the foot of the hero
   plate. The hero's own 3.4 degrees would be invisible on a 52px button — over
   that height it moves the edge barely 3px — so the rake opens to 14 degrees,
   leaning the same way the plate does.

   overflow:hidden clips the raked panel back to the button, and is safe here
   in a way clip-path would not be: overflow clips an element's DESCENDANTS,
   where clip-path clips the element itself, focus ring and all. */
.btn{position:relative;isolation:isolate;overflow:hidden;background:var(--sage-deep);color:var(--cream)}
.btn::before{
  content:"";position:absolute;top:-2px;bottom:-2px;left:-12%;width:124%;z-index:-1;
  background:var(--orchid-deep);
  transform:skewX(-14deg) scaleX(0);transform-origin:left center;
  transition:transform .5s cubic-bezier(.22,1,.36,1);
}
.btn:hover::before,.btn:focus-visible::before{transform:skewX(-14deg) scaleX(1)}
.btn:hover,.btn:focus-visible{background:var(--sage-deep);color:var(--cream)}
@media (prefers-reduced-motion:reduce){
  .btn::before{transition:none}
}

/* The tints give way to her colours at strength. The stories sit on a sage
   field, the closing on a wildflower one, and two whole sections reverse out
   of deep colour. Prose keeps a light ground everywhere it runs long — the
   mid-tones carry ink at about 9:1, so those grounds are properly coloured
   rather than merely tinted. */
.vgs{background:var(--sage-mid)}
.bio{background:var(--clay-mid)}
.outs{background:var(--orchid-mid)}
/* The closing section was reading as three stacked bands: a cream wave, then a
   strip of wildflower, then a sage form. Each was a flat fill with a hard edge
   against the next.

   It is now ONE field. The section carries a single top-to-bottom gradient
   that holds wildflower behind the wave and the plate, then eases into sage by
   the foot; the form no longer paints a ground of its own; and the wave takes
   its colour from CSS rather than a baked-in hex, so it dissolves into the
   gradient instead of sitting on top of it.

   The solid stop runs to 46% because the photograph band plus the plate occupy
   roughly the top half — the shift happens below them. */
.close{
  background:linear-gradient(to bottom,
    var(--orchid-tint) 0%,
    var(--orchid-tint) 46%,
    var(--sage-tint) 100%);
}
.close-curve{color:var(--orchid-tint)}
.frm-wrap{background:transparent}
.hdr.stuck{background:var(--sage-tint)}
.hdr.stuck .nav a:hover,.hdr.stuck .nav a:focus-visible{border-bottom-color:var(--orchid)}

.hero-plate::before{background:var(--sage-mid)}
.hero-who{color:var(--sage-deep)}

.vgs h2{color:var(--green-deep)}
/* Recolouring alone could not carry this. The inactive names are links and
   have to hold 4.5:1, which caps how far back they can be pushed — the widest
   luminance gap available between an accent that passes and an inactive that
   passes was 1.12:1, far too close to read as a state change.

   So the open one is FILLED instead: cream on wildflower, a 9.5:1 flip that
   cannot be missed, with the underline dropped since the fill already says
   it. The outcomes row is filled the same way. */
.roster-name{color:var(--clay-deep);border-radius:2px 2px 0 0}
.roster-name:hover{color:var(--plum)}
.roster-name.on{color:var(--cream);background:var(--plum)}
.roster-name.on::after{display:none}
.vg-slide .shot{box-shadow:0 26px 54px -34px rgba(49,64,42,.55)}
.turnline{color:var(--plum)}

.bridge-txt::before{background:var(--sage-mid)}
.bridge h2{color:var(--green-deep)}

.bio-txt h2,.bio-sub,.tools h3{color:var(--green-deep)}
.bio-cap{background:var(--sage-tint)}
.bio-photo .shot{box-shadow:0 24px 48px -30px rgba(78,68,55,.6)}

.svcs{background:var(--green-deep)}
.vwr-item.on,.set-label{color:#CBDCC0}

.outs h2{color:var(--plum)}
.turn-name{color:var(--clay-deep);border-radius:2px 2px 0 0}
.turn-name:hover,.turn-card b{color:var(--plum)}
.turn-name.on{color:var(--cream);background:var(--plum)}
.turn-name.on::after{display:none}
.turn-stage{background:var(--cream)}
.turn-step{border-color:rgba(92,52,89,.6);color:var(--plum)}
.turn-step:hover:not(:disabled),.turn-step:focus-visible{background:rgba(160,104,158,.2);border-color:var(--plum)}

.close-plate h2{color:var(--plum)}

.ftr{background:var(--plum)}
.ftr .mark span{color:#E6CFE4}
.pt:hover,.pt:focus-visible{border-color:#E6CFE4;background:rgba(230,207,228,.2)}

/* ══════════════════ AUDIT FIXES ══════════════════ */
/* ── animation: transform and opacity only ─────────────────────────────────
   Three rules were transitioning layout properties, which forces a reflow on
   every frame instead of staying on the compositor:
     .hdr        transitioned padding
     .vwr-item   transitioned padding-left
   Both become transforms. */
.hdr{transition:background .4s ease,box-shadow .4s ease}
.vwr-item{transition:color .35s,transform .35s cubic-bezier(.22,1,.36,1)}
.vwr-item.on,.vwr-item:hover,.vwr-item:focus-visible{padding-left:0;transform:translateX(12px)}
/* The drawer submenu keeps its max-height animation. grid-template-rows:0fr is
   the better technique in general, but it collapses only the FIRST row — and
   this submenu is three <li>, so the other two would stay at auto height and
   every submenu would be open the moment the drawer appeared. */
@media (prefers-reduced-motion:reduce){
  .vwr-item{transition:none}
  .sub{transition:none}
}

/* the tab panels are focusable for keyboard users, but should not draw a ring
   simply because they were scrolled to */
.vg-slide:focus{outline:none}
.vg-slide:focus-visible{outline:2.5px solid var(--orchid);outline-offset:4px}

/* ═══════════════════════════════════════════════════════════════════════════
   INNER PAGES
   The mockup is the homepage only. Everything below is the same design
   language applied to the inner pages: the plate, the 3:2:1 rule, the squared
   2px radius, the sage/clay/wildflower grounds.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── inner hero — a band, not a full-height stage ─────────────────────────
   height:clamp() rather than aspect-ratio + max-height: the latter has a
   WebKit bug where the container's WIDTH collapses to preserve the ratio when
   max-height clamps, leaving a gap beside the hero. */
.inner-hero{
  position:relative;background:var(--ink);
  height:clamp(360px,calc(32vw + 80px),500px);
  display:flex;align-items:flex-end;
  overflow:hidden;
}
.inner-hero .shot,.inner-hero-bg{position:absolute;inset:0;height:100%}
.inner-hero .shot img{filter:brightness(.82) saturate(1.02)}
.inner-hero::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:4px;z-index:6;
  background:var(--spectrum);pointer-events:none;
}
.inner-hero-content{
  position:relative;z-index:5;
  width:min(100% - (var(--gut)*2),var(--container));margin:0 auto;
  padding:0 0 clamp(26px,3.4vw,44px);
}
/* The title sits on its own plate rather than straight on the photograph —
   text on a photo gets a plate, never a bare scrim. */
/* The title card takes the same cut across its foot as the homepage hero
   plate, so the two are recognisably the same object at two sizes.

   Two things that matter here:
   - the shadow is a `filter: drop-shadow`, not a `box-shadow`. clip-path clips
     a box-shadow away with the rest of the box; drop-shadow follows the cut
     shape, which is the whole point.
   - the extra bottom padding is the cut's depth plus the normal padding, so
     the angle never runs into the last line of the title. */
.inner-page-title,.inner-hero-content h1{
  display:inline-block;margin:0;
  background:var(--cream);color:var(--green-deep);
  padding:clamp(14px,1.8vw,20px) clamp(18px,2.2vw,28px) calc(clamp(14px,1.8vw,20px) + 18px);
  border-radius:2px;
  clip-path:polygon(0 0,100% 0,100% calc(100% - 18px),0 100%);
  filter:drop-shadow(0 18px 30px rgba(45,42,38,.45));
  font-size:clamp(1.7rem,1.2rem + 2.1vw,2.7rem);
  max-width:min(100%,20ch);
}


/* ── Per-page hero framing ───────────────────────────────────────────────
   Each hero is cropped by object-fit:cover, so the Y offset decides what the
   band actually shows. These are tuned per photograph. */
body.page-couples-therapy .inner-hero .shot img{object-position:center 30%}
body.page-teen-therapy .inner-hero .shot img{object-position:center 35%}
/* contact/privacy-policy/terms-and-conditions/thank-you share one wide
   (1700x525) pre-cropped desk photo — its aspect is already close to the
   band's, so the default top object-position needs no per-page offset.
   individual-therapy uses its own hero-only.jpg (see inner-hero.php), also
   pre-cropped wide, so no offset needed there either. */

/* ── body ────────────────────────────────────────────────────────────────── */
.inner-content{padding:clamp(44px,5.4vw,72px) 0 clamp(40px,5vw,64px);background:var(--cream)}
.inner-body,.service-body{max-width:var(--service-body-max,1080px);margin:0 auto}
/* Prose sits at a readable measure. Without this a text-only block fills the
   full 1080px container at ~127 characters per line — about double what is
   comfortable — which is what makes a long section read as a wall regardless
   of how it is broken up. Headings keep the full width; only running text is
   constrained. */
.service-body > .svc-block > p,
.service-body > .svc-block > ul,
.service-body > .svc-block > ol{max-width:68ch}
.service-body h2{color:var(--green-deep);margin:0 0 .6em}
.service-body h3{color:var(--clay-deep);margin:0 0 .5em}
.service-body p{color:var(--ink-soft)}
.service-body em{font-style:italic}

/* Uniform section rhythm. The gap is declared ONCE, between siblings, and
   keyed on the WRAPPER — never on element type. A type-based rule can only
   space the shapes somebody remembered to enumerate, which is why "the padding
   between sections is never just standardized" recurs site after site. */
.service-body > .svc-block{margin:0}
.service-body > .svc-block + .svc-block{margin-top:var(--sec-gap)}
.service-body > .svc-block > *:first-child{margin-top:0}
.service-body > .svc-block > *:last-child{margin-bottom:0}
.service-body > .svc-block:first-child{margin-top:0}
.svc-img-section{margin:0}

/* Rule #7b — the COPY sets the height; the image fills it. In an
   align-items:stretch grid an in-flow <img> sizes the row to its own intrinsic
   height, so a short text column gets a towering photo beside it. Taking the
   image out of flow makes the copy authoritative at any length, with no
   per-page tuning. The min-height floor stops the opposite failure. */
.svc-img-section{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(24px,3.4vw,44px);align-items:stretch;
  min-height:clamp(240px,26vw,340px);
}
.svc-img-section--reverse .svc-text-col{order:2}
.svc-img-section--reverse .svc-img-col{order:1}
.svc-text-col{min-width:0;align-self:center}
.svc-img-col{min-width:0;position:relative;overflow:hidden;border-radius:2px;background:var(--taupe-tint)}
/* height:112% keeps the Shutterstock licence bar below the cut, exactly as
   .shot does on the homepage. */
.svc-img-col img,.svc-img-col picture{position:absolute;inset:0;width:100%;height:112%;object-fit:cover;object-position:center top}
.svc-img-col picture img{position:static;height:100%}
.svc-img-col{box-shadow:0 22px 46px -34px rgba(45,42,38,.5)}

/* editorial bands — white lead → cream middle → white resolution */
.svc-block.it-band{
  margin-inline:calc(50% - 50vw);width:100vw;background:var(--sage-tint);
  padding:calc(var(--sec-gap)/2) max(24px,calc(50vw - var(--service-body-max,1080px)/2));
}
.service-body > .svc-block.it-band + .svc-block.it-band{margin-top:0}
.svc-block.it-relief{background:transparent}
.it-strong{font-weight:700;font-style:normal;color:var(--ink)}
.svc-closing{color:var(--ink)}

/* ── About: the bio band is its own kind of thing ───────────────────────────
   Written as `.svc-block.about-band`, NOT `.about-band`. The section-rhythm
   rule `.service-body > .svc-block{margin:0}` is (0,2,0) and its `margin`
   SHORTHAND resets margin-inline, so a bare `.about-band` (0,1,0) loses and
   the band renders shifted a full padding-width to the right instead of
   full-bleed. Any future full-bleed block needs the compound selector too. */
.svc-block.about-band{
  margin-inline:calc(50% - 50vw);width:100vw;background:var(--clay-mid);
  padding:calc(var(--sec-gap)/2) max(24px,calc(50vw - var(--service-body-max,1080px)/2));
}
.about-band-in{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,340px);gap:clamp(26px,3.6vw,52px);align-items:start}
.about-portrait{position:sticky;top:clamp(96px,10vw,128px)}
.about-portrait .shot{aspect-ratio:4/5;border-radius:2px 2px 0 0}
.about-plate{background:var(--cream);border-radius:2px;padding:clamp(24px,3vw,38px);box-shadow:0 26px 52px -38px rgba(45,42,38,.5)}
@media (max-width:900px){
  .about-band-in{grid-template-columns:1fr}
  .about-portrait{position:static;max-width:340px}
}

/* ── FAQ — the Ask Console ────────────────────────────────────────────────
   Twenty-nine questions is too many to scroll, so this page is a tool rather
   than a document: a search field filters as you type, section chips narrow
   the field, and matches highlight in place.

   Every row is rendered server-side and merely HIDDEN by the filter, so the
   page works with no JavaScript and stays indexable — which is the whole point
   of writing 29 answers. */
.ac{max-width:860px;margin:0 auto}
.ac-bar{position:sticky;top:0;z-index:20;background:var(--cream);padding:14px 0 16px}
.ac-field{
  display:flex;align-items:center;gap:12px;position:relative;
  background:var(--cream-warm);border-radius:2px;padding:2px 16px;
}
/* the site's own tri-partite rule, drawing itself as the field takes focus */
.ac-field::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--spectrum);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .4s cubic-bezier(.22,1,.36,1);
}
.ac-field:focus-within::after{transform:scaleX(1)}
.ac-ico{position:relative;flex:0 0 auto;width:16px;height:16px;border:2px solid var(--sage-deep);border-radius:50%}
.ac-ico::after{content:"";position:absolute;right:-6px;bottom:-5px;width:8px;height:2px;
  background:var(--sage-deep);transform:rotate(45deg)}
.ac-field input{
  flex:1;min-width:0;border:0;background:none;outline:none;padding:16px 0;
  font-family:var(--f-head);font-size:1.06rem;font-weight:550;color:var(--ink);
}
.ac-field input::placeholder{color:var(--taupe-deep);font-weight:450}
.ac-field input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}

.ac-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:clamp(20px,2.4vw,30px)}
.ac-chip{
  background:none;border:1px solid rgba(139,123,106,.5);border-radius:2px;cursor:pointer;
  padding:8px 14px;font-family:var(--f-head);font-size:.84rem;font-weight:650;color:var(--taupe-deep);
  transition:background .25s,color .25s,border-color .25s;
}
.ac-chip:hover{border-color:var(--plum);color:var(--plum)}
.ac-chip.on{background:var(--plum);border-color:var(--plum);color:var(--cream)}
/* The running count is not shown — it read as clutter above the answers. It
   stays in the DOM as an aria-live region, because filtering a list is
   otherwise completely silent to a screen-reader user: they type, and nothing
   announces that the results changed. */
.ac-count{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

.ac-row{border-top:1px solid rgba(139,123,106,.35)}
.ac-row:last-child{border-bottom:1px solid rgba(139,123,106,.35)}
.ac-row[hidden]{display:none}
.ac-q{
  width:100%;display:flex;align-items:center;gap:14px;background:none;border:0;cursor:pointer;
  text-align:left;padding:clamp(22px,2.6vw,30px) 0;
  font-family:var(--f-head);font-weight:650;font-size:clamp(1rem,.95rem + .2vw,1.1rem);
  line-height:1.35;color:var(--ink);transition:color .25s;
}
.ac-q:hover{color:var(--plum)}
.ac-qt{min-width:0}
.ac-tag{
  margin-left:auto;flex:0 0 auto;font-size:.68rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--sage-deep);white-space:nowrap;
}
.ac-caret{
  flex:0 0 auto;width:9px;height:9px;
  border-right:2px solid var(--orchid);border-bottom:2px solid var(--orchid);
  transform:rotate(45deg) translateY(-2px);
  transition:transform .35s cubic-bezier(.22,1,.36,1);
}
.ac-row.open .ac-caret{transform:rotate(225deg) translateY(-2px)}
.ac-a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .4s cubic-bezier(.22,1,.36,1)}
.ac-row.open .ac-a{grid-template-rows:1fr}
.ac-a-in{overflow:hidden}
.ac-a-in > div{padding:0 0 clamp(24px,2.8vw,32px);max-width:64ch;color:var(--ink-soft);font-size:1.05rem;line-height:1.8}
.ac-row mark{background:var(--orchid-mid);color:var(--ink);padding:0 2px;border-radius:2px}
.ac-empty{margin-top:26px;color:var(--taupe-deep);font-style:italic}
@media (prefers-reduced-motion:reduce){
  .ac-a,.ac-caret,.ac-field::after{transition:none}
}
@media (max-width:560px){
  .ac-tag{display:none}
}

/* ── Contact ─────────────────────────────────────────────────────────────── */
.contact-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(28px,4vw,60px);align-items:start;
  max-width:var(--service-body-max,1080px);margin:0 auto;
}
.contact-card{background:var(--cream-warm);border-radius:2px;padding:clamp(24px,3vw,34px)}
.contact-card h2{color:var(--green-deep);margin-bottom:.5em}
/* The invitation and the direct contact details are two different offers, so
   they get real air between them rather than sitting as one run of text. */
.contact-card .svc-block{margin-bottom:clamp(30px,3.6vw,46px)}
.contact-line{display:block;margin:0 0 14px;font-family:var(--f-head);font-weight:670;font-size:1.04rem}
/* The email is the longest string in this card — without a wrap rule it
   runs past the card's right edge instead of staying inside the box. */
.contact-line a{text-decoration:none;transition:color .3s;overflow-wrap:anywhere;word-break:break-word}
.contact-line a:hover,.contact-line a:focus-visible{color:var(--orchid-deep)}
/* Nudged down from .95rem so the address clears the card at every desktop
   width without wrapping to a second line; still clears the 14px touch floor. */
.contact-note{color:var(--taupe-deep);font-size:.89rem;white-space:nowrap}

/* ── Blog ────────────────────────────────────────────────────────────────── */
.blog-list{max-width:var(--service-body-max,1080px);margin:0 auto}
.blog-meta{font-family:var(--f-head);font-size:.8rem;font-weight:650;letter-spacing:.14em;text-transform:uppercase;color:var(--taupe-deep);margin:0 0 10px}
/* Excerpts, never full posts. Generous leading so a card is a pleasure to
   skim rather than a block to wade through. */
.blog-excerpt p{color:var(--ink-soft);line-height:1.8;margin:0 0 .9em}
.blog-img{display:block;width:100%;height:112%;object-fit:cover;object-position:center top}

/* the lead post: photograph beside the copy, the newest piece given the room
   to actually be read */
.blog-lead{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  gap:clamp(24px,3.6vw,48px);align-items:center;
  padding-bottom:clamp(30px,3.6vw,46px);position:relative;
}
.blog-lead::after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--spectrum)}
.blog-lead__shot{
  display:block;aspect-ratio:4/3;border-radius:2px;
  box-shadow:0 26px 54px -36px rgba(45,42,38,.5);
}
.blog-lead__title{margin:0 0 .5em;color:var(--green-deep);font-size:clamp(1.6rem,1.24rem + 1.3vw,2.3rem)}
.blog-lead__title a{text-decoration:none}
.blog-lead__title a:hover{color:var(--plum)}

/* the run beneath */
.blog-grid{
  margin-top:clamp(32px,4vw,52px);
  display:grid;gap:clamp(24px,3vw,40px);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr));
}
.blog-card{min-width:0}
.blog-card__shot{
  display:block;aspect-ratio:16/10;border-radius:2px;margin-bottom:16px;
  box-shadow:0 20px 42px -30px rgba(45,42,38,.5);
}
.blog-card__title{margin:0 0 .5em;color:var(--green-deep);font-size:clamp(1.18rem,1.06rem + .5vw,1.44rem)}
.blog-card__title a{text-decoration:none}
.blog-card__title a:hover{color:var(--plum)}
@media (max-width:820px){
  .blog-lead{grid-template-columns:1fr}
}
.blog-more{display:inline-flex;align-items:center;gap:8px;margin-top:12px;font-family:var(--f-head);font-weight:700;font-size:.86rem;letter-spacing:.05em;color:var(--sage-deep);text-decoration:none;border-bottom:2px solid var(--sage);padding-bottom:2px}
.blog-more:hover,.blog-more:focus-visible{color:var(--orchid-deep);border-bottom-color:var(--orchid)}
.post-body{max-width:720px;margin:0 auto;font-size:1.12rem;line-height:1.85}
.post-body h2{color:var(--green-deep);margin:1.6em 0 .5em}
.post-body h3{color:var(--clay-deep);margin:1.4em 0 .45em}
.post-body blockquote{
  margin:1.6em 0;padding:0 0 0 22px;border-left:3px solid var(--orchid);
  font-size:1.2rem;font-style:italic;color:var(--ink);
}
.post-back{display:inline-flex;align-items:center;gap:8px;font-family:var(--f-head);font-weight:670;font-size:.88rem;color:var(--sage-deep);text-decoration:none}
.post-back:hover{color:var(--orchid-deep)}
.pagination{margin-top:clamp(30px,3.6vw,46px)}
.pagination ul{list-style:none;display:flex;flex-wrap:wrap;gap:8px;padding:0;margin:0}
.pagination a,.pagination span{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;border:1px solid rgba(139,123,106,.5);border-radius:2px;text-decoration:none;font-family:var(--f-head);font-weight:650}
.pagination .current{background:var(--plum);color:var(--cream);border-color:var(--plum)}

.post-back{margin-bottom:clamp(18px,2.2vw,26px)}
.post-body > .blog-meta{
  position:relative;padding-bottom:16px;margin-bottom:clamp(22px,2.6vw,32px);
}
/* the same tri-partite rule that divides every other section on the site */
.post-body > .blog-meta::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:3px;
  background:var(--spectrum);pointer-events:none;
}
/* Drop cap on the opening paragraph only. ::first-letter is ignored on an
   element whose display is not block-ish, so this is anchored on the <p>. */
.post-content > p:first-of-type::first-letter{
  float:left;font-family:var(--f-mark);font-weight:400;
  font-size:3.3em;line-height:.84;
  margin:.06em .12em 0 0;color:var(--plum);
  font-variation-settings:"SOFT" 60,"WONK" 1,"opsz" 96;
}
.post-content p{margin:0 0 1.15em}

.contact-form-wrap{min-width:0}
/* Contact form (form 53, Contact-page-only) nudged a little wider per client
   request — applied to the whole field container, not just the textarea, so
   every field (name/email/phone/message) and the submit button stay flush
   with each other instead of the message box alone sticking out past them.
   Scoped to the 2-col desktop layout, where .container has >=24px of
   right-side padding room to bleed into without risking viewport overflow;
   left off mobile to avoid an asymmetric right edge on the stacked
   single-column layout. */
@media (min-width:1025px){
  .contact-form-wrap .wpforms-container{width:calc(100% + 24px)!important;max-width:calc(100% + 24px)!important}
}

/* ── 404 ─────────────────────────────────────────────────────────────────── */
.nf-plate{max-width:640px;margin:0 auto;text-align:center;background:var(--cream);border-radius:2px;padding:clamp(28px,3.4vw,44px);box-shadow:0 30px 64px -40px rgba(45,42,38,.55)}
.nf-plate h1{color:var(--plum);font-size:clamp(1.7rem,1.2rem + 2vw,2.5rem)}
.nf-plate p{color:var(--ink-soft);margin-top:.9em}
.nf-acts{display:flex;flex-wrap:wrap;gap:14px;justify-content:center;margin-top:clamp(22px,2.6vw,30px)}

/* ── Legal pages: never fade in ──────────────────────────────────────────
   These bodies are 30–50KB walls of text. Wrapping them in a reveal makes the
   IntersectionObserver threshold unreachable (15% of a 10,000px element never
   enters the viewport), so .in never gets added and the page stays hidden. */
body.page-terms-and-conditions .reveal,
body.page-terms-and-conditions .fade-in,
body.page-privacy-policy .reveal,
body.page-privacy-policy .fade-in{
  opacity:1!important;transform:none!important;animation:none!important;transition:none!important;
}

/* A nav item carrying the `nav-hidden` class is built, styled and reachable by
   URL, but kept out of the menu. Used for the Blog: it ships complete so a
   future post drops straight in, and unhiding it is deleting one class in
   Appearance → Menus. */
.nav li.nav-hidden,
.nav-links > li.nav-hidden,
.mobile-menu li.nav-hidden{display:none}

/* ═══════════ MOBILE RESPONSIVE INVARIANTS — DO NOT REMOVE ═══════════
   Without these the wordmark pushes the burger off-screen and submenu items
   overflow on portrait phones. This is a WIDTH problem, not a touch problem,
   so it is deliberately outside the touch block. */
@media (max-width:900px){
  .mark{flex-shrink:1;min-width:0}
  .mark b{overflow-wrap:anywhere}
  .burger{flex:0 0 auto}
}
@media (max-width:768px){
  .nav li{white-space:normal}
  .sub,.sub li,.sub a,
  .nav .sub-menu,.nav .sub-menu li,.nav .sub-menu a,
  .nav .dropdown-menu,.nav .dropdown-menu li,.nav .dropdown-menu a{white-space:normal}
}
/* The mobile drawer's submenu <ul> can carry either class depending on which
   walker header.php uses. Target BOTH, always — walker choice has flipped
   site-by-site historically and CSS targeting one class breaks the other. */
.mobile-nav-links,
.mobile-nav-links ul,
.mobile-nav-links .sub-menu,
.mobile-nav-links .dropdown-menu{list-style:none!important;padding:0;margin:0}
.mobile-nav-links li,
.mobile-nav-links .sub-menu li,
.mobile-nav-links .dropdown-menu li{list-style:none!important}
