/* =========================================================================
   Digital Elements — New Mind Wellness
   Grove & Slate, signed off 2026-08-24.

   Order is load-bearing, do not reshuffle:
     1. @font-face        self-hosted, latin only
     2. :root tokens      the single source of every colour, size and rule
     3. reset
     4. layout
     5. primitives
     6. blocks            one band per block — added as blocks are built

   No render.php, template or partial may contain a literal hex value, font
   family or pixel size. If something is missing here, add a token.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. FONTS — self-hosted, latin subset, 178.6 KB across four files.
   No fonts.googleapis.com: no third-party origin in the critical path.

   Only the display face is preloaded (see de_preload_fonts()). Body text
   therefore swaps in late, so DM Sans gets a metric-matched local fallback
   below to stop that swap shifting the layout.
   ---------------------------------------------------------------------- */

@font-face{
  font-family:'Bricolage Grotesque';
  font-style:normal;
  font-weight:600 800;          /* variable: only 600 and 800 are used */
  font-display:swap;
  src:url('../fonts/bricolage-grotesque-var.woff2') format('woff2-variations');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face{
  font-family:'DM Sans';
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
  src:url('../fonts/dm-sans-var.woff2') format('woff2-variations');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* Kept deliberately: 174 <em>/<i> occurrences across 106 of 163 documents,
   and they are whole italicised CTA sentences and "Recommended:" cross-links,
   not just citation titles. Synthesised oblique would be visible everywhere. */
@font-face{
  font-family:'DM Sans';
  font-style:italic;
  font-weight:400;
  font-display:swap;
  src:url('../fonts/dm-sans-italic-var.woff2') format('woff2-variations');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face{
  font-family:'DM Mono';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('../fonts/dm-mono-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* The home hero's two faces, added with the hero revision. Static latin
   subsets, one weight each, 65.9 KB for all three — a variable axis buys
   nothing when exactly one weight is used.

   Cormorant Garamond is the hero display face and is preloaded alongside
   Bricolage (see de_preload_fonts): it sets the largest text on the page, so
   it is the LCP element on the front page. Both families are SIL Open Font
   License, which is what allows self-hosting them here rather than reaching
   for fonts.googleapis.com and putting a third party in the critical path. */
@font-face{
  font-family:'Cormorant Garamond';
  font-style:normal;
  font-weight:600;
  font-display:swap;
  src:url('../fonts/cormorant-garamond-600.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* The real italic, not a synthesised slant. The hero sets a whole sentence in
   it, and a faked oblique on a Garamond is obvious at 60px. */
@font-face{
  font-family:'Cormorant Garamond';
  font-style:italic;
  font-weight:600;
  font-display:swap;
  src:url('../fonts/cormorant-garamond-600-italic.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face{
  font-family:'Montserrat';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('../fonts/montserrat-500.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* Metric-matched fallback for DM Sans.
   Values measured from the real font binaries, not estimated:
     DM Sans  unitsPerEm 1000, xHeight 526, hhea asc 992 / desc -310 / gap 0
     Arial    unitsPerEm 2048, xHeight 1062, hhea asc 1854 / desc -434 / gap 67
   x-height ratios 0.5260 vs 0.5186 -> size-adjust 101.44%. The size-adjust is
   small; the real win is the ascent/descent override, because Arial's
   0.905/0.212 differs sharply from DM Sans's 0.992/0.310 and that gap is what
   moves the text when the webfont lands.
   Arial is the target because Helvetica is metrically compatible with it.
   Roboto on Android is close but not identical — a few tenths of a pixel. */
@font-face{
  font-family:'DM Sans Fallback';
  font-style:normal;
  font-weight:400 700;
  src:local('Arial'),local('Helvetica Neue'),local('Helvetica'),local('Roboto');
  size-adjust:101.44%;
  ascent-override:97.80%;
  descent-override:30.56%;
  line-gap-override:0%;
}

/* -------------------------------------------------------------------------
   2. TOKENS
   ---------------------------------------------------------------------- */

:root{
  /* ---- Palette ---- */
  --de-dark:         #0E2A35;  /* Deep Slate — hero/footer/dark bands */
  --de-dark-soft:    #16394A;  /* raised surface on dark */
  --de-brand:        #0086BE;  /* Signal Blue — logo blue, unchanged.
                                  Grounds, fills, card borders, focus rings and
                                  display type only. 4.07:1 — never body text. */
  --de-brand-light:  #7FD0F0;  /* Sky — on-dark accents, rules, eyebrows */
  --de-action:       #5F7A1E;  /* Grove — buttons. 4.90:1 w/ white = AA */
  --de-action-hover: #95B642;  /* existing button green, demoted to hover/on-dark */
  --de-paper:        #F6F8F7;  /* light band — tinted off-white, not cream */
  --de-ink:          #1B2A2F;  /* body text */
  --de-ink-mute:     #566A71;  /* meta, captions — 5.68:1 on white */
  --de-line:         #D6DEDC;  /* hairlines, input borders */
  --de-link:         #00729F;  /* Signal Deep — prose links. 5.37:1 on white,
                                  5.04:1 on Paper, so it clears AA at body size
                                  where --de-brand (4.07:1) cannot. */
  --de-white:        #FFFFFF;

  /* ---- Type ---- */
  /* Every heading on the site is the home hero's face. It was Bricolage
     Grotesque; the hero has been Cormorant since the type guide landed and
     the two faces disagreeing was the inconsistency. Weight is pinned by
     --de-fw-head below because only ONE Cormorant weight is loaded. */
  --de-font-head: 'Cormorant Garamond','Times New Roman',Times,serif;
  --de-font-body: 'DM Sans','DM Sans Fallback',system-ui,-apple-system,sans-serif;
  --de-font-util: 'DM Mono',ui-monospace,'SFMono-Regular',monospace;
  /* Home hero only. Kept separate from --de-font-head deliberately: the rest
     of the site still sets its headings in Bricolage, and widening these two
     beyond the hero is a redesign, not a tweak. */
  --de-font-hero:  'Cormorant Garamond','Times New Roman',Times,serif;
  --de-font-label: 'Montserrat','DM Sans Fallback',system-ui,sans-serif;

  /* The ONLY Cormorant weight on this site. Every heading that used to be
     800 reads this instead, so there is one place to change if a heavier
     cut is ever added to /fonts. */
  --de-fw-head:    600;

  --de-fs-display: clamp(34px, 4.2vw, 58px);
  --de-fs-h2:      clamp(26px, 2.6vw, 38px);
  --de-fs-h3:      clamp(20px, 1.7vw, 24px);
  --de-fs-body:    17px;
  --de-fs-small:   14px;
  --de-fs-eyebrow: 13px;

  /* Hero display: 60px is the signed-off desktop size, and the clamp is what
     keeps it from overflowing a phone. Tracking is expressed in em, not the
     -1px of the spec, so it stays proportional as the clamp scales — -0.017em
     IS -1px at 60px. Same for the label's 2px at 13px. */
  --de-fs-hero:    clamp(38px, 4.6vw, 60px);
  --de-lh-hero:    1;
  --de-tr-hero:    -0.017em;
  --de-tr-label:   0.154em;

  --de-lh-display: 1.06;
  --de-lh-head:    1.15;
  --de-lh-body:    1.62;
  --de-tr-display: -0.02em;
  --de-tr-eyebrow: 0.12em;

  /* ---- Rhythm ---- */
  --de-max-w:      1180px;   /* keep theme.json settings.layout.contentSize in sync */
  /* The header's own height. Declared once because two separate things need
     it: nothing today, and scroll-padding-top below, which has to clear a
     sticky header or every in-page jump lands underneath it. Kept in sync with
     .de-header__inner's min-height by hand — there are exactly two values. */
  --de-header-h:   88px;
  /* The closing CTA runs wider than the page measure on purpose: it is a
     full-bleed band with centred display type, not a column of prose. Sized to
     still clear the gutters at 1440. */
  --de-max-w-cta:  1360px;
  /* NOT 68ch. The ch unit is the advance of "0", and DM Sans sets a wide zero
     (0.687em), so 68ch resolves to 794px at 17px — wider than the content
     column itself, which meant the measure never applied and prose ran at ~87
     characters per line. 36rem = 576px lands at ~68 real characters. */
  --de-measure:    36rem;
  /* Long-form prose wants ~70 characters. Short marketing copy does not — a
     hero paragraph or a split intro at 36rem just gets taller for no reading
     benefit. 46rem is ~92 characters, fine for two or three sentences. */
  --de-measure-wide: 46rem;
  --de-gutter:     clamp(18px, 3vw, 32px);
  /* Was clamp(56px,7vw,96px). Measured on the migrated home page: 14 blocks
     paying padding top AND bottom came to 1728px of whitespace on their own.
     One gap per seam plus a tighter ceiling. */
  --de-section-y:  clamp(34px, 3.6vw, 52px);
  --de-rail-w:     320px;

  /* The measure for EVERY interior hero heading, in ch so it tracks the
     font size rather than a breakpoint. 27ch is ~773px at the 60px top of
     --de-fs-hero, which is a shade more than the widened panel offers, so
     in practice the panel governs on desktop and this stops the measure
     running away on a very wide screen. Raising it past the panel width
     does nothing; lower it to force earlier wraps. */
  --de-hero-measure: 39ch;

  /* Interior heroes only. The home hero keeps --de-fs-hero at 60px; these
     top out lower so a 75-character page title lands on two lines instead
     of three. Only the CAP moves - the 38px floor and the 4.6vw ramp are
     unchanged, so tablet and mobile render exactly as before. */
  --de-fs-hero-page: clamp(38px, 4.6vw, 48px);

  /* ---- Shape & depth ---- */
  --de-radius:     10px;
  --de-radius-sm:  6px;
  --de-shadow:     0 8px 32px rgba(14,42,53,.10);
  --de-transition: .2s ease;

  /* ---- Forms ---- */
  --de-input-h:      48px;
  --de-input-bg:     var(--de-paper);
  --de-input-border: 1px solid var(--de-line);
  --de-input-focus:  0 0 0 2px var(--de-brand);
  --de-error:        #B3261E;
}

/* -------------------------------------------------------------------------
   3. RESET
   ---------------------------------------------------------------------- */

*,*::before,*::after{box-sizing:border-box}

html{-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--de-white);
  color:var(--de-ink);
  font-family:var(--de-font-body);
  font-size:var(--de-fs-body);
  line-height:var(--de-lh-body);
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3,h4,h5,h6{
  font-family:var(--de-font-head);
  line-height:var(--de-lh-head);
  text-wrap:balance;
  margin:0;
}
h1{font-size:var(--de-fs-display);line-height:var(--de-lh-display);letter-spacing:var(--de-tr-display);font-weight:var(--de-fw-head)}
h2{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
h3{font-size:var(--de-fs-h3);font-weight:600}
/* h4-h6 had no size of their own, so they fell through to the browser's
   UA defaults, which are RELATIVE: against a 17px body that is h5 ~14px and
   h6 ~11.4px -- a heading rendering smaller than the paragraph under it.
   h4/h5 continue the ladder below h3. h6 is set to 25px BY REQUEST, which
   puts it above h3/h4/h5 -- deliberate, not an oversight. */
h4{font-size:clamp(19px, 1.4vw, 21px)}
h5{font-size:18px}
h6{font-size:25px}

p,ul,ol,figure,blockquote{margin:0}

img,svg,video,iframe{max-width:100%;height:auto;display:block}

/* Prose links: NO UNDERLINE AT ALL, at rest or on hover. Asked for twice,
   the second time after the trade-off below was put in writing, so this is a
   decision that was made rather than one that was missed.

   READ THIS BEFORE AN ACCESSIBILITY AUDIT. Inline links are now identified by
   colour and nothing else, which is the failure WCAG 1.4.1 names: Signal Deep
   #00729F against body ink #1B2A2F measures 2.72:1, and colour-alone links
   (technique G183) need 3:1 minimum AND a non-colour cue. Neither half is met
   now. Roughly one reader in twelve with a colour vision deficiency cannot
   reliably tell these links from the sentence around them, and there are 19 of
   them on a single treatment page.

   Keyboard focus is NOT part of this. The global :focus-visible ring below
   still outlines every link, so 2.4.7 holds — it is link identification that
   was traded away, not focus visibility.

   Two ways back, if an audit ever forces one, neither requiring an underline:
   a link colour at 3:1 or better against body ink while still clearing 4.5:1
   on white (they pull opposite ways — #0086BE reaches 3.61:1 against ink but
   drops to 4.07:1 on white and fails AA), or a non-colour cue such as setting
   inline links a weight heavier than the text around them. */
a{
  color:var(--de-link);
  text-decoration:none;
}

:focus-visible{outline:2px solid var(--de-brand);outline-offset:2px;border-radius:2px}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms!important;animation-duration:.01ms!important}
  html{scroll-behavior:auto}
}

/* -------------------------------------------------------------------------
   4. LAYOUT
   ---------------------------------------------------------------------- */

.de-wrap{max-width:var(--de-max-w);margin-inline:auto;padding-inline:var(--de-gutter)}
.de-band{padding-block:var(--de-section-y)}
.de-band--dark{background:var(--de-dark);color:var(--de-white)}
.de-band--paper{background:var(--de-paper)}
.de-band--white{background:var(--de-white)}

/* Interior page shell: prose at 68ch on the left, sticky rail on the RIGHT.
   The rail collapses when a page has no sidebar cards — see the Care Ladder
   decision in audit.txt.

   THE RAIL IS SECOND IN THE DOM, NOT REORDERED BY CSS. `order` or
   `grid-column` would have flipped it visually while leaving the rail first
   for a screen reader and for keyboard focus — the same WCAG 2.4.3 fault the
   Care Ladder refused to commit with column-reverse. Main content first in
   source, rail after it. The mobile rules further down still reorder, but
   they reorder to a different agreed layout rather than to paper over source
   order, and they set `order` on every item so DOM order is irrelevant there. */
.de-interior{
  display:grid;
  grid-template-columns:minmax(0,1fr) var(--de-rail-w);
  gap:clamp(30px,4.4vw,64px);
  align-items:start;
}
.de-interior--norail{grid-template-columns:minmax(0,1fr);justify-content:center}
@media (max-width:980px){
  /* minmax(0,1fr), NOT 1fr. A 1fr track takes `auto` as its minimum, so the
     widest grid item's min-content can expand it past the container. Once the
     rail became display:contents, the horizontal Care Ladder's 4 x min-width:132px
     leaked straight into the track and blew it out to 567px in a 390px viewport.
     It could not happen while the rail was a single grid item with its own
     overflow. */
  .de-interior{grid-template-columns:minmax(0,1fr)}
}

/* Not sticky. It followed the reader down the page and was asked to stop;
   the narrow-screen override that used to sit under this is gone with it,
   because static at every width is what it now is. */
.de-rail{display:flex;flex-direction:column;gap:16px}

/* The 68ch measure constrains TEXT, not the container. Constraining the
   container instead means any block that should be wider than prose — a gallery,
   a full-width band — cannot escape it. */
.de-prose{max-width:none;display:flex;flex-direction:column;gap:1.1em}
.de-prose > :where(p,ul,ol,h2,h3,h4,blockquote,figure,table){max-width:var(--de-measure)}
/*
 * A lede that runs the full column, centred.
 *
 * The reading measure above is deliberate and stays the default: body copy
 * capped at 36rem is why the prose is readable. But a page whose original
 * centres its opening paragraph across the full container cannot say so
 * without opting out of the measure, and /verify-insurance/ is that page —
 * the source sets text-align:center on a 1120px block with no max-width.
 * Opt-in per paragraph rather than a rule on the first child, because
 * "the first paragraph" is not what the treatment means.
 */
.de-prose > .de-lede{max-width:none;text-align:center}
.de-prose > * + h2{margin-top:.6em}
.de-prose > * + h3{margin-top:.3em}
/* DIRECT children only, and wrapped in :where() so this contributes no
   specificity. A descendant selector here (.de-prose ul) scores 0,1,1 and beats
   every single-class block rule — it silently forced .de-gallery__strip to
   flex-direction:column and stacked a 14-image scroll strip vertically, making
   the page 3x taller. Any block whose internals include a list is affected, so
   fix the cause rather than adding overrides per block. */
.de-prose > :where(ul,ol){padding-left:1.25em;display:flex;flex-direction:column;gap:.5em}
.de-accordion__body :where(ul,ol){padding-left:1.25em;display:flex;flex-direction:column;gap:.5em}

/* -------------------------------------------------------------------------
   5. PRIMITIVES
   ---------------------------------------------------------------------- */

.de-eyebrow{
  font-family:var(--de-font-util);
  font-size:var(--de-fs-eyebrow);
  letter-spacing:var(--de-tr-eyebrow);
  text-transform:uppercase;
  color:var(--de-ink-mute);
}
.de-band--dark .de-eyebrow{color:var(--de-brand-light)}

/* Buttons. Solid Grove = call, Solid Sky = verify insurance and navigate.
   THE OUTLINE BUTTON IS GONE. Both variants that used to be drawn as a border
   round transparent are now filled, on request, and they share one hover:
   Signal Deep with a white label. Anything added later that wants to be an
   outline is reopening a decision, not following one. */
.de-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  min-height:var(--de-input-h);padding:0 22px;
  border:1px solid transparent;border-radius:var(--de-radius-sm);
  font-family:var(--de-font-body);font-size:var(--de-fs-body);font-weight:600;
  /* Title case for every button, whatever an editor typed into the CTA field.
     capitalize only raises the first letter of each word and leaves the rest
     alone, so "PHP" and "IOP" in a Read More label survive intact. */
  text-transform:capitalize;
  text-decoration:none;cursor:pointer;
  transition:background var(--de-transition),color var(--de-transition),border-color var(--de-transition);
}
/* =========================================================================
   GLOBAL BUTTON SYSTEM - the two header buttons, everywhere.

   There are exactly two button roles on this site and every button resolves
   to one of them:

       PRIMARY    green   Verify Insurance, and any action button
       SECONDARY  blue    the phone number, and any navigation button

   Both are solid mid-tone fills with a white label, which is what lets this
   be global at all. The treatment they replace was an outline that turned
   invisible on Deep Slate, and the fix for that was a list of dark contexts
   that had to be kept up to date - it was missed five separate times. A fill
   that reads on white, on Paper and on Deep Slate needs no such list, so the
   per-context overrides that used to patch it are gone rather than ported.

   CONTRAST, MEASURED, BECAUSE IT IS NOT WHAT YOU WOULD WANT.
   The green is the header's rest colour and its white label is 2.32:1. AA
   wants 4.5:1 for a 17px label and 1.4.11 wants 3:1 for the control itself,
   so it misses both. Its own hover, #5F7A1E, is 4.90:1 and passes. Swapping
   the two - deeper green at rest, brighter on hover - fixes it, keeps both
   brand greens and is the more usual direction for a hover anyway. That is
   the two lines directly below and nothing else.
   The blue is 4.07:1: it passes 1.4.11 for the control, and misses AA for
   the label. Its hover, #00729F, is 5.37:1.
   ========================================================================= */
:root{
  /* Swap these two to fix the green label contrast. */
  --de-btn-primary-bg:         var(--de-action-hover);
  --de-btn-primary-hover-bg:   var(--de-action);

  --de-btn-primary-on:         var(--de-white);
  --de-btn-primary-hover-on:   var(--de-white);

  --de-btn-secondary-bg:       var(--de-brand);
  --de-btn-secondary-hover-bg: var(--de-link);
  --de-btn-secondary-on:       var(--de-white);
  --de-btn-secondary-hover-on: var(--de-white);
}

/* PRIMARY - green. Action buttons and the insurance CTA. */
.de-btn--solid,
.de-btn--verify{
  background:var(--de-btn-primary-bg);
  color:var(--de-btn-primary-on);
  border-color:var(--de-btn-primary-bg);
  font-weight:600;
}
.de-btn--solid:hover,
.de-btn--verify:hover,
.de-btn--solid:focus-visible,
.de-btn--verify:focus-visible{
  background:var(--de-btn-primary-hover-bg);
  color:var(--de-btn-primary-hover-on);
  border-color:var(--de-btn-primary-hover-bg);
}

/* SECONDARY - blue. The phone number and navigation buttons. */
.de-btn--call,
.de-btn--quiet{
  background:var(--de-btn-secondary-bg);
  color:var(--de-btn-secondary-on);
  border-color:var(--de-btn-secondary-bg);
  font-weight:600;
}
.de-btn--call:hover,
.de-btn--quiet:hover,
.de-btn--call:focus-visible,
.de-btn--quiet:focus-visible{
  background:var(--de-btn-secondary-hover-bg);
  color:var(--de-btn-secondary-hover-on);
  border-color:var(--de-btn-secondary-hover-bg);
}

/* One focus ring for every button. Two concentric rings rather than one,
   because a single ring can only be chosen for a light ground or a dark one:
   the white ring shows on Deep Slate, the dark ring shows on white, and one
   of the two is always the visible one. */
.de-btn:focus-visible{
  outline:3px solid var(--de-white);
  outline-offset:2px;
  box-shadow:0 0 0 6px var(--de-dark);
}

/* One active state for every button. */
.de-btn:active{transform:translateY(1px)}

/* SOLID, NOT OUTLINE. It was an outline in Sky and is now filled with it,
   Deep Slate label inside — 8.65:1, and it stops the second admissions CTA
   reading as the quieter of the two when it is the one that qualifies people.
   Hover DARKENS to Signal Deep and flips the label to white rather than
   emptying the fill: an outline hover would make the button look like it had
   been switched off. The label has to flip — Deep Slate on Signal Deep is
   2.6:1, so keeping it would trade a visible button for an unreadable one.

   The colours still come from INHERITED tokens, and every dark ground sets
   them once. Enumerating dark contexts per component
   (.de-band--dark .de-btn--verify, .de-footer .de-btn--verify, …) failed three
   times running — footer, CTA card, then the hero — each time rendering ink on
   Deep Slate, i.e. an invisible button. Inheritance means a new dark section
   only has to declare the tokens, and nested depth stops mattering.

   The fallbacks are for a light ground, where every one of these currently
   sits inside a dark one and so none of them render. --de-link, NOT --de-brand:
   white on #0086BE is 4.07:1 and this label is 17px/500, which is not large
   text, so --de-brand would fail AA the moment a verify button did land on
   Paper. --de-link is 5.37:1 and passes. */
/* The navigational variant, now drawn exactly like verify.
   "Take a Tour", "Mental Health Programs", "More FAQs" — links to another page
   rather than admissions actions. This was deliberately the quietest of the
   three so it could not compete with call and verify, and filling it ends that
   distinction: on a dark ground it is now pixel-identical to the verify button
   beside it. That was the instruction, and it is worth knowing it cost the
   hierarchy, because nothing in the markup will remind anyone later.

   It keeps its own token set rather than borrowing --de-verify-*, so giving
   navigation its own fill again is a two-line change here instead of an
   untangling. */
/* ONE APPEARANCE ON EVERY GROUND. The fallbacks below are now the same values
   the dark grounds pin, so this button is Sky with a Deep Slate label whether
   it sits on Deep Slate or on white. It used to fall back to a Signal Deep
   fill with a white label on light grounds, which is why the tour section's
   button did not match the one in the cards band.

   The cost is on white only, and it is a real one: Sky against #FFFFFF is
   1.72:1, where 1.4.11 wants 3:1 for the boundary of a control. The LABEL is
   fine anywhere — Deep Slate on Sky is 8.69:1 — it is the button's edge that
   goes soft. Giving it `border-color:var(--de-brand)` would take the edge to
   4.07:1 and settle it, at the price of a hairline the dark-ground version
   does not have. */
/* .de-home-hero was the FIFTH dark ground to be missed off that list, after
   the footer, the CTA card, the interior hero and the closing band. Each time
   the symptom was identical: near-black ink on Deep Slate, an outline button
   with nothing legible inside it.

   Inheriting tokens fixed the mechanism but not the real problem, which is
   that the list is an enumeration and an enumeration is never finished. The
   attribute below is the way out: a section declares its own ground at the
   point where its background is chosen, in the template, instead of being
   remembered in a stylesheet somewhere else. New dark sections should carry
   data-ground="dark" and nothing here needs editing again. */
/* LINKS on a dark ground, not just buttons. The programs band was the sixth
   time this class of bug appeared and the first time it was a link rather
   than a button: the card titles are anchors, so they took the prose
   treatment — ink text under a Signal Blue underline — and vanished into
   Deep Slate.

   Buttons are excluded because they carry their own colour, and so is
   anything that has already been given a colour by its own component. */
[data-ground="dark"] a:not(.de-btn),
.de-home-hero a:not(.de-btn){
  color:var(--de-white);
  text-decoration-color:var(--de-brand-light);
}
[data-ground="dark"] a:not(.de-btn):hover,
.de-home-hero a:not(.de-btn):hover{
  color:var(--de-brand-light);
}
@media (max-width:600px){.de-btn{width:100%}}

/* Sidebar cards — one system on Paper with a thin Signal Blue left border. */
.de-card{
  background:var(--de-paper);
  border:1px solid var(--de-line);
  border-left:3px solid var(--de-brand);
  border-radius:0 var(--de-radius) var(--de-radius) 0;
  padding:18px 18px 18px 17px;
}
.de-card__title{
  font-family:var(--de-font-util);font-size:12px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--de-ink-mute);margin-bottom:12px;
}
.de-card--cta{
  background:var(--de-dark);border-color:var(--de-dark);
  border-left-color:var(--de-brand-light);color:var(--de-white);
}
.de-card--cta .de-card__title{color:var(--de-brand-light)}

/* Forms — one rule set across all four Gravity Forms. */
.de-field{display:flex;flex-direction:column;gap:7px}
.de-field label{font-size:var(--de-fs-small);font-weight:500}
.de-field input,.de-field select,.de-field textarea{
  min-height:var(--de-input-h);padding:12px 13px;
  background-color:var(--de-input-bg);border:var(--de-input-border);
  border-radius:var(--de-radius-sm);
  font-family:var(--de-font-body);font-size:var(--de-fs-body);color:var(--de-ink);
  width:100%;
}
.de-field input:focus-visible,.de-field select:focus-visible,.de-field textarea:focus-visible{
  outline:none;box-shadow:var(--de-input-focus);border-color:var(--de-brand);
}
/* ---- <select>: one chevron, drawn once ---------------------------------
   THE BUG THIS FIXES. Gravity Forms sets appearance:none on its selects and
   supplies its own dropdown chevron as a background-image. The rules above
   used the `background` SHORTHAND, which does two things at once: it blanked
   that chevron at rest - so the control had no arrow and did not read as a
   dropdown at all - and it reset background-repeat to `repeat`. The moment GF
   re-applied its image on hover, at a specificity ours did not beat, a 12px
   chevron tiled across the whole field and struck through the label.

   So the fill is now background-COLOR, which leaves the image alone, and the
   chevron below is ours: stated once, no-repeat, positioned and sized, with
   padding-right to keep the text clear of it. Any image another stylesheet
   applies now lands on top of no-repeat rules and cannot tile.

   The hex inside the data URI is --de-ink-mute. A data URI cannot read a
   custom property, which is the one place on this sheet a literal is
   unavoidable; change both together. */
.de-field select,
.de-leadform .ginput_container select{
  -webkit-appearance:none;appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23566A71' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:12px 8px;
  padding-right:38px;
}

.de-field__error{font-size:13px;color:var(--de-error)}

/* Utility */
.de-mono{font-family:var(--de-font-util)}
.screen-reader-text{
  position:absolute!important;width:1px;height:1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;
}

/* -------------------------------------------------------------------------
   5b. HEADER & FOOTER
   Replaces Elementor HF #1165 / #1776.
   The 1200/1201px breakpoint is shared with de-header.js — change both together.
   Measured, not guessed: the six top-level items plus both CTAs and the logo need
   about 1075px of content width. A 1201px viewport yields ~1137px inside the
   gutters, which fits; 1101px yields ~1037px, which does not.
   ---------------------------------------------------------------------- */

.de-skip{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--de-dark);color:var(--de-white);
  padding:12px 18px;border-radius:0 0 var(--de-radius-sm) 0;
  text-decoration:none;font-size:var(--de-fs-small);
}
.de-skip:focus{left:0}

/* ---- header ---- */
/* STICKY, NOT FIXED.
   Sticky keeps the header in normal flow, so nothing below it needs a
   compensating margin and there is no content hidden under it at page load —
   the failure mode of position:fixed done in a hurry. It works here because
   .de-header is a direct child of <body> with no wrapper, and nothing in the
   ancestor chain sets overflow (the only overflow:hidden on <html> is the
   lightbox's scroll-lock, which is deliberate and temporary).

   z-index 50 is unchanged and still clears the page: the highest thing under it
   is z-index 1, the skip link at 100 stays above it on focus, and the lightbox
   is a native <dialog> in the top layer, above both. */
.de-header{
  background:var(--de-white);
  border-bottom:1px solid var(--de-line);
  position:sticky;top:0;z-index:50;
}
/* The admin bar is fixed at 783px and up, so a header stuck to top:0 would sit
   under it for every logged-in editor. Below 783px the bar is absolutely
   positioned and scrolls away, so the offset must NOT be applied there. */
@media screen and (min-width:783px){
  body.admin-bar .de-header{top:32px}
}
/* Every in-page jump — the rail's table of contents is the one that matters —
   now has to clear the header, or the heading it lands on is behind it. */
html{scroll-padding-top:calc(var(--de-header-h) + 12px)}
.de-header__inner{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  gap:clamp(14px,1.8vw,26px);
  min-height:88px;
}
.de-header__brand img,.de-header__brand .custom-logo{max-height:56px;width:auto}
.de-header__wordmark{
  font-family:var(--de-font-head);font-size:22px;font-weight:var(--de-fw-head);
  letter-spacing:-.015em;text-decoration:none;color:var(--de-ink);
}
.de-header__cta{display:flex;gap:10px;align-items:center}
.de-header__cta .de-btn{white-space:nowrap;padding:0 18px}

/* burger — hidden on desktop */
.de-header__burger{
  display:none;width:46px;height:46px;padding:0;
  background:transparent;border:1px solid var(--de-line);
  border-radius:var(--de-radius-sm);cursor:pointer;
  align-items:center;justify-content:center;
}
.de-header__burger-bars,
.de-header__burger-bars::before,
.de-header__burger-bars::after{
  display:block;width:20px;height:2px;background:var(--de-ink);
  border-radius:2px;transition:transform var(--de-transition),opacity var(--de-transition);
}
.de-header__burger-bars{position:relative;margin:0 auto}
.de-header__burger-bars::before,.de-header__burger-bars::after{content:"";position:absolute;left:0}
.de-header__burger-bars::before{top:-6px}
.de-header__burger-bars::after{top:6px}
.de-header--nav-open .de-header__burger-bars{background:transparent}
.de-header--nav-open .de-header__burger-bars::before{transform:translateY(6px) rotate(45deg)}
.de-header--nav-open .de-header__burger-bars::after{transform:translateY(-6px) rotate(-45deg)}

/* ---- nav ---- */
.de-nav__list,.de-nav__submenu{list-style:none;margin:0;padding:0}
.de-nav__list{display:flex;flex-wrap:nowrap;align-items:center;gap:0}
.de-nav__item{position:relative}
.de-nav__link{
  display:block;padding:9px 10px;white-space:nowrap;
  font-size:15px;font-weight:500;color:var(--de-ink);
  text-decoration:none;border-radius:var(--de-radius-sm);
  transition:color var(--de-transition),background var(--de-transition);
}
.de-nav__link:hover{color:var(--de-brand);background:var(--de-paper)}
.de-nav__item.current-menu-item > .de-nav__link{color:var(--de-action)}

/* Branch toggle — a real <button>, rendered by DE_Nav_Walker, not injected. */
.de-nav__toggle{
  position:absolute;top:50%;right:-2px;transform:translateY(-50%);
  width:26px;height:26px;padding:0;
  background:transparent;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
.de-nav__chev{
  width:7px;height:7px;
  border-right:2px solid var(--de-ink-mute);border-bottom:2px solid var(--de-ink-mute);
  transform:rotate(45deg) translateY(-1px);
  transition:transform var(--de-transition),border-color var(--de-transition);
}
.de-nav__toggle:hover .de-nav__chev{border-color:var(--de-brand)}
.de-nav__item--branch.is-open > .de-nav__toggle .de-nav__chev{transform:rotate(-135deg) translateY(-1px)}
.de-nav__empty{font-size:var(--de-fs-small)}

@media (min-width:1201px){
  /* Room for the chevron so it never overlaps the label. */
  .de-nav__item--branch.de-nav__item--depth-0 > .de-nav__link{padding-right:28px}

  .de-nav__submenu{
    position:absolute;top:100%;left:0;min-width:250px;
    background:var(--de-white);border:1px solid var(--de-line);
    border-top:2px solid var(--de-brand);
    border-radius:0 0 var(--de-radius) var(--de-radius);
    box-shadow:var(--de-shadow);padding:6px;
    opacity:0;visibility:hidden;transform:translateY(4px);
    transition:opacity var(--de-transition),transform var(--de-transition),visibility var(--de-transition);
  }
  /* Second level opens to the side rather than further down. */
  .de-nav__submenu .de-nav__submenu{
    top:-7px;left:100%;
    border-top:1px solid var(--de-line);border-left:2px solid var(--de-brand);
    border-radius:0 var(--de-radius) var(--de-radius) 0;
  }
  .de-nav__item--branch.is-open > .de-nav__submenu{
    opacity:1;visibility:visible;transform:translateY(0);
  }
  .de-nav__submenu .de-nav__link{padding:9px 34px 9px 12px;font-size:15px}
  /* ON DESKTOP THE ARROW POINTS AT THE PANEL, NOT AT ITS OWN STATE.
     Closed is down everywhere, from the base rule. What changes here is OPEN:

       top level  — stays DOWN. Its panel drops straight below the item, so
                    flipping to up would point away from the thing it opened.
       submenu    — turns RIGHT. That panel flies out to the side (left:100%
                    below), so right is where the reader should look.

     Neither is the base rule's up-when-open, and that is the point: up reads
     as "collapse me", which is right for an accordion and wrong for a menu
     whose panel is somewhere else on screen.

     SCOPED TO min-width:1201px ON PURPOSE. Under that the nav IS an accordion —
     items expand in place, downward — so the base down/up stays correct there
     and is deliberately left alone.

     The top-level open state is now visually identical to its closed state. The
     panel appearing is the feedback; aria-expanded on the toggle is what
     actually carries the state for assistive tech, and that is unchanged. */
  .de-nav__item--branch.is-open > .de-nav__toggle .de-nav__chev{
    transform:rotate(45deg) translateY(-1px);
  }
  .de-nav__submenu .de-nav__item--branch.is-open > .de-nav__toggle .de-nav__chev{
    transform:rotate(-45deg);
  }
}

@media (max-width:1200px){
  /* logo | spacer | call | burger */
  .de-header__inner{grid-template-columns:auto 1fr auto auto;min-height:72px;gap:10px}
  /* Matches the min-height directly above, so the anchor offset shrinks with
     the header instead of leaving 16px of dead space above every jump target. */
  :root{--de-header-h:72px}
  .de-header__burger{display:flex;order:3;justify-self:end}
  .de-header__brand{order:1}
  .de-header__brand img,.de-header__brand .custom-logo{max-height:44px}

  /* The call button stays in the header at every width — it is the primary
     conversion action on the site and must not be behind a menu. Verify moves
     into the panel, where there is room to label it properly. */
  .de-header__cta{display:flex;order:2}
  .de-header__cta .de-btn--verify{display:none}
  .de-header__cta .de-btn--call{padding:0 14px;font-size:15px;min-height:42px}
  .de-header--nav-open .de-header__cta{
    grid-column:1 / -1;flex-direction:column;align-items:stretch;
    padding-top:14px;padding-bottom:16px;border-top:1px solid var(--de-line);
  }
  .de-header--nav-open .de-header__cta .de-btn--verify{display:inline-flex}
  .de-header--nav-open .de-header__cta .de-btn--call{display:none}

  /* The primitives set .de-btn{width:100%} below 600px, which is right for
     buttons in content but blows the header grid past the viewport and pushes
     the burger off-screen. Header CTAs stay intrinsic — except inside the open
     panel, where full width is what we want. */
  .de-header__cta{min-width:0}
  .de-header__cta .de-btn{width:auto}
  .de-header--nav-open .de-header__cta .de-btn{width:100%}

  @media (max-width:400px){
    .de-header__cta .de-btn--call{padding:0 10px;font-size:14px}
    .de-header__brand img,.de-header__brand .custom-logo{max-height:38px}
  }

  /* Explicit order for all four children so nothing collides:
     1 brand · 2 call · 3 burger · 4 nav panel · 5 panel CTAs */
  .de-nav{
    order:4;grid-column:1 / -1;display:none;padding-bottom:6px;
    max-height:calc(100vh - 160px);overflow-y:auto;
  }
  .de-header--nav-open .de-nav{display:block}
  .de-header--nav-open .de-header__cta{order:5}

  .de-nav__list{display:block}
  .de-nav__link{padding:13px 0;font-size:17px;border-bottom:1px solid var(--de-line)}
  .de-nav__toggle{right:0;width:46px;height:46px;top:2px;transform:none;border-left:1px solid var(--de-line)}

  /* Accordion: closed until de-header.js adds .is-open.

     Depth used to be carried by a 16px indent and nothing else, so a parent
     and its children read as one flat list. A child now sits on a tinted
     ground, indents further, and takes a smaller label than its parent --
     three signals instead of one. The brand rail marks the FIRST level only;
     deeper levels drop to a hairline so the colour does not repeat down the
     tree and every level stays distinguishable from the one above it. */
  .de-nav__submenu{
    display:none;padding-left:20px;padding-block:2px;
    border-left:2px solid var(--de-brand);
    background:var(--de-paper);
  }
  .de-nav__item--branch.is-open > .de-nav__submenu{display:block}
  .de-nav__submenu .de-nav__link{font-size:15px;padding-block:11px}
  .de-nav__submenu .de-nav__item:last-child > .de-nav__link{border-bottom:0}
  .de-nav__submenu .de-nav__submenu{
    border-left-color:var(--de-line);background:transparent;
  }
  .de-nav__submenu .de-nav__submenu .de-nav__link{font-size:14px}
}

/* ---- footer ---- */
.de-footer{
  background:var(--de-dark);color:#C9DAE1;
  padding-block:clamp(44px,6vw,76px) 0;
  font-size:var(--de-fs-small);
}
.de-footer__grid{
  display:grid;grid-template-columns:1.4fr 1fr 1fr 1.15fr;
  gap:clamp(26px,3.4vw,52px);align-items:start;
}
@media (max-width:980px){.de-footer__grid{grid-template-columns:1fr 1fr}}
@media (max-width:600px){.de-footer__grid{grid-template-columns:1fr}}

.de-footer__col{display:flex;flex-direction:column;gap:14px;min-width:0}
.de-footer__heading{
  font-family:var(--de-font-util);font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--de-brand-light);font-weight:400;
}
.de-footer__desc{line-height:1.7;max-width:40ch}
.de-footer__desc p{margin:0 0 .7em}
.de-footer__col--brand img,.de-footer__col--brand .custom-logo{max-height:52px;width:auto}
.de-footer__logo{display:inline-block;text-decoration:none;border:0}
.de-footer__logo img{max-height:52px;width:auto}

/* Link lists.
   The live footer put a "»" glyph beside every link, which reads as decoration
   rather than affordance. Replaced by a left border that appears and insets the
   link on hover — the movement is the affordance, so no glyph is needed. */
.de-footer__links ul,
.de-footer__band-links ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.de-footer__links li,
.de-footer__band-links li{margin:0}
.de-footer__links a,
.de-footer__band-links a{
  display:block;padding:6px 0;padding-left:0;
  color:#C9DAE1;text-decoration:none;border-left:2px solid transparent;
  transition:padding-left var(--de-transition),border-color var(--de-transition),color var(--de-transition);
}
.de-footer__links a:hover,
.de-footer__links a:focus-visible,
.de-footer__band-links a:hover,
.de-footer__band-links a:focus-visible{
  border-left-color:var(--de-brand-light);padding-left:12px;color:var(--de-white);
}

/* Contact */
.de-footer__contact{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:13px}
.de-footer__label{
  display:block;font-family:var(--de-font-util);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:#7FA0AD;margin-bottom:3px;
}
.de-footer__contact a{color:var(--de-white);text-decoration:none;border-bottom:1px solid rgba(127,208,240,.4)}
.de-footer__contact a:hover{border-bottom-color:var(--de-brand-light);color:var(--de-brand-light)}
.de-footer__address{font-style:normal;color:var(--de-white);line-height:1.6}
.de-footer__cta{align-self:flex-start;margin-top:4px}

/* Social — labelled dots, no icon font */
.de-footer__social{list-style:none;margin:4px 0 0;padding:0;display:flex;gap:10px}
.de-footer__social-link{
  display:flex;width:38px;height:38px;align-items:center;justify-content:center;
  border:1px solid rgba(127,208,240,.34);border-radius:50%;text-decoration:none;
  transition:background var(--de-transition),border-color var(--de-transition);
}
.de-footer__social-dot{width:9px;height:9px;border-radius:50%;background:var(--de-brand-light);transition:background var(--de-transition)}
.de-footer__social-link:hover{background:var(--de-brand-light);border-color:var(--de-brand-light)}
.de-footer__social-link:hover .de-footer__social-dot{background:var(--de-dark)}

/* Base bar */
.de-footer__base{
  margin-top:clamp(32px,4vw,54px);
  border-top:1px solid rgba(255,255,255,.13);
  padding-block:20px 24px;
  display:flex;flex-wrap:wrap;gap:8px 20px;align-items:center;justify-content:space-between;
  font-family:var(--de-font-util);font-size:12px;color:#7FA0AD;
}
.de-footer__policy{color:#7FA0AD;text-decoration:none;border-bottom:1px solid rgba(127,160,173,.4)}
.de-footer__policy:hover{color:var(--de-brand-light);border-bottom-color:var(--de-brand-light)}


/* ---- generic page (placeholder until the page-type templates land) ---- */
.de-page{display:flex;flex-direction:column;gap:22px}
.de-page__title{max-width:var(--de-measure)}

/* ---- the bare page template ---------------------------------------------
   Privacy Policy, Opt-out preferences and the QA form use .de-page rather
   than the interior template, so they carry no rail — the prose column is the
   full 1116px. .de-prose still caps every child at the 36rem reading measure,
   which left a 576px block of text with 540px of empty page beside it.

   The interior template answers this with --norail; this one never gets that
   class. Widen to the wide measure the theme already uses for ledes and plain
   heroes, and cap the h1 with it so the heading and the copy share one left
   edge. Ranged left, like every other page — centring here would only break
   that alignment.
   -------------------------------------------------------------------- */
.de-page .de-prose > :where(p,ul,ol,h1,h2,h3,h4,blockquote,figure,table){
  max-width:var(--de-measure-wide);
}
.de-crumb{
  font-family:var(--de-font-util);font-size:12px;letter-spacing:.06em;
  color:var(--de-ink-mute);
}
.de-crumb a{color:var(--de-ink-mute);text-decoration-color:var(--de-line)}
.de-prose > .de-accordion,
.de-prose > .de-sources{margin-block:.6em}


/* -------------------------------------------------------------------------
   5c. INTERIOR PAGE — hero, rail cards, closing CTA
   ---------------------------------------------------------------------- */

/* ---- hero: asymmetric split, Deep Slate panel, image bleeding right ---- */
.de-hero{background:var(--de-dark);color:var(--de-white);overflow:hidden}
/* .68fr, not .8fr: the panel needs 848px for the heading to hold 760px of
   measure, and the media is object-fit:cover so it crops rather than
   squashes. Both columns are minmax(0,...) so neither can be forced wider
   than its share by its content. */
.de-hero__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.47fr);align-items:stretch}
.de-hero__panel{
  padding-left:max(var(--de-gutter),(100% - var(--de-max-w))/2);
  padding-right:clamp(24px,4vw,56px);
  padding-block:clamp(38px,5.5vw,72px);
  display:flex;flex-direction:column;gap:16px;justify-content:center;min-width:0;
}
/* Same two faces as the home hero, so a visitor moving from the front door to
   a treatment page meets one voice rather than two. The roles map across
   cleanly: the eyebrow is the small label, the h1 is the display line.

   font-family and font-weight are stated OUTRIGHT on the title. The bare h1
   rule up in the reset hands every h1 --de-font-head at weight 800, and this
   set neither, so without both declarations the interior headings would have
   quietly stayed Bricolage while the home page moved to Cormorant. */
.de-hero__eyebrow{
  font-family:var(--de-font-label);font-size:var(--de-fs-eyebrow);
  font-weight:500;
  letter-spacing:var(--de-tr-label);text-transform:uppercase;
  color:var(--de-brand-light);
}
/* LINE HEIGHT IS NOT THE HOME HERO'S 1.
   The front door sets two short, hand-picked lines with nothing below the
   baseline. Interior h1s are long clinical phrases that run to three lines and
   are full of descenders - "Partial Hospitalization Program (PHP)
   Philadelphia" carries p and g twice over - and Cormorant descends further
   than Bricolage did. At 1 those lines touch. --de-lh-display is 1.06, already
   on the sheet, and the extra 6% is what a Garamond's depth costs. */
.de-hero__title{
  font-family:var(--de-font-hero);
  font-size:var(--de-fs-hero-page);
  font-weight:600;
  line-height:var(--de-lh-display);
  letter-spacing:var(--de-tr-hero);
  max-width:var(--de-hero-measure);
}
.de-hero__desc{color:#DCE8ED;max-width:48ch}
.de-hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px}

/* Swapped emphasis — the two roles trade type treatments and nothing else.
   Both sides read the same tokens the unswapped hero uses, so "display" and
   "eyebrow" each have one definition on the site rather than three. The
   source order is swapped in the template, not here: reordering in CSS would
   put the reading order out of step with the visual one, which is the bug
   that was fixed in the care ladder. */
.de-hero--swap .de-hero__title{
  font-family:var(--de-font-label);font-size:var(--de-fs-eyebrow);
  letter-spacing:var(--de-tr-label);text-transform:uppercase;
  line-height:1.5;font-weight:500;max-width:none;color:var(--de-brand-light);
}
.de-hero--swap .de-hero__eyebrow{
  font-family:var(--de-font-hero);font-size:var(--de-fs-hero-page);
  line-height:var(--de-lh-display);letter-spacing:var(--de-tr-hero);
  text-transform:none;font-weight:600;max-width:var(--de-hero-measure);color:var(--de-white);
}

.de-hero__media{position:relative;min-height:320px;background:var(--de-dark-soft)}
.de-hero__img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center;
}
/* Gradient scrim so the panel type never sits on a busy edge of the photo. */
.de-hero__media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,var(--de-dark) 0%,rgba(14,42,53,.55) 14%,rgba(14,42,53,0) 46%);
}

/* Optional trust badge over the interior hero photo, the counterpart of
   .de-home-hero__badge. It needs a stacking context because ::after is painted
   after the image and would otherwise cover it. No page sets a badge today, so
   nothing below draws until an editor adds one. */
.de-hero__badge{
  position:absolute;z-index:1;
  right:clamp(12px,2vw,24px);bottom:clamp(12px,2vw,24px);
  max-width:min(200px,42%);
}
.de-hero__badge img{width:100%;height:auto;display:block}
.de-hero__badge-link{display:inline-block;border-radius:var(--de-radius-sm)}
.de-hero__badge-link:focus-visible{outline:3px solid var(--de-brand-light);outline-offset:4px}
@media (max-width:880px){
  .de-hero__badge{max-width:min(150px,38%);right:12px;bottom:12px}
}

@media (max-width:880px){
  .de-hero__grid{grid-template-columns:1fr}
  .de-hero__media{min-height:200px;order:-1}
  .de-hero__media::after{background:linear-gradient(0deg,var(--de-dark) 0%,rgba(14,42,53,.15) 60%)}
  .de-hero__panel{padding-inline:var(--de-gutter);padding-block:clamp(26px,6vw,40px)}
  .de-hero__title{max-width:none}
}

/* ---- breadcrumb (Yoast output, wrapped by de_breadcrumbs) ---- */
.de-hero .de-crumb,.de-hero .de-crumb a{color:#8FB6C4}
.de-hero .de-crumb a{text-decoration:none;border-bottom:1px solid rgba(143,182,196,.4)}
.de-hero .de-crumb a:hover{color:var(--de-brand-light);border-bottom-color:var(--de-brand-light)}
.de-hero .de-crumb .breadcrumb_last{color:var(--de-white)}

/* ---- interior main column ---- */
.de-interior__main{min-width:0}

/* ---- rail: TOC card ---- */
.de-toc{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px;counter-reset:de-toc}
.de-toc a{
  display:grid;grid-template-columns:26px minmax(0,1fr);gap:9px;align-items:baseline;
  padding:7px 8px;margin-inline:-8px;border-radius:var(--de-radius-sm);
  text-decoration:none;color:var(--de-ink);font-size:var(--de-fs-small);line-height:1.45;
  transition:background var(--de-transition),color var(--de-transition);
}
.de-toc a::before{
  counter-increment:de-toc;content:counter(de-toc,decimal-leading-zero);
  font-family:var(--de-font-util);font-size:11px;color:var(--de-ink-mute);
}
.de-toc a:hover{background:var(--de-white);color:var(--de-brand)}

/* ---- rail: Care Ladder ----
   DOM order == visual order, most intensive first. No column-reverse: reversing
   visually while leaving DOM order intact walks keyboard focus up the visible
   list, which fails WCAG 2.4.3. */
.de-ladder{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.de-rung{display:grid;grid-template-columns:22px minmax(0,1fr);gap:12px;padding:9px 0;align-items:center}
.de-rung + .de-rung{border-top:1px solid var(--de-line)}
.de-rung__mark{width:5px;height:20px;border-radius:3px;background:var(--de-line);justify-self:center}
.de-rung--here .de-rung__mark{background:var(--de-action);height:26px}
.de-rung--off .de-rung__mark{background:transparent;border-left:1px dashed var(--de-line);width:0;border-radius:0}
.de-rung__body{min-width:0}
.de-rung__name{display:block;font-size:var(--de-fs-small);font-weight:500;line-height:1.35;color:var(--de-ink);text-decoration:none}
/* Hover is the colour shift alone now; the underline came out with the rest. */
a.de-rung__name:hover{color:var(--de-brand);text-decoration:none}
.de-rung--here .de-rung__name{color:var(--de-action);font-weight:700}
.de-rung--off .de-rung__name{color:var(--de-ink-mute)}
.de-rung__meta{
  display:block;font-family:var(--de-font-util);font-size:11px;
  color:var(--de-ink-mute);letter-spacing:.03em;margin-top:2px;
}

/* ---- mobile: the rail disperses, per the agreed layout ----
   TOC collapses to a <details> at the top, the reviewed byline goes inline
   under the H1, and the CTA moves to the end of the content.

   display:contents promotes the rail's children to grid items of .de-interior
   so each one can be ordered independently. No duplicated markup and no
   second copy of the TOC for screen readers to read twice.

   THE ORDER VALUES MATCH DESKTOP'S CARD ORDER, deliberately: reviewed, TOC,
   ladder, then the content, then the CTA. They used to run reviewed, ladder,
   TOC — mobile said one thing and desktop another for the same three cards,
   which was never a decision, just two orders written at different times. The
   card SET per page type is signed off in audit.txt; the sequence was not.

   Only `order` values changed, not the treatments: the ladder is still the
   horizontal progression and the TOC is still a collapsed disclosure. And no
   page currently renders both cards — the ladder is on the Level of Care pages
   and none of those carry a reviewer — so this is aligning the rule ahead of
   the case that would expose it, not fixing a visible defect. */
@media (max-width:980px){
  .de-rail{display:contents}
  /* Promoted grid items need an explicit floor too, or min-width:auto lets any
     one card set the width of the whole column. */
  .de-rail__reviewed,.de-rail__ladder,.de-rail__toc,.de-rail__cta{min-width:0}
  /* Still explicit on all five even though reviewed/TOC/ladder now sit in this
     order in the DOM: .de-interior__main comes FIRST in source (it is the rail
     that moved after it), so `order` is what pulls the content back below the
     cards. Leaving the three cards to source order and only ordering main
     would work today and break the moment a card is added anywhere but the end. */
  .de-rail__reviewed{order:1}
  .de-rail__toc{order:2}
  /* The CTA sits directly under the table of contents rather than at the end
     of the article. It was last on the page, which on a 2,000-word interior
     meant a reader had to reach the bottom before being offered the call - the
     one action the page exists for. Above the fold-ish and immediately after
     the TOC is where it was asked to go. */
  .de-rail__cta{order:3}
  .de-rail__ladder{order:4}
  .de-interior__main{order:5}

  /* Byline, not a card: it sits immediately under the hero H1. */
  .de-rail__reviewed{
    background:transparent;border:0;border-top:1px solid var(--de-line);
    border-bottom:1px solid var(--de-line);border-radius:0;padding:12px 0;
  }
  .de-rail__reviewed .de-card__title{display:none}
  .de-rail__reviewed .de-reviewed{flex-direction:row;flex-wrap:wrap;gap:4px 10px;align-items:baseline}
  .de-rail__reviewed .de-reviewed__name::after{content:" ·";color:var(--de-ink-mute)}

  /* Care Ladder reads as a horizontal progression on a narrow screen. */
  .de-rail__ladder .de-ladder{flex-direction:row;overflow-x:auto;gap:0}
  .de-rail__ladder .de-rung{
    grid-template-columns:1fr;grid-template-rows:auto auto;gap:6px;
    padding:0 14px;min-width:132px;border-top:0;
  }
  .de-rail__ladder .de-rung + .de-rung{border-top:0;border-left:1px solid var(--de-line)}
  .de-rail__ladder .de-rung__mark{width:100%;height:4px;justify-self:stretch}
  .de-rail__ladder .de-rung--here .de-rung__mark{height:4px}
  .de-rail__ladder .de-rung--off .de-rung__mark{
    width:100%;height:0;border-left:0;border-top:1px dashed var(--de-line);
  }
}

/* Desktop: <details> is forced open by de-interior.js, so hide the marker and
   stop it looking clickable. */
@media (min-width:981px){
  .de-rail__toc > summary{list-style:none;cursor:default;pointer-events:none}
  .de-rail__toc > summary::-webkit-details-marker{display:none}
  .de-rail__toc > summary::marker{content:""}
}
@media (max-width:980px){
  .de-rail__toc > summary{
    cursor:pointer;display:flex;align-items:center;justify-content:space-between;
    margin-bottom:0;list-style:none;
  }
  .de-rail__toc > summary::-webkit-details-marker{display:none}
  .de-rail__toc > summary::after{
    content:"";width:9px;height:9px;flex:none;
    border-right:2px solid var(--de-link);border-bottom:2px solid var(--de-link);
    transform:rotate(45deg) translateY(-2px);transition:transform var(--de-transition);
  }
  .de-rail__toc[open] > summary::after{transform:rotate(-135deg) translateY(2px)}
  .de-rail__toc[open] > summary{margin-bottom:12px}
}

/* ---- rail: Medically reviewed ---- */
.de-reviewed{display:flex;flex-direction:column;gap:3px}
.de-reviewed__name{font-size:var(--de-fs-small);font-weight:700}
.de-reviewed__meta{font-family:var(--de-font-util);font-size:11.5px;color:var(--de-ink-mute);letter-spacing:.03em;line-height:1.6}

/* ---- rail: CTA card ---- */
.de-card__cta-title{font-size:19px;font-weight:var(--de-fw-head);line-height:1.2;margin-bottom:8px;color:var(--de-white)}
.de-card__cta-text{font-size:var(--de-fs-small);color:#C9DAE1;margin-bottom:14px}
.de-card__cta-btn{width:100%}

/* ---- closing CTA band ---- */
.de-closing__inner{display:flex;flex-direction:column;gap:16px;align-items:flex-start;max-width:var(--de-measure)}
.de-closing__title{color:var(--de-white);font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-closing__text{color:#C9DAE1}
.de-closing__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:4px}

/* -------------------------------------------------------------------------
   6. BLOCKS — one band per block, added as each is built.
   ---------------------------------------------------------------------- */

/* Editor-only placeholder for a block with no content yet. */
.de-block-empty{
  font-family:var(--de-font-util);font-size:var(--de-fs-small);
  color:var(--de-ink-mute);background:var(--de-paper);
  border:1px dashed var(--de-line);border-radius:var(--de-radius-sm);
  padding:14px 16px;
}

/* ---- de-accordion ----
   Replaces two inconsistent treatments with one. Hairline dividers inside a
   single bordered group, a chevron that rotates rather than swapping glyph,
   and the title in the display face at h3 so a long accordion still scans. */
.de-accordion{display:flex;flex-direction:column;gap:18px;max-width:var(--de-measure)}
.de-accordion__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-accordion__group{
  border:1px solid var(--de-line);border-radius:var(--de-radius);overflow:hidden;
}
.de-accordion__item + .de-accordion__item{border-top:1px solid var(--de-line)}
.de-accordion__summary{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:16px 20px;cursor:pointer;list-style:none;
  transition:background var(--de-transition);
}
.de-accordion__summary::-webkit-details-marker{display:none}
.de-accordion__summary:hover{background:var(--de-paper)}
.de-accordion__summary:focus-visible{outline:2px solid var(--de-brand);outline-offset:-2px}
.de-accordion__title{
  font-family:var(--de-font-head);font-size:var(--de-fs-h3);font-weight:600;
  line-height:var(--de-lh-head);
}
.de-accordion__chev{
  width:11px;height:11px;flex:none;
  border-right:2px solid var(--de-brand);border-bottom:2px solid var(--de-brand);
  transform:rotate(45deg) translateY(-2px);
  transition:transform var(--de-transition);
}
.de-accordion__item[open] .de-accordion__chev{transform:rotate(-135deg) translateY(2px)}
.de-accordion__body{padding:10px 20px 18px}
.de-accordion__body > * + *{margin-top:.9em}

/* ---- de-sources ----
   Reference apparatus, so it is mono-numbered and sits quieter than prose. */
.de-sources{display:flex;flex-direction:column;gap:14px;max-width:var(--de-measure)}
.de-sources__heading{
  font-family:var(--de-font-util);font-size:var(--de-fs-eyebrow);
  letter-spacing:var(--de-tr-eyebrow);text-transform:uppercase;
  color:var(--de-ink-mute);font-weight:400;
}
.de-sources__list{
  list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:10px;
  counter-reset:de-src;
  border-top:1px solid var(--de-line);padding-top:14px;
}
.de-sources__item{
  display:grid;grid-template-columns:30px minmax(0,1fr);gap:10px;
  font-size:var(--de-fs-small);line-height:1.6;
}
.de-sources__item::before{
  counter-increment:de-src;content:"[" counter(de-src) "]";
  font-family:var(--de-font-util);font-size:12px;color:var(--de-brand);
  font-variant-numeric:tabular-nums;
}
.de-sources__title{font-style:normal;color:var(--de-ink);grid-column:2}
/* grid-column:2 is required, not decorative: ::before takes column 1 and cite
   column 2, so without it the publisher wraps onto the next row into the 30px
   counter column and breaks one word per line. */
.de-sources__publisher{grid-column:2;display:block;color:var(--de-ink-mute)}

/* ---- de-gallery ----
   Interactive without a carousel library: a scroll-snap strip. Native momentum
   scrolling, keyboard-scrollable via the tabindex on the list, and nothing to
   break when a slider plugin is removed. */
.de-gallery{display:flex;flex-direction:column;gap:18px;max-width:var(--de-max-w)}
.de-gallery__head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.de-gallery__nav{display:flex;gap:8px}
.de-gallery__btn{
  width:40px;height:40px;padding:0;flex:none;
  background:var(--de-white);border:1px solid var(--de-line);
  border-radius:var(--de-radius-sm);cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:border-color var(--de-transition),background var(--de-transition);
}
.de-gallery__btn:hover:not(:disabled){border-color:var(--de-link);background:var(--de-paper)}
.de-gallery__btn:disabled{opacity:.35;cursor:default}
.de-gallery__btn span{
  width:9px;height:9px;
  border-right:2px solid var(--de-ink);border-bottom:2px solid var(--de-ink);
}
.de-gallery__btn--prev span{transform:rotate(135deg) translate(-1px,-1px)}
.de-gallery__btn--next span{transform:rotate(-45deg) translate(-1px,-1px)}
.de-gallery__count{font-family:var(--de-font-util);font-size:12px;color:var(--de-ink-mute)}
.de-gallery__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-gallery__strip{
  list-style:none;margin:0;padding:0 0 8px;
  display:grid;grid-auto-flow:column;
  grid-auto-columns:min(78%,420px);
  gap:14px;
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  scrollbar-color:var(--de-line) transparent;
}
.de-gallery__strip:focus-visible{outline:2px solid var(--de-brand);outline-offset:4px;border-radius:var(--de-radius)}
.de-gallery__item{scroll-snap-align:start;margin:0}
.de-gallery__item img{
  width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;
  border-radius:var(--de-radius);background:var(--de-paper);
}
.de-gallery__cta{margin:0}
@media (max-width:600px){
  .de-gallery__strip{grid-auto-columns:min(88%,340px)}
  .de-gallery__cta .de-btn{width:100%}
}

/* ---- de-reviews ----
   min-height reserves the space the widget will occupy, so deferring the loader
   does not trade a render-blocking script for a layout shift. */
.de-reviews{display:flex;flex-direction:column;gap:18px;max-width:var(--de-max-w)}
.de-reviews__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
/* 360px, not 260 — measured in a real browser with the live widget. A short
   reservation is worse than none: it trades a blocking script for the layout
   shift it was meant to prevent. Released once the widget is in, so a narrow
   viewport is not stuck with a desktop-sized floor. */
.de-reviews__mount{min-height:360px;display:flex;align-items:center;justify-content:center}
.de-reviews__mount.is-mounted{min-height:0;display:block;align-items:initial}
.de-reviews__mount.is-mounted .de-reviews__placeholder{display:none}
.de-reviews__placeholder{
  font-family:var(--de-font-util);font-size:var(--de-fs-small);
  color:var(--de-ink-mute);text-align:center;
}

/* ---- home page rhythm ----
   ONE gap per seam, not padding on both sides of every block. Bands that paint a
   background keep their own symmetric padding, because a dark band with no top
   padding reads as broken; everything in the flow just gets the gap. */
/* NO container gap. A flex gap puts page background between every child,
   which is invisible between two white sections and very visible either side
   of a full-bleed coloured band — it printed a white strip between the dark
   hero and the dark callback band, where the original runs them flush.

   So every section owns its own vertical space instead: the bleed bands
   already did, and the centred ones get half above and half below, which
   still totals one section-y between two of them. */
/* BLOCK, not flex, and the choice is load-bearing.

   A flex gap put page background between every child, which was invisible
   between two white sections and very visible either side of a coloured band
   — a white strip between the dark hero and the dark callback band, where the
   original runs them flush.

   Removing the gap fixed that and created the opposite fault: a band's own
   padding sits INSIDE its colour, so where a band met a white section the
   visible separation was half what it was between two white sections. 25.92
   against 51.84.

   Margin collapse resolves both, and flex containers do not collapse margins.
   As a block: two white sections collapse their margins to one section-y,
   a band and a white section get the white one's full margin, and two bands
   have no margin at all so they stay flush. One rule, three correct answers. */
.de-home{display:block}

/* Full-bleed bands: own width, own internal padding. */
.de-home > .de-home-hero,
/* ONE CLASS, NOT A LIST OF SECTION NAMES.

   This was four grouped selectors and a five-:not() exclusion list naming
   every section that bleeds. It is the same shape as the dark-ground
   enumeration that failed five times before data-ground replaced it, and it
   was one section away from failing the same way: anything bled that forgot
   to add itself to the :not() list got the flow margin AND its own padding.

   Every bleeding block now emits `de-bleed` at the point its background is
   chosen, in its own template, so nothing here needs editing again. */
.de-home > .de-bleed{
  width:100%;max-width:none;
  margin-block:0;padding-inline:0;
}
/* The vertical padding is the band's, EXCEPT where a block owns its own — the
   FAQ panels carry 50px inside each half and the contact panels carry theirs
   inside each third, as the originals do. A second helping from here would
   show a strip of page background above and below panels meant to run flush.

   Keyed on a class the block DECLARES, not on its name. `:not(.de-faq--panel)`
   was how the bleed list started the first time. */
.de-home > .de-bleed:not(.de-bleed--flush){padding-block:var(--de-section-y)}

/* Everything else is centred in the container with no vertical padding — the
   flex gap already spaces it. */
.de-home > :not(.de-home-hero):not(.de-bleed){
  width:100%;max-width:var(--de-max-w);
  margin-inline:auto;padding-inline:var(--de-gutter);
  /* MARGIN, not padding — padding cannot collapse, and collapsing is the
     whole point: it is what makes the gap between two of these equal to the
     gap between one of them and a band. */
  margin-block:var(--de-section-y);
}
/* First and last need no outer margin — the band above and the footer below
   already own that space. */
.de-home > :first-child{margin-block-start:0}
.de-home > :last-child{margin-block-end:0}

/* ==== HOME BLOCKS ==================================================== */

/* Blocks that own a full-bleed band manage their own vertical rhythm; the ones
   that sit inside the flow get it from .de-home > * spacing in front-page.php. */

/* ---- de-hero (home) ---- */
.de-home-hero{background:var(--de-dark);color:var(--de-white);overflow:hidden;position:relative}
/* Photo hero: the image is a background layer with a Deep Slate scrim over it,
   because the copy has to stay readable regardless of what the photo does.
   The scrim is opaque enough that white text clears AA on the darkest and
   lightest parts of the image alike. */
.de-home-hero--photo::before{
  content:"";position:absolute;inset:0;
  background-image:var(--de-hero-bg);background-size:cover;background-position:center;
}
.de-home-hero--photo::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(100deg,rgba(14,42,53,.94) 0%,rgba(14,42,53,.86) 42%,rgba(14,42,53,.62) 100%);
}
.de-home-hero > *{position:relative;z-index:1}
.de-home-hero__badge{align-self:end;justify-self:end;max-width:260px}
.de-home-hero__badge img{width:100%;height:auto}
@media (max-width:880px){.de-home-hero__badge{justify-self:start;align-self:start;max-width:200px}}
.de-home-hero__grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.85fr);
  gap:clamp(24px,4vw,56px);align-items:center;
  padding-block:clamp(40px,6vw,84px);
}
.de-home-hero__copy{display:flex;flex-direction:column;gap:16px;min-width:0}
/* HOME HERO TYPE — two ROLES, not two elements.

   One line is the display line and the other is the label above it, and
   .de-home-hero--swap decides which element plays which. So each role is
   written once, against both selectors that can carry it, rather than the
   treatment being duplicated per element. The swapped selectors are (0,2,0)
   against the unswapped (0,1,0), so the modifier wins on specificity and the
   pair is order-independent.

   This is the ONLY place these two faces are used. The paragraph below the
   heading is deliberately untouched — it stays DM Sans at body size. */
.de-home-hero__title,
.de-home-hero--swap .de-home-hero__sub{
  font-family:var(--de-font-hero);
  font-size:var(--de-fs-hero);
  font-weight:600;
  line-height:var(--de-lh-hero);
  letter-spacing:var(--de-tr-hero);
  color:var(--de-white);
  max-width:20ch;
  text-transform:none;
}
.de-home-hero__sub,
.de-home-hero--swap .de-home-hero__title{
  font-family:var(--de-font-label);
  font-size:var(--de-fs-eyebrow);
  font-weight:500;
  line-height:1.5;
  letter-spacing:var(--de-tr-label);
  text-transform:uppercase;
  color:var(--de-brand-light);
  max-width:none;
}

/* The second sentence finishes the line in italic Grove.

   Grove-on-hover is the palette's on-dark green and this is an on-dark use, so
   no new hex enters the sheet. It is a block so the two sentences always break
   where the design breaks them instead of wherever the measure happens to run
   out, and the rule is scoped to the display role — in the unswapped hero the
   subheading is the small label, where an italic green sentence would read as
   a mistake. The <span> is built in render.php, which also decides where the
   sentence boundary is. */
.de-home-hero--swap .de-home-hero__sub .de-home-hero__accent{
  display:block;
  font-style:italic;
  color:var(--de-action-hover);
}
.de-home-hero__body{color:#DCE8ED;max-width:var(--de-measure-wide)}
.de-home-hero__body p + p{margin-top:.8em}
.de-home-hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px}
.de-home-hero__media img{width:100%;height:auto;border-radius:var(--de-radius)}
@media (max-width:880px){
  .de-home-hero__grid{grid-template-columns:1fr}
  .de-home-hero__media{order:-1}
  .de-home-hero__title{max-width:none}
}

/* ---- de-split ---- */
/* 50/50, WHICH IS WHAT THE SOURCE SPECIFIES. Every two-column section on the
   original home page is structure:20 with both columns at 50% — About, Stigma,
   the tour, the FAQ, the contact band. This was built at .66/1 to stop "About
   Our Mental Health Programs" wrapping to two lines, which live holds on one.
   That reasoning was sound and the conclusion was wrong: live holds it on one
   line because its heading is Questrial at 33px and ours is Bricolage at 37px,
   so the fix was compensating for our own larger type by shrinking the photo to
   two thirds of the copy. The photo is the half of this section that was paying
   for it — 421px against 639px, and 282px tall against 435px of copy.

   The heading is allowed to wrap instead. Two lines of h2 is not a defect; a
   picture two thirds the size of the text beside it reads as a mistake. */
.de-split__grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(24px,4vw,56px);align-items:center;
}
.de-split--media-right .de-split__media{order:2}
.de-split__media img{width:100%;height:auto;border-radius:var(--de-radius);box-shadow:var(--de-shadow)}
/* ORDER MATTERS BELOW THIS LINE. The stretch rules are the same specificity
   as the base image rule above (0,2,0), so placed before it the base
   height:auto simply won and the photo went back to its natural height. */
/* SIZE AND MARGINS EQUAL, LITERALLY. Stretching the row makes the photo exactly
   as tall as the copy beside it, so the two halves start and finish on the same
   lines and there is no leftover margin to be uneven. Scoped above the stack
   breakpoint: once the columns are stacked there is nothing to match, and a
   height:100% image in an auto-height row collapses. */
@media (min-width:821px){
  .de-split__grid{align-items:stretch}
  .de-split__media{display:flex}
  .de-split__media img{
    height:100%;object-fit:cover;
    /* Floor, so a short copy column cannot squash the photo into a letterbox. */
    min-height:300px;
  }
}
.de-split__copy{display:flex;flex-direction:column;gap:12px;min-width:0}
.de-split__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-split__body{max-width:var(--de-measure-wide)}
.de-split__body p + p,.de-split__body ul{margin-top:.8em}
.de-split__body ul{padding-left:1.25em;display:flex;flex-direction:column;gap:.5em}
.de-split__cta{margin-top:4px}
@media (max-width:820px){
  .de-split__grid{grid-template-columns:1fr}
  .de-split--media-right .de-split__media{order:0}
}

/* ---- de-cards ---- */
.de-cards{display:flex;flex-direction:column;gap:clamp(16px,2vw,24px)}
.de-cards__head{display:flex;flex-direction:column;gap:12px;max-width:var(--de-measure-wide)}
.de-cards__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-cards__intro{color:var(--de-ink)}
.de-cards__grid{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(var(--de-cards-cols,3),minmax(0,1fr));
  gap:clamp(16px,2vw,26px);
}
.de-card-item{
  display:flex;flex-direction:column;gap:10px;min-width:0;
  background:var(--de-paper);border:1px solid var(--de-line);
  border-radius:var(--de-radius);padding:20px;
}
.de-cards--image .de-card-item{padding:0;overflow:hidden}
.de-cards--image .de-card-item > :not(.de-card-item__media){padding-inline:20px}
.de-cards--image .de-card-item > :last-child{padding-bottom:20px}
.de-card-item__media img{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover}
.de-card-item__title{font-size:var(--de-fs-h3);font-weight:600;line-height:var(--de-lh-head)}
.de-cards--image .de-card-item__title{margin-top:16px}
.de-card-item__title a{color:var(--de-ink);text-decoration-color:var(--de-link)}
.de-card-item__title a:hover{color:var(--de-link)}
.de-card-item__body{font-size:var(--de-fs-small);color:var(--de-ink-mute);line-height:1.65}
.de-cards__cta{margin:0}
@media (max-width:900px){.de-cards__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:600px){.de-cards__grid{grid-template-columns:1fr}}

/* ---- de-insurance ----
   Base shape only. The carousel, the centring, the arrows and the CTA live
   further down under "de-insurance, carousel + centred". The old row rules
   were REMOVED rather than overridden: this selector set
   grid-template-columns, the carousel rule sets grid-auto-columns, and at
   equal specificity the template value would have survived and pinned the
   track to a wrapping row. */
.de-insurance{display:flex;flex-direction:column;gap:18px;align-items:flex-start}
.de-insurance__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em;max-width:var(--de-measure-wide)}

/* ---- de-team ---- */
.de-team{display:flex;flex-direction:column;gap:18px}
.de-team__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
/* auto-FILL with a max, not auto-fit with 1fr: three members were stretching to
   360px each, so a 1/1 photo became a 360px-tall square. */
.de-team__grid{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,244px));
  gap:clamp(14px,2vw,24px);
}
.de-team__member{display:flex;flex-direction:column;gap:8px;min-width:0}
.de-team__photo img{
  width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;
  border-radius:var(--de-radius);background:var(--de-paper);
}
.de-team__name{font-size:var(--de-fs-h3);font-weight:600;margin-top:6px}
.de-team__name a{color:var(--de-ink);text-decoration-color:var(--de-link)}
.de-team__name a:hover{color:var(--de-link)}
.de-team__role{
  font-family:var(--de-font-util);font-size:12px;letter-spacing:.04em;
  text-transform:uppercase;color:var(--de-ink-mute);
}
.de-team__cta{margin:0}

/* ---- de-faq (shares the accordion band) ---- */
.de-faq{display:flex;flex-direction:column;gap:18px;max-width:var(--de-measure-wide)}
.de-faq__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-faq__cta{margin:0}

/* ---- de-lead-form ---- */
/* Heading ABOVE a full-width form, which is how the original was composed. Side
   by side the form only got ~55% of the width, fields stacked one per row, and
   the two form sections alone came to 1844px. Full width pairs them up. */
.de-leadform__inner{display:flex;flex-direction:column;gap:clamp(16px,2vw,26px)}
.de-leadform__copy{max-width:var(--de-measure-wide)}
.de-leadform__copy{display:flex;flex-direction:column;gap:12px;min-width:0}
.de-leadform__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-leadform--dark .de-leadform__heading{color:var(--de-white)}
.de-leadform--dark .de-leadform__intro{color:#C9DAE1}
.de-leadform__form{
  background:var(--de-white);border:1px solid var(--de-line);
  border-radius:var(--de-radius);padding:clamp(18px,2.4vw,28px);box-shadow:var(--de-shadow);
  /* The card is white whatever the band behind it, so its contents have to be
     ink. Gravity Forms gives its own colour to labels, inputs and the button,
     but not to the confirmation message it swaps in after a submit — on the
     dark homepage band that message inherited .de-band--dark's white and was
     invisible against this card. Setting the colour here covers the
     confirmation and anything else GF renders without one. */
  color:var(--de-ink);
}

/* Gravity Forms, styled through the tokens rather than rebuilt — submissions,
   notifications and entry history stay exactly as they are. One rule set for all
   four forms, which was the audit's ask. */
.de-leadform .gform_wrapper form{display:flex;flex-direction:column;gap:14px}
/* Gravity Forms 3 lays fields out on its OWN 12-column grid and its selector
   beats a single-class rule, so the auto-fit grid that used to be here never
   applied — the fields were already pairing correctly. What DOES need
   overriding is the 40px row gap, which was adding ~200px per form. Four class
   levels so this wins regardless of stylesheet order, without !important. */
.de-leadform .de-leadform__form .gform_wrapper .gform_fields{
  row-gap:18px;
  column-gap:16px;
}
.de-leadform .gfield{display:flex;flex-direction:column;gap:7px;min-width:0}
.de-leadform .gfield_label{font-size:var(--de-fs-small);font-weight:500;color:var(--de-ink)}
.de-leadform .gfield_required{color:var(--de-error);margin-left:2px}
.de-leadform .ginput_container input[type=text],
.de-leadform .ginput_container input[type=email],
.de-leadform .ginput_container input[type=tel],
.de-leadform .ginput_container input[type=number],
.de-leadform .ginput_container select,
.de-leadform .ginput_container textarea{
  width:100%;min-height:var(--de-input-h);padding:12px 13px;
  background-color:var(--de-input-bg);border:var(--de-input-border);
  border-radius:var(--de-radius-sm);
  font-family:var(--de-font-body);font-size:var(--de-fs-body);color:var(--de-ink);
}
.de-leadform .ginput_container textarea{min-height:120px}
/* The rule above sets `padding` shorthand and sits after the shared select
   rule, so it was resetting the right padding the chevron needs. Restated
   here, after it, rather than reordering the sheet. */
/* Vertical padding OFF for selects, and the height left to min-height.
   Something outside this sheet's readable cascade gives the select a 38px
   line-height; with 12px of padding top and bottom that leaves a 22px content
   box, and a 38px line box inside a 22px box is clipped - which is why the
   option label lost its descenders. Zero vertical padding turns the content
   box back into the full 46px, so any line-height fits and the browser centres
   it natively. Horizontal padding is restated because `padding` is a shorthand. */
.de-leadform .ginput_container select,
.de-field select{
  padding-top:0;padding-bottom:0;
  padding-left:13px;padding-right:38px;
  line-height:1.2;
}
.de-leadform .ginput_container input:focus-visible,
.de-leadform .ginput_container select:focus-visible,
.de-leadform .ginput_container textarea:focus-visible{
  outline:none;box-shadow:var(--de-input-focus);border-color:var(--de-brand);
}
.de-leadform .gfield_description,.de-leadform .gform_description{
  font-size:12.5px;color:var(--de-ink-mute);line-height:1.5;
}
/* Consent / legal copy: readable, but it should not set the height of the form. */
.de-leadform .gfield--type-consent,
.de-leadform .gfield--type-checkbox{font-size:12.5px;line-height:1.4}
.de-leadform .gfield--type-checkbox .gfield_label{margin-bottom:2px}
.de-leadform .gchoice{margin-block:2px}
.de-leadform .gfield--type-consent label,
.de-leadform .gfield--type-checkbox label{font-weight:400}

/* A consent label whose link text is a full URL cannot wrap: the URL is one
   unbreakable token, so the label grows past its grid cell, past the form and
   past the viewport, and the whole PAGE gains a horizontal scrollbar. The SMS
   consent field on the home page did exactly that -- 366px of label inside a
   301px cell, 60px of page overflow on a 375px screen.

   `anywhere` rather than `break-word`: it lets the browser break the long URL
   only at the point it actually overflows, and it counts toward min-content so
   the flex and grid parents stop reserving room for the unbroken string.
   Ordinary words are untouched. Scoped to labels and their links so nothing
   else in a form can be broken mid-word. */
.gform_wrapper .gform-field-label,
.gform_wrapper .gform-field-label a,
.gform_wrapper .gfield_consent_label,
.gform_wrapper .gfield_consent_label a{
  overflow-wrap:anywhere;
}
.de-leadform .gfield_validation_message,.de-leadform .validation_message{
  font-size:12.5px;color:var(--de-error);
}
.de-leadform .gform_footer{margin:0}
.de-leadform .gform_button{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:var(--de-input-h);padding:0 24px;
  background:var(--de-action);color:var(--de-white);
  border:1px solid transparent;border-radius:var(--de-radius-sm);
  font-family:var(--de-font-body);font-size:var(--de-fs-body);font-weight:500;cursor:pointer;
  transition:background var(--de-transition),color var(--de-transition);
}
.de-leadform .gform_button:hover{background:var(--de-action-hover);color:var(--de-dark)}
@media (max-width:600px){.de-leadform .gform_button{width:100%}}

/* ---- de-blog-list ---- */
.de-bloglist{display:flex;flex-direction:column;gap:18px}
.de-bloglist__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-bloglist__grid{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,2.4vw,30px);
}
@media (max-width:900px){.de-bloglist__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:600px){.de-bloglist__grid{grid-template-columns:1fr}}
.de-bloglist__item{display:flex;flex-direction:column;gap:8px;min-width:0}
.de-bloglist__media{display:block;border:0}
.de-bloglist__media img{
  width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;
  border-radius:var(--de-radius);background:var(--de-paper);
}
.de-bloglist__date{
  font-family:var(--de-font-util);font-size:11.5px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--de-ink-mute);margin-top:4px;
}
.de-bloglist__title{font-size:var(--de-fs-h3);font-weight:600;line-height:var(--de-lh-head)}
.de-bloglist__title a{color:var(--de-ink);text-decoration-color:var(--de-link)}
.de-bloglist__title a:hover{color:var(--de-link)}
.de-bloglist__cta{margin:0}

/* ---- de-contact ---- */
.de-contact__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em;margin-bottom:22px}
.de-contact__grid{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:clamp(16px,2.4vw,30px);
}
.de-contact__item{
  display:flex;flex-direction:column;gap:6px;min-width:0;
  border-left:3px solid var(--de-brand);padding-left:16px;
}
.de-contact__label{
  font-family:var(--de-font-util);font-size:11.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--de-ink-mute);
}
.de-contact__value{font-style:normal;line-height:1.6}
.de-contact__value a{color:var(--de-link)}
/* .de-contact__map removed with the embed itself: the footer band above
   already carries the office map beside the areas we serve. */

/* ---- inline icons ---- */
.de-icon{display:block;flex:none}
.de-card-item__icon{
  width:30px;height:30px;color:var(--de-brand);margin-bottom:2px;
}
.de-cards--plain .de-card-item{gap:8px}
.de-contact__icon{width:15px;height:15px;color:var(--de-brand)}
.de-contact__label{display:flex;align-items:center;gap:7px}

/* ---- de-embed ----
   The ratio box reserves the space before the iframe has a src, which is the
   whole reason this is a block and not a core HTML block. */
.de-embed{display:flex;flex-direction:column;gap:16px;max-width:var(--de-max-w)}
.de-embed__heading{font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);letter-spacing:-.015em}
.de-embed__frame{
  position:relative;width:100%;
  background:var(--de-paper);border:1px solid var(--de-line);
  border-radius:var(--de-radius);overflow:hidden;
}
.de-embed--16-9 .de-embed__frame{aspect-ratio:16/9}
.de-embed--4-3  .de-embed__frame{aspect-ratio:4/3}
.de-embed--3-2  .de-embed__frame{aspect-ratio:3/2}
.de-embed--1-1  .de-embed__frame{aspect-ratio:1/1}
.de-embed--auto .de-embed__frame{aspect-ratio:auto;min-height:420px}
.de-embed__frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.de-embed--auto .de-embed__frame iframe{position:relative;min-height:420px}
.de-embed__fallback{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:var(--de-font-util);font-size:var(--de-fs-small);color:var(--de-ink-mute);
}

/* ============================================================================
   ARCHIVES, SEARCH, POSTS, LOCATIONS, PEOPLE
   Templates added after the fourteen blocks. Everything here reuses existing
   tokens and the de-bloglist grid rather than introducing a parallel card.
   ========================================================================= */

/* ---- a hero with no media column -------------------------------------- */
.de-hero--plain .de-hero__grid{grid-template-columns:minmax(0,1fr)}

/* The panel carries the offset that lines hero text up with the page grid.
   Capping the PANEL (rather than its text) made that offset eat into the
   measure, so the copy sat short of the container and left the right half of
   the band empty. The cap comes off; each child keeps its own measure, and the
   padding mirrors so the block occupies exactly the .de-wrap column. */
.de-hero--plain .de-hero__panel{
  max-width:none;
  padding-left:calc(max(0px, (100% - var(--de-max-w)) / 2) + var(--de-gutter));
  padding-right:calc(max(0px, (100% - var(--de-max-w)) / 2) + var(--de-gutter));
}

/* ---- archive shell ----------------------------------------------------- */
.de-archive{display:flex;flex-direction:column;gap:var(--de-section-y)}
.de-archive__empty{color:var(--de-ink-mute);max-width:var(--de-measure)}
.de-archive__none{max-width:var(--de-measure)}

/* The excerpt only exists on the archive card, not the on-page teaser. */
.de-bloglist__excerpt{color:var(--de-ink-mute);font-size:var(--de-fs-small);margin:0}

/* ---- pagination --------------------------------------------------------
   Numbered and bookmarkable. Not infinite scroll: on a site where someone may
   be looking for one specific article, being able to reach page 4 and link to
   it matters more than the scroll feeling seamless. */
.de-pager{border-top:1px solid var(--de-line);padding-top:20px}
.de-pager__list{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0;padding:0;
  align-items:center;justify-content:center}
.de-pager__item{margin:0}
.de-pager .page-numbers{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;padding-inline:12px;
  border:1px solid var(--de-line);border-radius:var(--de-radius-sm);
  color:var(--de-link);text-decoration:none;
  font-size:var(--de-fs-small);font-variant-numeric:tabular-nums;
  transition:background var(--de-transition),border-color var(--de-transition);
}
.de-pager .page-numbers:hover{background:var(--de-paper);border-color:var(--de-brand)}
.de-pager .page-numbers.current{
  background:var(--de-brand);border-color:var(--de-brand);color:var(--de-white);font-weight:600;
}
.de-pager .page-numbers.dots{border-color:transparent;color:var(--de-ink-mute);min-width:24px;padding-inline:0}

/* ---- search form ------------------------------------------------------- */
.de-search{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-top:20px}
.de-search__label{flex:1 0 100%;font-size:var(--de-fs-eyebrow);letter-spacing:var(--de-tr-eyebrow);
  text-transform:uppercase;color:var(--de-ink-mute)}
.de-hero .de-search__label{color:var(--de-brand-light)}
.de-search__field{
  flex:1 1 260px;min-width:0;min-height:44px;padding:10px 14px;
  border:1px solid var(--de-line);border-radius:var(--de-radius-sm);
  background:var(--de-white);color:var(--de-ink);
  font:inherit;font-size:var(--de-fs-body);
}
.de-search__field:focus-visible{outline:3px solid var(--de-brand);outline-offset:2px}

/* ---- a post ------------------------------------------------------------ */
.de-post__meta{
  display:flex;flex-wrap:wrap;gap:6px 14px;align-items:baseline;
  margin:0 0 18px;padding-bottom:14px;border-bottom:1px solid var(--de-line);
  font-size:var(--de-fs-small);color:var(--de-ink-mute);
}
.de-post__date{font-variant-numeric:tabular-nums}
.de-post__role{font-style:italic}
.de-post__terms{
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  margin:28px 0 0;padding-top:16px;border-top:1px solid var(--de-line);
  font-size:var(--de-fs-small);
}
.de-post__terms-label{color:var(--de-ink-mute)}
.de-post__term{
  display:inline-block;padding:4px 10px;border:1px solid var(--de-line);
  border-radius:100px;color:var(--de-link);text-decoration:none;
}
.de-post__term:hover{background:var(--de-paper);border-color:var(--de-brand)}

.de-related{background:var(--de-paper)}
.de-related__heading{font-size:var(--de-fs-h2);line-height:var(--de-lh-head);margin:0 0 22px}

/* ---- location facts card ----------------------------------------------- */
.de-locfacts__travel{margin:0 0 12px;color:var(--de-ink-mute);font-size:var(--de-fs-small)}
.de-locfacts__label{
  margin:14px 0 4px;font-size:var(--de-fs-eyebrow);letter-spacing:var(--de-tr-eyebrow);
  text-transform:uppercase;color:var(--de-ink-mute);
}
.de-locfacts__address{font-style:normal;margin:0;font-size:var(--de-fs-small);line-height:1.5}
.de-locfacts__hours{margin:0;font-size:var(--de-fs-small);color:var(--de-ink-mute)}
.de-locfacts__call{margin-top:16px;width:100%;justify-content:center}

.de-locmap{background:var(--de-paper)}
.de-locmap__heading{font-size:var(--de-fs-h2);line-height:var(--de-lh-head);margin:0 0 20px}
.de-locmap__frame{
  position:relative;aspect-ratio:16/7;border-radius:var(--de-radius);overflow:hidden;
  border:1px solid var(--de-line);background:var(--de-white);
}
.de-locmap__frame iframe{position:absolute;inset:0;width:100%;height:100%}

/* ---- a person ---------------------------------------------------------- */
/* Portrait left, the person's details right, both on the page's own ground.
   The hero band this replaced put the name in white on Deep Slate; a staff bio
   has no offer to make, so it does not need the masthead every other page type
   opens with. */
.de-person__grid{
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);
  gap:clamp(24px,3.4vw,52px);align-items:start;
}
.de-person__media{min-width:0}
.de-person__photo{
  width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  border-radius:var(--de-radius);background:var(--de-paper);
}
.de-person__copy{display:flex;flex-direction:column;min-width:0}

/* A hairline above the name, as the original has under its logo. */
.de-person__rule{
  display:block;width:100%;height:1px;background:var(--de-line);
  margin:14px 0 22px;
}
.de-person__name{
  font-family:var(--de-font-head);font-size:var(--de-fs-display);
  line-height:var(--de-lh-display);letter-spacing:var(--de-tr-display);
  font-weight:var(--de-fw-head);color:var(--de-brand);margin:0;
}

/* Was --de-brand-light, which is Sky: an on-dark accent that measures about
   1.8:1 on this ground. --de-link is the palette's AA-on-white blue, and the
   role is small text so it needs the full 4.5:1. */
.de-person__role{
  margin:8px 0 0;font-family:var(--de-font-util);
  font-size:var(--de-fs-small);letter-spacing:.04em;
  text-transform:none;color:var(--de-link);
}
.de-person__bio{margin-top:20px}
.de-person__back{margin:26px 0 0}

@media (max-width:820px){
  .de-person__grid{grid-template-columns:1fr}
  .de-person__photo{aspect-ratio:1/1;max-width:420px}
  .de-person__rule{margin-top:4px}
}

@media (max-width:720px){
  .de-person__media{justify-content:flex-start;margin-top:20px}
  .de-locmap__frame{aspect-ratio:4/3}
  .de-pager .page-numbers{min-width:40px;padding-inline:8px}
}

/* ---- hero strapline: a brand line above the heading -------------------- */
.de-hero__strapline{
  margin:0 0 6px;font-family:var(--de-font-label);font-weight:500;
  font-size:var(--de-fs-small);letter-spacing:.02em;color:var(--de-brand-light);
}
/* ---- blog teaser authorship ------------------------------------------- */
.de-bloglist__byline{
  margin:2px 0 0;font-size:var(--de-fs-eyebrow);color:var(--de-ink-mute);
}

/* ---- gallery intro: the tour section's dropped paragraph ---------------- */
.de-gallery__intro{max-width:var(--de-measure-wide);margin:0 0 20px}

/* ---- long unbroken strings in prose ------------------------------------
   A raw URL used as its own link text cannot wrap at a space, so on a 390px
   viewport it pushes the page sideways. Found on the mental-health-assessment
   page, whose citation list links to ncbi.nlm.nih.gov and samhsa.gov by full
   URL. Applied to prose generally rather than that page, because any citation
   list will do the same. */
.de-prose a,
.de-prose li,
.de-prose p{overflow-wrap:anywhere}

/* ---- footer accreditation badge ---------------------------------------- */
.de-footer__accred{margin-top:22px}
.de-footer__accred-img{width:84px;height:auto;display:block}
.de-footer__accred-link{display:inline-block;border-radius:var(--de-radius-sm)}
.de-footer__accred-link:focus-visible{outline:3px solid var(--de-brand-light);outline-offset:3px}

/* ---- reviewer photo in the medically-reviewed card --------------------- */
.de-reviewed__photo{float:left;margin:0 12px 6px 0}
.de-reviewed__photo img{
  width:52px;height:52px;border-radius:50%;object-fit:cover;display:block;
  border:1px solid var(--de-line);
}

/* ---- de-gallery, GRID layout + lightbox --------------------------------
   The tour page's source was an Elementor gallery widget, not a carousel:
   grid, columns 4 / tablet 2 / mobile 1, gap 10px, aspect-ratio 3:2, an
   overlay that fades in on hover, and a slideshow lightbox on click. Those
   numbers are read from the widget's own data-settings, not guessed.

   Selectors are direct-child where they can be, because .de-prose ul already
   beat .de-gallery__strip once and turned a horizontal strip into a column.
   ---------------------------------------------------------------------- */
.de-gallery__grid{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;
  list-style:none;margin:0;padding:0;
}
.de-gallery__grid > .de-gallery__cell{margin:0}

.de-gallery__link{
  position:relative;display:block;overflow:hidden;
  border-radius:var(--de-radius-sm);background:var(--de-paper);
  /* The crop lives here so a mixed-orientation library still tiles evenly. */
  aspect-ratio:3/2;
}
.de-gallery__link > img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .45s ease;
}
.de-gallery__overlay{
  position:absolute;inset:0;background:var(--de-brand);opacity:0;
  transition:opacity .3s ease;
}
/* A magnifier drawn in CSS: no icon font, no extra request. */
.de-gallery__overlay::after{
  content:"";position:absolute;top:50%;left:50%;
  width:20px;height:20px;margin:-13px 0 0 -13px;
  border:2px solid #fff;border-radius:50%;
  box-shadow:6px 6px 0 -1px #fff;
  transform:rotate(45deg) scale(.8);
  transition:transform .3s ease;
}
.de-gallery__link:hover .de-gallery__overlay,
.de-gallery__link:focus-visible .de-gallery__overlay{opacity:.62}
.de-gallery__link:hover > img{transform:scale(1.04)}
.de-gallery__link:hover .de-gallery__overlay::after,
.de-gallery__link:focus-visible .de-gallery__overlay::after{transform:rotate(45deg) scale(1)}
.de-gallery__link:focus-visible{outline:3px solid var(--de-brand);outline-offset:3px}

@media (max-width:1024px){
  .de-gallery__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:600px){
  .de-gallery__grid{grid-template-columns:minmax(0,1fr)}
}
@media (prefers-reduced-motion:reduce){
  .de-gallery__link > img,
  .de-gallery__overlay,
  .de-gallery__overlay::after{transition:none}
  .de-gallery__link:hover > img{transform:none}
}

/* ---- the lightbox itself ---------------------------------------------- */
.de-lightbox{
  border:0;padding:0;margin:auto;max-width:100vw;max-height:100vh;
  width:100%;height:100%;background:transparent;overflow:hidden;
}
.de-lightbox::backdrop{background:rgba(11,18,25,.92)}
.de-lightbox__inner{
  position:relative;width:100%;height:100%;
  display:flex;align-items:center;justify-content:center;padding:clamp(12px,4vw,56px);
}
.de-lightbox__figure{margin:0;max-width:min(1200px,92vw);text-align:center}
.de-lightbox__figure.is-loading{opacity:.35}
.de-lightbox__img{
  max-width:100%;max-height:78vh;width:auto;height:auto;display:block;margin:0 auto;
  border-radius:var(--de-radius-sm);background:#0b1219;
}
.de-lightbox__caption{
  margin:14px 0 0;color:#fff;font-family:var(--de-font-util);font-size:13px;
  line-height:1.5;max-width:60ch;margin-inline:auto;
}
.de-lightbox__counter{
  position:absolute;top:clamp(10px,2.4vw,22px);left:50%;transform:translateX(-50%);
  margin:0;color:rgba(255,255,255,.72);font-family:var(--de-font-util);font-size:12px;
  font-variant-numeric:tabular-nums;
}
.de-lightbox__btn,
.de-lightbox__close{
  position:absolute;display:grid;place-items:center;cursor:pointer;
  background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.28);
  color:#fff;border-radius:999px;transition:background .2s ease,border-color .2s ease;
}
.de-lightbox__btn{width:48px;height:48px;top:50%;margin-top:-24px}
.de-lightbox__btn--prev{left:clamp(8px,2vw,26px)}
.de-lightbox__btn--next{right:clamp(8px,2vw,26px)}
.de-lightbox__btn span{
  width:11px;height:11px;border-top:2px solid currentColor;border-right:2px solid currentColor;
}
.de-lightbox__btn--prev span{transform:rotate(-135deg) translate(-1px,-1px)}
.de-lightbox__btn--next span{transform:rotate(45deg) translate(-1px,-1px)}
.de-lightbox__close{
  width:44px;height:44px;top:clamp(8px,2vw,20px);right:clamp(8px,2vw,20px);
  font-size:26px;line-height:1;font-family:var(--de-font-util);
}
.de-lightbox__btn:hover,
.de-lightbox__close:hover{background:rgba(255,255,255,.2);border-color:rgba(255,255,255,.5)}
.de-lightbox__btn:focus-visible,
.de-lightbox__close:focus-visible{outline:3px solid #fff;outline-offset:2px}

/* Stop the page behind from scrolling while the viewer is open. */
html.de-lightbox-open{overflow:hidden}

@media (max-width:600px){
  .de-lightbox__btn{width:40px;height:40px;margin-top:-20px}
  .de-lightbox__img{max-height:68vh}
}

/* ---- footer: areas-we-serve band with the map -------------------------
   Two columns on desktop, matching the original: links beside a map of the
   King of Prussia office. The map is the only thing in the footer that
   answers "where is this place", so it stacks rather than disappearing on
   a phone.
   -------------------------------------------------------------------- */
.de-footer__band{border-bottom:1px solid var(--de-footer-line,rgba(255,255,255,.14))}
.de-footer__band-inner{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,360px);
  gap:clamp(24px,4vw,56px);align-items:start;
  padding-block:clamp(28px,4vw,44px);
}
/* The band's list is a grid rather than a column, so it overrides the shared
   flex direction it inherits from .de-footer__links. Colour and hover come from
   that shared rule on purpose: a second copy of the palette here is how the
   band shipped with prose-blue links on Deep Slate the first time. */
.de-footer__band-links ul{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:2px 22px;
}

/* The map keeps a square-ish frame whatever the pasted iframe says: the
   embed arrives with hardcoded width/height attributes from Google. */
.de-footer__map{
  position:relative;aspect-ratio:1/1;width:100%;max-width:360px;
  border-radius:var(--de-radius-sm);overflow:hidden;
  background:rgba(255,255,255,.06);
}
.de-footer__map iframe{
  position:absolute;inset:0;width:100%;height:100%;border:0;display:block;
}

@media (max-width:900px){
  .de-footer__band-inner{grid-template-columns:minmax(0,1fr)}
  .de-footer__band-links ul{grid-template-columns:repeat(2,minmax(0,1fr))}
  .de-footer__map{max-width:none;aspect-ratio:16/10}
}
@media (max-width:480px){
  /* Kept in step with the <=520px rule further down, which currently wins on
     source order. Two rules that disagree is how the three-column bug in the
     comment above happened. */
  .de-footer__band-links ul{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* ---- rail cards for posts: recent + tags -------------------------------
   Both reuse the .de-card shell, so only the list interiors are new. The
   dates use tabular figures so a stack of them lines up.
   -------------------------------------------------------------------- */
.de-rail-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.de-rail-list li{margin:0;display:flex;flex-direction:column;gap:3px}
.de-rail-list__link{
  color:var(--de-ink);text-decoration:none;font-weight:600;
  font-size:14px;line-height:1.4;
  border-bottom:1px solid transparent;align-self:flex-start;
}
.de-rail-list__link:hover,
.de-rail-list__link:focus-visible{color:var(--de-link);border-bottom-color:currentColor}
.de-rail-list__date{
  font-family:var(--de-font-util);font-size:11px;color:var(--de-ink-mute);
  font-variant-numeric:tabular-nums;
}

.de-rail-tags{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.de-rail-tags li{margin:0}
.de-rail-tags__tag{
  display:inline-block;padding:4px 10px;border-radius:999px;
  border:1px solid var(--de-line);background:var(--de-paper);
  font-family:var(--de-font-util);font-size:11px;letter-spacing:.02em;
  color:var(--de-ink-mute);text-decoration:none;
  transition:border-color var(--de-transition),color var(--de-transition);
}
.de-rail-tags__tag:hover,
.de-rail-tags__tag:focus-visible{border-color:var(--de-link);color:var(--de-link)}

/* ---- hero trust badge, as a link ------------------------------------- */
.de-home-hero__badge-link{display:inline-block;border-radius:var(--de-radius-sm)}
.de-home-hero__badge-link:focus-visible{outline:3px solid var(--de-brand-light);outline-offset:4px}
.de-home-hero__badge-link img{display:block}

/* ---- closing CTA: centred, and over a photograph ----------------------
   WHAT WAS WRONG. The inner box was a 36rem measure with `margin:0 auto`,
   so it WAS horizontally centred — but its contents were left-aligned
   inside it, which reads as a narrow column adrift in a wide dark band.
   The heading then wrapped at 512px into "Begin Treatment at New / Mind
   Wellness Today". Not a tour-page fault: every page rendering this band
   had it, the tour page only made it obvious once the rail was removed
   and the empty track had nothing in it.

   The band is a full-bleed section already, so it does not need to break
   out of anything — it needs its CONTENT centred and given room.
   -------------------------------------------------------------------- */
/* THE BAND OWNS NO VERTICAL PADDING, THE INNER OWNS ALL OF IT.
   .de-band gives every band --de-section-y, and this inner box was adding its
   own clamp(48px,6vw,84px) on top: 82px to 136px of air above and below the
   copy, which is what made the band read as mostly empty. Zeroing the band and
   keeping one clamp here means the spacing is set in ONE place and reads as the
   number it actually is. 36-60px, roughly half what it was. */
.de-closing{padding-block:0}
.de-closing__inner{
  max-width:var(--de-max-w-cta);
  margin-inline:auto;
  text-align:center;
  align-items:center;
  gap:16px;
  padding-block:clamp(36px,4.2vw,60px);
}
/* The measure still applies to the running text — but it is a centred
   measure, not a left-aligned box, and both are wider now so the content
   actually uses the room the container gained. The heading was capped at 22ch,
   which is what broke "Begin Mental Health Treatment in Philadelphia Today"
   across two lines with a near-empty second one. */
.de-closing__title{
  max-width:30ch;margin-inline:auto;text-wrap:balance;
}
.de-closing__text{
  max-width:var(--de-measure-wide);margin-inline:auto;
}
.de-closing__cta{
  display:flex;flex-wrap:wrap;gap:14px;justify-content:center;
}

/* THE SAME TREATMENT AS THE HERO: a photograph under a directional Deep
   Slate gradient, not the near-flat 93-97% wash this used to carry. That wash
   was so close to opaque that the photograph behind it was academic; the band
   looked like flat colour, which is exactly what it was asked to stop doing.

   The angle matches the home hero (100deg, heavy left to light right) so the
   two bands read as one family. The LIGHT END DIFFERS, and deliberately: the
   hero eases to 62% because its copy is left-aligned and sits over the dark
   half, while this band centres everything and pushes two buttons and a
   paragraph out towards the light end. Over a bright photograph, white text on
   62% measures 4.40:1 and misses AA for body size; 72% holds it at 6.01:1
   against a worst-case white image. That floor is why it is not simply the
   hero's numbers copied across. */
.de-closing--photo{
  position:relative;isolation:isolate;
  background-image:var(--de-closing-bg);
  background-size:cover;background-position:center;
}
.de-closing--photo::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(
    100deg,
    rgba(14,42,53,.94) 0%,
    rgba(14,42,53,.86) 42%,
    rgba(14,42,53,.72) 100%
  );
}
.de-closing--photo > *{position:relative}

@media (max-width:600px){
  .de-closing__title{max-width:none}
  .de-closing__cta .de-btn{width:100%}
}

/* ---- footer areas-we-serve band: balance, and close the gap -----------
   The links sat hard left and the map hard right with a wide empty middle
   and dead vertical space beneath both, because the columns were fixed at
   1fr/360px with align-items:start and no relationship between their
   heights. Sizing the link column to its content and letting the map take
   the rest reads as one band.
   -------------------------------------------------------------------- */
.de-footer__band-inner{
  grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  gap:clamp(28px,4vw,64px);
  /* STRETCH, not center. The dead space under the links was the height
     difference between a short link list and a tall square map: centring
     them just put the gap above and below instead of below. Stretching
     makes the map exactly as tall as the column beside it, so the band has
     no spare height to leave empty. */
  align-items:stretch;
}
.de-footer__band-links{display:flex;flex-direction:column;justify-content:center}
.de-footer__band-links ul{
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:6px 18px;
}
.de-footer__map{
  max-width:none;
  /* Height comes from the row, not from a ratio — a ratio is what made it
     square and twice the height of the links. */
  aspect-ratio:auto;min-height:190px;height:100%;
}
/* Responsive overrides live AFTER the desktop rules above, deliberately.
   The earlier pass put a plain 3-column rule below the media queries, so it
   won on source order and phones got three cramped columns with "Plymouth
   Meeting" wrapping. Same specificity means later wins; keep the order. */
@media (max-width:900px){
  .de-footer__band-inner{grid-template-columns:minmax(0,1fr);align-items:start}
  .de-footer__map{aspect-ratio:16/10;height:auto;min-height:0}
  .de-footer__band-links ul{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:520px){
  /* TWO COLUMNS ALL THE WAY DOWN. This dropped to one below 520px, which left
     a single file of nine short place names down a phone screen and a lot of
     empty right-hand side. The column gap tightens from 22px to 12px here so
     the longest name, "Plymouth Meeting", still has room beside its pin at
     360px; the links are flex, so a name that does wrap keeps the pin centred
     against it rather than pinned to the first line. */
  .de-footer__band-links ul{grid-template-columns:repeat(2,minmax(0,1fr));gap:2px 12px}
}

/* ---- contact.php --------------------------------------------------------
   The original pairs the enquiry form with the office details side by side.
   The form column is the wider of the two because a form with a consent
   block and a captcha needs the room; the aside is sized to its content.

   Every value here is a token. The aside's map has no aspect-ratio: like the
   footer band, a fixed ratio is what made a map twice the height of the
   column beside it and left dead space underneath.
   -------------------------------------------------------------------- */
/* .de-wrap.de-contact, NOT .de-contact. TWO DIFFERENT COMPONENTS SHARE THIS
   CLASS: contact.php wraps its form-and-aside layout in `de-wrap de-contact`,
   and the de-contact BLOCK puts `de-contact` on its own <section>. This rule
   is the page's, and unscoped it was making the block's section a two-column
   grid as well — which nobody noticed while the block's content sat inside a
   single de-wrap child, and which squeezed the panel row to 814px of 1425 the
   moment that child became three. Scoped to the pair the page actually uses.
   The __label / __map / __value descendants are still shared and still want
   separating one day; this fixes the layout collision, not the naming. */
.de-wrap.de-contact{
  display:grid;grid-template-columns:minmax(0,1.45fr) minmax(0,1fr);
  gap:clamp(24px,3.4vw,52px);align-items:start;
}
.de-contact__form,.de-contact__aside{min-width:0}
.de-contact__form > *{max-width:none}
.de-contact__aside{display:flex;flex-direction:column;gap:16px}

.de-contact__map{
  position:relative;width:100%;min-height:300px;
  border:1px solid var(--de-line);border-radius:var(--de-radius);
  overflow:hidden;background:var(--de-paper);
}
.de-contact__map iframe{
  position:absolute;inset:0;width:100%;height:100%;border:0;display:block;
}

.de-contact__card{
  background:var(--de-paper);border:1px solid var(--de-line);
  border-left:3px solid var(--de-brand);border-radius:0 var(--de-radius) var(--de-radius) 0;
  padding:18px 20px;display:flex;flex-direction:column;gap:16px;
}
.de-contact__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.de-contact__row{display:flex;flex-direction:column;gap:3px;min-width:0}
.de-contact__label{
  font-family:var(--de-font-util);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--de-ink-mute);
}
/* COLOUR MOVED TO THE LINK BLUE WHEN THE UNDERLINE WENT.
   These were ink-coloured — the same value as the text beside them — with the
   underline doing the whole job of saying "this is a phone number you can
   tap". Deleting the underline and changing nothing else would have left the
   contact details rendered exactly like plain prose. Signal Deep is the site's
   link colour and clears 5.37:1 on white, so it identifies them and stays
   readable; hover deepens to Deep Slate for feedback. */
.de-contact__row a{
  color:var(--de-link);text-decoration:none;
  word-break:break-word;
}
.de-contact__row a:hover{color:var(--de-dark)}
.de-contact__address{font-style:normal;color:var(--de-ink);line-height:1.55}

.de-contact__social{list-style:none;margin:0;padding:0;display:flex;gap:10px}
.de-contact__social-link{
  display:flex;width:38px;height:38px;align-items:center;justify-content:center;
  border:1px solid var(--de-line);border-radius:50%;text-decoration:none;
  transition:background var(--de-transition),border-color var(--de-transition);
}
.de-contact__social-dot{
  width:9px;height:9px;border-radius:50%;background:var(--de-brand);
  transition:background var(--de-transition);
}
.de-contact__social-link:hover{background:var(--de-brand);border-color:var(--de-brand)}
.de-contact__social-link:hover .de-contact__social-dot{background:var(--de-white)}

@media (max-width:900px){
  .de-wrap.de-contact{grid-template-columns:minmax(0,1fr)}
  .de-contact__map{min-height:260px}
}

/* ---- the Areas band is a LIGHT band, not part of the dark footer --------
   On the original this sits on the page ground with a rule above it, and the
   dark footer starts below. The rebuild had it inside .de-footer, so it took
   the Deep Slate background and read as the top of the footer rather than as
   the last section of the page — which is what "it overlaps the footer"
   meant. Restyled rather than moved: it is already the first child of the
   footer, so recolouring it puts the boundary in the right place without
   disturbing markup every page depends on.
   -------------------------------------------------------------------- */
.de-footer__band{
  background:var(--de-paper);color:var(--de-ink);
  border-top:1px solid var(--de-brand);
  border-bottom:0;
}
.de-footer__band .de-footer__heading{color:var(--de-brand)}
/* FLEX, so the pin and the place name share a baseline row.
   The shared rule with the footer column sets display:block, which would drop
   the SVG onto its own line above the label — .de-icon is display:block itself.
   Scoped to the band: the column below keeps its blockish rows and its sliding
   border, and does not get a pin. The hover padding-left still works, because
   padding is unaffected by the switch to flex. */
.de-footer__band .de-footer__band-links a{
  color:var(--de-ink);border-bottom:1px solid var(--de-line);
  display:flex;align-items:center;gap:9px;
}
/* Signal Blue, matching the band's own "AREAS WE SERVE" heading, and sized to
   the text rather than to the 24px grid it is drawn on. flex:none so a long
   place name like "Plymouth Meeting" squeezes the label, never the pin. */
.de-footer__area-pin{
  width:15px;height:15px;flex:none;color:var(--de-brand);
}
.de-footer__band .de-footer__band-links a:hover,
.de-footer__band .de-footer__band-links a:focus-visible{
  color:var(--de-link);border-bottom-color:var(--de-link);
}
.de-footer__band .de-footer__map{background:var(--de-line)}

/* ---- Gravity Forms submit ----------------------------------------------
   GF 2.7's Orbital theme drives its controls from its OWN custom properties,
   so a selector war is the wrong tool — its rules are more specific than any
   single class we can reasonably write, and it renders a <button>, not the
   <input> the older markup used. Feeding our tokens into its variables is the
   same move as --de-verify-*: declare once on the container, let inheritance
   do the rest. The selector block below is kept for the pre-Orbital markup.
   -------------------------------------------------------------------- */
.gform_wrapper.gform-theme,
.gform_wrapper.gform-theme--orbital{
  --gf-ctrl-btn-bg-color-primary:var(--de-action);
  --gf-ctrl-btn-bg-color-hover-primary:var(--de-action-hover);
  --gf-ctrl-btn-bg-color-focus-primary:var(--de-action-hover);
  --gf-ctrl-btn-border-color-primary:var(--de-action);
  --gf-ctrl-btn-border-color-hover-primary:var(--de-action-hover);
  --gf-ctrl-btn-color-primary:var(--de-white);
  --gf-ctrl-btn-color-hover-primary:var(--de-dark);
  --gf-ctrl-btn-radius:var(--de-radius-sm);
  --gf-ctrl-btn-font-family:var(--de-font-body);
  --gf-ctrl-btn-size-height-lg:var(--de-input-h);
  --gf-ctrl-btn-padding-x-lg:22px;
  --gf-color-primary:var(--de-brand);
  --gf-ctrl-border-color:var(--de-line);
  --gf-ctrl-radius:var(--de-radius-sm);
  --gf-ctrl-size-height-lg:var(--de-input-h);
  --gf-ctrl-bg-color:var(--de-input-bg);
  --gf-local-color:var(--de-ink);
}
.gform_wrapper .gform_footer button.gform_button,
.gform_wrapper .gform-footer button.gform_button,
.gform_wrapper .gform_footer input[type="submit"],
.gform_wrapper input.gform_button{
  background:var(--de-action);color:var(--de-white);
  border:1px solid transparent;border-radius:var(--de-radius-sm);
  min-height:var(--de-input-h);padding:0 22px;
  font-family:var(--de-font-body);font-size:var(--de-fs-body);font-weight:500;
  letter-spacing:0;text-transform:none;cursor:pointer;
  transition:background var(--de-transition),color var(--de-transition);
}
.gform_wrapper .gform_footer button.gform_button:hover,
.gform_wrapper .gform-footer button.gform_button:hover,
.gform_wrapper .gform_footer input[type="submit"]:hover,
.gform_wrapper input.gform_button:hover{
  background:var(--de-action-hover);color:var(--de-dark);
}

/* Spacing around the band, in two parts — they are not the same thing.

   ABOVE: the footer's own top padding used to sit over the band, so once the
   band went light there was a 76px strip of Deep Slate above it containing
   nothing. That padding is dropped when a band is present.

   BELOW: dropping it also removed the only gap between the band and the
   footer columns, because the band's padding lives on __band-inner and not on
   the band itself — so the logo ended up hard against the light band with no
   breathing room. The grid now carries that spacing itself, which is where it
   belonged: it is the distance between two sections, not the top of the
   footer element. */
.de-footer:has(> .de-footer__band){padding-block-start:0}
.de-footer__grid{padding-block-start:clamp(40px,5vw,68px)}

/* ---- social brand marks -------------------------------------------------
   The circles were generic dots, so nobody could tell Facebook from LinkedIn.
   The dot rules stay as the fallback for a network with no mark rather than
   being deleted — an unrecognised slug should render something, not an empty
   ring. Colour comes from currentColor, so each context keeps its own palette
   without the mark needing to know where it is.
   -------------------------------------------------------------------- */
.de-social-mark{display:block;width:18px;height:18px;flex:none}

.de-footer__social-link{color:var(--de-brand-light)}
.de-footer__social-link:hover,
.de-footer__social-link:focus-visible{color:var(--de-dark)}

.de-contact__social-link{color:var(--de-brand)}
.de-contact__social-link:hover,
.de-contact__social-link:focus-visible{color:var(--de-white)}

/* ---- contact aside: the columns start level ----------------------------
   The map carried a 26px top margin from an inherited rule, so the right
   column began below the left one. The aside is a flex column with its own
   gap, so child margins are the wrong mechanism entirely — zeroing them lets
   the gap own the rhythm and puts both columns on the same line at every
   breakpoint, rather than patching the offset per media query.
   -------------------------------------------------------------------- */
.de-contact__aside > *{margin-block:0}

/* ==========================================================================
   HEADER — reconciled against the live site
   Values read off www.newmindpa.com rather than eyeballed. Both CTA colours
   turned out to already be in the token set, so nothing new was introduced:
   live's verify green is #95B642 (--de-action-hover) and its phone blue is
   #0086BE (--de-brand).
   ========================================================================== */

@media (min-width:1201px){

  /* ---- submenu: one divider per item, no panel borders ------------------
     The overlap was structural. The panel carried a 1px border on all four
     sides plus a 2px top; the nested panel inherited that and added a 2px
     left, so where a child opened beside its parent their edges stacked into
     a doubled line — and the child's top border crossed the parent's items.

     Live solves it by not bordering the panel at all: a soft shadow lifts it
     off the page and a single hairline under each item does the separating.
     Same approach here, so a border can never meet another border. */
  .de-nav__submenu{
    border:0;border-radius:var(--de-radius);padding:0;
    box-shadow:0 4px 14px -2px rgba(14,42,53,.16);
  }
  .de-nav__submenu .de-nav__submenu{
    top:-2px;border:0;border-radius:var(--de-radius);
  }
  .de-nav__submenu .de-nav__item + .de-nav__item{
    border-top:1px solid var(--de-line);
  }
  .de-nav__submenu .de-nav__link{
    padding:12px 34px 12px 16px;font-size:15px;border-radius:0;
  }
  .de-nav__submenu .de-nav__link:hover{background:var(--de-paper);color:var(--de-link)}

  /* A branch that is open reads as the trail into the panel beside it. */
  .de-nav__submenu .de-nav__item--branch.is-open > .de-nav__link{
    background:var(--de-paper);color:var(--de-link);
  }

  /* ---- the nav must not touch the CTAs ---------------------------------
     The nav column is 1fr and its list filled it, leaving about 7px between
     "Contact" and the Verify button. The grid gap alone cannot fix that
     without also pushing the logo, so the separation belongs to the nav. */
  .de-nav{padding-inline-end:clamp(10px,1.6vw,26px)}
}

/* ---- header CTAs -------------------------------------------------------
   Nothing here any more. The two header buttons ARE the global system now,
   so the rules that used to make the header a special case would only be
   restating it. What stays below is the header's own SIZING, which is a
   fitting problem rather than a design one. */

/* ---- the header has to FIT, not just be spaced ---------------------------
   Padding on the nav did not separate "Contact" from the Verify button,
   because the problem was never spacing: seven top-level items plus two solid
   CTAs are wider than the row, the links are nowrap so the list cannot
   shrink, and the overflow lands on the button. Measured at 1440 the gap was
   2px — the two were touching.

   So the row is made to fit rather than nudged: tighter link padding, live's
   15px nav size, and CTA padding closer to the original's. A guaranteed
   margin on the CTA group is the backstop, so even if a menu item is added
   later the button cannot be reached.
   -------------------------------------------------------------------- */
@media (min-width:1201px){
  .de-nav__list{flex-wrap:nowrap}
  .de-nav__link{padding:10px 9px;font-size:15px}
  .de-nav__item--branch.de-nav__item--depth-0 > .de-nav__link{padding-right:24px}
  .de-header__cta{margin-inline-start:clamp(14px,1.6vw,28px)}
  .de-header__cta .de-btn{padding:0 20px;font-size:15px}
}


/* ---- callback band: live's structure -----------------------------------
   The original centres the heading over the form on this band rather than
   ranging it left, and the band is dark. The colour comes from the block's
   own `ground` field, not from a rule here — Deep Slate is the token the
   design notes record as "refined from your existing #102D3A", which is
   exactly the colour live paints this section. */
.de-leadform--dark .de-leadform__copy{
  max-width:none;text-align:center;align-items:center;
}
.de-leadform--dark .de-leadform__intro{max-width:var(--de-measure-wide);margin-inline:auto}


/* ---- de-cards, banded ---------------------------------------------------
   The original runs its programs row as a full-bleed coloured band with
   everything on the centre line: heading, intro, an outlined circular icon
   over each card, the card copy, and one CTA underneath. Ours sat inline and
   left-aligned, which is why the heading and intro read as crowded — a
   left-ranged heading directly above a full-width paragraph has nothing
   separating the two.

   Structure copied, palette not: the band is Deep Slate rather than the
   original's green, because Grove is this site's single "act here" colour and
   spending it on 700px of background is what would make the buttons stop
   meaning anything.
   -------------------------------------------------------------------- */
.de-cards--banded{width:100%}
.de-cards--banded.de-cards--paper{background:var(--de-paper)}
.de-cards--banded.de-cards--dark{background:var(--de-dark);color:var(--de-white)}

.de-cards--banded > *,
.de-team--banded > *{
  max-width:var(--de-max-w);margin-inline:auto;padding-inline:var(--de-gutter);
}

/* Head: centred, and given room. The intro is held to a readable measure
   rather than run to the full container — 1400px of centred text is a wall. */
.de-cards--banded .de-cards__head{
  text-align:center;
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(14px,1.6vw,20px);
  margin-bottom:clamp(30px,3.6vw,52px);
}
.de-cards--banded .de-cards__intro{
  max-width:68ch;margin-inline:auto;
}
.de-cards--banded.de-cards--dark .de-cards__intro{color:#C9DAE1}

/* Cards: centred content under a circular outlined icon, as the original. */
.de-cards--banded .de-card-item{
  text-align:center;align-items:center;
  background:transparent;border:0;padding:0;box-shadow:none;
}
.de-cards--banded .de-card-item__icon{
  width:44px;height:44px;padding:16px;box-sizing:content-box;
  border:2px solid currentColor;border-radius:50%;
  margin-inline:auto;margin-bottom:clamp(14px,1.6vw,20px);
}
/* THE PHOTO GROUND IS A DARK GROUND, AND THIS RULE HAD NOT HEARD.
   render.php says so in as many words — "Photo is a dark ground too" — and
   sets .de-band--dark alongside it, which is what carries the on-dark tokens.
   But the ICON colour was enumerated against .de-cards--dark alone, so a photo
   band fell through to the base .de-card-item__icon rule and drew Signal Blue:
   1.57:1 against the olive wash, effectively invisible. Grove-on-hover is the
   light green the original circles the icons in, at 2.73:1.

   Same failure the verify button's comment catalogues five times over — a new
   dark context that an enumeration did not name. */
.de-cards--banded.de-cards--dark .de-card-item__icon,
.de-cards--banded.de-cards--photo .de-card-item__icon{color:var(--de-action-hover)}
.de-cards--banded.de-cards--dark .de-card-item__title{color:var(--de-white)}
.de-cards--banded.de-cards--dark .de-card-item__body{color:#C9DAE1}
.de-cards--banded .de-card-item__title{margin-bottom:.4em}
.de-cards--banded .de-card-item__body{max-width:38ch;margin-inline:auto}

.de-cards--banded .de-cards__grid{gap:clamp(28px,3.4vw,52px)}
.de-cards--banded .de-cards__cta{
  display:flex;justify-content:center;
  margin-top:clamp(30px,3.6vw,52px);
}

/* ---- de-gallery, SOLO layout + the two-column split ---------------------
   The home page tour section. Its source is an Elementor image-carousel with
   slides_to_show:1 and navigation:dots, sitting in the right-hand of two 50%
   columns; the left column holds heading, divider, text and button. Those
   numbers come from the widget's own settings, not from a screenshot.

   Layout and structure are copied. TYPE IS NOT: the heading stays on
   Bricolage Grotesque at --de-fs-h2 and the copy on DM Sans, because the whole
   point of the rebuild was getting off the source's Roboto/Fredoka mix.
   ---------------------------------------------------------------------- */

/* The track is a scroll-snap container one slide wide, so it scrolls natively
   before de-gallery.js runs. The dots and the autoplay are enhancement; with JS
   off this is a swipeable strip of photos, which is still the content. */
.de-gallery__solo{
  list-style:none;margin:0;padding:0;
  display:grid;grid-auto-flow:column;grid-auto-columns:100%;
  gap:0;
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  border-radius:var(--de-radius);
  /* The scrollbar is redundant once the dots are there, and on Windows it eats
     17px off the photo. Kept reachable by keyboard and touch either way. */
  scrollbar-width:none;
}
.de-gallery__solo::-webkit-scrollbar{display:none}
.de-gallery__solo:focus-visible{outline:3px solid var(--de-brand);outline-offset:3px}
.de-gallery__slide{scroll-snap-align:center;margin:0;min-width:0}
/* The slide's enlarge link fills the slide and draws no corner of its own: the
   .de-gallery__solo track already clips the whole run at --de-radius, and a
   second 6px radius inside a 10px clip shows as a bright sliver in each corner.
   The focus ring is inset for the same reason — offset outwards, the track's
   own overflow:auto would crop it away on the first and last slide. */
.de-gallery__slide .de-gallery__link{
  border-radius:0;height:100%;
}
.de-gallery__slide .de-gallery__link:focus-visible{outline-offset:-3px}
.de-gallery__slide img{
  width:100%;height:auto;display:block;
  /* 3:2, measured off the live section rather than assumed: its photo runs
     442x295 in the right-hand column. */
  aspect-ratio:3/2;object-fit:cover;
  background:var(--de-paper);
}

/* ---- the dot row ---- */
.de-gallery__dots{
  display:flex;align-items:center;justify-content:center;gap:10px;
  margin-top:16px;
}
/* NOWRAP, deliberately. 21 dots at a comfortable size overflow the media
   column and wrap three of them onto a second row, which reads as a broken
   control rather than as a page indicator. They shrink instead. */
.de-gallery__dotrow{
  display:flex;align-items:center;justify-content:center;
  gap:2px;flex-wrap:nowrap;min-width:0;
}
.de-gallery__dot{
  /* 7px of ink in a target that is deliberately taller than it is wide: 21
     dots have to fit a ~530px column, and vertical room is free. The padding
     IS the target — a 7px dot with a 7px target is how this control usually
     fails. */
  width:14px;height:22px;padding:3.5px 3.5px;box-sizing:border-box;
  flex:none;border:0;background:none;cursor:pointer;
  border-radius:var(--de-radius-sm);
  -webkit-appearance:none;appearance:none;
  display:flex;align-items:center;justify-content:center;
}
.de-gallery__dot::before{
  content:"";display:block;width:7px;height:7px;border-radius:50%;
  background:var(--de-line);
  transition:background var(--de-transition),transform var(--de-transition);
}
.de-gallery__dot:hover::before{background:var(--de-ink-mute)}
.de-gallery__dot.is-current::before{background:var(--de-ink);transform:scale(1.35)}
.de-gallery__dot:focus-visible{outline:2px solid var(--de-brand);outline-offset:0}

/* The pause / play control lived here. It was removed from both carousels on
   request, so its rules went with it rather than sitting dead. Putting it back
   means restoring the button in de-gallery/render.php and de-insurance/render.php
   plus the handlers in their scripts — see the WCAG 2.2.2 note in each. */

/* ---- the two-column split ----
   50/50, which is what the source section specified. de-split had to widen its
   copy column to 0.66/1 because a rigid half wrapped its heading badly — that
   does not apply here: "Tour Our Luxury Mental Health Facility" wraps to two
   lines on the live site at the same width, so matching the source is right. */
.de-gallery--split .de-gallery__split{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(24px,4vw,56px);align-items:center;
}
.de-gallery--split .de-gallery__copy{
  display:flex;flex-direction:column;align-items:flex-start;
  gap:0;min-width:0;
}
.de-gallery--split .de-gallery__media{min-width:0}

/* The heading, on OUR display face — the structure is borrowed, the type is
   not. */
.de-gallery--split .de-gallery__heading{
  font-family:var(--de-font-head);
  font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);
  line-height:var(--de-lh-head);letter-spacing:-.015em;
  margin:0;
}

/* The `divider` widget from the source column. Decoration, so it is a span with
   aria-hidden rather than an <hr> that announces a thematic break. */
/* The `divider` widget the source puts under a section heading. One definition,
   two hooks: the tour section and both splits carry the same element, and two
   copies of it is how they drift apart. Decoration, so both render it as a span
   with aria-hidden rather than an <hr> that announces a thematic break. */
.de-gallery__rule,
.de-split__rule,
.de-team__rule{
  display:block;width:64px;height:3px;flex:none;
  margin:18px 0 22px;border-radius:2px;
  background:var(--de-action);
}
/* The split's copy column already carries a 12px flex gap, so the rule takes
   less of its own margin and both sections land on the same 18px / 22px. */
.de-split__rule{margin:6px 0 10px}

.de-gallery--split .de-gallery__intro{
  margin:0;max-width:var(--de-measure);color:var(--de-ink);
}
.de-gallery--split .de-gallery__intro p + p{margin-top:1em}
.de-gallery--split .de-gallery__cta{margin:26px 0 0}

/* Stacks at the same breakpoint as de-split, so the two sections on the home
   page break to one column together rather than a hundred pixels apart. */
@media (max-width:820px){
  .de-gallery--split .de-gallery__split{grid-template-columns:1fr}
  .de-gallery--split .de-gallery__copy{gap:0}
}
@media (max-width:600px){
  .de-gallery--split .de-gallery__cta .de-btn{width:100%}
  .de-gallery--split .de-gallery__cta{align-self:stretch}
  /* On a phone the column is narrower still, so they tighten again. The strip
     stays swipeable and the pause control stays put either way. */
  .de-gallery__dotrow{max-width:100%;gap:0}
  .de-gallery__dot{width:12px;height:20px;padding:2.5px}
  .de-gallery__dot::before{width:6px;height:6px}
}
@media (prefers-reduced-motion:reduce){
  .de-gallery__dot::before{transition:none}
}

/* ---- de-btn--solid -----------------------------------------------------
   A fourth variant, for the insurance CTA. The source's button is solid green
   with a blue hover, which is a different shape from --call (green, hovers to
   a lighter green) and from --verify (outline).

   NOT THE SOURCE'S SWATCH, DELIBERATELY. It specifies #95B640 with a white
   label — about 2.2:1, which is the unreadable button the palette work removed
   on purpose; --de-action-hover is that exact green, demoted to hover and
   on-dark use for this reason. This uses --de-action, the same green family at
   4.90:1. The hover is --de-link (#00729F, 5.37:1) rather than --de-brand
   (#0086BE, 4.07:1): the source hovers to blue, and this is the blue that
   clears AA at body size. Same design, readable. */
/* Tokenised for the same reason --verify and --quiet are: a dark ground
   declares its button colours once and nesting depth stops mattering.
   Enumerating dark contexts per component failed five times on this build. */
/* ---- de-insurance, carousel + centred -----------------------------------
   The source is an image-carousel: slides_to_show 4 over 5 logos, arrows
   sized 16px positioned outside, aria-label "Insurance logo slider", and
   Elementor's autoplay defaults. It had been rebuilt as a static grid, which
   lost the motion and the affordance both. The heading and the button both
   carry align:center in the source, so the whole section centres.
   ---------------------------------------------------------------------- */
.de-insurance{align-items:center;text-align:center}
.de-insurance__heading{margin-inline:auto}

/* THE GAP ABOVE THIS SECTION, AND WHY IT IS NOT THE PAGE RHYTHM.
   The source ran the tour section and this one together on ONE #FBFAF6 band
   with 100px of padding below the tour and 25px above the insurance heading —
   125px of air between the tour's button and this heading. Flattened onto
   white at the uniform --de-section-y (52px), the heading crowded a button
   sitting directly above it, which is what Jeff saw. The band is a separate
   question (five of the fourteen home sections had a background colour and the
   rebuild carries none of them); the SPACING is not, and it is fixed here
   rather than by loosening --de-section-y, which was tightened deliberately to
   bring the home page from 9034px down to 7845px. */
/* PADDING, not margin, and that is the point. The rhythm rule above is
   `.de-home > :not()....` — four :not(.class) arguments, so (0,5,0), which no
   sane selector here beats. It also sets margin-block on BOTH sides, so
   winning it would have widened the gap below this section too. Padding does
   not collapse, so it simply adds to the 52px: 52 + 44 = 96px at desktop,
   and the section below is untouched. */
.de-gallery + .de-insurance{padding-block-start:clamp(28px,3vw,44px)}

.de-insurance__rail{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(6px,1.2vw,16px);
  width:100%;max-width:var(--de-max-w);
}

/* Four across, sized off the track rather than a fixed min-width, so a logo
   never lands half-visible at the right edge — the thing that makes a logo
   row read as clipped rather than as scrollable. */
.de-insurance__logos{
  --de-ins-visible:4;
  --de-ins-gap:clamp(14px,2vw,28px);
  list-style:none;margin:0;padding:0;min-width:0;flex:1;
  display:grid;grid-auto-flow:column;
  grid-auto-columns:calc(
    (100% - (var(--de-ins-visible) - 1) * var(--de-ins-gap)) / var(--de-ins-visible)
  );
  gap:var(--de-ins-gap);align-items:center;
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  scrollbar-width:none;
}
.de-insurance__logos::-webkit-scrollbar{display:none}
/* Continuous marquee: snapping and a strip that never rests between logos are
   contradictory. Mandatory snap hauls scrollLeft back to the nearest column on
   every frame, which turns the glide into a stutter. Added by script only while
   it is actually gliding, so a page without JS keeps snap for manual swiping,
   and it comes off again once an arrow hands control to the visitor. */
.de-insurance__logos.is-marquee{scroll-snap-type:none}
.de-insurance__logos:focus-visible{outline:3px solid var(--de-brand);outline-offset:4px;border-radius:var(--de-radius)}

/* Four or fewer logos: nothing to scroll, so it stays the row it was. */
.de-insurance:not(.de-insurance--carousel) .de-insurance__logos{
  grid-auto-flow:row;
  grid-template-columns:repeat(auto-fit,minmax(120px,1fr));
  overflow:visible;
}

/* NO CARD. The live section sets its logos straight on the ground, and the
   box was costing 30px of width plus a border on each side — on the widest
   wordmark that is the difference between a legible logo and a smudge. */
.de-insurance__logo{
  scroll-snap-align:start;margin:0;min-width:0;
  display:flex;align-items:center;justify-content:center;
  padding:0 6px;min-height:104px;
}

/* SIZED FROM THE INK, NOT THE CANVAS.
   Every one of these files is a square with the artwork floating inside it,
   and the padding is not consistent: Aetna, beacon and GEHA are about a
   quarter ink by height, UMR and BCBS about six tenths. `max-height:44px`
   therefore rendered the three wordmarks at roughly ELEVEN PIXELS TALL while
   giving the other two nearly three times that from the same rule.

   de_logo_metrics() measures each file's ink box once and emits --de-logo-k,
   the multiplier that turns one target size into the width the whole canvas
   must occupy for the ARTWORK to come out at a consistent optical mass.

   Area, not height. Matching heights was tried first and under-sold the
   stacked lockups: UMR is a wordmark over a swoosh over a line of small print,
   so at a single-line wordmark's height each of its parts is a third the size,
   and it read as the small logo in the row. Area gives a wide mark its width
   and a stacked one its height — which is what the live site's own
   proportions work out to, within a few pixels, for all five.

   --de-logo-max is the width of the file being SERVED, so nothing is ever
   upscaled into a blur — UMR and BCBS are only 150px originals. */
.de-insurance__logos{--de-logo-size:clamp(68px,6.6vw,96px)}
.de-insurance__logo img{
  width:min(calc(var(--de-logo-size) * var(--de-logo-k,2)),var(--de-logo-max,300px),100%);
  height:auto;max-height:none;object-fit:contain;
}

/* Arrows outside the track, as arrows_position said. Same shape as the gallery
   strip's buttons so the page has one arrow, not two. */
.de-insurance__arrow{
  width:40px;height:40px;padding:0;flex:none;
  background:var(--de-white);border:1px solid var(--de-line);
  border-radius:var(--de-radius-sm);cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:border-color var(--de-transition),background var(--de-transition);
}
.de-insurance__arrow:hover{border-color:var(--de-link);background:var(--de-paper)}
.de-insurance__arrow:focus-visible{outline:2px solid var(--de-brand);outline-offset:2px}
.de-insurance__arrow span{
  width:9px;height:9px;
  border-right:2px solid var(--de-ink);border-bottom:2px solid var(--de-ink);
}
.de-insurance__arrow--prev span{transform:rotate(135deg) translate(-1px,-1px)}
.de-insurance__arrow--next span{transform:rotate(-45deg) translate(-1px,-1px)}

.de-insurance__controls{display:flex;align-items:center;justify-content:center;margin-top:2px}
.de-insurance__cta{margin:0}

@media (max-width:1024px){
  .de-insurance__logos{--de-ins-visible:3}
}
@media (max-width:760px){
  .de-insurance__logos{--de-ins-visible:2}
}
@media (max-width:600px){
  /* The arrows would take a third of the width off a 390px track. The strip is
     still swipeable and the pause control stays, so nothing is lost. */
  .de-insurance__arrow{display:none}
  .de-insurance__cta .de-btn{width:100%}
  .de-insurance__cta{align-self:stretch}
}

/* ---- de-cards, PHOTO band ----------------------------------------------
   The specialities section. Read off the source rather than the screenshot:
   a background image (image-4.webp) at `top center / cover`, under a #51661A
   overlay at 0.9 opacity, 50px of padding, a centred white heading, six cards
   with NO box of their own, each a 12px-radius photo above a centred white
   title and centred white copy, and a centred solid button underneath.

   THE WASH IS THE SOURCE'S #51661A AT 0.9, AND BOTH NUMBERS ARE LOAD-BEARING.
   It was first built with --de-action (#5F7A1E) on the reasoning that the two
   greens are a shade apart and one token keeps the page consistent. Measured,
   that substitution FAILS: composited over the lightest pixel a ground image
   can contain, white text lands at 4.03:1 against a 4.5:1 requirement. The
   source's darker green gives 5.09:1 against the same worst case.

   Worst case means a pure-white ground image, not this one. An editor can
   swap the picture, and the wash has to keep the copy legible whatever they
   choose — so the guarantee is computed against white rather than against
   the file that happens to be there today. Do not lighten either number.

   Two layers on one element, not a pair of pseudo-elements: the wash is a
   flat gradient stacked over the image in a single background-image, which is
   one paint instead of three stacked boxes.
   ---------------------------------------------------------------------- */
.de-cards--photo{
  background-color:#51661A;
  background-image:
    linear-gradient(rgba(81,102,26,.9),rgba(81,102,26,.9)),
    var(--de-cards-bg,none);
  background-position:center,top center;
  background-repeat:no-repeat,no-repeat;
  background-size:cover,cover;
  color:var(--de-white);
}

/* .de-cards--banded already centres and full-bleeds. What is left is the
   card chrome, which this band does not have. */
.de-cards--photo .de-card-item{
  background:none;border:0;border-radius:0;padding:0;
  text-align:center;align-items:center;gap:0;
  overflow:visible;
}
/* The --image rules pad the text away from a card edge that no longer exists. */
.de-cards--photo.de-cards--image .de-card-item > :not(.de-card-item__media),
.de-cards--photo.de-cards--image .de-card-item > :last-child{padding:0}

.de-cards--photo .de-card-item__media{width:100%}
.de-cards--photo .de-card-item__media img{
  /* 12px, from image_border_radius in the source. */
  border-radius:12px;
  aspect-ratio:16/9;
}
.de-cards--photo .de-card-item__medialink{
  display:block;border-radius:12px;overflow:hidden;
}

.de-cards--photo .de-card-item__title{
  margin-top:18px;color:var(--de-white);
  /* The source sets 2px of tracking on these. Kept, scaled to the size: it is
     what stops a two-line title reading as a paragraph. OUR face, though —
     Bricolage, not the source's Lato. */
  letter-spacing:.04em;font-weight:600;
}
/* No underline at rest, as the original has none. A card title is not a link
   inside a block of prose — it is the card's own name, sitting under its own
   photo — so the affordance is position and hover rather than a rule under
   every one of six headings. The focus ring below is the keyboard's version
   of the same thing. */
.de-cards--photo .de-card-item__title a{
  color:var(--de-white);text-decoration:none;
}
.de-cards--photo .de-card-item__title a:hover{
  color:var(--de-white);text-decoration:none;
}
.de-cards--photo .de-card-item__title a:focus-visible{outline:3px solid var(--de-white);outline-offset:3px;border-radius:2px}

/* WHITE, not a soft tint, and not --de-ink-mute.
   --de-ink-mute on this ground is nowhere near legible, which was obvious.
   The trap was the fix: #EAF0E2 looks like a gentler white and measures
   4.38:1 over the worst case, still under the 4.5:1 this 14px copy needs.
   Hierarchy here comes from size and weight, not from dimming the body. */
.de-cards--photo .de-card-item__body{
  color:var(--de-white);margin-top:10px;max-width:34ch;margin-inline:auto;
}

.de-cards--photo .de-cards__heading{color:var(--de-white)}
.de-cards--photo .de-cards__grid{gap:clamp(22px,2.6vw,34px) clamp(16px,2vw,26px)}
.de-cards--photo .de-cards__cta{display:flex;justify-content:center;margin-top:clamp(22px,2.6vw,34px)}

@media (max-width:600px){
  /* The paragraph has to be released before the button can fill it.
     `.de-cards--banded > *` gives every direct child margin-inline:auto to
     centre it inside the bleed, and an auto cross-axis margin DISABLES the
     flex stretch — so the paragraph shrank to fit its button and the
     button's width:100% dutifully filled 250px of it. It looked like the
     width rule was not applying; it was applying to the wrong parent. */
  .de-cards--photo .de-cards__cta{width:100%}
  .de-cards--photo .de-cards__cta .de-btn{width:100%}
}

/* ---- de-team, BANDED --------------------------------------------------
   The experts row. From the source: a #F8F8F8 band, a centred heading with the
   same divider the splits carry, three people across, each a 400x500 portrait
   over a centred name, a centred role and a "Read Bio" button, then a centred
   "Meet Our Team" underneath.

   --de-paper stands in for #F8F8F8. Unlike the specialities wash, no contrast
   decision turns on the exact shade here — it is dark text on a light tint
   either way — so the token wins and the page keeps one light band colour.
   ---------------------------------------------------------------------- */
.de-team--banded.de-team--paper{background:var(--de-paper)}
.de-team--banded{width:100%;align-items:center;text-align:center}
.de-team--banded .de-team__heading{margin-inline:auto}
.de-team--banded .de-team__rule{margin-inline:auto}

/* Three across on a band, not the auto-fill rail. The rail caps a member at
   244px, which is right for a sidebar-ish row on white and far too narrow for
   the full-width band the original uses — it left the three portraits huddled
   in the left third of the page. */
.de-team--banded .de-team__grid{
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(18px,2.4vw,32px);
  width:100%;
}
.de-team--banded .de-team__member{align-items:center;gap:6px}

/* 4:5, which is the source's 400x500 AND kinder to the files: every portrait
   in the library is between 2:3 and 3:4, so the 1/1 crop this replaces was
   cutting a third off a photograph that was already the right shape. */
.de-team--banded .de-team__photo{width:100%}
.de-team--banded .de-team__photo img{aspect-ratio:4/5}
.de-team__photolink{display:block;border-radius:var(--de-radius);overflow:hidden}

.de-team--banded .de-team__name{margin-top:14px}
.de-team--banded .de-team__role{margin-top:2px}
.de-team__bio{margin:14px 0 0}
.de-team--banded .de-team__cta{
  display:flex;justify-content:center;
  margin-top:clamp(24px,2.8vw,38px);
}

/* These two buttons used to be told apart by colour, the per-person link Grove
   and the section link blue. They are both primary now: the global system has
   two roles and neither of these is the secondary one. */
@media (max-width:820px){
  .de-team--banded .de-team__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  .de-team--banded .de-team__grid{grid-template-columns:minmax(0,1fr);max-width:340px;margin-inline:auto}
  .de-team--banded .de-team__cta{width:100%}
  .de-team--banded .de-team__cta .de-btn{width:100%}
}

/* ---- de-faq, PANEL layout ----------------------------------------------
   The home page FAQ. Read off the source: layout full_width, two 50% columns,
   50px of padding in each. The LEFT column carries a photograph
   (mental-health-therapies, #4148) with a #102D3A overlay at 0.8 over it and a
   centred white uppercase heading. The RIGHT column is solid #0086BF with a
   white accordion and a green button.

   THE TWO PANEL COLOURS ARE NOT THE SOURCE'S TWO HEXES, AND ONE OF THEM COULD
   NOT BE. Measured:
     left  #102D3A @0.8 over a white photo pixel -> white at 7.63:1. Fine, and
           --de-dark (#0E2A35) is a shade darker again at 7.92:1, so the token
           wins and the page keeps one dark.
     right #0086BF with a white label -> 4.07:1. That is the whole panel's body
           copy and every question title, under a 4.5:1 requirement. --de-link
           (#00729F) is the same blue at 5.37:1.
   ---------------------------------------------------------------------- */
.de-faq__main{display:flex;flex-direction:column;gap:18px}

/* Two halves, edge to edge, each as tall as the other. No gap: the colour
   change IS the division, exactly as the original has it. */
.de-faq--panel{
  display:grid;grid-template-columns:1fr 1fr;
  gap:0;align-items:stretch;
  max-width:none;
}

.de-faq--panel .de-faq__aside{
  display:flex;align-items:center;justify-content:center;
  padding:clamp(44px,5vw,64px);
  background-color:var(--de-dark);
  background-image:
    linear-gradient(rgba(14,42,53,.8),rgba(14,42,53,.8)),
    var(--de-faq-bg,none);
  background-position:center,center;
  background-repeat:no-repeat,no-repeat;
  background-size:cover,cover;
}

/* The source hard-breaks the title ("Frequently Asked Questions <br>(FAQ)").
   A measure does the same job without a <br> in the content, and it keeps
   working when the heading is edited. Uppercase and the tracking are the
   source's; the face is ours. */
.de-faq--panel .de-faq__heading{
  color:var(--de-white);text-align:center;
  font-size:clamp(28px,3vw,40px);font-weight:var(--de-fw-head);
  text-transform:uppercase;letter-spacing:.02em;
  line-height:1.14;max-width:20ch;
}

.de-faq--panel .de-faq__main{
  background:var(--de-link);
  padding:clamp(44px,5vw,64px);
  justify-content:center;gap:22px;
}

/* ---- the accordion on the blue panel ----
   The group's card chrome comes off: on a coloured ground a bordered white box
   is a second panel inside the panel. Hairlines between the questions stay,
   because they are what makes four rows read as a list. */
.de-faq--panel .de-accordion__group{
  border:0;border-radius:0;background:none;
  border-top:1px solid rgba(255,255,255,.28);
}
.de-faq--panel .de-accordion__item + .de-accordion__item{
  border-top:1px solid rgba(255,255,255,.28);
}
.de-faq--panel .de-accordion__item:last-child{
  border-bottom:1px solid rgba(255,255,255,.28);
}
.de-faq--panel .de-accordion__summary{padding:18px 4px}
.de-faq--panel .de-accordion__summary:hover{background:rgba(255,255,255,.08)}
.de-faq--panel .de-accordion__summary:focus-visible{
  outline:2px solid var(--de-white);outline-offset:-2px;
}
.de-faq--panel .de-accordion__title{color:var(--de-white)}
.de-faq--panel .de-accordion__body{padding:10px 4px 20px;color:var(--de-white)}
/* Links inside an answer are already handled by the on-dark link rule that
   data-ground turns on; this only lifts the underline off the blue. */
.de-faq--panel .de-accordion__body a{text-decoration-color:rgba(255,255,255,.6)}

/* The source turns its open-state icon green. Ours is the same chevron the
   rest of the site uses, white on the blue and green once open. */
.de-faq--panel .de-accordion__chev{
  border-right-color:var(--de-white);border-bottom-color:var(--de-white);
}
.de-faq--panel .de-accordion__item[open] .de-accordion__chev{
  border-right-color:var(--de-action-hover);border-bottom-color:var(--de-action-hover);
}

/* This button used to carry ink on the light green rather than white, because
   #95B642 with a white label is 2.32:1 and with --de-ink it is 6.38:1. It now
   takes the global primary treatment like every other button, so it inherits
   that 2.32:1 along with the rest of the site. Swapping the two primary
   tokens at the top of this file fixes it everywhere at once. */
.de-faq--panel .de-faq__cta{margin:0}
/* One column below the split. The photo panel keeps a real height rather than
   collapsing to the heading's line box, so it still reads as an image. */
@media (max-width:860px){
  .de-faq--panel{grid-template-columns:1fr}
  .de-faq--panel .de-faq__aside{min-height:220px;padding-block:clamp(36px,8vw,56px)}
  .de-faq--panel .de-faq__heading{max-width:none}
}
@media (max-width:600px){
  .de-faq--panel .de-faq__cta .de-btn{width:100%}
}

/* ---- de-btn--sm --------------------------------------------------------
   A compact button, for a control that repeats. Three full-size buttons in a
   row of teaser cards outweigh the headlines above them; the Read More is an
   affordance, not the section's action. */
.de-btn--sm{
  min-height:0;padding:9px 18px;
  font-size:var(--de-fs-small);
}

/* ---- de-blog-list, structure from the source ---------------------------
   The original is a tp-blog-post widget with align:center on the heading,
   posts_per_page 3 and tp_post_button "Read More". The block replaced the
   widget when TP Core was removed and dropped both the centring and the
   button.
   ---------------------------------------------------------------------- */
.de-bloglist{align-items:center}
.de-bloglist__heading{text-align:center;margin-inline:auto}
.de-bloglist__grid{width:100%}

/* EQUAL AIR ABOVE AND BELOW THE HEADING.

   The section's own top margin is --de-section-y, so 52px of space sits
   above this heading at 1440. Below it the flex gap gave 18px — the
   tightest heading-to-content gap on the page, and it read as the cards
   being stuck to the title.

   The same token on both sides, so the two are equal BY CONSTRUCTION rather
   than by a number that happens to match today and stops matching the next
   time the rhythm is retuned. --de-section-y was tightened once already,
   from clamp(56,7vw,96) to clamp(34,3.6vw,52), to bring the home page down
   from 9034px; if it moves again this follows it.

   row-gap only: the column gap is irrelevant in a one-column flex and
   setting `gap` would overwrite it anyway. */
.de-bloglist{row-gap:var(--de-section-y)}
.de-bloglist__cta{display:flex;justify-content:center;width:100%}

/* THE CARDS NOW ALIGN, WHICH IS THE HALF OF "STRUCTURE" A SCREENSHOT SHOWS
   AND A WIDGET CONFIG DOES NOT. The teasers were a plain flow, so a
   three-line headline pushed its byline 28px below its neighbours' and the
   row read as three unrelated columns. Stretched, with the button pushed to
   the bottom of whatever height the tallest card sets, the three Read Mores
   land on one line and the row reads as a row. */
.de-bloglist__item{
  display:flex;flex-direction:column;align-items:flex-start;
  height:100%;min-width:0;
}
.de-bloglist__grid{align-items:stretch}
/* auto, not a fixed margin: this is what does the pushing. A fixed top
   margin would leave the button wherever its own card's text ended. */
.de-bloglist__more{margin:auto 0 0;padding-top:18px}

/* The excerpt is what gives, not the button: it holds three lines and the
   card stays the height its title and photo need. wp_trim_words has already
   capped the words; this caps the LINES, which is what actually varies once
   the column width changes. */
.de-bloglist__excerpt{
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden;
}

@media (max-width:600px){
  .de-bloglist__cta .de-btn{width:100%}
}

/* ---- de-contact, THREE PANELS -----------------------------------------
   The source: layout full_width, structure 30, each 33% column carrying its
   own background — #95B6427D on the outer two and the brand green on the
   middle — with a 70px icon over a 14px uppercase label over a 26px value,
   centred, and 8%/14% of padding.

   #95B6427D is that green at alpha 0x7D, which is 49%, so on white it
   composites to exactly #CBDBA2. Written as the flat colour rather than as a
   translucent one: the panels sit on whatever the page ground is, and a
   translucent green over a dark section would be a different colour.

   THE TEXT IS NOT THE SOURCE'S GREEN, AND COULD NOT BE. Measured against
   #CBDBA2:
     --de-action  3.31:1   passes at 26px (large text, 3:1) and FAILS for the
                           14px uppercase label, which needs 4.5:1
     --de-ink    10.00:1   comfortable for both
   So the ICONS keep the green — they are non-text content, where 3:1 is the
   bar and 3.31 clears it — and the words are ink. The panel reads green; the
   copy is readable.
   ---------------------------------------------------------------------- */
.de-contact--panels{--de-contact-pale:#CBDBA2}

.de-contact--panels .de-contact__grid{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:0;width:100%;max-width:none;
  list-style:none;margin:0;padding:0;
}

/* No rule, no left border, no gap: the colour change is the division, exactly
   as it is on the FAQ panels. */
.de-contact--panels .de-contact__item{
  border:0;padding:clamp(30px,4.4vw,54px) clamp(18px,3.2vw,44px);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;gap:10px;min-width:0;
  background:var(--de-contact-pale);color:var(--de-ink);
}

/* nth-child, because any of the three is conditional on a Site Option being
   filled in — the middle panel is whichever one ends up in the middle. */
.de-contact--panels .de-contact__item:nth-child(2){
  background:var(--de-action);color:var(--de-white);
}

.de-contact--panels .de-contact__icon{
  width:clamp(42px,4.6vw,64px);height:clamp(42px,4.6vw,64px);
  color:var(--de-action);margin-bottom:2px;
}
.de-contact--panels .de-contact__item:nth-child(2) .de-contact__icon{color:var(--de-white)}

/* The label keeps OUR utility face; the source's size and tracking. */
.de-contact--panels .de-contact__label{
  display:block;font-family:var(--de-font-util);
  font-size:13px;letter-spacing:.1em;text-transform:uppercase;
  color:inherit;opacity:.85;
}

.de-contact--panels .de-contact__value{
  font-style:normal;line-height:1.35;
  font-size:clamp(18px,1.75vw,24px);
  color:inherit;
}
/* The values are links — the address to a map, the phone to a dial. They take
   the panel's own colour rather than the prose blue, which on either of these
   grounds is a different problem each time. */
.de-contact--panels .de-contact__value a{
  color:inherit;text-decoration-color:currentColor;text-underline-offset:3px;
}
.de-contact--panels .de-contact__value a:hover{text-decoration-thickness:2px}
.de-contact--panels .de-contact__value a:focus-visible{
  outline:3px solid currentColor;outline-offset:3px;
}

/* Two across, then one. The middle panel keeps its colour at every width, so
   the alternation survives the reflow rather than becoming two pale panels
   and an orphan. */
@media (max-width:860px){
  .de-contact--panels .de-contact__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  .de-contact--panels .de-contact__grid{grid-template-columns:minmax(0,1fr)}
}

/* ---- de-cta: in-content call-to-action band ----------------------------
   The band the closing band is not. See inc/de-cta.php for why it exists and
   why the palette is Deep Slate + Grove rather than the original's cyan.

   It fills the content column instead of bleeding the viewport: on an interior
   page the prose is a grid track beside the rail, and escaping that track needs
   negative margins that break the moment the rail is hidden. Same reason
   de-bleed is scoped to `.de-home > *`.
   -------------------------------------------------------------------- */
.de-cta{position:relative;border-radius:var(--de-radius);overflow:hidden}
.de-cta__inner{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:14px;
  max-width:var(--de-measure-wide);margin-inline:auto;
  padding-inline:var(--de-gutter);
}
.de-cta__title{
  font-family:var(--de-font-head);font-size:var(--de-fs-h2);font-weight:var(--de-fw-head);
  letter-spacing:-.015em;line-height:var(--de-lh-head);margin:0;
}
.de-cta__body p{margin:0}
.de-cta__body p + p{margin-top:.75em}
.de-cta__action{margin:6px 0 0}

/* Paper keeps the page's ink; Deep Slate and the photo scrim both take on-dark
   type, and the muted body colour is the closing band's so the two read as the
   same family rather than two different dark bands. */
.de-cta--paper .de-cta__title{color:var(--de-ink)}
.de-cta--paper .de-cta__body{color:var(--de-ink)}
.de-cta--dark .de-cta__title,
.de-cta--photo .de-cta__title{color:var(--de-white)}
.de-cta--dark .de-cta__body,
.de-cta--photo .de-cta__body{color:#C9DAE1}
.de-cta--dark .de-cta__body a,
.de-cta--photo .de-cta__body a{color:var(--de-brand-light)}

/* The photograph, under the closing band's scrim. Opacity stays high because
   white type has to clear AA over every part of an arbitrary image, not just
   the dark corner of this one. */
.de-cta--photo{
  background-image:var(--de-cta-bg);
  background-size:cover;background-position:center;
}
.de-cta--photo::before{
  content:"";position:absolute;inset:0;
  background:rgba(14,42,53,.88);
}
.de-cta--photo > *{position:relative}

@media (max-width:560px){
  .de-cta__action{width:100%}
  .de-cta__action .de-btn{width:100%}
}

/* ---- de-cards: image icon, per-card button, photo tiles ----------------
   See inc/de-cards-ext.php for why each of these exists.
   -------------------------------------------------------------------- */

/* The raster mark. Sized like the SVG icons it sits beside, and centred with
   the rest of the card rather than ranged left, because a 3-up row of marks
   reads as a row only if they line up. */
.de-card-item__mark{
  display:block;width:44px;height:auto;margin:0 auto 2px;
}
.de-cards--plain .de-card-item{text-align:center;align-items:center}
.de-cards--plain .de-card-item__title{margin-top:2px}

/* The button. Small, solid, and pushed to the bottom so a row of cards with
   copy of different lengths still has its buttons on one line. */
.de-card-item{justify-content:flex-start}
.de-card-item__action{margin:auto 0 0;padding-top:14px}
.de-cards--plain .de-card-item__action{margin-inline:auto}

/* Photo tiles: the card's own image behind the same scrim the closing band and
   de-cta use, with the copy on a panel so it stays legible over any part of an
   arbitrary photograph. */
.de-cards--tile .de-card-item{
  position:relative;overflow:hidden;border:0;padding:0;
  background:var(--de-dark) var(--de-tile-bg,none) center/cover no-repeat;
  min-height:300px;text-align:center;align-items:center;
  justify-content:flex-start;gap:0;
}
.de-cards--tile .de-card-item::before{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(14,42,53,.55) 0%,rgba(14,42,53,.82) 100%);
}
.de-cards--tile .de-card-item > *{position:relative}
.de-cards--tile .de-card-item__title{
  color:var(--de-white);padding:22px 20px 0;margin:0;
}
.de-cards--tile .de-card-item__body{
  color:var(--de-white);
  margin:14px 20px 0;padding:14px 16px;
  background:rgba(14,42,53,.55);border-radius:var(--de-radius);
}
.de-cards--tile .de-card-item__action{padding:18px 20px 22px}

@media (max-width:900px){
  .de-cards--tile .de-card-item{min-height:260px}
}
@media (max-width:600px){
  .de-cards--tile .de-card-item__action .de-btn{width:100%}
}

/* ---- card buttons, all one size ---------------------------------------
   Measured on the disorders grid: eight different widths between 143px and
   188px, and two heights (43px and 65px) depending on whether the label wrapped.
   A row of buttons that are each a different size reads as an accident.

   Width is the easy half — 100% of the card. Height is not: the card is 230px
   wide, so "Bipolar Disorder Treatment" cannot sit on one line at a readable
   size however the padding is tuned. So the label is allowed to wrap on a
   tighter leading, and min-height holds the one-line buttons to the same box.
   Every button in the grid is then identical, whether its label wraps or not.
   -------------------------------------------------------------------- */
.de-card-item__action{width:100%}
.de-card-item__action .de-btn{
  display:flex;width:100%;
  align-items:center;justify-content:center;
  min-height:56px;
  padding-block:8px;padding-inline:12px;
  line-height:1.25;text-align:center;
}

/* ---- CTA eyebrow ------------------------------------------------------- */

/* The label above a CTA band's heading. Utility face and upper case so it reads
   as a label rather than a second, smaller headline. */
.de-cta__eyebrow{
  margin:0 0 2px;font-family:var(--de-font-util);
  font-size:var(--de-fs-eyebrow);letter-spacing:var(--de-tr-eyebrow);
  text-transform:uppercase;
}
.de-cta--dark .de-cta__eyebrow,
.de-cta--photo .de-cta__eyebrow{color:var(--de-brand-light)}
.de-cta--paper .de-cta__eyebrow{color:var(--de-link)}

/* ---- prose with no rail beside it -------------------------------------
   The reading measure is deliberate: .de-prose caps its children at 36rem so a
   line of body copy stays about 68 characters. With the rail present the column
   is ~740px and a 576px paragraph sits comfortably inside it.

   With the rail hidden the column becomes the full 1116px, and those same
   paragraphs stayed ranged left — a 576px text block with 540px of nothing
   beside it, which is what the tour page looked like. Centre the capped
   children instead of widening them: the measure is worth keeping, the empty
   right-hand half is not.

   Blocks that set their own width — the gallery, a banded CTA, a lede — are
   untouched, because auto margins on a full-width element do nothing.
   -------------------------------------------------------------------- */
.de-interior--norail .de-prose > :where(p,ul,ol,h2,h3,h4,blockquote,figure,table){
  margin-inline:auto;
}

/* ---- centred prose, full column (opt-in per page) ---------------------
   See inc/de-prose-centred.php for why this is a field and not a rule hung off
   --norail, and for the readability trade-off it accepts.

   max-width:none releases the 36rem measure; text-align:center is the part the
   reference actually asks for. Blocks that set their own width — the gallery, a
   banded CTA — keep it, and they keep their own alignment too.
   -------------------------------------------------------------------- */
body.de-prose-centred .de-prose > :where(p,ul,ol,h2,h3,h4,blockquote){
  max-width:none;
  /* Undo the --norail auto margins: in a flex column they shrink the item
     to its text instead of filling the column, which left the blocks at
     five different widths. Fill the track, centre the text inside it. */
  margin-inline:0;
  width:100%;
  text-align:center;
}
/* A centred list with its markers hanging off to the left reads as broken, so
   the markers come inside and the items centre with the rest. */
body.de-prose-centred .de-prose > :where(ul,ol){
  padding-left:0;list-style-position:inside;align-items:center;
}

@media (max-width:720px){
  /* On a phone the column is already narrow, and centred body copy there is
     all cost and no benefit — the measure is doing nothing to fight. */
  body.de-prose-centred .de-prose > :where(p,ul,ol,blockquote){text-align:left}
  body.de-prose-centred .de-prose > :where(ul,ol){list-style-position:outside;padding-left:1.25em}
}
