/* PSM Made Easy
 *
 * Mobile first, because almost every reader is on an Android phone on Indian
 * mobile data. No web fonts: the system stack renders Devanagari correctly on
 * every platform that matters here and costs nothing to download.
 */

:root {
  --ink: #16202b;
  --muted: #5a6b7a;
  --rule: #dfe5ea;
  --rule-soft: #eef2f5;
  --ground: #ffffff;
  --panel: #f7f9fa;
  --accent: #0b6a5b;
  --accent-ink: #085447;
  --measure: 38rem;

  /* The reading measure stays 38rem at every screen size, because ~70
     characters a line is what makes her prose readable and widening body text
     makes it worse. But the things that are NOT prose -- the 31 rebuilt
     statistical tables, the formulas, images up to 4000px wide -- were capped
     at the same 608px on a 1900px screen, with the rest of the display empty.
     The table rebuild was the largest content job in this migration; rendering
     a contingency table into a phone-sized box on a laptop wastes it. */
  --measure-wide: 54rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e6edf1;
    --muted: #94a5af;
    --rule: #26333a;
    --rule-soft: #1b242a;
    --ground: #0f1518;
    --panel: #151d22;
    --accent: #4fbfa8;
    --accent-ink: #7fd4c2;
  }
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans",
    "Noto Sans Devanagari", sans-serif;
  font-size: 1.0625rem;
  line-height: 1.65;
}

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

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 0.5rem;
  top: 0.5rem;
  z-index: 10;
  background: var(--accent);
  color: #fff;
  padding: 0.5rem 0.9rem;
  border-radius: 3px;
}

a { color: var(--accent-ink); }
a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- header */

header.site {
  border-bottom: 1px solid var(--rule);
  background: var(--panel);
}
header.site .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}
.brand {
  font-weight: 700;
  font-size: 1.05rem;
  text-decoration: none;
  color: var(--ink);
}
header.site nav {
  display: flex;
  gap: 1rem;
  margin-left: auto;
  font-size: 0.95rem;
}

/* ------------------------------------------------------------------ type */

main { padding: 1.6rem 1.1rem 3.5rem; }

h1 {
  font-size: 1.65rem;
  line-height: 1.2;
  margin: 0 0 0.6rem;
  text-wrap: balance;
}
h2 {
  font-size: 1.2rem;
  line-height: 1.3;
  margin: 2rem 0 0.6rem;
  text-wrap: balance;
}
h3 { font-size: 1.05rem; margin: 1.5rem 0 0.4rem; }

p { margin: 0 0 1rem; }
.muted { color: var(--muted); font-size: 0.95rem; }
.lede { font-size: 1.12rem; color: var(--muted); }

/* ------------------------------------------------------------------ post */

.post .cats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 1.4rem;
  padding: 0;
}
.post .cats a {
  font-size: 0.8rem;
  text-decoration: none;
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0.15rem 0.5rem;
  color: var(--muted);
}

.prose ul { padding-left: 1.15rem; margin: 0 0 1rem; }
.prose li { margin-bottom: 0.3rem; }
.prose li > ul { margin-top: 0.3rem; }

/* Images are camera photos and screenshots of tables, some over 4000px wide.
   They must never push the page sideways on a phone. */
.prose img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 1.2rem 0;
  border: 1px solid var(--rule-soft);
  border-radius: 2px;
}

/* Any real table, once the PowerPoint tables are rebuilt as text, scrolls
   inside its own box rather than breaking the page. */
.prose table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.92rem;
  font-variant-numeric: tabular-nums;
}
.prose table th,
.prose table td {
  border: 1px solid var(--rule);
  padding: 0.4rem 0.55rem;
  text-align: left;
}
.prose table thead th { background: var(--rule-soft); }

/* A formula inside a table cell compounds two reductions: the table's own
   0.92rem, and then the browser's smaller script level for the halves of a
   fraction. On the chi-square notes that left (8.1)^2 / 285.9 at roughly
   nine pixels on a phone, which is the size of a footnote and not of the
   arithmetic the page is teaching. Put the cell back to full size and let
   the fraction shrink from there. */
.prose table math { font-size: 1.15rem; }
.prose table td:has(> math) { padding: 0.5rem 0.55rem; }

.prose > p > a,
.prose a { overflow-wrap: anywhere; }

/* --------------------------------------------------------------- listings */

.hero { padding: 0.5rem 0 1.5rem; }

.panel {
  border-top: 1px solid var(--rule);
  padding-top: 1.4rem;
  margin-top: 1.8rem;
}

ul.list, ul.topics {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
}
ul.list li, ul.topics li {
  border-bottom: 1px solid var(--rule-soft);
  padding: 0.6rem 0;
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
}
ul.list a, ul.topics a { text-decoration: none; }
ul.list a:hover, ul.topics a:hover { text-decoration: underline; }

.count, .tag {
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--muted);
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0 0.4rem;
  white-space: nowrap;
}

.more { font-weight: 600; text-decoration: none; }
.more:hover { text-decoration: underline; }

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

footer.site {
  border-top: 1px solid var(--rule);
  background: var(--panel);
  padding: 1.4rem 0;
  font-size: 0.92rem;
}
footer.site p { margin: 0 0 0.3rem; }

/* ------------------------------------------------------------- wider view */

@media (min-width: 46rem) {
  body { font-size: 1.09rem; }
  h1 { font-size: 2rem; }
  main { padding-top: 2.2rem; }
}

/* Wide content breaks out of the reading column once there is room for it.
   Nothing below 62rem is touched, so phones -- most of her readers -- see
   exactly what they saw before.

   The breakout is done on the element rather than on its paragraph: 114 of
   the images sit inside a <p>, and widening the paragraph would stretch its
   text to match. margin-left:50% plus translate:-50% centres an element on
   the column it is overflowing, without needing a wrapper the export does
   not emit. */
@media (min-width: 62rem) {
  .prose > table,
  .prose > figure,
  .prose > details {
    width: min(var(--measure-wide), calc(100vw - 3rem));
    margin-left: 50%;
    translate: -50% 0;
  }

  /* An image keeps its own size and is only allowed to grow: max-content
     means a 300px diagram stays 300px rather than being stretched to fill
     the new width. */
  .prose > img,
  .prose > p > img,
  .prose > details img {
    width: max-content;
    max-width: min(var(--measure-wide), calc(100vw - 3rem));
    margin-left: 50%;
    translate: -50% 0;
  }
}

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

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

form.search {
  display: flex;
  gap: 0.5rem;
  margin: 0 0 1rem;
}
form.search input {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 0.55rem 0.7rem;
}
form.search input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
form.search button {
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 3px;
  padding: 0.55rem 0.9rem;
}

li.result { align-items: flex-start; }
li.result .excerpt {
  margin: 0.15rem 0 0;
  font-size: 0.92rem;
  color: var(--muted);
}
/* Pagefind wraps matched terms in <mark>. The default yellow is unreadable
   on the dark ground, so both themes get an explicit pair. */
li.result mark {
  background: transparent;
  color: var(--ink);
  font-weight: 600;
}

/* --------------------------------------------------------------- related */

/* Suggested reading, generated at build time. Set apart from the post so it
   reads as navigation rather than as more of the author's text. */
.related {
  border-top: 1px solid var(--rule);
  margin-top: 2.5rem;
  padding-top: 0.6rem;
}
.related h2 {
  font-size: 1rem;
  margin: 0.6rem 0 0.2rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
}
.related .note {
  font-size: 0.82rem;
  margin: 0.6rem 0 0;
}

/* --------------------------------------------------------------- staging */

/* Only rendered when SITE_ENV is not "production". Nobody should ever be
   confused about whether they are looking at the live site. */
.staging-banner {
  margin: 0;
  padding: 0.5rem 1.1rem;
  background: #8a5a00;
  color: #fff;
  font-size: 0.88rem;
  text-align: center;
}

/* ------------------------------------------------------ date and currency */

/* Quiet by design. It answers "how old is this" for a reader who thinks to
   ask, without implying that a note from 2016 is out of date — most of them
   are not. The ones that are get the notice below instead. */
.published {
  margin: -0.4rem 0 1rem;
  font-size: 0.82rem;
  color: var(--muted);
}

/* Loud by design, and there are exactly two of them. A superseded vaccine
   schedule read as current is a clinical problem, so this sits above the body
   and is the first thing after the title. */
.superseded {
  margin: 0 0 1.3rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--accent);
  border-left-width: 4px;
  border-radius: 3px;
  background: var(--rule-soft);
  font-size: 0.92rem;
}
.superseded a { font-weight: 600; }

/* ----------------------------------------------------------------- video */

/* A click-to-play facade, not an iframe. The page shows a local thumbnail and
   creates the YouTube player only when someone presses it, so nothing reaches
   Google until a reader chooses to watch and the page stays light on a phone. */
figure.video {
  margin: 1.4rem 0;
  padding: 0;
}
.video-play {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: #000;
  cursor: pointer;
  position: relative;
  line-height: 0;
  overflow: hidden;
}
.video-play img {
  width: 100%;
  height: auto;
  display: block;
  opacity: 0.86;
  transition: opacity 0.15s;
}
/* A card for a video that has no local thumbnail yet -- anything added after
   the migration, until videos.py is run again. The alternative was to pull the
   thumbnail from YouTube, which would contact Google on page load and undo the
   only reason this is a facade. The parent sets line-height: 0 for the image
   case, so text needs its own back. */
.video-name {
  display: block;
  line-height: 1.4;
  /* Clears the play triangle, which is centred by .video-play::before and
     ::after. At 3.2rem the caption sat behind the circle. */
  padding: 6.5rem 1.2rem 1.6rem;
  color: #fff;
  font-size: 1rem;
  text-align: center;
  text-wrap: balance;
}
.video-play:hover img,
.video-play:focus-visible img { opacity: 1; }
.video-play:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* The play triangle, drawn rather than loaded: one less request, and it
   inherits colour instead of shipping two versions for light and dark. */
.video-play::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 4.2rem; height: 4.2rem;
  margin: -2.1rem 0 0 -2.1rem;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.62);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
}
.video-play::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  z-index: 1;
  margin: -0.75rem 0 0 -0.4rem;
  border-style: solid;
  border-width: 0.75rem 0 0.75rem 1.25rem;
  border-color: transparent transparent transparent #fff;
}
figure.video figcaption {
  margin-top: 0.45rem;
  font-size: 0.9rem;
  color: var(--muted);
  line-height: 1.45;
}
figure.video figcaption a { color: var(--accent-ink); }
/* Once pressed, the real player replaces the button in the same box. */
figure.video iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 1px solid var(--rule);
  border-radius: 3px;
}

/* ------------------------------------------------------------ language */

/* Shown only on pages that exist in both languages. Above the body, because
   it answers "should I read this page at all". */
.langswitch {
  margin: 0 0 1.3rem;
  padding: 0.45rem 0.75rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 2px;
  background: var(--panel);
  font-size: 0.92rem;
}
.langswitch a { text-decoration: none; }
.langswitch a:hover { text-decoration: underline; }

/* ------------------------------------------------------------------ print */

/* Medical students print notes to revise from. Without this they get the nav,
   the related block, the language switch and a wall of adverts, and the links
   arrive as blue underlines pointing nowhere. */
@media print {
  :root {
    --ink: #000; --muted: #444; --rule: #999; --rule-soft: #ccc;
    --ground: #fff; --panel: #fff; --accent: #000; --accent-ink: #000;
  }
  body { font-size: 11pt; line-height: 1.45; background: #fff; color: #000; }
  main { padding: 0; }
  .wrap { max-width: none; padding: 0; }

  /* Navigation, suggestions and adverts are not part of the note. */
  header.site, footer.site, nav.related, .langswitch, .skip,
  .staging-banner, form.search, ins.adsbygoogle, iframe { display: none; }

  /* The collapsed original images stay collapsed rather than printing a
     duplicate of every table. */
  details { display: none; }

  h1 { font-size: 18pt; margin: 0 0 0.4rem; }
  h2 { font-size: 13pt; margin: 1rem 0 0.3rem; }

  /* Keep a table on one page where it fits; a chi-square worked example split
     across a page break is unreadable. */
  table, figure, .video { page-break-inside: avoid; break-inside: avoid; }
  h1, h2, h3 { page-break-after: avoid; break-after: avoid; }
  img { max-width: 100% !important; page-break-inside: avoid; }

  /* A printed link is dead paper unless it says where it goes. Internal ones
     are expanded to the full address; the reader has no browser to hover. */
  .prose a[href^="http"]::after { content: " (" attr(href) ")"; }
  .prose a[href^="/"]::after { content: " (ihatepsm.com" attr(href) ")"; }
  .prose a::after { font-size: 9pt; color: #555; word-break: break-all; }
  .prose a { text-decoration: none; color: #000; }

  /* The video facade is a button around a thumbnail; on paper it should be
     the address of the lecture, not a screenshot of a slide. */
  figure.video .video-play { display: none; }
  figure.video figcaption { font-size: 10pt; }

  @page { margin: 1.6cm; }
}
