/* ============================================================
   Provider pages — /team/<slug>/
   ============================================================
   Two pages, one system: a full-viewport hero where an unframed
   cut-out portrait stands on the section's floor, and a bio block
   that mirrors the hero's asymmetry the other way round.

   Scoped under .provider-page. Depends on the :root tokens in
   styles.css; entrance motion rides the .reveal system from
   animations.css. No hex, spacing or easing value is written
   here that is not a token.

   Two page-local decisions about ground colour:

   1. The hero ground is --c-ivory and carries no tint. Both hero
      figures are in black scrubs: against Ivory that is already the
      highest-contrast mass the page will ever hold, and a tinted
      field behind her would put a second mass of similar weight in
      the frame for the subject to compete with. Restrained is not
      timidity here, it is the only strategy where the person wins.

   2. The bio photo sits on --c-mint for the opposite reason: those
      scrub tops are ~oklch(93%) and Ivory is oklch(97.3%). On Ivory
      the subject nearly vanishes and reads as a floating head. Mint
      gives ~5 points of lightness plus a hue shift, so she separates.
   ============================================================ */

.provider-page {
  /* Type ladder for these pages. Ratios 2.05 / 1.82 / 1.29 / 1.31,
     all clear of the 1.25 floor. The name gets a page-local display
     step because an H1 that is a name is shorter than a sentence
     headline and can go bigger without wrapping past two lines. */
  --pp-name: clamp(44px, 6.2vw, 82px);
  --pp-position: 20px;
  --pp-cred: 14px;
  --pp-tag: 13px;

  /* Portrait tone. team.css already runs saturate(0.95) on every
     portrait; the cut-outs go one step further so the only saturated
     non-teal object on either page — Catherine's red sneakers —
     stops being the loudest thing in the composition. */
  --pp-photo: saturate(0.88);
}

/* ---------- 1. Hero ---------- */
/* svh, not vh or dvh: the figure stands on the section's bottom
   edge, and dvh would slide the floor out from under her feet as
   the iOS address bar collapses mid-scroll. */
.pp-hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 100svh;
  background: var(--c-ivory);
  overflow: hidden;
}
.pp-hero-inner {
  position: relative;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 80px;
}
.pp-hero-text {
  position: relative;
  z-index: 2;
  max-width: min(46vw, 620px);
}

.pp-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--pp-name);
  line-height: 1.02;
  letter-spacing: -0.015em;
  color: var(--c-deep);
  margin: 0;
}
.pp-cred {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--pp-cred);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.5;
  /* 5.26:1 on Ivory. --c-sea would be 4.34:1 and miss AA at 14px. */
  color: var(--c-sea-text);
  margin: var(--s-24) 0 0;
}
/* The positioning line is set in caps as supplied. Two consequences:
   caps need positive tracking or the letters jam, and caps read
   larger than their point size, so this sits a step BELOW the 22px
   the lower-case version used. It also takes --c-ink rather than
   --c-slate and a heavier weight, because it now has to hold its own
   against the credential line directly above it, which is also caps.
   The gap above it widens for the same reason: two caps lines at
   16px apart read as one block. */
.pp-position {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--pp-position);
  line-height: 1.5;
  letter-spacing: 0.1em;
  color: var(--c-ink);
  margin: var(--s-24) 0 0;
  max-width: 22ch;
}

/* The only horizontal element on the page. It bleeds off the
   viewport's left edge rather than starting at the container
   gutter, which is what stops the text stack reading as a card
   sitting in a box and starts it reading as type standing on a
   horizon. It terminates where the measure ends. */
.pp-rule {
  position: relative;
  display: block;
  width: 100%;
  height: 1px;
  background: var(--c-stone);
  margin: var(--s-32) 0 var(--s-32);
}
.pp-rule::before {
  content: "";
  position: absolute;
  top: 0;
  right: 100%;
  width: 50vw;
  height: 1px;
  background: var(--c-stone);
}

.pp-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-12);
}

/* The figure. No frame, no radius, no shadow, no card. */
/* Two positions, because the clearance to the text block is not the same
   at every width. From 1200px up there is room to bring her in off the
   edge, which is where she sits best. Below that, pulling her inward eats
   the gap fast: at 900px with a tall window the clearance drops to 58px,
   so she goes back to the edge with a small bleed instead.

   Where a bleed is used it is a translate, not a negative `right`. A
   percentage in translate resolves against the element's OWN width, and
   the two figures are not the same width (Brittany stands in profile at
   374px native, Catherine square-on at 523px). A fixed offset clipped
   12% off Brittany and 9% off Catherine, reading as a crop mistake on
   her; a percentage clips both the same. */
.pp-portrait {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 1;
  height: min(96svh, 1040px);
  transform: translateX(4%);
  pointer-events: none;
}
@media (min-width: 1200px) {
  .pp-portrait {
    right: var(--pp-inset, 5vw);
    transform: none;
  }
}

/* Brittany stands in profile and Catherine square-on, so at the same
   inset Brittany's figure is ~76px narrower and reads as sitting further
   right even though both are the same distance from the edge. The inset
   is per-provider so the two compositions balance, not so the numbers
   match. 9vw puts her optical centre just inside Catherine's. */
.provider-page--brittany-ptachick { --pp-inset: 9vw; }
.pp-portrait picture,
.pp-portrait img {
  display: block;
  height: 100%;
  width: auto;
  filter: var(--pp-photo);
}

/* ---------- 2. Bio ---------- */
/* Section rhythm decelerates down the page: 100svh -> 128/96 ->
   72 to the closing CTA. Uniform padding is monotony. */
.pp-bio {
  background: var(--c-pearl);
  padding: var(--s-128) 0 var(--s-96);
}
.pp-bio-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 80px;
}
.pp-bio-inner .h2 {
  margin: 0 0 var(--s-48);
}

/* The hero puts the figure right and the type left. This puts the
   figure left and the type right, so the two sections counter each
   other instead of repeating a layout family. */
.pp-bio-grid {
  display: grid;
  grid-template-columns: 38% 1fr;
  column-gap: var(--s-64);
  align-items: start;
}
.pp-bio-figure {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: var(--c-mint);
  padding: var(--s-32) var(--s-24) 0;
}
.pp-bio-figure img {
  display: block;
  width: 100%;
  height: auto;
  filter: var(--pp-photo);
}

.pp-bio-copy p {
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  color: var(--c-ink);
  /* impeccable caps body measure at 65-75ch. */
  max-width: 68ch;
  margin: 0 0 var(--s-24);
}
.pp-bio-copy p:last-of-type {
  margin-bottom: 0;
}

/* ---------- At a glance ---------- */
/* A plain list, as asked. Two columns so nine one-line facts do not
   become a tall thin stack, and no rule under each row: a hairline
   per item turns a list of credentials into a spec sheet. One rule
   above the block, none inside it. */
.pp-glance {
  margin: var(--s-64) 0 0;
  padding: var(--s-32) 0 0;
  border-top: 1px solid var(--c-stone);
}
.pp-glance ul {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: var(--s-64);
}
.pp-glance li {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  color: var(--c-ink);
  margin: 0 0 var(--s-16);
  padding-left: var(--s-16);
  position: relative;
  break-inside: avoid;
}
.pp-glance li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 1px;
  background: var(--c-sea);
}

/* ---------- Section labels ---------- */
.pp-label {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--pp-tag);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-sea-text);          /* 5.10:1 on Pearl */
  margin: 0 0 var(--s-16);
}

/* ---------- Specialty tags ---------- */
/* Not cards, and deliberately not pills either. Buttons on this
   site are 6px; these sit within ~400px of one and would lie about
   being clickable if they took the same radius and any fill.
   4px + a hairline + no fill is the rule, and it exists only
   because of that adjacency. */
.pp-specialties {
  margin: var(--s-48) 0 0;
}
.pp-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-8);
  list-style: none;
  margin: 0;
  padding: 0;
}
.pp-tags li {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 14px;
  line-height: 1;
  color: var(--c-ink);
  border: 1px solid var(--c-stone);
  border-radius: 4px;
  padding: 10px 14px;
}

.pp-bio-cta {
  margin: var(--s-64) 0 0;
  text-align: center;
}

/* ---------- Responsive ---------- */
@media (max-width: 1023px) {
  .pp-hero-inner,
  .pp-bio-inner { padding: 0 48px; }
  .pp-bio-grid { column-gap: var(--s-48); }
}

/* Below 900px the hero stacks: text first, portrait beneath it,
   capped at 55vh so it never eats the fold on a short phone. */
@media (max-width: 899px) {
  .pp-hero {
    display: block;
    min-height: 0;
    padding: var(--s-64) 0 0;
  }
  .pp-hero-text { max-width: none; }
  .pp-portrait {
    position: relative;
    right: auto;
    height: auto;
    /* Stacked, she is centred, so the bleed has to go. */
    transform: none;
    margin: var(--s-48) auto 0;
  }
  .pp-portrait picture,
  .pp-portrait img {
    height: auto;
    max-height: 55vh;
    width: auto;
    margin: 0 auto;
  }
  .pp-bio { padding: var(--s-96) 0 var(--s-64); }
  .pp-bio-grid {
    grid-template-columns: 1fr;
    row-gap: var(--s-32);
  }
  .pp-bio-figure { padding: var(--s-24) var(--s-24) 0; }
  .pp-bio-figure img { max-width: 420px; margin: 0 auto; }
  /* Two columns of long credential lines do not fit a phone. */
  .pp-glance ul { columns: 1; }
  .pp-glance { margin-top: var(--s-48); }
}

@media (max-width: 767px) {
  .pp-hero-inner,
  .pp-bio-inner { padding: 0 24px; }
  .pp-position { font-size: 17px; letter-spacing: 0.08em; max-width: none; }
  .pp-glance li { font-size: 15px; }
  .pp-actions .btn { width: 100%; }
  .pp-bio-copy p { font-size: 16px; }
}

/* ---------- Motion ---------- */
/* These pages are visited once or twice per patient, before
   booking — the "rare / first-time" row of the frequency table —
   so one restrained entrance is justified and nothing else is.
   Its single job is hierarchy: it states the reading order of the
   hero stack in the first 460ms. The portrait does not animate;
   giving the figure a reveal as well would be two entrances
   competing for the same moment.

   8px and 220ms rather than the site's 20px / 280ms: the stack is
   five short items in a column, and the larger rise reads as drift
   at that density. Delays are inline, 60ms apart. Nothing is
   gated on the animation — the buttons are hit-testable on frame
   one. */
.provider-page .pp-hero .reveal {
  transform: translateY(8px);
  transition-duration: 220ms;
}

@media (prefers-reduced-motion: reduce) {
  /* styles.css collapses every transition to 0.01ms !important and
     forces .reveal to opacity 1, so the site-wide reduced-motion
     behaviour is currently zero motion rather than reduced motion.
     Reduced means fewer and gentler, not none: movement goes,
     the opacity fade stays. Scoped to this page — changing that
     globally is a separate call. */
  .provider-page .pp-hero .reveal {
    opacity: 0 !important;
    transform: none !important;
    transition: opacity 200ms ease-out !important;
  }
  .provider-page .pp-hero .reveal.in {
    opacity: 1 !important;
  }
}
