/* ==========================================================================
   Page-scoped layout
   ========================================================================== */

/* --------------------------------------------------------------------------
   Home hero — the video reads the frame behind the headline
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: clamp(560px, 76vh, 860px);
  overflow: hidden;
  background: var(--paper);
  display: flex;
  align-items: center;
}
/* The scan is 1104px wide at source. Anchoring it to the right and capping the
   width keeps it at or below 1:1 on every viewport — stretching it was what
   made it look soft. */
.hero__media {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: min(68%, 980px);
  pointer-events: none;
}
/* .hero is a flex container, so its .shell child would otherwise shrink-to-fit
   instead of filling the band. */
.hero > .shell, .spread > .shell { position: relative; z-index: 2; width: 100%; }

.hero__veil { position: absolute; inset: 0; pointer-events: none; }
.hero__veil--side { background: linear-gradient(90deg, #fff 6%, rgba(255, 255, 255, .92) 36%, rgba(255,255,255,0) 68%); }
.hero__veil--edge { background: linear-gradient(180deg, #fff 0%, rgba(255,255,255,0) 16%, rgba(255,255,255,0) 82%, #fff 100%); }

.hero__copy {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 2.4vw, 28px);
  max-width: 640px;
  padding-block: 64px;
}

.hero__live {
  position: absolute;
  top: 32px; right: var(--gutter);
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 3;
}
.hero__sig {
  position: absolute;
  bottom: 32px; right: var(--gutter);
  z-index: 3;
}

@media (max-width: 1000px) {
  /* Read order becomes headline → visual. The corner stamps are absolutely
     positioned furniture; laid out statically they would sit outside the page
     gutter, so they go rather than half-work. */
  .hero {
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  .hero > .shell { order: 1; }
  .hero__media {
    order: 2;
    position: relative;
    right: auto; top: 0;
    transform: none;
    width: min(100%, 720px);
    margin: 4px auto 0;
  }
  .hero__veil--side { background: none; }
  .hero__veil--edge { background: linear-gradient(180deg, rgba(255,255,255,0) 78%, #fff 100%); }
  .hero__copy { padding-block: clamp(36px, 7vw, 56px) 0; }
  .hero__live, .hero__sig { display: none; }
}

/* --------------------------------------------------------------------------
   Feature bands with a full-bleed photographic backdrop
   -------------------------------------------------------------------------- */
.spread {
  position: relative;
  /*
   * Deep enough that a full-width cover crop still shows 25%–86% of the
   * capture. Below about 46vw the crop closes in from both ends and the hands
   * — which is where the wrist callout points — fall outside the frame.
   */
  min-height: clamp(560px, 46vw, 1100px);
  overflow: hidden;
  display: flex;
  align-items: center;
}

/*
 * Full bleed, no frame, no fade to transparent. The picture runs the whole band
 * and two white gradients lay over it: one across, so the copy has near-solid
 * paper under it and the capture emerges as it goes right; one down, so the
 * band dissolves into the sections above and below.
 *
 * This is the original treatment, and it is the right one. Every alternative
 * tried here — a masked panel, a defocused frame — put the picture in a box and
 * then went looking for ways to hide the box. A gradient over a full-bleed
 * image has no edges to hide in the first place.
 */
.spread__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: auto;              /* so the callouts below can sit above the veils */
}

.spread__veil {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}
.spread__veil--side {
  background: linear-gradient(90deg,
    #fff 0%,
    rgba(255, 255, 255, .97) 24%,
    rgba(255, 255, 255, .8) 42%,
    rgba(255, 255, 255, .06) 68%);
}
.spread__veil--edge {
  background: linear-gradient(180deg,
    #fff 0%,
    rgba(255, 255, 255, 0) 16%,
    rgba(255, 255, 255, 0) 84%,
    #fff 100%);
}

/* The callouts belong to the subject, not the backdrop, so they clear the wash. */
.spread__bg .anno__lines,
.spread__bg .anno__label,
.spread__bg .anno__pin,
.spread__bg .anno__box { z-index: 5; }

.spread__copy {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: min(520px, 38vw);
  padding-block: 72px;
}

/* Bottom left, under the copy: bottom right is where the wrist-load callout
   lands, and the two were printing on top of each other. */
.spread__sig { position: absolute; bottom: 28px; left: var(--gutter); z-index: 3; }

@media (max-width: 1000px) {
  /* Stacked: the capture becomes its own block above the copy, so the sideways
     wash has nothing to do and only the top-and-bottom one is kept. */
  .spread { min-height: 0; display: flex; flex-direction: column; }
  .spread > .shell { order: 2; width: 100%; }
  .spread__bg {
    order: 1;
    position: relative;
    inset: auto;
    width: 100%;
    height: clamp(300px, 62vw, 420px);
  }
  .spread__veil { display: none; }
  .spread__bg .anno__img {
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 13%, #000 87%, transparent 100%);
            mask-image: linear-gradient(180deg, transparent 0, #000 13%, #000 87%, transparent 100%);
  }
  .spread__copy { max-width: none; padding-block: 12px 40px; }
  .spread__sig { display: none; }
}

/* One band of air above each split, and none below — the section that follows
   brings its own. Two adjacent bands each contributing a full band of padding
   left a hole you could park in. */
.split-band { padding-block: var(--band) 0; }

/* An unframed hero study, with its caption below rather than over the fade. */
.bleed-figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bleed-figure__cap { align-self: flex-end; color: var(--ink-muted); }
@media (max-width: 1000px) {
  .bleed-figure__cap { align-self: flex-start; }
}

/* --------------------------------------------------------------------------
   Product page hero — copy beside a framed clinical image
   -------------------------------------------------------------------------- */
.p-hero {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: clamp(32px, 4.5vw, 56px);
  align-items: center;
  padding-block: clamp(48px, 6vw, 84px);
}
.p-hero__copy { display: flex; flex-direction: column; gap: clamp(16px, 2vw, 24px); }
@media (max-width: 1000px) {
  .p-hero { grid-template-columns: 1fr; }
}

.p-lede {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2vw, 24px);
  max-width: 760px;
  padding-block: clamp(44px, 7vw, 96px) clamp(40px, 6vw, 84px);
}

@media (max-width: 700px) {
  .p-hero { padding-block: 36px 44px; }
  .p-hero .figure--framed { padding: 6px; }
}

/* --------------------------------------------------------------------------
   Booking — interactive day grid
   -------------------------------------------------------------------------- */
.sched {
  display: grid;
  grid-template-columns: 52px repeat(3, 1fr);
  grid-auto-rows: minmax(64px, auto);
  gap: 6px;
  padding: 18px;
  background: var(--panel);
}
.sched__room {
  font-size: .71875rem;
  font-weight: 600;
  text-align: center;
  padding: 6px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  align-self: start;
}
.sched__time { font-size: .65625rem; color: var(--ink-muted); text-align: right; padding-right: 6px; padding-top: 4px; }

.slot {
  border-radius: 8px;
  padding: 7px 10px;
  font-size: .6875rem;
  line-height: 1.35;
  text-align: left;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.slot b { display: block; font-weight: 600; }
.slot__meta { color: var(--ink-faint); }
.slot--posture { background: var(--ink); color: #fff; }
.slot--scan    { background: var(--tint-alert); border: 1px solid var(--line-alert); color: var(--ink); }
.slot--scan .slot__meta    { color: var(--accent-deep); }
.slot--consult { background: var(--tint-info); border: 1px solid var(--line-info); color: var(--ink); }
.slot--consult .slot__meta { color: var(--status-info); }
.slot--open {
  border: 1px dashed var(--line-control);
  color: var(--ink-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .75rem;
  min-height: 64px;
}
button.slot:hover { transform: translateY(-2px); box-shadow: var(--lift-card); }
button.slot--open:hover { border-style: solid; border-color: var(--ink); color: var(--ink); }
/* Below 760px the three-room grid stops being readable, so each slot becomes a
   row that carries its own time and room label instead. */
@media (max-width: 760px) {
  .sched { display: flex; flex-direction: column; gap: 8px; padding: 14px; }
  .sched__room, .sched__time { display: none; }
  .sched__room-inline {
    display: block;
    font-size: .5625rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ink-muted);
    margin-bottom: 3px;
  }
  .slot--posture .sched__room-inline { color: var(--ink-faint); }
  .slot--open {
    min-height: 56px;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 2px;
  }
  .slot--open .sched__room-inline { margin-bottom: 0; }
}
@media (min-width: 761px) { .sched__room-inline { display: none; } }

/* --------------------------------------------------------------------------
   HR — roster table
   -------------------------------------------------------------------------- */
.roster { display: flex; flex-direction: column; gap: 8px; padding: 18px; }
.roster__head, .roster__row {
  display: grid;
  grid-template-columns: 2fr 1.4fr 1.4fr 1fr;
  gap: 10px;
  align-items: center;
}
.roster__head {
  padding: 8px 14px;
  font-size: .625rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.roster__row {
  padding: 11px 14px;
  font-size: .75rem;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}
.roster__name { font-weight: 600; }
.roster__cred { font-weight: 600; font-size: .71875rem; }
.roster__cred--ok    { color: var(--status-ok); }
.roster__cred--due   { color: var(--status-mild); }
.roster__cred--lapse { color: var(--status-review); }
.roster__hrs { font-variant-numeric: tabular-nums; }

.hr-body { display: grid; grid-template-columns: 1fr 300px; background: var(--panel); }
.hr-aside { padding: 18px 18px 18px 4px; display: flex; flex-direction: column; gap: 10px; }

@media (max-width: 900px) {
  .hr-body { grid-template-columns: 1fr; }
  .hr-aside { padding: 0 18px 18px; }
}
@media (max-width: 640px) {
  .roster__head { display: none; }
  .roster__row { grid-template-columns: 1fr auto; row-gap: 5px; padding: 13px 14px; }
  .roster__name { grid-column: 1 / -1; grid-row: 1; font-size: .8125rem; }
  .roster__cred { grid-column: 1; grid-row: 2; }
  .roster__hrs  { grid-column: 2; grid-row: 2; text-align: right; }
  .roster__shift {
    grid-column: 1 / -1; grid-row: 3;
    font-size: .6875rem; color: var(--ink-muted);
  }
}

/* A definite height, so the whole reading panel lands inside one screen rather
   than running off the bottom of it. */
.app__stage--survey {
  background: radial-gradient(ellipse at 50% 45%, #0e1626 0%, var(--imaging) 78%);
  padding: 20px;
  height: clamp(340px, 58vh, 560px);
}

/* Superseded by `.anno` in annotate.css, which positions overlays against the
   rendered picture rather than the box around it. */

/* --------------------------------------------------------------------------
   Modality strip — what the assistant reads
   -------------------------------------------------------------------------- */
.modalities {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2vw, 24px);
}
.modality { margin: 0; display: flex; flex-direction: column; gap: 14px; }
.modality__frame {
  position: relative;
  background: var(--imaging);
  border: 1px solid var(--line-strong);
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.modality__frame img {
  max-width: 100%;
  max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
  transition: transform var(--dur) var(--ease);
}
.modality:hover .modality__frame img { transform: scale(1.03); }
.modality__caption { display: flex; flex-direction: column; gap: 6px; }
.modality__region {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -.015em;
}

@media (max-width: 900px) { .modalities { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) {
  .modalities { grid-template-columns: 1fr; gap: 28px; }
  .modality { flex-direction: row; align-items: center; gap: 16px; }
  .modality__frame { width: 40%; flex: none; aspect-ratio: 3 / 4; }
}

/* --------------------------------------------------------------------------
   Radiology — findings review
   -------------------------------------------------------------------------- */
.impression {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  padding: 12px;
  font-size: .71875rem;
  line-height: 1.6;
  color: var(--slate-600);
}
.impression ol { margin: 0; padding-left: 18px; }
.impression li + li { margin-top: 4px; }
.impression__empty { color: var(--ink-muted); font-style: italic; }

.finding__actions { display: flex; gap: 6px; margin-top: 8px; }

/* --------------------------------------------------------------------------
   Skeletal — numbered evidence pins
   -------------------------------------------------------------------------- */
.pin {
  position: absolute;
  width: 24px; height: 24px;
  margin: -12px 0 0 -12px;   /* centre on the coordinate, leaving transform free for hover */
  border-radius: 50%;
  border: 2px solid var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .625rem;
  font-weight: 700;
  color: var(--accent);
  background: rgba(255, 255, 255, .85);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
button.pin:hover, .pin.is-active { transform: scale(1.2); background: var(--accent); color: #fff; }
.pin--resolved { border-color: var(--status-ok); color: var(--status-ok); }
button.pin--resolved:hover, .pin--resolved.is-active { background: var(--status-ok); }

/* --------------------------------------------------------------------------
   Closing call to action
   -------------------------------------------------------------------------- */
.close {
  text-align: center;
  padding-block: clamp(56px, 7vw, 100px) clamp(48px, 5vw, 80px);
  border-top: 1px solid var(--line);
}
.close .h-title, .close .h-display { max-width: 820px; margin-inline: auto; }
.close .lead { margin-top: 16px; }
.close .btn-row { margin-top: 30px; }

/* --------------------------------------------------------------------------
   404
   -------------------------------------------------------------------------- */
.missing {
  padding-block: clamp(72px, 12vw, 160px);
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: flex-start;
}

/* --------------------------------------------------------------------------
   Spinal analysis — the posture page hero
   --------------------------------------------------------------------------
   A standing full-spine film is a tall, narrow thing, and there is no honest
   way to make it a landscape image. The layout leans into that: the film runs
   as a column, and the segment callouts sit either side of it at the height of
   the vertebrae they describe.
   -------------------------------------------------------------------------- */
.sm {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(14px, 1.6vw, 20px);
  border: 1px solid var(--line);
  background: var(--paper);
  box-shadow: var(--lift-panel);
}

.sm__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.sm__global { color: var(--accent); }

.sm__stage {
  position: relative;
  display: flex;
  justify-content: flex-start;
  padding-block: 6px;

  /*
   * One number drives the film and the space the callouts get, so they cannot
   * drift apart. The film height is also the spacing budget: the seven callouts
   * are pinned to their own vertebrae, and the closest pair — T1–T9 and T6–T12
   * — sits nine percent of the film apart. Nine percent of this height has to
   * stay bigger than a callout, which is what every number below is chosen for.
   */
  --sm-film: clamp(150px, 46%, 210px);
}

.sm__film {
  position: relative;
  width: var(--sm-film);
  aspect-ratio: 575 / 1388;          /* the film's own proportions */
  background: var(--imaging);
  overflow: hidden;
  flex: none;
}

.sm__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* The plumb line and the curve are separate files lifted off the film, so each
   can be drawn on its own timing. They start clipped to nothing and are wiped
   downward, which is the direction the engine traces them. */
.sm__layer--plumb,
.sm__layer--curve {
  clip-path: inset(0 0 100% 0);
}
.js .sm.is-playing .sm__layer--plumb {
  animation: sm-draw 620ms var(--ease) 420ms forwards;
}
.js .sm.is-playing .sm__layer--curve {
  animation: sm-draw 900ms var(--ease) 1150ms forwards;
}
@keyframes sm-draw {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* the acquisition pass that precedes them */
.sm__sweep {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 22%;
  opacity: 0;
  background: linear-gradient(180deg, transparent, rgba(86, 232, 122, .18) 76%, rgba(86, 232, 122, .95));
  pointer-events: none;
}
.js .sm.is-playing .sm__sweep { animation: sm-sweep 1.6s var(--ease) 300ms 1; }
@keyframes sm-sweep {
  0%   { opacity: 0; transform: translateY(-24%); }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(460%); }
}

/* --- callouts ------------------------------------------------------------ */
.sm__callout {
  position: absolute;
  top: 0;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 0 8px;
  padding: 3px 0;
  font-size: .625rem;
  line-height: 1.2;

  /* Default: the film sits left and every callout runs down one side of it.
     Straddling the film needs gutters wide enough for a legible column on both
     sides, and a full-width study only leaves that on a large screen. */
  left: calc(var(--sm-film) + 20px);
  right: auto;
  width: calc(100% - var(--sm-film) - 28px);
  flex-flow: row wrap;
  align-items: baseline;
  text-align: left;
}

/* the hairline that ties a callout to its level on the film */
.sm__callout::after {
  content: '';
  position: absolute;
  top: 50%;
  width: clamp(10px, 1.4vw, 20px);
  height: 1px;
  background: var(--line-control);
}
.sm__callout::after { left: -14px; right: auto; width: 10px; }

.sm__level {
  font-family: var(--font-label);
  font-size: .5625rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.sm__value {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(.9375rem, .86rem + .34vw, 1.125rem);
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.sm__shift { font-size: .625rem; color: var(--ink-muted); }

.js .sm .sm__callout { opacity: 0; }
.js .sm.is-playing .sm__callout {
  animation: sm-callout 460ms var(--ease) var(--cue) forwards;
}
@keyframes sm-callout {
  from { opacity: 0; transform: translateY(-50%) translateX(0) scale(.96); }
  to   { opacity: 1; transform: translateY(-50%); }
}

/* --- key and replay ------------------------------------------------------ */
.sm__foot {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
  padding-top: 12px;
  font-size: var(--t-fine);
  color: var(--ink-muted);
}
.sm__key { display: inline-flex; align-items: center; gap: 6px; }
.sm__swatch { width: 14px; height: 2px; border-radius: 2px; }
/* The plumb line's own green, matched to the overlay PNG rather than the
   palette — a key has to be the colour of the thing it is a key for. */
.sm__swatch--plumb { background: #56e87a; }
.sm__swatch--curve { background: var(--accent); }
.sm__replay {
  margin-left: auto;
  font-size: var(--t-fine);
  font-weight: 600;
  color: var(--ink-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  min-height: 32px;
}
.sm__replay:hover { color: var(--accent); }

/* Phones: the film is short enough that the closest pair of callouts clears by
   about 33px, so the translation figure goes and the tilt stays — the tilt is
   what the analysis leads on, and the global translation is in the header. */
@media (max-width: 700px) {
  .sm__shift { display: none; }
  .sm__value { font-size: .8125rem; }
}

/* --------------------------------------------------------------------------
   Large screens: the callouts straddle the film again
   --------------------------------------------------------------------------
   Only once there is room for a readable column either side. Below this the
   two gutters are narrower than the text they would have to hold.
   -------------------------------------------------------------------------- */
@media (min-width: 1200px) {
  .sm__stage { --sm-film: clamp(215px, 40%, 260px); justify-content: center; }

  .sm__callout {
    flex-flow: column nowrap;
    gap: 0;
    width: min(22%, 152px);
    left: auto;
    right: auto;
  }
  .sm__callout--left {
    right: calc(50% + var(--sm-film) / 2 + 16px);
    text-align: right;
    align-items: flex-end;
  }
  .sm__callout--right {
    left: calc(50% + var(--sm-film) / 2 + 16px);
    text-align: left;
    align-items: flex-start;
  }
  .sm__callout--left::after  { right: -14px; left: auto; }
  .sm__callout--right::after { left: -14px; right: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .js .sm .sm__callout,
  .js .sm.is-playing .sm__callout { opacity: 1; animation: none; transform: translateY(-50%); }
  .sm__layer--plumb, .sm__layer--curve { clip-path: none !important; animation: none !important; }
  .sm__sweep { display: none; }
}


