/* eyespecialist.sg — /eye-screening/ and its spokes
   ==========================================================================
   Loaded after site.css, which now owns .sec, .band, .copy, .faq and .toc —
   they lived in cataract.css until this page needed them, and a component
   used by more than one page type belongs in the shared sheet. Nothing in
   this file duplicates one of them.

   Four components here and every one is genuinely new:
     .hero--screening  one crop value
     .smx              the comparison matrix. The page's whole argument
     .rstep            the optometrist -> report -> consultation chain
     .myo              the myopia package, which cannot go in .smx

   TOKEN DISCIPLINE: every colour and font-family below resolves through a
   var(--token). No hex, oklch() or rgb() anywhere in this file.
   ========================================================================== */

/* ---- The fold ----------------------------------------------------------
 * SAME MASTER AS THE CLINIC PAGES — bedok-staff, 2000x1325, 1.509:1 — so it
 * takes the same derived value clinic.css derived for it, 50% 50%. That is
 * NOT a house default: CLAUDE.md records it as right for a 1.51:1 source and
 * wrong below it, and site.css's own 28% 100% is tuned to the 1.97:1
 * specialists photograph and would bottom-anchor this one, taking the crop
 * off the top of four heads.
 *
 * THE VALUE IS WRITTEN HERE RATHER THAN SHARED WITH .hero--clinic because the
 * two heroes are the same value for independent reasons — same master today,
 * and either page may be given its own photograph tomorrow. RE-DERIVE IT if
 * this page gets the optometrist photograph it should have: compute the
 * visible rectangle from the 50vw x 576px media box, the source's natural
 * size and the computed object-position, then crop the master to that rect
 * and look at it. */
.hero--screening .hero__media img {
  object-position: 50% 50%;
}

/* ---- .smx — the screening comparison matrix ---------------------------
 * Five columns: one row-head plus four packages. Nobody in this sector
 * publishes a per-test comparison across screening tiers, which is the
 * strongest reason this hub exists as a page rather than a section.
 *
 * IT SCROLLS INSIDE ITS OWN BOX BELOW THE WIDTH WHERE FIVE COLUMNS FIT, and
 * that is a deliberate construction rather than a fallback. html and body
 * carry overflow-x: clip, so a table allowed to overrun the content column
 * would paint past the screen edge while the document reported zero
 * horizontal overflow — the failure mode CLAUDE.md documents for
 * .btn--solid. Inside a scroll container the overrun is contained by an
 * element whose own right edge can be measured against innerWidth.
 *
 * tabindex="0" AND role="region" ARE ON THE MARKUP, NOT DECORATION. A scroll
 * container that cannot be focused cannot be scrolled from the keyboard, and
 * a table wider than its box is unreachable to anyone not using a pointer. */
.smx__scroll {
  margin-top: var(--space-lg);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

.smx__scroll:focus-visible {
  outline: var(--rule-thick) solid var(--color-focus);
  outline-offset: var(--space-3xs);
}

.smx {
  width: 100%;
  /* The floor at which five columns are still legible: a 15rem row head plus
   * four 7.5rem package columns. Below this the box scrolls rather than the
   * columns compressing — a squeezed tick column reads as a rendering fault,
   * and the gloss under each test name would break to four lines. */
  min-width: 45rem;
  border-collapse: collapse;
}

.smx th,
.smx td {
  padding-block: var(--space-sm);
  padding-inline: var(--space-xs);
  border-bottom: var(--rule-hair) solid var(--color-rule);
  text-align: left;
  vertical-align: baseline;
}

/* THE ROW HEAD TAKES THE SLACK AND THE TICK COLUMNS COLLAPSE, which is the
 * inverse of the fee table and right for the same reason it is right there.
 * width: 1% collapses a column to its own content — correct for a tick or a
 * price, wrong the moment a cell holds a phrase. Here the phrases are all in
 * the row head. */
.smx__rowhead {
  width: auto;
  padding-left: 0;
}

/* 9rem, DERIVED NOT GUESSED: the widest column label is "Diabetic retinal" at
 * --text-sm, which measures ~110px, plus two --space-xs paddings. At 7.5rem
 * all four labels wrapped to two lines. */
.smx__pack {
  width: 1%;
  min-width: 9rem;
}

/* ---- The column heads --------------------------------------------------
 * Name, price, audience. The audience line is the router — it is what turns
 * a table of ticks into a page that answers "which one do I need". */
/* A HIT AREA IS A PADDING / NEGATIVE-MARGIN PAIR, NOT SPACING. The label is
 * one line of --text-sm at 1.3, which is 18.7px — well under the site's 44px
 * floor, exactly as .crumb's and .nearby's links were. 13px of padding-block
 * cancelled by an equal negative margin takes the target to 44.7px while the
 * header row's height and the price beneath it are untouched.
 *
 * MUST BE inline-block. On an inline element the padding paints but does not
 * enlarge the hit area, which is the failure that makes this look fixed while
 * the target is still 19px. Re-check if --text-sm moves. */
.smx__name {
  display: inline-block;
  padding-block: 13px;
  margin-block: -13px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-ink);
  text-decoration: underline;
  text-decoration-thickness: var(--rule-hair);
  text-underline-offset: 0.22em;
  transition: color var(--dur-short) var(--ease-out);
}

.smx__name:hover {
  color: var(--color-accent);
}

/* Lining tabular figures, per the house rule: this column sits above four
 * numerals that must align on their own decimal. */
.smx__price {
  display: block;
  margin-top: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--text-md);
  color: var(--color-ink);
}

.smx__for {
  display: block;
  max-width: var(--measure-note);
  margin-top: var(--space-2xs);
  font-size: var(--text-xs);
  font-weight: var(--weight-body);
  line-height: 1.45;
  color: var(--color-muted);
}

/* ---- The row group -----------------------------------------------------
 * A real <th colspan scope="rowgroup"> in its own <tbody>, the same
 * construction the fee table uses. Ink at 500 rather than the mono .label
 * register — the column heads above are already a mix of faces and a third
 * one here would read as a repeat rather than a level below. */
.smx__group th {
  padding-top: var(--space-lg);
  padding-left: 0;
  border-bottom: var(--rule-hair) solid var(--color-rule-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-ink);
}

.smx tbody:first-of-type .smx__group th {
  padding-top: var(--space-sm);
}

.smx__test {
  display: block;
  font-size: var(--text-base);
  font-weight: var(--weight-body);
  color: var(--color-ink);
}

/* The plain-English gloss. It is the reason a reader who has never heard of
 * an anterior segment OCT can still use this table, and on a site whose
 * readers disproportionately have cataracts and presbyopia that is not a
 * nicety. --measure-note rather than --measure: ch resolves against the
 * element's own font-size, so a smaller line needs a wider-named token. */
.smx__gloss {
  display: block;
  max-width: var(--measure-note);
  margin-top: var(--space-3xs);
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--color-muted);
}

/* `.smx td` IS (0,1,1) AND `.smx__cell` WAS (0,1,0), SO THIS RULE LOST TO IT
 * ENTIRELY — both the centring and the top alignment were dead. Measured, not
 * guessed: on the fundus row the tick sat 17px above the em dash beside it and
 * 54px left of the "Dilated where necessary" it was labelling. Qualifying the
 * selector with the element takes it to (0,2,1) and it wins.
 *
 * THE TICK IS A BLOCK WITH AUTO MARGINS rather than an inline glyph relying on
 * text-align. An inline SVG sits ON THE BASELINE, so it can never line up with
 * an em dash in the neighbouring cell, which sits on the x-height — a stacked
 * cell needs the mark taken out of the text flow. .smx__no gets the same 20px
 * box for the same reason, so the two states occupy identical space. */
.smx td.smx__cell {
  text-align: center;
  vertical-align: top;
}

.smx__cell .tick {
  display: block;
  width: 20px;
  height: 20px;
  margin-inline: auto;
  color: var(--color-tick);
}

/* The absent cell is an em dash, not an empty box: an empty cell reads as
 * "we forgot" and a cross reads as a failure. Both states also carry a
 * visually hidden word, because a tick glyph has no accessible name and a
 * comparison table read aloud as five silent cells is unusable. */
/* --color-muted, NOT --color-rule-2. It was a rule token and measured 1.19:1
 * off painted pixels — the same figure CLAUDE.md records for the hairline that
 * vanishes on the hero field. A hairline token is for hairlines; this dash
 * CARRIES INFORMATION (a sighted reader tells "not included" from "included"
 * by it) so it takes the 4.5 text floor like any other glyph that means
 * something. At --color-muted it measures 5.25. */
.smx__no {
  display: block;
  height: 20px;
  line-height: 20px;
  color: var(--color-muted);
}

/* Dilation. The one patient-facing fact in the matrix that changes a
 * reader's day — it decides whether they can drive home — so it sits under
 * its tick rather than in a footnote nobody reaches. */
.smx__qual {
  display: block;
  max-width: 7rem;
  margin: var(--space-2xs) auto 0;
  font-size: var(--text-xs);
  line-height: 1.35;
  color: var(--color-muted);
}

.smx__basis {
  max-width: var(--measure);
  margin-top: var(--space-md);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* ---- .rstep — screening, report, consultation -------------------------
 * Three steps where the third is the only one with a price on it. The whole
 * band exists to keep "your report is read by a doctor" and "$70 to go
 * through your report with a doctor" from reading as charging twice, so the
 * INCLUDED tag on step 2 is load-bearing copy, not decoration.
 *
 * align-content: start, because normal computes to stretch and the auto rows
 * would grow to fill whichever item wrapped longest, pushing each tag off
 * its row mate's line. */
.rstep {
  display: grid;
  grid-template-columns: 1fr;
  align-content: start;
  gap: var(--space-lg);
  margin: var(--space-xl) 0 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 48rem) {
  .rstep {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-xl);
  }
}

.rstep__item {
  display: flex;
  flex-direction: column;
  align-items: start;
  padding-top: var(--space-sm);
  border-top: var(--rule-hair) solid var(--color-rule);
}

/* The numeral is metadata, so it takes the mono face the credentials and the
 * spec sheets use — not a heading face, which would make it compete with the
 * step name directly beneath it. */
/* THE GLYPH SHARES THE NUMERAL'S ROW rather than sitting above the heading.
 * Above the heading it competed with it for the top of the item; beside the
 * step number it reads as one marker — the number says which step, the glyph
 * says what happens in it. */
.rstep__n {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin: 0;
  color: var(--color-muted);
}

.rstep__icon {
  flex: none;
  width: 26px;
  height: 26px;
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rstep__name {
  margin-top: var(--space-xs);
  font-size: var(--text-lg);
  font-weight: var(--weight-subhead);
  letter-spacing: -0.008em;
}

.rstep__note {
  max-width: var(--measure-note);
  margin-top: var(--space-2xs);
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--color-ink-2);
}

/* The two filled pupils in the child glyph. .index__icon sets fill: none and
 * stroke to the accent, so a bare fill="currentColor" on those circles would
 * paint them in the HEADING's ink while the outline stayed accent — one glyph
 * in two colours. Token, not a literal, per the site's colour discipline. */
.index__icon .index__dot {
  fill: var(--color-accent);
  stroke: none;
}

/* The follow-up option, below the three included steps rather than beside
 * them. THE GAP ABOVE IS DELIBERATELY LARGER THAN THE GAP INSIDE A STEP: the
 * steps are a row, this is a separate statement about all three, and it has to
 * clear the TALLEST note in that row, not the shortest — at --space-lg it sat
 * close under step 1's two-line note and read as that step's own trailing
 * sentence. */
.rstep__after {
  max-width: var(--measure);
  margin-top: var(--space-2xl);
  padding-top: var(--space-lg);
  border-top: var(--rule-hair) solid var(--color-rule);
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--color-ink-2);
}

.rstep__after strong {
  font-weight: 600;
  color: var(--color-ink);
}

/* ---- .myo — the myopia package ----------------------------------------
 * Its own block for the reason recorded in screening-data.php: three of its
 * nine tests are in no other package, its reader is a parent, and its price
 * is NOT nett. Dropped into .smx it would sit under "All fees shown are
 * nett" and understate the figure. */
.myo {
  display: grid;
  grid-template-columns: 1fr;
  align-content: start;
  gap: var(--space-lg);
  margin-top: var(--space-xl);
}

@media (min-width: 60rem) {
  .myo {
    grid-template-columns: 18rem 1fr;
    gap: var(--space-2xl);
  }
}

.myo__price {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  line-height: 1;
  color: var(--color-ink);
}

/* The ++ is set small and raised rather than inline at full size. It is a
 * qualifier on the number, and at full size it reads as part of it. */
.myo__basis {
  margin-left: 0.1em;
  font-size: var(--text-sm);
  vertical-align: super;
  color: var(--color-muted);
}

.myo__for {
  max-width: var(--measure-note);
  margin-top: var(--space-xs);
  font-size: var(--text-base);
  color: var(--color-ink-2);
}

.myo__note {
  max-width: var(--measure-note);
  margin-top: var(--space-sm);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-muted);
}

.myo__list {
  display: grid;
  grid-template-columns: 1fr;
  align-content: start;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 40rem) {
  .myo__list {
    grid-template-columns: repeat(2, 1fr);
    column-gap: var(--space-xl);
  }
}

/* Subgrid so the tick, the name and the gloss of every item share three
 * columns rather than each item sizing its own — without it a long test
 * name in the left column pushes its gloss out of line with the right. */
.myo__test {
  display: grid;
  grid-template-columns: 20px 1fr;
  column-gap: var(--space-xs);
  align-items: baseline;
  padding-block: var(--space-sm);
  border-bottom: var(--rule-hair) solid var(--color-rule);
}

.myo__test .tick {
  width: 20px;
  height: 20px;
  color: var(--color-tick);
  transform: translateY(0.2em);
}

.myo__tname {
  font-size: var(--text-base);
  color: var(--color-ink);
}

.myo__gloss {
  grid-column: 2;
  max-width: var(--measure-note);
  margin-top: var(--space-3xs);
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--color-muted);
}
