/* ── Sobre mí ──────────────────────────────────────────────────────────────
   The story, told down a line.

   Three beats hang off a rule running through the middle of the section: who
   he is, what he is for, and what a consultation with him is actually like.
   The rule fills as the section is read — js/about.js scrubs the beam over it
   against scroll and lights each dot as it is passed — so the line is a
   reading position rather than a graphic behind the words.

   Then it lets go, and the section becomes the ordinary thing it always was:
   his face, and his record beside it. That is the whole shape of it. Nothing
   here is a card and nothing here is centred in a measure; the line is the
   layout, until it stops.

   The rounded top corners and the z-index belong to the transition: this
   section is the thing that slides up over the pinned hero, so it carries
   its own ground and its own lip. See css/hero.css.
   ────────────────────────────────────────────────────────────────────────── */

.about {
  position: relative;
  /* Above the hero, which is pinned underneath it. */
  z-index: 1;
  background: var(--ground);
  /* The lip that rides over the hero. Squared off again once the section has
     landed would be a second animation; at this radius it simply reads as the
     edge of the sheet. */
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
  /* So the photograph's top-left corner is cut by that radius rather than
     poking through it. */
  overflow: hidden;
}

.about__inner {
  width: var(--measure);
  margin-inline: auto;
  padding: clamp(3.5rem, 8vw, 7rem) var(--gutter);
}

/* ── His face ──────────────────────────────────────────────────────────────
   A tall, heavily rounded frame rather than a rectangle or a circle: the
   corners are soft enough to read as a portrait and square enough not to
   read as an avatar. The photograph inside is larger than the frame so the
   slow drift js/about.js gives it never pulls an edge into view.
   ────────────────────────────────────────────────────────────────────────── */

.about__figure {
  position: relative;
  margin: 0;
  width: clamp(15rem, 26vw, 23rem);
  aspect-ratio: 5 / 7;
  background: var(--ground-alt);
  border-radius: clamp(3rem, 7vw, 6rem);
  overflow: hidden;
}

/* No will-change and no drift. The portrait is the one thing in this section
   that holds still — everything else in the scene moves around it and ends
   at it — and promoting it to its own layer only risked the frame being left
   unpainted when the section is rebuilt around it. */
.about__portrait {
  position: absolute;
  left: 0;
  right: 0;
  /* A little taller than the frame, so the crop is a choice rather than the
     photograph's own edges. */
  top: -4%;
  width: 100%;
  height: 108%;
  object-fit: cover;
  object-position: center 28%;
}

/* ── The story ─────────────────────────────────────────────────────────────
   A line down the middle with three beats hung off it, alternating sides.

   The track is the full height and always there; the beam over it is what
   moves — js/about.js scrubs its height against scroll, so the line draws
   itself at exactly the rate the section is read rather than on a clock of
   its own. Each dot lights as the beam reaches it.
   ────────────────────────────────────────────────────────────────────────── */

.tl {
  position: relative;
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
}

.tl__track {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0.5rem;
  width: 2px;
  background: var(--ink-12);
}

.tl__beam {
  position: absolute;
  inset: 0 0 auto 0;
  height: 0;
  background: linear-gradient(to bottom,
    var(--accent) 0%, var(--accent) 72%, transparent 100%);
}

/* flow-root so the last beat's margin stays inside. Without it that margin
   collapses out through the list and the track stops short of the portrait
   the line is supposed to be arriving at. */
.tl__beats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flow-root;
}

/* The space between beats is margin, not padding, and deliberately so: the
   dot is centred on the beat's box, so a gap held inside that box would sit
   the mark half a gap below the words it marks. */
.tl__beat {
  position: relative;
  padding-left: clamp(2rem, 5vw, 2.75rem);
  margin-bottom: clamp(4.4rem, 12.1vw, 7.7rem);
}

.tl__beat:last-child { margin-bottom: clamp(3rem, 7vw, 5rem); }

/* ── The photographs ───────────────────────────────────────────────────────
   One per beat, in the half the words are not using. They are not cards:
   no rule, no shadow, no tilt. What makes them read as floating is that they
   move — js/about.js drifts each one at its own rate against the scroll, so
   they never sit still relative to the text beside them.

   The corner radius is the portrait's, a size down. That is deliberate: by
   the time the line reaches the bottom of the section the reader has seen
   this shape three times, so the portrait it ends at is not a new object —
   it is the last and largest of the same family.
   ────────────────────────────────────────────────────────────────────────── */

.tl__shot {
  position: relative;
  overflow: hidden;
  border-radius: clamp(1.75rem, 3.5vw, 3rem);
  background: var(--ground-alt);
  aspect-ratio: 16 / 11;
  margin-top: clamp(1.5rem, 4vw, 2rem);
}

/* Taller than its frame, so the drift never pulls an edge into view.

   No will-change here, deliberately. These start hidden and hold a lazily
   decoded photograph, and promoting that combination to its own layer up
   front left Chrome showing an empty frame for seconds after the image had
   decoded — the layer was never repainted. GSAP promotes what it is actually
   animating for the length of the tween, which is all this needs. */
.tl__shot img {
  position: absolute;
  left: 0;
  top: -8%;
  width: 100%;
  height: 116%;
  object-fit: cover;
  object-position: center 38%;
}

/* The dot. Hollow until the beam reaches it, then filled — so the line is
   not decoration running behind the words but a reading position. */
.tl__beat::before {
  content: "";
  position: absolute;
  left: 0.5rem;
  top: 0.55em;
  width: 0.8125rem;
  height: 0.8125rem;
  border-radius: 50%;
  transform: translateX(-50%);
  background: var(--ground-alt);
  border: 2px solid var(--ink-12);
  transition: background-color 360ms var(--ease), border-color 360ms var(--ease);
}

.tl__beat[data-lit]::before {
  background: var(--accent);
  border-color: var(--accent);
}

.tl__title { margin: 0 0 0.6rem; }

/* Both a step up the scale from where they started. This is the one place on
   the page where the reader is being told something in the doctor's own
   voice rather than shown a list, and at body size it read as caption to the
   photograph beside it instead of the other way round. Line-height comes
   down as the size goes up — 1.6 is a body measure and leaves large type
   looking loose. */

.tl__lede {
  margin: 0;
  font-size: var(--fs-title-s);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: var(--track-body);
  color: var(--accent);
}

.tl__text {
  margin: 0;
  font-size: var(--fs-lead);
  line-height: 1.5;
  letter-spacing: var(--track-body);
  color: var(--ink-70);
  text-wrap: pretty;
}

/* ── From 56rem: the line moves to the middle ──────────────────────────────
   Beats alternate either side of it, and each one is set against the line
   rather than away from it — the odd ones ranged right, the even ones left.
   That is what makes the line read as the spine of the story instead of a
   rule that happens to run past three paragraphs.

   Below this width there is no room for two columns, so the line goes to the
   left edge and every beat hangs off it the same way.
   ────────────────────────────────────────────────────────────────────────── */

@media (min-width: 56rem) {
  .tl__track,
  .tl__beat::before { left: 50%; }

  /* Two equal halves with the line running down the gap between them, so the
     words and the photograph are the same distance from it on either side. */
  .tl__beat {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(3rem, 7vw, 5.5rem);
    align-items: center;
    padding-left: 0;
    margin-bottom: clamp(6.6rem, 14.3vw, 11rem);
  }

  .tl__beat:last-child { margin-bottom: clamp(4rem, 9vw, 7rem); }

  /* Both pinned to row 1. Without it the even beats break: the card takes
     column 2, which walks the auto-placement cursor past column 1, so the
     photograph is pushed down into a second row and the two stop being a
     pair. */
  .tl__card,
  .tl__shot { grid-row: 1; }

  /* Words and photograph are centred against each other here, so the mark
     goes to the middle of the beat rather than its first line — otherwise it
     sits level with the top corner of a photograph and nothing else. */
  .tl__beat::before {
    top: 50%;
    transform: translate(-50%, -50%);
  }

  .tl__beat:nth-of-type(odd)  .tl__card { grid-column: 1; text-align: right; }
  .tl__beat:nth-of-type(odd)  .tl__shot { grid-column: 2; }
  .tl__beat:nth-of-type(even) .tl__card { grid-column: 2; }
  .tl__beat:nth-of-type(even) .tl__shot { grid-column: 1; }

  /* Upright, and well short of its half: a photograph that filled the column
     would be the other half of a two-column layout. This one has room around
     it, which is the difference between placed and floating. */
  .tl__shot {
    width: min(100%, 20rem);
    aspect-ratio: 4 / 5;
    margin-top: 0;
  }

  .tl__beat:nth-of-type(odd)  .tl__shot { justify-self: start; }
  .tl__beat:nth-of-type(even) .tl__shot { justify-self: end; }
}

/* ── Entrance ──────────────────────────────────────────────────────────────
   The photographs start closed, because js/about.js opens each one like a
   curtain as it is scrolled to. Nothing may start hidden that nothing will
   ever show, so both escapes are here: no script at all, and motion turned
   down.
   ────────────────────────────────────────────────────────────────────────── */

.tl__shot { opacity: 0; }

.no-js .tl__shot { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .tl__shot { opacity: 1; }
  .tl__beat::before { transition-duration: 1ms; }
}

/* ── Where the line lets go ───────────────────────────────────────────────
   The story stops and the section resolves into three parts: the promise the
   whole page is making, his face, and the two reasons to believe it — what
   he trained in, and what his patients said afterwards.

   The flanking columns are ranged toward the middle, which is what holds the
   three of them together as one row rather than three things in a line.
   ────────────────────────────────────────────────────────────────────────── */

.about__end {
  display: grid;
  gap: clamp(2rem, 4.5vw, 3rem);
  margin-top: clamp(3.5rem, 8vw, 6rem);
  justify-items: center;
}

.about__headline {
  margin: 0;
  text-wrap: balance;
}

.about__headline .oh { display: block; }

/* ── The count ────────────────────────────────────────────────────────────
   Five stars and the number behind them. It sits under the record because it
   is the same kind of claim — something outside this page vouching for him —
   and it is the only one of the two he did not earn himself.
   ────────────────────────────────────────────────────────────────────────── */

.about__proof { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }

.about__rating {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  margin: 0 0 clamp(0.9rem, 2vw, 1.25rem);
}

.about__stars { display: inline-flex; gap: 0.1875rem; }

.about__star {
  width: 0.9375rem;
  height: 0.9375rem;
  fill: var(--star);
  flex: none;
}

.about__rating-txt {
  font-size: var(--fs-meta);
  font-weight: 500;
  letter-spacing: var(--track-body);
  color: var(--ink-70);
  text-wrap: pretty;
}

/* ── Below 56rem ───────────────────────────────────────────────────────────
   One column: the promise, then his face, then the record. The photograph
   has the full measure to itself here, so it is larger than the share it
   gets between two columns at desktop width.
   ────────────────────────────────────────────────────────────────────────── */

@media (max-width: 55.99rem) {
  .about__figure  { width: min(26rem, 82vw); }
  .about__record  { width: 100%; }
  .about__end     { justify-items: center; }
  /* Full measure, not fit-content: centred inside a box only as wide as its
     longest line, the headline wraps far earlier than it needs to. */
  .about__headline { text-align: center; width: 100%; }
}

@media (min-width: 56rem) {
  .about__end {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    column-gap: clamp(2rem, 5vw, 4rem);
    justify-items: stretch;
  }

  .about__headline { text-align: right; }

  .about__record { text-align: left; }

  /* A third of the measure is too narrow for the 8.5rem label column, so the
     rows stack label over value — and once they stack they need room between
     them, or six short lines read as one block of grey. */
  .about__record .creds { margin-bottom: 0; gap: clamp(1.15rem, 2.4vw, 1.6rem); }
  .about__record .creds__row { grid-template-columns: minmax(0, 1fr); }

  /* The headline is display type in a narrow column; it wants its own
     leading rather than the section default. */
  .about__headline { line-height: 1.04; }
}

/* ── The record ────────────────────────────────────────────────────────────
   Ruled top and bottom: it is a band of its own beside the photograph, not
   the block that closes a column of prose.

   Everything here is set loose rather than tight. Six short lines of small
   type in a narrow column read as one block of grey if they are packed, and
   the whole point of a record is that each line is a separate claim.
   ────────────────────────────────────────────────────────────────────────── */

.creds {
  margin: 0 0 clamp(1.75rem, 3.5vw, 2.5rem);
  padding-block: clamp(1.4rem, 2.8vw, 2rem);
  border-top: 1px solid var(--ink-12);
  border-bottom: 1px solid var(--ink-12);
  display: grid;
  gap: 0.95rem;
}

.creds__row {
  display: grid;
  gap: 0.3rem 1rem;
}

@media (min-width: 30rem) {
  .creds__row {
    grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
    align-items: baseline;
  }
}

.creds dt {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* Two memberships are two things. They were one string joined by a middle
   dot, which read as a single unwieldy name. */
.creds__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.4rem;
}

.creds dd {
  margin: 0;
  font-size: var(--fs-ui);
  line-height: 1.45;
  letter-spacing: var(--track-body);
  color: var(--ink-70);
  text-wrap: pretty;
}

/* A licence number is looked up, digit by digit, against a register — so it
   is set to be read that way rather than as prose. */
.creds__num {
  font-variant-numeric: tabular-nums;
  letter-spacing: normal;
  color: var(--ink);
  font-weight: 500;
}

/* ── The turning mark ──────────────────────────────────────────────────────
   The badge sits in the section's top corner and never stops turning — slowly
   on its own, and faster while the page is being scrolled, in whichever
   direction the scroll is going. js/about.js drives it.

   It is behind the story and in front of nothing: it reads as a watermark on
   the corner rather than as a thing to click.
   ────────────────────────────────────────────────────────────────────────── */

.about__badge {
  position: absolute;
  top: clamp(1.25rem, 3.5vw, 3rem);
  right: clamp(1.25rem, 3.5vw, 3rem);
  z-index: 2;
  width: clamp(4.5rem, 9vw, 8rem);
  height: auto;
  /* Its own centre, or it would wobble instead of turning. It turns about
     its upright axis — see js/about.js. */
  transform-origin: 50% 50%;
  will-change: transform;
  pointer-events: none;
}

/* Stacked, the top corner belongs to the photograph — the mark sits on it,
   small, rather than crowding the words. */
@media (max-width: 55.99rem) {
  .about__badge {
    width: clamp(3.25rem, 14vw, 5rem);
    top: clamp(0.875rem, 3vw, 1.25rem);
    right: clamp(0.875rem, 3vw, 1.25rem);
  }
}

/* ── The licences, on a phone ──────────────────────────────────────────────
   The hero carries these at desktop width. Below 48rem it does not, so the
   record does — the same two rows, the same markup, one of the pair always
   display:none and therefore out of the accessibility tree as well as the
   layout. See the matching rule in css/hero.css.
   ────────────────────────────────────────────────────────────────────────── */

.creds__row--phone { display: none; }

@media (max-width: 47.99rem) {
  .creds__row--phone { display: grid; }
}
