/* ===========================================================================
   /emergency — Nepal emergency helplines
   Page: src/pages/emergency.astro · Data: src/data/emergency-contacts.js
   ===========================================================================

   Every colour here resolves through a semantic `--ice-color-*` token, so both
   themes are covered by the contract in docs/04 §5 rather than by a second set
   of values maintained here. The memorial band on the homepage is the site's
   one documented literal-colour exception; this page is not, and must not
   become one.

   Every selector is prefixed `.emg-` and every element rule is scoped under
   `.page-emergency`, per the AGENTS.md rule about broad selectors leaking into
   shared chrome.

   ⚠️ SINCE 2026-09-04 THIS SHEET IS THE FOURTH OF FOUR. The page renders the
   college profile's components, so `ice-feed.css` (the post, the tab row),
   `ice-glass.css` (the mesh) and `ice-college-profile.css` (the profile card,
   the rail) load ahead of it and own everything that is not `.emg-`. This file
   loads last and only adapts the directory to living inside a post. Do not
   restate a value any of those three already sets.

   TAP TARGETS. This page is read one-handed, on a phone, by someone who is
   frightened. Every phone link is a real target: the four lifeline cards are
   96px+ tall, and no inline `.emg-num` is below the 48px control minimum.
   =========================================================================== */

/* Every Nepali string on this page — the lifeline labels, the desk names, the
   province names — is set in the same local Devanagari stack the homepage
   memorial and ice-tools.css use. Without this they inherit the Apple UI stack,
   which carries no Devanagari at all, so each reader got whatever their OS
   happened to substitute and the four emergency cards rendered in a different
   face on every phone. No @font-face and no download: PRODUCT.md forbids
   self-hosted faces. */
.page-emergency {
  /* Promoted from a repeated literal on 2026-08-28. Two surfaces now set
     Devanagari (this page and the homepage memorial), which is the point at
     which a value stops being local and starts being a token. */
  --emg-devanagari: "Noto Sans Devanagari", "Nirmala UI", Mangal, sans-serif;

  /* The paper lift under an authored diagram. The eleven charts carry their own
     white ground inside the SVG so graphite dark mode cannot eat them, which is
     right, but a 16.5:1 white slab sitting flush on a #1E1F22 page reads as a
     hole punched in the page rather than as a document laid on it. b4703c8
     solved the same problem on /exam-access with a mat, a hairline and a real
     offset shadow. Named here rather than written inline because it takes two
     values, one per theme, and the file's own rule is that a value used twice
     stops being a literal. */
  --emg-diagram-lift: var(--ice-shadow-surface);
}

[data-theme="dark"] .page-emergency {
  --emg-diagram-lift: 0 1px 0 rgba(0, 0, 0, .55), 0 10px 28px rgba(0, 0, 0, .5);
}

/* ── THE GRID FLOOR, ADDED 2026-09-01 ─────────────────────────────────────
   Every list on this page is a grid with no explicit column below its first
   breakpoint, so the implicit `auto` track sizes to the widest item's
   min-content. `karnalispo_spokesperson@nepalpolice.gov.np` has no break
   opportunity, which forced all seven province cards to 395px inside a 320px
   column at 360px wide. `main { overflow-x: clip }` then swallowed the excess,
   so `document.scrollWidth` stayed at 360 and every overflow check on this site
   passed while 55px of every card sat off-screen: the seat line, the district
   list and the source link were all cut mid-word.

   `minmax(0, 1fr)` is the one-line floor. It is declared for all five grids and
   not just the province one, because the other four are the same construction
   and are one long string away from the same defect. The email also gets a
   break opportunity below, since a card that has to hyphenate an address is
   still better than a card that hides it. */
.page-emergency .emg-provinces,
.page-emergency .emg-desks,
.page-emergency .emg-valley,
.page-emergency .emg-roads,
.page-emergency .emg-checklist,
.page-emergency .emg-account {
  grid-template-columns: minmax(0, 1fr);
}
/* `.emg-lifeline` and `.emg-toll` are not in that list because both declare an
   explicit two-column track in their own base rule, at every width. */

.page-emergency [lang="ne"] {
  /* `!important` was added because `body.page-course main :is(p,li,dd)` pinned
     font-family with !important and `.emg-desk__np` is a `<p>`. This page left
     `page-course` on 2026-09-04 and the rule that forced it is gone, but it is
     kept: `.post__body p` and any future post rule are both more specific than
     an attribute selector, and this is the one declaration on the page that
     decides whether Devanagari renders at all. Inside the docs/04 §1 contract:
     it is a script the Apple UI stack cannot set. */
  font-family: var(--emg-devanagari) !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   THE SHELL — the profile feed, 2026-09-04

   This page ran on `.article-layout` / `.article-body`, the /privacy furniture,
   until the owner asked for the college profile's UI. It now renders the same
   three components `/colleges/[slug]` does — the `.pf` profile card, a `.pfeed`
   grid of `.post` cards and a sticky `.prail` — out of `ice-feed.css`,
   `ice-glass.css` and `ice-college-profile.css`. Those sheets own all of that;
   what is left here is the shell they sit in, plus the adaptations the `.emg-*`
   directory needs to live inside a post.

   ⚠️ `.col` is NOT loaded. `ice-colleges.css` is 578 lines of record-layout
   furniture and this page uses six declarations of it, so the shell is
   restated here instead. `col--profile` still goes on `<main>`, because that is
   the class `ice-college-profile.css` hangs every `--pf-*` token off and
   `.pf__card { border: var(--pf-line) }` paints nothing without it.

   ── WIDTH: PROSE READS, DIRECTORIES FILL ─────────────────────────────────

   The original defect and its fix both survive the move. Body measure stays at
   65–75ch or the prose becomes unreadable, and the directory grids break out of
   it — `ice-feed.css` already caps `.post__body p` at 68ch and its headings at
   34–38ch, so the prose half now needs no rule here at all and only the grids
   below carry one. */

.emg-page {
  max-width: 1240px;
  margin: 0 auto;
  padding: 18px var(--gutter) 72px;
}

/* `min-width: 0` on the feed column. Without it the widest post's intrinsic
   width — an authored diagram holds 960px inside its own scroll frame — pushes
   the grid track past the viewport, and the excess is swallowed rather than
   scrolled. Same reasoning as the grid floor below, one level up. */
.emg-page .emg-feed { min-width: 0; }

.emg-crumb { margin: 0 0 var(--ice-space-4); }

.emg-crumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
}

/* The separator is a CSS marker rather than a character in the markup. Written
   between two anchors it welds itself to the next link when JSX collapses the
   newline after it, which is how the answer library shipped "Answers ·Fees" on
   59 pages, and a screen reader reads it out as punctuation. */
.emg-crumb li + li::before {
  content: "·";
  margin-right: 10px;
  color: var(--ice-color-text-muted);
}

.emg-crumb a,
.emg-crumb span { color: var(--ice-color-text-muted); text-decoration: none; }
.emg-crumb a:hover { color: var(--ice-color-text); text-decoration: underline; }

/* ── the profile card's two page-specific parts ───────────────────────────── */

/* ══ THE AVATAR ═══════════════════════════════════════════════════════════
   ⚠️ TWO SEPARATE DEFECTS LIVED HERE, and the first one is not this page's.

   1. **THE CUTOUT WAS A STACKING BUG.** `.pf__cover` is `position: relative` in
      `ice-college-profile.css` and `.pf__avatar` is not positioned at all, so
      the cover PAINTS OVER the top of an avatar that is pulled up underneath it
      by a -78px margin. It is a latent bug in the shared component and
      `/emergency` is the first page anywhere to hit it, because no college in
      the record has a cover photograph yet — the component's own header says
      so. Fixed page-scoped below; the same one line is owed to
      `ice-college-profile.css` the day a college gets a hero.

   2. **NAVY ON NAVY.** `/img/ice-crest.png` is a NAVY seal with navy rim text
      on a TRANSPARENT ground, and it was being painted on
      `--ice-color-surface-brand`, which is navy in both themes. Only the red
      quarters of the shield survived. Moot now — see below — but the same
      mistake is still in `.post__avatar--crest` in `ice-feed.css` at 44px,
      where the college pages and the answer library carry it.

   ── AND THE CREST IS GONE FROM THIS PAGE ──────────────────────────────────

   Owner, 2026-09-04: "dont put our college logo in everything make it something
   relecant". The profile is "Emergency help in Nepal" and what it does is hand
   a reader a number to call, so the mark is a handset — the same `phone` glyph
   `src/components/profile/icons.js` gives the National desks row, on the
   crimson of the Call 100 button.

   Attribution does not depend on the mark and is not lost: the handle line
   underneath reads "icenepal.com · Imperial College of Engineering ·
   Bhaktapur", the tick links to the freshness stamp, and the site chrome above
   carries the crest.

   ⚠️ A data URI, not a file. It is one 24px glyph used at two sizes and an
   asset would be a fourth network request for 300 bytes of path data. It is
   CSS in an external sheet, so `script-src 'self'` is not involved. */

/* ⚠️ The `position: relative; z-index: 1` that used to sit here is GONE, and
   that is not a regression. It was a page-scoped patch for a bug in the shared
   component; on 2026-09-04 the one line moved to `.pf__avatar` in
   `ice-college-profile.css` itself, where it also fixes the 38 college pages
   that carry a cover photograph. Do not re-add it here. */

.page-emergency {
  --emg-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 3.8h4l1.4 4-2.2 1.6a11 11 0 0 0 4.4 4.4L16.2 12l4 1.4v4a2 2 0 0 1-2.2 2C10.6 18.8 5.2 13.4 4.8 6a2 2 0 0 1 2.2-2.2Z'/%3E%3C/svg%3E");
  --emg-mark-fill: linear-gradient(180deg, #E8526A, var(--ice-color-crimson));
}

/* A circle, because a profile avatar is a circle. */
.page-emergency .pf__avatar--mark {
  border-radius: 50%;
  background: var(--emg-mark) center / 44% no-repeat, var(--emg-mark-fill);
  box-shadow:
    0 0 0 7px var(--ice-color-surface),
    0 16px 30px -14px rgb(196 30 58 / 55%),
    inset 0 2px 3px rgb(255 255 255 / 35%);
}

/* The 38–44px one in a post header keeps the squircle, so it matches the
   `.fold__thumb` tiles it sits in a column with rather than the profile avatar
   it sits far above. Keyed off the id because `FeedPost` takes no class prop,
   and `#numbers` is the only post on the page that still renders an author row
   — the closing note passes `head={false}`. */
.page-emergency #numbers .post__avatar {
  background: var(--emg-mark) center / 46% no-repeat, var(--emg-mark-fill);
  box-shadow:
    0 10px 18px -10px rgb(196 30 58 / 55%),
    inset 0 2px 3px rgb(255 255 255 / 35%);
}

/* Share is a real `<button>`, because copying a link is a page action and not a
   navigation. A button does not inherit the page font, so it is given one here
   rather than relying on `.pf__btn`, which was written for anchors. */
.page-emergency button.pf__btn {
  font-family: inherit;
  font-size: 15px;
  cursor: pointer;
}

/* ⚠️ The pills need a RIGHT bound. `ice-college-profile.css` positions them
   `top:14px; left:14px` with no right edge, which is fine for the two a college
   carries and is not for the three here: at 375px the second row ran off the
   cover and "NO SIGN-IN" sat outside the card. An absolutely positioned flex
   container has no width to wrap against until it is given one. */
.page-emergency .pf__pills { right: 14px; }

/* The tick is inside the `<h1>` on this page, so it flows after the last word
   instead of being a flex item beside a block-level heading. As a sibling it
   sat alone under the name at 375px, and then alone at the far right of the
   first line — a stray dark disc either way. `inline-grid` keeps the glyph
   centred; the em-relative size keeps it in proportion as the H1 clamps. */
.page-emergency .pf__nameline { display: block; }

.page-emergency .pf__name .pf__tick {
  display: inline-grid;
  place-items: center;
  width: .62em;
  height: .62em;
  margin-left: .22em;
  vertical-align: baseline;
  translate: 0 .04em;
}

.page-emergency .pf__name .pf__tick svg { width: 55%; height: 55%; }

/* The header's freshness line carries THREE dates and a licence credit, so it
   wraps on a phone and must stay legible when it does. */
.page-emergency .pf__reg a { color: var(--ice-color-text-action); }

.page-emergency .emg-standfirst {
  font-size: var(--ice-type-lede-size);
  line-height: var(--ice-type-lede-line);
  color: var(--ice-color-text);
  margin: 0 0 4px;
}

/* ── The four ──────────────────────────────────────────────────────────── */

.page-emergency .emg-lifeline {
  list-style: none;
  margin: 24px 0 32px;
  padding: 0;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* ⚠️ A CONTAINER query, not a viewport one, and every grid on this page moved
   the same way on 2026-09-04. These lists now sit inside `.post__body`, which
   declares `container-type: inline-size`, and the post column is between a
   0px and a 320px rail depending on the width — so at a 1400px viewport the
   column is ~850px and a viewport breakpoint of 900px would never fire on a
   list that has ample room. What decides a grid's column count is the width of
   the post, which is what these measure. */
@container (min-width: 620px) {
  .page-emergency .emg-lifeline { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
}

/* THE FOUR BUTTONS MUST BE THE SAME HEIGHT. They were not: at 360px they
   measured 104, 112, 104 and 129px, because "AMBULANCE एम्बुलेन्स" wraps to two
   lines and "TRAFFIC POLICE ट्राफिक" to three while "POLICE प्रहरी" fits on one.
   Two primary emergency buttons of visibly different heights sitting in the
   same row is the first thing a frightened reader sees on this page.

   Subgrid rather than a min-height guess: the item spans the list's two implicit
   row tracks, so the LINK stretches to the tallest link in its row and the
   detail paragraphs start on a shared line, whatever the label does. A fixed
   min-height would have to be tall enough for three lines and would then leave
   dead space in the one-line cards at every other width. */
.page-emergency .emg-lifeline__item {
  margin: 0;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 2;
}

.page-emergency .emg-lifeline__link {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  min-height: 104px;
  padding: 16px;
  border-radius: 8px;
  background: var(--ice-color-action);
  color: var(--ice-color-on-action);
  text-decoration: none;
}

.page-emergency .emg-lifeline__link:hover { background: var(--ice-color-action-hover); }

.page-emergency .emg-lifeline__link:focus-visible {
  outline: 3px solid var(--ice-color-text);
  outline-offset: 3px;
}

.page-emergency .emg-lifeline__number {
  font-size: clamp(2.25rem, 1.9rem + 1.6vw, 3rem);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.page-emergency .emg-lifeline__label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  font-size: var(--ice-type-button-size);
  line-height: var(--ice-type-button-line);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.page-emergency .emg-lifeline__np {
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  opacity: .85;
}

/* No top margin: the list's own row-gap now does that spacing, because the item
   is a subgrid and the detail sits in the second track. */
.page-emergency .emg-lifeline__detail {
  margin: 0 2px;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

/* ── Toll figures ──────────────────────────────────────────────────────── */

.page-emergency .emg-toll {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* No bottom margin and no bottom radius: `.emg-asof` is welded to the underside
     of this grid, because the hour is what makes these four numbers honest. */
  margin: 24px 0 0;
  padding: 0;
  background: var(--ice-color-border);
  border: 1px solid var(--ice-color-border);
  border-radius: 8px 8px 0 0;
  overflow: hidden;
}

@container (min-width: 560px) {
  .page-emergency .emg-toll { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* The toll is four figures. Left to fill 850px they drift apart into four
   unrelated numbers, so it keeps a measure of its own, and `.emg-asof` — which
   is welded to its underside — keeps the same one. */
@container (min-width: 820px) {
  .page-emergency .emg-toll,
  .page-emergency .emg-asof { max-width: 780px; }
}

.page-emergency .emg-toll__cell {
  background: var(--ice-color-surface);
  padding: 16px 12px;
  text-align: center;
  /* "Confirmed dead" wrapped while "Injured" did not, which pushed its figure
     a line lower than the other three. The labels now share a fixed block so
     all four numbers sit on one baseline whatever the label length. */
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.page-emergency .emg-toll__cell dt {
  min-height: 2.8em;
  font-size: var(--ice-type-label-size);
  line-height: var(--ice-type-label-line);
  font-weight: var(--ice-type-label-weight);
  letter-spacing: var(--ice-type-label-track);
  text-transform: uppercase;
  color: var(--ice-color-text-muted);
  margin: 0 0 6px;
}

.page-emergency .emg-toll__cell dd {
  margin: 0;
  font-size: var(--ice-type-stat-size);
  line-height: var(--ice-type-stat-line);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ice-color-text);
}

/* The missing are the number this page exists for. */
.page-emergency .emg-toll__cell--accent dd { color: var(--ice-color-text-action); }

/* THE HOUR IS NOT A FOOTNOTE. This line was 13px muted grey under a grid of
   bold stat numbers, which is the wrong way round: the numbers above are only
   honest because of the stamp below them, and this file's own header records
   that these exact figures were 4.5x wrong for three days while nobody looked
   at the date. It now sits at body size in body ink, attached to the grid it
   qualifies rather than floating under it. */
.page-emergency .emg-asof {
  font-size: var(--ice-type-body-size);
  line-height: var(--ice-type-body-line);
  color: var(--ice-color-text);
  margin: 0 0 24px;
  padding: 10px 12px;
  border: 1px solid var(--ice-color-border);
  border-top: 0;
  border-radius: 0 0 8px 8px;
  background: var(--ice-color-surface-muted);
}

/* Added by public/js/emergency-freshness.js when the figures are a day or more
   old. Absent, and correctly so, on the day they were checked. */
.page-emergency .emg-asof__age {
  display: block;
  margin-top: 4px;
  font-weight: 700;
  color: var(--ice-color-text-action);
}

/* ── Figures ───────────────────────────────────────────────────────────────
   The satellite frames, the two charts and the tunnel section. Rendered by
   src/components/FloodFigure.astro from `floodFigures` in flood-2026.js.

   WIDER THAN THE PROSE, ON PURPOSE. The prose column is capped at the reading
   measure, which is right for sentences and wrong for a map carrying eight
   district labels and a river gauge trace. These sit at 960px, which is the
   `sizes` value the component hands the browser — change one and change the
   other, or the browser picks a candidate it does not use and the page pays
   for the image twice.

   Every image ships with `width`/`height`, so the caption cannot jump under a
   reader mid-sentence while the file decodes. That matters more here than
   anywhere else on the site: this page is read on a phone, on a bad
   connection, by someone who is frightened.

   The white ground is in the SVG files themselves rather than here, so the
   charts survive graphite dark mode without a theme rule. The raster frames
   are satellite imagery and are dark-ish in both themes already.

   ── THE LEGIBLE FLOOR, ADDED 2026-09-01 ────────────────────────────────────
   A photograph shrinks. A 1200px chart does not. The eleven authored diagrams
   are drawn with 14 to 15px type, and a phone gives the figure about 320 CSS px,
   a scale of 0.267, so that type landed at 3.7px. That is the same defect and
   almost the same number as /exam-access before b4703c8 (14px landing at 3.9px),
   and it means the part of this page a news desk could not have made was
   decoration on the device the page is actually read on.

   Below the width at which the figure would render under 960px, a diagram now
   HOLDS 960 inside a scroll frame instead of shrinking into it. At 960 the
   smallest type lands at 11.2px, which is the floor b4703c8 settled on. The
   photographs are untouched: they scale honestly and always did. */

.page-emergency .emg-figure {
  margin: 28px 0 32px;
  max-width: 960px;
}

/* A press photograph narrower than the column natively. Stretching one past its
   own pixels to fill 960px is how a page starts looking cheap, so the two
   portrait Army frames are capped here instead. FloodFigure.astro adds this
   class below 960 and puts the SAME number in `sizes`; move one and move both. */
.page-emergency .emg-figure--narrow { max-width: 720px; }

.page-emergency .emg-figure__img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--ice-color-border);
  border-radius: 8px;
  background: var(--ice-color-surface);
}

.page-emergency .emg-figure__cap {
  display: block;
  margin-top: 10px;
  max-width: var(--ice-measure-prose-wide);
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

.page-emergency .emg-figure__caption {
  display: block;
  color: var(--ice-color-text);
}

/* The line that stops a figure being read as something it is not: the ERCC
   map's own toll is four days old, and the Gyirong frame is the Chinese bank.
   Both need saying next to the picture, not three paragraphs away. */
.page-emergency .emg-figure__note {
  display: block;
  margin-top: 4px;
}

.page-emergency .emg-figure__credit {
  display: block;
  margin-top: 4px;
  font-style: normal;
}

.page-emergency .emg-figure__credit a { color: var(--ice-color-text-action); }

/* ── Authored diagrams: the scroll frame, the mat, and the prose version ──── */

/* The frame is the window; the drawing inside it keeps its own size. Border and
   radius move off the image and onto this element so a diagram that is wider
   than its frame reads as a document you can slide, not as a picture that has
   been cut off. */
.page-emergency .emg-figure--diagram .emg-figure__frame {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  border: 1px solid var(--ice-color-border);
  border-radius: 8px;
  box-shadow: var(--emg-diagram-lift);
}

.page-emergency .emg-figure--diagram .emg-figure__img {
  /* `width: 100%` still applies from the base rule, so at the cap the drawing
     fills the frame exactly and nothing scrolls. Below it, `min-width` is what
     stops the chart shrinking past the point where its labels mean anything.
     960 is the same number `emg-figure`, FloodFigure's `sizes` and the desktop
     cap all use; move one and move all of them.

     The 2px is the frame's own two hairlines, which sit outside its content box.
     Without subtracting them the drawing overflows the frame by two pixels at the
     desktop cap, and the frame reports itself scrollable with nothing to scroll. */
  min-width: calc(960px - 2px);
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* The hint only exists while the frame actually scrolls. 1080px is the
   breakpoint the rest of this file already turns the wide layout on at, and it
   is comfortably above the width where the column reaches 960. */
.page-emergency .emg-figure__scrollhint {
  display: block;
  margin-top: 4px;
}

.page-emergency .emg-figure__scrollhint a { color: var(--ice-color-text-action); }

@media (min-width: 1080px) {
  .page-emergency .emg-figure__scrollhint { display: none; }
}

/* The prose version of a chart. Closed by default, because a sighted reader on
   a desktop has the drawing; open to anyone who would rather read it, and
   present in the DOM for a screen reader and a text extractor either way. */
.page-emergency .emg-figure__desc {
  margin-top: 10px;
  max-width: var(--ice-measure-prose-wide);
  border: 1px solid var(--ice-color-border);
  border-radius: 6px;
  background: var(--ice-color-surface-muted);
  color: var(--ice-color-on-surface-muted);
}

.page-emergency .emg-figure__desc-summary {
  padding: 10px 14px;
  cursor: pointer;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--ice-color-text-action);
  /* A summary is a control. It gets the same 48px floor every other control on
     this page gets, and a visible focus ring. */
  min-height: 48px;
  display: flex;
  align-items: center;
}

.page-emergency .emg-figure__desc-summary:focus-visible {
  outline: 3px solid var(--ice-color-text-action);
  outline-offset: -3px;
  border-radius: 6px;
}

.page-emergency .emg-figure__desc-body {
  padding: 0 14px 12px;
}

.page-emergency .emg-figure__desc-body p {
  margin: 0 0 8px;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

.page-emergency .emg-figure__desc-body p:last-child { margin-bottom: 0; }

/* ── Checklist ─────────────────────────────────────────────────────────── */

.page-emergency .emg-checklist {
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
  display: grid;
  gap: 10px;
  /* Kept to the reading measure. Every other list on this page is a card grid
     that wants the room; this one is five sentences and reads worse at 820px. */
  max-width: var(--ice-measure-prose-wide);
}

.page-emergency .emg-checklist li {
  position: relative;
  padding: 12px 14px 12px 42px;
  border: 1px solid var(--ice-color-border);
  border-radius: 6px;
  background: var(--ice-color-surface-muted);
  color: var(--ice-color-on-surface-muted);
  font-size: var(--ice-type-body-size);
  line-height: var(--ice-type-body-line);
}

.page-emergency .emg-checklist li::before {
  content: '';
  position: absolute;
  left: 15px;
  top: 1.05em;
  width: 12px;
  height: 12px;
  border-radius: 2px;
  border: 2px solid var(--ice-color-accent);
}

/* ── Desk cards (national, specialist, relief points) ──────────────────── */

.page-emergency .emg-desks {
  list-style: none;
  margin: 20px 0 30px;
  padding: 0;
  display: grid;
  gap: 12px;
}

@container (min-width: 540px) {
  .page-emergency .emg-desks { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* `auto-fit` rather than a fixed count, so the five national desks and the
   three collection points reflow instead of leaving a stranded orphan at one
   specific width. */
@container (min-width: 900px) {
  .page-emergency .emg-desks { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
}

.page-emergency .emg-desk {
  margin: 0;
  padding: 18px;
  border: 1px solid var(--ice-color-border);
  border-radius: 8px;
  background: var(--ice-color-surface);
  color: var(--ice-color-on-surface);
}

/* The "Toll free" badge used to live INSIDE this <h3>, which put it in the
   heading's own text: a screen reader and the document outline both read
   "Health Emergency Operation CentreToll free". The badge is now a sibling and
   this wrapper does the layout the heading used to do. */
.page-emergency .emg-desk__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 2px;
}

.page-emergency .emg-desk__name {
  margin: 0;
  font-size: var(--ice-type-h4-size);
  line-height: var(--ice-type-h4-line);
  font-weight: var(--ice-type-h4-weight);
  letter-spacing: var(--ice-type-h4-track);
  color: var(--ice-color-text);
}

.page-emergency .emg-desk__free {
  flex: none;
  padding: 3px 8px;
  border-radius: 3px;
  background: var(--ice-color-accent);
  color: var(--ice-color-on-accent);
  font-size: 11px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.page-emergency .emg-desk__np {
  margin: 0 0 10px;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

/* The gap does the separating. There used to be a `·` between chips, emitted
   before every chip after the first, and when a row wrapped it was left dangling
   at the end of the previous line: visible on Sudurpashchim's three numbers at
   360px. A bordered chip on a filled ground does not need a separator to read as
   a separate thing, so the glyph went and the column gap grew to carry it. */
.page-emergency .emg-desk__numbers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin: 0 0 6px;
}

.page-emergency .emg-desk__also {
  margin: 0 0 6px;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
  /* A government mailbox can be 42 characters with no space in it, and one of
     them (karnalispo_spokesperson@nepalpolice.gov.np) was setting the width of
     the whole province grid. Same reasoning as `.emg-account dd`: an address
     that hyphenates is readable, an address pushed off the screen is not. */
  overflow-wrap: anywhere;
}

.page-emergency .emg-desk__also a { color: var(--ice-color-text-action); }

.page-emergency .emg-desk__detail {
  margin: 8px 0 0;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

/* The number itself. A control, not a run of text: 48px minimum, always. */
.page-emergency .emg-num {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 4px 12px;
  border-radius: 5px;
  background: var(--ice-color-surface-muted);
  border: 1px solid var(--ice-color-border);
  color: var(--ice-color-text-action);
  font-size: 1.0625rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
  text-decoration: none;
  white-space: nowrap;
  /* ⚠️ NO TRANSITION ON background OR border-color, and this is not a style
     preference. Both values come from a `--ice-color-*` custom property, and
     when the theme button flips `data-theme` on <html> the transition pins the
     chip at the OLD theme's value: measured stuck for seconds, until a scroll
     or a reload. Light to dark left all 44 numbers as #F79AAA on #F3EFE9, which
     is 1.8:1 and unreadable, on the one page whose controls are the point.
     `.emg-desk` sets the same two tokens with no transition and flips instantly,
     which is how this was isolated. Keep the feedback on `transform`, below. */
  transition: transform var(--dur-fast) var(--ease);
}

.page-emergency .emg-num:hover {
  background: var(--ice-color-surface-field);
  border-color: var(--ice-color-text-action);
}

.page-emergency .emg-num:focus-visible {
  outline: 3px solid var(--ice-color-text-action);
  outline-offset: 2px;
}

/* Alternate lines for the same desk. Quieter than the primary chip, still a
   real 48px target: on this page every callable number is something a person
   taps under stress, and a 20px inline link is not a control. Inline links
   inside running prose stay inline links — those are references to a number,
   not the button for it. */
.page-emergency .emg-desk__numbers--alt { margin-top: -2px; }

.page-emergency .emg-also-label {
  font-size: var(--ice-type-caption-size);
  color: var(--ice-color-text-muted);
  padding-right: 4px;
}

/* Quieter than the primary chip, but NOT greyed out. It was `--ice-color-text-muted`
   on a transparent ground, which next to the solid primary chip reads as a
   disabled control; these are live numbers that place a real call. It keeps the
   action colour and steps down on weight and ground instead. */
.page-emergency .emg-num--alt {
  font-size: .9375rem;
  font-weight: 600;
  background: transparent;
  color: var(--ice-color-text-action);
}

.page-emergency .emg-num--alt:hover {
  background: var(--ice-color-surface-muted);
  border-color: var(--ice-color-text-action);
}

/* ── Provinces ─────────────────────────────────────────────────────────── */

.page-emergency .emg-provinces {
  list-style: none;
  margin: 20px 0 30px;
  padding: 0;
  display: grid;
  gap: 12px;
}

@container (min-width: 540px) {
  .page-emergency .emg-provinces { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@container (min-width: 900px) {
  .page-emergency .emg-provinces { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
}

/* Same frame as .emg-desk, deliberately. An earlier revision gave these a 4px
   coloured left border, crimson on the two flood-affected provinces. It went:
   on five of the seven cards that stripe carried no information at all, and on
   the other two the meaning was already stated in words by the "Flood-affected"
   chip in the card header. A colour stripe needs a legend the reader does not
   have; a labelled chip does not. Do not reintroduce it. */
.page-emergency .emg-province {
  margin: 0;
  padding: 18px;
  border: 1px solid var(--ice-color-border);
  border-radius: 8px;
  background: var(--ice-color-surface);
  color: var(--ice-color-on-surface);
}

.page-emergency .emg-province__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 2px;
}

.page-emergency .emg-province__name {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin: 0;
  font-size: var(--ice-type-h4-size);
  line-height: var(--ice-type-h4-line);
  font-weight: var(--ice-type-h4-weight);
  letter-spacing: var(--ice-type-h4-track);
  color: var(--ice-color-text);
}

.page-emergency .emg-province__np {
  font-size: var(--ice-type-caption-size);
  font-weight: 400;
  color: var(--ice-color-text-muted);
}

.page-emergency .emg-province__flag {
  flex: none;
  padding: 3px 8px;
  border-radius: 3px;
  background: var(--ice-color-action);
  color: var(--ice-color-on-action);
  font-size: 11px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.page-emergency .emg-province__seat,
.page-emergency .emg-province__districts,
.page-emergency .emg-province__source {
  margin: 0 0 8px;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

.page-emergency .emg-province__seat { margin-bottom: 10px; }
.page-emergency .emg-province__districts { margin-top: 4px; }
.page-emergency .emg-province__source { margin-bottom: 0; }
.page-emergency .emg-province__source a { color: var(--ice-color-text-action); }

/* ── Valley strip ──────────────────────────────────────────────────────── */

.page-emergency .emg-valley {
  list-style: none;
  margin: 18px 0 30px;
  padding: 0;
  display: grid;
  gap: 8px;
}

.page-emergency .emg-valley__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--ice-color-border);
  border-radius: 6px;
  background: var(--ice-color-surface);
}

.page-emergency .emg-valley__name {
  font-size: var(--ice-type-body-size);
  font-weight: 600;
  color: var(--ice-color-text);
}

.page-emergency .emg-valley__nums {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}

/* ── Relief account ────────────────────────────────────────────────────── */

.page-emergency .emg-account {
  margin: 18px 0 26px;
  padding: 18px;
  border: 1px solid var(--ice-color-border);
  border-radius: 8px;
  background: var(--ice-color-surface-muted);
  color: var(--ice-color-on-surface-muted);
  display: grid;
  gap: 12px;
}

@container (min-width: 520px) {
  .page-emergency .emg-account { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.page-emergency .emg-account dt {
  margin: 0 0 4px;
  font-size: var(--ice-type-label-size);
  line-height: var(--ice-type-label-line);
  font-weight: var(--ice-type-label-weight);
  letter-spacing: var(--ice-type-label-track);
  text-transform: uppercase;
  color: var(--ice-color-text-muted);
}

.page-emergency .emg-account dd {
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.4;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ice-color-text);
  /* Account numbers are long and must never widen the page on a 320px screen. */
  overflow-wrap: anywhere;
}

/* ── Roads ─────────────────────────────────────────────────────────────── */

.page-emergency .emg-roads {
  list-style: none;
  margin: 20px 0 30px;
  padding: 0;
  display: grid;
  gap: 10px;
}

.page-emergency .emg-road {
  margin: 0;
  padding: 16px 18px;
  border: 1px solid var(--ice-color-border);
  border-radius: 8px;
  background: var(--ice-color-surface);
  color: var(--ice-color-on-surface);
}

.page-emergency .emg-road__name {
  margin: 0 0 4px;
  font-size: var(--ice-type-h4-size);
  line-height: var(--ice-type-h4-line);
  font-weight: var(--ice-type-h4-weight);
  letter-spacing: var(--ice-type-h4-track);
  color: var(--ice-color-text);
}

.page-emergency .emg-road__status {
  margin: 0 0 6px;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--ice-color-text-action);
}

.page-emergency .emg-road__detail {
  margin: 0;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

/* ── Close ─────────────────────────────────────────────────────────────── */

/* The closing post carries no author row, so `.post__body`'s zero top padding
   would put the condolence line hard against the card's own edge. */
.page-emergency #close .post__body { padding-top: 18px; }

/* No rule and no border of its own any more: it used to need one to separate
   itself from four thousand words of running article, and it is now the only
   thing in its own card. */
.page-emergency .emg-close {
  margin: 0;
  max-width: var(--ice-measure-prose-wide);
  color: var(--ice-color-text-muted);
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
}

/* The same condolence that heads the homepage memorial, closing this page.
   One line, in the language the family reading it grieves in. */
.page-emergency .emg-close__np {
  display: block;
  margin-bottom: 6px;
  color: var(--ice-color-text-accent);
  font-size: 1.0625rem;
  line-height: 1.5;
  font-weight: 600;
}

/* ── THE ADMISSION FURNITURE COMES OFF THIS PAGE ───────────────────────────
   `Footer.astro` pins `.sticky-cta` (71px: "Online admission", "Call the
   admissions office", "WhatsApp the admissions office") to the bottom of every
   route, and `.admission-dock` to the side. Once the reader scrolls, `.nav` and
   `.id-ribbon` also go fixed, so on a 360x640 phone 201px of a 640px screen was
   permanently college marketing while somebody looked for a missing relative.

   That is the thing this page's own header comment forbids: "no form, no lead
   capture, and the admission section is at the BOTTOM, after everything a person
   in trouble actually needs." `merit-announce.js` already suppresses the merit
   popup on this route for the same reason; the CTA bar had simply never been
   given the same treatment.

   Nothing is lost. The admission route is still on the page, in the `#students`
   section where the header says it belongs, and the college's own number now
   carries a real 48px chip there rather than relying on a 40px icon in a bar
   labelled for admissions. */
.page-emergency .sticky-cta,
.page-emergency .admission-dock {
  display: none;
}

/* ── Pressed state ─────────────────────────────────────────────────────────
   Declared for every control family on this page. A phone link that does not
   acknowledge the tap gets tapped twice, and on a page where a tap places a
   real call that is a defect rather than a nicety. Kept to a transform so it
   costs no repaint. */
.page-emergency .emg-lifeline__link:active,
.page-emergency .emg-num:active {
  transform: translateY(1px);
}

.page-emergency .emg-lifeline__link:active { background: var(--ice-color-action-hover); }
.page-emergency .emg-num:active { background: var(--ice-color-surface-field); }

@media (prefers-reduced-motion: reduce) {
  .page-emergency .emg-lifeline__link:active,
  .page-emergency .emg-num:active { transform: none; }
}

/* The last two grids take the room the post gives them. Container queries, for
   the reason stated at `.emg-lifeline` above. */
@container (min-width: 700px) {
  .page-emergency .emg-roads { grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }
}

@container (min-width: 620px) {
  .page-emergency .emg-valley { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE FOLD — every post opens and closes, at every width
   Added 2026-09-04. Owner: "we need to make the site like collapsable and it
   still looks too lengthly and also desktop version too make it collapsable so
   with little info and pic where they can open and see and quickly navigate."

   Closed, a post is one row: a picture, the title, a line saying what is inside,
   and a count. Fifteen of those plus the four numbers is about two phone
   screens, against the fifteen the same content ran to open.

   ⚠️ NOTHING HERE HIDES ANYTHING FROM A CRAWLER. Everything inside a closed
   `<details>` is in the DOM and in the HTML the crawler is served, which is why
   `audit:seo`'s grep for "Last checked" and `audit:onpage`'s heading count both
   still pass unchanged.

   ⚠️ THE FOUR SHORT CODES NEVER FOLD. That post is a plain `FeedPost` and has
   no summary. A person told by the standfirst to stop reading and call must not
   have to open a control first.
   ══════════════════════════════════════════════════════════════════════════ */

/* `.post` in ice-feed.css already carries the card, the border, the radius and
   the shadow, and it does not care whether the element is an `<article>` or a
   `<details>`. Nothing about the card is restated here.

   ── the bar above the feed ── */

.page-emergency .emg-foldbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px var(--ice-space-4);
  margin: 0 0 var(--ice-space-5);
  padding: 12px 16px;
  border: 1px solid var(--ice-color-border);
  border-radius: 18px;
  background: var(--ice-color-surface);
  box-shadow: var(--pf-lift-sm);
}

.page-emergency .emg-foldbar__note {
  margin: 0;
  min-width: 0;
  flex: 1 1 15rem;
  font-size: var(--ice-type-caption-size);
  line-height: var(--ice-type-caption-line);
  color: var(--ice-color-text-muted);
}

.page-emergency .emg-foldbar__btn {
  flex: none;
  min-height: 44px;
  padding: 10px 18px;
  border: 1px solid var(--ice-color-border);
  border-radius: 14px;
  background: var(--ice-color-surface-field);
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ice-color-text);
  cursor: pointer;
}

.page-emergency .emg-foldbar__btn:hover {
  background: color-mix(in srgb, var(--ice-color-text) 8%, var(--ice-color-surface-field));
}

.page-emergency .emg-foldbar__btn:focus-visible {
  outline: 3px solid var(--ice-color-text-action);
  outline-offset: 2px;
}

/* ── the summary row ── */

.page-emergency .fold {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  cursor: pointer;
  list-style: none;
}

/* Both are needed: `list-style: none` covers Chromium and Firefox, the
   pseudo-element covers Safari, which ignores the first. */
.page-emergency .fold::-webkit-details-marker { display: none; }

.page-emergency .fold:hover { background: var(--ice-color-surface-field); }

.page-emergency .fold:focus-visible {
  outline: 3px solid var(--ice-color-text-action);
  outline-offset: -3px;
  border-radius: inherit;
}

/* ── the picture ── */

.page-emergency .fold__thumb {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  flex: none;
  border-radius: 16px;
  overflow: hidden;
  background: var(--ice-color-surface-muted);
}

.page-emergency .fold__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* No photograph belongs to a directory section, and inventing one would be the
   first dishonest picture on this page. An icon tile says "section" instead. */
.page-emergency .fold__thumb--icon {
  background: linear-gradient(180deg, #4A5D8A, var(--ice-color-surface-brand));
  box-shadow: inset 0 2px 3px rgb(255 255 255 / 25%);
}

.page-emergency .fold__thumb--warm {
  background: linear-gradient(180deg, #F0A97A, var(--ice-color-terracotta));
  box-shadow: inset 0 2px 3px rgb(255 255 255 / 45%);
}

.page-emergency .fold__thumb--icon svg {
  width: 30px;
  height: 30px;
  fill: none;
  stroke: var(--ice-color-on-action);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── the text ── */

.page-emergency .fold__text { min-width: 0; display: grid; gap: 3px; }

.page-emergency .fold__title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.008em;
  line-height: 1.3;
  color: var(--ice-color-text);
  text-wrap: pretty;
}

.page-emergency .fold__kind {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--ice-color-text-muted);
  /* One line, always. A kind that wraps adds a whole row of height to one card
     and the scan the fold exists to give stops being a scan. The strings are
     written short enough not to truncate at 375px; this is the guard for the
     next one somebody adds. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.page-emergency .fold__teaser {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ice-color-text-muted);
  /* Two lines, so a long teaser cannot make one row twice the height of its
     neighbours and break the scan the fold exists to give. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Open, the row is the post header and the teaser has been replaced by the
   thing it was teasing. */
.page-emergency .post--fold[open] > .fold .fold__teaser { display: none; }

/* ── the caret ── */

.page-emergency .fold__chev {
  width: 10px;
  height: 10px;
  flex: none;
  margin-right: 4px;
  border-right: 2px solid var(--ice-color-text-muted);
  border-bottom: 2px solid var(--ice-color-text-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 180ms var(--pf-ease);
}

.page-emergency .post--fold[open] > .fold .fold__chev {
  transform: rotate(-135deg) translate(-2px, -2px);
}

@media (prefers-reduced-motion: reduce) {
  .page-emergency .fold__chev { transition: none; }
}

/* ── the body, once open ── */

.page-emergency .post--fold > .post__body { padding-top: 4px; }

/* ⚠️ Print gets everything open, and CSS CANNOT DO IT. A closed `<details>`
   hides its content through the UA's own mechanism — `content-visibility` on an
   internal slot, spelled `::details-content` in Chromium and something else
   everywhere else — so `display: block` on the body reveals nothing. The
   `beforeprint` handler in `public/js/emergency-fold.js` sets `open` on all of
   them instead, which works in every browser that can print. What is left here
   is the chrome that would be meaningless on paper. */
@media print {
  .page-emergency .fold__chev,
  .page-emergency .fold__teaser,
  .page-emergency .emg-foldbar { display: none; }
  .page-emergency .fold { padding-block: 8px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE PHONE — the Instagram rhythm, and the carousels
   Added 2026-09-04. Owner: "it doesn't look like post and also see how
   Instagram handled post and how clean it looks especially in mobile or like
   too cluttered, for mobile make it carousel swipable like Instagram."

   ── What was actually wrong ────────────────────────────────────────────────
   Not the card. The card was already a post. What was wrong was the DENSITY
   INSIDE it: a 20px page gutter and a 16px body padding took 72px off a 375px
   screen before a word was set, every figure sat inside that padding with its
   own frame so nothing ever reached the edge of the card, and a post carrying
   seven province cards or six satellite frames was one continuous vertical
   scroll several screens long. A feed post is a bounded object. These were not.

   ── What Instagram actually does, and what is taken from it ────────────────
   Measured off its own published carousel specs and its web chrome: the header,
   the action row and the dot row are FIXED-HEIGHT rows and only the media
   flexes; media runs to the full width of the post with no side padding; a
   multi-image post is a horizontal snap track with a dot per slide; the avatar
   in the post header is ~32px, not the 44px a desktop feed can afford.

   Taken: the fixed chrome / flexing media split, the full-bleed media, the snap
   track with dots, the tighter header.

   NOT taken, and each is a decision rather than an omission:
   · **The circle avatar.** Ours is a squircle at radius 13-15px, which is the
     shape `ice-feed.css` gives every post on this site. A round avatar here and
     a squircle on /colleges is a worse inconsistency than not matching
     Instagram.
   · **The 2-line caption clamp with "… more".** Instagram's caption is a
     sentence; these are 300 to 700 words of sourced analysis and the page is
     built to be cited from. Hiding it behind a disclosure trades the thing the
     page is for against tidiness.
   · **Edge-to-edge posts with no card.** The mesh behind the feed is the
     college profile's own surface treatment and the card is what sits on it.
     The gutter comes in to 10px instead, which recovers 20px of card width.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the carousel, shared by media and cards ───────────────────────────────
   No JavaScript and no library. `scroll-snap-type` is the swipe, and the dots
   are `::scroll-marker` pseudo-elements whose active state is `:target-current`,
   which the browser maintains itself.

   ⚠️ That is deliberate rather than clever. Production CSP is
   `script-src 'self'` and Astro inlines small page scripts, so a script-driven
   carousel is precisely the kind of feature that ships dead and looks fine in
   dev (AGENTS.md rule 3). A carousel with no script cannot.

   ⚠️ THE PEEK IS THE FALLBACK. `::scroll-marker` is Chromium 135+ and Safari
   26+, and not Firefox at the time of writing. Slides stop short of the track
   so a sliver of the next one always shows, which is what tells a reader there
   is more when the dots are not drawn. Snap and horizontal scroll work
   everywhere, so the worst case is a carousel with no dots. Do not widen the
   slides to 100% to match Instagram exactly without replacing that affordance. */

@media (max-width: 720px) {
  .page-emergency .emg-desks,
  .page-emergency .emg-provinces,
  .page-emergency .emg-roads,
  .page-emergency .emg-gal {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    /* The track bleeds to the card's edges so the peek reaches them, and the
       padding puts the FIRST slide back in line with the prose above it.
       `scroll-padding-inline` makes a snapped slide land on that same line
       instead of against the raw edge. */
    margin-inline: calc(-1 * var(--emg-pad));
    width: calc(100% + var(--emg-pad) * 2);
    max-width: none;
    padding-inline: var(--emg-pad);
    scroll-padding-inline: var(--emg-pad);
    scrollbar-width: none;
  }

  .page-emergency :is(.emg-desks, .emg-provinces, .emg-roads, .emg-gal)::-webkit-scrollbar {
    display: none;
  }

  .page-emergency .emg-desk,
  .page-emergency .emg-province,
  .page-emergency .emg-road {
    flex: 0 0 86%;
    scroll-snap-align: start;
  }

  /* ⚠️ `start`, not the flex default of `stretch`. A track is as tall as its
     tallest slide either way, but stretched cards PAINT that height: Bagmati
     carries three numbers, an email and fourteen districts, so Koshi's card
     rendered with 350px of empty white below its one phone number. Aligned to
     the top, the spare height is track, not card. */
  .page-emergency :is(.emg-desks, .emg-provinces, .emg-roads) { align-items: start; }

  /* A photograph is not a card. The media track carries wider slides and a
     hairline gap, which is what makes a run of frames read as one object.
     ⚠️ The bottom margin has to clear the dot row. `::scroll-marker-group` is
     in flow after the track, but its height is the browser's business, so the
     group below is given an explicit one and this margin is measured against
     it. Without both, the dots painted straight over the paragraph underneath. */
  .page-emergency .emg-gal { gap: 3px; align-items: start; margin: 16px 0 22px; }
  .page-emergency .emg-gal > .emg-figure {
    flex: 0 0 93%;
    max-width: none;
    margin: 0;
    scroll-snap-align: start;
  }

  .page-emergency .emg-gal__hint {
    margin: 8px 0 20px;
    font-size: var(--ice-type-caption-size);
    line-height: var(--ice-type-caption-line);
    color: var(--ice-color-text-muted);
  }
}

/* Stacked above the breakpoint, so the hint is a lie and goes. */
@media (min-width: 721px) {
  .page-emergency .emg-gal { display: grid; gap: var(--ice-space-6); }
  .page-emergency .emg-gal__hint { display: none; }
}

/* ── the dots ──
   Inside `@supports` so a browser without them is never left with a group box
   that has no markers in it. */
@supports (scroll-marker-group: after) {
  @media (max-width: 720px) {
    .page-emergency :is(.emg-desks, .emg-provinces, .emg-roads, .emg-gal) {
      scroll-marker-group: after;
    }

    .page-emergency :is(.emg-desks, .emg-provinces, .emg-roads, .emg-gal)::scroll-marker-group {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      align-items: center;
      gap: 0;
      /* ⚠️ An EXPLICIT height. Left to size itself the group measured 32px
         under one track and 10px under another, and at 10px the dots painted
         over the paragraph below. A fixed row is what the tracks' bottom
         margins are measured against. */
      height: 34px;
      padding-top: 10px;
      box-sizing: border-box;
    }

    /* A 7px mark inside a 24px control. `::scroll-marker` is a real control —
       it is focusable and it scrolls the track — so it owes the 24px of
       WCAG 2.5.8, and the pitch is 24px too because the rule is that a 24px
       circle centred on one target may not reach the next one. That is why
       these sit further apart than Instagram's, which are indicators only.

       The size comes from a TRANSPARENT BORDER rather than padding: border-radius
       rounds the padding box, so `background-clip: padding-box` gives a round
       7px dot, and `background-clip: content-box` with padding would give a
       square one. */
    .page-emergency :is(.emg-desk, .emg-province, .emg-road)::scroll-marker,
    .page-emergency .emg-gal > .emg-figure::scroll-marker {
      content: "";
      width: 7px;
      height: 7px;
      border-radius: 50%;
      border: 8.5px solid transparent;
      background-color: color-mix(in srgb, var(--ice-color-text) 22%, transparent);
      background-clip: padding-box;
    }

    /* ⚠️ `background-color`, NEVER the `background` shorthand. The shorthand
       resets `background-clip` to `border-box`, which paints the whole 24px
       control and renders the current slide's dot as a crimson disc four times
       the size of the others. That shipped for about ten minutes. */
    .page-emergency :is(.emg-desk, .emg-province, .emg-road)::scroll-marker:target-current,
    .page-emergency .emg-gal > .emg-figure::scroll-marker:target-current {
      background-color: var(--ice-color-crimson);
    }

    /* With real dots the count sentence is redundant. */
    .page-emergency .emg-gal__hint { display: none; }
  }
}

/* ── the post itself ──────────────────────────────────────────────────────── */

@media (max-width: 720px) {
  /* `--emg-pad` is the post's own side padding and the carousels read it to
     work out how far to bleed. One value, declared once, because the two have
     to agree or the first slide stops being in line with the prose. */
  .page-emergency { --emg-pad: 14px; }

  /* 10px, not the 20px `--gutter` floor. A feed reads as a feed when the card
     is nearly as wide as the phone; this recovers 20px of card. */
  .emg-page { padding: 10px 10px 56px; }
  .emg-crumb { margin-inline: 4px; }

  .page-emergency .post {
    border-radius: 20px;
    margin-bottom: 12px;
  }

  /* The fixed-height chrome row. Avatar down from 44px, which is a desktop
     size on a phone, and the padding with it. */
  .page-emergency .post__head { gap: 10px; padding: 12px var(--emg-pad) 9px; }
  .page-emergency .post__avatar { width: 38px; height: 38px; border-radius: 13px; }
  .page-emergency .post__title { font-size: 15.5px; }
  .page-emergency .post__sub { font-size: 12.5px; }

  .page-emergency .post__body { padding: 0 var(--emg-pad) 14px; }

  /* The fold row, on the same rhythm as the header it replaces. 64px is the
     largest thumbnail that leaves a two-line teaser room to be read at 375px. */
  .page-emergency .fold { gap: 12px; padding: 12px var(--emg-pad); }
  .page-emergency .fold__thumb { width: 64px; height: 64px; border-radius: 14px; }
  .page-emergency .fold__thumb--icon svg { width: 26px; height: 26px; }
  .page-emergency .fold__title { font-size: 15.5px; }
  .page-emergency .fold__kind { font-size: 11px; }
  .page-emergency .fold__teaser { font-size: 13.5px; }

  .page-emergency .emg-foldbar { margin-bottom: 12px; padding: 11px 14px; border-radius: 16px; }
  /* Full width, because at 375px a button beside a two-line note leaves the
     note about nine characters. */
  .page-emergency .emg-foldbar__btn { flex: 1 1 100%; }

  /* Every grid-turned-track already sets its own margins above; these are the
     blocks that stay stacked and only want their spacing pulled in. */
  .page-emergency .emg-lifeline { margin: 16px 0 20px; gap: 10px; }
  .page-emergency .emg-toll { margin-top: 18px; }
  .page-emergency .emg-asof { margin-bottom: 20px; }
  .page-emergency .emg-checklist { margin-bottom: 20px; }
  .page-emergency .emg-valley { margin: 14px 0 22px; }
  .page-emergency .emg-account { margin: 14px 0 20px; padding: 14px; }
  .page-emergency .emg-desks,
  .page-emergency .emg-provinces,
  .page-emergency .emg-roads { margin: 16px 0 22px; }

  .page-emergency .post__foot { margin-top: 14px; padding-top: 11px; }

  /* ── media runs to the edge of the card ──
     The single strongest signal that a card is a post rather than an article
     panel, and the one thing the first version of this page never did: a figure
     sat inside the body padding with a border and a radius on all four sides,
     so it read as an illustration in a document. It now reaches both edges and
     only the caption is indented back. */
  .page-emergency .post__body > .emg-figure {
    margin-inline: calc(-1 * var(--emg-pad));
    width: calc(100% + var(--emg-pad) * 2);
    max-width: none;
    margin-block: 16px 18px;
  }

  .page-emergency .post__body > .emg-figure > .emg-figure__img,
  .page-emergency .post__body > .emg-figure > .emg-figure__frame {
    border-radius: 0;
    border-inline: 0;
  }

  .page-emergency .post__body > .emg-figure > .emg-figure__cap {
    padding-inline: var(--emg-pad);
  }

  /* A slide inside a track keeps its frame: it is one of several objects in a
     row and the edges are what separate them. */
  .page-emergency .emg-gal > .emg-figure > .emg-figure__img,
  .page-emergency .emg-gal > .emg-figure > .emg-figure__frame {
    border-radius: 8px;
    border-inline: 1px solid var(--ice-color-border);
  }
  .page-emergency .emg-gal > .emg-figure > .emg-figure__cap { padding-inline: 0; }

  /* The profile card, on the same rhythm. */
  .page-emergency .pf { margin-bottom: 12px; }
  .page-emergency .pf__pills { top: 10px; left: 10px; right: 10px; gap: 5px; }
  .page-emergency .pf__pill { padding: 5px 10px; font-size: 10.5px; letter-spacing: .07em; }
  .page-emergency .ptabs { margin-bottom: 12px; }
}

/* ── reduced motion ──
   `scroll-behavior: smooth` is inherited from `html` on this site, and a
   carousel that animates its way between slides is motion a reader asked not to
   have. Snapping still happens; it just happens at once. */
@media (prefers-reduced-motion: reduce) {
  .page-emergency :is(.emg-desks, .emg-provinces, .emg-roads, .emg-gal) {
    scroll-behavior: auto;
  }
}

/* Print gets the stack back. A carousel on paper is one slide and a row of
   dots, which is the whole point of it lost. */
@media print {
  .page-emergency :is(.emg-desks, .emg-provinces, .emg-roads, .emg-gal) {
    display: block;
    overflow: visible;
    width: auto;
    margin-inline: 0;
    padding-inline: 0;
  }
  .page-emergency .emg-gal__hint { display: none; }
}
