:root {
  --bg: #050506;
  --fg: #f6f6f4;
  --fg-muted: rgba(246, 246, 244, 0.64);
  --fg-faint: rgba(246, 246, 244, 0.4);
  --glass: rgba(28, 28, 32, 0.56);
  --glass-strong: rgba(22, 22, 26, 0.78);
  --hairline: rgba(255, 255, 255, 0.12);
  --green: #2ec27e;
  --red: #e5484d;
  --amber: #f5b14c;
  --radius: 20px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --gutter: 16px;
  --ctl-size: 58px;
  --controls-bottom: calc(var(--safe-bottom) + 20px);
  /* The subtitles and email card live between the top bar and the controls. */
  --dock-top: calc(var(--safe-top) + 72px);
  --dock-bottom: calc(var(--controls-bottom) + var(--ctl-size) + 14px);
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}

button { font: inherit; color: inherit; cursor: pointer; }
svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* Every dvh below has a %/vh fallback first: browsers without dvh (Chrome
   before 108, Samsung Internet before 21) drop the dvh line and keep it. */
.stage {
  position: fixed;
  inset: 0;
  height: 100%;
  height: 100dvh;
  overflow: hidden;
  background: var(--bg);
}

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

.backdrop {
  position: absolute;
  inset: -40px;
  background: url("assets/abhinav-portrait.webp") center 30% / cover no-repeat;
  filter: blur(36px) brightness(0.45) saturate(1.1);
  transform: scale(1.1);
}

.tile {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

#persona-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  background: transparent;
  opacity: 0;
  transition: opacity 700ms var(--ease);
}

body[data-state="live"] #persona-video,
body[data-state="ending"] #persona-video { opacity: 1; }

/* Top and bottom scrims keep chrome and subtitles legible over a bright frame. */
.tile::before,
.tile::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
  z-index: 1;
}
.tile::before {
  top: 0;
  height: calc(140px + var(--safe-top));
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.55), transparent);
}
.tile::after {
  bottom: 0;
  height: 62%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.86) 0%, rgba(0, 0, 0, 0.6) 45%, transparent 100%);
}

/* Shown when the browser only allows muted autoplay. */
.sound-pill {
  position: absolute;
  z-index: 3;
  top: calc(var(--safe-top) + 72px);
  left: 0;
  right: 0;
  width: fit-content;
  margin: 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 18px 0 14px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--glass-strong);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  font-size: 15px;
  font-weight: 500;
  animation: rise 400ms var(--ease) both;
}
.sound-pill[hidden],
body:not([data-state="live"]) .sound-pill { display: none; }
.sound-pill svg { width: 20px; height: 20px; }

/* ---------- top bar ---------- */

.topbar {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: calc(var(--safe-top) + 14px) calc(var(--safe-right) + var(--gutter)) 0 calc(var(--safe-left) + var(--gutter));
}

/* Glass pill like the timer: the name stays readable over a bright frame. */
.who {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 4px 14px 4px 4px;
  border-radius: 999px;
  background: var(--glass-strong);
  border: 1px solid var(--hairline);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
}
.who-photo {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center 20%;
  border: 1px solid var(--hairline);
}
.who-name { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.who-meta { font-size: 12px; color: rgba(246, 246, 244, 0.76); margin-top: 1px; }

.live-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px;
  border-radius: 999px;
  background: var(--glass);
  border: 1px solid var(--hairline);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 0 rgba(46, 194, 126, 0.6);
  animation: pulse-dot 2s infinite;
}

/* ---------- in-video dock: subtitles and email card ---------- */

/* Bounded on both sides, so subtitles shrink instead of running under the
   top bar, whatever the screen height, email card or keyboard. While the
   email field has focus app.js sets --keyboard-inset (how much of the
   layout viewport the keyboard covers) and the dock rides above it. */
.tile-dock {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  top: var(--dock-top);
  bottom: max(var(--dock-bottom), calc(var(--keyboard-inset, 0px) + 12px));
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 14px;
  padding: 0 calc(var(--safe-right) + var(--gutter)) 0 calc(var(--safe-left) + var(--gutter));
  pointer-events: none;
}
.sound-pill:not([hidden]) ~ .tile-dock { top: calc(var(--dock-top) + 56px); }
/* If a short screen and the keyboard leave too little room, the card wins
   over the top bar: its field and Submit stay above the keyboard. The
   controls stay above the subtitle plate. */
body.email-open .tile-dock { z-index: 3; }
body.email-open .controls { z-index: 4; }

.tile-dock > * { flex: none; width: 100%; max-width: 640px; pointer-events: auto; }

/* Outside the call the chrome is invisible, so it must also be unfocusable
   and silent to screen readers: visibility flips after the fade out and
   before the fade in. */
.topbar, .tile-dock, .controls { transition: opacity 400ms var(--ease), transform 400ms var(--ease), visibility 0s; }
body:not([data-state="live"]):not([data-state="ending"]) :is(.topbar, .tile-dock, .controls) {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 400ms var(--ease), transform 400ms var(--ease), visibility 0s 400ms;
}
body:not([data-state="live"]):not([data-state="ending"]) .tile-dock > * { pointer-events: none; }
body:not([data-state="live"]):not([data-state="ending"]) :is(.tile-dock, .controls) { transform: translateY(12px); }

.captions {
  position: relative;
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Backing plate: darkens from just above the first line to the bottom of
   the screen, so even older lines and visitor bubbles over a white shirt or
   a blown-out frame stay above 4.5:1. It follows the subtitles' height. */
.captions::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -24px;
  bottom: -100vh;
  left: -100vw;
  right: -100vw;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.66) 52px);
  pointer-events: none;
}

.captions-scroll {
  flex: 0 1 auto;
  min-height: 0;
  max-height: min(32vh, 300px);
  max-height: min(32dvh, 300px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 28px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 28px);
  mask-image: linear-gradient(to bottom, transparent 0, #000 28px);
}
.captions-scroll::-webkit-scrollbar { display: none; }

body.email-open .captions-scroll { max-height: min(18vh, 160px); max-height: min(18dvh, 160px); }
body.captions-off .captions { display: none; }

.line {
  margin: 0;
  max-width: 92%;
  animation: rise 360ms var(--ease) both;
  overflow-wrap: anywhere;
}

.line.persona {
  align-self: flex-start;
  font-size: 18px;
  line-height: 1.42;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--fg);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.45);
}

.line.user {
  align-self: flex-end;
  font-size: 15px;
  line-height: 1.4;
  color: rgba(246, 246, 244, 0.86);
  padding: 7px 12px;
  border-radius: 16px 16px 4px 16px;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.line.note {
  align-self: center;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--fg-muted);
}

.line.is-interrupted .text::after { content: " —"; color: var(--fg-faint); }

/* Older persona lines recede so the current one reads as the subtitle. */
.line.persona:not(.is-current) { color: rgba(246, 246, 244, 0.72); }

/* Sits on the faded top edge of the subtitles, never over a readable line. */
.jump {
  position: absolute;
  top: -18px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 36px;
  padding: 0 12px 0 10px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--glass-strong);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  font-size: 13px;
  color: var(--fg);
}
/* Invisible extension to a 44px touch target. */
.jump::before { content: ""; position: absolute; inset: -5px; }
.jump svg { width: 14px; height: 14px; }
.jump[hidden] { display: none; }

/* ---------- email card ---------- */

.email-card {
  padding: 14px 14px 14px 16px;
  border-radius: var(--radius);
  background: var(--glass-strong);
  border: 1px solid var(--hairline);
  backdrop-filter: blur(24px) saturate(1.5);
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: translateY(16px) scale(0.98);
  transition: opacity 380ms var(--ease), transform 380ms var(--ease);
}
.email-card[hidden] { display: none; }
.email-card.is-open { opacity: 1; transform: none; }

.email-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.email-title { font-size: 13px; font-weight: 600; color: var(--fg-muted); letter-spacing: 0.02em; }

/* 44px touch target; the negative margins keep the card's spacing. */
.icon-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -11px -11px -11px 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--fg-muted);
}
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn:hover { background: rgba(255, 255, 255, 0.08); color: var(--fg); }

.email-field {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  height: 52px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: border-color 200ms, background 200ms;
}
.email-field svg { flex: none; width: 20px; height: 20px; color: var(--fg-faint); }
/* The input has no outline of its own; the field draws a clear 2px ring. */
.email-field:focus-within { border-color: var(--fg); box-shadow: 0 0 0 1px var(--fg); background: rgba(255, 255, 255, 0.1); }
.email-card.is-invalid .email-field { border-color: rgba(229, 72, 77, 0.7); }

.email-field input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--fg);
  font: 500 17px/1 var(--font); /* 16px+ stops iOS from zooming on focus */
  letter-spacing: -0.005em;
}
/* The blank card shows only this hint, so it must meet 4.5:1 too. */
.email-field input::placeholder { color: var(--fg-muted); }

.email-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; }
.email-status { margin: 0; font-size: 13px; color: var(--fg-muted); }
.email-card.is-invalid .email-status { color: #ff8b8f; }
.email-card.is-sent .email-status { color: var(--green); }

.submit-btn {
  position: relative;
  flex: none;
  min-width: 112px;
  height: 44px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  background: var(--fg);
  color: #0b0b0c;
  font-size: 15px;
  font-weight: 600;
  transition: transform 160ms var(--ease), opacity 200ms;
}
.submit-btn:active { transform: scale(0.97); }
.submit-btn:disabled { cursor: default; }
.submit-btn .spinner {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid rgba(0, 0, 0, 0.2);
  border-top-color: #0b0b0c;
  opacity: 0;
  animation: spin 800ms linear infinite;
}
.email-card.is-sending .submit-label { opacity: 0; }
.email-card.is-sending .spinner { opacity: 1; }
.email-card.is-sent .submit-btn { background: var(--green); color: #04150c; }

/* ---------- controls ---------- */

.controls {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: var(--controls-bottom);
  display: flex;
  justify-content: center;
  gap: 18px;
}

.ctl {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--ctl-size);
  height: var(--ctl-size);
  border-radius: 50%;
  border: 1px solid var(--hairline);
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  transition: background 200ms, transform 160ms var(--ease), opacity 200ms;
}
.ctl:active { transform: scale(0.94); }
.ctl:disabled { opacity: 0.4; cursor: default; }
.ctl svg { width: 24px; height: 24px; }

#mic-btn .off { display: none; }
#mic-btn[aria-pressed="true"] { background: var(--fg); color: #0b0b0c; }
#mic-btn[aria-pressed="true"] .on { display: none; }
#mic-btn[aria-pressed="true"] .off { display: block; }

/* Soft ring while the visitor is speaking. */
#mic-btn::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 2px solid var(--green);
  opacity: 0;
  transform: scale(0.92);
  transition: opacity 200ms, transform 300ms var(--ease);
}
#mic-btn.is-speaking::after { opacity: 1; transform: none; }

#cc-btn[aria-pressed="false"] { color: var(--fg-faint); }

.ctl-end { background: var(--red); border-color: transparent; }
.ctl-end svg { width: 28px; height: 28px; fill: currentColor; stroke: none; }

/* ---------- overlay: lobby, connecting, ended, error, unsupported, unavailable ---------- */

/* Scrolls when the card doesn't fit (short landscape screens). The card is
   centred with auto margins rather than place-items, so an overflowing card
   starts at the top and stays reachable instead of being clipped above it. */
.overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: calc(var(--safe-top) + 24px) calc(var(--safe-right) + var(--gutter)) calc(var(--safe-bottom) + 24px) calc(var(--safe-left) + var(--gutter));
  background: radial-gradient(120% 80% at 50% 30%, rgba(5, 5, 6, 0.25), rgba(5, 5, 6, 0.75));
  transition: opacity 600ms var(--ease), visibility 600ms;
}
body[data-state="live"] .overlay,
body[data-state="ending"] .overlay { opacity: 0; visibility: hidden; pointer-events: none; }

.card {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 360px;
  margin: auto;
  text-align: center;
  animation: rise 600ms var(--ease) both;
}

.portrait {
  position: relative;
  width: 128px;
  height: 128px;
  margin-bottom: 22px;
}
.portrait img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  object-position: center 22%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.5);
}
.portrait::before,
.portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.5);
  opacity: 0;
}
body[data-state="connecting"] .portrait::before { animation: ring 2s var(--ease) infinite; }
body[data-state="connecting"] .portrait::after { animation: ring 2s var(--ease) 1s infinite; }

.card-name { margin: 0; font-size: 28px; font-weight: 650; letter-spacing: -0.02em; }
.card-role { margin: 4px 0 0; font-size: 15px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.card-text { margin: 22px 0 0; font-size: 16px; line-height: 1.5; color: var(--fg); max-width: 300px; text-wrap: balance; }

.primary-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 28px;
  min-width: 200px;
  height: 56px;
  padding: 0 28px;
  border: 0;
  border-radius: 999px;
  background: var(--green);
  color: #04150c;
  font-size: 17px;
  font-weight: 600;
  box-shadow: 0 12px 36px rgba(46, 194, 126, 0.32);
  transition: transform 160ms var(--ease), box-shadow 200ms;
}
.primary-btn:active { transform: scale(0.97); }
.primary-btn[hidden] { display: none; }
.primary-btn.is-secondary { background: var(--fg); color: #0b0b0c; box-shadow: none; }

/* Secondary actions: Cancel while connecting (quiet glass), Copy link on the
   unsupported-browser screen (white, like "Call again"). Each shows only in
   its own state, whether or not app.js also toggles [hidden]. */
#overlay-cancel,
#overlay-copy {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 160px;
  height: 48px;
  margin-top: 24px;
  padding: 0 24px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 600;
  box-shadow: none;
  transition: transform 160ms var(--ease);
}
#overlay-cancel {
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: var(--glass);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  color: var(--fg);
}
#overlay-copy { border: 0; background: var(--fg); color: #0b0b0c; }
#overlay-cancel:active,
#overlay-copy:active { transform: scale(0.97); }
body[data-state="connecting"] #overlay-cancel:not([hidden]),
body[data-state="unsupported"] #overlay-copy:not([hidden]) { display: inline-flex; }

/* Turnstile: takes no space while invisible; an interactive challenge
   (300px wide) shows centred under the button. */
#turnstile-slot { display: flex; justify-content: center; width: 100%; }
#turnstile-slot:empty { display: none; }
/* Never squeezed: on a 320px screen the 300px widget spills evenly into the gutters. */
#turnstile-slot > * { flex: none; }
body.turnstile-interactive #turnstile-slot { margin-top: 18px; }

.card-foot { margin: 16px 0 0; font-size: 13px; color: var(--fg-muted); }
.card-foot:empty { display: none; }
/* 44px tall touch target; the hairline underline keeps the old look. */
.card-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 6px;
  padding: 0 12px;
  font-size: 14px;
  color: var(--fg-muted);
  text-decoration-line: underline;
  text-decoration-color: rgba(255, 255, 255, 0.3);
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
}
.card-link[hidden] { display: none; }

/* Privacy notice in the lobby. */
#overlay-privacy {
  display: none;
  margin: 20px 0 0;
  max-width: 320px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--fg-muted);
}
body[data-state="idle"] #overlay-privacy:not([hidden]) { display: block; }

body[data-state="error"] .card-text { color: #ffb3b5; }

/* ---------- ended or dropped with an unsubmitted email ---------- */

/* The card the visitor hasn't submitted stays usable above the "Call ended"
   or "The call dropped" overlay (app.js sets email-pending only then); the
   overlay keeps its own content clear of it. The two dock rules also name
   those states: only that outweighs the rules above that hide the dock
   outside the call. */
body.email-pending:is([data-state="ended"], [data-state="error"]) .tile-dock {
  z-index: 6;
  opacity: 1;
  visibility: visible;
  transform: none;
  bottom: max(calc(var(--safe-bottom) + 16px), calc(var(--keyboard-inset, 0px) + 12px));
  transition: none;
}
body.email-pending:is([data-state="ended"], [data-state="error"]) .tile-dock > .email-card { pointer-events: auto; }
body.email-pending .captions { display: none; }
body.email-pending .overlay { padding-bottom: calc(max(calc(var(--safe-bottom) + 16px), calc(var(--keyboard-inset, 0px) + 12px)) + 204px); }
body.email-pending .portrait { width: 80px; height: 80px; margin-bottom: 14px; }

/* ---------- focus and screen-reader helpers ---------- */

:where(button, a):focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.ctl:focus-visible { outline-offset: 4px; }
/* Browsers make the scrolling subtitles a Tab stop; the mask would hide an
   outer ring, so draw it inside. */
.captions-scroll:focus-visible { outline: 2px solid var(--fg); outline-offset: -2px; }

.sr-only,
#sr-captions {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  border: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
}

/* ---------- motion ---------- */

@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes ring { 0% { opacity: 0.7; transform: scale(1); } 100% { opacity: 0; transform: scale(1.45); } }
@keyframes pulse-dot {
  0% { box-shadow: 0 0 0 0 rgba(46, 194, 126, 0.55); }
  70% { box-shadow: 0 0 0 7px rgba(46, 194, 126, 0); }
  100% { box-shadow: 0 0 0 0 rgba(46, 194, 126, 0); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- short screens: compact spacing so every action stays on screen ---------- */

@media (max-height: 700px) {
  :root { --ctl-size: 52px; --controls-bottom: calc(var(--safe-bottom) + 14px); }
  .portrait { width: 104px; height: 104px; margin-bottom: 16px; }
  .card-text { margin-top: 16px; }
  .primary-btn { margin-top: 22px; height: 52px; }
}

@media (max-height: 580px) {
  :root { --ctl-size: 48px; --controls-bottom: calc(var(--safe-bottom) + 10px); --dock-top: calc(var(--safe-top) + 64px); }
  .topbar { padding-top: calc(var(--safe-top) + 10px); }
  .tile-dock { gap: 10px; }
  .line.persona { font-size: 17px; }
  .email-card { padding: 10px 12px 12px 14px; }
  .email-head { margin-bottom: 6px; }
  .email-field { height: 48px; }
  .email-foot { margin-top: 10px; }
  .portrait { width: 80px; height: 80px; margin-bottom: 12px; }
  .card-name { font-size: 24px; }
  .card-text { margin-top: 12px; font-size: 15px; line-height: 1.45; }
  .primary-btn { margin-top: 18px; height: 48px; }
  #overlay-cancel, #overlay-copy { margin-top: 18px; }
  .card-foot { margin-top: 12px; }
  #overlay-privacy { margin-top: 14px; }
}

/* ---------- wide screens: a phone-style call in a portrait frame ---------- */

/* The avatar's largest portrait stream is 768x1152, so on laptops the whole phone
   layout sits in a fixed 2:3 frame, never taller than the stream itself. Its
   size depends only on the window, never on the stream, so it can't jump
   when the stream's resolution ramps up. Only on screens tall enough for
   the phone layout: a phone held sideways gets its own layout below. */
@media (min-width: 600px) and (min-height: 600px) and (min-aspect-ratio: 4/5) {
  body::before {
    content: "";
    position: fixed;
    inset: -60px;
    background: url("assets/abhinav-portrait.webp") center 30% / cover no-repeat;
    filter: blur(48px) brightness(0.35) saturate(1.1);
  }

  /* transform, not the translate property: older browsers lack translate,
     and declaring both would move the frame twice. */
  .stage {
    inset: auto;
    top: 50%;
    left: 50%;
    height: min(calc(100vh - 48px), 1152px);
    height: min(calc(100dvh - 48px), 1152px);
    aspect-ratio: 2 / 3;
    transform: translate(-50%, -50%);
    border-radius: 28px;
    border: 1px solid var(--hairline);
    box-shadow: 0 40px 120px rgba(0, 0, 0, 0.6);
  }

  .captions-scroll { max-height: min(28vh, 300px); max-height: min(28dvh, 300px); }

  /* The frame sits 24px above the window's bottom edge. */
  .tile-dock { bottom: max(var(--dock-bottom), calc(var(--keyboard-inset, 0px) - 12px)); }
}

/* ---------- phones held sideways: video on the left, subtitles on the right ---------- */

@media (min-aspect-ratio: 4/3) and (max-height: 599px) {
  /* The video column is exactly the stream's 2:3 at full height. */
  :root { --video-w: calc(100vh * 2 / 3); --dock-top: calc(var(--safe-top) + 58px); }
  @supports (height: 100dvh) {
    :root { --video-w: calc(100dvh * 2 / 3); }
  }

  #persona-video { left: var(--safe-left); right: auto; width: var(--video-w); }

  .topbar { padding-left: calc(var(--safe-left) + 10px); }

  .sound-pill {
    left: var(--safe-left);
    right: calc(100% - var(--safe-left) - var(--video-w));
    max-width: calc(var(--video-w) - 16px);
  }

  .controls { left: var(--safe-left); right: auto; width: var(--video-w); gap: 14px; }

  .tile-dock,
  .sound-pill:not([hidden]) ~ .tile-dock {
    left: calc(var(--safe-left) + var(--video-w));
    top: var(--dock-top);
    bottom: max(calc(var(--safe-bottom) + 12px), calc(var(--keyboard-inset, 0px) + 8px));
    padding-left: var(--gutter);
  }
  /* The dock bounds the subtitles here; the plate covers the right side only. */
  .captions-scroll,
  body.email-open .captions-scroll { max-height: none; }
  .captions::before { left: calc(-1 * var(--gutter)); }

  /* Overlay card: portrait beside the text, so the button fits on screen. */
  .overlay { padding-top: calc(var(--safe-top) + 12px); padding-bottom: calc(var(--safe-bottom) + 12px); }
  .card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 24px;
    justify-items: start;
    align-items: start;
    max-width: 560px;
    text-align: left;
  }
  .card > * { grid-column: 2; }
  .card > .portrait { grid-column: 1; grid-row: 1 / span 12; align-self: center; width: 96px; height: 96px; margin: 0; }
  .card-text { max-width: none; }
  .card-link { margin-left: -12px; }
  #turnstile-slot { justify-content: flex-start; }

  /* Ended or dropped with an unsubmitted email: the card keeps the right
     side and the overlay's text moves to the left column. */
  body.email-pending .overlay {
    padding-right: calc(100% - var(--safe-left) - var(--video-w) + 8px);
    padding-bottom: calc(var(--safe-bottom) + 12px);
  }
  body.email-pending .card {
    display: flex;
    text-align: center;
    align-items: center;
  }
  body.email-pending .portrait { width: 56px; height: 56px; margin: 0 0 8px; }
  body.email-pending .card-name { font-size: 22px; }
  body.email-pending .card-text { margin-top: 8px; font-size: 14px; }
  body.email-pending .primary-btn { min-width: 0; margin-top: 12px; }
  body.email-pending .card-link { margin-left: 0; }
}
