/* ============================================================================
   OUR HOSPITALS  —  our-hospitals.html
   Loads AFTER site.css -> v4.css -> network.css. network.css carries the page
   type scale (--t-display ... --t-micro) and the shared .net-eyebrow / .net-h2,
   so this file only adds what is genuinely new.

   WHAT THIS PAGE IS (Brees, 8/21, after picking direction B):
     "It's not meant to highlight milford in a sense of what they do — more of
      they are part of the network... This is perfect to eventually grow."
   So: membership and geography, NOT a services page. There is deliberately no
   equipment ledger and no clinical-capability copy here; that argument belongs
   to excelsior-network.html. Identity facts only.

   BUILT TO GROW: .oh-entry is a REPEATABLE record. Adding hospital #2 is one
   more <li class="oh-entry">, no layout work. Nothing on this page is written
   as though there is exactly one.
   🔴 Never add an empty/placeholder entry to "fill" the list. The client is
   specifically sensitive about exposing how few practices there are; a vacant
   slot advertises the gap louder than a short list does.

   MOBILE-FIRST: single column is the BASE; splits are added at min-width 861px.
   (This repo has shipped the shadowed-override bug four times.)
   ========================================================================== */

/* ---- 1. HERO — the Partner With Us triptych ---------------------------
   Brees, 8/21: "Section 1 is a bit hard to see the video... keep it so that
   way it's the same style as the Partner Us Hero."
   It WAS a full-bleed background video under a .78 scrim, which is exactly why
   the footage was hard to read: the scrim existed to make text legible over it,
   and it did that by hiding the video. The triptych gives the video its own
   panel at full brightness and puts the type on the navy ground beside it, so
   nothing has to be dimmed.
   Structure and classes are the SHARED ones (.triptych / .triptych__panel /
   .triptych__media / .phero--dark) — this file only re-centres the text, the
   same three lines pwu.css uses.
   🔴 The <video> MUST carry class="triptych__media". A video's height attribute
   lands as real CSS height (there is no UA rule for it, unlike <img>), and the
   class's height:auto is what overrides it — without it the panel renders
   390x1200 next to the image's 390x519. site.css records that exact bug. */
.oh-hero .triptych__text { text-align: center; }
.oh-hero .phero__title,
.oh-hero .phero__lede { margin-inline: auto; }
.oh-hero .phero__title { max-width: 18ch; }
.oh-hero .phero__lede  { max-width: 34ch; }
.oh-hero .btn-row { justify-content: center; }

/* ---- 2. THE MAP -------------------------------------------------------
   Geometry is real: Albers Equal Area Conic over public-domain state
   boundaries, and two REAL coordinates. No invented pins, ever.
   🔴 Albers returns y increasing NORTHWARD and SVG's y axis points DOWN, so
   the generator flips y. Without that flip New York renders south of
   Pennsylvania. Regenerate only via .shots/make-hospitals-map.py.

   Two framings: the country (where the network is going) and the belt (where
   the hospital actually is). At national scale Milford and Middletown are ~6px
   apart — 25 real miles across a continent — so the zoom is not decoration,
   it is the only way both points are ever legible. */
.oh-geo { padding-block: clamp(56px, 7vw, 96px); }
.oh-geo__head { max-width: 46ch; margin: 0 0 var(--sp-3); }
.oh-geo__lede { font-family: var(--font-body); font-size: var(--t-body);
  line-height: 1.75; color: rgba(251,247,239,.82); max-width: 56ch;
  margin: var(--sp-1) 0 0; }

/* 🔴 A sticky child dies inside ANY overflow:hidden/clip ancestor — the network
   page records exactly that failure. .oh-geo and .oh-geo__stage must not clip. */
.oh-geo__stage { position: relative; }
.oh-map { position: relative; background: var(--navy-deep); }
.oh-map__svg { display: block; width: 100%; height: auto; }

.oh-map__stage { transform-origin: 0 0;
  transition: transform 1.5s cubic-bezier(.22,.61,.36,1); }
.oh-map.is-zoomed .oh-map__stage {
  transform: translate(var(--ztx), var(--zty)) scale(var(--zscale)); }

/* states: hairlines. vector-effect keeps them 1px through the zoom.
   .oh-st--home = the states the network is ACTUALLY IN (PA: the flagship;
   NY: the office). It is not a target region - see make-hospitals-map.py. */
.oh-st { fill: none; stroke: rgba(251,247,239,.14); stroke-width: 1;
  vector-effect: non-scaling-stroke;
  opacity: 0; transition: opacity .8s var(--ease); }
.oh-st--home { stroke: rgba(251,247,239,.62); stroke-width: 1.25;
  fill: rgba(251,247,239,.085); }
.oh-map.is-in .oh-st { opacity: 1; }
.oh-map.is-in .oh-st:nth-child(3n)   { transition-delay: .10s; }
.oh-map.is-in .oh-st:nth-child(3n+1) { transition-delay: .20s; }
.oh-map.is-in .oh-st:nth-child(3n+2) { transition-delay: .30s; }
.oh-map.is-in .oh-st--home { transition-delay: .55s; }

.oh-link { stroke: rgba(251,247,239,.42); stroke-width: 1;
  vector-effect: non-scaling-stroke; stroke-dasharray: 4 4;
  opacity: 0; transition: opacity .6s var(--ease) .25s; }
.oh-map.is-zoomed .oh-link { opacity: 1; }

.oh-pin { opacity: 0; transform: translateY(-10px);
  transition: opacity .5s var(--ease), transform .5s var(--ease); }
.oh-map.is-zoomed .oh-pin { opacity: 1; transform: none; }
.oh-map.is-zoomed .oh-pin--b { transition-delay: .18s; }
.oh-pin__dot { fill: var(--gold); }        /* gold on navy — 1 of 2 this page */
.oh-pin--b .oh-pin__dot { fill: rgba(251,247,239,.9); }
.oh-pin__ring { fill: none; stroke: var(--gold); stroke-width: 1;
  vector-effect: non-scaling-stroke; opacity: .55; }
.oh-pin--b .oh-pin__ring { stroke: rgba(251,247,239,.7); }

/* The SVG is aria-hidden. THIS list is the content — same contract as the
   network page's constellation. The map must never be the only way to get a
   fact off this page. */
.oh-key { margin: var(--sp-3) 0 0; border-top: 1px solid rgba(251,247,239,.16); }
.oh-key__row { border-bottom: 1px solid rgba(251,247,239,.16);
  padding-block: 16px; display: grid; gap: 6px; }
.oh-key__k { font-family: var(--font-body); font-weight: 700;
  font-size: var(--t-micro); letter-spacing: .12em; text-transform: uppercase;
  color: #9AA6C4; }
.oh-key__v { font-family: var(--font-head); font-weight: 500;
  font-size: var(--t-statement); line-height: 1.3; color: var(--cream);
  margin: 0; }
.oh-key__d { font-family: var(--font-body); font-size: var(--t-ui);
  line-height: 1.6; color: rgba(251,247,239,.82); margin: 0; }
.oh-key__v .oh-dot { display: inline-block; width: .5em; height: .5em;
  border-radius: 50%; background: var(--gold); margin-right: .5em;
  transform: translateY(-.15em); }
.oh-key__row--office .oh-dot { background: rgba(251,247,239,.9); }

/* The WHOLE composition pins, not just the map: pinning the map alone lets the
   key scroll away and leaves half the stage empty for the entire hold. */
.oh-geo__cols { display: grid; gap: clamp(28px, 4vw, 64px); }
.oh-geo__room { height: 0; }               /* scroll room lives INSIDE the stage */
@media (min-width: 861px) {
  .oh-geo__sticky { position: sticky; top: calc(var(--header-h, 93px) + 24px); }
  .oh-geo__cols { grid-template-columns: minmax(0, 1.4fr) minmax(0, .6fr);
    align-items: center; }
  .oh-key { margin-top: 0; }
  .oh-geo__room { height: 95vh; }
}
@media (prefers-reduced-motion: reduce) {
  /* No travel. Land on the belt framing immediately — it is the only one that
     actually shows both locations. */
  .oh-map__stage { transition: none;
    transform: translate(var(--ztx), var(--zty)) scale(var(--zscale)); }
  .oh-st, .oh-pin, .oh-link { opacity: 1 !important; transform: none !important;
    transition: none !important; }
}

/* ---- 3. MEMBER PRACTICES — the repeatable record ---------------------- */
.oh-entries { margin: 0; padding: 0; list-style: none;
  border-top: 1px solid var(--rule); }
.oh-entry { border-bottom: 1px solid var(--rule);
  padding-block: clamp(32px, 4.5vw, 64px); display: grid;
  gap: clamp(24px, 3.5vw, 44px); }
.oh-entry__label { font-family: var(--font-body); font-weight: 700;
  font-size: var(--t-micro); letter-spacing: .14em; text-transform: uppercase;
  color: var(--red); margin: 0 0 10px; }
.oh-entry__name { font-family: var(--font-head); font-weight: 500;
  font-size: var(--t-heading); line-height: 1.18; color: var(--navy);
  margin: 0 0 6px; max-width: 20ch; }
.oh-entry__where { font-family: var(--font-head); font-weight: 400;
  font-size: var(--t-statement); line-height: 1.35; color: var(--navy-soft);
  margin: 0 0 var(--sp-1); }
.oh-entry__body { font-family: var(--font-head); font-weight: 400;
  font-size: var(--t-body); line-height: 1.62; color: var(--navy-soft);
  max-width: 48ch; margin: 0; }
.oh-entry__body strong { color: var(--navy); font-weight: 500; }

.oh-facts { margin: var(--sp-2) 0 0; border-top: 1px solid var(--rule); }
.oh-fact { border-bottom: 1px solid var(--rule); padding-block: 13px;
  display: grid; gap: 4px;
  font-family: var(--font-body); font-size: var(--t-ui); color: var(--navy); }
.oh-fact__k { font-weight: 700; font-size: var(--t-micro);
  letter-spacing: .12em; text-transform: uppercase; color: var(--navy-soft); }
.oh-fact__v { margin: 0; line-height: 1.6; }
.oh-entry a { color: var(--navy); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 1px;
  text-decoration-color: var(--rule); }
.oh-entry a:hover { text-decoration-color: var(--navy); }

@media (min-width: 620px) {
  .oh-fact { grid-template-columns: 11ch minmax(0, 1fr);
    gap: var(--s3); align-items: baseline; }
}
@media (min-width: 861px) {
  .oh-entry { grid-template-columns: minmax(0, .78fr) minmax(0, 1.22fr);
    gap: clamp(32px, 4.5vw, 72px); align-items: start; }
}

/* ---- 4. FIGURES — the wipe ---------------------------------------------
   A solid panel retracts off the photograph. TWO grounds need TWO colours:
   one colour for two grounds has failed in this codebase four times. */
.oh-fig { position: relative; overflow: hidden; margin: 0; }
.oh-fig img { display: block; width: 100%; height: 100%; object-fit: cover; }
.oh-fig::after { content: ""; position: absolute; inset: 0; z-index: 2;
  background: var(--cream); transform-origin: bottom;
  transition: transform 1s var(--ease); }
.oh-fig--on-band::after { background: var(--cream-2); }
.oh-fig--on-dark::after { background: var(--navy-deep); }
.oh-fig.is-in::after { transform: scaleY(0); }
/* 🔴 FAIL-SAFE. .is-in only ever lands on a .reveal element, so a .oh-fig
   WITHOUT .reveal would stay masked forever — the photograph simply gone,
   while a reveal-counter still reports 100% lit because the figure was never
   a reveal to begin with. That shipped once during this build (three team
   portraits). Degrade to a plain visible image instead of a blank box. */
.oh-fig:not(.reveal)::after { display: none; }
.oh-fig.reveal { opacity: 1; transform: none; }   /* wipe only, no double fade */
@media (prefers-reduced-motion: reduce) { .oh-fig::after { display: none; } }

.oh-entry__fig img { width: 100%; aspect-ratio: 4 / 3; }
@media (min-width: 861px) { .oh-entry__fig img { aspect-ratio: 1 / 1; } }


/* ---- 6. CLOSE ---------------------------------------------------------- */
.oh-close { position: relative; background: var(--navy-deep); overflow: hidden; }
.oh-close__bg { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0; }
.oh-close__scrim { position: absolute; inset: 0; z-index: 1;
  background: rgba(18, 29, 59, .85); }
.oh-close .wrap { position: relative; z-index: 2; }
.oh-close__title { font-family: var(--font-head); font-weight: 500;
  font-size: var(--t-display); line-height: 1.1; letter-spacing: -.02em;
  color: var(--cream); margin: 0 0 var(--sp-2); max-width: 20ch; }
.oh-close__body { font-family: var(--font-body); font-size: var(--t-body);
  line-height: 1.75; color: rgba(251,247,239,.82); max-width: 54ch;
  margin: 0 0 var(--sp-3); }

/* ---- 9. THE PRACTICE MARK -------------------------------------------
   Brees, 8/21: "What if instead of an image at the practice we just put the
   logo?" - and it is the better answer for a roster. Every practice has a mark;
   not every practice will have usable photography, and Milford has none at all
   (462 media items on their site, zero exteriors, zero facility interiors).
   A logo also scales to N entries without a photo shoot per hospital.
   ⚠️ NOT a photo slot: no aspect-ratio, no object-fit: cover, and NO wipe -
   a solid panel retracting off a logo reads as a glitch. It just fades in.
   ⚠️ The source is 330x200. Do not render it wider than ~220px or it softens. */
.oh-entry__logo { margin: 0; }
.oh-entry__logo img { width: clamp(150px, 22vw, 210px); height: auto;
  display: block; }
@media (min-width: 861px) {
  /* Top-aligned, not centred: centring left the mark floating ~320px down a
     tall fact column, reading as an accident rather than a listing. Level with
     the practice name is how a roster reads. */
  .oh-entry { align-items: start; }
  .oh-entry__logo { padding-top: 4px; }
  .oh-entry__logo img { width: clamp(170px, 15vw, 210px); }
}
