/* ============================================================
   Madison Street Dental — responsive layer
   The dc-runtime has no breakpoint feature and all component
   styling is inline, so media queries live here and target
   `msd-*` classes added to the markup.
   Breakpoints: 820px = nav collapses, 700px = grids stack.
   ============================================================ */

/* ---------- guard ----------
   NOTE: deliberately NOT using `overflow-x:hidden` here. That would hide
   sideways scroll rather than fix it, and would also defeat the QA harness,
   which detects overflow via scrollWidth > clientWidth. Root causes are
   fixed instead. */
/* single source of truth for the sticky header height — anchor targets and
   anchor-scroll.js both offset by it so a deep link lands flush under the bar */
:root { --msd-header: 52px; }
*, *::before, *::after { box-sizing: border-box; }
main section[id], main [id].msd-contact-grid { scroll-margin-top: var(--msd-header) !important; }
img, svg, video { max-width: 100%; }

/* ---------- header ----------
   The dc-runtime wraps each component in its own .sc-host box. The header's
   host is only 53px tall, so `position:sticky` on the component root had no
   room to travel and scrolled away. Stickiness has to live on the HOST, whose
   parent is the full-height page div. Scoped with :has so only the header's
   host is affected — never the footer's or the page root's. */
.sc-host:has(> .msd-header-root) {
  position: sticky;
  top: 0;
  z-index: 60;
}

/* ---------- header ---------- */
.msd-burger { display: none; }

@media (max-width: 820px) {
  .msd-nav    { display: none !important; }
  .msd-cta    { display: none !important; }
  .msd-burger { display: inline-flex !important; }
  .msd-megamenu { grid-template-columns: 1fr 1fr !important; gap: 28px !important; }
  .msd-resmenu  { grid-template-columns: 1fr 1fr !important; gap: 26px !important; }
}

/* Drop the "DENTAL CLINIC" lockup until there is genuinely room for it.
   Measured widths in the bar: "Madison Street" ~150px + "DENTAL CLINIC" ~109px
   + phone 121px + burger 44px + 44px padding + 16px gaps = ~484px needed.
   Hidden below 520px, which covers every common phone (320/390/414/430) with
   margin. Both spans are white-space:nowrap, so without this they overflow the
   flex-shrunk logo link and collide with the phone number. */
@media (max-width: 520px) {
  .msd-logo-sub { display: none !important; }
}

/* Hard guard: if the logo link is ever squeezed, clip rather than overlap.
   Vertical padding brings the 18px-tall lockup to a 44px tap target (WCAG
   2.5.8); it sits inside the 52px bar so nothing shifts. */
.msd-bar > a:first-child {
  overflow: hidden;
  padding-top: 13px;
  padding-bottom: 13px;
}

/* ---------- Home: one continuous dark block at the foot of the page ----------
   The closing CTA band and the footer share #1d1d1f so the page ends in a
   single field of black instead of a band followed by a grey slab. The footer's
   address/phone/hours strip is hidden HERE ONLY — the CTA directly above it
   states all three, so on this page it was pure repetition. Every other page
   keeps the standard light footer with its contact strip. */
.msd-home .msd-footer-root { background: #1d1d1f !important; color: #a1a1a6 !important; }
.msd-home .msd-foot-contact { display: none !important; }
.msd-home .msd-footer-root h2 { color: #f5f5f7 !important; }
.msd-home .msd-footer-root a { color: #cfcfd4 !important; }
.msd-home .msd-foot-grid { border-bottom-color: rgba(255,255,255,0.14) !important; padding-top: 4px !important; }

/* ---------- footer membership badges ----------
   Equal-size tiles so the chips align on a grid: the logos have wildly
   different aspect ratios (ADA is squarish, Seattle Study Club is very wide),
   so sizing by height alone produced ragged rows. Each tile is now identical
   and the logo is contained inside it. */
.msd-badges { max-width: 190px; }
/* ADA and WSDA sit side by side; the two wide marks span BOTH columns, so every
   row shares the same left and right edge instead of ending raggedly. */
.msd-badges span:nth-child(n+3) { grid-column: 1 / -1; }
.msd-badges span:nth-child(-n+2) { height: 52px; }
@media (max-width: 700px) { .msd-badges { max-width: 230px; margin: 0 auto; } }

/* ---------- review cards ---------- */
@media (max-width: 900px) { .msd-reviews { grid-template-columns: 1fr 1fr !important; } }
@media (max-width: 620px) { .msd-reviews { grid-template-columns: 1fr !important; } }

/* ---------- grids that must stack ---------- */
@media (max-width: 700px) {
  .msd-contact-grid { grid-template-columns: 1fr !important; }
  .msd-megamenu     { grid-template-columns: 1fr !important; }
  .msd-resmenu      { grid-template-columns: 1fr !important; }
}

/* Schedule page: the two booking options stay side by side while there is room
   for both to be seen at once, which is the whole point of the page. They stack
   at 860px -- earlier than the 700px grids -- because each card carries a
   heading, a definition box, a list and a control, and two of those squeezed
   into half a tablet reads as clutter rather than a choice. */
@media (max-width: 860px) {
  .msd-book-grid { grid-template-columns: 1fr !important; }
}
@media (max-width: 700px) {
  .msd-twofig { grid-template-columns: 1fr !important; }
}
@media (max-width: 480px) {
  .msd-book-fields { grid-template-columns: 1fr !important; }
  .msd-book-grid   { padding-left: 16px !important; padding-right: 16px !important; gap: 18px !important; }
  .msd-book-grid > div { padding: 26px 22px !important; }
}

/* ---------- mobile type + rhythm ---------- */
@media (max-width: 700px) {
  .msd-section { padding-left: 20px !important; padding-right: 20px !important; }
}

/* Reading material set at desktop scale is cramped on a phone. These are the
   places with actual sentences (not labels) under 15px. Phone-only; desktop
   is untouched.
   The footer contact line matters most: it carries the address and the phone
   number, it appears on all 33 pages, and at 12px it was the smallest real
   text on the site. */
@media (max-width: 700px) {
  .msd-foot-contact { font-size: 15px !important; }
  .msd-foot-grid    { font-size: 13px !important; }
  nav[aria-label="Breadcrumb"] ol { font-size: 15px !important; }
  /* Schedule page carries the same kind of small print as the contact card */
  .msd-book-grid label,
  .msd-book-grid .msd-formnote { font-size: 15px !important; }
}

/* Contact card + form were set at desktop scale (14.5px body, 13.5px field
   labels, 12.5px note). Those read fine on a laptop and are cramped on a
   phone, where this is the page people actually use. Phone-only step up;
   desktop is untouched. */
@media (max-width: 700px) {
  .msd-contact-grid p,
  .msd-contact-grid a       { font-size: 16px !important; line-height: 1.55 !important; }
  .msd-contact-grid label   { font-size: 15px !important; }
  .msd-contact-grid .msd-formnote { font-size: 15px !important; }
  .msd-quickcards p, .msd-quickcards a { font-size: 16px !important; }
  .msd-contact-grid input,
  .msd-contact-grid textarea,
  .msd-contact-grid select  { font-size: 16px !important; }  /* < 16px makes iOS zoom the page on focus */
}

/* ---------- tap targets ----------
   WCAG 2.5.8 (AA) requires 24x24 CSS px. The header phone number is the
   primary conversion action on mobile, so it gets the full 44px comfort
   target; footer links are brought up over the 24px AA floor without
   ballooning footer height. */
@media (max-width: 820px) {
  .msd-phone {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}
/* Footer link targets apply at EVERY width — the links are 15px tall with a 9px
   gap by default, which fails the 24px AA floor on desktop just as it does on
   mobile. Scoping this to mobile only was a bug. */
.msd-foot-col { gap: 0 !important; }
.msd-foot-col a {
  padding-top: 6px;
  padding-bottom: 6px;
  min-height: 24px;
  display: flex;
  align-items: center;
}

/* ---------- full-bleed hero (Option A, chosen 2026-09-02) ----------
   The dc-runtime keeps component styling inline, but the hero needs
   different geometry, gradient direction, and text placement per
   breakpoint, so the whole block lives here like .msd-foot-col does.
   Dark background-color doubles as the image-loading fallback AND the
   base the contrast checker resolves white text against. */
.msd-hero {
  position: relative;
  min-height: 600px;
  height: calc(100vh - 52px);   /* fallback */
  height: calc(100svh - 52px);  /* fill the first screen exactly; 52px sticky header */
  overflow: hidden;
  display: flex;
  align-items: center;
  background-color: #241b12;
}
.msd-hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 30%;
}
.msd-hero-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
    rgba(24,18,12,0.78) 0%, rgba(24,18,12,0.55) 34%,
    rgba(24,18,12,0.08) 62%, rgba(24,18,12,0) 78%);
}
.msd-hero-content {
  position: relative;
  width: 100%;
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 40px;
}
.msd-hero-inner {
  max-width: 560px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: flex-start;
  text-align: left;
}
@media (max-width: 880px) {
  /* phones/narrow: face stays visible up top, text drops to the bottom
     over a bottom-up gradient instead of the left scrim */
  .msd-hero { height: auto; min-height: calc(100svh - 52px); align-items: flex-end; }
  .msd-hero-img { object-position: 62% 20%; }
  .msd-hero-scrim {
    background: linear-gradient(180deg,
      rgba(24,18,12,0) 20%, rgba(24,18,12,0.45) 48%,
      rgba(24,18,12,0.88) 84%);
  }
  .msd-hero-content { padding: 0 20px 38px; }
}

/* ---------- person bands (Meet Us) ----------
   Big portrait panel with the bio beside it, sides alternating down the page.
   Bio copy is LEFT-aligned by design: a narrow column beside a photo reads
   badly centred (the sitewide centred-prose rule is for full-width columns).
   Below 860px the band stacks, photo first, and the text centres to match the
   rest of the site. */
.msd-person { padding: 68px 22px; }
.msd-person + .msd-person { padding-top: 8px; }
.msd-person-inner {
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
  gap: 58px;
  align-items: center;
}
.msd-person-photo {
  width: 100%;
  aspect-ratio: 4 / 5;
  height: auto;
  object-fit: cover;
  border-radius: 24px;
  display: block;
  background: #f4efe8;
  box-shadow: 0 22px 56px rgba(40, 28, 18, 0.16);
}
.msd-person.rev .msd-person-inner { grid-template-columns: minmax(0, 1.14fr) minmax(0, 0.86fr); }
.msd-person-text p:last-child { margin-bottom: 0; }
@media (max-width: 860px) {
  .msd-person { padding: 44px 22px; }
  .msd-person-inner,
  .msd-person.rev .msd-person-inner { grid-template-columns: 1fr; gap: 28px; }
  .msd-person.rev .msd-person-photo { order: -1; }
  .msd-person-photo { max-width: 420px; margin: 0 auto; }
  .msd-person-text { text-align: center; }
}

/* ---------- home service tiles: one row of four ----------
   Four categories read as a single row of peers rather than a 2x2 block that
   ran past the fold. Cards are compact: the photo keeps a fixed ratio so all
   four line up, and the grid steps 4 -> 2 -> 1 as width runs out. */
.msd-tiles h2 { font-size: 21px; }
/* The four descriptions are different lengths. Letting the paragraph absorb the
   slack keeps every card's CTA and photo on the same line across the row --
   the cards are already equal height (grid stretch), so without this the
   shorter blurbs float their photo higher than the rest. */
.msd-tiles p  { font-size: 14.5px; flex: 1 1 auto; display: flex; align-items: center; }
.msd-tiles img { aspect-ratio: 16/10; margin-top: 12px !important; }
@media (max-width: 1180px) and (min-width: 861px) {
  .msd-tiles { grid-template-columns: repeat(2, 1fr) !important; max-width: 820px !important; }
}
@media (max-width: 860px) and (min-width: 621px) {
  .msd-tiles { grid-template-columns: repeat(2, 1fr) !important; }
}

/* ---------- full-bleed person bands (Meet Us v2 preview) ----------
   Same construction as the home hero: photo covers the whole band, scrim
   carries the type. Height is min- not fixed, so long bios grow the band
   instead of clipping. Portrait sources in a landscape band are cropped
   VERTICALLY only (cover scales by width), so object-position tunes the
   face; horizontal position has no effect. Dark background-color doubles as
   loading fallback and the base the contrast checker resolves against. */
.msd-p2 {
  position: relative;
  /* Height is DERIVED from width (56.25vw = 16:9, matching the composed art)
     but capped at one screen. Setting aspect-ratio instead made the band
     narrower than the viewport once max-height bit — the width was derived
     from the capped height and full-bleed broke. */
  /* The screen-derived height is a FLOOR, not a cap: when the bio needs
     more lines (short window, bookmarks bar, large zoom) the band grows
     instead of clipping the last line against overflow:hidden. */
  height: auto;
  min-height: max(660px, min(calc(100svh - 52px), 62vw));
  display: flex;
  /* flex-start, not center: centring made each bio start at a different
     height depending on its length. Both bands now anchor the text 92px
     from the band top, and the matching bottom padding keeps a grown band
     from ending flush against its edge. */
  align-items: flex-start;
  overflow: hidden;
  background-color: #241b12;
  padding: 92px 0 92px;
}
/* The photo lives in its own transparent wrapper. Sitting directly inside the
   dark section made it read as "media not filling a painted box" on mobile,
   where the photo is a top band and the copy fills the rest by design. */
.msd-p2-media { position: absolute; inset: 0; }
.msd-p2-img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Dr E's band art is a composed 16:9 frame (he stands right of centre, the
     copy sits over the building on the left) so it needs no vertical nudge. */
  object-position: 50% 50%;
}
.msd-p2.rev .msd-p2-img { object-position: 50% 6%; }
.msd-p2-scrim {
  position: absolute; inset: 0;
  /* Radial, anchored off the left edge. A linear ramp had to fall 0.90 -> 0
     within ~90px to stay off him, and that straight edge landed on the wall
     beside the door — it read as a seam. A curved falloff spreads the same
     transition over a longer, non-parallel path, so no architectural line
     coincides with it and the wash reads as light falling away. */
  background: linear-gradient(90deg, rgba(14,10,7,0.68) 0%, rgba(14,10,7,0.68) 2%, rgba(14,10,7,0.68) 4%, rgba(14,10,7,0.68) 6%, rgba(14,10,7,0.68) 8%, rgba(14,10,7,0.68) 10%, rgba(14,10,7,0.68) 12%, rgba(14,10,7,0.68) 14%, rgba(14,10,7,0.68) 16%, rgba(14,10,7,0.68) 18%, rgba(14,10,7,0.68) 20%, rgba(14,10,7,0.68) 22%, rgba(14,10,7,0.68) 24%, rgba(14,10,7,0.68) 26%, rgba(14,10,7,0.68) 28%, rgba(14,10,7,0.68) 30%, rgba(14,10,7,0.674) 32%, rgba(14,10,7,0.641) 34%, rgba(14,10,7,0.569) 36%, rgba(14,10,7,0.464) 38%, rgba(14,10,7,0.34) 40%, rgba(14,10,7,0.216) 42%, rgba(14,10,7,0.111) 44%, rgba(14,10,7,0.039) 46%, rgba(14,10,7,0.006) 48%, rgba(14,10,7,0.0) 50%, rgba(14,10,7,0.0) 52%, rgba(14,10,7,0.0) 54%, rgba(14,10,7,0.0) 56%, rgba(14,10,7,0.0) 57%, rgba(14,10,7,0.0) 60%, rgba(14,10,7,0.0) 62%, rgba(14,10,7,0.0) 64%, rgba(14,10,7,0.0) 66%, rgba(14,10,7,0.0) 68%, rgba(14,10,7,0.0) 70%, rgba(14,10,7,0.0) 72%, rgba(14,10,7,0.0) 74%, rgba(14,10,7,0.0) 76%, rgba(14,10,7,0.0) 78%, rgba(14,10,7,0.0) 80%, rgba(14,10,7,0.0) 82%, rgba(14,10,7,0.0) 84%, rgba(14,10,7,0.0) 86%, rgba(14,10,7,0.0) 88%, rgba(14,10,7,0.0) 90%, rgba(14,10,7,0.0) 92%, rgba(14,10,7,0.0) 94%, rgba(14,10,7,0.0) 96%, rgba(14,10,7,0.0) 98%, rgba(14,10,7,0.0) 100%);
}
.msd-p2.rev .msd-p2-scrim {
  background: linear-gradient(270deg, rgba(14,10,7,0.68) 0%, rgba(14,10,7,0.68) 2%, rgba(14,10,7,0.68) 4%, rgba(14,10,7,0.68) 6%, rgba(14,10,7,0.68) 8%, rgba(14,10,7,0.68) 10%, rgba(14,10,7,0.68) 12%, rgba(14,10,7,0.68) 14%, rgba(14,10,7,0.68) 16%, rgba(14,10,7,0.68) 18%, rgba(14,10,7,0.68) 20%, rgba(14,10,7,0.68) 22%, rgba(14,10,7,0.68) 24%, rgba(14,10,7,0.68) 26%, rgba(14,10,7,0.68) 28%, rgba(14,10,7,0.68) 30%, rgba(14,10,7,0.674) 32%, rgba(14,10,7,0.641) 34%, rgba(14,10,7,0.569) 36%, rgba(14,10,7,0.464) 38%, rgba(14,10,7,0.34) 40%, rgba(14,10,7,0.216) 42%, rgba(14,10,7,0.111) 44%, rgba(14,10,7,0.039) 46%, rgba(14,10,7,0.006) 48%, rgba(14,10,7,0.0) 50%, rgba(14,10,7,0.0) 52%, rgba(14,10,7,0.0) 54%, rgba(14,10,7,0.0) 56%, rgba(14,10,7,0.0) 57%, rgba(14,10,7,0.0) 60%, rgba(14,10,7,0.0) 62%, rgba(14,10,7,0.0) 64%, rgba(14,10,7,0.0) 66%, rgba(14,10,7,0.0) 68%, rgba(14,10,7,0.0) 70%, rgba(14,10,7,0.0) 72%, rgba(14,10,7,0.0) 74%, rgba(14,10,7,0.0) 76%, rgba(14,10,7,0.0) 78%, rgba(14,10,7,0.0) 80%, rgba(14,10,7,0.0) 82%, rgba(14,10,7,0.0) 84%, rgba(14,10,7,0.0) 86%, rgba(14,10,7,0.0) 88%, rgba(14,10,7,0.0) 90%, rgba(14,10,7,0.0) 92%, rgba(14,10,7,0.0) 94%, rgba(14,10,7,0.0) 96%, rgba(14,10,7,0.0) 98%, rgba(14,10,7,0.0) 100%);
}
.msd-p2-content {
  position: relative;
  /* The copy sits toward the band's left edge. A fixed centred container
     pushed it inward on wide screens and squeezed the gap to his figure
     (11px at 2560). Width now tracks the viewport so the gap holds. */
  width: 100%; max-width: 1560px;
  margin: 0 auto; padding: 0 clamp(26px, 4.5vw, 96px);
  box-sizing: border-box;
}
.msd-p2.rev .msd-p2-content { display: flex; justify-content: flex-end; }
.msd-p2-inner { max-width: 376px; text-align: left;
  text-shadow: 0 1px 4px rgba(10,7,4,0.7), 0 0 22px rgba(10,7,4,0.45); }
@media (max-width: 880px) {
  /* photo on top, copy below on the dark base — a full-height photo with a
     four-paragraph bio over it is unreadable on a phone */
  /* height must return to auto here: the desktop rule sets a FIXED height
     (min(100svh-52, 62vw)) and on a narrow screen that is far shorter than
     photo + bio, so the content overflowed into the next section. */
  .msd-p2 { height: auto; min-height: 0; display: block; padding: 0 0 44px; }
  /* portrait frame + landscape art: cover crops HORIZONTALLY here, so each
     image is anchored on its own subject (composed at 68% / 33% of width) */
  .msd-p2-media { position: relative; height: 52svh; }
  /* portrait frame on phones crops the landscape art horizontally — anchor on him */
  .msd-p2-img { object-position: 68% 50%; }
  .msd-p2.rev .msd-p2-img { object-position: 50% 10%; }
  .msd-p2-scrim { display: none; }
  .msd-p2-content { padding: 26px 22px 0; }
  .msd-p2.rev .msd-p2-content { display: block; }
  .msd-p2-inner { max-width: none; text-align: center; }
}

/* ---------- v2 preview: uninterrupted photo band + bio beneath ----------
   Him and the sign sit at opposite edges of the frame, so no copy can overlay
   the photo without covering one of them. The photo gets its own band and the
   bio follows underneath. */
.msd-photoband { position: relative; width: 100%; height: min(62svh, 44vw); min-height: 320px; overflow: hidden; background: #241b12; }
.msd-photoband-img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; display: block; }
.msd-bio { padding: 54px 22px 60px; }
.msd-bio-inner { max-width: 760px; margin: 0 auto; text-align: center; }
.msd-bio-inner h1 { font-size: clamp(32px, 4vw, 46px) !important; }
@media (max-width: 700px) { .msd-photoband { height: 46svh; } .msd-bio { padding: 34px 20px 44px; } }

/* ---------- memberships marquee ----------
   Slow continuous logo carousel. The track holds the set TWICE and shifts by
   exactly one cycle — (total width + one gap) / 2 = 50% + half a gap — so the
   loop is seamless with no visible jump. Edges fade out via mask so logos
   enter/leave softly instead of being chopped by the container edge.
   WCAG 2.2.2 (Pause, Stop, Hide): pauses on hover AND keyboard focus, and is
   fully static under prefers-reduced-motion (rule below the global motion
   block, with !important, so it wins). */
.msd-marquee {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.msd-membs {
  animation: msd-marquee 46s linear infinite;
  will-change: transform;
}
.msd-marquee:hover .msd-membs,
.msd-marquee:focus-within .msd-membs { animation-play-state: paused; }
@keyframes msd-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - 27px)); }
}
@media (max-width: 700px) {
  .msd-membs { gap: 40px !important; }
  @keyframes msd-marquee {
    from { transform: translateX(0); }
    to   { transform: translateX(calc(-50% - 20px)); }
  }
}

/* ---------- accessibility: visible keyboard focus everywhere ---------- */
:focus-visible {
  outline: 2px solid #c14f24;
  outline-offset: 2px;
  border-radius: 6px;
}

/* ---------- respect reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- ultra-narrow phones (iPhone SE 1st gen, 320px) ----------
   At 320px the bar needs: logo 125 + phone 121 + burger 44 + 44 padding +
   16 gaps = 350px, which overflows. Tighten padding and logo size so
   everything fits rather than clipping. */
@media (max-width: 360px) {
  .msd-bar { padding-left: 12px !important; padding-right: 12px !important; gap: 4px !important; }
  .msd-bar > a:first-child span { font-size: 17px !important; }
  /* the header type was stepped up sitewide (nav/phone 13 -> 15px); at 320px
     that pushed the phone number into the wordmark, so it steps back down
     here only */
  .msd-phone { font-size: 13px !important; padding-left: 6px !important; padding-right: 6px !important; }
  /* Call link and menu button ended up 4px apart here -- inside WCAG 2.5.8's
     spacing allowance, but a 4px gap between "dial the practice" and "open the
     menu" is a real mis-tap on a 320px phone. Trade side padding for margin so
     the gap triples without making the bar any wider. */
  .msd-phone { padding-left: 4px !important; padding-right: 4px !important; margin-right: 8px !important; }
}

/* memberships strip: equal-gap flex row, wraps naturally on small screens */
@media (max-width: 700px) {
  .msd-membs { gap: 34px !important; }
  /* The society logos are set 142-237px wide from 350-611px source files. At
     dpr3 the Snohomish badge needed 678 device px from a 464px file and went
     soft; 226px is also over half the screen for one decorative logo. Capping
     brings every badge back above its own pixel density AND fits more of the
     strip on screen. */
  .msd-membs img { max-width: 150px !important; }
}

/* marquee must be genuinely static (not merely fast) for reduced-motion users */
@media (prefers-reduced-motion: reduce) {
  .msd-membs {
    animation: none !important;
    transform: none !important;
    width: 100% !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
  }
  .msd-membs a[aria-hidden="true"] { display: none !important; }
  .msd-marquee { -webkit-mask-image: none; mask-image: none; }
}

/* ---------- white-wash variant (preview) ----------
   Same analytic falloff as the dark band, inverted: a light wash needs DARK
   copy, so the type flips with it. Coral eyebrow stays — it reads on light. */
.msd-lightscrim .msd-p2-scrim {
  /* Warm light wash: a gentle PLATEAU across the copy (0.60, not the 1.00 that
     read as a white panel), then an analytic release. The plateau matters —
     without it the copy's right edge fell to 0.37 over dark brick and dark
     type measured 3.2:1 there. */
  background: linear-gradient(90deg, rgba(250,247,241,0.6) 0%, rgba(250,247,241,0.6) 2%, rgba(250,247,241,0.6) 4%, rgba(250,247,241,0.6) 6%, rgba(250,247,241,0.6) 8%, rgba(250,247,241,0.6) 10%, rgba(250,247,241,0.6) 12%, rgba(250,247,241,0.6) 14%, rgba(250,247,241,0.6) 16%, rgba(250,247,241,0.6) 18%, rgba(250,247,241,0.6) 20%, rgba(250,247,241,0.6) 22%, rgba(250,247,241,0.6) 24%, rgba(250,247,241,0.6) 26%, rgba(250,247,241,0.6) 28%, rgba(250,247,241,0.599) 30%, rgba(250,247,241,0.596) 32%, rgba(250,247,241,0.588) 34%, rgba(250,247,241,0.573) 36%, rgba(250,247,241,0.551) 38%, rgba(250,247,241,0.523) 40%, rgba(250,247,241,0.487) 42%, rgba(250,247,241,0.446) 44%, rgba(250,247,241,0.4) 46%, rgba(250,247,241,0.351) 48%, rgba(250,247,241,0.3) 50%, rgba(250,247,241,0.249) 52%, rgba(250,247,241,0.2) 54%, rgba(250,247,241,0.154) 56%, rgba(250,247,241,0.113) 58%, rgba(250,247,241,0.077) 60%, rgba(250,247,241,0.049) 62%, rgba(250,247,241,0.027) 64%, rgba(250,247,241,0.012) 66%, rgba(250,247,241,0.004) 68%, rgba(250,247,241,0.001) 70%, rgba(250,247,241,0.0) 72%, rgba(250,247,241,0.0) 74%, rgba(250,247,241,0.0) 76%, rgba(250,247,241,0.0) 78%, rgba(250,247,241,0.0) 80%, rgba(250,247,241,0.0) 82%, rgba(250,247,241,0.0) 84%, rgba(250,247,241,0.0) 86%, rgba(250,247,241,0.0) 88%, rgba(250,247,241,0.0) 90%, rgba(250,247,241,0.0) 92%, rgba(250,247,241,0.0) 94%, rgba(250,247,241,0.0) 96%, rgba(250,247,241,0.0) 98%, rgba(250,247,241,0.0) 100%);
}
.msd-lightscrim .msd-p2.rev .msd-p2-scrim {
  background: linear-gradient(270deg, rgba(250,247,241,0.6) 0%, rgba(250,247,241,0.6) 2%, rgba(250,247,241,0.6) 4%, rgba(250,247,241,0.6) 6%, rgba(250,247,241,0.6) 8%, rgba(250,247,241,0.6) 10%, rgba(250,247,241,0.6) 12%, rgba(250,247,241,0.6) 14%, rgba(250,247,241,0.6) 16%, rgba(250,247,241,0.6) 18%, rgba(250,247,241,0.6) 20%, rgba(250,247,241,0.6) 22%, rgba(250,247,241,0.6) 24%, rgba(250,247,241,0.6) 26%, rgba(250,247,241,0.6) 28%, rgba(250,247,241,0.599) 30%, rgba(250,247,241,0.596) 32%, rgba(250,247,241,0.588) 34%, rgba(250,247,241,0.573) 36%, rgba(250,247,241,0.551) 38%, rgba(250,247,241,0.523) 40%, rgba(250,247,241,0.487) 42%, rgba(250,247,241,0.446) 44%, rgba(250,247,241,0.4) 46%, rgba(250,247,241,0.351) 48%, rgba(250,247,241,0.3) 50%, rgba(250,247,241,0.249) 52%, rgba(250,247,241,0.2) 54%, rgba(250,247,241,0.154) 56%, rgba(250,247,241,0.113) 58%, rgba(250,247,241,0.077) 60%, rgba(250,247,241,0.049) 62%, rgba(250,247,241,0.027) 64%, rgba(250,247,241,0.012) 66%, rgba(250,247,241,0.004) 68%, rgba(250,247,241,0.001) 70%, rgba(250,247,241,0.0) 72%, rgba(250,247,241,0.0) 74%, rgba(250,247,241,0.0) 76%, rgba(250,247,241,0.0) 78%, rgba(250,247,241,0.0) 80%, rgba(250,247,241,0.0) 82%, rgba(250,247,241,0.0) 84%, rgba(250,247,241,0.0) 86%, rgba(250,247,241,0.0) 88%, rgba(250,247,241,0.0) 90%, rgba(250,247,241,0.0) 92%, rgba(250,247,241,0.0) 94%, rgba(250,247,241,0.0) 96%, rgba(250,247,241,0.0) 98%, rgba(250,247,241,0.0) 100%);
}
.msd-lightscrim .msd-p2-inner { text-shadow: 0 1px 2px rgba(255,255,255,0.9), 0 0 14px rgba(255,255,255,0.6); }
.msd-lightscrim .msd-p2-inner h1,
.msd-lightscrim .msd-p2-inner h2 { color: #1d1d1f !important; }
.msd-lightscrim .msd-p2-inner p { color: #1d1d1f !important; }
.msd-lightscrim .msd-p2-inner p:first-child { color: #b3491f !important; }
.msd-lightscrim .msd-p2 { background-color: #e8e3da; }

/* ---------- pinned: the pre-2026-09-14 scrim ----------
   _Meet Us white and _Meet Us v2 sign were saved to compare gradient
   treatments. The live scrim was lightened (0.85 -> 0.68, released by
   50% instead of trailing to 62%) because the band read as too dark;
   these two keep the wash they were saved with. */
.msd-scrim-v1 .msd-p2-scrim {
  background: linear-gradient(90deg, rgba(14,10,7,0.85) 0%, rgba(14,10,7,0.85) 2%, rgba(14,10,7,0.85) 4%, rgba(14,10,7,0.85) 6%, rgba(14,10,7,0.85) 8%, rgba(14,10,7,0.85) 10%, rgba(14,10,7,0.85) 12%, rgba(14,10,7,0.85) 14%, rgba(14,10,7,0.85) 16%, rgba(14,10,7,0.85) 18%, rgba(14,10,7,0.849) 20%, rgba(14,10,7,0.844) 22%, rgba(14,10,7,0.833) 24%, rgba(14,10,7,0.812) 26%, rgba(14,10,7,0.781) 28%, rgba(14,10,7,0.74) 30%, rgba(14,10,7,0.69) 32%, rgba(14,10,7,0.632) 34%, rgba(14,10,7,0.567) 36%, rgba(14,10,7,0.497) 38%, rgba(14,10,7,0.425) 40%, rgba(14,10,7,0.353) 42%, rgba(14,10,7,0.283) 44%, rgba(14,10,7,0.218) 46%, rgba(14,10,7,0.16) 48%, rgba(14,10,7,0.11) 50%, rgba(14,10,7,0.069) 52%, rgba(14,10,7,0.038) 54%, rgba(14,10,7,0.017) 56%, rgba(14,10,7,0.006) 58%, rgba(14,10,7,0.001) 60%, rgba(14,10,7,0.0) 62%, rgba(14,10,7,0.0) 64%, rgba(14,10,7,0.0) 66%, rgba(14,10,7,0.0) 68%, rgba(14,10,7,0.0) 70%, rgba(14,10,7,0.0) 72%, rgba(14,10,7,0.0) 74%, rgba(14,10,7,0.0) 76%, rgba(14,10,7,0.0) 78%, rgba(14,10,7,0.0) 80%, rgba(14,10,7,0.0) 82%, rgba(14,10,7,0.0) 84%, rgba(14,10,7,0.0) 86%, rgba(14,10,7,0.0) 88%, rgba(14,10,7,0.0) 90%, rgba(14,10,7,0.0) 92%, rgba(14,10,7,0.0) 94%, rgba(14,10,7,0.0) 96%, rgba(14,10,7,0.0) 98%, rgba(14,10,7,0.0) 100%);
}
.msd-scrim-v1 .msd-p2.rev .msd-p2-scrim {
  background: linear-gradient(270deg, rgba(14,10,7,0.85) 0%, rgba(14,10,7,0.85) 2%, rgba(14,10,7,0.85) 4%, rgba(14,10,7,0.85) 6%, rgba(14,10,7,0.85) 8%, rgba(14,10,7,0.85) 10%, rgba(14,10,7,0.85) 12%, rgba(14,10,7,0.85) 14%, rgba(14,10,7,0.85) 16%, rgba(14,10,7,0.85) 18%, rgba(14,10,7,0.849) 20%, rgba(14,10,7,0.844) 22%, rgba(14,10,7,0.833) 24%, rgba(14,10,7,0.812) 26%, rgba(14,10,7,0.781) 28%, rgba(14,10,7,0.74) 30%, rgba(14,10,7,0.69) 32%, rgba(14,10,7,0.632) 34%, rgba(14,10,7,0.567) 36%, rgba(14,10,7,0.497) 38%, rgba(14,10,7,0.425) 40%, rgba(14,10,7,0.353) 42%, rgba(14,10,7,0.283) 44%, rgba(14,10,7,0.218) 46%, rgba(14,10,7,0.16) 48%, rgba(14,10,7,0.11) 50%, rgba(14,10,7,0.069) 52%, rgba(14,10,7,0.038) 54%, rgba(14,10,7,0.017) 56%, rgba(14,10,7,0.006) 58%, rgba(14,10,7,0.001) 60%, rgba(14,10,7,0.0) 62%, rgba(14,10,7,0.0) 64%, rgba(14,10,7,0.0) 66%, rgba(14,10,7,0.0) 68%, rgba(14,10,7,0.0) 70%, rgba(14,10,7,0.0) 72%, rgba(14,10,7,0.0) 74%, rgba(14,10,7,0.0) 76%, rgba(14,10,7,0.0) 78%, rgba(14,10,7,0.0) 80%, rgba(14,10,7,0.0) 82%, rgba(14,10,7,0.0) 84%, rgba(14,10,7,0.0) 86%, rgba(14,10,7,0.0) 88%, rgba(14,10,7,0.0) 90%, rgba(14,10,7,0.0) 92%, rgba(14,10,7,0.0) 94%, rgba(14,10,7,0.0) 96%, rgba(14,10,7,0.0) 98%, rgba(14,10,7,0.0) 100%);
}

/* ---------- sitemap link targets ----------
   The columns were a flex stack with gap:2px and 5px of vertical padding, so
   neighbouring links sat 2px apart — inside WCAG 2.5.8's allowance, but on a
   phone a 2px miss lands you on the wrong page. Same treatment the footer
   columns already get: drop the gap, grow the target. */
.msd-sitemap > div { gap: 0 !important; }
.msd-sitemap a {
  padding-top: 9px !important;
  padding-bottom: 9px !important;
  min-height: 24px;
  display: flex;
  align-items: center;
}

/* ---------- $95 offer card (Home closing band) ----------
   Price sits left of the copy on desktop; under 700px the lockup stacks and
   recentres so the card reads top-down on a phone. */
@media (max-width: 700px) {
  .msd-offer-grid { grid-template-columns: 1fr !important; text-align: center !important; gap: 18px !important; }
  .msd-offer-grid > div { align-items: center !important; }
  .msd-offer > div { padding: 32px 22px 24px !important; }
}

/* ---------- 320px: the contact form could not shrink ----------
   `grid-template-columns: 1fr` resolves to minmax(auto, 1fr), so a column can
   never go narrower than its item's min-content. A <textarea> with no `cols`
   reports a ~230px intrinsic width; plus the form's 2x36px padding that pinned
   the column at 302px inside a 276px content box — 4px of sideways scroll at
   320. Letting the FIELDS shrink is what lets the column shrink; capping the
   form padding buys back the rest. */
@media (max-width: 420px) {
  .msd-contact-grid > form,
  .msd-contact-grid > div      { min-width: 0 !important; }
  .msd-contact-grid input,
  .msd-contact-grid textarea,
  .msd-contact-grid select     { min-width: 0 !important; width: 100% !important; }
  .msd-contact-grid > form     { padding: 26px 20px !important; }
}

/* ---------- 320px: long single-word page headings ----------
   The shared page-hero H1 clamps to a 40px floor. "Comprehensive" at 40px is
   339px wide — wider than the 276px content box — and a single word cannot
   wrap, so the H1 box itself overflowed the viewport. One class on every hero
   H1 (33 pages) means the floor steps down everywhere at once instead of each
   page drifting its own way. */
@media (max-width: 400px) {
  .msd-page-h1 { font-size: clamp(28px, 9.5vw, 40px) !important; }
}

/* ---------- sticky mobile call bar ----------
   Below 820px the header's "Schedule" button is hidden to fit the bar, which
   left the phone number as the only visible CTA and no booking action at all
   on a phone. This pins both to the bottom of the viewport, where a thumb
   already is.
   Notes:
   - fixed, not sticky: the QA gate treats descendants of a fixed overlay as
     exempt from the overlap check, and a sticky bar inside <footer> would
     stop travelling once the footer scrolled past.
   - `padding-bottom` on the footer reserves the bar's height so it never
     covers the last line of the footer, and safe-area-inset keeps it clear of
     the iPhone home indicator.
   - 52px tall halves: both targets clear WCAG 2.5.8 by a wide margin. */
.msd-callbar { display: none; }
@media (max-width: 820px) {
  .msd-callbar {
    display: grid;
    grid-template-columns: 1fr 1fr;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 70;
    background: rgba(250,250,252,0.94);
    backdrop-filter: saturate(1.8) blur(20px);
    -webkit-backdrop-filter: saturate(1.8) blur(20px);
    border-top: 1px solid rgba(0,0,0,0.10);
    padding: 7px 10px calc(7px + env(safe-area-inset-bottom));
    gap: 8px;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  }
  .msd-callbar a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 46px;
    border-radius: 980px;
    font-size: 16px;
    font-weight: 600;
    text-decoration: none;
    letter-spacing: -0.01em;
  }
  .msd-callbar .msd-callbar-call { background: #f47e57; color: #3a1d0d; }
  .msd-callbar .msd-callbar-book { background: #1d1d1f; color: #ffffff; }
  .msd-callbar svg { flex: none; }
  /* reserve the bar's footprint so the footer's last row stays reachable */
  .msd-footer-root { padding-bottom: calc(68px + env(safe-area-inset-bottom)) !important; }
  /* Below 880px the hero bottom-aligns its copy inside a 100svh-52px box, so
     the Call / Schedule row sits exactly where this bar lands — the QA gate
     caught it as 0px clearance on "Schedule online". Lift the hero copy by the
     bar's height; 38px is the hero's own bottom padding at this breakpoint. */
  .msd-hero-content { padding-bottom: calc(38px + 68px + env(safe-area-inset-bottom)) !important; }
  /* With the bar on screen, the hero's own "Schedule online" text link is the
     same action twice, and at rest it sat half-behind the bar. The bar is the
     schedule CTA on phones; the hero keeps the Call button. */
  .msd-hero .msd-textcta { display: none; }
  /* Three offers in the ticket pushed the hero's Call button into the sticky
     bar (measured -5px clearance on a 390x664 phone). The copy block's own
     rhythm is the cheapest space to buy back. */
  .msd-hero-inner { gap: 12px; }
}
/* Stand the call bar down while the mobile menu covers the screen. Keyed on
   the OPEN state, not mere existence: in the dc prototype the panel exists
   only while open, but in the EXPORT site.js keeps the captured panel in the
   DOM permanently and toggles `hidden` — :has(#msd-mobile-menu) alone matches
   always there and would hide the bar on every production page, which no gate
   asserts against. :not([hidden]) is true in exactly the open state in both
   worlds. */
@media (max-width: 820px) {
  body:has(#msd-mobile-menu:not([hidden])) .msd-callbar { display: none !important; }
}

/* ---------- New Patients: $95 offer card ----------
   Price beside the copy while there is room; under 520px the lockup stacks and
   centres, same treatment the Home closing band's offer card gets. */
@media (max-width: 520px) {
  .msd-np-offer { flex-direction: column !important; text-align: center !important; gap: 12px !important; padding: 26px 20px !important; }
  .msd-np-offer > span:last-child { align-items: center !important; }
}

/* ---------- text CTAs ("Schedule online ›") ----------
   17px type gives these links a 20px-tall box, under WCAG 2.5.8's 24px floor.
   They were passing the gate on neighbour spacing alone, which the sticky call
   bar then removed in the Home hero at 320px. Give the target its own height
   rather than letting it depend on whatever happens to sit next to it. */
.msd-textcta {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 3px 0;
}

/* ---------- emergency $45 offer card ----------
   Price beside the copy while there is room; under 620px the lockup stacks and
   centres, same treatment the other offer cards get. */
@media (max-width: 620px) {
  .msd-er-offer { grid-template-columns: 1fr !important; }
  .msd-er-offer > div:last-child { border-left: 0 !important; border-top: 1px dashed rgba(244,126,87,0.38) !important; text-align: center; align-items: center; }
  .msd-er-offer > div:last-child a { align-self: center !important; }
}

@media (max-width: 620px) {
  .msd-tiles { grid-template-columns: 1fr !important; }
}

/* ---------- insurance carrier grid (Home + Financial Info) ----------
   Flex rather than grid so a final short row centres under the ones above it
   instead of hanging left. Logo heights are set per-carrier on the elements:
   they were measured (render at a fixed height, measure the ink bounding box,
   solve for equal bbox area) so every mark reads at the same optical size
   despite aspect ratios running from 1.3:1 to 7.6:1. */
.msd-ins-cell {
  /* Content-width, NOT equal columns. Equal cells centred logos of very
     different widths inside them, so the visible gap between two logos swung
     from 79px to 197px — that irregular air is what read as "too much white
     space". Auto width + one gap value makes every gap identical. Height stays
     fixed so the rows still line up (and so the alignment gate's equal-height
     short-circuit still applies). */
  flex: 0 0 auto;
  /* FIXED height, not min-height: flex rows size independently, so the Delta
     Dental cell (logo + a states sub-label) sat 12px taller than its row
     neighbours and the alignment gate caught it. Tallest content is the
     Regence lockup at 57px + 36px padding = 93px. */
  /* Tight to the tallest logo (Regence 60px) + 10px breathing room top and
     bottom. The old 104px left a lot of air around the short wide wordmarks,
     which is what read as excess whitespace between rows. */
  height: 86px;
  box-sizing: border-box;
}
@media (max-width: 860px)  { .msd-ins-cell { flex: 0 0 auto; } }
@media (max-width: 760px) {
  .msd-ins-cell { flex: 0 0 auto; height: 58px; }
  /* Two-up cells are ~170px wide, so the wide wordmarks are width-limited to
     about 20px tall. Without a cap here the near-square marks (Regence, Cigna)
     keep their 68px/60px desktop height and dwarf everything else. */
  /* Phones: keep an explicit height (SVGs need it to compute a width) but
     scale each logo to ~58% of its desktop size, and cap the width so two fit
     per row. A single shared height here would leave the near-square marks
     ~40px wide while the wordmarks clamp — the imbalance just fixed on desktop. */
  /* the 64px desktop column gap has to shrink too, or two half-width cells
     plus the gap exceed 100% and everything drops to one per row */
  .msd-ins-grid { gap: 26px 20px !important; }
  .msd-ins-cell { flex: 0 0 calc(50% - 10px) !important; }
  .msd-ins-grid img { max-width: 100% !important; width: auto !important; }
  .msd-ins-grid img[alt="Delta Dental"] { height: 17px !important; }
  .msd-ins-grid img[alt="GEHA"] { height: 15px !important; }
  .msd-ins-grid img[alt="MetLife"] { height: 26px !important; }
  .msd-ins-grid img[alt="Guardian"] { height: 25px !important; }
  .msd-ins-grid img[alt="Aetna"] { height: 26px !important; }
  .msd-ins-grid img[alt="Ameritas"] { height: 27px !important; }
  .msd-ins-grid img[alt="Humana"] { height: 27px !important; }
  .msd-ins-grid img[alt="Premera"] { height: 29px !important; }
  .msd-ins-grid img[alt="UnitedHealthcare"] { height: 33px !important; }
  .msd-ins-grid img[alt="Cigna"] { height: 36px !important; }
  .msd-ins-grid img[alt="Regence"] { height: 38px !important; }
}
