/* chrome.css - the site chrome, defined once.
 *
 * Generated by lib/extract/make_chrome_css.py from JHS-Deploy.
 *
 * MEMBERSHIP IS BY MATCHING, NOT BY NAME. A selector is here when it
 * matches an element inside a chrome region on at least one page and
 * never matches page content on any page. A name test would also pull
 * in .arm-nav, .kanavel-* (it contains "nav"), .card-footer and
 * .mini-footer, none of which style chrome anywhere.
 *
 * 81 rules, keyed (media context, selector). 5 further keys are
 * EXCLUDED because the site does not agree on their body - writing the
 * majority would change the minority pages. They stay inline until ruled.
 */

.breadcrumb {
  background: var(--off-white);
  border-bottom: 1px solid var(--border);
  padding: 10px 0;
}
.breadcrumb a:hover {
  text-decoration: underline;
}
.breadcrumb-inner {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
  color: var(--slate);
  flex-wrap: wrap;
}
.breadcrumb-inner a {
  color: var(--blue);
  text-decoration: none;
}
.breadcrumb-inner a:hover {
  text-decoration: underline;
}
/* CONTRAST - var(--border) #e2e8f0 on --off-white measured 1.18:1, the worst
   ratio on the site, on 93 pages at every width. It is the mechanism CLAUDE.md
   documents: a BORDER TOKEN USED AS A TEXT COLOUR, which is a perfectly good
   value in its intended role and is why no value-scan finds it. var(--slate) is
   5.31:1 and is already the colour of .breadcrumb-inner's own text. */
.breadcrumb-sep {
  color: var(--slate);
}
.footer {
  background: var(--charcoal);
  padding: 40px 0;
}
.footer-brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.footer-copy {
  font-size: 0.875rem;
  color: rgba(255,255,255,.55);
}
/* Chrome, and it was only ever on 17 pages. The fixed fingerprint surfaced
   it at once: `.footer-copy a:hover` undefined on 56 of the 92 scored
   pages, because canonical carried it inline and most pages did not. The
   value is identical on all 17 that had it, so promoting is lossless.

   NOT promoted alongside it: `.container` @600, the other divergence the
   gate now reports on 20 pages. That is CLAUDE.md's documented MIXED
   SELECTOR -- chrome on 93 pages, page content on 13 -- so moving it would
   restyle page content sitewide. It stays unresolved deliberately. */
.footer-copy a:hover {
  color: rgba(255,255,255,.9);
}
/* CONTRAST - the enHANDced wordmark. .2 on --charcoal measured 1.90:1 on 94
   pages. CLAUDE.md's card.html precedent governs this exact component: "the
   #en / ced brackets around HAND are the mark itself, not an ornament repeating
   something adjacent ... If the brackets need to sit back from HAND, that is a
   size or weight step." .75 is 10.02:1, the same alpha that ruling used.
   The .25 below paints nothing today - every character is inside a span - and is
   raised with the rest so it cannot become a 2.26:1 the moment text is added. */
.footer-enhanced {
  font-family: var(--serif);
  font-size: 1.3125rem;
  color: rgba(255,255,255,.75);
  letter-spacing: .02em;
}
/* Raised to #fff (17.06:1) ONLY because the brackets moved to .75. At .55 HAND
   measured 5.96:1 and passed, but once #/en/ced sit at 10.02:1 a dimmer HAND
   inverts the wordmark's emphasis. It keeps the emphasis by weight and style as
   before; the brightness now agrees with them instead of fighting them. */
.footer-enhanced .hand {
  color: #fff;
  font-style: italic;
  font-weight: 700;
}
.footer-enhanced .hash {
  color: rgba(255,255,255,.75);
}
.footer-enhanced .post {
  color: rgba(255,255,255,.75);
}
.footer-enhanced .pre {
  color: rgba(255,255,255,.75);
}
.footer-enhanced-label {
  font-size: 0.875rem;
  color: rgba(255,255,255,.75);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 500;
}
.footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
}
.footer-links a:hover {
  color: rgba(255,255,255,.8);
}
.mobile-cta-bar {
  display: none;
}
.nav {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(0,0,0,.06);
}
.nav-cta {
  background: var(--blue);
  color: var(--white) !important;
  padding: 9px 20px !important;
  border-radius: var(--radius) !important;
  white-space: nowrap;
}
.nav-cta:hover {
  background: var(--blue-deep) !important;
  color: var(--white) !important;
}
.nav-divider {
  /* A RULE, not a character. This was `<span class="nav-divider">|</span>`
     coloured var(--border) - a text glyph at 1.23:1 on white, which is 116 of
     the site's remaining contrast findings across 58 pages and the single
     largest family. Recolouring it would make a deliberately quiet separator
     loud; the real fault is that a separator was built out of text at all.
     As a 1px box it is decorative by construction: no text, no ratio, and it
     renders exactly as intended. aria-hidden in the markup keeps it out of the
     accessibility tree, where a spoken "vertical line" was never wanted. */
  align-self: center;
  flex: 0 0 auto;
  width: 1px;
  height: 18px;
  background: var(--border);
  margin: 0 8px;
  user-select: none;
}
.nav-hamburger {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 10px;
  margin-right: -10px;
  -webkit-tap-highlight-color: transparent;
}
.nav-hamburger span {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--charcoal);
  border-radius: 2px;
  transition: transform .25s, opacity .2s;
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 32px;
  max-width: 1200px;
  margin: 0 auto;
  min-height: 72px;
  flex-wrap: wrap;
  row-gap: 8px;
  padding-top: 8px;
  padding-bottom: 8px;
}
.nav-links {
  display: flex;
  gap: 2px;
  align-items: center;
}
.nav-links a {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--charcoal);
  text-decoration: none;
  padding: 6px 14px;
  border-radius: var(--radius);
  transition: background .15s, color .15s;
  white-space: nowrap;
}
.nav-links a:hover {
  background: var(--blue-tint);
  color: var(--blue);
}
.nav-logo {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  flex-shrink: 0;
}
.nav-logo-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.nav-logo-mark img {
  display: block;
  height: 48px;
  width: auto;
}
.nav-logo-name {
  font-family: var(--serif);
  font-size: 1.125rem;
  color: var(--charcoal);
  font-weight: 400;
  white-space: nowrap;
}
.nav-logo-sub {
  font-size: 0.75rem;
  color: var(--slate);
  font-weight: 500;
  letter-spacing: .04em;
  white-space: nowrap;
}
.nav-logo-text {
  line-height: 1.2;
  flex-shrink: 0;
  white-space: nowrap;
}
.nav-mobile-appt {
  background: var(--blue);
  color: var(--white);
  box-shadow: 0 4px 14px rgba(18,91,154,.32);
}
.nav-mobile-call {
  background: var(--white);
  color: var(--blue);
  border: 1.5px solid var(--blue);
}
.nav-mobile-ctas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 14px 20px 18px;
  background: var(--off-white);
  border-top: 1px solid var(--border);
}
.nav-mobile-ctas a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 13px 10px;
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  text-align: center;
  min-height: 48px;
}
.nav-mobile-links {
  display: flex;
  flex-direction: column;
  padding: 8px 0;
}
.nav-mobile-links a {
  font-size: 1rem;
  font-weight: 500;
  color: var(--charcoal);
  text-decoration: none;
  padding: 14px 24px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
  transition: background .15s;
  min-height: 44px;
}
.nav-mobile-links a:active {
  background: var(--blue-tint);
  color: var(--blue);
}
.nav-mobile-links a:hover {
  background: var(--blue-tint);
  color: var(--blue);
}
.nav-mobile-links a:last-of-type {
  border-bottom: none;
}
.nav-mobile-panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--white);
  border-top: 1px solid var(--border);
  border-bottom: 2px solid var(--blue);
  box-shadow: 0 8px 24px rgba(0,0,0,.12);
  z-index: 99;
  overflow: hidden;
}
/* CONTRAST - #16a34a measured 3.30:1 on white and 2.92:1 on the --blue-tint
   hover ground, on 94 pages whenever the hamburger panel is open. #166534 is
   7.13:1 and 6.31:1. NOT #15803d, which is the trap in this set: 5.02:1 on
   white looks like a pass but it is 4.44:1 on the hover ground - it fails in
   the state a user reaches by pointing at it. */
.nav-mobile-walkin {
  color: #166534 !important;
  font-weight: 600 !important;
}
.nav-mobile-walkin-dot {
  width: 8px;
  height: 8px;
  background: #4ade80;
  border-radius: 50%;
  flex-shrink: 0;
  animation: joinPulse 2s ease-in-out infinite;
}
.skip-link {
  position: absolute;
  top: -48px;
  left: 6px;
  background: #125b9a;
  color: #fff;
  padding: 8px 14px;
  border-radius: 0 0 6px 6px;
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  z-index: 9999;
  transition: top .15s;
}
.skip-link:focus {
  top: 0;
}
.topbar {
  background: var(--blue-deep);
  color: rgba(255,255,255,.75);
  font-size: 0.875rem;
  letter-spacing: .02em;
  padding: 9px 0;
}
.topbar a:hover {
  color: #fff;
}
.topbar-address {
  /* Was an inline style="display:flex;gap:6px;align-items:center" on all
     94 pages. Inline beats every stylesheet rule, so the large-text guard's
     display:none could not hide it -- the same lesson as .join-hours-link:
     an inline style is invisible to the cascade AND unoverridable by it. */
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
  min-width: 0;
}
.topbar-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.topbar-links {
  display: flex;
  /* 14px, not 20px. The topbar container is capped at max-width 1200px with
     32px padding = 1136px usable, and the row needs 1150px (address 436 + gap
     12 + links 703). Over by FOURTEEN pixels, so it wrapped to two lines at
     every viewport above 1200px - and widening the viewport never helped,
     because the container is capped. Six gaps instead of seven items means
     every 1px off the gap frees 6px. 16px was tried first and cleared 1264px+
     but still wrapped in the
     narrow band 1201-1263px, where the container stops being capped and goes
     viewport-relative: a real browser's scrollbar takes ~15px there, leaving
     1122px against a 1126px row. 14px frees 36px and clears every width above
     the 1200 breakpoint with room to spare.
     This does NOT affect the narrow-viewport wrap, which was a real fix: at
     <=1200px the nav breakpoint hides Patient Portal and Referring Physicians,
     so the row is ~250px shorter and never reaches the wrap point. */
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
  overflow: visible;
}
/* CONTRAST - the | separators, .3 on --blue-deep measured 2.34:1 on 94 pages
   at >=1200px. .75 is 6.78:1, matching the alpha used for muted white text
   elsewhere on this project. */
.topbar-links span {
  color: rgba(255,255,255,.75);
}
.topbar-walkin {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(74,222,128,.15);
  border: 1px solid rgba(74,222,128,.35);
  border-radius: 100px;
  padding: 3px 10px;
  font-size: 0.75rem;
  font-weight: 700;
  color: #4ade80;
  letter-spacing: .04em;
  text-decoration: none !important;
}
.topbar-walkin-dot {
  width: 6px;
  height: 6px;
  background: #4ade80;
  border-radius: 50%;
  animation: joinPulse 2s ease-in-out infinite;
}

@media (max-width: 1200px) {
  .mobile-cta-appt {
    background: var(--blue);
    color: var(--white);
  }
  .mobile-cta-bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 300;
    border-top: 1px solid var(--border);
    box-shadow: 0 -4px 16px rgba(0,0,0,.1);
  }
  .mobile-cta-bar a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 15px 10px;
    padding-bottom: calc(15px + env(safe-area-inset-bottom));
    font-size: 0.875rem;
    font-weight: 700;
    text-decoration: none;
    text-align: center;
  }
  .mobile-cta-call {
    background: var(--white);
    color: var(--blue);
    border-right: 1px solid var(--border);
  }
  .nav {
    position: sticky;
    top: 0;
    z-index: 200;
  }
  .nav-hamburger {
    display: flex;
  }
  .nav-inner {
    position: relative;
  }
  .nav-links {
    display: none !important;
  }
  .nav-logo-sub {
    display: none;
  }
  .topbar a[href^="tel"] {
    padding: 8px 4px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .topbar-links .topbar-hide-mobile {
    display: none;
  }
  .topbar-links a[href$="/for-physicians"] {
    display: none;
  }
  .topbar-links a[href*="patientportal"] {
    display: none;
  }
  .topbar-links a[href*="request-appointment"] {
    display: none;
  }
}

@media (max-width: 480px) {
  .nav-logo {
    flex-shrink: 1;
    min-width: 0;
  }
  .nav-logo-name {
    white-space: normal;
  }
  .nav-logo-text {
    white-space: normal;
    flex-shrink: 1;
    min-width: 0;
  }
  .topbar .topbar-walkin {
    white-space: normal;
    text-align: center;
  }
}

@media (max-width: 600px) {
  .nav-inner {
    padding: 0 20px;
  }
  .nav-links {
    display: none;
  }
  .topbar-address {
    display: none;
  }
  .topbar-inner {
    flex-direction: column;
    gap: 6px;
  }
  .topbar-links {
    gap: 12px;
  }
  .topbar-links .topbar-hide-mobile {
    display: none;
  }
  .topbar-links > span {
    display: none;
  }
}

/* ---- LARGE-TEXT GUARD -------------------------------------------------
   Fires when the reader's text is large RELATIVE TO THEIR SCREEN HEIGHT, not
   when the viewport is short. An em in a media query resolves against the
   browser's initial font size -- the reader's setting -- and is immune to any
   html{font-size} this site sets, which is what makes it usable as a signal.

       reader at 16px  ->  25em = 400px  ->  a 640px phone does NOT match
       reader at 32px  ->  25em = 800px  ->  a 640px phone DOES match

   Measured at 200% on a 390x640 phone before this existed: nav + fixed CTA bar
   permanently occupied 296px, 46% of the screen, and the topbar alone was
   335px so the first screenful was an address and a hamburger.

   Nothing below shrinks text. The reader asked for bigger text and gets it;
   what shrinks is how much room the furniture is allowed to take.        */
@media (max-height: 25em) {
  /* The address recovers 159px and costs nothing: it stays in the DOM, in the
     PostalAddress schema on 93 pages and in the footer on 95, so NAP and local
     SEO are unaffected. Ruled by David 23 Aug. */
  .topbar-address {
    display: none;
  }
  .topbar {
    padding: 5px 0;
  }
  /* Un-pinned, not hidden. A fixed bar that occupies 165px of a 640px screen is
     working against the reader it is meant to help; as part of the page it is
     still reachable, and the same CTA is in the hero and at the page foot. */
  .mobile-cta-bar {
    position: static;
  }
  body {
    padding-bottom: 0;
  }
  .nav-inner {
    padding-top: 4px;
    padding-bottom: 4px;
  }
}

/* Mobile CTA bar - threshold reveal. Ruled by David 24 Aug 2026: hidden at the
   top of the page, revealed once the topbar and nav have scrolled away, and
   then STAYING revealed regardless of scroll direction until the reader is
   back at the top.

   Everything here is gated behind .js-cta-reveal, which lib/apply_cta_reveal.py
   adds to <html> from script. With JS off the class never appears and the bar
   behaves exactly as it did before -- visible, fixed, reachable. That is the
   whole reason the opt-in runs this way round. */
.js-cta-reveal .mobile-cta-bar {
  transform: translateY(110%);
  transition: transform .22s ease-out;
  will-change: transform;
}
.js-cta-reveal .mobile-cta-bar.is-revealed {
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .js-cta-reveal .mobile-cta-bar {
    transition: none;
  }
}
