/* ─────────────────────────────────────────────────────────────────────────────────────────────
   restyle.css — 21 September 2026.

   THE FOURTH AND LAST STYLESHEET, AND THE ONE THAT DECIDES WHAT THE SITE LOOKS LIKE.

   Load order, set in the site layout: the legacy stylesheet, then the v2 stylesheet, then the
   bridge, then this file. Each of the first three still does its own job — components, the v2
   palette and 18px floor, and the dark-region contrast fixes. This file is the typographic and
   density layer over all of them, and it is deliberately ONE file rather than an edit spread
   across three: the change it makes is a single design decision and it has to be reviewable,
   revertible and greppable as a single thing.

   IT NAMES NO INTERNAL REPOSITORY FILE, ON PURPOSE. This stylesheet is passthrough-copied byte
   for byte, so these comments are served to every reader. Nothing here cites a repo path.

   ── WHAT IT RESTORES, AND WHY THERE IS A "RESTORES" AT ALL ────────────────────────────────
   The design that shipped on 20 September set every page in one grotesque, at large sizes, in
   rounded panels with long air between them, inside a band that used 60% of a desktop screen.
   It was rejected. The content, the data corrections and the removals from that work are RIGHT
   and are untouched here; only the presentation changes.

   The target is the site's own earlier design, recovered from its history:

     display / headings   Source Serif 4        variable serif, Google Fonts
     body                 Inter                 same source
     page background      warm off-white        not the cold flat grey
     surfaces             white, one hairline, small radius, NO shadow
     structure            hairline rules, small uppercase labels, a coloured top rule on the
                          summary card, teal reserved for actions
     figures              the size of a heading, under the sentence they support

   ── AND WHAT IS NEW RATHER THAN RECOVERED ────────────────────────────────────────────────
   THE WIDTH RULE. The band is min(92vw, 1760px), and 84vw above 2100px, so the content fills
   at least three quarters of a desktop screen at every width. The PROSE inside it is capped
   separately, so a wider page gives a SHORTER line, not a longer one: the band width goes to
   the rails, the card grids and the tables, which are the things that were starved of it.

     viewport   band      share
       1280     1178      92.0%
       1440     1325      92.0%
       1920     1760      91.7%
       2100     1760      83.8%   <- the lowest share at any desktop width
       2560     2150      84.0%

   ── THE MEASURE IS IN em, NEVER IN ch ─────────────────────────────────────────────────────
   `ch` is the advance of the digit zero, which varies by a third between interface faces, so a
   `65ch` rule renders a different line length in every typeface. `em` holds its character count
   at every step of the text-size control. 36em against Inter at 18px is 648px, and the longest
   line measured on a rendered page at 1920, 1440, 768 and 390 is 81 characters — inside the 60
   to 90 band at every one of them.
   ───────────────────────────────────────────────────────────────────────────────────────── */

:root {
  /* ── COLOUR ROLES ────────────────────────────────────────────────────────────────────────
     The brand colours are unchanged: navy #0D1D34, teal #3AC0A8, and #12705F as the teal that
     is safe as text. What changes is the neutrals, which go warm.

     MEASURED, not assumed. Every ratio below was recomputed from these hex values:
       navy      on paper      15.51:1   body text and headings
       muted     on paper       7.22:1   supporting sentences
       teal ink  on paper       5.49:1   links
       white     on teal ink    5.99:1   the primary button
       white     on navy       16.90:1   the masthead
       teal      on navy        7.47:1   a link inside a dark region
       control   on paper       3.30:1   WCAG 2.2 SC 1.4.11, the edge of a control
       hairline  on paper       1.30:1   DECORATIVE ONLY. Never the edge of a control. */
  --vox-paper:       #F7F5F0;   /* the page. Warm, not the cold flat grey it replaces.        */
  --vox-paper-dim:   #EFECE4;   /* the soft grey a statistic tile sits on.                    */
  --vox-surface:     #FFFFFF;   /* panels and cards.                                          */
  --vox-ink:         #0D1D34;   /* navy. Text, the masthead, the summary rule.                */
  --vox-muted:       #4A5261;   /* a supporting sentence, a caption, a unit.                  */
  --vox-teal:        #3AC0A8;   /* FILL ONLY. 2.08:1 on paper: never text on a light surface. */
  --vox-teal-ink:    #12705F;   /* links, and the primary button's fill under white text.     */
  --vox-hairline:    #DCD9D0;   /* decorative rules. NOT a control edge.                      */
  --vox-control:     #7D8896;   /* the visible edge of anything you click or type in.         */

  /* ── WIDTH ───────────────────────────────────────────────────────────────────────────── */
  --vox-band:    min(92vw, 1760px);
  --vox-measure: 36em;          /* prose. About 82 characters at the 18px body size.          */
  --vox-rail:    21rem;         /* the "on this page" and support rails.                      */
  /* CARD GRIDS AUTO-FILL AGAINST THIS, AND 19rem RATHER THAN 21rem IS A MEASURED FIGURE. At
     21rem a 768px screen fell one pixel short of two columns inside a panel's padding, so the
     index pages laid one 660px card per row there and the metadata line inside it ran to 98
     characters. 19rem gives two columns at 768 and five at 1920, and the longest line measured
     inside a card drops to about 50. */
  --vox-card:    19rem;

  /* ── SPACING ─────────────────────────────────────────────────────────────────────────────
     A 4px grid. In px rather than rem on purpose: when a reader presses the larger-text
     control the TEXT should grow and the whitespace should not, or an enlarged page fits less
     on screen than the ordinary one and scrolls further. */
  --vox-1:  4px;
  --vox-2:  8px;
  --vox-3:  12px;
  --vox-4:  16px;
  --vox-5:  22px;
  --vox-6:  30px;
  --vox-7:  42px;
  --vox-8:  60px;

  /* ── TYPE SCALE ──────────────────────────────────────────────────────────────────────────
     Against an 18px body. The steps are close together on purpose: a clinical page earns its
     hierarchy from weight, rule and case, not from size alone, and a 2.5x jump between body
     and h1 is what makes a page of three facts read as a poster.

       caption  0.8125rem  13px   the FLOOR. Nothing on this site is smaller.
       label    0.875rem   14px   small uppercase labels, units, chips
       body     1rem       18px   set on <body> by the v2 layer, not here
       h3       1.15rem    18.4px
       h2       1.45rem    23.2px
       h1       clamp      28 to 37.6px */
  --vox-t-caption: 0.8125rem;
  --vox-t-label:   0.875rem;
  --vox-t-h3:      1.15rem;
  --vox-t-h2:      1.45rem;
  --vox-t-h1:      clamp(1.75rem, 1.35rem + 1.1vw, 2.35rem);

  --vox-radius:       6px;      /* every corner on the site. One value, so none can drift.    */
  --vox-radius-pill:  999px;    /* status pills and nothing else.                             */
}

@media (min-width: 2100px) { :root { --vox-band: 84vw; } }
@media (max-width: 719px)  {
  /* Below 720px the band is the screen less a thumb-sized margin. 92vw would leave a 31px
     gutter on a 390px phone, which is not enough to keep text off the curve of the display. */
  :root { --vox-band: calc(100vw - 32px); }
}

/* THE GUTTER IS A TOKEN, AND THAT IS WHAT MAKES THE FULL-BLEED BANDS SAFE. The page column is
   the band, centred by equal padding on <main>; a band that has to run edge to edge cancels
   exactly that padding with a negative margin and puts it back as its own.

   NOT `calc(50% - 50vw)`, WHICH IS THE USUAL RECIPE AND IS WRONG HERE. `100vw` includes the
   scrollbar, so on a real desktop browser that recipe makes every full-bleed band about 15px
   wider than the viewport and the whole document scrolls sideways — and the usual second half
   of the recipe, `overflow-x: hidden` on an ancestor, would then hide any GENUINE sideways
   overflow from every check that looks for it. Cancelling the measured padding cannot overrun
   anything, so no clipping is needed and nothing is being masked. */
:root { --vox-gutter: max(calc((100vw - var(--vox-band)) / 2), 0px); }

/* ═══ TYPOGRAPHY ═══════════════════════════════════════════════════════════════════════════
   One family for headings, one for body, everywhere, on every page type. Before this the site
   ran two systems at once: the pages rebuilt in September set their headings in the body
   grotesque while every page that was not rebuilt kept the serif. */
body {
  font-family: var(--v2-font);
  background: var(--vox-paper);
  color: var(--vox-ink);
  line-height: 1.55;
}

h1, h2, h3, h4, h5, h6,
.v2-card__label, .v2-stat__value, .v2-tile__code,
.today-stat__n, .acc-stat-num, .error-code {
  font-family: var(--v2-font-display);
}

h1 { font-size: var(--vox-t-h1); line-height: 1.15; letter-spacing: -0.015em; font-weight: 600; margin: 0 0 var(--vox-3); }
h2 { font-size: var(--vox-t-h2); line-height: 1.22; letter-spacing: -0.008em; font-weight: 600; margin: 0 0 var(--vox-3); }
h3 { font-size: var(--vox-t-h3); line-height: 1.3;  font-weight: 600; margin: 0 0 var(--vox-2); }
h4, h5, h6 { font-size: 1rem; line-height: 1.35; font-weight: 600; margin: 0 0 var(--vox-2); }

p { margin: 0 0 var(--vox-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--vox-teal-ink); }

/* ═══ THE BAND ═════════════════════════════════════════════════════════════════════════════
   ONE BAND, SET ON <main>, AND EVERY WRAPPER INSIDE IT IS TOLD TO STOP SETTING ITS OWN.

   This site has four different content wrappers and three page families do not use one at all:
   the condition, rare-disease and trial bodies open their two-column grid as a bare child of
   <main>, so their breadcrumb, heading and intro ran to the very edge of the screen — measured
   at 1920px, the breadcrumb started at x=0. Putting the band on <main> reaches all of them,
   including any page type that is written later and forgets a wrapper. */
main {
  padding-inline: var(--vox-gutter);
  padding-bottom: var(--vox-7);
}
.v2-wrap,
main > .container,
.content-page,
.content-page > .container,
.v2-layout,
.trial-page,
.error-page {
  width: 100%;
  max-width: none;
  margin-inline: auto;
  padding-inline: 0;
}

/* THE TWO FULL-BLEED BANDS. Each cancels <main>'s gutter and puts it back as its own padding,
   so its background runs edge to edge while its contents stay on the band. */
.page-hero,
.v2-panel--navy:has(h1) {
  margin-inline: calc(-1 * var(--vox-gutter));
  padding-inline: var(--vox-gutter);
}
.page-hero .container { width: 100%; max-width: none; margin-inline: 0; padding-inline: 0; }

/* ═══ THE PROSE MEASURE ════════════════════════════════════════════════════════════════════
   Applied to the TEXT ELEMENTS, never to a wrapper. A wrapper would also cap the tables, the
   card grids and the state tiles, which are exactly the things the wide band is for. A table
   inside a panel still gets the whole column.

   THE `:not()` LIST IS LOAD-BEARING. A grid of state tiles is a `<ul>` and a direct child of a
   panel, so the first version of this rule capped the tile grid at the prose measure: the
   condition page rendered three state tiles per row inside a 1,370px column with 770px of
   nothing beside them. A list that lays out as a grid is not prose. */
main p, main dd, main blockquote,
main ul:not([class]) > li, main ol:not([class]) > li,
.v2-panel > h2, .v2-panel > h3,
.v2-sources, .v2-source-text, .v2-editorial-line,
main > .v2-wrap > h1 { max-width: var(--vox-measure); }

/* EVERY EXEMPTION IS A PARAGRAPH THAT IS NOT A PARAGRAPH, or one that already sits in a narrow
   column. `.v2-stat` and `.v2-card__links` are `<p>` elements used as a tile and as a button
   row; a card, a rail item, a tile and a table cell are already narrow, and capping inside one
   leaves a ragged right edge against its own border. */
.v2-stat, .v2-card__links, .today-stat, .today-stat *,
.v2-card p, .v2-card ul, .v2-card li,
.v2-side p, .v2-side li, .v2-side ul,
.v2-tiles, .v2-tiles li, .v2-cards, .v2-cards li, .v2-stats, .v2-freq, .v2-filters,
.shortage-recent li, .shortage-recent p, .today-row, .today-row p,
.shortage-row, .shortage-row p,
td p, td ul, td li, th p,
table p, table li { max-width: none; }

/* ═══ MASTHEAD ═════════════════════════════════════════════════════════════════════════════
   Navy band, wordmark left, navigation right, edge to edge, with its contents on the band. A
   navy strip that stops at the content edge reads as a box; one that runs the width of the
   screen with the band inside it reads as a masthead. */
.site-header { border-bottom: 2px solid var(--vox-teal); }
.header-inner {
  width: var(--vox-band);
  max-width: none;
  margin-inline: auto;
  padding: var(--vox-2) 0;
}
.site-tagline { font-size: var(--vox-t-caption); letter-spacing: 0.01em; }

/* Every header control clears 44px. The hamburger was 38x30, which is the smallest control on
   the site and the one a phone reader meets first. */
.nav-toggle { min-width: 44px; min-height: 44px; align-items: center; padding: 10px 11px; }
.site-logo--wordmark, .nav-search-icon, .nav-login {
  display: inline-flex; align-items: center; min-height: 44px;
}
.nav-search-icon { min-width: 44px; justify-content: center; }
.site-nav > a { display: inline-flex; align-items: center; min-height: 44px; }

/* ═══ FOOTER ═══════════════════════════════════════════════════════════════════════════════ */
.site-footer { border-top: 2px solid var(--vox-teal); }
.site-footer .container { width: var(--vox-band); max-width: none; padding-inline: 0; }
.site-footer a { display: inline-flex; align-items: center; }
.footer-col-h {
  font-size: var(--vox-t-label); text-transform: uppercase; letter-spacing: 0.08em;
  font-family: var(--v2-font);
}

/* ═══ SURFACES ═════════════════════════════════════════════════════════════════════════════
   Flat. One hairline, one radius, no shadow, no gradient. Depth on a clinical page is a rule,
   not a blur, and a 14px radius with a drop shadow is the single strongest "consumer app"
   signal a panel can carry. */
.v2-panel, .v2-card, .v2-trust, .acc-card, .trial-card, .shortage-headline, .today-stat {
  border-radius: var(--vox-radius);
  box-shadow: none;
}
.v2-panel {
  background: var(--vox-surface);
  border: 1px solid var(--vox-hairline);
  padding: var(--vox-5);
  margin-bottom: var(--vox-5);
}
.v2-card {
  background: var(--vox-surface);
  border: 1px solid var(--vox-hairline);
  padding: var(--vox-4);
}
.v2-trust {
  border: 1px solid var(--vox-hairline);
  border-radius: var(--vox-radius);
  padding: var(--vox-3) var(--vox-4);
  font-size: var(--vox-t-label);
  gap: var(--vox-2) var(--vox-5);
}

/* A section heading sits under a hairline, which is what gives a dense page its structure. */
.v2-panel > h2:first-child,
.v2-panel > h3:first-child {
  padding-bottom: var(--vox-2);
  border-bottom: 1px solid var(--vox-hairline);
  margin-bottom: var(--vox-4);
}
.v2-panel > h2:first-child { max-width: none; }

/* ═══ THE NAVY PANEL, WHICH WAS A WALL ═════════════════════════════════════════════════════
   A whole-panel navy fill in the middle of a page is the "wall" this restyle removes: it turns
   a summary into a billboard and it is the loudest thing on the page whatever it says. Every
   navy summary panel becomes a WHITE card with a TEAL TOP RULE — the treatment the earlier
   design used to mark a card as the lead one — and navy goes back to being the masthead, the
   footer and an accent.

   THE ONE EXCEPTION IS THE PAGE HEADING BAND. A navy band directly under a navy masthead reads
   as one masthead rather than as a slab, which is what the earlier home page did, so a navy
   panel that carries the page's own h1 keeps its fill and goes full bleed.

   `:has()` DEGRADES THE SAFE WAY. In an engine without it, the exception never matches and the
   hero renders as the same white card with a teal rule and navy text: restrained rather than
   wrong. The unreadable direction — white text on a white card — cannot occur, because the
   colour is set on the default arm and only overridden by the exception. */
.v2-panel--navy {
  background: var(--vox-surface);
  color: var(--vox-ink);
  border: 1px solid var(--vox-hairline);
  border-top: 3px solid var(--vox-teal);
}
.v2-panel--navy a:not(.v2-btn) { color: var(--vox-teal-ink); }
.v2-panel--navy .v2-stat__label { color: var(--vox-muted); }

.v2-panel--navy:has(h1) {
  background: var(--vox-ink);
  color: #FFFFFF;
  border: 0;
  border-radius: 0;
  margin-block: 0 var(--vox-6);
  padding-block: var(--vox-6);
}
/* THE HERO COLUMN IS CENTRED IN THE BAND, WHICH IS THE EARLIER DESIGN AND NOT A COMPROMISE.
   Left-aligned at a 1,760px band, a capped heading and a capped paragraph leave a 1,100px void
   down the right of the masthead and the page opens lopsided. The earlier hero was a centred
   820px column inside a full-bleed navy band, with its search row left-aligned inside that
   column, and that is what this reproduces. */
.v2-panel--navy:has(h1) > h1,
.v2-panel--navy:has(h1) > p {
  margin-inline: auto;
  text-align: center;
}
.v2-panel--navy:has(h1) > h1 { max-width: 46rem; }
.v2-panel--navy:has(h1) > p  { max-width: var(--vox-measure); }
.v2-panel--navy:has(h1) > h1 { color: #FFFFFF; }
.v2-panel--navy:has(h1) a:not(.v2-btn) { color: var(--vox-teal); }
/* THE HERO SEARCH IS A FIELD AND A BUTTON, NOT THREE EQUAL COLUMNS. v2 gives .v2-filters three
   equal tracks, which is right for the four-filter row on the trial finder and wrong here: the
   hero form has two children, so the input took a third of the column and truncated its own
   placeholder at "e.g. breast cancer, epilep". */
.v2-panel--navy:has(h1) .v2-filters { max-width: 46rem; margin-inline: auto; text-align: left; }
/* SCOPED TO 720px AND UP, because v2 stacks every filter grid below that and a two-track form
   on a 358px screen leaves the field 130px wide with the button beside it. */
@media (min-width: 720px) {
  .v2-panel--navy:has(h1) .v2-filters { grid-template-columns: minmax(0, 1fr) auto; }
}
.v2-panel--navy:has(h1) .v2-filters label { color: #FFFFFF; }

/* The breadcrumb above a full-bleed hero would otherwise sit on the band with the hero pushed
   under it; it keeps its own margin so the two do not collide. */
.v2-breadcrumb { font-size: var(--vox-t-label); margin: var(--vox-3) 0 var(--vox-2); }
.v2-breadcrumb a { padding: var(--vox-1) 0; }

/* ═══ FIGURES ══════════════════════════════════════════════════════════════════════════════
   A number in a summary panel is the size of a heading, not five times the body size, and the
   SENTENCE is what the reader is meant to read first. Before this the figure was 28px against
   a 17px label on a navy fill; it is now 23px against an 18px label on a soft grey tile, which
   is the earlier design's treatment.

   Tabular numerals, so a column of counts lines up instead of looking ragged. */
.v2-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  gap: var(--vox-3);
  margin: 0;
}
.v2-stat {
  background: var(--vox-paper-dim);
  border-radius: var(--vox-radius);
  padding: var(--vox-3) var(--vox-4);
  margin: 0;
}
.v2-stat__value {
  font-size: var(--vox-t-h2);
  font-weight: 600;
  line-height: 1.1;
  color: var(--vox-ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  order: 2;
}
.v2-stat__label {
  font-size: 1rem;
  line-height: 1.35;
  color: var(--vox-muted);
  margin-bottom: var(--vox-1);
}
/* The label is written after the figure in the markup and is READ first. Reversing the visual
   order here rather than in the markup keeps the accessible reading order — figure then its
   name — which is the order that makes sense read aloud. */
.v2-stat { display: flex; flex-direction: column; }
.v2-stat__label { order: 1; }

.v2-panel--navy:has(h1) .v2-stat { background: rgba(255,255,255,0.08); }
.v2-panel--navy:has(h1) .v2-stat__value { color: #FFFFFF; }
.v2-panel--navy:has(h1) .v2-stat__label { color: #D7DEE6; }

/* THE LEGACY STAT TILE IS THE SAME COMPONENT UNDER ANOTHER NAME, AND IT GETS THE SAME
   TREATMENT. On the shortage board and the daily update these rendered as white cards with a
   38px numeral — the same "figure first, five times the body size" shape the v2 tiles had. */
.today-stats { gap: var(--vox-3); }
.today-stat {
  display: flex;
  flex-direction: column;
  background: var(--vox-paper-dim);
  border: 0;
  border-radius: var(--vox-radius);
  padding: var(--vox-3) var(--vox-4);
}
.today-stat__n {
  order: 2;
  font-size: var(--vox-t-h2);
  font-weight: 600;
  line-height: 1.1;
  color: var(--vox-ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.today-stat__label {
  order: 1;
  font-size: var(--vox-t-label);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  color: var(--vox-muted);
  margin-bottom: var(--vox-1);
}
.today-stat__delta { order: 3; font-size: var(--vox-t-caption); color: var(--vox-muted); margin-top: var(--vox-1); }

/* ═══ CONTROLS ═════════════════════════════════════════════════════════════════════════════
   Teal buttons with white text, which is the earlier design's primary action. The FILL is the
   darker teal: white on the bright teal is 1.86:1 and is not a button, it is a decoration with
   writing on it. White on #12705F is 5.99:1. */
.v2-btn {
  border-radius: var(--vox-radius);
  font-weight: 600;
  font-size: 1rem;
  padding: var(--vox-2) var(--vox-5);
}
.v2-btn--primary {
  background: var(--vox-teal-ink);
  border-color: var(--vox-teal-ink);
  color: #FFFFFF;
}
.v2-btn--primary:hover { background: #0E5B4D; border-color: #0E5B4D; }
.btn-primary { border-radius: var(--vox-radius); box-shadow: none; }

.v2-filters select,
.v2-filters input,
.v2-textsize,
.v2-tile,
.v2-compare-toggle { border-radius: var(--vox-radius); }

.v2-filters {
  gap: var(--vox-3);
  align-items: end;
}
.v2-filters label {
  font-size: var(--vox-t-label);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  color: var(--vox-muted);
  margin-bottom: var(--vox-1);
}
.v2-filters input {
  width: 100%;
  min-height: 44px;
  padding: var(--vox-2) var(--vox-3);
  font: inherit;
  color: var(--vox-ink);
  background: var(--vox-surface);
  border: 1px solid var(--vox-control);
}

/* ═══ CARD GRIDS ═══════════════════════════════════════════════════════════════════════════
   A wider screen buys MORE CARDS, never wider cards. One card per row inside a 1,760px band is
   what made the index pages a tall ribbon with white on both sides — and it is why several of
   them ran to twenty thousand pixels and more.

   minmax(min(X, 100%), 1fr), NEVER minmax(X, 1fr): a grid track's minimum is a hard floor, and
   a bare 21rem minimum makes every card 24px too wide on a 358px band, which pushes the whole
   document sideways. */
.v2-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--vox-card), 100%), 1fr));
  gap: var(--vox-3);
  align-items: start;
}
/* A DETAILED CARD NEEDS A WIDER TRACK THAN AN INDEX CARD, AND ONE FIGURE FOR BOTH IS WORSE THAN
   ONE PER ROW. The condition, rare-disease and trial pages list FULL trial cards — chips, a
   registry title, a key-and-value block and two buttons. At the index-card minimum they fell
   into four 323px columns and each card rendered 1,154px tall, so the trial list came out
   7,621px: taller than the single-column list it replaced. Measured, on this page. */
.v2-layout .v2-cards { --vox-card: 26rem; }

/* THE CARD IS ITS OWN LAYOUT CONTEXT. A key-and-value row keyed off the VIEWPORT width is the
   trap underneath the figures above: v2 turns the rows two-column above a 720px viewport, which
   put an 11rem label column inside a 323px card and left 147px for the value. A container query
   asks the only question that matters — how wide is this card — and where it is unsupported the
   rows simply stay stacked, which is the readable arm. */
.v2-card { container-type: inline-size; }
.v2-card__row { grid-template-columns: minmax(0, 1fr); }
@container (min-width: 26rem) {
  .v2-card__row { grid-template-columns: 10rem minmax(0, 1fr); gap: var(--vox-3); }
}

.v2-card__label { font-size: var(--vox-t-h3); margin-bottom: var(--vox-1); }
.v2-card__ids, .v2-card__key { font-size: var(--vox-t-label); color: var(--vox-muted); }
.v2-card__chips { gap: var(--vox-1); margin-bottom: var(--vox-2); }
.v2-card__links .v2-btn { font-size: var(--vox-t-label); padding: var(--vox-2) var(--vox-3); }

/* ═══ CHIPS, TILES AND SMALL LABELS ════════════════════════════════════════════════════════ */
.v2-chip {
  font-size: var(--vox-t-label);
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: var(--vox-1) var(--vox-3);
  border-radius: var(--vox-radius-pill);
}
.v2-tiles {
  grid-template-columns: repeat(auto-fill, minmax(min(9rem, 100%), 1fr));
  gap: var(--vox-2);
}
/* A grid item will not shrink below its widest child unless it is told it may, and a long
   tile label pushed the rare-disease hub 24px sideways at 768px and 19px at 500px. */
.v2-tile { min-width: 0; padding: var(--vox-2) var(--vox-3); }
.v2-tile__code { font-size: 1rem; font-weight: 600; overflow-wrap: anywhere; }
.v2-tile__count, .v2-tile__label { font-size: var(--vox-t-label); overflow-wrap: anywhere; }

/* ═══ THE TWO-COLUMN PAGE ══════════════════════════════════════════════════════════════════ */
.v2-layout { gap: var(--vox-6); margin: var(--vox-4) auto var(--vox-7); align-items: start; }
@media (min-width: 1000px) {
  .v2-layout { grid-template-columns: minmax(0, 1fr) minmax(0, var(--vox-rail)); }
  .v2-layout--reverse { grid-template-columns: minmax(0, var(--vox-rail)) minmax(0, 1fr); }
}
.v2-side { gap: var(--vox-4); position: sticky; top: var(--vox-4); }
@media (max-width: 999px) { .v2-side { position: static; } }
.v2-side a { padding: var(--vox-2) 0; min-height: 44px; display: flex; align-items: center; }
.v2-side .v2-panel { padding: var(--vox-4); }

/* ═══ SOURCES AND FOOTNOTES ════════════════════════════════════════════════════════════════ */
.v2-sources { font-size: var(--vox-t-label); color: var(--vox-muted); }
.v2-sources li { margin-bottom: var(--vox-1); }

/* ═══ LEGACY PAGE HEROES ═══════════════════════════════════════════════════════════════════
   The pages that were never rebuilt open with their own navy hero band. It keeps the fill —
   it is a masthead continuation, not a mid-page wall — and loses the outsized padding. */
.page-hero { padding: var(--vox-7) 0 var(--vox-6); }
.page-hero .container { width: var(--vox-band); max-width: none; margin-inline: auto; }
.page-hero h1 { font-weight: 600; margin-bottom: var(--vox-3); max-width: 22em; }
.page-hero p { font-size: 1rem; max-width: var(--vox-measure); }
.content-page { padding-top: var(--vox-6); }

/* ═══ THE CAPTION FLOOR ════════════════════════════════════════════════════════════════════
   Nothing on this site renders below 13px. Every selector named here was MEASURED below that
   floor on a real rendered page, at between 11.2px and 12.8px; the list is what the measurement
   returned, not a guess at what might be small. A caption is still a caption — it stays smaller
   than the body text and it is a label, a unit or a note, never a sentence somebody has to read
   to use the page. */
.vox-caption-floor,
.tga-attribution, .vox-stamp, .vox-stamp strong,
.condition-stat-label, .creq__label, .creq__consent,
.today-filters__note, .today-tag, .today-stat__label, .today-stat__delta,
.today-row__rank, .today-row__ctx, .today-arch-row__date,
.tdsignup__label, .tdsignup__consent, .tdsignup--compact .tdsignup__consent,
.tdsignup--compact .tdsignup__msg,
.shortage-recent__product, .shortage-recent__date, .shortage-recent__ago,
.shortage-pill, .shortage-row-meta, .shortage-attrib,
.filter-label, .chip, .breadcrumb, .breadcrumb a, .breadcrumb span,
.acc-digest-fine, .trial-nct, .trial-au-badge, .status-badge,
.footer-legal, .footer-bottom, .footer-bottom span,
.shortage-facts dt, .today-caption,
.today-crumb, .today-crumb a, .today-crumb span,
.today-filters label, .today-filters label span {
  font-size: var(--vox-t-caption);
}

/* ═══ TAP TARGETS ══════════════════════════════════════════════════════════════════════════
   44px in both directions on every control that was measured under it. The inline-link
   exception in WCAG 2.5.8 covers a link inside a sentence and is not claimed here for anything
   that is a row, a chip or an icon. */
.chip, .shortage-alpha__link, .today-arch-row__date, .trial-page-back,
.shortage-recent__name, .card-follow-star, .cond-bar-btn,
.cond-related-card, .mobile-sub-bar__login,
.btn-primary, .btn-secondary, .btn-sm, .creq__btn,
.creq__input, input[type="text"], input[type="search"], input[type="email"],
.v2-filters select, select, summary, .today-tipdetails > summary,
.site-footer a, .footer-social,
.cookie-btn, .tsw__close, .today-row__name, .today-crumb a,
.error-actions a {
  min-height: 44px;
}
.footer-social, .cookie-btn, .tsw__close, .today-row__name, .today-crumb a,
.error-actions a {
  display: inline-flex; align-items: center; justify-content: center; min-width: 44px;
}
.today-row__name { justify-content: flex-start; min-width: 0; }
/* The legacy stylesheet sets this one to a 24px minimum through a two-class selector, which
   out-specifies the rule above. Matched exactly rather than reached for with !important. */
.footer-nav a.footer-social { min-height: 44px; min-width: 44px; justify-content: center; }
.chip { display: inline-flex; align-items: center; padding: var(--vox-2) var(--vox-4); border-radius: var(--vox-radius-pill); }
.shortage-alpha__link { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; }
.today-arch-row__date, .trial-page-back, .shortage-recent__name,
.mobile-sub-bar__login, .btn-primary, .btn-secondary, .creq__btn {
  display: inline-flex; align-items: center;
}
.mobile-sub-bar__login, .btn-primary, .btn-secondary, .creq__btn { justify-content: center; min-width: 44px; }
.cond-related-card { display: block; padding-block: var(--vox-2); }
.card-follow-star { min-width: 44px; }
/* A <summary> GETS ITS HEIGHT FROM PADDING, NOT FROM `display: flex`. Flex removes the
   disclosure marker, and a disclosure with no affordance is a heading in bold that happens to
   open — which is what a global flex rule here did to the phase explainer on the trial finder.
   The v2 layer sets flex on its own panel summaries and those keep their existing treatment. */
summary { padding-block: var(--vox-2); cursor: pointer; }
select, input[type="text"], input[type="search"], input[type="email"] { padding-block: var(--vox-2); }

/* ═══ THE RECENT-SHORTAGE ROW ON A PHONE ═══════════════════════════════════════════════════
   The row is a flex pair: the medicine on the left, the date on the right with `nowrap`. On a
   390px screen the date column took 150px of it and the medicine name was left wrapping one
   word to a line. Below 640px the two stack and each gets the full width. */
@media (max-width: 640px) {
  .shortage-recent__row { flex-wrap: wrap; }
  .shortage-recent__main { flex: 1 1 100%; min-width: 0; }
  /* THE TWO DATE PARTS WRAP AS WELL, AND THAT LAST PART IS NOT COSMETIC. Both carry
     `white-space: nowrap` — the exact TGA date must not break mid-phrase — and side by side
     they are 259px, which overran a 320px screen by 18px once a scrollbar was on it. They wrap
     as a pair instead; neither phrase is ever broken. */
  .shortage-recent__when {
    flex: 1 1 100%; text-align: left;
    display: flex; flex-wrap: wrap; gap: 0 var(--vox-3); align-items: baseline;
  }
}
/* A long generic name is one unbroken token — a medicine name routinely is — and an unbroken
   token in a fixed column is clipped rather than wrapped. Every place a medicine name is
   rendered is told it may break inside a word as a last resort. */
.shortage-recent__name, .shortage-row-name, .shortage-headline-label,
.shortage-record-title, .shortage-med-name,
.page-hero h1, .content-page h1, h1, .v2-card__label {
  overflow-wrap: anywhere;
  word-break: normal;
  hyphens: auto;
}

/* ═══ THE FLOATING EMAIL BUTTON ════════════════════════════════════════════════════════════
   It is fixed to the bottom right corner, so at the foot of a page it sat on top of the last
   archive rows and there was no scroll left to clear it. The page reserves its height, the same
   way the site already reserves the two other fixed bars. The reservation is on the page
   wrapper rather than on `body`, so the footer still reaches the bottom of the screen. */
body:has(.tsw:not([hidden])) main { padding-bottom: 76px; }
@media (max-width: 640px) { body:has(.tsw:not([hidden])) main { padding-bottom: 96px; } }

/* ═══ DENSITY ══════════════════════════════════════════════════════════════════════════════
   A clinical site is dense. Every figure below is a reduction from what shipped on
   20 September, and the vertical rhythm is one scale rather than one per component. */
.v2-panel > *:last-child { margin-bottom: 0; }
.v2-panel ul, .v2-panel ol { margin: 0 0 var(--vox-4); padding-left: 1.15rem; }
.v2-panel li { margin-bottom: var(--vox-1); }
.v2-trust { margin-bottom: var(--vox-4); }
details.v2-panel > summary { min-height: 44px; }

/* ON A PHONE THE PADDING IS THE PAGE. Panel and card padding that is comfortable inside a
   1,760px band is a third of the width of a 358px one, so it comes down a step — and the 44px
   targets, which are the reason a phone page is taller at all, stay exactly as they are. */
@media (max-width: 719px) {
  .v2-panel { padding: var(--vox-4); margin-bottom: var(--vox-4); }
  .v2-card  { padding: var(--vox-3); }
  .v2-card__row { padding-block: var(--vox-1); }
  .v2-trust { padding: var(--vox-2) var(--vox-3); }
  .v2-stat { padding: var(--vox-2) var(--vox-3); }
  .v2-layout { gap: var(--vox-5); margin-bottom: var(--vox-6); }
  h1 { margin-bottom: var(--vox-2); }
}
dl { margin: 0 0 var(--vox-4); }
dt { font-weight: 600; }
dd { margin: 0 0 var(--vox-2) 0; }

/* ═══ PRINT ════════════════════════════════════════════════════════════════════════════════
   The band is a screen rule. On paper the page is the sheet. */
@media print {
  :root { --vox-gutter: 0px; }
  /* THE v2 LAYER ALREADY SETS A WHITE PRINT PAGE AND THIS FILE OVERRODE IT WITHOUT MEANING TO.
     Its rule is inside a print block but earlier in the cascade, and the warm page background
     set at the top of this file is an unconditional rule of equal specificity that comes after
     it, so it won even on paper. Restated here rather than removed there. */
  body { background: #FFFFFF; color: #000000; }
  .v2-wrap, .v2-layout, .header-inner, .page-hero .container,
  main, main > .container, .content-page > .container { width: auto; padding-inline: 0; }
  .page-hero,
  .v2-panel--navy:has(h1) { margin-inline: 0; background: #FFFFFF; color: #000000; padding: 0; }
  .v2-panel--navy:has(h1) > h1, .page-hero h1, .page-hero p { color: #000000; }
  /* THE MEASURE IS A SCREEN RULE. On paper the sheet is the measure, and a 34em column down
     the left of an A4 page wastes a third of every sheet — and the referral letter is the one
     page on this site people actually print. */
  main p, main dd, main blockquote, main li, .v2-sources { max-width: none; }
  body:has(.tsw:not([hidden])) main { padding-bottom: 0; }
}

/* ═══ REDUCED MOTION ═══════════════════════════════════════════════════════════════════════
   The v2 layer already zeroes animation and transition under the preference. This restates it
   for the transform-based hovers the legacy stylesheet sets on cards, which are a transform
   rather than an animation and so survive a naive reset. */
@media (prefers-reduced-motion: reduce) {
  .trial-card:hover, .acc-card:hover, .v2-card:hover { transform: none; }
  html { scroll-behavior: auto; }
}
