/* ---------- Buttons & links ---------- */

.btn {
  display: inline-block;
  background-color: var(--cb-600);
  color: var(--cream);
  text-decoration: none;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 14px;
  line-height: 1.2;
  padding: 12px 24px;
  border: 1px solid var(--cb-600);
  border-radius: var(--r-pill);
  cursor: pointer;
}

.btn:hover {
  background-color: var(--cb-700);
  border-color: var(--cb-700);
}

.text-link {
  font-size: 14px;
  font-weight: 600;
  color: var(--cb-600);
  text-decoration: none;
}

.text-link:hover {
  color: var(--cb-700);
  text-decoration: underline;
}

/* ---------- Hero ---------- */

/* overflow-x: clip because 100vw (inside --bleed) counts the scrollbar, so
   the bled photo overshoots under it and would otherwise add a horizontal
   scroll. clip, unlike hidden, doesn't make .hero a scroll container. */
.hero {
  border-bottom: 1px solid var(--linen);
  overflow-x: clip;
}

/* Held to the same measure as .wrap so the hero copy sits on the same left
   edge as the header lockup and the footer. A full-bleed hero would put the
   headline 50px to the left of the logo above it. Only the photo bleeds. */
.hero__grid {
  display: grid;
  grid-template-columns: 1fr;
  max-width: var(--maxw);
  margin: 0 auto;
}

/* On mobile the copy and photo share one grid cell. The square photo (100vw
   tall) opens the hero with her face clear, and the copy starts 68vw down,
   over the bottom of the photo. The fade turns solid paper where the photo
   ends, so the photo melts into the page instead of stopping at a hard edge. */
.hero__content {
  grid-area: 1 / 1;
  position: relative;
  z-index: 1;
  padding: 68vw 20px 48px;
  background: linear-gradient(
    to bottom,
    transparent 54vw,
    color-mix(in srgb, var(--paper) 80%, transparent) 72vw,
    var(--paper) 100vw
  );
}

.hero .display {
  margin-bottom: 16px;
}

.hero .body-l {
  max-width: 30em;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 20px;
  margin-top: 28px;
}

/* Lets the img inside be the grid item, so the picture wrapper doesn't
   change the layout. */
.hero__picture {
  display: contents;
}

/* Square at the top of the cell. Stretching it to the full hero height
   would zoom in until her face sat behind the text. */
.hero__image {
  grid-area: 1 / 1;
  align-self: start;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: 50% 0%;
}

/* ---------- Practice (home) ---------- */

/* The map bleeds to the left edge of the viewport while the copy keeps the
   .wrap gutters. Map first in the DOM so it sits left when side by side. */
.practice__grid {
  display: grid;
  grid-template-columns: 1fr;
  max-width: var(--maxw);
  margin: 0 auto;
}

/* On mobile the map and copy share one grid cell, like the hero: the map
   opens the section and the heading sits over its empty western terrain,
   so the map costs no scroll height beyond its own. */
.practice__map {
  grid-area: 1 / 1;
  margin: 0;
}

/* The source is centered on Pittsburgh with the offices in its middle third
   and filler terrain on every side. Every layout crops it with centered
   cover, so narrower boxes lose terrain, never offices. */
.practice__map img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: 50% 50%;
  /* Fades the bottom edge into the page, below the McMurray star. */
  mask-image: linear-gradient(to bottom, #000 88%, transparent);
}

/* The 4:3 map is 75vw tall. Starting the copy 48px short of that lands the
   heading on the map's bottom edge and the list just below it. */
.practice__body {
  grid-area: 1 / 1;
  position: relative;
  z-index: 1;
  padding: calc(75vw - 48px) 20px var(--space-section);
}

/* Nothing sits above this heading, so it steps up a size to carry the section. */
.practice__body h2 {
  font-size: var(--size-h1);
}

/* ---------- Rule list (the kit's clear-space list pattern) ---------- */

/* Used where the content is a short set of parallel facts. Rules rather than
   boxes: four bordered cards in a row would be four times the chrome for the
   same eight words each. */
.rule-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--sand);
}

.rule-list li {
  padding: 20px 0;
  border-bottom: 1px solid var(--sand);
}

.rule-list h2,
.rule-list h3 {
  margin: 0 0 4px;
}

.rule-list p {
  margin: 0;
  color: var(--cocoa);
  max-width: 46em;
}

/* ---------- Cards ---------- */

.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

/* auto-fill packs as many 220px+ cards as fit (4 at full width) instead of
   jumping at fixed breakpoints. */
.card-grid--staff {
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px;
}

.card {
  background-color: var(--paper);
  border: 1px solid var(--sand);
  border-radius: var(--r-lg);
  padding: 28px;
}

.card h3 {
  margin-top: 0;
}

.card p {
  color: var(--cocoa);
}

.section--alt .card {
  border-color: var(--sand);
}

/* ---------- Staff directory ---------- */

.staff-filters {
  margin: 32px 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.staff-filters__search-field {
  position: relative;
  max-width: 420px;
}

.staff-filters__search-icon {
  position: absolute;
  left: 16px;
  top: 50%;
  width: 18px;
  height: 18px;
  transform: translateY(-50%);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  color: var(--stone);
  /* Let clicks on the icon land in the input underneath. */
  pointer-events: none;
}

.staff-filters__search {
  font: inherit;
  width: 100%;
  padding: 12px 16px 12px 44px;
  border: 1px solid var(--sand);
  border-radius: var(--r-pill);
  background-color: var(--paper);
  color: var(--ink);
}

/* Grid, not flex-wrap: flex-wrap decides per group whether the chips fit
   beside the label, so one group could sit inline while the next stacked. */
.staff-filters__group {
  display: grid;
  gap: 8px 12px;
}

.staff-filters__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chip {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--cocoa);
  background-color: var(--paper);
  border: 1px solid var(--sand);
  border-radius: var(--r-pill);
  padding: 6px 14px;
  cursor: pointer;
}

.chip:hover {
  border-color: var(--cb-400);
  color: var(--cb-700);
}

.chip[aria-pressed="true"] {
  background-color: var(--cb-600);
  border-color: var(--cb-600);
  color: var(--cream);
}

.staff-filters__empty {
  color: var(--stone);
}

/* Photo bleeds to the card edges, so the card drops its padding and moves
   it onto the text body instead. position:relative anchors the name
   button's stretched overlay. */
.staff-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.staff-card:hover {
  transform: translateY(-4px);
  border-color: var(--cb-400);
  box-shadow: 0 8px 24px rgb(72 16 30 / 0.08);
}

/* The button's own outline would only ring the name, so the card draws it. */
.staff-card:has(.staff-card__open:focus-visible) {
  outline: 2px solid var(--cb-400);
  outline-offset: 2px;
}

.staff-card__photo {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.staff-card__placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  padding: 24px;
  background-color: var(--cb-100);
  color: var(--cb-600);
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1.15;
  text-align: center;
  text-wrap: balance;
}

.staff-card__body {
  padding: 18px 20px;
}

/* A person's name reads as a title, not a UI subhead, so it takes the serif
   rather than the sans H3 token. */
.staff-card__name {
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.2;
  margin-bottom: 4px;
}

/* Stretched link: the ::after covers the whole card, making it one big hit
   area while the accessible name stays the clinician's name. */
.staff-card__open {
  font: inherit;
  color: var(--cb-700);
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.staff-card__open::after {
  content: "";
  position: absolute;
  inset: 0;
}

.staff-card__open:focus-visible {
  outline: none;
}

.staff-card:hover .staff-card__open {
  color: var(--cb-400);
}

.staff-card__title {
  margin-bottom: 10px;
}

.staff-card__facts {
  margin: 10px 0 0;
  font-size: var(--size-body-s);
  line-height: 1.4;
  color: var(--cocoa);
}

.staff-card__facts dd {
  margin: 0 0 4px;
}

.staff-card__facts dd:last-child {
  margin-bottom: 0;
}

/* Labeled Offices/Specialties list inside the bio dialog. */
.staff-card__meta {
  margin: 16px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--linen);
  font-size: var(--size-body-s);
  color: var(--stone);
}

.staff-card__meta dt {
  font-size: var(--size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--stone);
}

.staff-card__meta dd {
  margin: 2px 0 10px;
  color: var(--cocoa);
}

.staff-card__meta dd:last-child {
  margin-bottom: 0;
}

/* Waitlist note, styled after the kit's badge-rec pill. */
.badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  background-color: var(--cb-100);
  color: var(--cb-700);
  border-radius: var(--r-pill);
  padding: 4px 10px;
  margin-bottom: 16px;
}

/* ---------- Staff bio dialog ---------- */

/* Mobile: a full-width sheet pinned to the bottom, where a thumb can reach
   the close button. Becomes a centered card at 768px (see below). */
.staff-bio {
  width: 100%;
  max-width: 100vw;
  max-height: 85vh;
  margin: auto 0 0;
  padding: 0;
  border: none;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  background-color: var(--cream);
  color: var(--ink);
  overflow-y: auto;
}

.staff-bio::backdrop {
  background-color: rgb(33 27 26 / 0.55); /* --ink; custom props don't reach ::backdrop in all browsers */
}

.staff-bio__inner {
  position: relative;
  padding: 32px 24px;
}

.staff-bio__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 40px;
  height: 40px;
  font-size: 28px;
  line-height: 1;
  color: var(--cocoa);
  background: none;
  border: none;
  border-radius: 50%;
  cursor: pointer;
}

.staff-bio__close:hover {
  background-color: var(--cb-100);
  color: var(--cb-700);
}

.staff-bio__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
  margin-bottom: 24px;
  padding-right: 32px;
}

.staff-bio__photo {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
}

.staff-bio__name {
  font-family: var(--serif);
  font-size: 28px;
  line-height: 1.15;
  margin: 0 0 4px;
}

.staff-bio__header .badge {
  margin: 8px 0 0;
}

.staff-bio__body p {
  color: var(--cocoa);
}

.staff-bio__cta {
  margin-top: 24px;
}

body:has(dialog[open]) {
  overflow: hidden;
}

/* ---------- Forms ---------- */

.form {
  margin-top: 32px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: 520px;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Sentence-case labels, not the 12px caps used for captions. Uppercase
   micro-type is fine as decoration and poor as an input label. */
.form-field label {
  font-size: var(--size-body-s);
  font-weight: 600;
  color: var(--ink);
}

.form-field input,
.form-field select,
.form-field textarea {
  font: inherit;
  padding: 11px 14px;
  border: 1px solid var(--sand);
  border-radius: var(--r-sm);
  background-color: var(--paper);
  color: var(--ink);
}

/* Stone, not mist: mist lands around 2.6:1 against paper, which fails AA even
   for hint text. Stone clears 5:1 and still reads as secondary. */
.form-field input::placeholder,
.form-field textarea::placeholder,
.staff-filters__search::placeholder {
  color: var(--stone);
}

.form-field input:hover,
.form-field select:hover,
.form-field textarea:hover {
  border-color: var(--mist);
}

.form .btn {
  align-self: flex-start;
}

/* The form hands off to the visitor's mail client rather than posting, so
   say so before they press the button and get surprised by a compose window. */
.form-note {
  margin: 0;
  font-size: var(--size-body-s);
  color: var(--cocoa);
}

/* ---------- Contact ---------- */

.contact-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

.contact-aside {
  padding-top: 8px;
}

.contact-aside h2 {
  font-size: var(--size-h2);
  margin-bottom: 4px;
}

.contact-aside p {
  color: var(--cocoa);
  font-size: var(--size-body-l);
}

.contact-aside .office__name {
  font-size: 19px;
}

.contact-aside .rule-list {
  margin-top: 24px;
}

.contact-aside .rule-list li {
  padding: 14px 0;
}

/* The aside runs at body size, a step up from the footer's small text, and
   its own paragraph color would otherwise outrank the muted fax gray. */
.contact-aside .office__fax {
  font-size: var(--size-body);
  color: var(--stone);
}

/* ---------- Utilities ---------- */

/* Hidden on screen but still read by screen readers, e.g. the card's dt
   labels, which sighted users infer from context. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Breakpoints (components) ---------- */

/* 768px and up: tablet */
@media (min-width: 768px) {
  /* Fixed label column so both groups' chips start on the same left edge;
     baseline lines the label up with the first row of chips. */
  .staff-filters__group {
    grid-template-columns: 88px 1fr;
    align-items: baseline;
  }

  .hero__grid {
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
  }

  /* Side by side from here up, so undo the mobile overlay. */
  /* Bleeds left like the photo bleeds right, so the cell spans the window
     edge to the photo and the copy centers in what reads as the left half. */
  .hero__content {
    grid-area: 1 / 1;
    background: none;
    padding: 56px 32px;
    margin-left: calc(-1 * var(--bleed));
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

  /* One shared width keeps every child on the same left edge once centered. */
  .hero__content > * {
    width: min(100%, var(--hero-copy-w));
  }

  /* Explicit height rather than height:100%. With no definite height on the
     grid row, 100% resolves to auto and the photo grows to its intrinsic
     size, stretching the hero to twice the height it should be. */
  /* Runs to the right edge of the viewport, mirroring the map below it. */
  /* Placed explicitly: the picture wrapper is display: contents, so its
     <source> would otherwise take the second column by auto-placement. */
  .hero__image {
    grid-area: 1 / 2;
    align-self: auto;
    object-position: 50% 50%;
    height: 420px;
    width: calc(100% + var(--bleed));
    max-width: none;
    margin-right: calc(-1 * var(--bleed));
  }

  /* minmax(0, ...) lets the columns shrink below the image's intrinsic width. */
  .practice__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  }

  /* The copy sets the row height and the map fills it, like the hero photo.
     Absolute positioning keeps the image's intrinsic height out of the row
     sizing. The negative margin pulls the map past the centered --maxw
     column to the viewport's left edge. */
  .practice__map {
    grid-area: auto;
    position: relative;
    margin-left: calc(-1 * var(--bleed));
  }

  .practice__map img {
    position: absolute;
    inset: 0;
    height: 100%;
    mask-image: none;
  }

  .practice__body {
    grid-area: auto;
    padding: var(--space-section) 32px var(--space-section) 48px;
  }

  .contact-layout {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
    gap: 64px;
  }

  .staff-bio {
    width: min(640px, 100vw - 32px);
    margin: auto;
    border-radius: var(--r-lg);
  }

  .staff-bio__inner {
    padding: 40px;
  }

  .staff-bio__photo {
    width: 160px;
    height: 160px;
  }
}

/* 1280px and up: desktop */
@media (min-width: 1280px) {
  .hero__content {
    padding: 64px 40px;
  }

  .hero__image {
    height: 640px;
  }

  .practice__body {
    padding: var(--space-section) 40px var(--space-section) 64px;
  }
}
