/* Survey 28: the H world of build_v7.py / build_v6_info.py, ported from inline styles to classes.
   Mobile first at the 390 px artboard; desktop (>= 768 px) is the same column on white, zoomed 1.2x / 1.3x (owner 13.09).
   Tokens: NAVY #152642 · CHIP #0f1b2f · PILL #0e1520 · INK #1a1a1a · LINE #dcdcdc · PALE #f0f3f8 · EDGE #cfcfcf · MARK #949494
           DIS #ededed · COLD #4a7bd0 · HOT #d9463e · GREEN #2fbf71 · radii 24 / 12
           MUTED #4a4a4a: the board's grey (#6b6b6b) lifted to ink at 75 % for the 45+ readers (owner 13.09); placeholders keep #6b6b6b.
   Readability floor (owner 13.09, raised again after he walked staging on his phone 13.09): copy never under 18 px (was 17,
   the board's 16), headlines 28 (the board's 26), weight 500 where the board had 400, line-height 1.5 on paragraphs and on
   option rows (was 1.45 / 1.35). Montserrat is a brand lock and its x-height is short, so the compensation is size and leading,
   never the palette: the greys stay exactly as they were. The consent print is 16 (was 13). Smaller only in the header Google
   block (12 / 13, chrome, not copy).
   Motion: every keyframe of the board with its ramp and delay (--d, --dur); the board loops every 6 s for the canvas, the app plays
   the same entrance on every screen injection. Selection feedback = the board's `sel` / `fill` ramps (.45 s). */

:root {
  --navy: #152642; --chip: #0f1b2f; --pill: #0e1520; --ink: #1a1a1a; --muted: #4a4a4a; --ph: #6b6b6b; --line: #dcdcdc;
  --pale: #f0f3f8; --edge: #cfcfcf; --mark: #949494; --dis-bg: #ededed; --cold: #4a7bd0; --hot: #d9463e;
  --green: #2fbf71; --sep: rgba(0,0,0,.12); --rc: 24px; --ri: 12px;
  --bounce: cubic-bezier(.34,1.56,.64,1);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; font-family: 'Montserrat', 'Helvetica Neue', Arial, sans-serif; color: var(--ink); background: #fff;
       -webkit-font-smoothing: antialiased; font-size: 18px; line-height: 1.5; }
a { color: var(--navy); }
a:hover { color: var(--ink); }
button { font: inherit; color: inherit; }
img { display: block; max-width: 100%; }
[hidden] { display: none !important; }
/* the back chevron keeps its grid cell when hidden (screens 1 and 24), so the wordmark stays centred like the board's empty first cell */
.hdr-back[hidden] { display: flex !important; visibility: hidden; pointer-events: none; }

/* ---- page + chrome ------------------------------------------------------------------ */
.page { min-height: 100dvh; display: flex; flex-direction: column; background: #fff; overflow: hidden; }
.hdr { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 14px 24px 0; height: 58px; }
.hdr-back { width: 44px; height: 44px; margin-left: -14px; display: flex; align-items: center; justify-content: center;
            background: none; border: 0; padding: 0; border-radius: 22px; cursor: pointer; justify-self: start; }
.hdr-back:hover { background: var(--pale); }
.hdr-logo { height: 17px; width: auto; }
.hdr-rating { justify-self: end; min-height: 44px; display: flex; flex-direction: column; align-items: flex-end; justify-content: center; gap: 3px; line-height: 1; }
.hdr-rating-row { display: flex; align-items: baseline; gap: 4px; }
.hdr-g { font-size: 12px; color: var(--muted); }
.hdr-score { font-size: 13px; font-weight: 600; color: var(--ink); }
.hdr-stars { display: flex; gap: 2px; }
.hdr-stars svg { flex-shrink: 0; }

/* the bar: the board's `pf` keyframe fills from the previous value over 12 % of the 6 s loop = .72 s ease-out */
.bar { display: flex; align-items: center; gap: 6px; padding: 10px 24px 0; }
.bar-seg { width: 26px; height: 6px; border-radius: 999px; background: var(--navy); flex-shrink: 0; }
.bar-track { flex: 1; height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.bar-fill { width: 100%; height: 100%; border-radius: 999px; background: var(--navy); transform-origin: left; transform: scaleX(var(--p, 0)); transition: transform .72s ease-out; }

/* one grid cell holds the outgoing and the incoming .scr for the 260 ms of the hand-over, so they overlap instead of stacking */
.screen { display: grid; grid-template-columns: 100%; align-content: start; padding: 0 24px 24px; margin-top: 20px; flex: 1; }
.scr { grid-area: 1 / 1; align-self: start; display: flex; flex-direction: column; gap: 12px; }

.nojs { padding: 40px 24px; text-align: center; }

/* ---- type ------------------------------------------------------------------------------- */
.h1 { margin: 0; font-size: 28px; font-weight: 600; line-height: 1.25; letter-spacing: -0.01em; text-wrap: pretty; color: var(--navy); }
.h1-white { color: #fff; }
.grey { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--muted); text-wrap: pretty; }
.body { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--ink); text-wrap: pretty; }
.navy-line { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 600; color: var(--navy); }
.label { font-size: 18px; line-height: 1.4; font-weight: 600; color: var(--ink); }
.muted { color: var(--muted); }
.consent { margin: 0; font-size: 16px; line-height: 1.5; font-weight: 500; color: var(--muted); text-wrap: pretty; }
.consent a { color: var(--muted); }
.lock { display: flex; gap: 8px; align-items: flex-start; font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--muted); }
.lock .ic { flex-shrink: 0; margin-top: 3px; }
.issue { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--hot); }
/* a failed answer or a failed screen: the line she reads and the one control she taps to try again */
.notice { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.err { color: var(--hot); }
.group { display: flex; flex-direction: column; gap: 8px; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.plain { max-width: 560px; margin: 0 auto; padding: 40px 24px; display: flex; flex-direction: column; gap: 12px; }
.sep { height: 1px; background: var(--sep); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---- options (build_v7 row): 56 px rows, 72 with a tile; the ring is the board's `sel` ramp ------------- */
.opts { display: flex; flex-direction: column; gap: 8px; }
.opt { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 8px 17px; border: 1px solid var(--edge); border-radius: var(--ri);
       font-size: 18px; line-height: 1.5; color: var(--ink); background: #fff; text-align: left; width: 100%; cursor: pointer;
       font-weight: 500; -webkit-tap-highlight-color: transparent; }
.opt-slot { min-height: 72px; padding: 7px 16px 7px 7px; }
.opt.sel { border-color: var(--navy); box-shadow: inset 0 0 0 1px var(--navy); font-weight: 600; animation: sel .45s ease-out both; }
.opt:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.opt-text { flex: 1; }
.opt-sub { display: block; font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--muted); margin-top: 2px; }
.opt-thumb { width: 56px; height: 56px; border-radius: var(--ri); object-fit: cover; flex-shrink: 0; background: var(--pale); }
.opt-tile { width: 56px; height: 56px; border-radius: var(--ri); background: var(--pale); flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.opt-box { width: 22px; height: 22px; border-radius: 6px; border: 1.5px solid var(--mark); background: #fff; flex-shrink: 0;
           display: flex; align-items: center; justify-content: center; }
.opt-box .ic { opacity: 0; }
.opt.sel .opt-box { border-color: var(--navy); background: var(--navy); }
.opt.sel .opt-box .ic { opacity: 1; }

/* chips of two kinds: the dark answer chip (info screens) and the pick chip (screens 23, 24); `fill` is the board's ramp */
.chip { padding: 10px 14px; border-radius: var(--ri); background: var(--chip); color: #fff; font-size: 18px; line-height: 1.2; font-weight: 600;
        display: inline-flex; align-items: center; white-space: nowrap; flex-shrink: 0; }
.picks { display: flex; gap: 8px; flex-wrap: wrap; }
.pick { padding: 9px 13px; border: 1px solid var(--edge); border-radius: var(--ri); font-size: 18px; line-height: 1.2; display: inline-flex; align-items: center;
        white-space: nowrap; background: #fff; color: var(--ink); font-weight: 500; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pick.sel { background: var(--navy); color: #fff; border-color: var(--navy); font-weight: 600; animation: fill .45s ease-out both; }
.pick:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }

/* ---- fields ------------------------------------------------------------------------------- */
.field { min-height: 56px; width: 100%; border: 1px solid var(--edge); border-radius: var(--ri); padding: 0 17px; display: flex; align-items: center; gap: 8px;
         font: inherit; font-size: 18px; line-height: 1.4; font-weight: 500; color: var(--ink); background: #fff; margin: 0; -webkit-appearance: none; appearance: none; }
.field::placeholder { color: var(--ph); font-weight: 500; }
.field:focus, .field:focus-within { outline: none; border-color: var(--navy); box-shadow: inset 0 0 0 1px var(--navy); }
.field-select { position: relative; padding: 0; }
.field-select select { flex: 1; min-height: 54px; border: 0; background: transparent; padding: 0 44px 0 17px; font: inherit; font-size: 18px; font-weight: 500; color: var(--ink);
                       -webkit-appearance: none; appearance: none; outline: none; width: 100%; }
.field-select .ic { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); pointer-events: none; }
input[type=number].field::-webkit-outer-spin-button, input[type=number].field::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number].field { -moz-appearance: textfield; }
.head-avatar { display: flex; align-items: flex-start; gap: 12px; }
.head-avatar .h1 { flex: 1; }
.avatar62 { width: 62px; height: 62px; border-radius: 50%; overflow: hidden; flex-shrink: 0; background: var(--pale); position: relative; display: block; }
.avatar62 img { position: absolute; left: -17px; top: -10px; width: 103px; height: 103px; max-width: none; }

/* ---- slider (build_v7 slider): 12 px hot-to-cold track, 28 px white handle; the entrance travel is app.js slideIn (the board's `slide`)
   The track runs red on the left to blue on the right on both sliders (owner 13.09, walking staging); the board had it the other way. */
.slider { display: flex; flex-direction: column; gap: 8px; }
.range { -webkit-appearance: none; appearance: none; width: 100%; height: 28px; margin: 8px 0 0; background: transparent; cursor: pointer; }
.range:focus { outline: none; }
.range::-webkit-slider-runnable-track { height: 12px; border-radius: 999px; background: linear-gradient(90deg, var(--cold) 0%, var(--hot) 100%); }
.range::-moz-range-track { height: 12px; border-radius: 999px; background: linear-gradient(90deg, var(--cold) 0%, var(--hot) 100%); }
/* Screen 6 «Наскільки це вам заважає зараз?» runs cold to hot: the right anchor is the worse end.
   Screen 10 «Наскільки ви розглядаєте втручання?» is the other way round, because there the LEFT
   anchor «уникаю втручань» is the worse end. The flow file marks that one with reverse_track. */
.range-rev::-webkit-slider-runnable-track { background: linear-gradient(90deg, var(--hot) 0%, var(--cold) 100%); }
.range-rev::-moz-range-track { background: linear-gradient(90deg, var(--hot) 0%, var(--cold) 100%); }
.range::-webkit-slider-thumb { -webkit-appearance: none; width: 28px; height: 28px; margin-top: -8px; border-radius: 50%; background: #fff;
                               border: 2px solid var(--navy); box-shadow: 0 2px 6px rgba(21,38,66,.25); }
.range::-moz-range-thumb { width: 24px; height: 24px; border-radius: 50%; background: #fff; border: 2px solid var(--navy); box-shadow: 0 2px 6px rgba(21,38,66,.25); }
.range:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--navy); outline-offset: 2px; }
.anchors { display: flex; justify-content: space-between; gap: 12px; font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--muted); }

/* ---- the pill ------------------------------------------------------------------------------- */
.pill { display: flex; align-items: center; justify-content: center; gap: 8px; height: 48px; margin-top: 8px; border-radius: 999px; background: var(--pill);
        color: #fff; font-size: 18px; font-weight: 600; border: 0; width: 100%; cursor: pointer; transition: background-color .15s, color .15s, opacity .15s; }
.pill:hover { background: #1b2a44; }
.pill:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.pill[disabled] { background: var(--dis-bg); color: var(--muted); cursor: default; }
.pill.busy { opacity: .7; cursor: wait; }
/* screen 23 only (owner 13.09): the submit button is never disabled. While a required field is empty it
   carries this reddish hue instead, and a tap on it says in words which field is missing. White on #a33b34
   is 6.5:1. The board's disabled grey stays on every other screen. */
.pill.warn { background: #a33b34; }
.pill.warn:hover { background: #b5423a; }

/* ---- cards: the board's fixed heights kept as aspect ratios, so a wider column shows the same picture, only larger ----

   The button is never allowed below the fold (owner 13.09, walking staging on his phone): the picture gives up
   height before the button does. Each card keeps the board's ratio until the viewport is too short for it, and
   only then the clamp bites, so nothing changes on a tall phone. The offsets are measured, not guessed: they are
   everything the screen carries besides the card, at the 390 px artboard (520 on 20b with the longest verdict,
   299 on 24), plus the 24 px the page ends with; the narrow block below re-measures them at 320.
   `100svh` is the viewport with the browser toolbar SHOWING, which is exactly the height that has to hold the
   button, and it does not move when the toolbar retracts. `100vh` is declared first for the engines that know
   neither svh nor dvh; they get the toolbar-less height, which is the old behaviour, never worse than it.
   .portrait and .thanks-photo clamp their HEIGHT and let object-fit: cover crop, which keeps them full-bleed;
   there is no overlay on either to knock out of place.
   Screen 8 has no clamp of any kind: it is a square at the full column width, and the square is what buys
   the height its button needs (owner 13.09 on staging: «I want it to still fill up the entire width, if it
   is a square it should fit perfectly»). */
.card { border-radius: var(--rc); overflow: hidden; position: relative; }
.card-navy { background: var(--navy); color: #fff; }
.card-pale { background: var(--pale); }
.portrait { aspect-ratio: 342 / 300; min-height: 120px; max-height: calc(100vh - 520px); max-height: calc(100svh - 520px); }
.portrait img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; }
.thanks-photo { aspect-ratio: 342 / 192; min-height: 96px; max-height: calc(100vh - 299px); max-height: calc(100svh - 299px); }
.thanks-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.thanks-src { margin-top: 8px; }

/* screen 8: the 342 x 342 square window on the zone with the dashed box drawn on over 600 ms at 1.2 s, then
   the faint slow pulse. The card was 342 x 430 until 13.09: the owner asked for the original crop as a square
   at the full column width, so the photograph keeps its scale and object-fit: cover simply shows 88 px less of
   it, 44 off the top and 44 off the bottom. The dashed boxes in data/assets.json are recomputed for the shorter
   card, so every one of them still sits on the same feature of the same face. */
.zone { aspect-ratio: 1 / 1; width: 100%; }
.zone-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.zone-eyes .zone-img { inset: auto; max-width: none; object-fit: fill; }   /* placed by the inline per-cent style */
.zone-box { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.zb-draw { animation: draw .6s ease-in-out 1.2s both; }
.zb-pulse { animation: pulse 6s ease-in-out 1.8s infinite; }

/* screen 3: «1 з 3» */
.one3 { padding: 30px 24px 26px; }
.one3-num { display: flex; align-items: flex-end; gap: 12px; line-height: 1; }
.one3-roll { height: 120px; overflow: hidden; }
.one3-digits { font-size: 120px; font-weight: 600; letter-spacing: -0.05em; animation: roll .6s cubic-bezier(.3,.9,.35,1.06) .4s both; }
.one3-digits > div { height: 120px; }
.one3-of { font-size: 40px; font-weight: 500; letter-spacing: -0.02em; margin-bottom: 21px; }
.one3-faces { display: flex; gap: 14px; margin-top: 26px; padding-top: 50px; }
.one3-face { width: 56px; height: 56px; border-radius: 50%; overflow: hidden; flex-shrink: 0; position: relative; background: rgba(255,255,255,.15);
             box-shadow: 0 0 0 1.5px rgba(255,255,255,.9); display: block; }
.one3-face img { width: 100%; height: 100%; object-fit: cover; }
.one3-third { overflow: visible; }
.one3-third img { border-radius: 50%; }
.one3-third .rej { animation: reject .5s ease-in-out 1.75s both; }
.one3-chip { position: absolute; left: 50%; bottom: 64px; transform: translateX(-50%); }
.one3-line { margin: 24px 0 0; font-size: 18px; line-height: 1.5; font-weight: 500; text-wrap: pretty; }

/* screen 15: the story card */
.story { background: var(--pale); padding: 4px; }
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.shot { position: relative; aspect-ratio: 1 / 1; border-radius: var(--ri); overflow: hidden; background: var(--line); }
.shot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cap { font-size: 18px; line-height: 1.4; font-weight: 600; color: var(--muted); margin: 6px 0 0 8px; }
.facts { display: flex; flex-direction: column; gap: 8px; padding: 14px 12px 12px; }
.fact { display: flex; gap: 10px; align-items: flex-start; font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--ink); }
.fact .ic { flex-shrink: 0; margin-top: 3px; }

/* screen 16: the day rows and the growing line */
.tl { position: relative; display: flex; flex-direction: column; gap: 16px; }
.tl-line { position: absolute; left: 6px; top: 36px; bottom: 36px; width: 2px; background: var(--line); }
.tl-grow { width: 100%; height: 100%; background: var(--navy); transform-origin: top; animation: grow 1.6s ease-in-out 1s both; }
.tl-row { display: flex; align-items: center; gap: 14px; min-height: 72px; }
.tl-dotcol { width: 14px; flex-shrink: 0; display: flex; justify-content: center; }
.tl-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--navy); box-shadow: 0 0 0 3px #fff; display: block; }
.tl-text { flex: 1; }
.tl-day { font-size: 18px; line-height: 1.4; font-weight: 700; color: var(--ink); }
.tl-cap { font-size: 18px; line-height: 1.5; font-weight: 500; color: var(--muted); margin-top: 2px; }
.tl-thumb { width: 72px; height: 72px; border-radius: var(--ri); object-fit: cover; background: var(--line); flex-shrink: 0; }

/* screen 20a: the checklist card */
.loading { padding: 26px 24px 28px; min-height: 360px; }
.loading .h1 { margin-top: 22px; }
.spinner { border-radius: 50%; border: 2px solid rgba(255,255,255,.3); border-top-color: #fff; animation: spin 1s linear infinite; }
.spinner-36 { width: 36px; height: 36px; border-width: 3px; }
.checklist { display: flex; flex-direction: column; gap: 14px; margin-top: 22px; }
.check-line { display: flex; align-items: center; gap: 12px; font-size: 18px; line-height: 1.5; font-weight: 500; }
.check-line .ic { flex-shrink: 0; }
.dot-green { width: 12px; height: 12px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 4px rgba(47,191,113,.28); margin: 0 3px; flex-shrink: 0; }

/* arm A handoff page */
.handoff { max-width: 560px; margin: 0 auto; padding: 60px 24px; text-align: center; display: flex; flex-direction: column; gap: 12px; }
.handoff-text { margin: 0; font-size: 18px; color: var(--muted); }
.handoff-link { font-weight: 600; }

/* ---- motion: the board's keyframes; one entrance per element on every injection, resting after it ------------------- */
.fu { animation: fadeUp var(--dur, .45s) ease-out both; animation-delay: var(--d, 0s); }
.pop { animation: popIn var(--dur, .45s) var(--bounce) both; animation-delay: var(--d, 0s); }
.ph { animation: fadeIn .6s ease-out .2s both; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes draw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
@keyframes pulse { 0%, 32% { opacity: 1; } 52% { opacity: .78; } 72% { opacity: 1; } 92%, 100% { opacity: 1; } }
@keyframes roll { from { transform: translateY(0); } to { transform: translateY(-120px); } }
@keyframes reject { from { filter: none; opacity: 1; } to { filter: grayscale(1) brightness(.6); opacity: .85; } }
@keyframes grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes sel { from { border-color: var(--edge); box-shadow: inset 0 0 0 0 var(--navy); } to { border-color: var(--navy); box-shadow: inset 0 0 0 1px var(--navy); } }
@keyframes fill { from { background: #fff; color: var(--ink); border-color: var(--edge); } to { background: var(--navy); color: #fff; border-color: var(--navy); } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .zb-draw { stroke-dashoffset: 0; }
  .one3-digits { transform: translateY(-120px); }
  .one3-third .rej { filter: grayscale(1) brightness(.6); opacity: .85; }
  .tl-grow { transform: none; }
}

/* The next button never leaves the screen (owner, 13.09 evening): on an information screen
   that carries more than a phone holds, the button pins to the bottom of the viewport on a
   white pad and the content scrolls under it, instead of the screen's photos being shrunk.
   That is the board's own mechanism (flow-v3-mfs.md §1). Opt in per screen with
   `"sticky_button": true` in the flow, so a screen that already fits is untouched, and so the
   plastics quiz, whose data sets the flag nowhere, keeps the behaviour it has. `:has()` is the
   only part an old engine can miss, and missing it leaves today's behaviour, never worse. */
.page:has(.scr-sticky) { overflow: visible; }
.scr-sticky .pill { position: sticky; bottom: 16px; z-index: 2;
                    box-shadow: 0 10px 0 10px #fff, 0 -12px 20px 12px rgba(255, 255, 255, .92); }
/* A pinned button needs no room from the photograph, so the height clamps that buy that room
   are off here: the picture keeps its size and the content scrolls (owner 13.09: «keep the
   height adequate, you cannot even see the doctor»). */
.scr-sticky .portrait, .scr-sticky .thanks-photo, .scr-sticky .zone { max-height: none; max-width: none; }

/* ---- desktop: white, the same single column centred, everything scaled with the column
   (RemedyMeds; owner 13.09). zoom scales type, spacing and images together, so the 390 px
   layout is reproduced at 468 px (>= 768) and 507 px (>= 1200). */

/* a 320 px phone wraps one line more in the headline and in the read-back, so the same three screens
   need more room for their copy; measured the same way at 320. */
@media (max-width: 359px) {
  .portrait { max-height: calc(100vh - 604px); max-height: calc(100svh - 604px); }
  .thanks-photo { max-height: calc(100vh - 340px); max-height: calc(100svh - 340px); }
}

@media (min-width: 768px) {
  body { background: #fff; }
  .page { max-width: 390px; margin: 0 auto; zoom: 1.2; min-height: calc(100dvh / 1.2); }
  .opt:hover, .pick:hover { border-color: var(--navy); }
  .plain { padding: 60px 24px; }
  /* zoom scales the used value of every length inside the column, viewport units included, so the clamps
     have to be divided by the same factor to keep meaning the height of the real window. */
  .portrait { max-height: calc(100vh / 1.2 - 520px); max-height: calc(100svh / 1.2 - 520px); }
  .thanks-photo { max-height: calc(100vh / 1.2 - 299px); max-height: calc(100svh / 1.2 - 299px); }
}

@media (min-width: 1200px) {
  .page { zoom: 1.3; min-height: calc(100dvh / 1.3); }
  .portrait { max-height: calc(100vh / 1.3 - 520px); max-height: calc(100svh / 1.3 - 520px); }
  .thanks-photo { max-height: calc(100vh / 1.3 - 299px); max-height: calc(100svh / 1.3 - 299px); }
}
