/* PSIRA chat widget (assistant name: Ira) -- fixed bottom-right, self-contained
   so it can be dropped onto any page with one <script> tag (REQ-060/REQ-062:
   the real site may be WordPress, so the widget must not depend on, or leak
   into, the host page's CSS).

   Palette matches the existing PSIRA mobile app's amber/gold chrome:
     gold light  #e3b568   gold base  #d8a448   gold dark  #b8842e
   Hex values are inlined rather than using CSS custom properties so nothing
   here can be overridden by -- or override -- the host page. */

.psira-launcher {
  position: fixed; right: 34px; bottom: 34px; z-index: 9998;
  width: 70px; height: 70px; border-radius: 50%; border: none; cursor: pointer;
  background: linear-gradient(140deg, #e3b568 0%, #d8a448 55%, #b8842e 100%);
  color: #fff; font-size: 25px; line-height: 1; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 20px rgba(74,50,15,.3), 0 2px 6px rgba(0,0,0,.12);
  transition: transform .16s ease, box-shadow .16s ease;
  /* Deliberately no perpetual pulse/ping animation -- a permanently
     attention-seeking button reads as a marketing pop-up, not an official
     service entry point. A calm, static button is the more institutional
     choice; the badge count is enough to signal something needs attention. */
  opacity: 0; animation: psira-launcher-in .5s cubic-bezier(.34,1.4,.64,1) .2s forwards;
}
@keyframes psira-launcher-in {
  from { opacity: 0; transform: scale(.4) translateY(16px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.psira-launcher:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(74,50,15,.36); }
.psira-launcher:active { transform: translateY(0); }
.psira-launcher .psira-launch-icon,
.psira-launcher .psira-close-icon {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  transition: opacity .16s ease, transform .2s cubic-bezier(.4,0,.2,1);
}
.psira-launcher .psira-launch-icon svg,
.psira-launcher .psira-close-icon svg { width: 30px; height: 30px; }
/* The Lottie bot fills the whole button face; lottie sets inline width/height
   on its generated <svg>, so !important is needed to size it to the button. */
.psira-launcher .psira-bot-anim { display: none; width: 100%; height: 100%; }
.psira-launcher .psira-bot-anim svg { width: 100% !important; height: 100% !important; }
.psira-launcher.bot-ready .psira-bot-anim { display: block; }
.psira-launcher.bot-ready .psira-fallback-icon { display: none; }
.psira-launcher .psira-close-icon { opacity: 0; transform: rotate(-30deg) scale(.7); }
.psira-launcher.open .psira-launch-icon { opacity: 0; transform: rotate(30deg) scale(.7); }
.psira-launcher.open .psira-close-icon { opacity: 1; transform: rotate(0) scale(1); }
.psira-launcher .badge {
  position: absolute; top: -2px; right: -2px; min-width: 19px; height: 19px;
  border-radius: 10px; background: #b3401f; color: #fff; font-size: 11px; font-weight: 700;
  line-height: 19px; padding: 0 5px; text-align: center; display: none;
  box-shadow: 0 2px 5px rgba(0,0,0,.2);
  animation: psira-badge-in .22s cubic-bezier(.2,.7,.3,1);
}
@keyframes psira-badge-in { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }

.psira-panel {
  position: fixed; right: 34px; bottom: 116px; z-index: 9999;
  width: 380px; max-width: calc(100vw - 44px);
  height: 570px; max-height: calc(100vh - 152px);
  background: #fff; border-radius: 20px; overflow: hidden;
  display: none; flex-direction: column;
  box-shadow: 0 28px 64px rgba(21,42,66,.32), 0 6px 18px rgba(0,0,0,.1);
  font-family: -apple-system, "Segoe UI", system-ui, Roboto, sans-serif;
  border: 1px solid rgba(216,164,72,.14);
}
.psira-panel.open { display: flex; animation: psira-panel-in .28s cubic-bezier(.2,.7,.3,1); }
@keyframes psira-panel-in {
  from { opacity: 0; transform: translateY(18px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---- header ---- */
.psira-head {
  position: relative; background: linear-gradient(135deg, #b8842e 0%, #d8a448 100%);
  color: #fff; padding: 14px 16px; display: flex; align-items: center; gap: 11px; flex-shrink: 0;
  border-bottom: 2px solid #8a5a1f; /* deeper bronze accent line */
}
.psira-head .psira-ava {
  position: relative; width: 40px; height: 40px; border-radius: 50%; background: #fff; color: #b8842e;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  flex-shrink: 0; box-shadow: 0 3px 8px rgba(0,0,0,.18), 0 0 0 2.5px rgba(255,255,255,.35);
}
.psira-head .psira-ava svg { width: 22px; height: 22px; }
.psira-head .psira-ava .psira-avatar-img { width: 100%; height: 100%; object-fit: cover; }
.psira-head .psira-hgroup { min-width: 0; position: relative; }
.psira-head .title { font-size: 14.5px; font-weight: 700; letter-spacing: .2px; }
.psira-head .sub { font-size: 11px; opacity: .92; display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.psira-head .sub::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: #4ade80; box-shadow: 0 0 0 3px rgba(74,222,128,.3);
  animation: psira-dot-pulse 2s ease-in-out infinite;
}
@keyframes psira-dot-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(74,222,128,.3); }
  50%      { box-shadow: 0 0 0 5px rgba(74,222,128,.12); }
}
.psira-head .spacer { margin-left: auto; }
.psira-head button {
  position: relative; display: flex; align-items: center; gap: 5px;
  background: rgba(255,255,255,.14); border: none; color: #fff; cursor: pointer; font-family: inherit;
  font-size: 11.5px; font-weight: 600; padding: 7px 12px; border-radius: 999px;
  transition: background .14s ease, transform .12s ease;
}
.psira-head button svg { width: 13px; height: 13px; flex-shrink: 0; }
.psira-head button.psira-x { padding: 7px; border-radius: 50%; }
.psira-head button.psira-x svg { width: 12px; height: 12px; }
.psira-head button:hover { background: rgba(255,255,255,.26); }

/* ---- message log ---- */
.psira-log {
  flex: 1 1 auto; min-height: 150px; overflow-y: auto; padding: 18px 14px;
  background: #f4f7fb;
  display: flex; flex-direction: column; gap: 12px;
  scrollbar-width: thin; scrollbar-color: #cdd9e6 transparent;
  /* soft top fade so content sliding under the header edge feels like it's
     dissolving rather than getting clipped -- a small, recognisably "native
     app" detail */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 16px, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 16px, #000 100%);
}
.psira-log::-webkit-scrollbar { width: 8px; }
.psira-log::-webkit-scrollbar-thumb { background: #cdd9e6; border-radius: 4px; }
.psira-log::-webkit-scrollbar-thumb:hover { background: #b7c6d8; }

/* Each message is a row: an avatar (assistant only) + the bubble, aligned
   like a real messaging app rather than a lone floating bubble. */
.psira-row { display: flex; align-items: flex-end; gap: 7px; max-width: 90%; }
.psira-row.assistant { align-self: flex-start; }
.psira-row.user { align-self: flex-end; }
.psira-row.system, .psira-row.notice { align-self: center; max-width: 96%; }

.psira-mini-ava {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; margin-bottom: 1px;
  background: linear-gradient(135deg, #d8a448, #b8842e); color: #fff;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  box-shadow: 0 1px 3px rgba(74,50,15,.25);
}
.psira-mini-ava svg { width: 13px; height: 13px; }
.psira-mini-ava .psira-avatar-img { width: 100%; height: 100%; object-fit: cover; }

.psira-msg {
  max-width: 100%; padding: 10px 13px; border-radius: 16px; font-size: 13.5px; line-height: 1.52;
  white-space: pre-wrap; word-wrap: break-word;
  animation: psira-msg-in .24s cubic-bezier(.2,.7,.3,1);
}
@keyframes psira-msg-in { from { opacity: 0; transform: translateY(7px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
.psira-msg.assistant {
  background: #fff; border: 1px solid #e6ebf2; color: #1c2733;
  border-bottom-left-radius: 5px; box-shadow: 0 1px 3px rgba(74,50,15,.07);
}
.psira-msg.user {
  background: linear-gradient(135deg, #d8a448, #b8842e); color: #fff;
  border-bottom-right-radius: 5px; box-shadow: 0 3px 10px rgba(184,132,46,.3);
}
.psira-msg.system { background: #e8edf3; color: #5b6472; font-size: 11.5px; padding: 5px 11px; border-radius: 11px; }
.psira-msg.notice { background: #fdf5e6; color: #8a6516; border: 1px solid #f0d9a6; font-size: 12px; text-align: center; }
.psira-msg strong { font-weight: 700; }

/* Landing screen's opening bubble only (see widget.js::welcomeBubble) -- the
   PSIRA crest sits above the greeting text inside the same bubble. */
.psira-logo { display: block; width: 100%; max-width: 220px; height: auto; margin: 0 0 10px; }

/* Each server line (graph/common.py::render_bulleted) becomes one block here.
   step/bullet lines are a flex row with a fixed-width marker column, so a
   long requirement that wraps to a second line indents under its own text
   instead of sliding back under the "1." or "•" -- a hanging indent, the
   thing plain pre-wrapped text can't do. */
.psira-msg .psira-line { display: block; }
.psira-msg .psira-line + .psira-line { margin-top: 3px; }
.psira-msg .psira-line.gap { margin-top: 11px; }
.psira-msg .psira-line.step, .psira-msg .psira-line.bullet {
  display: flex; align-items: baseline; gap: 7px;
}
.psira-msg .psira-line .marker { flex: 0 0 auto; font-weight: 700; }
.psira-msg .psira-line.step .marker { min-width: 1.5em; }
.psira-msg .psira-line.bullet .marker { min-width: .7em; opacity: .7; }
.psira-msg .psira-line .text { flex: 1 1 auto; min-width: 0; }
.psira-msg .psira-line.header { font-weight: 700; }

/* animated typing dots */
.psira-typing { display: flex; gap: 4px; padding: 11px 14px; background: #fff; border: 1px solid #e6ebf2; border-radius: 16px; border-bottom-left-radius: 5px; box-shadow: 0 1px 3px rgba(74,50,15,.07); }
.psira-typing span { width: 7px; height: 7px; border-radius: 50%; background: #9db4cc; animation: psira-bounce 1.2s infinite ease-in-out; }
.psira-typing span:nth-child(2) { animation-delay: .18s; }
.psira-typing span:nth-child(3) { animation-delay: .36s; }
@keyframes psira-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: .5; } 30% { transform: translateY(-5px); opacity: 1; } }

/* ---- inline button groups (rendered inside the log, under the prompt) ---- */
.psira-btns { display: flex; flex-direction: column; gap: 7px; align-self: flex-start; max-width: 94%; margin-top: 0; }
.psira-btns button:disabled { opacity: .5; cursor: default; }
.psira-btns button {
  animation: psira-btn-in .3s cubic-bezier(.2,.7,.3,1) both;
}
@keyframes psira-btn-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.psira-btns button:nth-child(1) { animation-delay: .02s; }
.psira-btns button:nth-child(2) { animation-delay: .06s; }
.psira-btns button:nth-child(3) { animation-delay: .10s; }
.psira-btns button:nth-child(4) { animation-delay: .14s; }
.psira-btns button:nth-child(5) { animation-delay: .18s; }
.psira-btns button:nth-child(6) { animation-delay: .22s; }
.psira-btns button:nth-child(n+7) { animation-delay: .26s; }

/* sub-module option menus: vertical list with a gold marker dot */
.psira-btns.optionlist button.psira-opt {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  border: 1px solid #dbe4ee; background: #fff; color: #24384f; border-radius: 12px;
  padding: 10px 13px; font-size: 13px; line-height: 1.35; cursor: pointer; font-family: inherit;
  box-shadow: 0 1px 2px rgba(27,54,84,.05);
  transition: background .14s ease, border-color .14s ease, transform .1s ease, box-shadow .14s ease;
}
.psira-btns.optionlist button.psira-opt::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: #d8a448; flex: 0 0 auto;
  box-shadow: 0 0 0 3px rgba(216,164,72,.18);
}
.psira-btns.optionlist button.psira-opt:hover {
  background: #fbf3e4; border-color: #d8a448; color: #3a2a12; transform: translateY(-1px);
  box-shadow: 0 5px 14px rgba(184,132,46,.16);
}

/* navigation controls (Back / Main Menu / End Chat): a compact horizontal row
   of small ghost pills, set off by a divider line, so they read as navigation
   rather than as content choices like the .psira-opt cards above them. The
   hover is blue (not the content buttons' gold) to reinforce the distinction. */
.psira-btns.navrow {
  flex-direction: row; flex-wrap: nowrap; gap: 8px; width: 100%; max-width: 94%;
  margin-top: 6px; padding-top: 11px; border-top: 1px solid #e4ebf3;
}
/* Each control shares the row width equally, so the row always fills with no
   leftover gap: 3 controls -> thirds (left / middle / right), 2 -> halves.
   Icon + label + a per-action accent keeps them clearly distinct from the
   gold-dot content cards above. */
.psira-btns.navrow button.psira-nav {
  flex: 1 1 0; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid #d6dfea; background: #fff; color: #5a6b80;
  border-radius: 10px; padding: 8px 10px; font-size: 12px; font-weight: 600;
  letter-spacing: .01em; cursor: pointer; font-family: inherit;
  box-shadow: 0 1px 2px rgba(27,54,84,.05);
  transition: transform .12s ease, box-shadow .16s ease, border-color .16s ease,
              background .16s ease, color .16s ease;
}
.psira-btns.navrow button.psira-nav .psira-nav-ico { display: inline-flex; flex: 0 0 auto; opacity: .85; }
.psira-btns.navrow button.psira-nav .psira-nav-ico svg { width: 14px; height: 14px; display: block; }
.psira-btns.navrow button.psira-nav .psira-nav-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.psira-btns.navrow button.psira-nav:hover { transform: translateY(-1px); box-shadow: 0 6px 14px rgba(20,40,80,.13); }
.psira-btns.navrow button.psira-nav:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(27,54,84,.08); }
/* per-action accents, visible AT REST (not only on hover): Back -> blue,
   Main Menu -> brand gold, End Chat -> a soft danger red (it closes the chat).
   Icons inherit currentColor, so they take the same accent. */
.psira-btns.navrow button.psira-nav .psira-nav-ico { opacity: 1; }

.psira-btns.navrow button.nav-back {
  color: #1c4e80; border-color: #cdddf0; background: #f2f8fd;
}
.psira-btns.navrow button.nav-back:hover {
  color: #143a63; border-color: #7fa6d1; background: #e6f0fb;
}

.psira-btns.navrow button.nav-main_menu {
  color: #8a5a12; border-color: #ecd6a6; background: #fdf6e8;
}
.psira-btns.navrow button.nav-main_menu:hover {
  color: #6f470c; border-color: #d8a448; background: #f8ead0;
}

.psira-btns.navrow button.nav-end_chat {
  color: #a83540; border-color: #f0cccf; background: #fdf2f2;
}
.psira-btns.navrow button.nav-end_chat:hover {
  color: #8f2028; border-color: #e39ba0; background: #fbe4e5;
}

/* service menu: a 2-column grid (5 modules -> two full rows plus a lone
   last card) instead of one full-width stacked column, so the landing menu
   reads as a compact grid of services rather than a long list. Overrides
   the generic .psira-btns column layout: grid instead of flex, and stretched
   instead of shrink-to-fit so the two columns actually share the row's full
   width evenly. */
.psira-btns.services {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-self: stretch; max-width: 100%;
}
/* An odd module count (5 today) leaves one card alone in the last row --
   :nth-last-child(1):nth-child(odd) matches ONLY that leftover (never a
   normal paired row), spans both tracks, and centers within them at roughly
   one column's width, so it reads as a deliberate "odd one out" card rather
   than a left-aligned card with a dangling empty cell beside it. */
.psira-btns.services button.psira-service:nth-last-child(1):nth-child(odd) {
  grid-column: 1 / -1; justify-self: center; width: 50%;
}

/* service menu: one card per module, module colour as a short inset accent
   bar. A full-height border-left was tried first but a 4px side clashing
   with a 13px border-radius left a visibly jagged corner where the two
   curves didn't match -- an inset ::before bar avoids the corner entirely
   instead of fighting it. */
.psira-btns.services button.psira-service {
  position: relative; display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  border: 1px solid #e3e9f0;
  background: #fff; border-radius: 13px; padding: 10px 10px 10px 16px; color: #1c2733; cursor: pointer; font-family: inherit;
  box-shadow: 0 2px 7px rgba(27,54,84,.07), 0 1px 2px rgba(27,54,84,.05);
  transition: box-shadow .16s ease, transform .14s ease, border-color .14s ease;
}
.psira-btns.services button.psira-service::before {
  content: ""; position: absolute; left: 8px; top: 11px; bottom: 11px; width: 3px;
  border-radius: 3px; background: var(--accent, #d8a448);
}
.psira-btns.services button.psira-service:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(74,50,15,.15); border-color: #d8e0ea;
}
.psira-btns.services button.psira-service:active { transform: translateY(0); }
.psira-btns.services button.psira-service .ico {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent, #d8a448);
  background: rgba(0,0,0,.05);
  background: color-mix(in srgb, var(--accent, #d8a448) 13%, #ffffff);
}
.psira-btns.services button.psira-service .ico svg { width: 14px; height: 14px; }
/* min-width:0 lets a long label (e.g. "Registration") wrap onto a second
   line within its half-width column instead of overflowing the card --
   a plain flex child would otherwise refuse to shrink below its text's
   natural single-line width. */
.psira-btns.services button.psira-service .txt {
  font-weight: 700; font-size: 12.5px; line-height: 1.25; flex: 1 1 auto; min-width: 0;
}

/* ---- footer input ---- */
.psira-foot { border-top: 1px solid #e6ebf2; padding: 12px 12px 10px; background: #fff; flex-shrink: 0; }
.psira-inputwrap {
  display: flex; align-items: center; gap: 4px;
  background: #f4f7fb; border: 1.5px solid transparent; border-radius: 26px;
  padding: 4px 4px 4px 16px;
  transition: border-color .14s ease, box-shadow .14s ease, background .14s ease;
}
.psira-inputwrap:focus-within { background: #fff; border-color: #d8a448; box-shadow: 0 0 0 3px rgba(216,164,72,.14); }
.psira-foot input {
  flex: 1; min-width: 0; border: none; background: transparent; padding: 9px 0;
  font-size: 13.5px; outline: none; font-family: inherit; color: #1c2733;
}
.psira-foot input::placeholder { color: #9aa6b5; }
.psira-foot input:disabled { color: #9aa3b2; }
.psira-foot button {
  border: none; background: linear-gradient(135deg, #d8a448, #b8842e); color: #fff; cursor: pointer;
  width: 38px; height: 38px; border-radius: 50%; font-size: 15px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 8px rgba(184,132,46,.32); transition: transform .12s ease, box-shadow .14s ease;
}
.psira-foot button:hover:not(:disabled) { transform: scale(1.08); box-shadow: 0 4px 12px rgba(184,132,46,.44); }
.psira-foot button:active:not(:disabled) { transform: scale(.94); }
.psira-foot button:disabled { background: #c2cdda; cursor: default; box-shadow: none; }
/* Nothing typed yet: the send button is still clickable-looking without this,
   which reads as "press me" even though there's nothing to send. Dimming it
   until there's text gives the button an honest at-a-glance affordance. */
.psira-foot button.is-empty:not(:disabled) {
  opacity: .45; box-shadow: none; transform: none; cursor: default;
}
.psira-foot button.is-empty:not(:disabled):hover { transform: none; box-shadow: none; }

/* ---- keyboard focus -----------------------------------------------------
   Every interactive control gets one consistent, on-brand focus ring instead
   of each browser's default (usually blue, clashing with the gold theme) --
   :focus-visible so it only shows for keyboard/assistive-tech use, never on
   a mouse click. */
.psira-launcher:focus-visible,
.psira-head button:focus-visible,
.psira-btns button:focus-visible,
.psira-foot button:focus-visible {
  outline: 2px solid #d8a448; outline-offset: 2px;
}
/* ==========================================================================
   Embed mode -- the widget as the whole page.

   Set by the /chat shell (web/app.py) for a native app's WebView: there is no
   host page to float above, so the launcher goes away and the panel becomes
   the viewport. Everything below is chrome only; not one conversational
   behaviour differs between this and the floating widget.

   Scoped under html.psira-embed so a normal embed on a host site is untouched
   -- these rules simply never match there.
   ========================================================================== */

html.psira-embed,
html.psira-embed body {
  margin: 0; padding: 0; height: 100%;
  background: #fff;
  /* Kill the browser affordances that give away "this is a web page": the
     rubber-band scroll past the ends, and Chrome's pull-to-refresh -- which
     in a chat would reload the page mid-conversation on a downward swipe. */
  overscroll-behavior: none;
  /* iOS bumps font sizes in landscape unless told not to; the panel is a
     designed type scale, not flowing body copy. */
  -webkit-text-size-adjust: 100%;
  /* The grey flash on every tap reads as a web page, not an app control. */
  -webkit-tap-highlight-color: transparent;
}

html.psira-embed .psira-launcher { display: none !important; }

html.psira-embed .psira-panel {
  position: fixed; inset: 0;
  width: 100%; max-width: none;
  /* --psira-vh is kept in sync with visualViewport by the shell, so the panel
     shrinks to sit above the on-screen keyboard on iOS (which overlays rather
     than resizing the viewport). Falls back to the viewport height when the
     shell's script hasn't run or VisualViewport is unavailable. */
  height: var(--psira-vh, 100%); max-height: none;
  border: none; border-radius: 0; box-shadow: none;
  /* The panel's entrance animation is a bubble expanding out of the launcher.
     With no launcher and nothing behind it, it just delays first paint. */
  animation: none !important;
}

/* Nothing to close *to* inside a WebView -- the host app's own navigation
   owns leaving the screen. "New conversation" stays. */
html.psira-embed .psira-head button.psira-x { display: none; }

/* Safe areas: the notch/status bar above the header, the home indicator below
   the composer. Padding rather than margin so the gold header still bleeds
   into the status-bar area instead of leaving a white strip above it. */
html.psira-embed .psira-head {
  padding-top: calc(14px + env(safe-area-inset-top, 0px));
  padding-left: calc(16px + env(safe-area-inset-left, 0px));
  padding-right: calc(16px + env(safe-area-inset-right, 0px));
}
html.psira-embed .psira-foot {
  padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  padding-left: calc(12px + env(safe-area-inset-left, 0px));
  padding-right: calc(12px + env(safe-area-inset-right, 0px));
}
html.psira-embed .psira-log {
  padding-left: calc(14px + env(safe-area-inset-left, 0px));
  padding-right: calc(14px + env(safe-area-inset-right, 0px));
}

/* Room for a host-drawn back control. The host app overlays its own native
   arrow (Material/Cupertino, with that platform's own pop behaviour) rather
   than the page drawing one, because only the host knows what "back" means --
   pop a route, switch a tab, nothing at all. The page's job is just to not put
   the avatar underneath it. Requested with /chat?back=1. */
html.psira-embed.psira-hasback .psira-head {
  padding-left: calc(52px + env(safe-area-inset-left, 0px));
}

/* Phone type scale. 13.5px suits a 380px panel viewed at desk distance; a
   phone held at arm's length wants the platform's own body size -- the same
   call the Flutter package made (mobile/psira_chat). */
html.psira-embed .psira-msg:not(.system):not(.notice) { font-size: 15px; }
html.psira-embed .psira-btns.optionlist button.psira-opt { font-size: 14.5px; }
html.psira-embed .psira-head .title { font-size: 16px; }
html.psira-embed .psira-head .sub { font-size: 12px; }

/* MUST stay >= 16px. Below that, iOS Safari/WKWebView zooms the page in when
   the field takes focus and never zooms back out, leaving the chat permanently
   magnified and horizontally scrollable. This single value is the whole fix. */
html.psira-embed .psira-foot input { font-size: 16px; }

/* Touch targets. 38px is a comfortable mouse target and a marginal thumb one;
   44px is the platform minimum on both iOS and Android. */
html.psira-embed .psira-foot button { width: 44px; height: 44px; }
html.psira-embed .psira-head button { padding: 9px 13px; }

/* A caret and text selection inside the transcript are desktop affordances;
   long-pressing a bubble should feel like an app, not select a paragraph.
   The input keeps both, obviously -- people edit what they type. */
html.psira-embed .psira-log { -webkit-user-select: none; user-select: none; }
html.psira-embed .psira-foot input { -webkit-user-select: text; user-select: text; }
