/* ===== Baffless Chat — dark theme ===== */
:root{
  --bg:#161616;            /* app background */
  --bg-2:#1e1e1e;          /* bars */
  --bg-3:#262626;          /* incoming bubble */
  --bg-4:#2f2f2f;          /* inputs */
  --line:#3a3a3a;
  --accent:#c4956a;        /* baffless copper */
  --accent-2:#8a6a4a;
  --accent-d:#46342a;      /* my (outgoing) bubble — warm copper-brown */
  --text:#e8e8e8;
  --text-dim:#9a9a9a;
  --ok:#4caf50;
  --warn:#d6a35d;
  --danger:#cf7e7e;
  --radius:18px;
  --safe-top:env(safe-area-inset-top,0px);
  --safe-bot:env(safe-area-inset-bottom,0px);
}
/* iOS 27 standalone chrome sits on top of the webview and eats taps, but
   env(safe-area-inset-top) often does not include it — so the Back chevron
   is painted in the chrome while the live hit target is the strip below. */
@media (display-mode: standalone), (display-mode: fullscreen) {
  :root{ --safe-top:calc(env(safe-area-inset-top, 0px) + 24px); }
}
html.standalone{
  --safe-top:calc(env(safe-area-inset-top, 0px) + 24px);
}
@media (min-width:700px){
  :root, html.standalone{ --safe-top:env(safe-area-inset-top, 0px); }
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%;margin:0}
html{
  position:fixed;inset:0;width:100%;height:100%;overflow:hidden;
  overscroll-behavior:none;
}
body{
  background:var(--bg);color:var(--text);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  overflow:hidden;position:fixed;inset:0;width:100%;height:100%;
  -webkit-font-smoothing:antialiased;
  overscroll-behavior:none;
}
.hidden{display:none!important}

/* ===== Onboarding ===== */
.setup{position:fixed;top:0;left:0;right:0;height:var(--vv-h, 100dvh);background:var(--bg);display:flex;align-items:center;justify-content:center;padding:24px;z-index:50;overflow-y:auto}
.setup-card{width:100%;max-width:420px;text-align:center}
.setup-logo{width:210px;height:auto;margin-bottom:18px}
.setup h1{margin:6px 0;font-size:26px;letter-spacing:.3px}
.setup-sub{color:var(--text-dim);margin:0 0 18px}
.setup textarea{width:100%;height:96px;background:var(--bg-4);border:1px solid var(--line);border-radius:12px;color:var(--text);padding:12px;font-family:ui-monospace,monospace;font-size:13px;resize:none}
.setup-manual{margin-top:16px;text-align:left;color:var(--text-dim)}
.setup-manual summary{cursor:pointer;padding:8px 0}
.setup-manual label{display:block;font-size:13px;margin:8px 0}
.setup-manual input{width:100%;margin-top:4px;background:var(--bg-4);border:1px solid var(--line);border-radius:10px;color:var(--text);padding:10px}
.setup-err{color:var(--danger);min-height:18px;margin-top:10px}
.setup-manual-fields{margin:8px 0 0 12px}
.setup-manual-warn{font-size:12px;color:var(--warn);line-height:1.35;margin:6px 0 0}
.web-pair-panel{display:flex;flex-direction:column;align-items:center}
.web-pair-qr{width:min(270px,72vw);aspect-ratio:1;background:#fff;border-radius:18px;padding:10px;
  display:flex;align-items:center;justify-content:center;box-shadow:0 14px 42px #0008}
.web-pair-qr svg{display:block;width:100%;height:100%}
.web-pair-fingerprint{margin-top:14px;color:var(--text-dim);font-size:12px;letter-spacing:.02em}
.web-pair-fingerprint strong{display:block;margin-top:4px;color:var(--text);font-size:19px;letter-spacing:.14em}
.web-pair-status{min-height:18px;margin:10px 0 0;color:var(--text-dim);font-size:13px}
.web-pair-actions{width:min(270px,72vw);display:flex;gap:8px}
.web-pair-actions .btn-secondary{margin-top:10px;padding:9px;font-size:13px}

.btn-primary{background:var(--accent);color:#1a1206;border:0;border-radius:12px;padding:14px;width:100%;font-size:16px;font-weight:600;margin-top:14px}
.btn-primary:active{background:var(--accent-2)}
.btn-secondary{background:var(--bg-4);color:var(--text);border:1px solid var(--line);border-radius:12px;padding:12px;width:100%;font-size:15px;margin-top:10px}

/* ===== Face ID lock ===== */
.app-lock{
  position:fixed;top:0;left:0;right:0;height:var(--vv-h, 100dvh);z-index:100;background:var(--bg);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:28px calc(28px + env(safe-area-inset-right,0px))
          calc(28px + env(safe-area-inset-bottom,0px))
          calc(28px + env(safe-area-inset-left,0px));
  text-align:center;
}
.lock-logo{width:72px;height:72px;border-radius:21px;margin-bottom:18px;box-shadow:0 10px 34px #0008}
.app-lock h1{font-size:24px;margin:0 0 8px}
.app-lock p{color:var(--text-dim);font-size:14px;margin:0 0 18px}
.app-lock .btn-primary{max-width:310px}
.app-lock .lock-error{color:var(--danger);min-height:18px;margin-top:14px}
.lock-form{width:100%;max-width:310px;display:flex;flex-direction:column;align-items:center}
.lock-pass{width:100%;max-width:310px;margin:0 0 12px;background:var(--bg-4);border:1px solid var(--line);
  border-radius:12px;color:var(--text);padding:13px;font-size:16px}
.lock-pass:focus{outline:none;border-color:var(--accent)}
.settings-hint{font-size:12px;color:var(--text-dim);line-height:1.35;margin:0 0 8px}
.pass-setup{display:flex;flex-direction:column;gap:8px;margin:4px 0 10px}
.pass-setup input{width:100%;background:var(--bg-4);border:1px solid var(--line);border-radius:10px;
  color:var(--text);padding:11px;font-size:15px}

/* ===== Phone-as-key scanner ===== */
.web-scan{position:fixed;inset:0;z-index:130;background:#101010;color:var(--text);
  display:flex;flex-direction:column;padding:calc(var(--safe-top) + 14px) 18px calc(var(--safe-bot) + 20px)}
.web-scan-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex:0 0 auto}
.web-scan-top h2{font-size:23px;margin:3px 0 4px}
.web-scan-top p{margin:0;color:var(--text-dim);font-size:13px;line-height:1.35}
.web-scan-camera{position:relative;flex:1;min-height:0;margin-top:18px;display:flex;flex-direction:column;align-items:center}
.web-scan-camera video{width:100%;max-width:520px;flex:1;min-height:260px;max-height:68dvh;
  border-radius:20px;background:#000;object-fit:cover}
.web-scan-frame{position:absolute;left:50%;top:42%;width:min(62vw,280px);aspect-ratio:1;
  transform:translate(-50%,-50%);border:3px solid var(--accent);border-radius:22px;
  box-shadow:0 0 0 999px #0004;pointer-events:none}
.web-scan-camera .btn-secondary{width:min(320px,90%);margin-top:14px}
.web-scan-confirm{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}
.web-device-icon{width:84px;height:64px;border:3px solid var(--accent);border-radius:9px;
  display:flex;align-items:center;justify-content:center;color:var(--accent);font-size:31px;box-shadow:0 12px 32px #0008}
.web-scan-confirm h3{font-size:22px;margin:20px 0 6px}
.web-scan-confirm p{color:var(--text-dim);font-size:12px;margin:0 0 5px}
.web-scan-confirm strong{font-size:24px;letter-spacing:.16em}
.web-scan-buttons{width:min(360px,100%);display:flex;gap:10px;margin-top:26px}
.web-scan-buttons button{margin-top:0}
.web-scan-buttons .btn-secondary{flex:0 0 36%}
.web-scan-buttons .btn-primary{flex:1}

/* ===== App layout ===== */
.app{position:fixed;top:0;left:0;right:0;bottom:0;height:auto;overflow:hidden;display:flex;flex-direction:column}
/* v262: measured height only while the keyboard is up; otherwise fill the screen */
body.kb-open .app{bottom:auto;height:var(--vv-h, 100dvh)}
/* Keyboard open: drop the home-indicator inset, hide the quota meter so the
   field sits higher, and leave the iOS prev/next/Done capsule a clear lane
   (JS already subtracted that capsule from --vv-h). */
body.kb-open .composer{padding-bottom:6px}
body.kb-open .session-usage{display:none}
.topbar{
  display:flex;align-items:center;gap:12px;
  padding:calc(var(--safe-top) + 8px) 14px 8px;
  background:var(--bg-2);border-bottom:1px solid var(--line);
  position:relative;z-index:10;
}
.topbar-logo{width:38px;height:38px;border-radius:12px}
.topbar-title{flex:1;min-width:0}
.t-name{font-weight:600;font-size:17px}
.t-status{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-dim)}
.dot{width:8px;height:8px;border-radius:50%;background:var(--text-dim);transition:background .3s}
.dot.on{background:var(--ok)}
.dot.wait{background:var(--warn)}
.dot.off{background:var(--danger)}
.model-pick{background:transparent;border:0;color:var(--accent);font-size:12.5px;font-weight:600;padding:3px 4px 3px 7px}
.model-pick:active{opacity:.6}
.model-menu{position:absolute;top:calc(var(--safe-top) + 54px);left:50%;transform:translateX(-50%);
  background:var(--bg-3);border:1px solid var(--line);border-radius:13px;padding:6px;z-index:30;
  box-shadow:0 10px 34px #000b;display:flex;flex-direction:column;gap:2px;min-width:190px}
.model-menu button{background:transparent;border:0;color:var(--text);text-align:left;padding:12px 16px;font-size:15px;border-radius:9px}
.model-menu button.sel{color:var(--accent);font-weight:600}
.model-menu button:active{background:#ffffff12}
.icon-btn{background:transparent;border:0;color:var(--text-dim);padding:8px;border-radius:50%;display:flex;align-items:center;justify-content:center}
.icon-btn:active{background:#ffffff14;color:var(--text)}
.web-key-btn{position:relative}
.web-key-btn .web-key-dot{position:absolute;right:5px;top:5px;width:7px;height:7px;border-radius:50%;
  background:var(--text-dim);border:1px solid var(--bg-2);opacity:.45}
.web-key-btn.active{color:var(--accent)}
.web-key-btn.active .web-key-dot{background:var(--warn);opacity:1;box-shadow:0 0 0 2px #d6a35d22}
.web-key-btn.connected .web-key-dot{background:var(--ok);box-shadow:0 0 0 2px #4caf5030}
.voice-start-btn{color:var(--accent)}
.voice-start-btn:disabled{color:var(--text-dim);opacity:.45}

/* ===== Screens (chat list / conversation) ===== */
.screen{position:absolute;inset:0;display:flex;flex-direction:column}
/* iOS 27 beta steals taps in the far-left edge for the system back
   gesture. The old -6px margin parked the chevron inside that zone, so
   Back only fired if the finger landed on the inner sliver. Keep the
   icon off the edge and grow the hit box inward (not further left). */
#chatview .topbar{
  padding-left:max(12px, calc(env(safe-area-inset-left, 0px) + 10px));
}
.back-btn{
  position:relative;
  z-index:20;
  margin-left:0;
  flex-shrink:0;
  min-width:48px;
  min-height:48px;
  padding:12px;
  touch-action:manipulation;
  -webkit-user-select:none;
  user-select:none;
}
.back-btn::before{
  content:"";
  position:absolute;
  /* Do not extend upward — that zone is the iOS 27 chrome. Grow down/in. */
  top:0;
  right:-18px;
  bottom:-16px;
  left:0;
}
.chat-avatar{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:15px;font-weight:700;color:#fff;flex-shrink:0}
.chat-rows{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;background:var(--bg)}
.chat-row{display:flex;align-items:center;gap:13px;padding:11px 14px;border-bottom:1px solid var(--line)}
.chat-row:active{background:#ffffff0a}
.avatar{width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:19px;font-weight:700;color:#fff;flex-shrink:0}
img.avatar{object-fit:cover}
.row-main{flex:1;min-width:0}
.row-top{display:flex;align-items:baseline;gap:8px}
.row-name{font-weight:600;font-size:16px;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row-time{font-size:12px;color:var(--text-dim);flex-shrink:0}
.row-bot{display:flex;align-items:center;gap:8px;margin-top:3px}
.row-preview{flex:1;min-width:0;font-size:14px;color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row-preview.typing{color:var(--accent)}
.row-preview .draft{color:var(--danger)}
.badge{background:var(--accent);color:#1a1206;font-size:12px;font-weight:700;min-width:20px;height:20px;border-radius:10px;display:flex;align-items:center;justify-content:center;padding:0 6px;flex-shrink:0}

/* ===== Messages ===== */
.messages{
  flex:1;overflow-y:auto;padding:14px 12px 6px;
  display:flex;flex-direction:column;gap:3px;
  background:
    radial-gradient(1200px 600px at 70% -10%, #1a130c 0%, transparent 60%),
    var(--bg);
  -webkit-overflow-scrolling:touch;
}

/* ===== Namai dashboard ===== */
.home-tabs{
  flex:0 0 auto;display:flex;align-items:center;gap:5px;padding:7px 10px;
  background:var(--bg-2);border-bottom:1px solid var(--line);
}
.home-tabs button{
  border:0;border-radius:9px;background:transparent;color:var(--text-dim);
  padding:7px 12px;font:600 13px/1 inherit;
}
.home-tabs button.active{background:#ffffff10;color:var(--text)}
.home-tabs button:disabled{opacity:.35}
.home-protocol-locked{opacity:.35!important;pointer-events:none}
.home-readonly{
  margin-left:auto;border:1px solid #c4956a55;border-radius:999px;padding:4px 8px;
  color:var(--accent);font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
}
.home-dashboard{
  flex:1;min-height:0;overflow:hidden;background:
    radial-gradient(900px 420px at 84% -5%, #4a2d1d55 0%, transparent 58%),var(--bg);
}
.home-scroll{
  height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:14px 12px calc(22px + var(--safe-bot));
}
.home-hero{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  max-width:980px;margin:0 auto 12px;padding:16px 17px;border:1px solid #ffffff12;
  border-radius:18px;background:linear-gradient(135deg,#2d241f,#211d1a);box-shadow:0 10px 28px #0003;
}
.home-kicker{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--accent)}
.home-hero h2{font-size:22px;line-height:1.15;margin:5px 0 3px}
.home-hero p{font-size:12px;color:var(--text-dim);margin:0}
.home-refresh{
  width:42px;height:42px;flex:0 0 auto;border:1px solid var(--line);border-radius:50%;
  background:#ffffff0b;color:var(--accent);font-size:25px;line-height:1;
}
.home-refresh:active{transform:rotate(35deg);background:#ffffff16}
.home-refresh.loading{animation:home-spin .85s linear infinite}
@keyframes home-spin{to{transform:rotate(360deg)}}
.home-cards{
  max-width:980px;margin:0 auto 10px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;
}
.home-card{
  min-height:104px;padding:13px 14px;border:1px solid #ffffff10;border-radius:16px;
  background:linear-gradient(155deg,#282828,#202020);display:grid;grid-template-columns:1fr auto;
  grid-template-rows:auto 1fr;align-items:end;
}
.home-card span{grid-column:1/-1;align-self:start;color:var(--text-dim);font-size:12px}
.home-card strong{font-size:30px;line-height:1;font-weight:650;letter-spacing:-.04em;margin-top:12px}
.home-card small{font-size:11px;color:var(--text-dim);padding-bottom:2px;text-align:right}
.home-state-row{max-width:980px;margin:0 auto 10px;display:flex;gap:6px;overflow-x:auto;padding:1px 0 3px;scrollbar-width:none}
.home-state-row::-webkit-scrollbar{display:none}
.home-state{white-space:nowrap;border:1px solid var(--line);border-radius:999px;padding:6px 9px;background:#222;color:var(--text-dim);font-size:11px}
.home-state.on{border-color:#4caf5066;color:#82d58a;background:#18351c80}
.home-state.warn{border-color:#d6a35d66;color:#e0b775;background:#3a2b1580}
.home-state.danger{border-color:#cf7e7e77;color:#efa0a0;background:#421e1e80}
.home-panel{
  max-width:980px;margin:0 auto 10px;padding:14px;border:1px solid #ffffff10;border-radius:17px;background:#202020;
}
.home-panel-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.home-panel h3{font-size:15px;margin:0 0 2px}
.home-panel-head p{font-size:11px;color:var(--text-dim);margin:0}
.home-range{display:flex;gap:2px;background:#171717;border:1px solid var(--line);border-radius:9px;padding:2px}
.home-range button{border:0;border-radius:6px;padding:5px 7px;background:transparent;color:var(--text-dim);font:600 10px/1 inherit}
.home-range button.active{background:#3a302a;color:var(--accent)}
.home-range #homeZoomReset{color:var(--accent)}
.home-legend{display:flex;gap:13px;margin:11px 0 4px;color:var(--text-dim);font-size:10px}
.home-legend span::before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px}
.home-legend .outside::before{background:#d79558}.home-legend .room::before{background:#e8c547}.home-legend .heating::before{background:#66bb6a}.home-legend .dhw::before{background:#4aa3df}
.home-legend .hygiene::before{background:#c084fc;border-radius:2px}.home-legend .heater::before{background:#e07a7a;border-radius:2px}
.home-legend .power::before{background:#e6a15c;border-radius:2px}
.home-chart-wrap{height:190px;min-width:0;position:relative;touch-action:pan-y;cursor:ew-resize;user-select:none}
#homeChart,#homePowerChart{display:block;width:100%;height:100%}
.home-details{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;margin-top:11px;background:var(--line);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.home-details div{min-width:0;background:#242424;padding:10px 11px;display:flex;flex-direction:column;gap:4px}
.home-details span{font-size:10px;color:var(--text-dim)}
.home-details strong{font-size:15px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.home-details strong[data-kind="on"]{color:#82d58a}
.home-details strong[data-kind="warn"]{color:#e0b775}
.home-note{max-width:980px;margin:5px auto 0;text-align:center;color:var(--text-dim);font-size:10.5px}
#chatview.home-dashboard-mode #jumpBottom,
#chatview.home-dashboard-mode .attach-sheet,
#chatview.home-dashboard-mode .attach-preview{display:none!important}
@media (min-width:700px){
  .home-scroll{padding:22px 24px 34px}.home-cards{grid-template-columns:repeat(4,minmax(0,1fr))}
  .home-chart-wrap{height:250px}.home-details{grid-template-columns:repeat(3,minmax(0,1fr))}
}
/* contain:layout keeps a bubble's internals off the layout path of everything else —
   without it every composer keystroke (which measures the textarea) re-laid out the
   whole conversation. .no-anim is set on bulk-rendered history: a hundred bubbles
   playing the pop animation at once is a guaranteed dropped-frame storm. */
.msg{max-width:82%;padding:8px 11px;border-radius:var(--radius);font-size:15.5px;line-height:1.35;position:relative;word-wrap:break-word;animation:pop .14s ease-out;contain:layout style}
.msg.no-anim{animation:none}
@keyframes pop{from{transform:translateY(4px);opacity:0}to{transform:none;opacity:1}}
.load-earlier{align-self:center;margin:2px 0 8px;padding:6px 14px;border:1px solid var(--line);
  border-radius:999px;background:var(--bg-3);color:var(--text-dim);font-size:13px;font-family:inherit}
.load-earlier:disabled{opacity:.6}
.msg.in{align-self:flex-start;background:var(--bg-3);border-bottom-left-radius:6px}
.msg.out{align-self:flex-end;background:var(--accent-d);border-bottom-right-radius:6px}
.msg .who{font-size:12.5px;font-weight:600;color:var(--accent);margin-bottom:2px}
.msg .meta{font-size:10.5px;color:var(--text-dim);text-align:right;margin-top:3px;user-select:none}
.msg.out .meta{color:#c8a98a}
.send-state{margin-left:3px}
.send-state.pending{opacity:.7}
.send-state.sent{color:#7fd18c}
.send-state.failed{color:#ff8a80}
.msg.grouped{margin-top:1px}
.msg img.photo{max-width:100%;border-radius:12px;display:block;margin:2px 0}
.msg audio{width:230px;max-width:60vw;margin:2px 0}
.file-card{display:flex;align-items:center;gap:10px;padding:6px 2px}
.file-ic{width:40px;height:40px;border-radius:10px;background:var(--accent);color:#1a1206;display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}
.file-meta{min-width:0}
.file-name{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:55vw}
.file-sub{font-size:12px;color:var(--text-dim)}
.file-card a{color:var(--accent);text-decoration:none;font-size:13px}
.file-caption{margin-top:5px;font-size:15px;line-height:1.35;white-space:pre-wrap;word-wrap:break-word}
.day-sep{align-self:center;background:#00000066;color:var(--text-dim);font-size:12px;padding:3px 10px;border-radius:10px;margin:8px 0}

/* ===== Composer ===== */
.composer{
  display:flex;flex-direction:column;gap:3px;
  /* equal top/bottom padding so the field is vertically centred in the bar
     (symmetric); the bottom also clears the home indicator via the safe inset */
  padding:7px 8px max(6px, calc(var(--safe-bot) * 0.5));
  background:var(--bg-2);border-top:1px solid var(--line);
}
.composer-row{width:100%;display:flex;align-items:center;gap:5px}
.msg-input{
  min-width:0;
  flex:1;background:var(--bg-4);border:0;border-radius:21px;
  color:var(--text);font-size:16px;padding:11px 16px;resize:none;max-height:120px;
  min-height:42px;line-height:1.4;box-sizing:border-box;
  scroll-margin-bottom:8px;
}
.msg-input::placeholder{color:var(--text-dim)}
.msg-input:focus{outline:none;background:#3a3a3a}
.composer-row .icon-btn{width:42px;height:42px;flex-shrink:0}
#readAloudBtn .read-stop{display:none}
#readAloudBtn.reading{color:var(--accent,#3390ec);background:rgba(51,144,236,.14)}
#readAloudBtn.reading .read-play{display:none}
#readAloudBtn.reading .read-stop{display:block}
.simple-call .voice-control:disabled{opacity:.35;pointer-events:none}
#simpleCall[data-state=""] #scSendBtn,#simpleCall[data-state=""] #scSkipBtn{display:none}
.composer .icon-btn svg{width:24px;height:24px}
.send-btn,.mic-btn{color:var(--accent)}
/* v261: big voice-note mic, easy to hit while driving */
.composer-row .icon-btn.mic-btn{width:64px;height:64px;background:var(--accent);color:#1a1206}
.composer-row .icon-btn.mic-btn:active{background:var(--accent-2)}
.composer .icon-btn.mic-btn svg{width:34px;height:34px}
.send-btn{background:var(--accent);color:#1a1206}
.send-btn:active{background:var(--accent-2)}
.stop-btn{background:#8a3030;color:#ffe8e8}
.stop-btn:active{background:#a03a3a}
/* One line per provider window: short window on top, weekly below. */
.session-usage{width:calc(100% - 94px);margin:1px 47px 0;
  display:flex;flex-direction:column;gap:1px;color:var(--text-dim);
  font-size:10.5px;line-height:14px}
.usage-row{min-height:14px;display:flex;align-items:center;gap:6px}
.usage-row.hidden{display:none}
.usage-caption{flex-shrink:0;min-width:54px}   /* keeps both bars on one left edge */
.session-usage strong{min-width:31px;color:var(--text);font-size:11px;
  line-height:14px;text-align:right;font-weight:650}
#usageReset,#usageReset2{min-width:25px;font-size:9.5px;white-space:nowrap}
.usage-track{height:3px;flex:1;background:#ffffff20;border-radius:3px;overflow:hidden}
.usage-track span{display:block;width:0;height:100%;background:var(--accent);
  border-radius:2px;transition:width .35s ease,background .25s ease}
.usage-row.warn .usage-track span{background:#d49b4c}
.usage-row.full .usage-track span{background:var(--danger)}
/* The weekly line is context, not the live constraint: keep it quieter. */
.usage-row + .usage-row{opacity:.75}
.usage-row + .usage-row strong{font-weight:550}
.session-usage.stale{opacity:.85}
.session-usage.stale strong{color:var(--text-dim);font-weight:500;min-width:auto}

/* pending attachment preview (above composer) */
.attach-preview{display:flex;align-items:center;gap:8px;padding:8px 8px 8px 12px;background:var(--bg-2);border-top:1px solid var(--line)}
.attach-chips{flex:1;min-width:0;display:flex;gap:8px;overflow-x:auto;-webkit-overflow-scrolling:touch;padding:2px 0}
.attach-chip{position:relative;flex:0 0 auto;width:56px;height:56px;border-radius:10px;overflow:hidden;background:var(--bg-4)}
.attach-chip img{width:100%;height:100%;object-fit:cover;display:block}
.attach-chip-ic{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:22px}
.attach-chip-x{position:absolute;top:2px;right:2px;width:20px;height:20px;border:0;border-radius:50%;
  background:#000000aa;color:#fff;font-size:13px;line-height:20px;padding:0;cursor:pointer}
.attach-x{background:transparent;border:0;color:var(--text-dim);font-size:18px;padding:8px;flex-shrink:0}
.attach-x:active{color:var(--text)}

/* attach sheet */
.attach-sheet{position:absolute;bottom:64px;left:10px;background:var(--bg-3);border:1px solid var(--line);border-radius:14px;padding:6px;display:flex;flex-direction:column;gap:2px;z-index:20;box-shadow:0 8px 30px #000a}
.attach-sheet button{background:transparent;border:0;color:var(--text);text-align:left;padding:12px 18px;font-size:15px;border-radius:10px}
.attach-sheet button:active{background:#ffffff10}

/* recording */
.rec-bar{position:absolute;bottom:0;left:0;right:0;display:flex;align-items:center;gap:10px;padding:12px 14px calc(var(--safe-bot) + 12px);background:var(--bg-2);border-top:1px solid var(--line);z-index:25}
.rec-dot{width:12px;height:12px;border-radius:50%;background:var(--danger);animation:blink 1s infinite}
@keyframes blink{50%{opacity:.25}}
.rec-hint{color:var(--text-dim);font-size:13px;flex:1}
.rec-cancel{background:transparent;border:0;color:var(--danger);font-size:16px;padding:14px 10px}
.rec-send{background:var(--accent);color:#1a1206;border:0;border-radius:28px;padding:18px 30px;font-size:18px;font-weight:700;min-height:60px}

/* ===== Live Realtime voice call ===== */
.voice-call{
  position:fixed;inset:0;z-index:90;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:calc(var(--safe-top) + 72px) max(24px, env(safe-area-inset-right))
          calc(var(--safe-bot) + 28px) max(24px, env(safe-area-inset-left));
  color:var(--text);text-align:center;
  background:
    radial-gradient(circle at 50% 22%, #8a6a4a44 0, transparent 34%),
    linear-gradient(180deg,#211d1a 0%,#111 78%);
}
.voice-call audio{display:none}
.voice-call-top{position:absolute;top:calc(var(--safe-top) + 12px);left:18px;right:12px;
  display:flex;align-items:center;justify-content:space-between}
.voice-secure{font-size:12px;letter-spacing:.02em;color:var(--text-dim)}
.voice-secure span{color:var(--ok);font-size:15px;margin-right:4px}
.voice-close{width:42px;height:42px;border:0;border-radius:50%;background:#ffffff0d;
  color:var(--text-dim);font-size:30px;line-height:38px}
.voice-call-avatar{width:116px;height:116px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;background-color:var(--accent-2);background-size:cover;background-position:center;
  color:#fff;font-size:38px;font-weight:700;box-shadow:0 16px 50px #0009,inset 0 1px 2px #fff4}
.voice-call h2{font-size:27px;line-height:1.15;margin:22px 0 4px}
.voice-call-model{min-height:18px;margin:0;color:var(--text-dim);font-size:13px}
.voice-pulse{height:52px;margin:28px 0 10px;display:flex;align-items:center;justify-content:center;gap:6px}
.voice-pulse span{display:block;width:5px;height:10px;border-radius:5px;background:var(--accent);
  opacity:.45;transform-origin:center;transition:height .2s,opacity .2s}
.voice-call[data-state="listening"] .voice-pulse span,
.voice-call[data-state="speaking"] .voice-pulse span{animation:voiceWave .9s ease-in-out infinite;opacity:1}
/* Honest mic meter: fake waves hid a deaf analyser. Live RMS drives the bars. */
.simple-call[data-state="listening"] .voice-pulse span{
  animation:none;
  height:calc(8px + var(--sc-level, 0) * 36px);
  opacity:calc(.4 + var(--sc-level, 0) * .6);
  transition:height .08s linear,opacity .08s linear;
}
.voice-call[data-state="speaking"] .voice-pulse span{background:#e8e8e8}
.voice-pulse span:nth-child(2),.voice-pulse span:nth-child(4){animation-delay:-.2s!important}
.voice-pulse span:nth-child(3){animation-delay:-.4s!important}
@keyframes voiceWave{0%,100%{height:10px}50%{height:44px}}
.voice-call-status{font-size:16px;min-height:22px;margin:0;color:var(--text)}
.voice-call-error{max-width:340px;margin:10px 0 0;color:#f1aaaa;font-size:13px;line-height:1.4}
/* On the simple call the error line doubles as the retry button: iOS frees a
   busy microphone far more readily inside a real tap than from a timer. */
.simple-call .voice-call-error{cursor:pointer;-webkit-tap-highlight-color:transparent}
.voice-diag{max-width:340px;margin:12px 0 0;padding:10px 12px;border-radius:12px;background:#ffffff10;text-align:left}
.voice-diag-stats{margin:0;color:#cfd6e0;font-size:11px;font-variant-numeric:tabular-nums;line-height:1.5}
.voice-diag-section{margin:10px 0 0;color:#9aa3b2;font-size:10px;font-weight:600;letter-spacing:.02em;text-transform:uppercase}
.voice-diag-row{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.voice-diag-toggle{padding:5px 9px;border:1px solid #ffffff26;border-radius:14px;background:transparent;
  color:var(--text-dim);font-size:10.5px;line-height:1.2}
.voice-diag-toggle[data-on="1"]{border-color:var(--accent);color:var(--accent)}
.voice-diag-toggle.voice-diag-report{border-color:#ffffff40}
.voice-diag-toggle.voice-diag-report[data-crackle-report="crackle"][data-flash="1"]{border-color:#e07070;color:#f1aaaa}
.voice-diag-toggle.voice-diag-report[data-crackle-report="clean"][data-flash="1"]{border-color:#70c090;color:#a8e0c0}
.voice-diag-note{margin:8px 0 0;color:#666;font-size:10px}
.voice-retry{margin:16px 0 0;padding:10px 18px;border:1px solid var(--accent);border-radius:20px;
  background:transparent;color:var(--accent);font-size:14px;font-weight:600}
.voice-call-controls{display:flex;align-items:flex-start;justify-content:center;gap:22px;margin-top:auto;padding-top:24px}
.voice-control{width:76px;border:0;background:transparent;color:var(--text-dim);font-size:12px;
  display:flex;flex-direction:column;align-items:center;gap:8px}
.voice-control-icon{width:58px;height:58px;border-radius:50%;background:#ffffff14;color:var(--text);
  display:flex;align-items:center;justify-content:center;transition:background .15s,transform .15s}
.voice-control-icon svg{width:27px;height:27px}
.voice-control:active .voice-control-icon{transform:scale(.93)}
.voice-control[aria-pressed="true"] .voice-control-icon{background:#f0f0f0;color:#222}
.voice-end .voice-control-icon{background:#c94747;color:#fff}
.voice-cost{margin:22px 0 0;color:#777;font-size:10.5px}
.voice-call-note{margin:7px 0 0;color:#666;font-size:10.5px}

/* ===== Modal ===== */
.modal{position:fixed;top:0;left:0;right:0;height:var(--vv-h, 100dvh);background:#000a;display:flex;align-items:center;justify-content:center;padding:24px;z-index:40;overflow-y:auto}
.modal-card{width:100%;max-width:380px;background:var(--bg-2);border:1px solid var(--line);border-radius:16px;padding:20px}
.modal-card h2{margin:0 0 14px}
.modal-card label{display:block;font-size:13px;color:var(--text-dim);margin:10px 0}
.modal-card input{width:100%;margin-top:5px;background:var(--bg-4);border:1px solid var(--line);border-radius:10px;color:var(--text);padding:11px;font-size:15px}
.modal-card label.row-toggle{display:flex;align-items:center;justify-content:space-between;gap:10px}
.modal-card label.row-toggle input{width:auto;margin-top:0;flex:0 0 auto;transform:scale(1.3)}
.modal-card .row-toggle span{font-size:13px;color:var(--text-dim)}
.btn-inline{width:auto !important;margin-top:0 !important;padding:8px 12px !important;font-size:13px !important;flex:0 0 auto}
.modal-row{display:flex;gap:10px;margin-top:16px}
.modal-row .btn-primary,.modal-row .btn-secondary{margin-top:0}

/* scrollbar (desktop) */
.messages::-webkit-scrollbar,.chat-rows::-webkit-scrollbar{width:7px}
.messages::-webkit-scrollbar-thumb,.chat-rows::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}

/* ===== Professional polish ===== */
/* depth on bubbles + avatars */
.msg{box-shadow:0 1px 1.5px #0000002e}
.avatar,.chat-avatar{box-shadow:inset 0 1px 2px #ffffff22, inset 0 -2px 4px #0003}
.topbar{box-shadow:0 1px 0 #0003}

/* subtle screen entrance (list <-> chat) */
.screen:not(.hidden){animation:screenIn .2s ease}
@keyframes screenIn{from{opacity:.4;transform:translateX(8px)}to{opacity:1;transform:none}}
#chatlist:not(.hidden){animation:listIn .2s ease}
@keyframes listIn{from{opacity:.4;transform:translateX(-8px)}to{opacity:1;transform:none}}

/* animated typing bubble (Telegram-style three dots) */
.typing-bubble{padding:13px 14px!important;display:flex!important;gap:5px;align-items:center}
.typing-bubble span{width:7px;height:7px;border-radius:50%;background:var(--text-dim);animation:typingDot 1.3s infinite}
.typing-bubble span:nth-child(2){animation-delay:.18s}
.typing-bubble span:nth-child(3){animation-delay:.36s}
.typing-bubble .typing-label{font-size:12px;color:var(--text-dim);font-style:normal;margin-left:2px}
@keyframes typingDot{0%,60%,100%{opacity:.35;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}

/* empty chat-list hint */
.list-empty{color:var(--text-dim);text-align:center;padding:40px 20px;font-size:14px}

/* message search (chat list) */
.search-row{padding:6px 10px;background:var(--bg-2);border-bottom:1px solid var(--line)}
.search-row input{width:100%;background:var(--bg-4);border:1px solid var(--line);border-radius:18px;
  color:var(--text);padding:8px 14px;font-size:14px;outline:none}
.search-row input::placeholder{color:var(--text-dim)}

/* rich text in bubbles */
.msg a,.snap-msg a{color:#6ab3f3;text-decoration:underline;word-break:break-all;
  -webkit-user-select:auto;user-select:auto;-webkit-touch-callout:default}
.msg code{background:#00000055;border-radius:5px;padding:1px 5px;font-family:ui-monospace,monospace;font-size:13.5px}
.msg pre.code{background:#00000055;border-radius:8px;padding:8px 10px;margin:4px 0;overflow-x:auto;
  font-family:ui-monospace,monospace;font-size:12.5px;line-height:1.4;white-space:pre-wrap;word-break:break-word}
.file-gone{color:var(--text-dim);font-style:italic}

/* stop iOS from selecting bubble text / showing the copy-callout during our long-press
   (partial copy still works inside the dedicated .seltext-body panel, which re-enables it) */
.messages, .messages .msg, .msg-menu-ov, .msg-menu, .msg-menu button{
  -webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
@media (hover:hover) and (pointer:fine){
  .messages, .messages .msg{
    -webkit-user-select:text;user-select:text;-webkit-touch-callout:default;cursor:text}
}
/* no text-selection in the agents list / top bars (search input stays selectable) */
.chat-rows, .chat-row, .topbar{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}

/* long-press action menu (bottom sheet) */
.msg-menu-ov{position:fixed;inset:0;background:#0006;z-index:115;display:flex;align-items:flex-end;justify-content:center}
.msg-menu{width:100%;max-width:460px;margin:0 8px calc(env(safe-area-inset-bottom) + 8px);
  background:var(--bg-2);border:1px solid var(--line);border-radius:16px;overflow:hidden;
  display:flex;flex-direction:column;animation:sheetup .16s ease-out}
@keyframes sheetup{from{transform:translateY(14px);opacity:.6}to{transform:translateY(0);opacity:1}}
.msg-menu button{background:transparent;border:0;border-bottom:1px solid var(--line);
  color:var(--text);font-size:17px;padding:15px;text-align:center}
.msg-menu button:last-child{border-bottom:0}
.msg-menu .mm-cancel{color:var(--text-dim);font-weight:600}
.msg-menu .mm-danger{color:#e35d6a;font-weight:600}
.msg-menu .mm-title{color:var(--text-dim);font-size:13px;font-weight:600;text-align:center;padding:10px 15px 8px;border-bottom:1px solid var(--line)}

/* selectable-text panel (partial copy) */
.seltext-ov{position:fixed;inset:0;background:#0008;z-index:118;display:flex;align-items:center;justify-content:center;padding:16px}
.seltext-box{width:100%;max-width:560px;max-height:80dvh;display:flex;flex-direction:column;
  background:var(--bg-2);border:1px solid var(--line);border-radius:14px;overflow:hidden}
.seltext-head{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;
  border-bottom:1px solid var(--line);color:var(--text-dim);font-size:13px;font-weight:600}
.seltext-close{background:transparent;border:0;color:var(--text);font-size:24px;width:34px;height:34px}
.seltext-body{padding:14px;overflow-y:auto;font-size:15.5px;line-height:1.4;white-space:pre-wrap;word-break:break-word;
  user-select:text;-webkit-user-select:text;-webkit-touch-callout:default;cursor:text}

/* reply bar above the composer + quoted block inside a bubble */
#replyBar{display:flex;align-items:center;gap:8px;padding:7px 12px;background:var(--bg-2);
  border-top:1px solid var(--line);border-left:3px solid var(--accent)}
#replyBar .reply-q{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.25}
#replyBar .reply-to{font-size:12px;color:var(--accent);font-weight:600}
#replyBar .reply-t{font-size:13px;color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#replyBar .reply-x{background:transparent;border:0;color:var(--text-dim);font-size:18px;width:34px;height:34px;flex-shrink:0}
.q-block{border-left:3px solid var(--accent);padding:2px 8px;margin:0 0 5px;border-radius:4px;
  background:#ffffff10;font-size:13px;line-height:1.3}
.q-block .q-from{display:block;color:var(--accent);font-weight:600;font-size:12px}

/* saved / bookmarked messages */
.msg.saved{box-shadow:-3px 0 0 0 var(--accent)}
/* frozen snapshot viewer */
.snap-viewer{position:fixed;inset:0;background:var(--bg);z-index:110;display:flex;flex-direction:column}
.snap-head{display:flex;align-items:center;gap:8px;padding:calc(env(safe-area-inset-top) + 10px) 12px 10px;
  background:var(--bg-2);border-bottom:1px solid var(--line)}
.snap-close{border:0;background:transparent;color:var(--text);font-size:26px;width:38px;height:38px;flex-shrink:0}
.snap-title{font-size:13.5px;color:var(--text-dim);font-weight:600;min-width:0}
.snap-body{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column}
.snap-msg{max-width:82%;margin:3px 0;padding:8px 11px;border-radius:12px;font-size:15px;line-height:1.35;word-wrap:break-word;white-space:pre-wrap}
.snap-msg.in{background:var(--bg-3);align-self:flex-start}
.snap-msg.out{background:#2b5278;color:#fff;align-self:flex-end}
.snap-msg .who{font-size:12px;color:var(--text-dim);margin-bottom:2px}
.snap-msg.out .who{color:#cde}
.snap-msg .meta{font-size:10px;opacity:.6;margin-top:3px}
.saved-mark{margin-left:4px}
.msg.flash{animation:msgflash 1.6s ease}
@keyframes msgflash{0%,100%{background:inherit}20%,60%{background:#e8a13340}}
.icon-btn.active{color:var(--accent)}
#toast{position:fixed;left:50%;bottom:90px;transform:translateX(-50%) translateY(10px);
  background:#000000d9;color:#fff;padding:9px 16px;border-radius:20px;font-size:14px;
  z-index:120;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;max-width:80vw;text-align:center}
#toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* full-screen image viewer — image fills the viewport at (0,0), origin top-left, so the
   JS focal-zoom maths line up exactly (object-fit:contain still centres the picture) */
.img-viewer{position:fixed;inset:0;background:#000000e6;z-index:100;overflow:hidden;touch-action:none}
.img-viewer img{position:absolute;top:0;left:0;width:100vw;height:100dvh;object-fit:contain;
  transform-origin:0 0;touch-action:none;user-select:none;-webkit-user-select:none;
  -webkit-user-drag:none;will-change:transform}
.img-close{position:absolute;top:calc(env(safe-area-inset-top) + 12px);right:14px;width:40px;height:40px;
  border:0;border-radius:999px;background:#00000088;color:#fff;font-size:28px;line-height:36px;z-index:1}

/* ===== Responsive: centre as a column on tablet/desktop ===== */
@media (min-width:600px){
  body{background:#0c0c0c}
  .app{left:50%;right:auto;width:min(480px,100vw);margin-left:calc(min(480px,100vw) / -2);
       border-left:1px solid var(--line);border-right:1px solid var(--line)}
  .msg{max-width:74%}
  .voice-call{left:50%;right:auto;width:min(480px,100vw);transform:translateX(-50%);
    border-left:1px solid var(--line);border-right:1px solid var(--line)}
}
/* ===== Wide desktop: full-screen two-pane (chat list + conversation) ===== */
@media (min-width:1000px){
  body{background:#0c0c0c}
  .app{left:0;right:auto;width:100vw;margin-left:0;flex-direction:row;border:0}
  #chatlist.screen{position:relative;inset:auto;flex:0 0 340px;width:340px;
                   border-right:1px solid var(--line)}
  #chatview.screen{position:relative;inset:auto;flex:1 1 auto;min-width:0}
  /* keep BOTH panes visible regardless of the mobile show/hide toggling */
  #chatlist.hidden,#chatview.hidden{display:flex!important}
  .back-btn{display:none!important}
  .msg{max-width:600px}
}
@media (hover:hover){
  .chat-row:hover{background:#ffffff08}
  .icon-btn:hover{color:var(--text)}
  .attach-sheet button:hover{background:#ffffff10}
}

/* Telegram-style jump-to-latest button */
.jump-bottom{
  position:absolute;
  right:12px;
  bottom:calc(84px + max(9px, calc(var(--safe-bot) * 0.5)));
  width:42px;height:42px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--bg-3);color:var(--text);
  border:1px solid var(--line);
  box-shadow:0 2px 10px #00000066;
  z-index:9;cursor:pointer;
  opacity:.95;
  transition:opacity .15s ease, transform .15s ease;
}
.jump-bottom:active{transform:scale(.92)}

/* ===== Simple voice call (js/simple-call.js) ===== */
/* Reuses the .voice-call shell; only the answer preview and the thinking
   state are new. Blue tint separates it from the Realtime call at a glance. */
.simple-call{
  background:
    radial-gradient(circle at 50% 22%, #3a5a8a44 0, transparent 34%),
    linear-gradient(180deg,#1a1e24 0%,#111 78%);
}
/* Quota bar borrowed from the chat footer while the call is open: same element,
   same renderUsage(), just wider and centred under the controls. */
.sc-usage{width:min(340px,100%);margin:18px 0 0;min-height:14px}
.sc-usage .session-usage{width:100%;margin:0}
.sc-usage .usage-track{background:#ffffff2a}
.sc-reply{
  max-width:340px;max-height:6.2em;overflow:hidden;
  margin:12px 0 0;color:var(--text-dim);font-size:13px;line-height:1.45;
}
