/* First Minutes
 *
 * Designed for the worst reading conditions there are: a moving deck, glare or
 * darkness, wet hands, and somebody frightened. Everything follows from that.
 *
 *   - No web fonts. A font that has to download is a font that is missing on
 *     the boat, and the system stack is already the most legible thing on the
 *     device.
 *   - Tap targets are large enough to hit while shaking. Nothing important is
 *     smaller than 56px tall.
 *   - Light and dark are both first-class. Direct sun wants light; a night
 *     crossing wants dark; the reader chooses neither, their phone does.
 *   - Red is reserved. It means "call" and "do not". Nothing decorative is red,
 *     so red never has to be read twice.
 */

:root {
  --bg: #ffffff;
  --surface: #f4f5f7;
  --surface-2: #e9ebef;
  --text: #14161a;
  --text-dim: #565c66;
  --line: #d3d7de;
  --red: #b8121b;
  --red-ink: #8c0d14;
  --red-wash: #fdeceb;

  /* The call tile must NOT follow the theme.
   *
   * --red lightens on dark so inline red text stays legible on a near-black
   * page. The call tiles cannot follow it: measured, white on the lightened
   * red is 3.62:1 — the single most important string in the app, at its least
   * legible exactly when somebody is reading it at night. So the tile stays
   * brand red in both themes, its text stays white, and the provenance line
   * under the number is the palest tint that still clears AA on it. */
  --call-bg: #b8121b;
  --call-ink: #ffffff;
  --call-note: #ffe3e4;

  /* Step numerals are ink, not red. Red is reserved for call and do-not, and a
   * numbered step is neither. Dark disc with light figures on light, light
   * disc with dark figures on dark. */
  --step-bg: #14161a;
  --step-ink: #ffffff;

  /* The CPR prompter is deliberately the same near-black in both themes: it is
   * read at arm's length on a deck, and a white full-screen pulse only reads
   * as a pulse against something dark. These do not follow the theme. */
  --cpr-bg: #07090c;
  --cpr-ink: #ffffff;
  --cpr-dim: #c3cad2;
  --cpr-label: #8b949e;
  --cpr-panel: #12161c;
  --cpr-btn: #1b212a;
  --cpr-amber-ink: #f0b45e;
  --cpr-amber-bg: #2b2113;
  /* The breath swell. Blue, because it is the one colour in the palette that
   * means neither call nor do-not nor unreviewed, and a breath must not look
   * like a push. Does not follow the theme. */
  --cpr-breath: #9cc0ff;
  --amber-ink: #7a4b00;
  --amber-wash: #fdf1dc;
  --ok: #0f6b3f;
  --focus: #0b57d0;
  /* Selectors — a choice the reader makes on the call script, and the two
   * segment switches. Blue, because red means call and do-not, amber means
   * unreviewed, and a choice is none of those. */
  --sel-ink: #0b57d0;
  --sel-wash: #e4edff;
  --sel-line: #9db8ec;
  --radius: 14px;
  --gutter: clamp(16px, 4vw, 28px);
  --measure: 40rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d0f12;
    --surface: #171a1f;
    --surface-2: #21252c;
    --text: #f2f4f7;
    --text-dim: #a4acb9;
    --line: #333944;
    --red: #ef4b52;
    --red-ink: #ff8b8f;
    --red-wash: #2a1214;
    /* --call-bg, --call-ink, --call-note and the --cpr-* set deliberately do
     * not change here. */
    --step-bg: #f2f4f7;
    --step-ink: #14161a;
    --amber-ink: #f0b45e;
    --amber-wash: #2b2113;
    --ok: #5ed39b;
    --focus: #7cabff;
    --sel-ink: #9cc0ff;
    --sel-wash: #182a4a;
    --sel-line: #3b5590;
  }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 17px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  overflow-wrap: break-word;
}

a { color: inherit; }

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Nothing here animates for its own sake, but the two transforms that exist
 * are press feedback, and a reader who has asked for less motion should not
 * get it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .tel:active, .item:active { transform: none; }
}

.wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---------- the call block ----------
 *
 * Two red tiles on the page, not a red panel with pale tiles inside it. Red
 * means "call": making the panel red as well spent the loudest colour in the
 * app on a background, and the tiles had to be pale to sit on it — which is
 * how the dive-doctor number ended up dark red on near-white. Now the tile IS
 * the red thing, the number is white on it, and the page around it is the
 * page. Verb, then number, then where the number came from and when: never a
 * number without the third line.
 */

.call {
  background: var(--bg);
  padding: calc(4px + env(safe-area-inset-top)) var(--gutter) 0;
}

.call__brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 6px;
  font-size: 15px;
  line-height: 1;
}
.call__lockup { display: flex; align-items: center; gap: 0.32em; min-width: 0; }
/* Where the phone is, top right: town and country from the GPS when there is
 * a fix, the country from the clock until then, and one tap to change. Two
 * lines of small type — it names, it does not compete with the tiles. */
.loc {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  min-height: 44px;
  max-width: 58%;
  padding: 2px 0 2px 10px;
  text-align: end;
  text-decoration: none;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.15;
}
.loc__main {
  max-width: 100%;
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.loc__main::before { content: "⌖ "; color: var(--text-dim); }
.loc__sub { font-size: 11.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

.call__grid {
  display: grid;
  gap: 8px;
  max-width: var(--measure);
  margin: 0 auto;
}

.tel {
  display: block;
  min-height: 64px;
  padding: 12px 16px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 16px;
  text-decoration: none;
}

.tel:active { transform: translateY(1px); }

/* The two lead tiles. 84 px minimum — about 13 mm on a 460 ppi screen, nearly
 * twice Apple's 44 pt, which is what a wet thumb on a moving deck needs — and
 * they stay brand red in both themes, because a red that lightens for a night
 * screen drops white text to 3.6:1. */
.tel--lead {
  min-height: 84px;
  padding: 10px 16px;
  background: var(--call-bg);
  border-color: var(--call-bg);
  color: var(--call-ink);
  box-shadow: 0 1px 0 rgba(0, 0, 0, .18);
}

.tel__name {
  display: block;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.12;
}

.tel__num {
  display: block;
  font-size: clamp(24px, 6.6vw, 28px);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.tel__note { display: block; font-size: 12.5px; line-height: 1.3; margin-top: 2px; }
.tel--lead .tel__note { display: none; }

/* One provenance line for both tiles. Red line 8 says every number carries
 * its date; it does not say the date has to be printed inside each tile in
 * eleven-point type. "Greece · from your phone's clock · checked 6 Sep" is
 * the whole story, and "Change" is the escape. */
.call__where {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 0 4px;
  font-size: 13px;
  color: var(--text-dim);
  line-height: 1.3;
}
.call__where a {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 8px;
  font-weight: 700;
  color: var(--text);
  text-decoration: none;
}


.call__vhfn { font-size: 17px; font-weight: 700; }
.call__vhft { font-size: 14px; color: var(--text-dim); text-align: end; }

/* The ring inside a red tile is white; the blue one measures 1.05:1 on that
 * red, so a keyboard or switch user could not see where they were. */
.tel--lead:focus-visible,
.tel--more:focus-visible {
  outline-color: #ffffff;
  box-shadow: 0 0 0 6px rgba(0, 0, 0, .45);
}

/* Other regions.
 *
 * DAN Europe is the primary tile because that is where the app is going out.
 * The rest of DAN's hotlines are one tap away behind a summary that looks like
 * a tile, in-country lines first and the worldwide line labelled "anywhere not
 * listed", so a reader off another coast never has to guess which of six
 * numbers is theirs from a wall of them. */
.call__more { display: block; min-width: 0; }
.call__more summary { list-style: none; cursor: pointer; }
.call__more summary::-webkit-details-marker { display: none; }

.tel--more {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  flex-wrap: nowrap;
}

.tel--more .tel__name { flex: 1 1 auto; font-size: 17px; font-weight: 600; }
.tel--more .tel__num {
  flex: 1 1 auto;
  min-width: 0;
  text-align: end;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
}
.tel--more .tel__note { display: none; }
.tel--more::after { content: "+"; flex: none; font-size: 22px; line-height: 1; color: var(--text-dim); }
.call__more[open] .tel--more::after { content: "\2212"; }

.call__sub { display: grid; gap: 8px; margin-top: 8px; }

.call__subhead {
  margin: 4px 0 0;
  font: 700 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.tel--sub { min-height: 60px; }
.tel--sub .tel__name { font-size: 16px; font-weight: 600; }
.tel--sub .tel__num { font-size: 19px; }
.tel--sub .tel__note { color: var(--text-dim); }

.tel--link {
  display: flex;
  align-items: center;
  min-height: 56px;
  background: transparent;
  border-style: dashed;
  font-weight: 600;
  font-size: 15px;
  color: var(--text-dim);
}

.call__credit {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-dim);
}

/* Compact, and docked to the bottom.
 *
 * It used to sit at the top of every inner page. That put the two most
 * important targets on a 390-wide screen in the one strip a thumb cannot
 * reach, directly beside the back control they would be mistaken for. Docked
 * above the safe area instead, it is in the thumb arc, it never scrolls away,
 * and the reader's hand is already there. Two tiles, not three: the worldwide
 * expander needs room to breathe and lives on the home screen and on Numbers.
 * Provenance is deferred here, never dropped — it is one tap away on Numbers,
 * and full size on home. */
body.inner .call {
  position: sticky;
  top: 0;
  z-index: 20;
  padding: calc(6px + env(safe-area-inset-top)) 10px 8px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

body.inner .call__brand,
body.inner .call__more,
body.inner .call__vhf,
body.inner .call__where,
body.inner .tel__note { display: none; }

body.inner .call__grid { grid-template-columns: 1fr 1fr; gap: 6px; }

body.inner .tel--lead {
  min-height: 60px;
  padding: 9px 12px;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* No bar at all on the cards, the CPR screen and the calm-day pages — the
 * tiles are on Home and on the call script, and Home is one tap away on the
 * menu from anywhere (owner, 8 Sep). The CPR panel then starts at the top of
 * the screen and carries the safe area itself. */
body.nocall .call { display: none; }
body.nocall .cpr { padding-top: calc(10px + env(safe-area-inset-top)); }
/* The bar used to carry the top safe-area inset; without it the page must,
 * or the first line of a card sits under the iPhone's status bar. */
body.nocall main { padding-top: calc(24px + env(safe-area-inset-top)) !important; }

body.inner .tel__name { font-size: 13px; font-weight: 700; line-height: 1.2; }
/* One line, always. A wrapped phone number in a 60 px bar is a number that
 * pushes its own tile off the bottom of the screen. */
body.inner .tel__num { font-size: 17px; white-space: nowrap; }
body.inner #tel-dan .tel__num { font-size: 16px; }

/* Three tiles when a scanned plan supplies the dive centre's own line. On
 * home they stack like the pair; in the compact bar they share the row, and
 * the number gives up size before it gives up its line — the verb is the
 * target, the number is there to be read back. */
body.inner .call--plan .call__grid { grid-template-columns: 1fr 1fr 1fr; gap: 5px; }
body.inner .call--plan .tel--lead { padding: 8px 7px; }
body.inner .call--plan .tel__name { font-size: 12px; }
body.inner .call--plan .tel__num,
body.inner .call--plan #tel-dan .tel__num { font-size: clamp(11px, 3.4vw, 14px); letter-spacing: -0.02em; }
.call__own { display: grid; gap: 8px; }

/* ---------- the menu ----------
 *
 * Fixed to the bottom on every screen. Targets are 60 px tall — a wet thumb
 * on a moving deck — and the active one is marked by weight and a bar, not
 * by red. Everything under it gets padding so nothing is ever hidden. */
.tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  padding: 4px 6px calc(6px + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: 1px solid var(--line);
}

.tabs a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 54px;
  border-radius: 12px;
  font-size: 11.5px;
  letter-spacing: -0.01em;
  white-space: nowrap;
  font-weight: 600;
  color: var(--text-dim);
  text-decoration: none;
  position: relative;
}

.tabs__ic { font-size: 20px; line-height: 1; }
.tabs a.is-on { color: var(--text); font-weight: 750; }
.tabs a.is-on::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 22%;
  right: 22%;
  height: 3px;
  border-radius: 2px;
  background: var(--text);
}
.tabs a:active { background: var(--surface-2); }

main { padding-bottom: calc(78px + env(safe-area-inset-bottom)) !important; }
.foot { padding-bottom: calc(92px + env(safe-area-inset-bottom)) !important; }

/* ---------- structure ---------- */

main { padding-top: 24px; padding-bottom: 8px; }
body:not(.inner) main { padding-top: 10px; }

h2 {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--text-dim);
  margin: 32px 0 12px;
}

h3 { font-size: 22px; line-height: 1.25; margin: 0 0 4px; letter-spacing: -0.01em; }

.lede { color: var(--text-dim); margin: 0 0 20px; }

/* ---------- the disclaimer strip ----------
 *
 * Replaces a modal that used to cover the phone numbers until it was tapped
 * away. Two lines, one button, gone for good once dismissed; the full
 * statement lives in the footer of every page. */
.notice {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 12px 14px;
  margin: 0 0 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 14px;
}

.notice p { margin: 0; flex: 1; }
.notice .btn { min-height: 48px; padding: 10px 16px; flex: none; }

/* ---------- do now: the three verbs ----------
 *
 * The home screen is the sentence the product is built on: safe and warm and
 * oxygen on, say the words, write it down. Three numbered rows — numbered
 * because people count out loud under stress — with no card chrome around
 * them, because they are the sentence and not a menu. They are still links,
 * so a reader who taps the words they just read lands where the words say.
 */
/* ---------- the four home cards ----------
 *
 * CPR · Diving injuries · Call script · Analysis. Big, because a thumb picks
 * one; two words and a gloss each. Measured 7 Sep 2026 at 393 × 759 (an
 * iPhone 16 with its safe areas taken off): the grid ends well clear of the
 * tab bar. The CPR card carries a heavy border rather than a red fill,
 * because red is call and do-not and this is neither. */
.home__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 4px 0 10px; }
.home__card {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 4px;
  min-height: 128px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
}
.home__card:active { background: var(--surface-2); }
.home__card--cpr { border: 2px solid var(--text); }
.home__name { font-size: 23px; font-weight: 750; line-height: 1.1; letter-spacing: -0.015em; }
.home__sum { font-size: 14px; color: var(--text-dim); line-height: 1.25; }
.home__trip { margin: 0; font-size: 14px; color: var(--text-dim); }

.dock__links { display: flex; justify-content: space-between; gap: 8px; margin-top: 2px; }

.dock__links a {
  display: inline-flex;
  align-items: center;
  min-height: 56px;
  padding: 0 4px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-dim);
  text-decoration: none;
}

.dock__trip { margin: 0 0 18px; font-size: 13px; color: var(--text-dim); }

/* ---------- boat first aid chips ----------
 *
 * Eleven cards whose titles say everything — Choking, Burns, CPR — so they
 * render as a wrap of big chips rather than a list of summaries, one tap each,
 * visible on the first scroll. The draft badge stays on every chip. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 8px; padding: 0; list-style: none; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 56px;
  padding: 8px 14px;
  font-size: 17px;
  font-weight: 650;
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.chip:active { background: var(--surface-2); }
.chip--two { flex-direction: column; align-items: flex-start; gap: 1px; padding: 8px 14px; }
.chip__sub { display: block; font-size: 12.5px; font-weight: 500; color: var(--text-dim); }

/* ---------- lists of cards ---------- */

.list { display: grid; gap: 10px; }

.item--muted { background: transparent; border-style: dashed; }

.item {
  display: block;
  padding: 14px 16px;
  min-height: 60px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
}

.item:active { background: var(--surface-2); }

.item__kicker {
  display: block;
  font: 600 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .12em;
  color: var(--text-dim);
  text-transform: uppercase;
}

.item__title { display: block; font-size: 19px; font-weight: 650; margin-top: 2px; }
.item__sum { display: block; font-size: 14px; color: var(--text-dim); margin-top: 4px; }

/* ---------- one protocol ---------- */

.back {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  margin-bottom: 8px;
  padding: 0 12px 0 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-dim);
  text-decoration: none;
}

.kicker {
  font: 600 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--red-ink);
}

.title { font-size: clamp(26px, 6.5vw, 33px); line-height: 1.12; margin: 6px 0 10px; letter-spacing: -0.02em; }

.signs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 22px; padding: 0; list-style: none; }

.sign {
  font-size: 14px;
  padding: 5px 11px;
  background: var(--surface-2);
  border-radius: 999px;
  color: var(--text);
}

.steps { counter-reset: s; list-style: none; margin: 0; padding: 0; }

.step { counter-increment: s; position: relative; padding: 0 0 20px 46px; }

.step::before {
  content: counter(s);
  position: absolute;
  left: 0;
  top: 0;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  background: var(--step-bg);
  color: var(--step-ink);
  border-radius: 50%;
  font-weight: 700;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
}

.step__text { font-size: 18px; line-height: 1.45; }

.cite { margin-top: 8px; font-size: 13px; }

.cite summary {
  cursor: pointer;
  color: var(--text-dim);
  font-weight: 600;
  list-style: none;
  padding: 4px 0;
}

.cite summary::-webkit-details-marker { display: none; }
.cite summary::before { content: "▸ "; }
.cite[open] summary::before { content: "▾ "; }

.cite__body {
  margin-top: 6px;
  padding: 10px 12px;
  border-inline-start: 3px solid var(--line);
  background: var(--surface);
  border-radius: 0 8px 8px 0;
  color: var(--text-dim);
}

.cite__quote { font-style: italic; }
.cite__src { display: block; margin-top: 6px; font-size: 12px; }

.uncited {
  margin-top: 8px;
  font-size: 13px;
  color: var(--amber-ink);
  background: var(--amber-wash);
  padding: 8px 10px;
  border-radius: 8px;
}

.donot {
  margin: 10px 0 24px;
  padding: 14px 16px;
  background: var(--red-wash);
  border: 1px solid var(--red);
  border-radius: var(--radius);
}

.donot h4 {
  margin: 0 0 6px;
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--red-ink);
}

.donot p { margin: 0; font-size: 17px; }

.case {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 10px;
  background: var(--surface);
}

.case h4 { margin: 0 0 2px; font-size: 17px; }
.case__detail { margin: 0 0 8px; font-size: 14px; color: var(--text-dim); }
.case__action { margin: 0; font-size: 16px; }

details.bg { margin: 8px 0 24px; }

details.bg summary {
  cursor: pointer;
  padding: 14px 0;
  font-weight: 650;
  color: var(--text-dim);
  border-top: 1px solid var(--line);
}

/* ---------- draft line ---------- */

.draftline {
  margin: -4px 0 14px;
  font-size: 14px;
  color: var(--amber-ink);
}

/* ---------- write it down ---------- */

.obs {
  width: 100%;
  min-height: 180px;
  padding: 12px 14px;
  font: inherit;
  font-size: 17px;
  line-height: 1.5;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  resize: vertical;
}

.obs__bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 20px; }
.obs__bar .btn { flex: 1 1 auto; text-align: center; }

/* ---------- selects and textareas ---------- */

.field select,
.field textarea {
  width: 100%;
  min-height: 52px;
  padding: 10px 14px;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.field textarea { min-height: 84px; resize: vertical; }

/* ---------- this trip ----------
 *
 * The dive centre's plan, scanned in from the boat sheet's QR. It sits under
 * the call block on the home screen with its provenance on it — who keeps
 * it, when it was checked — and its numbers are the operator's, never mixed
 * with the app's own checked numbers. */
.trip {
  margin: 0 0 20px;
  padding: 12px 14px 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.trip__head { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; margin-bottom: 8px; }
.trip__name { font-size: 17px; font-weight: 700; }
.trip__prov { font-size: 12.5px; color: var(--text-dim); }
.trip__rows { display: grid; gap: 6px; margin: 0 0 8px; }

.trip__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  text-decoration: none;
  font-size: 15px;
}

.trip__row b { font-variant-numeric: tabular-nums; text-align: end; }
a.trip__row { min-height: 56px; align-items: center; }
a.trip__row b { font-size: 18px; }
.trip__foot { font-size: 12.5px; color: var(--text-dim); margin: 0 0 6px; }
.trip__row--text { flex-direction: column; gap: 2px; }
.trip__row--text b { text-align: start; font-weight: 500; font-size: 16px; }
.trip__row--text span { font-size: 12.5px; color: var(--text-dim); }

/* ---------- prefilled script lines ---------- */

/* A choice on the call script. Blue border and wash; the sentence to read is
 * built under it in the page's own ink, so "choose" and "say" never look the
 * same. */
.sel { display: block; }
.sel__opts { display: flex; flex-wrap: wrap; gap: 6px; }
.sel__opt {
  min-height: 44px;
  padding: 8px 13px;
  font: inherit;
  font-size: 15px;
  font-weight: 650;
  color: var(--sel-ink);
  background: var(--bg);
  border: 2px solid var(--sel-line);
  border-radius: 999px;
  cursor: pointer;
}
.sel__opt.is-on { background: var(--sel-wash); border-color: var(--sel-ink); }
.sel__opt.is-on::before { content: "✓ "; }
.sel__other {
  flex: 1 1 120px;
  min-height: 44px;
  padding: 6px 12px;
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.sel__say { margin: 8px 0 0; font-size: 17px; }
.sel__say b { font-weight: 700; }
.sel__skip { color: var(--text-dim); font-size: 15px; }
.sel__link { font-weight: 700; white-space: nowrap; }
.sel__cpr { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 15px; color: var(--text-dim); }
.sel__cpr input {
  min-height: 44px;
  padding: 4px 10px;
  font: inherit;
  font-size: 17px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.sbar__hint { margin: 0; padding: 8px 16px 12px; font-size: 13px; color: var(--text-dim); }
.geo {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 12px;
  align-items: center;
  padding: 10px 16px 12px;
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.geo--card { border: 1px solid var(--line); border-radius: var(--radius); margin: 0 0 12px; }
.geo__lab {
  grid-column: 1 / -1;
  font: 700 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.geo__pos { grid-column: 1; font-size: 19px; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.geo__meta { grid-column: 1; font-size: 13px; color: var(--text-dim); }
.geo__btn {
  grid-column: 2;
  grid-row: 2 / span 2;
  min-height: 44px;
  padding: 8px 14px;
  font: inherit;
  font-size: 15px;
  font-weight: 650;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
}
.sbar--confirm .sbar__letter { color: var(--ok); }
.confirm { padding: 0 16px 14px; }
.confirm .obs__bar { align-items: center; }
.say__first {
  margin: 0 0 12px;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--line);
  font-size: 17px;
}
.say__firstl { display: block; font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); }
.say__firsten { display: block; font-size: 14px; color: var(--text-dim); }
.say__eap { margin-bottom: 12px; }
.say__noplan { margin: 0 0 12px; font-size: 14px; color: var(--text-dim); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sbar__lines li .fill {
  display: inline-block;
  padding: 0 6px;
  border-radius: 6px;
  background: var(--surface-2);
  font-weight: 650;
}
.sbar__lines li .fill--empty { background: transparent; font-weight: 400; padding: 0; }

/* ---------- the printed QR ----------
 *
 * The plain app link is a small code. A code carrying the plan is a larger
 * one, and a 26 mm print of it would be a laminated failure; the print
 * stylesheet sizes it by which it is. */
.sheet__qr--data svg { width: 118px; height: 118px; }

/* ---------- badges and notes ---------- */

.pill {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
}

.pill--ok { background: var(--surface-2); color: var(--ok); }
.pill--draft { background: var(--amber-wash); color: var(--amber-ink); }
.pill--off { background: var(--amber-wash); color: var(--amber-ink); }

.note {
  padding: 14px 16px;
  border-radius: var(--radius);
  margin: 0 0 22px;
  font-size: 15px;
  background: var(--surface);
  border: 1px solid var(--line);
}

.note--warn { background: var(--amber-wash); border-color: transparent; color: var(--amber-ink); }
.note p:first-child { margin-top: 0; }
.note p:last-child { margin-bottom: 0; }

/* ---------- search ---------- */

.search {
  width: 100%;
  min-height: 56px;
  padding: 12px 16px;
  font-size: 17px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 8px;
}

/* ---------- find page ---------- */

.list--row { margin-top: 4px; }

/* Sign chips grow into tap targets on the index page. 44px minimum height:
 * these get hit with wet thumbs. */
.signs--index { margin-bottom: 28px; }

.sign--link {
  display: inline-flex;
  align-items: center;
  min-height: 56px;
  padding: 8px 16px;
  font-size: 16px;
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line);
}

.sign--link:active { background: var(--surface-2); }

.signs--index li { list-style: none; }

.az { display: grid; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }

.az__row {
  display: block;
  padding: 13px 16px;
  min-height: 50px;
  font-size: 17px;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.az__row:last-child { border-bottom: 0; }
.az__row:active { background: var(--surface-2); }
.az__see { font-weight: 400; color: var(--text-dim); font-size: 15px; }

/* ---------- the two-script toggle ---------- */

.toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 0 0 16px; }

.toggle__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 56px;
  padding: 10px 14px;
  font-size: 16px;
  font-weight: 650;
  text-align: center;
  text-decoration: none;
  border: 2px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text-dim);
}

.toggle__btn.is-on {
  border-color: var(--sel-ink);
  color: var(--sel-ink);
  background: var(--sel-wash);
}

.toggle__btn.is-on::before { content: "✓ "; }

/* ---------- one sentence in four languages ---------- */

.lang {
  margin: 0 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.lang summary {
  display: flex;
  align-items: center;
  min-height: 56px;
  padding: 12px 16px;
  font-weight: 650;
  cursor: pointer;
  list-style: none;
}

.lang summary::-webkit-details-marker { display: none; }
.lang summary::before { content: "▸ "; margin-inline-end: 6px; color: var(--text-dim); }
.lang[open] summary::before { content: "▾ "; }
.lang__lines { margin: 0; padding: 0 16px 12px; list-style: none; }
.lang__lines li { display: flex; gap: 12px; padding: 9px 0; border-top: 1px solid var(--line); font-size: 17px; }

.lang__l {
  flex: none;
  min-width: 2.2em;
  padding-top: 4px;
  font: 700 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .08em;
  color: var(--text-dim);
}

/* ---------- the DAN credit ---------- */

.credit {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 16px;
  margin: 0 0 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.credit__logo { height: 44px; width: auto; flex: none; }
.credit__word { flex: none; font-size: 22px; font-weight: 800; letter-spacing: -.02em; line-height: 1.3; }
.credit__text { margin: 0; font-size: 15px; }

/* ---------- SBAR ---------- */

.sbar { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin-bottom: 12px; }

.sbar__head { display: flex; gap: 12px; align-items: baseline; padding: 12px 16px; background: var(--surface-2); }

.sbar__letter {
  font: 700 24px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--red-ink);
  width: 22px;
}

.sbar__name { font-weight: 650; font-size: 18px; }
.sbar__gloss { display: block; font-size: 13px; color: var(--text-dim); font-weight: 400; }
.sbar__lines { margin: 0; padding: 12px 16px 14px; list-style: none; }
.sbar__lines li { padding: 7px 0; font-size: 17px; border-bottom: 1px solid var(--line); }
.sbar__lines li:last-child { border-bottom: 0; }

/* ---------- neuro record ---------- */

.check { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 10px; background: var(--surface); }
.check h4 { margin: 0 0 6px; font-size: 18px; }
.check__how { margin: 0 0 8px; font-size: 16px; }
.check__rec { margin: 0; font-size: 14px; color: var(--text-dim); }
.check__rec strong { color: var(--text); }

/* ---------- buttons ---------- */

.btn {
  display: inline-block;
  min-height: 56px;
  padding: 15px 22px;
  font: inherit;
  font-weight: 650;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
}

/* Ink, not red. Red in this app means "call" and "do not", and a Print or a
 * Stamp button is neither — a second red thing on screen is a red thing the
 * reader has to stop and read twice. */
.btn--primary { background: var(--step-bg); border-color: var(--step-bg); color: var(--step-ink); }

/* ---------- gate ---------- */

.gate {
  border: 0;
  border-radius: var(--radius);
  padding: 0;
  max-width: 34rem;
  width: calc(100% - 32px);
  background: var(--bg);
  color: var(--text);
}

.gate::backdrop { background: rgba(0, 0, 0, .6); }
.gate form { padding: var(--gutter); }
.gate h2 { margin-top: 0; font-size: 22px; text-transform: none; letter-spacing: -0.01em; color: var(--text); }
.gate p { font-size: 15px; }

/* ---------- footer ---------- */

.foot { padding-top: 16px; border-top: 1px solid var(--line); margin-top: 28px; }
/* The lockup.
 *
 * Proportions come from the brand spec and are expressed in ems so the mark
 * scales with whatever type size it sits beside: flag height is 1.22x cap
 * height (cap height ~0.72em in this stack, so 0.88em), gap is 0.36x the flag.
 *
 * The stripe is `--bg`, not white. On dark the field lightens to the dark red
 * and the stripe takes the page behind it, so the mark reads as a division of
 * a field rather than a glowing white slash on a night screen.
 */
.lockup { display: flex; align-items: center; gap: 0.32em; margin-bottom: 16px; font-size: 17px; }
.lockup__flag { width: 0.88em; height: 0.88em; flex: none; display: block; }
.lockup__field { fill: var(--red); }
.lockup__stripe { fill: var(--bg); }
.lockup__word { font-weight: 750; letter-spacing: -0.028em; line-height: 1; }

.foot__nav { display: none; }

/* Measured at 23px tall before this: the footer links were the smallest
 * targets in the app. Padding rather than font-size, so the type stays the
 * size it wants to be and the target grows around it. */
.foot__nav a {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0 10px;
  font-size: 15px;
  font-weight: 600;
}
.foot__meta { font-size: 13px; color: var(--text-dim); margin: 0 0 10px; }
.foot__legal { font-size: 12.5px; color: var(--text-dim); margin: 0; }

/* ---------- forms ---------- */

.field { display: block; margin-bottom: 12px; }
.field span { display: block; font-size: 13px; font-weight: 650; margin-bottom: 4px; color: var(--text-dim); }

.field input {
  width: 100%;
  min-height: 52px;
  padding: 10px 14px;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pair .field { margin-bottom: 12px; }

/* ---------- the printed A5 boat sheet ----------
 *
 * The zero-battery layer, and the only part of this product that works when
 * the phone is at the bottom of the sea. Mono laser on damp paper: black bar,
 * heavy rules, no grey text, nothing that depends on colour. Two pages —
 * English, then English beside a second language — each one A5 on its own.
 */
.a5 { display: grid; gap: 20px; overflow-x: auto; }

.a5__page {
  width: 132mm;
  min-height: 194mm;
  background: #fff;
  color: #000;
  border: 1px solid var(--line);
  padding: 8mm;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* On screen this is a preview of a piece of paper, so it keeps the paper's
 * proportions and is scaled to the phone rather than reflowed to it — a
 * preview that reflows is a preview of something that will not print. */
@media screen {
  .a5__page { zoom: .68; }
}

.a5__bar {
  display: flex;
  align-items: center;
  gap: 3mm;
  background: #000;
  color: #fff;
  padding: 2.6mm 3mm;
  margin: 0 0 3mm;
}

.a5__mark { width: 9mm; height: 6.3mm; flex: none; display: block; }
.a5__wordmark { font-size: 14pt; font-weight: 800; letter-spacing: .04em; }
.a5__who { margin-left: auto; font-size: 8.5pt; font-weight: 700; line-height: 1.25; text-align: right; }

.a5__h {
  margin: 0 0 1.6mm;
  font-size: 9.5pt;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.a5__three { margin: 0 0 3mm; }
.a5__step { display: flex; gap: 2.4mm; padding: 1.8mm 0; border-top: .3mm solid #000; }
.a5__stepn { flex: none; width: 5mm; font-size: 15pt; font-weight: 800; line-height: 1.1; }
.a5__stept { font-size: 12pt; font-weight: 700; line-height: 1.2; }
.a5__stepd { display: block; font-size: 10pt; font-weight: 400; line-height: 1.25; }
.a5__alt { display: block; font-size: 10.5pt; font-weight: 700; line-height: 1.25; margin-top: .6mm; }

.a5__nums { margin: 0 0 3mm; }

.a5__num {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 3mm;
  padding: 1.9mm 0;
  border-bottom: .5mm solid #000;
}

.a5__num:first-child { border-top: .5mm solid #000; }
.a5__numl { font-size: 11pt; font-weight: 800; letter-spacing: .02em; }
.a5__numl small { display: block; font-size: 9pt; font-weight: 400; letter-spacing: 0; }
.a5__numv { font-size: 14pt; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }

.a5__bottom { display: flex; gap: 4mm; align-items: flex-start; margin-top: auto; }
.a5__left { flex: 1 1 auto; min-width: 0; }
.a5__say { border: .5mm solid #000; padding: 2mm 2.4mm; margin-bottom: 2mm; }
.a5__sayt { font-size: 11pt; font-weight: 700; line-height: 1.25; }
.a5__sayn { font-size: 9pt; margin-top: 1mm; }
.a5__keeper { font-size: 9pt; line-height: 1.3; }
.a5__keeper b { display: block; }
.a5__qr { flex: none; width: 48mm; text-align: center; }
.a5__qr svg { width: 48mm; height: 48mm; display: block; }
.a5__qrc { font-size: 8.5pt; font-weight: 700; line-height: 1.2; margin: 1mm 0 0; }

.a5__prov {
  margin: 3mm 0 0;
  padding-top: 1.6mm;
  border-top: .5mm solid #000;
  font-size: 7pt;
  line-height: 1.28;
}

.a5__bi2 { font-size: 10.5pt; font-weight: 700; line-height: 1.22; }

/* The bilingual page carries roughly half as much again, on the same piece of
 * paper. Everything on it is one step smaller, and it still clears 10 pt —
 * which is what a wet reader at arm's length needs. */
.a5__page--bi .a5__bar { padding: 2mm 3mm; margin-bottom: 2.4mm; }
.a5__page--bi .a5__h { margin-bottom: 1.1mm; }
.a5__page--bi .a5__three { margin-bottom: 2.2mm; }
.a5__page--bi .a5__nums { margin-bottom: 2.2mm; }
.a5__page--bi .a5__say { padding: 1.6mm 2mm; margin-bottom: 1.6mm; }
.a5__page--bi .a5__step { padding: .9mm 0; }
.a5__page--bi .a5__stept { font-size: 10.5pt; line-height: 1.16; }
.a5__page--bi .a5__bi2 { font-size: 9.5pt; }
.a5__page--bi .a5__num { padding: 1.05mm 0; }
.a5__page--bi .a5__numl { font-size: 10pt; }
.a5__page--bi .a5__numl small { font-size: 8.5pt; }
.a5__page--bi .a5__numv { font-size: 12.5pt; }
.a5__page--bi .a5__sayt { font-size: 10pt; }
.a5__page--bi .a5__sayn { font-size: 8pt; }
.a5__page--bi .a5__keeper { font-size: 8pt; }
.a5__page--bi .a5__prov { font-size: 6.5pt; }
.a5__page--bi .a5__qrc { font-size: 8pt; }

/* ---------- the ICE card ----------
 *
 * What a buddy reads out while somebody else holds the phone. No chrome, no
 * navigation, nothing to tap by accident: six facts at arm's length. */
.ice { display: grid; gap: 14px; margin: 0 0 20px; }
.ice__l { display: block; font-size: 13px; color: var(--text-dim); }
.ice__v { display: block; font-size: 26px; font-weight: 700; line-height: 1.15; }
.ice__v--big { font-size: 30px; }
.ice__v--sm { font-size: 22px; }

/* ---------- the CPR beat prompter ----------
 *
 * The beat is the edge of the screen. A fixed layer over the whole panel,
 * painted once as an inset glow and animated in opacity only, which the
 * compositor handles without the main thread, and which lets every tap
 * through. Thirty white flashes under the word PUSH, then two slow swells
 * under BREATHE in the one colour that means neither call nor do-not nor
 * unreviewed: a breath. The panel is near-black in both themes, because a
 * glow only reads against dark; the glow frames the panel and stops at the
 * tiles above and the tabs below, which keep the page's own theme — painting
 * the bar black around the red tiles read as a border on the numbers (owner,
 * from the phone, 8 Sep). The tab bar is the way out; there is no stop button.
 */
.cpr {
  position: fixed;
  inset: 0;
  top: var(--bar, 0px); /* the measured call bar */
  bottom: calc(65px + env(safe-area-inset-bottom)); /* the tab bar: 4 + 54 + 6 + 1 */
  z-index: 10;
  background: var(--cpr-bg);
  color: var(--cpr-ink);
  display: flex;
  flex-direction: column;
  padding: 10px 14px;
  overflow-y: auto;
}

.cpr__glow {
  position: fixed;
  inset: 0;
  top: var(--bar, 0px);
  bottom: calc(65px + env(safe-area-inset-bottom));
  z-index: 11;
  pointer-events: none;
  opacity: 0;
  box-shadow: inset 0 0 clamp(54px, 15vw, 120px) clamp(16px, 4.5vw, 34px) var(--cpr-ink);
}
.cpr__glow--breath {
  box-shadow: inset 0 0 clamp(80px, 22vw, 170px) clamp(24px, 7vw, 52px) var(--cpr-breath);
}

.cpr--on .cpr__glow--push { animation: fmglow var(--beat, .545s) linear var(--beats, 30); }
.cpr--on .cpr__glow--breath { animation: fmbreath var(--breath, 6s) linear 1; }

@keyframes fmglow {
  0% { opacity: 1; }
  55% { opacity: .05; }
  100% { opacity: 0; }
}

@keyframes fmbreath {
  0%, 6% { opacity: 0; }
  22% { opacity: 1; }
  42% { opacity: 0; }
  60% { opacity: 1; }
  78%, 100% { opacity: 0; }
}

/* Reduced motion still needs a beat — that is the whole point of the screen.
 * The glow moves nothing; it is a brightness change already, so it keeps its
 * tempo and its count where the global rule would freeze it. */
@media (prefers-reduced-motion: reduce) {
  .cpr--on .cpr__glow--push { animation: fmglow var(--beat, .545s) linear var(--beats, 30) !important; }
  .cpr--on .cpr__glow--breath { animation: fmbreath var(--breath, 6s) linear 1 !important; }
}

.cpr__top { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.cpr__lab { font: 700 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .12em; color: var(--cpr-label); }
.cpr__t { font-size: 30px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.cpr__bpm { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.cpr__right { text-align: right; }

.cpr__stage {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 0;
  text-align: center;
}
.cpr__cue {
  min-height: 1.4em;
  font: 700 15px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--cpr-label);
}
.cpr__word {
  min-height: 1em;
  font-size: clamp(60px, 18vw, 96px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
}
.cpr__word--breath { color: var(--cpr-breath); }
.cpr__fig { width: min(240px, 62vw); }
.cpr__fig .puppet { margin: 0; padding: 0; max-width: none; background: transparent; }
.cpr__line { font-size: 17px; line-height: 1.4; color: var(--cpr-dim); max-width: 34rem; }

.cpr__panel { background: var(--cpr-panel); border-radius: 16px; padding: 14px 16px; margin: 0 0 10px; }
.cpr__panelt { font-size: 19px; font-weight: 700; }
.cpr__paneln { font-size: 15px; color: var(--cpr-dim); margin-top: 4px; }

.cpr__acts { display: flex; gap: 8px; }
.cpr__mode { flex: 1 1 auto; display: flex; gap: 6px; }

.cpr__opt,
.cpr__btn {
  min-height: 64px;
  padding: 8px 6px;
  text-align: center;
  background: var(--cpr-btn);
  color: var(--cpr-ink);
  border: 2px solid transparent;
  border-radius: 12px;
  font: inherit;
  font-size: 17px;
  font-weight: 650;
  text-decoration: none;
  cursor: pointer;
}
.cpr__opt { flex: 1 1 0; }
.cpr__opt.is-on { border-color: var(--cpr-ink); }
.cpr__btn { flex: 0 0 auto; min-width: 84px; }
.cpr__opt small, .cpr__btn small { display: block; font-size: 12px; font-weight: 400; color: var(--cpr-dim); }
.cpr :focus-visible { outline-color: var(--cpr-ink); }


/* ---------- observations, read aloud ---------- */

.round__said { background: var(--surface-2); border-radius: 14px; padding: 14px 16px; margin: 0 0 14px; }
.round__lab { font: 700 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .12em; text-transform: uppercase; color: var(--text-dim); }
.round__q { font-size: 21px; font-weight: 600; line-height: 1.25; margin-top: 4px; }
.round__bars[hidden] { display: none; }
.round__bars { display: flex; align-items: flex-end; justify-content: center; gap: 6px; height: 40px; margin: 0 0 8px; }
.round__bar { width: 8px; height: 100%; background: var(--text); border-radius: 4px; transform-origin: bottom; }
.round--listening .round__bar { animation: fmlisten .5s ease-in-out infinite alternate; }
.round__bar:nth-child(2) { animation-duration: .62s; }
.round__bar:nth-child(3) { animation-duration: .43s; }
.round__bar:nth-child(4) { animation-duration: .55s; }
.round__bar:nth-child(5) { animation-duration: .47s; }

@keyframes fmlisten { 0% { transform: scaleY(.3); } 100% { transform: scaleY(1); } }

.round__heard { border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; margin: 0 0 12px; background: var(--surface); }
.round__heardv { font-size: 17px; font-weight: 600; margin: 4px 0 10px; }
.round__acts { display: flex; flex-wrap: wrap; gap: 8px; }
.round__acts .btn { flex: 1 1 auto; text-align: center; }
.round__step { font-size: 13px; color: var(--text-dim); margin: 0 0 10px; }

.sign--none {
  font-size: 15px;
  color: var(--amber-ink);
  background: var(--amber-wash);
  padding: 12px 16px;
  border-radius: var(--radius);
  list-style: none;
}

/* ---------- print ----------
 *
 * @page is A5 with an 8 mm margin, so each .a5__page has 132 x 194 mm to fill
 * and breaks after itself. The data QR is 48 mm: at version 20 that keeps a
 * module above half a millimetre, which is what a phone camera needs off
 * laminated paper. The plain app-link QR is a much smaller code and prints at
 * 26 mm.
 */
@media print {
  @page { size: A5; margin: 8mm; }
  body { background: #fff; color: #000; font-size: 11pt; }
  /* Scoped to the page's own chrome. `header` on its own also matched the
   * black bar at the top of the A5 card, and printed a sheet with no title
   * on it — which is exactly the failure this stylesheet exists to prevent. */
  .call, .foot, .no-print, body > header, body > footer, body > nav { display: none !important; }
  body.inner main { padding: 0; }
  main { padding: 0; }
  .wrap { max-width: none; padding: 0; }
  a { text-decoration: none; color: #000; }

  .a5 { display: block; gap: 0; }

  .a5__page {
    width: 132mm;
    height: 194mm;
    padding: 0;
    border: 0;
    border-radius: 0;
    page-break-after: always;
    break-after: page;
    page-break-inside: avoid;
    break-inside: avoid;
    display: flex;
    flex-direction: column;
  }

  .a5__page:last-child { page-break-after: auto; break-after: auto; }
  .a5__bottom { margin-top: auto; }
  .a5__prov { margin-top: 3mm; }
  .a5__qr svg { width: 48mm; height: 48mm; }
  .a5__qr--link svg { width: 26mm; height: 26mm; }
}

/* ---------- the puppets ----------
 *
 * Line figures under a step, drawn in web/puppets.js and moved here. Ink
 * follows the page; water and breath are the one blue in the palette; nothing
 * is red, and emphasis is weight, halo and the callout ring rather than hue.
 * Every movement is a transform or an opacity on an SVG group with its own
 * origin, so the browser composites it, and the CPR figures take their tempo
 * from the same --beat and --breath as the glow.
 *
 * THE RULE THAT IS NOT A PREFERENCE: no base `opacity: 0`, ever. The global
 * reduced-motion rule above does not switch animations off — it sets them to
 * 0.01ms, and with the default fill-mode every element then snaps back to its
 * *base* style. Anything that starts invisible and animates up is invisible
 * to a reader with reduced motion on. That shipped once (the splint's
 * fingertip check) and tools/audit.py now fails the build on it. An animation
 * may only move or dim something that is already fully drawn. */
.puppet {
  --pp-r: var(--text);
  --pp-c: var(--text-dim);
  --pp-o: var(--text-dim);
  --pp-w: var(--sel-ink);
  --pp-bg: var(--surface);
  margin: 10px 0 0;
  max-width: 330px;
  padding: 4px 10px;
  background: var(--pp-bg);
  border-radius: 12px;
}
.puppet svg { display: block; width: 100%; height: auto; }
.puppet g, .puppet path, .puppet circle, .puppet rect, .puppet ellipse { transform-box: view-box; }
.pp-r { color: var(--pp-r); }
.pp-c { color: var(--pp-c); }
.pp-o { color: var(--pp-o); }
.pp-w { color: var(--pp-w); }
.pp-halo { color: var(--pp-bg); }
.pp-g { color: var(--pp-o); opacity: .62; }
.cpr .puppet { --pp-r: var(--cpr-ink); --pp-c: var(--cpr-dim); --pp-o: var(--cpr-label); --pp-w: var(--cpr-breath); --pp-bg: var(--cpr-bg); }

/* The callout ring: the same mark on the spot in the wide view and around it
 * in the close-up, so two panels read as one picture. Never invisible. */
.pp-spot { color: var(--pp-r); opacity: .5; }
.pp-spot--on { animation: ppSpot 2.6s ease-in-out infinite; }
@keyframes ppSpot { 0%, 100% { opacity: .42; transform: scale(1); } 50% { opacity: .95; transform: scale(1.08); } }

/* Compressions: the rescuer rocks and the chest goes down and comes all the
 * way back up, both on the beat, with a dwell at full height — the dwell is
 * how a drawing says "all the way". */
.pp-lean { animation: ppLean var(--beat, .545s) ease-in-out infinite; }
@keyframes ppLean { 0% { transform: rotate(-6deg); } 42% { transform: rotate(0deg); } 78%, 100% { transform: rotate(-6deg); } }
.pp-recoil { animation: ppRecoil var(--beat, .545s) ease-in-out infinite; }
@keyframes ppRecoil { 0% { transform: scaleY(1); } 42% { transform: scaleY(.55); } 78%, 100% { transform: scaleY(1); } }

/* Breaths: the head is tilted in the still picture and stays tilted for most
 * of the cycle; the chest rises twice. */
.pp-tilt { transform: rotate(12deg); animation: ppTilt var(--breath, 3s) ease-in-out infinite; }
@keyframes ppTilt { 0% { transform: rotate(2deg); } 14%, 86% { transform: rotate(12deg); } 100% { transform: rotate(2deg); } }
.pp-rise { animation: ppRise var(--breath, 3s) ease-in-out infinite; }
@keyframes ppRise {
  0%, 6% { transform: scaleY(1); }
  22% { transform: scaleY(1.5); }
  42% { transform: scaleY(1); }
  58% { transform: scaleY(1.5); }
  76%, 100% { transform: scaleY(1); }
}

.pp-press { animation: ppPress 1.7s ease-in-out infinite; }
@keyframes ppPress { 0%, 100% { transform: rotate(-2deg); } 50% { transform: rotate(-5deg); } }

/* The recovery strip: three complete panels, lit in turn. Base is full
 * strength, so a frozen figure shows all three equally. */
.pp-seq1, .pp-seq2, .pp-seq3 { animation: 6s ease-in-out infinite; }
.pp-seq1 { animation-name: ppSeq1; }
.pp-seq2 { animation-name: ppSeq2; }
.pp-seq3 { animation-name: ppSeq3; }
@keyframes ppSeq1 { 0%, 26% { opacity: 1; } 34%, 100% { opacity: .62; } }
@keyframes ppSeq2 { 0%, 26% { opacity: .62; } 34%, 59% { opacity: 1; } 67%, 100% { opacity: .62; } }
@keyframes ppSeq3 { 0%, 59% { opacity: .62; } 67%, 92% { opacity: 1; } 100% { opacity: .62; } }

.pp-flow { animation: ppFlow .9s linear infinite; }
@keyframes ppFlow { to { stroke-dashoffset: -16; } }
.pp-flowback { animation: ppFlowBack 1.2s linear infinite; }
@keyframes ppFlowBack { to { stroke-dashoffset: 16; } }
.pp-drop { animation: ppDrop 1.2s ease-in infinite; }
@keyframes ppDrop { 0% { transform: translateY(0); opacity: 0; } 20% { opacity: 1; } 100% { transform: translateY(12px); opacity: 0; } }
/* The ring closes once, slowly, while the water keeps running: a set time,
 * all of it, without a numeral. The card carries the number. */
.pp-clock { stroke-dasharray: 113.1; animation: ppClock 6s linear infinite; }
@keyframes ppClock { from { stroke-dashoffset: 113.1; } to { stroke-dashoffset: 0; } }

/* The splint: ties appear above and below, then the fingertips are checked.
 * The tie strokes and the fingertip ring are both fully drawn at rest. */
.pp-wrap1, .pp-wrap2, .pp-wrap3, .pp-wrap4 { animation: 5s steps(1, end) infinite; }
.pp-wrap1 { animation-name: ppWrap1; }
.pp-wrap2 { animation-name: ppWrap2; }
.pp-wrap3 { animation-name: ppWrap3; }
.pp-wrap4 { animation-name: ppWrap4; }
@keyframes ppWrap1 { 0%, 14% { opacity: 0; } 15%, 100% { opacity: 1; } }
@keyframes ppWrap2 { 0%, 29% { opacity: 0; } 30%, 100% { opacity: 1; } }
@keyframes ppWrap3 { 0%, 44% { opacity: 0; } 45%, 100% { opacity: 1; } }
@keyframes ppWrap4 { 0%, 59% { opacity: 0; } 60%, 100% { opacity: 1; } }
.pp-pulse { animation: ppPulse 2.4s ease-in-out infinite; }
@keyframes ppPulse { 0%, 100% { opacity: .45; transform: scale(.94); } 45% { opacity: 1; transform: scale(1.14); } }

/* Dressings arriving on the pile. The pad against the skin is not animated at
 * all — it is the one that does not move. */
.pp-pile2 { animation: ppPile2 5s ease-out infinite; }
.pp-pile3 { animation: ppPile3 5s ease-out infinite; }
@keyframes ppPile2 { 0%, 10% { transform: translate(14px, -46px); opacity: 0; } 26%, 100% { transform: none; opacity: 1; } }
@keyframes ppPile3 { 0%, 40% { transform: translate(14px, -46px); opacity: 0; } 56%, 100% { transform: none; opacity: 1; } }

.pp-lift { animation: ppLift 3.4s ease-in-out infinite; }
@keyframes ppLift { 0%, 16% { transform: none; } 52%, 100% { transform: translate(36px, -7px); } }
.pp-lift2 { animation: ppLift2 3.4s ease-in-out infinite; }
@keyframes ppLift2 { 0%, 16% { transform: none; } 56%, 100% { transform: translate(-14px, -22px); } }
.pp-write { animation: ppWrite 1.8s ease-in-out infinite; }
@keyframes ppWrite { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(-11deg) translateX(-6px); } }
.pp-lay { animation: ppLay 4s ease-out infinite; }
@keyframes ppLay { 0% { transform: translateY(-26px); opacity: 0; } 26%, 100% { transform: none; opacity: 1; } }
.pp-sink { animation: ppSink 3s ease-in infinite; }
@keyframes ppSink { 0%, 24% { transform: none; opacity: 1; } 100% { transform: translateY(28px); opacity: 0; } }
.pp-inflate { animation: ppInflate 3s ease-in-out infinite; }
@keyframes ppInflate { 0%, 100% { transform: scaleY(.7); } 50% { transform: scaleY(1.25); } }
.pp-peel { animation: ppPeel 4.5s ease-in-out infinite; }
@keyframes ppPeel { 0%, 20% { transform: none; } 62%, 100% { transform: translate(34px, 10px) rotate(9deg); } }

.pp-strike { animation: ppStrike 3s ease-in-out infinite; }
@keyframes ppStrike {
  0% { transform: rotate(46deg); } 8% { transform: rotate(0deg); }
  16% { transform: rotate(46deg); } 24% { transform: rotate(0deg); }
  32% { transform: rotate(46deg); } 40% { transform: rotate(0deg); }
  48% { transform: rotate(46deg); } 56% { transform: rotate(0deg); }
  64% { transform: rotate(46deg); } 72% { transform: rotate(0deg); }
  80%, 100% { transform: rotate(46deg); }
}

.pp-slide { animation: ppSlide 5s ease-out infinite; }
@keyframes ppSlide { 0% { transform: translateX(46px); opacity: 0; } 30% { transform: translateX(0); opacity: 1; } 100% { transform: translateX(0); opacity: 1; } }
.pp-sun { animation: ppSun 3s ease-in-out infinite alternate; }
@keyframes ppSun { from { transform: scale(.92); } to { transform: scale(1.06); } }
.pp-fan { animation: ppFan 1.1s ease-in-out infinite alternate; }
@keyframes ppFan { from { transform: rotate(-25deg); } to { transform: rotate(25deg); } }
.pp-rock { animation: ppRock 4s ease-in-out infinite alternate; }
@keyframes ppRock { from { transform: rotate(-3deg); } to { transform: rotate(3deg); } }
.pp-wave { animation: ppWave 2s linear infinite; }
@keyframes ppWave { to { transform: translateX(-25px); } }
.pp-puff { animation: ppPuff 1.8s ease-out infinite; }
@keyframes ppPuff { 0% { transform: translateX(0); opacity: 0; } 30% { opacity: 1; } 100% { transform: translateX(-16px); opacity: 0; } }
.pp-steam { animation: ppSteam 2.4s ease-out infinite; }
@keyframes ppSteam { 0% { transform: translateY(0); opacity: 0; } 30% { opacity: .9; } 100% { transform: translateY(-14px); opacity: 0; } }

/* ---------- right to left ----------
 *
 * Arabic and Dhivehi (Thaana) read right to left. Most of this interface is
 * flex and grid, which mirror themselves once `dir` is set on the document,
 * and the physical `text-align: right` rules above are now logical, so they
 * mirror too. What is left is the handful of places where a glyph or an inset
 * carries the direction in its own shape.
 *
 * Not mirrored, deliberately: a phone number, which is dialled left to right
 * in every script and is marked so the bidi algorithm cannot reorder it; the
 * numerals in a time stamp; and the beat animation, which has no handedness.
 */
[dir="rtl"] .back::before { content: "→ "; }
[dir="rtl"] .back { direction: rtl; }
[dir="rtl"] .loc__main::before { content: ""; }
[dir="rtl"] .loc__main::after { content: " ⌖"; color: var(--text-dim); }
[dir="rtl"] .lang summary::before { content: "◂ "; }
[dir="rtl"] .lang[open] summary::before { content: "▾ "; }

/* A number stays a number. `unicode-bidi: isolate` stops a leading + or a
 * trailing country name from dragging the digits into the wrong order, which
 * is the failure that makes a hotline unreadable rather than merely ugly. */
.tel__num, .trip__row b, .geo__pos, .cpr__t, .obs__stamp {
  unicode-bidi: isolate;
  direction: ltr;
}

/* Thai has no spaces between words, so a long label wraps mid-word unless the
 * browser is told the language; Thaana and Arabic want a face that actually
 * has the glyphs. Both are system fonts on iOS and Android — nothing is
 * downloaded, and if a device lacks the face the text falls back rather than
 * failing. Measured on a device before either is promised (OBLIGATIONS). */
:lang(th) { line-break: loose; word-break: normal; }
:lang(ar), :lang(dv) { font-size-adjust: none; }
