/* Murmur site: the hero phone's demo (home-anim.css). index.html loads it after home.css, on the home page only, with
   home-anim.js.

   WHAT IT ADDS TO THE PHONE (.hero-phone .hpa, markup in index.html, section "H-1")
   - The still: the chat with Maude as it ends, with the "Pinned Message" bar under the header, one calm notice
     "You pinned a message", a pin in the time of "Come up Saturday?", and the ticks drawn in three layers (sent,
     delivered, read). It is all there is without JavaScript, with reduced motion and in print, and the moment of
     the demo just before it goes back to the Chats list. The phone itself (frame, screen grid, the app's tokens,
     status bar, header, notice, bubbles, composer) is in home.css.
   - The demo (about 60 s, once per page load, a pause after every step): App Lock, its first frame, shown from the
     first paint, for a few seconds; Face ID (the Dynamic Island grows into the Face ID square), the Chats list for a
     few seconds, then Maude starts typing in her row; her chat pushed in, her photo, the iOS keyboard and your
     replies typed key by key, her heart, a long press on "Come up Saturday?", Pin, "Pin for Me and Maude", the
     pinned bar and her last two messages; then back to the Chats list, where her row shows her last message, read,
     and there it stays. home-anim.js plays it with the Web Animations API (transform and opacity only). Its layers
     show only under .hpa--live, a class home-anim.js sets once the demo is built on its first frame (see "Still or
     demo" below).
   - Every screen is the app as it is today (the reference shots of the real app: the lock screen, Chats, the chat,
     typing, the long press, the Pin sheet, the pinned bar). Sizes are the app's points, calc(N * var(--pt)),
     --pt = 1/393 of the screen (home.css): the demo scales with the phone and never reflows. The iOS keyboard keeps
     its own 440-unit grid, --u. Colors are the site's tokens and the app's (home.css), plus the keyboard's grays
     below. Dark tokens are for screens only, as in site.css: print takes the light ones, whatever the theme.
   - Nothing here reaches outside the phone. */


/* ------------------------------------------------------------------------------------------------- tokens */
/* The finger, and the iOS keyboard's grays */
.hpa {
  --hpa-touch: rgb(60 60 67 / 0.20);
  --hpa-touch-ring: rgb(255 255 255 / 0.70);
  --kb-bg: #D1D4DA;
  --kb-key: #FFFFFF;
  --kb-fn: #ACB1BA;
  --kb-ink: #000000;
  --kb-shadow: rgb(0 0 0 / 0.30);
  --kb-sep: rgb(0 0 0 / 0.16);
  --kb-hl: #FFFFFF;
  --kb-press-key: #ACB1BA;
  --kb-press-fn: #FFFFFF;
}
/* Dark, on screens only (as in site.css): print takes the light tokens above */
@media screen {
  :root[data-theme="dark"] .hpa {
    --hpa-touch: rgb(235 235 245 / 0.26);
    --hpa-touch-ring: rgb(255 255 255 / 0.22);
    --kb-bg: #2B2B2E;
    --kb-key: #5F5F63;
    --kb-fn: #3E3E41;
    --kb-ink: #FFFFFF;
    --kb-shadow: rgb(0 0 0 / 0.55);
    --kb-sep: rgb(255 255 255 / 0.16);
    --kb-hl: #6E6E73;
    --kb-press-key: #3E3E41;
    --kb-press-fn: #5F5F63;
  }
}
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hpa {
    --hpa-touch: rgb(235 235 245 / 0.26);
    --hpa-touch-ring: rgb(255 255 255 / 0.22);
    --kb-bg: #2B2B2E;
    --kb-key: #5F5F63;
    --kb-fn: #3E3E41;
    --kb-ink: #FFFFFF;
    --kb-shadow: rgb(0 0 0 / 0.55);
    --kb-sep: rgb(255 255 255 / 0.16);
    --kb-hl: #6E6E73;
    --kb-press-key: #3E3E41;
    --kb-press-fn: #5F5F63;
  }
}


/* ------------------------------------------------------------------------------------------------- the still */
/* The chat is a page of its own (it slides in over the Chats list, its shadow on its left edge, outside the screen
   at rest); its content scrolls inside .hpa-scroll. */
.hpa-page { position: absolute; inset: 0; }
.hpa-chat { z-index: 2; display: flex; flex-direction: column; background: var(--bg); box-shadow: var(--app-page-edge); }
.hpa-scroll { position: relative; flex: none; display: flex; flex-direction: column; padding-top: calc(4 * var(--pt)); }

/* Header: one hairline under the whole header, the pinned bar included (as in the app): .hpa-hair while no message
   is pinned, then the pinned bar's own */
.hpa-hair { position: absolute; left: 0; right: 0; bottom: 0; border-bottom: calc(0.5 * var(--pt)) solid var(--app-bar-hair); opacity: 0; }
.hpa-sub { display: grid; min-width: 0; }
.hpa-sub > span { grid-area: 1 / 1; white-space: nowrap; }
.hpa-sub__b { color: var(--seal); opacity: 0; } /* "typing" over "online" */
/* the typing dots inside a line of text (the list, the header) */
.hpa-dots3 { display: inline-flex; align-items: center; gap: calc(2 * var(--pt)); margin-left: calc(3 * var(--pt)); vertical-align: calc(2 * var(--pt)); }
.hpa-dots3 i { width: calc(3.5 * var(--pt)); height: calc(3.5 * var(--pt)); border-radius: 50%; background: currentColor; }
@keyframes hpa-wave { 0%, 60%, 100% { opacity: 0.35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(calc(-1.5 * var(--pt))); } }

/* The pinned bar under the navigation bar (modules/chat/chat.css): the same material, which reaches 12 points up under
   the bar (hidden there), the wax track, "Pinned Message", the message, and Unpin, its glyph on the 16-point margin */
.hpa-pinbar {
  position: absolute; z-index: 2; top: calc(102 * var(--pt)); left: 0; right: 0; height: calc(60.5 * var(--pt));
  display: flex; align-items: center; gap: calc(10 * var(--pt)); padding: calc(12 * var(--pt)) calc(4 * var(--pt)) 0 calc(16 * var(--pt));
  background: var(--app-bar); border-bottom: calc(0.5 * var(--pt)) solid var(--app-bar-hair);
  -webkit-backdrop-filter: saturate(1.8) blur(calc(20 * var(--pt))); backdrop-filter: saturate(1.8) blur(calc(20 * var(--pt)));
}
.hpa-pinbar__track { flex: none; width: calc(2 * var(--pt)); height: calc(32 * var(--pt)); border-radius: calc(1 * var(--pt)); background: var(--seal); }
.hpa-pinbar__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hpa-pinbar__text b { font-size: calc(13 * var(--pt)); line-height: calc(17 * var(--pt)); font-weight: 600; letter-spacing: -0.003em; color: var(--seal); white-space: nowrap; }
.hpa-pinbar__text span { font-size: calc(15 * var(--pt)); line-height: calc(20 * var(--pt)); letter-spacing: -0.009em; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hpa-pinbar__x { display: grid; place-items: center; flex: none; width: calc(44 * var(--pt)); height: calc(44 * var(--pt)); margin-left: calc(-6 * var(--pt)); color: var(--text-2); }
.hp__screen .hpa-pinbar__x svg { width: calc(20 * var(--pt)); height: calc(20 * var(--pt)); }

/* Messages: they grow from the corner they belong to. A message that changed during the demo (the pin, the heart)
   has its earlier version laid over the still's (.hpa-before, shown in the demo only). */
.hpa .hp-group--in :is(.hp-b, .hp-swap) { transform-origin: 0 100%; }
.hpa .hp-group--out :is(.hp-b, .hp-swap) { transform-origin: 100% 100%; }
.hp-swap { position: relative; display: flex; flex-direction: column; }
.hp-group--in .hp-swap { align-items: flex-start; }
.hp-group--out .hp-swap { align-items: flex-end; }
.hpa-before { display: none; }
.hpa-tk { display: grid; flex: none; }
.hpa-tk > svg { grid-area: 1 / 1; }
.hp__screen .hpa-tk > svg:not(:last-child) { color: var(--bubble-out-meta); opacity: 0; } /* sent and delivered */
.hp-rx__chip { transform-origin: 30% 60%; }
.hpa .hp-sys { transform-origin: 50% 100%; }

/* Composer: the text you type, a cover that uncovers it letter by letter, the caret, the focus ring, and Send: the wax
   that grows over the round button at the field's right while there is text, over the microphone (as in the app,
   Composer.tsx and chat/composer.css) */
.hpa .hp-field__ph { z-index: 1; } /* over the typed text's cover */
.hpa-focus { position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 calc(1 * var(--pt)) var(--app-field-focus); opacity: 0; }
/* the text starts on the field's 14-point inset; its box starts 2 points earlier, so the caret, centered on the
   text's start, shows whole in an empty field */
.hpa-type { position: absolute; left: calc(12 * var(--pt)); right: calc(14 * var(--pt)); top: calc(7 * var(--pt)); height: calc(22 * var(--pt)); overflow: hidden; }
.hpa-type__row {
  position: absolute; left: calc(2 * var(--pt)); top: 0; opacity: 0; white-space: pre;
  font-size: calc(17 * var(--pt)); line-height: calc(22 * var(--pt)); letter-spacing: -0.013em; color: var(--text);
}
.hpa-type__cover { position: absolute; top: 0; bottom: 0; left: calc(2 * var(--pt)); width: 100%; background: var(--app-field); }
.hpa-caret {
  position: absolute; z-index: 2; left: calc(1 * var(--pt)); top: calc(0.5 * var(--pt)); width: calc(2 * var(--pt)); height: calc(21 * var(--pt));
  border-radius: calc(1 * var(--pt)); background: var(--seal); opacity: 0;
}
.hpa-send {
  position: absolute; z-index: 1; left: calc(4 * var(--pt)); top: calc(4 * var(--pt)); display: grid; place-items: center;
  width: calc(36 * var(--pt)); height: calc(36 * var(--pt)); border-radius: 50%; opacity: 0; transform: scale(0.4);
  background: var(--app-brand); color: var(--on-brand); box-shadow: inset 0 -1px 0 rgb(0 0 0 / 0.12), inset 0 1px 0 rgb(255 255 255 / 0.18);
}
.hp__screen .hpa-send svg { width: calc(20 * var(--pt)); height: calc(20 * var(--pt)); }
/* The seal press when you send (app.css .seal-press): the arrow goes at once (the button leaves with the text), the
   plain wax disc stamps down and lifts away, and a wax ring spreads 9 points around it as it fades. The ring is a
   disc under the button, 9 points wider on each side, scaled up from the button's size (transform and opacity only). */
.hpa-ring {
  position: absolute; z-index: 1; left: calc(-5 * var(--pt)); top: calc(-5 * var(--pt)); width: calc(54 * var(--pt)); height: calc(54 * var(--pt));
  border-radius: 50%; background: color-mix(in srgb, var(--seal) 55%, transparent); opacity: 0; transform: scale(0.667);
}


/* ------------------------------------------------------------------------------------------------- layers of the demo */
/* Shown only under .hpa--live (see "Still or demo" below). Each one rests on the still's frame (hidden, off screen
   or transparent), so showing them changes nothing until the demo moves them. The global status bar replaces the
   chat's own, which slides with its page: the status bar of an iPhone never moves. */
.hpa-status { position: absolute; z-index: 5; top: 0; left: 0; right: 0; }
.hpa-touch {
  position: absolute; z-index: 4; left: 0; top: 0; width: calc(40 * var(--pt)); height: calc(40 * var(--pt)); border-radius: 50%;
  background: var(--hpa-touch); box-shadow: inset 0 0 0 calc(1.5 * var(--pt)) var(--hpa-touch-ring); opacity: 0; pointer-events: none;
}

/* A check that draws itself from left to right: the window slides in while its content slides back (transforms only) */
.hpa-wipe { position: absolute; display: block; overflow: hidden; transform: translateX(-100%); }
.hpa-wipe__in { display: block; width: 100%; height: 100%; transform: translateX(100%); }
.hp__screen .hpa-wipe svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; overflow: visible; }

/* App Lock (modules/settings: the lock screen and its keypad, with the Face ID key): the seal, "Unlock Murmur",
   "Enter your PIN" (it stays while iOS looks for your face), the PIN dots, the keypad. It is the demo's first frame, opaque, so it shows whole as soon as it is displayed (see
   "Still or demo" below). */
.hpa-lock { z-index: 4; background: var(--app-hero); }
.hpa-lock__in { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; padding-top: calc(118 * var(--pt)); text-align: center; } /* the block centred between the status bar and "Use Password Instead", as in the app */
.hp__screen .hpa-lock__seal { width: calc(64 * var(--pt)); height: calc(64 * var(--pt)); margin-bottom: calc(16 * var(--pt)); overflow: visible; filter: drop-shadow(0 calc(6 * var(--pt)) calc(14 * var(--pt)) var(--app-seal-shadow)); }
.hpa-mk-l { display: var(--app-mark-l); }
.hpa-mk-d { display: var(--app-mark-d); }
.hpa-lock__title { font-size: calc(22 * var(--pt)); line-height: calc(28 * var(--pt)); font-weight: 700; letter-spacing: -0.018em; color: var(--text); }
.hpa-lock__sub {
  display: grid; place-items: center; min-height: calc(40 * var(--pt)); margin: calc(4 * var(--pt)) 0 calc(14 * var(--pt));
  font-size: calc(15 * var(--pt)); line-height: calc(20 * var(--pt)); letter-spacing: -0.009em; color: var(--text-2);
}
.hpa-pin { display: flex; gap: calc(18 * var(--pt)); height: calc(14 * var(--pt)); }
.hpa-pin i { width: calc(14 * var(--pt)); height: calc(14 * var(--pt)); border-radius: 50%; box-shadow: inset 0 0 0 calc(1.5 * var(--pt)) var(--outline); }
.hpa-pad { display: grid; grid-template-columns: repeat(3, calc(76 * var(--pt))); column-gap: calc(28 * var(--pt)); row-gap: calc(16 * var(--pt)); margin-top: calc(40 * var(--pt)); }
.hpa-k {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(1 * var(--pt));
  width: calc(76 * var(--pt)); height: calc(76 * var(--pt)); border-radius: 50%; background: var(--container); color: var(--text);
}
.hpa-k b { font-size: calc(32 * var(--pt)); line-height: calc(36 * var(--pt)); font-weight: 400; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.hpa-k small { min-height: calc(12 * var(--pt)); padding-left: 0.05em; font-size: calc(10 * var(--pt)); line-height: calc(12 * var(--pt)); font-weight: 600; letter-spacing: 0.1em; color: var(--text-2); }
.hpa-k--abc { padding-bottom: calc(3 * var(--pt)); }
.hpa-k--one { padding-top: calc(2 * var(--pt)); }
.hpa-k--fid { background: var(--accent-container); color: var(--seal); }
.hpa-k--del { background: transparent; }
.hpa-fid__ok { position: absolute; inset: 0; border-radius: 50%; background: var(--success-container); opacity: 0; }
.hp__screen .hpa-fid {
  position: absolute; left: 50%; top: 50%; width: calc(34 * var(--pt)); height: calc(34 * var(--pt)); margin: calc(-17 * var(--pt)) 0 0 calc(-17 * var(--pt));
  fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round;
}
.hp__screen .hpa-fid--ok { color: var(--success); opacity: 0; }
/* the key's check: the glyph's check (17 to 48 by 21 to 45 of its 64 units) at the key's 34-point glyph size */
.hpa-fid-check {
  left: calc(50% - 7.97 * var(--pt)); top: calc(50% - 5.84 * var(--pt)); width: calc(16.47 * var(--pt)); height: calc(12.75 * var(--pt));
  color: var(--success);
}
.hpa-lock__link {
  position: absolute; left: 0; right: 0; bottom: calc(52 * var(--pt)); height: calc(44 * var(--pt)); line-height: calc(44 * var(--pt));
  font-size: calc(17 * var(--pt)); letter-spacing: -0.013em; color: var(--link);
}

/* Face ID in the Dynamic Island: the island grows into the Face ID square and back. Drawn by home-anim.js from six
   black pieces (two bars and four discs) that make an exact rounded rectangle at every frame while they move, so the
   corners never stretch; the white glyph scans, then turns into a check. */
.hpa-isl { position: absolute; z-index: 6; inset: 0; pointer-events: none; }
.hpa-isl__p, .hpa-isl__sq { position: absolute; background: #000000; opacity: 0; }
.hpa-isl__p.is-round { border-radius: 50%; }
.hpa-isl__g { position: absolute; color: #FFFFFF; opacity: 0; }
.hp__screen .hpa-isl__g > svg { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }

/* Chats (the app today, app.css and modules/chat): the large title "Chats" with New Message on its line (its glyph on
   the right margin), the search field under it at full width, then the chats, the first row's avatar 34 points under
   the search field; the tab bar. One list, no folders. A pinned chat has a slight tint behind its whole row, its pin at
   the end of the preview line, and no separator runs along it; a green dot on the avatar of someone who shares that they are online. */
.hpa-list { z-index: 1; overflow: hidden; opacity: 0; background: var(--bg); color: var(--text); }
.hpa-list__title {
  position: absolute; top: calc(98 * var(--pt)); left: 0; right: 0; margin: 0; padding: calc(3 * var(--pt)) calc(16 * var(--pt)) calc(8 * var(--pt));
  font-size: calc(34 * var(--pt)); line-height: calc(41 * var(--pt)); font-weight: 700; letter-spacing: -0.022em; color: var(--text);
}
.hp__screen .hpa-list__compose { position: absolute; top: calc(109.5 * var(--pt)); right: calc(13.5 * var(--pt)); width: calc(24 * var(--pt)); height: calc(24 * var(--pt)); color: var(--link); }
.hpa-search {
  position: absolute; top: calc(150 * var(--pt)); left: calc(16 * var(--pt)); right: calc(16 * var(--pt)); height: calc(36 * var(--pt));
  display: flex; align-items: center; gap: calc(6 * var(--pt)); padding: 0 calc(8 * var(--pt)); border-radius: calc(10 * var(--pt));
  background: var(--container); color: var(--text-2);
}
.hp__screen .hpa-search svg { width: calc(17 * var(--pt)); height: calc(17 * var(--pt)); }
.hpa-search span { font-size: calc(17 * var(--pt)); line-height: calc(22 * var(--pt)); letter-spacing: -0.013em; color: var(--text-2); }
/* The rows: 76 points, the avatar (56) on the margin, the text 12 points after it; a hairline between rows, from the text */
.hpa-rows { position: absolute; top: calc(210 * var(--pt)); left: 0; right: 0; }
.hpa-row { --ring: var(--bg); position: relative; display: flex; align-items: center; height: calc(76 * var(--pt)); padding-left: calc(16 * var(--pt)); }
.hpa-row.is-pinned { --ring: var(--app-row-pinned); background: var(--app-row-pinned); }
.hpa-row__hl { position: absolute; inset: 0; background: var(--container-2); opacity: 0; }
.hpa-av {
  position: relative; flex: none; display: grid; place-items: center; width: calc(56 * var(--pt)); height: calc(56 * var(--pt)); margin-right: calc(12 * var(--pt)); 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(21 * var(--pt)); line-height: 1; font-weight: 600; letter-spacing: 0.01em;
}
.hpa-av--emoji { background: color-mix(in srgb, var(--av) var(--app-emoji-mix), var(--surface)); font-size: calc(28 * var(--pt)); }
.hpa-av--emoji img.emoji { margin: 0; }
.hpa-av--vault { background: linear-gradient(180deg, #4B5B79, #313D53); color: #FFFFFF; }
.hp__screen .hpa-av--vault svg { width: calc(32 * var(--pt)); height: calc(32 * var(--pt)); }
/* online (Last Seen & Online): an 11-point green dot at the avatar's bottom right, ringed with the row's colour */
.hpa-on { position: absolute; left: calc(42 * var(--pt)); top: calc(42 * var(--pt)); width: calc(11 * var(--pt)); height: calc(11 * var(--pt)); border-radius: 50%; background: var(--success); box-shadow: 0 0 0 calc(2 * var(--pt)) var(--ring); }
.hpa-row__main {
  position: relative; flex: 1; min-width: 0; align-self: stretch; display: flex; flex-direction: column; justify-content: center;
  gap: calc(2 * var(--pt)); padding: calc(11 * var(--pt)) calc(16 * var(--pt)) calc(10 * var(--pt)) 0;
}
.hpa-sep { position: absolute; top: 0; left: 0; right: 0; border-top: calc(0.5 * var(--pt)) solid var(--divider); }
.hpa-row__top { display: flex; align-items: center; gap: calc(8 * var(--pt)); }
.hpa-row__top b { flex: 1; min-width: 0; font-size: calc(17 * var(--pt)); line-height: calc(22 * var(--pt)); font-weight: 600; letter-spacing: -0.013em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hpa-row__top time { flex: none; font-size: calc(15 * var(--pt)); line-height: calc(20 * var(--pt)); letter-spacing: -0.009em; color: var(--text-2); font-variant-numeric: tabular-nums; }
.hpa-row__top time.is-unread { color: var(--seal); font-weight: 500; }
.hpa-row__meta { flex: none; display: flex; align-items: center; gap: calc(3 * var(--pt)); }
.hp__screen .hpa-row__tk { width: calc(18 * var(--pt)); height: calc(12 * var(--pt)); color: var(--tick-read); fill: none; }
.hpa-row__bot { display: flex; align-items: center; gap: calc(8 * var(--pt)); min-height: calc(22 * var(--pt)); }
.hpa-row__pv { flex: 1; min-width: 0; font-size: calc(15 * var(--pt)); line-height: calc(20 * var(--pt)); letter-spacing: -0.009em; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hpa-row__pv b { font-weight: 500; color: var(--text); }
.hpa-row__pv.is-typing { color: var(--seal); }
/* A pinned chat keeps its 15-point pin at the end of the preview line, in the third text color (.chat-flag) */
.hp__screen .hpa-row__flag { flex: none; width: calc(15 * var(--pt)); height: calc(15 * var(--pt)); color: var(--text-3); }
.hp__screen .hpa-row__pv svg { display: inline-block; width: calc(15 * var(--pt)); height: calc(15 * var(--pt)); margin-right: calc(4 * var(--pt)); vertical-align: calc(-2 * var(--pt)); color: var(--text-3); }
/* Maude's row holds its three moments in one place: her "Good morning!" (9:30 AM), then "typing", then her last
   message, read (9:41 AM). home-anim.js swaps them; the last one while the list is out of sight, under the chat. */
.hpa-swap { flex: 1; min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.hpa-swap > * { grid-area: 1 / 1; }
.hpa-swap > :not(:first-child) { opacity: 0; }
.hpa-swap--time { flex: none; grid-template-columns: auto; justify-items: end; }
.hpa-badge {
  flex: none; min-width: calc(20 * var(--pt)); height: calc(20 * var(--pt)); padding: 0 calc(6 * var(--pt)); border-radius: calc(10 * var(--pt));
  background: var(--seal); color: var(--on-brand); text-align: center;
  font-size: calc(13 * var(--pt)); line-height: calc(20 * var(--pt)); font-weight: 600; letter-spacing: 0; font-variant-numeric: tabular-nums;
}
/* The tab bar: 49 points and the home zone, its items centered above the home indicator, 28-point icons (filled when
   selected), 10-point labels, the count on Chats (ui/TabBar.tsx) */
.hpa-tabs {
  position: absolute; left: 0; right: 0; bottom: 0; height: calc(83 * var(--pt)); display: flex; padding-bottom: calc(13 * var(--pt));
  background: var(--app-bar); border-top: calc(0.5 * var(--pt)) solid var(--app-bar-hair);
  -webkit-backdrop-filter: saturate(1.8) blur(calc(20 * var(--pt))); backdrop-filter: saturate(1.8) blur(calc(20 * var(--pt)));
}
.hpa-tab {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(2 * var(--pt));
  color: var(--text-3); font-size: calc(10 * var(--pt)); line-height: calc(12 * var(--pt)); font-weight: 500; letter-spacing: 0.01em; white-space: nowrap;
}
.hpa-tab.is-on { color: var(--seal); }
.hpa-tab__i { position: relative; display: grid; place-items: center; height: calc(28 * var(--pt)); }
.hp__screen .hpa-tab__i svg { width: calc(28 * var(--pt)); height: calc(28 * var(--pt)); }
.hpa-tab__i b {
  position: absolute; top: calc(-3 * var(--pt)); left: calc(50% + 6 * var(--pt)); min-width: calc(18 * var(--pt)); height: calc(18 * var(--pt)); padding: 0 calc(5 * var(--pt));
  border-radius: calc(9 * var(--pt)); background: var(--seal); color: var(--on-brand); box-shadow: 0 0 0 calc(1.5 * var(--pt)) var(--bg);
  font-size: calc(12 * var(--pt)); line-height: calc(18 * var(--pt)); font-weight: 600; letter-spacing: 0; text-align: center;
}
.hpa-list__dim { position: absolute; inset: 0; background: var(--app-push-dim); opacity: 0; }

/* The iOS keyboard (drawn by home-anim.js on its own 440-unit grid, --u): suggestions, letters, the 123 plane, the
   emoji key, the key pop-ups. Its emoji are Apple's images, like the app's. */
.hpa-kb { position: absolute; z-index: 4; left: 0; right: 0; bottom: 0; height: calc(346 * var(--u)); background: var(--kb-bg); transform: translateY(103%); }
.hpa-pred { position: absolute; top: 0; left: 0; right: 0; height: calc(44 * var(--u)); overflow: hidden; }
.hpa-pred__sep { position: absolute; top: calc(11 * var(--u)); width: 1px; height: calc(22 * var(--u)); background: var(--kb-sep); }
.hpa-pred__hl { position: absolute; top: calc(5 * var(--u)); left: calc(152 * var(--u)); width: calc(136 * var(--u)); height: calc(34 * var(--u)); border-radius: calc(9 * var(--u)); background: var(--kb-hl); opacity: 0; }
.hpa-pred__strip { position: relative; display: block; }
.hpa-pred__row { display: flex; height: calc(44 * var(--u)); }
.hpa-pred__row > span {
  flex: 1 1 0; min-width: 0; display: grid; place-items: center; overflow: hidden; white-space: nowrap;
  font-size: calc(17 * var(--u)); letter-spacing: -0.013em; color: var(--kb-ink);
}
.hpa-pred__row img.emoji { margin: 0; }
.hpa-kb__plane { position: absolute; left: 0; right: 0; top: calc(44 * var(--u)); bottom: 0; background: var(--kb-bg); }
.hpa-kb__up, .hpa-kb__num { opacity: 0; }
.hpa-key {
  position: absolute; display: grid; place-items: center; border-radius: calc(6 * var(--u));
  background: var(--kb-key); color: var(--kb-ink); box-shadow: 0 calc(1 * var(--u)) 0 var(--kb-shadow);
  font-size: calc(24 * var(--u)); line-height: 1; white-space: nowrap;
}
.hpa-key.is-fn { background: var(--kb-fn); font-size: calc(16 * var(--u)); letter-spacing: -0.01em; }
.hpa-key.is-word { font-size: calc(16 * var(--u)); letter-spacing: -0.01em; }
.hpa-key.is-on { background: var(--kb-key); }
.hp__screen .hpa-key svg { width: calc(24 * var(--u)); height: calc(24 * var(--u)); }
.hpa-key__press { position: absolute; z-index: 1; border-radius: calc(6 * var(--u)); opacity: 0; }
.hpa-key__press--key { background: var(--kb-press-key); }
.hpa-key__press--fn { background: var(--kb-press-fn); }
.hpa-key__press > span { position: absolute; inset: 0; display: grid; place-items: center; font-size: calc(16 * var(--u)); letter-spacing: -0.01em; color: var(--kb-ink); }
.hp__screen .hpa-kb__emoji { position: absolute; left: calc(20 * var(--u)); top: calc(286 * var(--u)); width: calc(28 * var(--u)); height: calc(28 * var(--u)); color: var(--kb-ink); opacity: 0.85; }
.hpa-co { position: absolute; z-index: 2; left: 0; top: 0; opacity: 0; pointer-events: none; }
.hp__screen .hpa-co svg { position: absolute; left: 0; top: 0; overflow: visible; fill: var(--kb-key); filter: drop-shadow(0 calc(1 * var(--u)) calc(2.5 * var(--u)) rgb(0 0 0 / 0.30)); }
.hpa-co__win { position: absolute; left: 0; top: 0; overflow: hidden; }
.hpa-co__strip { display: flex; }
.hpa-co__strip > span { flex: none; display: grid; place-items: center; font-size: calc(38 * var(--u)); line-height: 1; color: var(--kb-ink); }

/* Long press on a message (app/overlays/Overlays.tsx): the blur, the reactions (52 points, Apple's emoji, the "+"
   disc), the lifted bubble, and the menu (250 points, 44-point rows: Reply, Copy, Pin, Forward, Save to Vault, Info,
   then Delete after a thick separator). For a message
   you received, all three sit on the bubble's side, the 16-point margin. */
.hpa-menu { z-index: 3; }
.hpa-menu__blur {
  position: absolute; inset: 0; background: var(--app-wash); opacity: 0;
  -webkit-backdrop-filter: blur(calc(16 * var(--pt))) saturate(1.5); backdrop-filter: blur(calc(16 * var(--pt))) saturate(1.5);
}
.hpa-rx {
  position: absolute; left: calc(16 * var(--pt)); top: 0; display: flex; align-items: center; height: calc(52 * var(--pt)); padding: 0 calc(6 * var(--pt));
  border-radius: calc(26 * var(--pt)); background: var(--app-menu); opacity: 0; transform-origin: 0 100%;
  box-shadow: 0 calc(8 * var(--pt)) calc(30 * var(--pt)) rgb(0 0 0 / 0.14), 0 0 0 calc(0.5 * var(--pt)) var(--app-sep);
  -webkit-backdrop-filter: blur(calc(30 * var(--pt))); backdrop-filter: blur(calc(30 * var(--pt)));
}
.hpa-rx > span { display: grid; place-items: center; width: calc(44 * var(--pt)); height: calc(44 * var(--pt)); border-radius: calc(22 * var(--pt)); font-size: calc(27 * var(--pt)); line-height: 1; }
.hpa-rx img.emoji { margin: 0; }
.hpa-rx > .hpa-rx__more { width: calc(34 * var(--pt)); height: calc(34 * var(--pt)); margin-left: calc(4 * var(--pt)); border-radius: 50%; background: var(--app-more); color: var(--text-2); }
.hp__screen .hpa-rx__more svg { width: calc(20 * var(--pt)); height: calc(20 * var(--pt)); }
.hpa .hpa-lift { position: absolute; top: 0; left: 0; margin: 0; border-radius: calc(18 * var(--pt)) calc(18 * var(--pt)) calc(18 * var(--pt)) calc(7.8 * var(--pt)); opacity: 0; transform-origin: 50% 50%; box-shadow: var(--app-lift); }
.hpa-cm {
  position: absolute; top: 0; left: calc(16 * var(--pt)); width: calc(250 * var(--pt)); overflow: hidden; border-radius: calc(8 * var(--pt));
  background: var(--app-menu); opacity: 0; transform-origin: 0 0;
  box-shadow: 0 calc(12 * var(--pt)) calc(40 * var(--pt)) rgb(0 0 0 / 0.16), 0 0 0 calc(0.5 * var(--pt)) var(--app-sep);
  -webkit-backdrop-filter: saturate(1.8) blur(calc(30 * var(--pt))); backdrop-filter: saturate(1.8) blur(calc(30 * var(--pt)));
}
.hpa-cm__i {
  position: relative; display: flex; align-items: center; justify-content: space-between; gap: calc(12 * var(--pt)); height: calc(44 * var(--pt)); padding: 0 calc(16 * var(--pt));
  font-size: calc(17 * var(--pt)); line-height: calc(22 * var(--pt)); letter-spacing: -0.013em; color: var(--text); white-space: nowrap;
}
.hpa-cm__i + .hpa-cm__i { border-top: calc(0.5 * var(--pt)) solid var(--app-sep); }
.hpa-cm__i.is-del { border-top: calc(8 * var(--pt)) solid var(--app-sep-thick); color: var(--error); }
.hpa-cm__i > span, .hpa-cm__i > svg { position: relative; }
.hpa-cm__i > .hpa-cm__hl { position: absolute; }
.hp__screen .hpa-cm__i > svg { width: calc(20 * var(--pt)); height: calc(20 * var(--pt)); }
.hpa-cm__hl { position: absolute; inset: 0; background: var(--app-press); opacity: 0; }

/* The action sheet of "Pin" (app.css "Alerts and action sheets"): Pin for Me, Pin for Me and Maude, Cancel. Its
   choices are in the text color; Cancel alone is semibold. */
.hpa-sheet { z-index: 3; }
.hpa-sheet__dim { position: absolute; inset: 0; background: var(--app-sheet-dim); opacity: 0; }
.hpa-sheet__box { position: absolute; left: calc(8 * var(--pt)); right: calc(8 * var(--pt)); bottom: calc(34 * var(--pt)); display: flex; flex-direction: column; gap: calc(8 * var(--pt)); transform: translateY(150%); }
.hpa-sheet__g {
  overflow: hidden; border-radius: calc(14 * var(--pt)); background: var(--app-thick);
  -webkit-backdrop-filter: saturate(1.8) blur(calc(30 * var(--pt))); backdrop-filter: saturate(1.8) blur(calc(30 * var(--pt)));
}
.hpa-sheet__i { position: relative; display: grid; place-items: center; height: calc(57 * var(--pt)); padding: 0 calc(16 * var(--pt)); font-size: calc(20 * var(--pt)); letter-spacing: -0.017em; color: var(--text); white-space: nowrap; }
.hpa-sheet__i + .hpa-sheet__i { border-top: calc(0.5 * var(--pt)) solid var(--app-sep); }
.hpa-sheet__i.is-cancel { font-weight: 600; }
.hpa-sheet__i > span { position: relative; }
.hpa-sheet__i > .hpa-sheet__hl { position: absolute; }
.hpa-sheet__hl { position: absolute; inset: 0; background: var(--app-press); opacity: 0; }


/* ------------------------------------------------------------------------------------------------- still or demo */
/* The still (the chat with Maude as it ends): no JavaScript, reduced motion, print, a browser without the Web
   Animations API, or a demo that failed (home-anim.js then sets .hpa--still). Otherwise, from the first paint (the
   .js class is set in the head), the demo's first frame: the lock screen and the status bar over the still, which the
   opaque lock hides, so the still never shows first, even before the phone comes into view. home-anim.js sets
   .hpa--live once the demo is built on that same frame; the demo's layers then show, each resting where the first
   frame has it, so nothing jumps. */
.hpa :is(.hpa-lock, .hpa-list, .hpa-kb, .hpa-menu, .hpa-sheet, .hpa-touch, .hpa-status, .hpa-isl) { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .js .hpa:not(.hpa--still) :is(.hpa-lock, .hpa-status) { display: block; }
  .js .hpa:not(.hpa--still) .hpa-status { display: flex; }
  /* until then, the parts the demo animates first get the layers their animations will give them, so the first frame
     is drawn the same way before and after (its text does not shimmer when the demo starts) */
  .js .hpa:not(.hpa--still):not(.hpa--live) :is(.hpa-lock, .hpa-k--fid, .hpa-fid) { will-change: transform, opacity; }
  /* the keyboard, the heaviest layer, comes one idle moment later (.hpa--kb), so that no single layout is long */
  .hpa--live :is(.hpa-lock, .hpa-list, .hpa-menu, .hpa-sheet, .hpa-touch, .hpa-isl) { display: block; }
  .hpa--live .hpa-status { display: flex; }
  .hpa--live.hpa--kb .hpa-kb { display: block; }
  .hpa--live .hp-top > .hp-status { visibility: hidden; }
  /* a message's earlier version, over the still's */
  .hpa--live .hpa-before { display: block; position: absolute; top: 0; width: max-content; max-width: calc(274.36 * var(--pt)); }
  .hpa--live .hp-group--in .hpa-before { left: 0; }
  .hpa--live .hp-group--out .hpa-before { right: 0; }
  /* the typing dots wave only while the demo can run (home-anim.js pauses them with the rest) */
  .hpa--live .hpa-dots3 i { animation: hpa-wave 1.2s ease-in-out infinite; }
  .hpa--live .hpa-dots3 i:nth-child(2) { animation-delay: 0.15s; }
  .hpa--live .hpa-dots3 i:nth-child(3) { animation-delay: 0.3s; }
  .hpa--live .hp-typing i { animation: hpa-typing 1.3s ease-in-out infinite; }
  .hpa--live .hp-typing i:nth-child(2) { animation-delay: 0.18s; }
  .hpa--live .hp-typing i:nth-child(3) { animation-delay: 0.36s; }
}
@keyframes hpa-typing { 0%, 60%, 100% { opacity: 0.35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(calc(-3 * var(--pt))); } }
@media print {
  .hpa :is(.hpa-lock, .hpa-list, .hpa-kb, .hpa-menu, .hpa-sheet, .hpa-touch, .hpa-status, .hpa-isl, .hpa-before) { display: none !important; }
  .hpa .hp-top > .hp-status { visibility: visible !important; }
}
