/* =====================================================================================================================
   MURMUR SITE · SECURITY PAGE, THE TWO VIEWS (security-viz.css), used by security.html and its French twin,
   security-fr.html, with security-viz.js (the few rules only French needs are at the end, scoped to
   :root[lang^="fr"], so the English page never moves with them). Every class starts with sec-viz-. The page's other styles (the idea cards, the comparison) are in its own <style>.

   The top of security.html: "Security." and its lead, then one short chat twice, side by side.
   - "What you see / On your phone": the chat with Nadia Haddad on an iPhone, drawn as the app draws it (the reference
     shots of the real app with founder-r4, -r5 and -r6: v1 to v6; the prototype's src/app/app.css, src/ui/ui.css,
     src/modules/chat/chat.css and src/modules/contacts/contacts.css). Four layers on one screen, as in the app: the
     chat (its bar with the lock at the far right, the "Sealed end-to-end" notice, "Today", the code notices, the
     bubbles, the composer), the lock's sheet ("Now it's your turn", Verify Security Code, OK), the Security Code
     screen (You and Nadia, the QR code, the 12 groups of 5 digits, Copy Code and Scan Code, Mark as Verified,
     then Unverify), and the toast "Nadia is verified". The status bar, the Dynamic Island and the home bar stay on
     top, as on an iPhone.
   - "What Murmur sees / Of the same chat": a sheet of paper with only what how-it-works.html#data-table lists:
     "Sender: sealed" (row 9) and "To an anonymous mailbox" (row 6), one sealed envelope per message with the time it
     arrived (row 10), one more for the check of the code (a sealed word to Nadia, like a message), "All the same
     size" (row 10), "No key to open them" (#end-to-end).
   - The note says it in words, without a link.
   The still, which is all there is without JavaScript, with reduced motion and in print, and where the story stops
   for good: the chat as it ends (three messages, the two code notices, the green lock) and the four envelopes.

   Layout
   - Below 768 px: the title, then the two views side by side, whole on the first screen, without any scroll: the
     phone (--sv-w, by the window's width and height) and, on its right, the sheet as a narrow column of the phone's
     height, the four envelopes one under the other. The lead and the note come under them.
   - 768 to 1023 px: the title above; the phone, the wax seal on a dashed line, and the sheet, the same size as the
     phone (--sv-w, 220 to 280 px, by the window's height). The note below.
   - 1024 px and up: the text on the left (the title, the lead, the note), the two views on the right, all within
     the site's 1200 px column, the width of the idea cards below too, so the hero and the cards share one left edge. The phone is 220 to
     about 300 px wide, smaller in short windows, so the two views stay whole on the first screen.
   The whole screen of the phone is drawn on one unit, --u, 1/393 of the screen: the prototype's screen is 393 points
   wide, so every point value is one --u, and the screen looks as in the reference shots at every size.

   Motion (security-viz.js): about 30 s, once, then the still. Until the script has built the story's first frame,
   the views wait, invisible (1.5 s at most: then they show the still by themselves); then they rise in (350 ms).
   Accessibility: the drawings are aria-hidden; each view is a group named by its visible label, with a hidden
   description that tells the whole story; the note says it in words. Nothing in the section is focusable.
   Print: the light tokens whatever the theme, and the drawings keep their fills.
   ===================================================================================================================== */


/* ------------------------------------------------------------------------------------------------- Tokens */
.sec-viz-hero {
  --sv-gap: 80px;                 /* the divider's column, from 768 */
  --sv-label-h: 56px;             /* a label (title 22 + sub 18) and its 16 px below, from 768 */
  --sv-device-shadow: 0 1px 2px rgb(60 42 24 / 0.10), var(--shadow-3);
  --sv-glow: 0;
  --sv-tile: var(--container);    /* the server's icon tile */
  --sv-env-fill: var(--surface);
  --sv-env-flap: color-mix(in srgb, var(--container) 55%, var(--surface));
  --sv-env-edge: color-mix(in srgb, var(--outline) 40%, var(--surface));
  --sv-env-fold: color-mix(in srgb, var(--outline) 22%, var(--surface));
  --sv-env-shadow: rgb(60 42 24 / 0.16);
  --sv-fly-shadow: rgb(60 42 24 / 0.22);
  --sv-seal-shade: rgb(70 20 8 / 0.30);
  --sv-seal-contact: rgb(60 14 6 / 0.32);
  --sv-ring: color-mix(in srgb, var(--seal) 50%, transparent);
}
/* The app's own values where the site has none (the prototype's src/ui/tokens.css), light; dark below */
.sec-viz-screen {
  --sv-bar: rgb(251 248 243 / 0.80);            /* --bar-material */
  --sv-hair: rgb(31 35 41 / 0.16);              /* --bar-hairline */
  --sv-card: var(--surface);                    /* the sealed notice */
  --sv-grouped: 0 1px 2px rgb(60 42 24 / 0.05), 0 0 0 calc(0.5 * var(--u)) rgb(60 42 24 / 0.04); /* --grouped-shadow */
  --sv-shadow-1: 0 1px 2px rgb(60 42 24 / 0.06), 0 1px 3px rgb(60 42 24 / 0.05);
  --sv-pill: rgb(239 233 224 / 0.86);           /* --pill-material: the date */
  --sv-field: var(--surface);                   /* --field-bg */
  --sv-field-edge: #E3DCD0;
  --sv-sheet: var(--bg);                        /* a sheet's page */
  --sv-sheet-dim: rgb(26 20 14 / 0.28);
  --sv-push-dim: rgb(31 35 41 / 0.10);
  --sv-page-edge: calc(-0.5 * var(--u)) 0 0 rgb(0 0 0 / 0.05), calc(-10 * var(--u)) 0 calc(30 * var(--u)) rgb(0 0 0 / 0.10);
  --sv-sheet-shadow: 0 calc(-0.5 * var(--u)) 0 rgb(0 0 0 / 0.06), 0 calc(-6 * var(--u)) calc(30 * var(--u)) rgb(0 0 0 / 0.14);
  --sv-thick: rgb(255 255 255 / 0.82);          /* --material-thick: the toast */
  --sv-disc: var(--container);                  /* the sheet's lock disc */
  --sv-qr-bg: #FFFFFF; --sv-qr-fg: #1F2329; --sv-qr-eye: #B4412C;
  --sv-ok-disc: color-mix(in srgb, var(--verified) 16%, transparent); /* the Security Code screen's lock, once green */
  --sv-dots: color-mix(in srgb, var(--text) 22%, transparent);
  --sv-touch: rgb(60 60 67 / 0.20);
  --sv-touch-ring: rgb(255 255 255 / 0.70);
}
/* Dark, on screens only (as in site.css): print takes the light tokens above */
@media screen {
  :root[data-theme="dark"] .sec-viz-hero {
    --sv-device-shadow: 0 0 0 1px rgb(255 255 255 / 0.09), var(--shadow-3);
    --sv-glow: 1;
    --sv-tile: var(--container-2);  /* --container would melt into the dark paper */
    --sv-env-fill: var(--container-2);
    --sv-env-flap: color-mix(in srgb, var(--container-2) 90%, var(--text));
    --sv-env-edge: color-mix(in srgb, var(--outline) 52%, var(--container-2));
    --sv-env-fold: color-mix(in srgb, var(--outline) 30%, var(--container-2));
    --sv-env-shadow: rgb(0 0 0 / 0.5);
    --sv-fly-shadow: rgb(0 0 0 / 0.6);
    --sv-seal-shade: rgb(0 0 0 / 0.55);
    --sv-seal-contact: rgb(0 0 0 / 0.45);
  }
  :root[data-theme="dark"] .sec-viz-screen {
    --sv-bar: rgb(18 19 22 / 0.78); --sv-hair: rgb(242 238 232 / 0.14); --sv-card: var(--container); --sv-grouped: none;
    --sv-shadow-1: 0 1px 2px rgb(0 0 0 / 0.3), 0 1px 3px rgb(0 0 0 / 0.2); --sv-pill: rgb(36 39 44 / 0.86);
    --sv-field: var(--container); --sv-field-edge: #30333A; --sv-sheet: var(--surface); --sv-sheet-dim: rgb(0 0 0 / 0.46);
    --sv-push-dim: rgb(0 0 0 / 0.32); --sv-thick: rgb(36 39 44 / 0.86); --sv-disc: var(--container-2);
    --sv-page-edge: calc(-0.5 * var(--u)) 0 0 rgb(255 255 255 / 0.04), calc(-10 * var(--u)) 0 calc(30 * var(--u)) rgb(0 0 0 / 0.45);
    --sv-qr-bg: #F2EEE8; --sv-ok-disc: color-mix(in srgb, var(--verified) 18%, transparent);
    --sv-touch: rgb(235 235 245 / 0.26); --sv-touch-ring: rgb(255 255 255 / 0.22);
  }
}
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sec-viz-hero {
    --sv-device-shadow: 0 0 0 1px rgb(255 255 255 / 0.09), var(--shadow-3);
    --sv-glow: 1;
    --sv-tile: var(--container-2);
    --sv-env-fill: var(--container-2);
    --sv-env-flap: color-mix(in srgb, var(--container-2) 90%, var(--text));
    --sv-env-edge: color-mix(in srgb, var(--outline) 52%, var(--container-2));
    --sv-env-fold: color-mix(in srgb, var(--outline) 30%, var(--container-2));
    --sv-env-shadow: rgb(0 0 0 / 0.5);
    --sv-fly-shadow: rgb(0 0 0 / 0.6);
    --sv-seal-shade: rgb(0 0 0 / 0.55);
    --sv-seal-contact: rgb(0 0 0 / 0.45);
  }
  :root:not([data-theme="light"]) .sec-viz-screen {
    --sv-bar: rgb(18 19 22 / 0.78); --sv-hair: rgb(242 238 232 / 0.14); --sv-card: var(--container); --sv-grouped: none;
    --sv-shadow-1: 0 1px 2px rgb(0 0 0 / 0.3), 0 1px 3px rgb(0 0 0 / 0.2); --sv-pill: rgb(36 39 44 / 0.86);
    --sv-field: var(--container); --sv-field-edge: #30333A; --sv-sheet: var(--surface); --sv-sheet-dim: rgb(0 0 0 / 0.46);
    --sv-push-dim: rgb(0 0 0 / 0.32); --sv-thick: rgb(36 39 44 / 0.86); --sv-disc: var(--container-2);
    --sv-page-edge: calc(-0.5 * var(--u)) 0 0 rgb(255 255 255 / 0.04), calc(-10 * var(--u)) 0 calc(30 * var(--u)) rgb(0 0 0 / 0.45);
    --sv-qr-bg: #F2EEE8; --sv-ok-disc: color-mix(in srgb, var(--verified) 18%, transparent);
    --sv-touch: rgb(235 235 245 / 0.26); --sv-touch-ring: rgb(255 255 255 / 0.22);
  }
}


/* ------------------------------------------------------------------------------------------------- Section and grid */
/* Clipped sideways only (the dark-theme glow behind the phone is wide) */
.sec-viz-hero { position: relative; padding: var(--s-6) 0 var(--s-8); background: var(--hero-bg); overflow-x: clip; }
.sec-viz-sprite { position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none; }
.sec-viz-grid {
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "stage" "note";
  justify-items: center; text-align: center; container-type: inline-size;
}
.sec-viz-head { grid-area: head; }
.sec-viz-head h1 { margin-top: var(--s-4); }
.sec-viz-head .lead { margin: var(--s-5) auto 0; }
.sec-viz-note { grid-area: note; margin-top: var(--s-8); font-size: 15px; line-height: 22px; color: var(--text-2); }
.sec-viz-note p + p { margin-top: var(--s-2); }

/* The stage holds the envelopes in flight (security-viz.js), so it is their positioned box */
.sec-viz-stage { grid-area: stage; position: relative; display: grid; width: 100%; text-align: left; }
.sec-viz-view { position: relative; display: flex; flex-direction: column; align-items: center; min-width: 0; }
.sec-viz-divider { display: none; }

.sec-viz-label { display: flex; flex-direction: column; align-items: center; margin: 0 0 var(--s-3); text-align: center; }
.sec-viz-label__title { font-size: 15px; line-height: 20px; font-weight: 600; letter-spacing: -0.005em; color: var(--text); white-space: nowrap; }
.sec-viz-label__sub { font-size: 13px; line-height: 18px; color: var(--text-2); white-space: nowrap; }


/* ------------------------------------------------------------------------------------------------- The phone */
/* The home page's phone (home.css), sized by its width, --sv-w (below 768, in the block "Below 768" further down) */
.sec-viz-phone {
  --sv-r: 15cqw; --sv-ring: 1.5px; --sv-bezel: 3cqw;
  position: relative; z-index: 0; width: var(--sv-w); container-type: inline-size; forced-color-adjust: none;
}
.sec-viz-phone::before { /* dark theme: a soft wax glow, so the black phone reads on the night background */
  content: ""; position: absolute; z-index: -2; inset: -12% -40%; pointer-events: none; opacity: var(--sv-glow);
  background: radial-gradient(closest-side, color-mix(in srgb, var(--seal) 15%, transparent), transparent);
}
.sec-viz-device { position: relative; aspect-ratio: 10 / 21; }
.sec-viz-frame {
  position: absolute; inset: 0; border-radius: var(--sv-r);
  background: linear-gradient(155deg, #4A4B50 0%, #3A3B40 45%, #2B2C30 100%); box-shadow: var(--sv-device-shadow);
}
.sec-viz-frame::before { content: ""; position: absolute; inset: var(--sv-ring); border-radius: calc(var(--sv-r) - var(--sv-ring)); background: #0A0A0C; }
.sec-viz-key { position: absolute; z-index: -1; width: 2cqw; border-radius: 0.8cqw; background: linear-gradient(90deg, #2B2C30, #4A4B50 50%, #2B2C30); }
.sec-viz-key--action, .sec-viz-key--up, .sec-viz-key--down { left: -0.9cqw; }
.sec-viz-key--side { right: -0.9cqw; }
.sec-viz-key--action { top: 17.2%; height: 4.6%; }
.sec-viz-key--up { top: 24.6%; height: 7.4%; }
.sec-viz-key--down { top: 33.4%; height: 7.4%; }
.sec-viz-key--side { top: 26%; height: 11.6%; }
.sec-viz-key--camera {
  right: -0.45cqw; top: 58.4%; height: 7.2%; width: 1.6cqw; border-radius: 0.6cqw;
  background: linear-gradient(90deg, #26272B, #34353A 50%, #26272B); box-shadow: inset 0 0 0 0.25cqw #45464B;
}
/* The screen: --u is 1/393 of it (its children read 100cqw on it). Its layers are all absolute. */
.sec-viz-screen {
  --u: calc(100cqw / 393);
  position: absolute; inset: calc(var(--sv-ring) + var(--sv-bezel)); z-index: 1; overflow: hidden; isolation: isolate;
  border-radius: calc(var(--sv-r) - var(--sv-ring) - var(--sv-bezel)); container-type: inline-size;
  background: var(--bg); color: var(--text); font-family: var(--font-ui); text-align: left;
  -webkit-user-select: none; user-select: none;
}
/* On screens, an opaque mask makes the screen one surface cut by its own corners (as on the home page): whatever
   moves on it stays inside them, and its frosted bars take in only the screen. */
@media screen { .sec-viz-screen { -webkit-mask-image: linear-gradient(#000, #000); mask-image: linear-gradient(#000, #000); } }
.sec-viz-screen svg { display: block; flex: none; fill: currentColor; }

/* iOS on top of the app: the island (126 x 37, 11 from the top), the home bar (134 x 5, 8 from the bottom), and the
   status bar (54 tall, the time and the icons each centred in a 134-wide column at an edge) */
.sec-viz-island {
  position: absolute; z-index: 20; top: calc(11 * var(--u)); left: 50%; width: calc(126 * var(--u)); height: calc(37 * var(--u));
  margin-left: calc(-63 * var(--u)); border-radius: calc(18.5 * var(--u)); background: #000;
}
.sec-viz-homebar {
  position: absolute; z-index: 20; left: 50%; bottom: calc(8 * var(--u)); width: calc(134 * var(--u)); height: calc(5 * var(--u));
  margin-left: calc(-67 * var(--u)); border-radius: calc(3 * var(--u)); background: var(--text); opacity: 0.92;
}
.sec-viz-status {
  position: absolute; z-index: 6; top: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: space-between;
  height: calc(54 * var(--u)); padding-top: calc(5 * var(--u)); color: var(--text); pointer-events: none;
}
.sec-viz-status__time {
  display: flex; justify-content: center; width: calc(134 * var(--u)); padding-left: calc(4 * var(--u));
  font-size: calc(17 * var(--u)); line-height: calc(22 * var(--u)); font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.sec-viz-status__icons {
  display: flex; align-items: center; justify-content: center; gap: calc(6 * var(--u));
  width: calc(134 * var(--u)); padding-right: calc(2 * var(--u));
}
.sec-viz-screen .sec-viz-sb-bars { width: calc(18 * var(--u)); height: calc(12 * var(--u)); }
.sec-viz-screen .sec-viz-sb-wifi { width: calc(16 * var(--u)); height: calc(12 * var(--u)); fill: none; }
.sec-viz-screen .sec-viz-sb-battery { width: calc(27 * var(--u)); height: calc(13 * var(--u)); fill: none; }

/* The app's pages: the chat at the bottom, the Security Code screen over it (pushed in from the right, its shadow on
   its left edge), both under the status bar. A page's dim (the push) covers it whole. */
.sec-viz-page { position: absolute; inset: 0; overflow: hidden; background: var(--bg); }
.sec-viz-chatpage { z-index: 1; }
.sec-viz-codepage { z-index: 2; box-shadow: var(--sv-page-edge); opacity: 0; transform: translateX(100%); }
.sec-viz-pagedim { position: absolute; inset: 0; z-index: 10; background: var(--sv-push-dim); opacity: 0; pointer-events: none; }


/* ------------------------------------------------------------------------------------------------- The chat */
/* Avatars (Avatar.tsx): a disc, light at the top, the account's colour at the bottom; initials in white */
.sec-viz-avatar {
  display: grid; place-items: center; flex: none; width: calc(36 * var(--u)); height: calc(36 * var(--u));
  border-radius: 50%; background: linear-gradient(180deg, color-mix(in srgb, var(--av) 78%, #FFFFFF 22%) 0%, var(--av) 100%);
  color: var(--on-avatar); font-size: calc(14 * var(--u)); line-height: 1; font-weight: 600; letter-spacing: 0.01em;
}
.sec-viz-avatar--56 { width: calc(56 * var(--u)); height: calc(56 * var(--u)); font-size: calc(21 * var(--u)); }

/* The bar (.nav-bar-bg, 60 tall on a chat, under the 54 of the status bar): the paper at the top fading into the
   frosted material over 26 points, the hairline under it. In it, centred on a 44 row 2 under the status bar: the back
   chevron on the 16 margin, the avatar at 48 (36), the name 16/20 and the status 13/16 at 94, and the lock (24 in a
   44 target, its ink on the 16 margin), grey until both marked the code, green after. */
.sec-viz-bar {
  position: absolute; z-index: 3; top: 0; left: 0; right: 0; height: calc((54 + 60) * var(--u));
  background: linear-gradient(var(--bg) 0, var(--sv-bar) calc(26 * var(--u)));
  border-bottom: 1px solid var(--sv-hair);
  -webkit-backdrop-filter: saturate(1.8) blur(calc(20 * var(--u))); backdrop-filter: saturate(1.8) blur(calc(20 * var(--u)));
}
.sec-viz-chathead {
  position: absolute; left: 0; right: 0; top: calc(56 * var(--u)); display: flex; align-items: center; height: calc(44 * var(--u));
  padding: 0 calc(1 * var(--u)) 0 calc(16 * var(--u));
}
.sec-viz-screen .sec-viz-back { width: calc(13 * var(--u)); height: calc(21 * var(--u)); color: var(--link); }
.sec-viz-chathead .sec-viz-back { margin-right: calc(19 * var(--u)); }
.sec-viz-chathead .sec-viz-avatar { margin-right: calc(10 * var(--u)); }
.sec-viz-who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sec-viz-who__name {
  font-size: calc(16 * var(--u)); line-height: calc(20 * var(--u)); font-weight: 600; letter-spacing: -0.011em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sec-viz-who__status { font-size: calc(13 * var(--u)); line-height: calc(16 * var(--u)); letter-spacing: -0.003em; color: var(--verified); white-space: nowrap; }
.sec-viz-lock { position: relative; display: grid; place-items: center; flex: none; width: calc(44 * var(--u)); height: calc(44 * var(--u)); }
.sec-viz-screen .sec-viz-lock svg { grid-area: 1 / 1; width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
.sec-viz-lock__grey { color: var(--text-3); opacity: 0; }   /* the still: green */
.sec-viz-lock__green { color: var(--verified); }

/* The conversation, as the app lays out a short one: the newest item 18 above the composer (22 for a notice: its
   row keeps 4 under it), the notice at the top of the chat, the free room above it, under the bar. The column moves
   as one when a message comes (security-viz.js). */
.sec-viz-chat {
  position: absolute; z-index: 1; left: 0; right: 0; top: 0; bottom: calc(81 * var(--u));
  display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: calc(18 * var(--u)); overflow: hidden;
}
.sec-viz-col { display: flex; flex-direction: column; flex: none; }
/* The notice at the top of every chat (.sealed-notice): the seal on its tinted disc (36, the seal 22), the title
   15/20, the text 13/18, a chevron 16 from the right edge */
.sec-viz-notice {
  position: relative; display: flex; align-items: center; gap: calc(12 * var(--u)); flex: none;
  margin: 0 calc(16 * var(--u)); padding: calc(12 * var(--u)) calc(36 * var(--u)) calc(12 * var(--u)) calc(12 * var(--u));
  border-radius: calc(16 * var(--u)); background: var(--sv-card); box-shadow: var(--sv-grouped);
}
.sec-viz-notice__seal {
  display: grid; place-items: center; flex: none; width: calc(36 * var(--u)); height: calc(36 * var(--u));
  border-radius: 50%; background: var(--accent-container); color: var(--seal);
}
.sec-viz-screen .sec-viz-notice__seal svg { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.sec-viz-notice__text { display: flex; flex-direction: column; gap: calc(2 * var(--u)); min-width: 0; }
.sec-viz-notice__text b { font-size: calc(15 * var(--u)); line-height: calc(20 * var(--u)); font-weight: 600; letter-spacing: -0.009em; }
.sec-viz-notice__text span { font-size: calc(13 * var(--u)); line-height: calc(18 * var(--u)); letter-spacing: -0.003em; color: var(--text-2); }
.sec-viz-screen .sec-viz-notice__chevron {
  position: absolute; right: calc(16 * var(--u)); top: 50%; width: calc(14 * var(--u)); height: calc(14 * var(--u)); margin-top: calc(-7 * var(--u));
  color: var(--text-3); opacity: 0.55;
}
/* The date pill (.day-pill): 16 under the notice */
.sec-viz-day { flex: none; display: flex; justify-content: center; margin-top: calc(16 * var(--u)); }
.sec-viz-day span {
  padding: calc(3 * var(--u)) calc(10 * var(--u)); border-radius: calc(11 * var(--u)); background: var(--sv-pill); color: var(--system-text);
  font-size: calc(12 * var(--u)); line-height: calc(16 * var(--u)); font-weight: 600; letter-spacing: 0.01em;
}
/* The code notices (.sys-row, .sys-pill): centred, 24 from the edges, 8 above and 4 under; the text 500 13/18 in
   even lines, a 14 icon before the first word; "Tap to verify." 600 in the link colour. The green one on
   --success-container. Two versions of the first one share its place: with "Tap to verify." while it waits for
   me, without it once I have marked the code (the still). */
.sec-viz-sys { position: relative; display: flex; justify-content: center; flex: none; margin: calc(8 * var(--u)) 0 calc(4 * var(--u)); padding: 0 calc(24 * var(--u)); }
.sec-viz-pill {
  display: inline-block; max-width: 100%; padding: calc(4 * var(--u)) calc(12 * var(--u)); border-radius: calc(13 * var(--u));
  background: var(--system-bg); color: var(--system-text); text-align: center;
  font-size: calc(13 * var(--u)); line-height: calc(18 * var(--u)); font-weight: 500; letter-spacing: -0.003em;
}
.sec-viz-pill b { font-weight: 600; color: var(--link); }
.sec-viz-screen .sec-viz-pill svg { display: inline-block; width: calc(14 * var(--u)); height: calc(14 * var(--u)); margin: 0 calc(5 * var(--u)) 0 calc(-1 * var(--u)); vertical-align: calc(-2.5 * var(--u)); }
.sec-viz-sys__alt { position: absolute; top: 0; left: calc(24 * var(--u)); right: calc(24 * var(--u)); display: flex; justify-content: center; opacity: 0; }
.sec-viz-sys--ok .sec-viz-pill { background: var(--success-container); color: var(--on-success-container); }

/* Messages (.msg-row, .bubble, .b-text): every message its own bubble, 8 apart, 16 from the edges, at most 76% of
   the row; corners 18, 7.8 on the photo's side (no tail, as in the app since 0.9.19); the text 16/22, 6 above and 7 under.
   The time and ticks (.meta, 11/13) sit 10 from the right and 6 from the bottom; a hidden copy at the end of the
   text keeps their room on the last line (.meta-spacer). */
.sec-viz-msg { display: flex; flex: none; margin-top: calc(8 * var(--u)); padding: 0 calc(16 * var(--u)); }
.sec-viz-msg--out { justify-content: flex-end; }
.sec-viz-b {
  position: relative; display: flow-root; isolation: isolate; max-width: 76%; padding: calc(6 * var(--u)) calc(12 * var(--u)) calc(7 * var(--u));
  border-radius: calc(18 * var(--u)) calc(18 * var(--u)) calc(18 * var(--u)) calc(7.8 * var(--u));
  background: var(--bubble-in); color: var(--bubble-in-text);
  font-size: calc(16 * var(--u)); line-height: calc(22 * var(--u)); letter-spacing: -0.011em; overflow-wrap: anywhere;
}
.sec-viz-msg--out .sec-viz-b { border-radius: calc(18 * var(--u)) calc(18 * var(--u)) calc(7.8 * var(--u)) calc(18 * var(--u)); background: var(--bubble-out); color: var(--bubble-out-text); }
/* A bubble arrives from its own corner (the app's bubble-receive and bubble-send) */
.sec-viz-msg--in .sec-viz-b { transform-origin: 0 100%; }
.sec-viz-msg--out .sec-viz-b { transform-origin: 100% 100%; }
.sec-viz-meta, .sec-viz-spacer {
  display: inline-flex; align-items: center; gap: calc(3 * var(--u)); white-space: nowrap;
  font-size: calc(11 * var(--u)); line-height: calc(13 * var(--u)); letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.sec-viz-meta { position: absolute; right: calc(10 * var(--u)); bottom: calc(6 * var(--u)); color: var(--bubble-in-meta); }
.sec-viz-msg--out .sec-viz-meta { color: var(--bubble-out-meta); }
.sec-viz-meta time { opacity: 0.68; }
.sec-viz-spacer { visibility: hidden; margin-left: calc(8 * var(--u)); vertical-align: baseline; line-height: 1; }
/* Ticks (15 x 10): delivered in the time's ink, read in the wax; both in one place (the still: read) */
.sec-viz-ticks { position: relative; display: grid; width: calc(15 * var(--u)); height: calc(10 * var(--u)); margin-right: calc(-2 * var(--u)); }
.sec-viz-screen .sec-viz-ticks svg { grid-area: 1 / 1; width: 100%; height: 100%; }
.sec-viz-tick--sent { color: var(--bubble-out-meta); opacity: 0; }
.sec-viz-tick--read { color: var(--tick-read); }

/* The composer, idle (.composer, 81 tall, and chat/composer.css): the frosted material and its hairline; the "+" (a 36
   disc), the 36-tall "Message" field (white, a 1 px ring, the hint 16/21 and paler than any other) and the round
   microphone, the "+"'s twin, each disc 6 from the field and 18 from the screen's edge, 22 under the hairline and
   22 above the bottom */
.sec-viz-composer {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; height: calc(81 * var(--u));
  display: flex; align-items: flex-start; gap: calc(6 * var(--u)); padding: calc(22 * var(--u)) calc(18 * var(--u)) 0 calc(18 * var(--u));
  background: var(--sv-bar); border-top: 1px solid var(--sv-hair);
  -webkit-backdrop-filter: saturate(1.8) blur(calc(20 * var(--u))); backdrop-filter: saturate(1.8) blur(calc(20 * var(--u)));
}
.sec-viz-attach {
  display: grid; place-items: center; flex: none; width: calc(36 * var(--u)); height: calc(36 * var(--u));
  border-radius: 50%; background: var(--container); color: var(--text-2);
}
.sec-viz-screen .sec-viz-attach svg { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
.sec-viz-screen .sec-viz-attach--mic svg { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
/* Dark: the discs carry the field's 1 px rim, and their glyphs the text's colour */
:root[data-theme="dark"] .sec-viz-attach { box-shadow: inset 0 0 0 1px var(--sv-field-edge); color: var(--text); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .sec-viz-attach { box-shadow: inset 0 0 0 1px var(--sv-field-edge); color: var(--text); } }
.sec-viz-field {
  flex: 1; min-width: 0; height: calc(36 * var(--u)); padding: calc(7 * var(--u)) calc(14 * var(--u)) calc(8 * var(--u));
  border-radius: calc(18 * var(--u)); background: var(--sv-field); box-shadow: inset 0 0 0 1px var(--sv-field-edge);
  font-size: calc(16 * var(--u)); line-height: calc(21 * var(--u)); letter-spacing: -0.011em; white-space: nowrap;
  color: color-mix(in srgb, var(--text-3) 58%, transparent); /* the app's paler hint (app.css, composer-field) */
}


/* ------------------------------------------------------------------------------------------------- The lock's sheet */
/* SealStepSheet (r6): a sheet as tall as what it says, its page on top of the chat dimmed under --sheet-dim; the
   grabber; the lock (28) in a 60 disc; the title 700 20/25; one line 15/21 in even lines; Verify Security Code (the
   primary button, 50, radius 12) and, 12 under it (--space-stack), OK, a grey button of the same height and shape
   (the founder, 12 Nov 2026). 28 above, 24 on the sides, the home bar's 34 and 6 under. Out of sight in the still. */
.sec-viz-sheetdim { position: absolute; inset: 0; z-index: 7; background: var(--sv-sheet-dim); opacity: 0; }
.sec-viz-sheet {
  position: absolute; z-index: 8; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; align-items: center;
  padding: calc(28 * var(--u)) calc(24 * var(--u)) calc(40 * var(--u)); border-radius: calc(12 * var(--u)) calc(12 * var(--u)) 0 0;
  background: var(--sv-sheet); box-shadow: var(--sv-sheet-shadow); text-align: center; opacity: 0; transform: translateY(100%);
}
.sec-viz-grabber {
  position: absolute; top: calc(6.5 * var(--u)); left: 50%; width: calc(36 * var(--u)); height: calc(5 * var(--u)); margin-left: calc(-18 * var(--u));
  border-radius: calc(3 * var(--u)); background: var(--outline); opacity: 0.45;
}
.sec-viz-sheet__disc {
  display: grid; place-items: center; width: calc(60 * var(--u)); height: calc(60 * var(--u)); margin-bottom: calc(14 * var(--u));
  border-radius: 50%; background: var(--sv-disc); color: var(--text-2);
}
.sec-viz-screen .sec-viz-sheet__disc svg { width: calc(28 * var(--u)); height: calc(28 * var(--u)); }
.sec-viz-sheet__title { margin-bottom: calc(6 * var(--u)); font-size: calc(20 * var(--u)); line-height: calc(25 * var(--u)); font-weight: 700; letter-spacing: -0.017em; }
.sec-viz-sheet__text {
  max-width: calc(340 * var(--u)); margin-bottom: calc(20 * var(--u));
  font-size: calc(15 * var(--u)); line-height: calc(21 * var(--u)); letter-spacing: -0.009em; color: var(--text-2);
}
.sec-viz-sheet .sec-viz-btn + .sec-viz-btn { margin-top: calc(12 * var(--u)); }

/* Buttons (.btn): large 50 tall, radius 12, 600 17/22, the icon 20 and 8 apart; small 34, radius 17, 600 15/20 */
.sec-viz-btn {
  display: flex; align-items: center; justify-content: center; gap: calc(8 * var(--u)); width: 100%; height: calc(50 * var(--u));
  padding: 0 calc(20 * var(--u)); border-radius: calc(12 * var(--u)); white-space: nowrap;
  font-size: calc(17 * var(--u)); line-height: calc(22 * var(--u)); font-weight: 600; letter-spacing: -0.013em;
}
.sec-viz-screen .sec-viz-btn svg { width: calc(20 * var(--u)); height: calc(20 * var(--u)); margin-left: calc(-2 * var(--u)); }
.sec-viz-btn--primary { background: var(--primary); color: var(--on-primary); }
.sec-viz-btn--secondary { background: var(--container); color: var(--text); }
.sec-viz-btn--danger { font-weight: 500; color: var(--error); }
.sec-viz-btn--small {
  width: auto; height: calc(34 * var(--u)); gap: calc(6 * var(--u)); padding: 0 calc(14 * var(--u)); border-radius: calc(17 * var(--u));
  font-size: calc(15 * var(--u)); line-height: calc(20 * var(--u)); letter-spacing: -0.009em;
  background: var(--accent-container); color: var(--on-accent-container);
}
.sec-viz-screen .sec-viz-btn--small svg { width: calc(17 * var(--u)); height: calc(17 * var(--u)); }


/* ------------------------------------------------------------------------------------------------- The Security Code screen */
/* VerifyScreen (r6): the bar ("Back" 5 after its chevron, and "Security Code"), then You and Nadia side by side, each
   in a column that takes the room there is, joined through the chat's own lock (a dotted link on a side not done, a
   solid green one on a side done; the lock turns green once both are), the title 700 22/28 and its line 15/20, each
   sentence on its own even lines; the white card (the QR in its tile, the code in 12 cells of 4 columns, Copy Code
   and Scan Code, and under them the line that says how to send the code); Mark as Verified, or Unverify once
   marked; "How this code is made". The
   still is the screen once both marked it (it is out of sight there); the script starts it one step earlier. */
.sec-viz-codepage { display: flex; flex-direction: column; padding-top: calc(54 * var(--u)); }
.sec-viz-navbar { position: relative; flex: none; height: calc(44 * var(--u)); display: flex; align-items: center; }
.sec-viz-navback { position: absolute; left: calc(16 * var(--u)); top: 0; bottom: 0; display: flex; align-items: center; gap: calc(5 * var(--u)); color: var(--link); }
.sec-viz-navback span { font-size: calc(17 * var(--u)); line-height: calc(22 * var(--u)); letter-spacing: -0.013em; }
.sec-viz-navtitle { width: 100%; text-align: center; font-size: calc(17 * var(--u)); line-height: calc(22 * var(--u)); font-weight: 600; letter-spacing: -0.013em; }
.sec-viz-vhead {
  display: flex; flex-direction: column; align-items: center; flex: none; gap: calc(16 * var(--u));
  margin: calc(16 * var(--u)) 0 calc(24 * var(--u)); padding: 0 calc(28 * var(--u)); text-align: center;
}
.sec-viz-sides {
  display: grid; grid-template-columns: minmax(calc(96 * var(--u)), 1fr) auto minmax(calc(96 * var(--u)), 1fr); align-items: start;
  column-gap: calc(12 * var(--u)); width: 100%; max-width: calc(340 * var(--u));
}
.sec-viz-side { position: relative; display: flex; flex-direction: column; align-items: center; min-width: 0; }
.sec-viz-side__av { position: relative; margin-bottom: calc(8 * var(--u)); }
.sec-viz-side__check {
  position: absolute; right: calc(-4 * var(--u)); bottom: calc(-4 * var(--u)); display: grid; place-items: center;
  width: calc(24 * var(--u)); height: calc(24 * var(--u)); border-radius: 50%; background: var(--bg); color: var(--verified);
}
.sec-viz-screen .sec-viz-side__check svg { width: calc(22 * var(--u)); height: calc(22 * var(--u)); }
.sec-viz-side__name { font-size: calc(15 * var(--u)); line-height: calc(20 * var(--u)); font-weight: 600; letter-spacing: -0.009em; white-space: nowrap; }
.sec-viz-side__state { display: grid; font-size: calc(13 * var(--u)); line-height: calc(18 * var(--u)); letter-spacing: -0.003em; white-space: nowrap; }
.sec-viz-side__state > span { grid-area: 1 / 1; justify-self: center; }
.sec-viz-side__state .is-ok { font-weight: 600; color: var(--verified); }
.sec-viz-side__state .is-not { color: var(--text-2); opacity: 0; }
/* The chat's lock between (.ct-sides-lock): lock-fill 18 in a 36 disc, 10 under the avatars' top; grey on the sheet's
   disc colour until both marked the code, then green on a soft green disc, scaled to 1.06. A link joins each avatar
   to it, drawn from the side (.ct-side::after, ::before), 2 tall, 27 under the side's top, stopping 4 from the
   avatar and 4 from the lock at any width. */
.sec-viz-sides__lock { display: grid; margin-top: calc(10 * var(--u)); transform: scale(1.06); }
.sec-viz-sidelock { grid-area: 1 / 1; display: grid; place-items: center; width: calc(36 * var(--u)); height: calc(36 * var(--u)); border-radius: 50%; }
.sec-viz-sidelock--not { background: var(--sv-disc); color: var(--text-2); opacity: 0; }
.sec-viz-sidelock--ok { background: var(--sv-ok-disc); color: var(--verified); }
.sec-viz-screen .sec-viz-sidelock svg { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
.sec-viz-link { position: absolute; top: calc(27 * var(--u)); height: calc(2 * var(--u)); border-radius: calc(1 * var(--u)); }
.sec-viz-link--me { left: calc(50% + 32 * var(--u)); right: calc(-8 * var(--u)); }
.sec-viz-link--them { left: calc(-8 * var(--u)); right: calc(50% + 32 * var(--u)); }
.sec-viz-link > i { position: absolute; inset: 0; border-radius: inherit; }
.sec-viz-link__dots { background: repeating-linear-gradient(90deg, var(--sv-dots) 0 calc(3 * var(--u)), transparent calc(3 * var(--u)) calc(6 * var(--u))); opacity: 0; }
.sec-viz-link__solid { background: var(--verified); }
.sec-viz-words { display: flex; flex-direction: column; align-items: center; gap: calc(6 * var(--u)); width: 100%; }
.sec-viz-words__title, .sec-viz-words__text { position: relative; display: block; width: 100%; }
.sec-viz-words__title > span, .sec-viz-words__text > span { display: block; }
.sec-viz-line { display: block; }
.sec-viz-words__title { font-size: calc(22 * var(--u)); line-height: calc(28 * var(--u)); font-weight: 700; letter-spacing: -0.018em; }
.sec-viz-words__text { font-size: calc(15 * var(--u)); line-height: calc(20 * var(--u)); letter-spacing: -0.009em; color: var(--text-2); }
/* The words before the mark ("Now it's your turn" and its line) wait over the still's, out of the flow (their line
   may be a line longer: it then hangs out over the card, which the script moves down by that much while they show) */
.sec-viz-words .is-before { position: absolute; top: 0; left: 0; right: 0; opacity: 0; }
/* The rest of the screen, 24 under the words */
.sec-viz-lower { flex: none; }
.sec-viz-codecard {
  display: flex; flex-direction: column; align-items: center; gap: calc(16 * var(--u)); margin: 0 calc(16 * var(--u)) calc(24 * var(--u));
  padding: calc(20 * var(--u)) calc(14 * var(--u)) calc(16 * var(--u)); border-radius: calc(16 * var(--u)); background: var(--surface); box-shadow: var(--sv-grouped);
}
/* Copy Code and Scan Code, two small pills 8 apart, centred (contacts.css .ct-verify-tools); Scan Code only until I
   mark the code, so in the still (marked) Copy Code is alone in the middle: the pair waits shifted left by half of
   Scan Code and its gap, and slides back as Scan Code fades (security-viz.js) */
.sec-viz-tools { display: flex; justify-content: center; width: 100%; }
.sec-viz-tools__pair { position: relative; display: flex; }
.sec-viz-tools__scan { position: absolute; top: 0; left: calc(100% + 8 * var(--u)); opacity: 0; }
.sec-viz-codenote {
  max-width: calc(300 * var(--u)); margin-top: calc(-8 * var(--u)); text-align: center; color: var(--text-2);
  font-size: calc(13 * var(--u)); line-height: calc(18 * var(--u)); letter-spacing: -0.003em;
}
.sec-viz-qrbox {
  position: relative; display: grid; place-items: center; padding: calc(10 * var(--u)); border-radius: calc(12 * var(--u));
  background: var(--sv-qr-bg); box-shadow: var(--sv-shadow-1);
}
.sec-viz-screen .sec-viz-qr { width: calc(120 * var(--u)); height: calc(120 * var(--u)); }
.sec-viz-qr__mod { fill: var(--sv-qr-fg); stroke: var(--sv-qr-fg); stroke-width: 0.56; stroke-linejoin: round; }
.sec-viz-qr__eye { fill: var(--sv-qr-eye); }
.sec-viz-qrbox__ring { position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 calc(2 * var(--u)) var(--verified); }
.sec-viz-qrbox__stamp { position: absolute; inset: 0; display: grid; place-items: center; color: var(--verified); opacity: 0; }
.sec-viz-screen .sec-viz-qrbox__stamp svg { width: calc(48 * var(--u)); height: calc(48 * var(--u)); filter: drop-shadow(0 calc(4 * var(--u)) calc(10 * var(--u)) rgb(0 0 0 / 0.18)); }
.sec-viz-keys { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: calc(8 * var(--u)); width: 100%; }
.sec-viz-keys span {
  display: grid; place-items: center; height: calc(44 * var(--u)); border-radius: calc(10 * var(--u)); background: var(--container);
  font-family: var(--font-mono); font-size: calc(17 * var(--u)); line-height: calc(22 * var(--u)); font-weight: 500; letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Mark as Verified, or Unverify in its place; "How this code is made" 24 under
   them. In the still, Unverify; Mark as Verified waits over it, and the row under them sits where Unverify leaves it
   (the script moves it down while it shows). */
.sec-viz-actions { position: relative; margin: 0 calc(16 * var(--u)) calc(24 * var(--u)); }
.sec-viz-actions__mark { position: absolute; top: 0; left: 0; right: 0; display: flex; flex-direction: column; gap: calc(12 * var(--u)); opacity: 0; }
.sec-viz-howrow {
  display: flex; align-items: center; height: calc(44 * var(--u)); margin: 0 calc(16 * var(--u)); padding: 0 calc(16 * var(--u)) 0 calc(19.5 * var(--u));
  border-radius: calc(12 * var(--u)); background: var(--surface); box-shadow: var(--sv-grouped);
  font-size: calc(17 * var(--u)); line-height: calc(22 * var(--u)); letter-spacing: -0.013em;
}
.sec-viz-screen .sec-viz-howrow svg:first-child { width: calc(22 * var(--u)); height: calc(22 * var(--u)); margin-right: calc(15.5 * var(--u)); color: var(--link); }
.sec-viz-howrow span { flex: 1; min-width: 0; }
.sec-viz-screen .sec-viz-howrow svg:last-child { width: calc(14 * var(--u)); height: calc(14 * var(--u)); color: var(--text-3); opacity: 0.55; }


/* ------------------------------------------------------------------------------------------------- Toast and finger */
/* The toast (.toast): centred on the screen, the thick material, the icon 30 in --text-2, 600 15/20 */
.sec-viz-toast {
  position: absolute; z-index: 9; left: 50%; top: 50%; display: flex; flex-direction: column; align-items: center; gap: calc(8 * var(--u));
  min-width: calc(140 * var(--u)); padding: calc(18 * var(--u)) calc(22 * var(--u)) calc(15 * var(--u)); border-radius: calc(14 * var(--u));
  background: var(--sv-thick); -webkit-backdrop-filter: blur(calc(30 * var(--u))); backdrop-filter: blur(calc(30 * var(--u)));
  box-shadow: 0 calc(10 * var(--u)) calc(30 * var(--u)) rgb(0 0 0 / 0.12); text-align: center; white-space: nowrap;
  font-size: calc(15 * var(--u)); line-height: calc(20 * var(--u)); font-weight: 600; letter-spacing: -0.009em; color: var(--text);
  opacity: 0; transform: translate(-50%, -50%);
}
.sec-viz-screen .sec-viz-toast svg { width: calc(30 * var(--u)); height: calc(30 * var(--u)); color: var(--text-2); }
/* The finger: a soft disc where the screen is touched (the home page's) */
.sec-viz-touch {
  position: absolute; z-index: 19; left: 0; top: 0; width: calc(40 * var(--u)); height: calc(40 * var(--u)); border-radius: 50%;
  background: var(--sv-touch); box-shadow: inset 0 0 0 calc(1.5 * var(--u)) var(--sv-touch-ring); opacity: 0; pointer-events: none;
}


/* ------------------------------------------------------------------------------------------------- What Murmur sees: the sheet */
.sec-viz-ledger {
  position: relative; z-index: 0; display: flex; flex-direction: column; width: 100%; min-width: 0; isolation: isolate;
  border-radius: var(--r-sheet); background: var(--paper); box-shadow: 0 0 0 1px var(--card-edge), var(--shadow-3);
  container-type: inline-size; forced-color-adjust: none; -webkit-user-select: none; user-select: none;
}
.sec-viz-ledger::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; background-image: var(--grain); }
.sec-viz-ledger svg { display: block; flex: none; fill: currentColor; }
/* What the server knows of the chat: the sender is sealed (row 9), the envelopes go to an anonymous mailbox (row 6) */
.sec-viz-ledger__head { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-5) var(--s-5) var(--s-4); border-bottom: 1px dashed var(--outline-soft); }
.sec-viz-ledger__icon {
  display: grid; place-items: center; width: 44px; height: 44px; flex: none; border-radius: 12px;
  background: var(--sv-tile); color: var(--text-2); box-shadow: inset 0 0 0 1px var(--card-edge);
}
.sec-viz-ledger .sec-viz-ledger__icon svg { width: 24px; height: 24px; }
.sec-viz-ledger__who { display: flex; flex-direction: column; min-width: 0; }
.sec-viz-ledger__title { font-size: 15px; line-height: 20px; font-weight: 600; color: var(--text); white-space: nowrap; }
.sec-viz-ledger__sub { font-size: 13px; line-height: 18px; color: var(--text-2); white-space: nowrap; }
/* One envelope per message, the time it arrived beside it; the four rows share the list evenly, each in its own
   place from the first frame (an envelope still to come keeps its place, empty, rule included) */
.sec-viz-ledger__list { flex: 1; display: flex; flex-direction: column; margin: 0; padding: var(--s-1) var(--s-5) 0; list-style: none; }
.sec-viz-env { position: relative; flex: 1 1 0; display: flex; align-items: center; gap: var(--s-4); min-height: 0; padding: 6px 0; }
.sec-viz-env + .sec-viz-env { border-top: 1px solid var(--divider); }
.sec-viz-ledger .sec-viz-env__art { width: 26cqw; height: auto; aspect-ratio: 8 / 5; overflow: visible; filter: drop-shadow(0 1px 1.5px var(--sv-env-shadow)); }
.sec-viz-env__wax { transform-box: fill-box; transform-origin: center; }
.sec-viz-env__time { font-size: 15px; line-height: 20px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The rounded size, once for all (row 10) */
.sec-viz-ledger__same {
  margin: 0 var(--s-5); padding: var(--s-2) 0 var(--s-3); border-top: 1px solid var(--divider);
  font-size: 13px; line-height: 18px; color: var(--text-2); text-align: center; white-space: nowrap;
}
.sec-viz-ledger__foot {
  display: flex; align-items: center; justify-content: center; gap: var(--s-2); padding: var(--s-4) var(--s-5) var(--s-5);
  border-top: 1px dashed var(--outline-soft); font-size: 14px; line-height: 20px; font-weight: 600; color: var(--text); white-space: nowrap;
}
.sec-viz-ledger .sec-viz-ledger__foot svg { width: 18px; height: 18px; color: var(--seal); }

/* Below 768: the two views side by side, whole on the first screen, so the envelopes stay in sight for the whole story.
   The title, then the labels on one line, each on its view's outer edge (the sheet's reaches over the phone's corner,
   where nothing else is), then the phone and, on its right, the sheet as a column of the same height: the head, the
   four envelopes one under the other, each over its time, then the size and the key. The lead moves under the views
   (.sec-viz-head gives its three lines to the grid).
   The phone (--sv-w) takes what the sheet (--sv-card, a quarter of the column) and the gap of 8 leave, and never so much
   that the views leave the first screen: the header 64, the padding 16, the eyebrow 16, the title 52, the gap 16, the
   labels 46 and 8 of air keep 218 px of the window's height. --sv-tall is 1px where that height lets the phone take its
   whole width, and 0 where it does not (a phone's browser with its bars): there, the eyebrow and the labels' second
   lines give the phone their 40 px. It reads svh, so nothing moves when the bars slide away during a scroll. */
@media (max-width: 767px) {
  .sec-viz-hero {
    --sv-card: clamp(84px, 25cqw, 132px);
    --sv-tall: clamp(0px, ((100svh - 218px) / 2.1 - min(100cqw - var(--sv-card) - 8px, 300px)) * 99, 1px);
    --sv-w: clamp(196px, min(100cqw - var(--sv-card) - 8px, (100svh - 218px + (1px - var(--sv-tall)) * 40) / 2.1), 300px);
    padding-top: var(--s-4);
  }
  .sec-viz-grid { grid-template-areas: "eyebrow" "title" "stage" "lead" "note"; }
  .sec-viz-head { display: contents; }
  .sec-viz-head .eyebrow { grid-area: eyebrow; max-height: calc(var(--sv-tall) * 16); overflow: hidden; }
  .sec-viz-head h1 { grid-area: title; margin-top: calc(var(--sv-tall) * 6); }
  .sec-viz-head .lead { grid-area: lead; margin: var(--s-8) 0 0; }
  .sec-viz-note { margin-top: var(--s-5); }
  .sec-viz-stage { grid-template-columns: var(--sv-w) minmax(var(--sv-card), 132px); column-gap: 8px; justify-content: center; margin-top: var(--s-4); }
  .sec-viz-view--murmur { grid-column: 2; align-items: stretch; }
  .sec-viz-label { margin-bottom: var(--s-2); }
  .sec-viz-label__sub { max-height: calc(var(--sv-tall) * 18); overflow: hidden; }
  .sec-viz-view--you .sec-viz-label { align-self: flex-start; align-items: flex-start; text-align: left; }
  .sec-viz-view--murmur .sec-viz-label { align-self: flex-end; align-items: flex-end; text-align: right; }
  .sec-viz-ledger { flex: 1; border-radius: 20px; box-shadow: 0 0 0 1px var(--card-edge), var(--shadow-2); }
  .sec-viz-ledger__head { flex-direction: column; gap: 6px; padding: 10px 6px 8px; text-align: center; }
  .sec-viz-ledger__icon { width: 28px; height: 28px; border-radius: 8px; }
  .sec-viz-ledger .sec-viz-ledger__icon svg { width: 16px; height: 16px; }
  .sec-viz-ledger__title { font-size: 12px; line-height: 15px; white-space: normal; text-wrap: balance; }
  .sec-viz-ledger__sub { margin-top: 2px; font-size: 12px; line-height: 15px; white-space: normal; text-wrap: balance; }
  .sec-viz-ledger__list { padding: 0 6px; }
  .sec-viz-env { flex-direction: column; justify-content: center; gap: 3px; padding: 3px 0; }
  .sec-viz-ledger .sec-viz-env__art { width: min(60px, 62cqw); }
  .sec-viz-env__time { font-size: 12px; line-height: 15px; }
  .sec-viz-ledger__same { margin: 0 6px; padding: 6px 0; font-size: 12px; line-height: 15px; white-space: normal; text-wrap: balance; }
  .sec-viz-ledger__foot { flex-direction: column; gap: 3px; padding: 8px 6px 10px; font-size: 12px; line-height: 15px; text-align: center; white-space: normal; text-wrap: balance; }
  .sec-viz-ledger .sec-viz-ledger__foot svg { width: 14px; height: 14px; }
}
/* The smallest phones: the sheet is too short for the size's line, and the envelopes take a size down */
@media (max-width: 339px) {
  .sec-viz-ledger__same { display: none; }
  .sec-viz-ledger .sec-viz-env__art { width: 50cqw; }
}


/* ------------------------------------------------------------------------------------------------- 768 and up: side by side */
@media (min-width: 768px) {
  .sec-viz-hero { padding: var(--s-12) 0; }
  .sec-viz-head .lead { margin-top: var(--s-6); }
  .sec-viz-stage { display: grid; grid-template-columns: var(--sv-w) var(--sv-gap) var(--sv-w); align-items: start; width: auto; margin-top: var(--s-12); }
  .sec-viz-view--you { grid-column: 1; }
  .sec-viz-view--murmur { grid-column: 3; }
  .sec-viz-label { margin-bottom: var(--s-4); }
  .sec-viz-label__title { font-size: 17px; line-height: 22px; }
  .sec-viz-note { margin-top: var(--s-10); font-size: 16px; line-height: 24px; }
  /* the sheet: the same size as the phone */
  .sec-viz-ledger { aspect-ratio: 10 / 21; }
  /* the divider: a dashed line from top to bottom, the wax seal at its middle (64 px, in an 80 px column) */
  .sec-viz-divider { grid-column: 2; position: relative; display: block; align-self: stretch; margin-top: var(--sv-label-h); }
  .sec-viz-divider__line {
    position: absolute; left: 50%; top: 8%; bottom: 8%; margin-left: -1px; border-left: 2px dashed var(--outline-soft);
    -webkit-mask: linear-gradient(transparent, #000 14%, #000 calc(50% - 46px), transparent calc(50% - 46px), transparent calc(50% + 46px), #000 calc(50% + 46px), #000 86%, transparent);
    mask: linear-gradient(transparent, #000 14%, #000 calc(50% - 46px), transparent calc(50% - 46px), transparent calc(50% + 46px), #000 calc(50% + 46px), #000 86%, transparent);
  }
  .sec-viz-seal { position: absolute; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; }
  .sec-viz-seal__wax { position: relative; display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 1px 1px var(--sv-seal-contact)); }
  .sec-viz-seal__shadow { /* the soft shadow the wax casts on the page, a little below it */
    position: absolute; left: 6%; right: 6%; top: 18%; bottom: -10%; border-radius: 50%;
    background: radial-gradient(closest-side, var(--sv-seal-shade), transparent);
  }
}
/* A sheet under 260 px (short windows, down to 220 px): a tighter head and foot */
@media (min-width: 768px) {
  @container (max-width: 259px) {
    .sec-viz-ledger__head { padding: 14px 14px 12px; }
    .sec-viz-ledger__icon { width: 36px; height: 36px; border-radius: 10px; }
    .sec-viz-ledger .sec-viz-ledger__icon svg { width: 20px; height: 20px; }
    .sec-viz-ledger__title { font-size: 14px; line-height: 18px; }
    .sec-viz-ledger__sub { font-size: 12px; line-height: 16px; }
    .sec-viz-ledger__list { padding: 2px 14px 0; }
    .sec-viz-env { gap: 12px; padding: 4px 0; }
    .sec-viz-env__time { font-size: 14px; line-height: 18px; }
    .sec-viz-ledger__same { margin: 0 14px; padding: 6px 0 8px; font-size: 12px; line-height: 16px; }
    .sec-viz-ledger__foot { gap: 6px; padding: 10px 14px 12px; font-size: 13px; line-height: 18px; }
    .sec-viz-ledger .sec-viz-ledger__foot svg { width: 16px; height: 16px; }
  }
}
/* 768 to 1023: the title above, the two views below: the phone is 280 px, smaller in short windows (the header 64,
   the padding 48, the title 184, the gap 48, the labels 56 and 24 px of air keep 424 px), down to 220 px */
@media (min-width: 768px) and (max-width: 1023px) {
  .sec-viz-hero { --sv-w: clamp(220px, (100svh - 424px) / 2.1, 280px); }
}
/* 1024 and up: the text on the left, the two views on the right, within the site's 1200 px column (the idea cards'
   width too, .sec-grid in security.html). The text keeps 304 px at least, the gap 48, the divider 80: 432 px. The phone is what is left,
   split in two, and 300 px at most; in a short window it shrinks so the views stay whole (the header 64, the padding
   48, the labels 56 and 52 px of air keep 220 px), down to 220 px. */
@media (min-width: 1024px) {
  .sec-viz-hero { --sv-w: clamp(220px, min((100cqw - 432px) / 2, (100svh - 220px) / 2.1), 300px); }
  .sec-viz-grid {
    max-width: calc(var(--content-max) + 2 * var(--gutter));
    grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 1fr auto auto 1fr;
    grid-template-areas: ". stage" "head stage" "note stage" ". stage";
    column-gap: var(--s-12); justify-items: start; text-align: left;
  }
  /* the text block is centred on the two views, not on their labels: 56 px more above it */
  .sec-viz-head { margin-top: var(--sv-label-h); }
  .sec-viz-head .lead { margin-left: 0; margin-right: 0; }
  .sec-viz-stage { margin-top: 0; }
  .sec-viz-note { margin-top: var(--s-8); padding-top: var(--s-6); border-top: 1px solid var(--divider); }
}
@media (min-width: 1024px) and (max-height: 760px) { .sec-viz-hero { padding-top: var(--s-6); } }


/* ------------------------------------------------------------------------------------------------- Motion */
/* Only while JavaScript runs (html.js, set before the first paint) and motion is welcome. Until security-viz.js has
   built the story on its first frame (.is-ready), the views wait, invisible, for 1.5 s at most: if the script never
   comes, they show the still by themselves. With .is-ready they rise in (350 ms), once: .is-risen then drops the rise,
   so the divider, hidden below 768, never rises again when the window crosses 768. With .is-still (reduced motion, no
   Web Animations, an error) they show the still at once. */
@keyframes sec-viz-rise { from { opacity: 0; transform: translateY(16px); } }
@keyframes sec-viz-wait { from, to { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  html.js .sec-viz-hero :is(.sec-viz-phone, .sec-viz-divider, .sec-viz-ledger) { animation: sec-viz-wait 1.5s linear; }
  html.js .sec-viz-hero.is-ready :is(.sec-viz-phone, .sec-viz-divider, .sec-viz-ledger) { animation: sec-viz-rise var(--dur-lg) var(--ease) both; }
  html.js .sec-viz-hero:is(.is-still, .is-risen) :is(.sec-viz-phone, .sec-viz-divider, .sec-viz-ledger) { animation: none; }
}
/* An envelope in flight: a copy of a row's own drawing, laid over the stage by security-viz.js */
.sec-viz-fly {
  position: absolute; left: 0; top: 0; z-index: 3; display: block; overflow: visible; pointer-events: none; opacity: 0;
  transform-origin: 50% 50%; filter: drop-shadow(0 6px 10px var(--sv-fly-shadow));
}
.sec-viz-fly__ring { fill: none; stroke: var(--sv-ring); stroke-width: 1.6px; vector-effect: non-scaling-stroke; transform-box: fill-box; transform-origin: center; opacity: 0; }
@media (prefers-reduced-motion: reduce) { .sec-viz-fly { display: none; } }
/* Print: the still, whole, on one page; the drawings keep their fills even when the browser leaves out background
   graphics (Chrome's default) */
@media print {
  .sec-viz-stage { break-inside: avoid; }
  .sec-viz-phone, .sec-viz-divider, .sec-viz-ledger { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .sec-viz-fly, .sec-viz-touch, .sec-viz-toast { display: none !important; }
}
