/* subscribe.css — the pricing page, and the only stylesheet it loads.
 *
 * WHY NOT app.css
 *
 * app.css is 236 KB: the whole terminal, its grid, its story rail, its charts.
 * Every other page pays that because every other page IS the terminal. This
 * one is the commercial front door — the first thing a stranger loads, on a
 * phone, from a link — and 236 KB of terminal CSS to draw three cards is the
 * kind of cost that shows up as a bounce, not as a bug.
 *
 * THE TOKENS BELOW ARE A MIRROR, NOT A FORK. They are copied from app.css's
 * :root and [data-theme="light"] blocks so this page is the same product to
 * look at. A copy can drift, so build/test_subscribe.py parses BOTH files and
 * fails if any mirrored value stops matching. Change a colour in app.css and
 * that test tells you this file needs the same edit — which is the whole
 * reason the mirror is allowed to exist.
 */

/* theme.js writes ◑ / ◐ (U+25D1 / U+25D0) into the theme button. Those live in
   the self-hosted Noto subset, and this page does not load app.css where the
   face is declared — so without this the glyph falls back to whatever the
   system has, which is exactly the trap assets/fonts/README.md documents. */
@font-face {
  font-family: "AXIOM Symbols";
  src: url("fonts/sym-noto.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+25B4, U+25B8, U+25BE, U+25D0, U+25D1, U+26A1, U+2715, U+270D;
}

:root {
  --bg:        #0A2032;
  --bg2:       #081B2B;
  --panel:     #0E2A3D;
  --panel2:    #13314A;
  --field:     #163952;
  --grid:      #1B374F;
  --grid-soft: #163045;
  --text:      #E9F1F8;
  --text-dim:  #A9BDCD;
  --faint:     #7A93A6;
  --brand:     #4D9BE0;
  --brand-l:   #5BA6E8;
  --brand-d:   #1D6BB4;
  --cont:      #D8944A;
  --up:        #1f9d6b;
  --up-l:      #3ec78f;
  --save-fg:   #3ec78f;   /* page-local, see .save */
  --footer:    #071521;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --sans: "Inter", "AXIOM Symbols", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
}

[data-theme="light"] {
  --bg:        #FFFFFF;
  --bg2:       #F2F5F8;
  --panel:     #F2F5F8;
  --panel2:    #E6F1FB;
  --field:     #FFFFFF;
  --grid:      #D8E0E8;
  --grid-soft: #E9EEF3;
  --text:      #0A2032;
  --text-dim:  #5B6B7A;
  --faint:     #547392;
  --brand:     #2F6FAE;
  --brand-l:   #2F6FAE;
  --brand-d:   #1D6BB4;
  --cont:      #B06A1E;
  --up:        #1f9d6b;
  --up-l:      #178a5d;
  --save-fg:   #16865a;   /* page-local, see .save */
  --footer:    #F2F5F8;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--brand); }
img { max-width: 100%; }

/* Focus is never removed, only restyled. Half this page is keyboard-operable
   controls (a toggle, eight CTAs, nine FAQ rows) and an invisible focus ring
   makes all of it unusable without a mouse. */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; }

/* ---- top bar ------------------------------------------------------------ */
.nav {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 20px 0 8px;
}
.nav-mark {
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--text);
  text-decoration: none; line-height: 1.3;
}
.nav-mark span { color: var(--brand); }
.nav-right { display: flex; align-items: center; gap: 8px; }
.nav-a {
  font-size: 13.5px; color: var(--text-dim); text-decoration: none;
  padding: 8px 12px; border-radius: 8px;
}
.nav-a:hover { color: var(--text); background: var(--panel); }
.nav-btn {
  font: inherit; font-size: 13.5px; cursor: pointer;
  padding: 8px 12px; border-radius: 8px;
  border: 1px solid var(--grid); background: transparent; color: var(--text-dim);
}
.nav-btn:hover { color: var(--text); border-color: var(--faint); }

/* ---- hero --------------------------------------------------------------- */
.hero { text-align: center; padding: 56px 0 8px; }
.eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--faint); margin: 0 0 18px;
}
.h1 {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(34px, 6.2vw, 58px); line-height: 1.08;
  letter-spacing: -.02em; margin: 0 0 18px;
}
.lede {
  font-size: clamp(16px, 2.1vw, 19px); color: var(--text-dim);
  max-width: 42ch; margin: 0 auto; line-height: 1.5;
}
.lede b { color: var(--text); font-weight: 600; }

/* ---- hero sub ----------------------------------------------------------- */
/* The segmented monthly/annual control that used to sit here is gone: with
   Monthly and Annual as their own cards, a toggle would have been a second way
   to ask a question the cards already answer — and it hid the annual saving
   behind a click instead of standing it next to the monthly price. */
.hero-sub {
  text-align: center; font-size: 13px; color: var(--faint);
  margin: 16px auto 30px; max-width: 46ch;
}

/* ---- plan cards --------------------------------------------------------- */
.plans {
  display: grid; gap: 18px; padding: 4px 0 8px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
}
/* FIVE ACROSS needs more room than the 1120px the prose is set at, so the
   pricing block alone breaks out to 1320. Cards narrower than ~230px turn
   every bullet into four lines and the row stops being scannable, which is
   the only job it has. Detail lives in the comparison table below. */
/* The breakout itself, shared: Enterprise Plus sits directly under the row and
   has to line up with it. Measured before this was factored out — the cards
   ran to 1320 and the band stopped at 1072, so the tier that is meant to read
   as the widest one was visibly the narrowest thing on the screen. */
.plans--four, .eplus {
  max-width: 1320px; width: calc(100vw - 48px);
  margin-left: 50%; transform: translateX(-50%);
}
.plans--four {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}
.plans--four .plan { padding: 22px 18px 20px; border-radius: 14px; }
.plans--four .plan-num { font-size: 32px; }
.plans--four .plan-num.is-word { font-size: 21px; }
.plans--four .plan-for { font-size: 13px; min-height: 54px; }
.plans--four .plan-list li { font-size: 13.5px; }
.plans--four .plan-cta { font-size: 13.5px; padding: 11px 12px; }
.plan {
  position: relative; display: flex; flex-direction: column;
  background: var(--bg); border: 1px solid var(--grid);
  border-radius: 16px; padding: 26px 24px 24px;
}
/* The recommended plan is the one being sold, so it is the one that looks
   sold: brand border, a tint, and it does not move on hover — a card that
   jumps under the cursor is a card you can miss when you click. */
.plan.is-pick {
  border-color: var(--brand); background: var(--panel);
  box-shadow: 0 0 0 1px var(--brand);
}
.plan-tag {
  position: absolute; top: -11px; left: 24px;
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: #fff; background: var(--brand-d);
  padding: 4px 10px; border-radius: 999px;
}
.plan-name { font-size: 17px; font-weight: 700; margin: 0 0 4px; letter-spacing: -.01em; }
.plan-for { font-size: 13.5px; color: var(--text-dim); margin: 0 0 20px; min-height: 40px; }
.plan-cost { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.plan-num {
  font-family: var(--mono); font-size: 40px; font-weight: 600;
  letter-spacing: -.03em; line-height: 1;
}
/* A word in the price slot ("Free", "Let's talk") set at the numeric size
   out-shouts £15, which is the one number on the page that has to win. */
.plan-num.is-word { font-size: 27px; letter-spacing: -.01em; }
.plan-per { font-size: 13.5px; color: var(--text-dim); }
.plan-fx {
  font-family: var(--mono); font-size: 12px; color: var(--faint);
  margin: 9px 0 0; min-height: 18px;
}
.plan-bill { font-size: 12.5px; color: var(--text-dim); margin: 5px 0 0; min-height: 19px; }
.plan-cta {
  display: block; width: 100%; margin: 20px 0 18px; text-align: center;
  font: inherit; font-size: 14.5px; font-weight: 600; cursor: pointer;
  padding: 12px 16px; border-radius: 10px; text-decoration: none;
  border: 1px solid var(--grid); background: var(--bg); color: var(--text);
  transition: filter .16s ease, border-color .16s ease;
}
.plan-cta:hover { border-color: var(--faint); }
.plan-cta.is-primary {
  background: var(--brand-d); border-color: var(--brand-d); color: #fff;
}
.plan-cta.is-primary:hover { filter: brightness(1.1); }
.plan-note {
  font-size: 12px; color: var(--faint); text-align: center;
  margin: -12px 0 16px; min-height: 17px;
}
.plan-inc {
  font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
  margin: 0 0 11px; padding-top: 16px; border-top: 1px solid var(--grid-soft);
}
.plan-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
/* NOT display:grid, and this cost a rebuild to notice. Under grid, every
   child of the li becomes a grid item — and so does every run of bare text
   between them. A bullet reading "The <b>ledger</b> — all <span>247</span>
   rows" is five items, not one, so a two-column track laid them out three
   rows deep and each bullet stood 117–228px tall instead of 20. Position the
   tick out of flow instead and the text stays ordinary inline text. */
.plan-list li {
  position: relative; padding-left: 26px;
  font-size: 14px; line-height: 1.42; color: var(--text-dim);
}
.plan-list b { color: var(--text); font-weight: 600; }
/* The tick is drawn, not typed. A "✓" depends on a glyph the font may not
   have — the same unicode-range trap the wire already paid for once. */
.plan-list li::before {
  content: ""; position: absolute; left: 3px; top: 6px;
  width: 11px; height: 6px;
  border-left: 2px solid var(--up); border-bottom: 2px solid var(--up);
  transform: rotate(-45deg);
}

/* ---- numbers band ------------------------------------------------------- */
.band {
  margin: 46px 0 0; padding: 26px 24px;
  background: var(--panel); border: 1px solid var(--grid); border-radius: 16px;
  display: grid; gap: 18px; grid-template-columns: repeat(3, minmax(0, 1fr));
  text-align: center;
}
.band div b {
  display: block; font-family: var(--mono); font-size: 27px; font-weight: 600;
  letter-spacing: -.02em; color: var(--text);
}
.band div span { font-size: 13px; color: var(--text-dim); }

/* ---- section furniture -------------------------------------------------- */
.sec { padding: 62px 0 0; }
.sec-h {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(24px, 3.4vw, 33px); letter-spacing: -.015em;
  margin: 0 0 8px; text-align: center;
}
.sec-p {
  font-size: 15px; color: var(--text-dim); text-align: center;
  max-width: 56ch; margin: 0 auto 26px;
}

/* ---- comparison table --------------------------------------------------- */
/* Wide content scrolls inside its own box; the page body never scrolls
   sideways, which on a phone is the difference between a table and a mess. */
.cmp-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cmp {
  width: 100%; min-width: 640px; border-collapse: collapse;
  font-size: 14px;
}
.cmp caption { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.cmp th, .cmp td { padding: 13px 14px; border-bottom: 1px solid var(--grid-soft); }
.cmp thead th {
  position: sticky; top: 0; background: var(--bg); z-index: 1;
  border-bottom: 1px solid var(--grid); text-align: center;
  font-size: 14px; font-weight: 700;
}
.cmp thead th:first-child { text-align: left; }
.cmp thead th small { display: block; font-weight: 500; font-size: 12px; color: var(--text-dim); }
.cmp tbody th {
  text-align: left; font-weight: 500; color: var(--text-dim);
  font-size: 14px;
}
.cmp tbody th b { color: var(--text); font-weight: 600; display: block; }
.cmp tbody th span { font-size: 12.5px; color: var(--faint); }
.cmp td { text-align: center; color: var(--text-dim); }
.cmp .grp th {
  font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--faint);
  padding-top: 26px; border-bottom-color: var(--grid);
}
.cmp .yes, .cmp .no { font-size: 0; }
.cmp .yes::after {
  content: ""; display: inline-block; width: 12px; height: 7px;
  border-left: 2px solid var(--up); border-bottom: 2px solid var(--up);
  transform: rotate(-45deg); vertical-align: middle;
}
/* Absence is a dash, not an empty cell: an empty cell reads as "we forgot to
   fill this in", and on a comparison table that is the wrong doubt to create. */
.cmp .no::after {
  content: ""; display: inline-block; width: 11px; height: 0;
  border-top: 2px solid var(--grid); vertical-align: middle;
}
.cmp .pick { background: var(--panel); }

/* ---- faq ---------------------------------------------------------------- */
.faq { max-width: 760px; margin: 0 auto; }
.faq details {
  border-bottom: 1px solid var(--grid-soft);
}
.faq summary {
  cursor: pointer; list-style: none; padding: 17px 34px 17px 2px;
  font-size: 15.5px; font-weight: 600; position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 6px; top: 24px;
  width: 9px; height: 9px; border-right: 2px solid var(--faint);
  border-bottom: 2px solid var(--faint); transform: rotate(45deg);
  transition: transform .18s ease;
}
.faq details[open] summary::after { transform: rotate(-135deg); top: 27px; }
.faq summary:hover { color: var(--brand); }
.faq-a {
  padding: 0 34px 19px 2px; margin: 0; font-size: 15px;
  color: var(--text-dim); max-width: 68ch;
}
.faq-a + .faq-a { padding-top: 12px; }

/* ---- closing ------------------------------------------------------------ */
.end {
  margin: 62px 0 0; padding: 44px 28px; text-align: center;
  background: var(--panel); border: 1px solid var(--grid); border-radius: 18px;
}
.end h2 { font-family: var(--serif); font-weight: 600; font-size: clamp(23px, 3.2vw, 31px); margin: 0 0 10px; letter-spacing: -.015em; }
.end p { color: var(--text-dim); margin: 0 auto 22px; max-width: 52ch; }
.end .plan-cta { display: inline-block; width: auto; min-width: 240px; margin: 0; }

/* ---- footer ------------------------------------------------------------- */
.foot {
  margin-top: 70px; padding: 30px 0 46px;
  border-top: 1px solid var(--grid); background: var(--footer);
}
.foot p { font-size: 12.5px; color: var(--faint); margin: 0 0 9px; max-width: 90ch; }
.foot a { color: var(--text-dim); }

/* ---- responsive --------------------------------------------------------- */
@media (max-width: 900px) {
  .plans { grid-template-columns: 1fr; }
  /* NO REORDERING. This used to pull the recommended card to the front on a
     phone, which is the usual advice and is wrong here: the four tiers are an
     escalation — Free, Monthly, Annual, Team — and moving Annual to the top
     broke the sequence a reader is using to work out where they fit. It also
     read as three cards plus a stray one. Operator's call, 1 Sep. */
  .plan-for, .plan-fx, .plan-bill, .plan-note { min-height: 0; }
  .hero { padding: 34px 0 4px; }
  .sec { padding: 48px 0 0; }
}
@media (max-width: 560px) {
  .wrap { padding: 0 16px; }
  .band { grid-template-columns: 1fr; gap: 22px; }
  .nav-a.is-hideable { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
@media print {
  .nav, .end, .seg { display: none; }
  body { background: #fff; color: #000; }
}

/* ---- enterprise plus ---------------------------------------------------- */
.eplus {
  /* margin-TOP only. As `margin: 26px 0 0` this reset margin-left to 0, and
     because it is declared after the shared breakout rule it won the cascade —
     leaving the band 1320px wide starting at left -496, half of it off-screen
     to the left. A shorthand quietly overwriting a longhand set elsewhere. */
  margin-top: 26px; padding: 30px 30px 28px;
  background: var(--panel); border: 1px solid var(--grid); border-radius: 18px;
  /* Brand edge down the leading side: it is a tier, not a footnote, and it has
     to read as one without borrowing the recommended card's full treatment. */
  box-shadow: inset 3px 0 0 var(--brand);
}
.eplus-in {
  display: grid; gap: 30px; align-items: start;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
}
.eplus-k {
  font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--brand);
  margin: 0 0 8px;
}
.eplus-h {
  font-family: var(--serif); font-weight: 600; margin: 0 0 10px;
  font-size: clamp(22px, 3vw, 30px); letter-spacing: -.015em;
}
.eplus-p { margin: 0; color: var(--text-dim); font-size: 15px; max-width: 54ch; }
.eplus-list { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 9px; }
.eplus-list li {
  position: relative; padding-left: 26px;
  font-size: 14px; line-height: 1.42; color: var(--text-dim);
}
.eplus-list b { color: var(--text); font-weight: 600; }
.eplus-list li::before {
  content: ""; position: absolute; left: 3px; top: 6px;
  width: 11px; height: 6px;
  border-left: 2px solid var(--brand); border-bottom: 2px solid var(--brand);
  transform: rotate(-45deg);
}
.eplus .plan-cta { margin: 0; }
.eplus-note { font-size: 12.5px; color: var(--faint); margin: 10px 0 0; text-align: center; }

/* ---- enquiry form ------------------------------------------------------- */
.enq { max-width: 780px; margin: 0 auto; }
/* Off-screen, not display:none. A hidden input is the first thing a bot skips
   and the first thing a screen reader announces; this is invisible to both and
   still filled by anything that fills every field it can find. */
.enq-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.enq-grid { display: grid; gap: 15px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.enq-f { display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; }
.enq-f > span { font-weight: 600; color: var(--text); }
.enq-f em { font-style: normal; font-weight: 400; color: var(--faint); }
.enq-wide { grid-column: 1 / -1; }
.enq-f input, .enq-f select, .enq-f textarea {
  font: inherit; font-size: 15px; color: var(--text);
  background: var(--field); border: 1px solid var(--grid);
  border-radius: 9px; padding: 11px 12px; width: 100%;
  /* iOS zooms the page on focus for anything under 16px; 15px plus the
     viewport's own scale is the line where it stops doing that. */
  min-height: 46px;
}
.enq-f textarea { min-height: 104px; resize: vertical; line-height: 1.45; }
.enq-f input:focus, .enq-f select:focus, .enq-f textarea:focus {
  border-color: var(--brand); outline: 2px solid var(--brand); outline-offset: 1px;
}
.enq-f input::placeholder, .enq-f textarea::placeholder { color: var(--faint); }
.enq-foot {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin: 20px 0 0;
}
.enq-send { width: auto; min-width: 210px; margin: 0; }
.enq-msg { font-size: 13.5px; color: var(--text-dim); margin: 0; }
.enq-msg.is-bad { color: var(--down); }
.enq-note { font-size: 12.5px; color: var(--faint); margin: 14px 0 0; max-width: 62ch; }
.enq-done { font-size: 16px; color: var(--text); margin: 0; padding: 18px 0; }

@media (max-width: 1180px) {
  .plans--four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .plans--four, .eplus { max-width: 100%; width: 100%; margin-left: 0; transform: none; }
}
@media (max-width: 860px) {
  .eplus-in { grid-template-columns: 1fr; gap: 20px; }
  .enq-grid { grid-template-columns: 1fr; }
}
@media (max-width: 700px) {
  .plans--four { grid-template-columns: 1fr; }
  .plans--four .plan-for { min-height: 0; }
  .eplus { padding: 24px 20px; }
  .enq-send { width: 100%; }
}

/* ---- redeem ------------------------------------------------------------- */
.code-form { margin-bottom: 22px; }
#codeInput {
  font-family: var(--mono); font-size: 19px; letter-spacing: .12em;
  text-transform: uppercase; max-width: 15ch;
}
/* A rule with the word on it, rather than two forms stacked with nothing
   between them saying they are alternatives. */
.or-line {
  display: flex; align-items: center; gap: 14px;
  margin: 26px auto; max-width: 780px;
  font-size: 12.5px; color: var(--faint);
}
.or-line::before, .or-line::after {
  content: ""; flex: 1; height: 1px; background: var(--grid);
}
.enq--slim { margin-bottom: 0; }
.code-key {
  font-family: var(--mono); font-size: 20px; letter-spacing: .1em;
  background: var(--field); border: 1px solid var(--grid); border-radius: 10px;
  padding: 14px 16px; margin: 14px 0; word-break: break-all; user-select: all;
}

/* ---- enterprise, the quieter of the two bands --------------------------- */
/* Same construction as Enterprise Plus so they read as a pair, one step down
   in emphasis so the order still escalates: four cards, then this, then a
   custom build. Its rail is --faint rather than --brand for that reason. */
.eplus--ent { box-shadow: inset 3px 0 0 var(--faint); margin-top: 22px; }
.eplus--ent .eplus-k { color: var(--text-dim); }
.eplus--ent .eplus-list li::before {
  border-left-color: var(--up); border-bottom-color: var(--up);
}

/* ---- the preview shots -------------------------------------------------- */
/* width/height are on every <img> so the browser reserves the box before the
   file arrives. Without them the collage collapses to nothing and then shoves
   the comparison table down as each shot lands, which on a slow connection is
   the page jumping under a reader's cursor. */
.shot { margin: 0 0 20px; }
.shot img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--grid); border-radius: 12px;
  background: var(--bg);
}
.shot figcaption {
  font-size: 13px; color: var(--text-dim); margin: 10px 2px 0; line-height: 1.5;
}
.shot figcaption b { color: var(--text); font-weight: 600; }
.shot--wide { margin-bottom: 26px; }
.shot-pair { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; }
/* The two lower shots are crops of tall pages, capped and anchored to the top —
   the interesting half of a table is always its first rows.
   
   NO FADE MASK HERE, because there is nothing left to fade. At 752px wide a
   1180x620 shot renders 396px tall against the 430px cap below, so it is not
   cropped; in two columns it is ~341 against 340, which is one pixel. The
   mid-row cut that prompted a fade came from the OLD 340px cap, and raising
   that cap removed it.

   A gradient mask WAS added for it first, and blamed for the previews
   rendering blank in a screenshot. That was wrong: the images were complete,
   opacity 1 and correctly laid out the whole time, and a forced repaint made
   them appear with no mask involved — the capture was not compositing lazily
   loaded images. Nothing here is evidence against mask-image; it simply is not
   needed. Recorded because "don't mask, it renders blank" would be false
   guidance to inherit. */
.shot-pair .shot img {
  max-height: 340px; object-fit: cover; object-position: top left;
}
@media (max-width: 800px) {
  .shot-pair { grid-template-columns: 1fr; }
  /* Stacked, they are not competing for width, so a shallower letterbox is
     just wasted detail — let them run taller. */
  .shot-pair .shot img { max-height: 430px; }
}
