 :root {
   --bg:#f3f4f6; --surface:#ffffff; --border:#e5e7eb; --muted:#6b7280;
   --text:#0f172a; --accent:#2563eb; --accent2:#1d4ed8;
   --in-bubble:#eef2ff; --out-bubble:#dbeafe;
   --danger:#ef4444; --safe:#10b981;
   /* mobile redesign v2 */
   --app-bg:#f5f7fb;
   --surface-soft: rgba(255,255,255,.82);
   --line: rgba(15,23,42,.08);
   --accent-soft:#dbeafe;
   --shadow-soft: 0 10px 30px rgba(15,23,42,.08);
   --topbar-h: 48px;
   --kb-inset: 0px;
   --composer-h: 64px;
   --safe-bottom-active: env(safe-area-inset-bottom);
   --composer-bottom: -12px;
   --composer-bottom-positive: 0px;
   /* premium upgrade v2.2 */
   --app-bg-2: #eef4ff;
   --surface-strong: rgba(255,255,255,.96);
   --muted-2: #94a3b8;
   --line-strong: rgba(15,23,42,.12);
   --accent-2: #4f46e5;
   --success: #16a34a;
   --warning: #f59e0b;
   --shadow-card: 0 8px 24px rgba(15,23,42,.06);
   --radius-lg: 22px;
   --radius-md: 16px;
 }
 *,*::before,*::after { box-sizing: border-box; }
 html { scroll-behavior: smooth; }
 html, body { margin:0; padding:0; }
 body { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
        background: var(--bg); color: var(--text); -webkit-tap-highlight-color: transparent;
        -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
        text-rendering: optimizeLegibility; }
 a { color: var(--accent); text-decoration: none; }
 button, a, .seg-item, .card, .btn-link, .attach-btn {
   transition: background-color .14s ease, color .14s ease,
               box-shadow .18s ease, transform .14s ease, opacity .14s ease;
 }

 .topbar { position: sticky; top:0; z-index:10; background:#1f2937; color:#fff;
           padding-top: env(safe-area-inset-top);
           box-shadow: 0 1px 0 rgba(0,0,0,.04); }
 .topbar-row { display:flex; gap:18px; align-items:center; padding: 10px 14px;
               max-width: 900px; margin: 0 auto; }
 .topbar a { color:#cbd5e1; font-weight:500; padding: 4px 2px; border-radius: 6px; }
 .topbar a:hover { color:#fff; }
 .topbar a:active { color:#fff; transform: translateY(0); }
 .topbar .brand { color:#fff; font-weight:700; font-size:16px; letter-spacing:-.01em; }

 main { max-width: 900px; margin: 0 auto; padding: 12px;
        padding-bottom: calc(16px + env(safe-area-inset-bottom)); }

 .err { background:#fef2f2; color:#991b1b; padding:10px 14px; border-radius:10px;
        margin: 0 0 10px; border:1px solid #fecaca; }
 .ok  { background:#ecfdf5; color:#065f46; padding:10px 14px; border-radius:10px;
        margin: 0 0 10px; border:1px solid #a7f3d0; }

 .empty { padding: 36px 20px; text-align:center; color:var(--muted);
          background: var(--surface); border-radius: 14px; border:1px solid var(--border); }
 .muted { color: var(--muted); font-size: 13px; }
 h2 { font-size: 18px; margin: 4px 4px 12px; }

 /* Avatar */
 .avatar { width: 44px; height: 44px; min-width: 44px; flex: 0 0 44px;
           border-radius: 50%; background:#9ca3af; color:#fff;
           font-weight:600; font-size:16px;
           display:inline-flex; align-items:center; justify-content:center;
           flex-shrink:0; overflow:hidden; user-select:none; }
 .avatar img { width:100%; height:100%; object-fit:cover; display:block;
               transition: none !important; animation: none !important;
               -webkit-backface-visibility: hidden; backface-visibility: hidden; }
 .avatar.sm { width: 36px; height:36px; min-width: 36px; flex: 0 0 36px; font-size:14px; }
 .avatar.lg { width: 56px; height:56px; min-width: 56px; flex: 0 0 56px; font-size:20px; }

 /* Inbox cards */
 .cards { display:flex; flex-direction:column; gap: 8px; }
 .card { display:flex; gap:12px; padding:12px; background: var(--surface);
         border:1px solid var(--border); border-radius:14px;
         color: inherit; align-items:center;
         box-shadow: 0 1px 2px rgba(15,23,42,.04); }
 .card:hover { box-shadow: 0 8px 24px rgba(15,23,42,.06); transform: translateY(-1px); }
 .card:active { background:#f9fafb; transform: scale(.99); box-shadow: 0 1px 2px rgba(15,23,42,.05); }
 .card.is-loading { opacity: .55; }
 .card .body { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
 .card .row1 { display:flex; align-items:center; gap:8px; }
 .card .group-name { font-weight:600; font-size:15px; flex:1; min-width:0;
                     overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
 .card .timestamp { font-size:12px; color:var(--muted); flex-shrink:0; }
 .card .row2 { display:flex; align-items:center; gap:8px; }
 .card .peer-name { font-size:14px; color:var(--text); flex:1; min-width:0;
                    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
 .card .peer-id { font-size:12px; color:var(--muted); flex-shrink:0; }
 .card .preview { font-size:13px; color:var(--muted);
                  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%; }
 .badge { background: var(--accent); color:#fff; border-radius:10px; font-size:11px;
          padding:1px 7px; font-weight:600; min-width:20px; text-align:center; }

 /* Dialog */
 .dialog-header { position: sticky; top: calc(env(safe-area-inset-top) + var(--topbar-h, 44px)); z-index:5;
                  display:flex; gap:10px; align-items:center; padding:8px 12px;
                  background: var(--surface); border:1px solid var(--border);
                  border-radius:14px; margin-bottom:10px;
                  min-height: 56px; box-sizing: border-box; }
 .dialog-header .back { font-size:20px; color: var(--accent); padding:4px 8px;
                        margin: -4px 0 -4px -4px; line-height:1; }
 .dialog-header .titles { flex:1; min-width:0; display:flex; flex-direction:column;
                          justify-content:center; gap:1px; }
 .dialog-header .group { font-weight:600; font-size:15px; line-height:1.2;
                         overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
 .dialog-header .peer  { font-size:12px; color: var(--muted); line-height:1.2;
                         overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

 details.tech { background: var(--surface); border:1px solid var(--border);
                border-radius: 10px; padding: 8px 12px; font-size: 13px;
                margin: 0 0 10px; }
 details.tech summary { color: var(--muted); cursor: pointer; outline: none; }
 details.tech .kv { display:grid; grid-template-columns: max-content 1fr; gap: 4px 12px; margin-top:8px; }
 details.tech code { background:#f1f5f9; padding:1px 5px; border-radius:3px; font-size:12px; }

 /* Bottom safe-area is handled inside .send only — no double counting here. */
 .messages { display:flex; flex-direction:column; gap: 4px;
             padding: 12px 4px 8px; }
 .scroll-anchor { width: 0; height: 0; padding: 0; margin: 0; flex-shrink: 0; }
 .msg-row { display:flex; align-items:flex-end; gap: 8px; margin: 6px 0; }
 .msg-row.in  { justify-content:flex-start; }
 .msg-row.out { justify-content:flex-end; }
 .bubble { display: block; width: fit-content; max-width: min(82vw, 560px);
           min-width: 0; padding: 9px 12px 7px; border-radius: 16px;
           font-size: 15px; line-height: 1.32;
           word-wrap: break-word; overflow-wrap: anywhere; }
 .bubble.in  { background: var(--in-bubble); border-bottom-left-radius: 6px; }
 .bubble.out { background: var(--out-bubble); border-bottom-right-radius: 6px; }
 .bubble-text { margin: 0; white-space: pre-wrap; }
 .bubble .meta { display:block; margin-top: 5px; font-size: 11px;
                 line-height: 1.2; opacity: .65; color: var(--text); }
 .msg-status { margin-left: 4px; }
 .msg-status.read   { color: #2563eb; opacity: .9; }
 .msg-status.failed { color: #dc2626; opacity: .9; }

 /* Attachments / materials */
 .media-grid { display: grid; gap: 6px; margin-top: 8px; grid-template-columns: 1fr; }
 .media-grid.grid-multi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
 .media-item { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
 .media-item img { width: 100%; max-height: 240px; object-fit: cover;
                   border-radius: 12px; display: block; }
 .grid-multi .media-item img { max-height: 180px; }
 .media-placeholder { background: rgba(0,0,0,.04); border-radius: 12px;
                      padding: 10px 12px; font-size: 14px; color: var(--text); }
 .media-placeholder.video { font-size: 22px; text-align: center; padding: 16px; }
 .media-actions { display: flex; align-items: center; gap: 8px;
                  flex-wrap: wrap; font-size: 12px; }
 .btn-link { display: inline-block; padding: 4px 10px; border-radius: 8px;
             background: rgba(0,0,0,.06); color: var(--text);
             font-size: 12px; font-weight: 500; text-decoration: none; }
 .btn-link:active { background: rgba(0,0,0,.12); }
 .media-bulk { margin-top: 8px; }
 .media-bulk .btn-link { background: var(--accent); color: #fff; }
 .media-bulk .btn-link:active { background: var(--accent2); }

 /* Send form (Telegram-like: slim sticky bar, circular send) */
 .send { position: sticky; bottom: 0; background: var(--surface);
         border-top: 1px solid var(--border);
         padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
         margin: 8px -12px -16px; z-index: 4; }
 .send-grid { display:flex; gap: 6px; align-items:flex-end;
              max-width: 900px; margin: 0 auto; }
 .send textarea { flex:1; min-height: 38px; max-height: 140px; resize: none;
                  padding: 8px 14px; border:1px solid var(--border);
                  border-radius: 19px; font: inherit; font-size: 16px;
                  background:#fff; line-height:1.32;
                  outline: none; transition: border-color .14s ease; }
 .send textarea:focus { border-color: var(--accent); }
 .send-btn { background: var(--accent); color:#fff; border:none;
             border-radius: 50%; width: 38px; height: 38px;
             padding: 0; display: inline-flex; align-items: center;
             justify-content: center; cursor: pointer; flex-shrink: 0;
             font-size: 18px; line-height: 1;
             transition: background-color .14s ease, opacity .14s ease, transform .14s ease; }
 .send-btn:active { background: var(--accent2); transform: scale(.94); }
 .send-btn[disabled] { opacity: .45; cursor: not-allowed; }
 .send-btn svg { width: 18px; height: 18px; display: block; }

 /* Forms (groups add) */
 .form-block { background: var(--surface); border:1px solid var(--border);
               border-radius:14px; padding: 14px; }
 .form-block label { display:block; font-size:13px; color:var(--muted); margin: 12px 0 4px; }
 .form-block label:first-child { margin-top: 0; }
 .form-block input { width:100%; padding:10px 12px; border:1px solid var(--border);
                     border-radius:10px; font: inherit; font-size:16px; background:#fff; }
 .form-block button { margin-top:14px; background: var(--accent); color:#fff;
                      border:none; border-radius:10px; padding:10px 18px;
                      font-size:15px; font-weight:600; cursor:pointer; }

 /* Inbox stats chips */
 .chips { display:flex; gap:6px; margin: 0 0 10px; flex-wrap:wrap; }
 .inbox-head { display:flex; align-items:center; justify-content:space-between;
               gap: 10px; margin: 0 0 6px; }
 .inbox-head h2 { margin: 0; }
 .mini-refresh-btn { border: 1px solid var(--line); background: var(--surface);
                     border-radius: 999px; padding: 6px 12px;
                     font-size: 13px; font-weight: 700; color: var(--text);
                     cursor: pointer; line-height: 1; }
 .mini-refresh-btn:active { background: rgba(15,23,42,.06); }
 .mini-refresh-btn.is-spinning { opacity: .6; }
 .chip { background: var(--surface); border:1px solid var(--border);
         border-radius: 12px; padding: 6px 10px; min-width: 60px;
         display:flex; flex-direction:column; line-height:1.05; }
 .chip-num { font-size: 17px; font-weight:600; }
 .chip-lbl { font-size: 11px; color: var(--muted); margin-top:2px; }

 /* Push card (compact toolbar v2.3) */
 .push-card { background: var(--surface); border: 1px solid var(--border);
              border-radius: 14px; padding: 8px 12px; margin: 0 0 12px;
              box-shadow: 0 1px 2px rgba(15,23,42,.04);
              display: flex; align-items: center; justify-content: space-between;
              gap: 10px; flex-wrap: wrap; }
 .push-card-main { display: flex; align-items: center; gap: 8px;
                   min-width: 0; flex: 1 1 auto; }
 .push-icon { font-size: 18px; line-height: 1; color: var(--accent);
              flex-shrink: 0; }
 .push-title { font-weight: 600; font-size: 14px; line-height: 1.2;
               white-space: nowrap; flex-shrink: 0; }
 .push-status { font-size: 12px; line-height: 1.2; min-width: 0;
                overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
 .push-actions { display: flex; gap: 6px; flex-shrink: 0; }
 .push-actions .btn-link { padding: 5px 10px; font-size: 12px;
                           min-height: 28px; display: inline-flex;
                           align-items: center; line-height: 1; }

 /* Login page */
 .login-block { max-width: 380px; margin: 24px auto; padding: 22px 22px 26px;
                background: var(--surface); border: 1px solid var(--border);
                border-radius: 18px; box-shadow: 0 8px 24px rgba(15,23,42,.06); }
 .login-brand { font-size: 22px; font-weight: 700; letter-spacing: -.01em; }
 .login-tag { margin: 4px 0 16px; }
 .login-form label { display: block; font-size: 13px; color: var(--muted);
                     margin: 14px 0 4px; }
 .login-form input[type=text],
 .login-form input[type=password] {
   width: 100%; padding: 12px 14px; border: 1px solid var(--border);
   border-radius: 12px; font: inherit; font-size: 16px; background: #fff;
 }
 .login-form .checkbox-row { display: flex; align-items: center; gap: 10px;
                             margin-top: 16px; font-size: 14px; color: var(--text); }
 .login-form .checkbox-row input { width: 18px; height: 18px; }
 .login-form button { margin-top: 18px; width: 100%; min-height: 46px;
                      background: var(--accent); color: #fff; border: none;
                      border-radius: 12px; font-size: 16px; font-weight: 600;
                      cursor: pointer; }
 .login-form button:active { background: var(--accent2); }
 .login-err { margin-bottom: 0; }

 /* Topbar Выйти aligned right */
 .topbar .topbar-right { margin-left: auto; }

 /* Segmented period control */
 .seg { display:flex; gap:4px; margin: 0 0 14px; padding: 4px;
        background: var(--surface); border:1px solid var(--border);
        border-radius: 14px; max-width: 100%; overflow:hidden; }
 .seg-item { flex:1; min-width: 0; padding: 8px 10px;
             text-align: center; border-radius: 10px; color: var(--text);
             font-size: 13px; font-weight: 500; line-height: 1.1;
             display:flex; flex-direction:column; gap: 2px;
             transition: background .14s ease, color .14s ease, transform .14s ease; }
 .seg-item:active { transform: scale(.985); }
 .seg-item.on { background: var(--accent); color: #fff; }
 .seg-item .seg-count { font-size: 11px; opacity: .75; }
 .seg-item.on .seg-count { opacity: .85; }

 /* Members count under group name */
 .card .members { font-size: 12px; color: var(--muted); margin-top: 1px; }
 .dialog-header .members { font-size: 11px; color: var(--muted); margin-top: 1px; }

 /* Doc / file cards inside bubble */
 .doc-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
 .doc-card { display: flex; align-items: center; gap: 10px;
             background: rgba(255,255,255,.7); border:1px solid var(--border);
             border-radius: 12px; padding: 8px 10px; min-width: 0; }
 .bubble.in  .doc-card { background: #ffffffcc; }
 .bubble.out .doc-card { background: #ffffffd0; }
 .doc-icon { width: 44px; height: 44px; border-radius: 10px;
             background: rgba(0,0,0,.04);
             display:flex; flex-direction:column; align-items:center;
             justify-content:center; flex-shrink: 0; line-height: 1; }
 .doc-emoji { font-size: 22px; line-height: 1; }
 .doc-ext { font-size: 9px; color: var(--muted); letter-spacing: .04em;
            text-transform: uppercase; margin-top: 1px; }
 .doc-thumb { width: 48px; height: 48px; border-radius: 10px;
              object-fit: cover; flex-shrink: 0; }
 .doc-info { flex: 1; min-width: 0; }
 .doc-title { font-size: 14px; font-weight: 500; line-height: 1.25;
              overflow: hidden; text-overflow: ellipsis;
              display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
 .doc-meta { font-size: 11px; color: var(--muted); margin-top: 2px; }
 .doc-actions { display: flex; flex-direction: column; gap: 4px; flex-shrink: 0; }
 .doc-actions .btn-link { font-size: 12px; padding: 4px 8px; text-align: center; min-width: 70px; }
 .btn-link.primary { background: var(--accent); color: #fff; }
 .btn-link.primary:active { background: var(--accent2); }

 /* Attach button + file preview (in dialog send form) */
 .attach-btn { display:inline-flex; align-items:center; justify-content:center;
               width: 38px; height: 38px; border-radius: 50%;
               background: rgba(0,0,0,.06); font-size: 17px; cursor: pointer;
               user-select: none; flex-shrink: 0; }
 .attach-btn:active { background: rgba(0,0,0,.12); }
 .file-preview { display:flex; flex-wrap:wrap; gap:6px;
                 padding: 0 4px 6px; max-width: 900px; margin: 0 auto; }
 .file-preview .file-item { display:flex; flex-direction:column; align-items:center;
                            gap:4px; background: rgba(0,0,0,.04); border-radius:10px;
                            padding: 6px; max-width: 110px; }
 .file-preview .file-item img { width: 90px; height: 90px; object-fit: cover;
                                 border-radius: 8px; display:block; }
 .file-preview .file-name { font-size: 11px; color: var(--muted);
                            max-width: 95px; overflow:hidden;
                            text-overflow:ellipsis; white-space:nowrap; }
 .file-preview .file-remove { font-size: 11px; color: var(--accent);
                              cursor:pointer; user-select:none; }

 /* Desktop tweaks */
 @media (min-width: 720px) {
   main { padding: 16px; }
   .bubble { max-width: min(68vw, 600px); }
   .send { position: static; padding: 12px; border-radius: 14px;
           border: 1px solid var(--border); margin: 12px 0 0; }
   .dialog-header { position: static; }
 }

 /* Mobile tweaks: full-bleed dialog header so it lines up with the
    edge-to-edge topbar (no side gaps from <main>'s 12px padding).
    Page scroll is the standard browser behavior; .send stays sticky-bottom
    (defined globally above). interactive-widget=resizes-content in the
    viewport meta keeps the composer above the keyboard without us forcing
    a fixed-viewport flex layout — that earlier attempt destabilized the
    message flow on iOS Safari, so it has been removed. */
 @media (max-width: 719px) {
   .dialog-header {
     margin: -12px -12px 8px;
     border-radius: 0;
     border: none;
     border-bottom: 1px solid var(--border);
     box-shadow: 0 1px 0 rgba(0,0,0,.04);
   }
 }

 /* === Mobile redesign v2 — fullscreen chat / iMessage-like polish === */
 @media (max-width: 760px) {
   body { background: var(--app-bg); overflow-x: hidden; }
   .topbar {
     /* perf v1.1: drop heavy backdrop blur on mobile sticky topbar — solid bg
        renders cheaper and avoids flicker on iOS back-navigation. */
     background: rgb(17,24,39);
     -webkit-backdrop-filter: none;
     backdrop-filter: none;
     z-index: 30;
   }
   .topbar-row { min-height: 44px; padding: 6px 12px; gap: 14px;
                 overflow-x: auto; scrollbar-width: none; }
   .topbar-row::-webkit-scrollbar { display: none; }
   .topbar .brand { font-size: 15px; }
   .topbar a { font-size: 15px; padding: 6px 2px; opacity: .92; white-space: nowrap; }

   /* Fullscreen-chat: dialog page eats main padding */
   main:has(.dialog-header) { padding: 0; padding-bottom: 0; max-width: 100%; }

   .dialog-header {
     margin: 0;
     border-radius: 0;
     border: none;
     border-bottom: 1px solid var(--line);
     padding: 8px 12px;
     min-height: 54px;
     /* perf v1.1: solid bg + lighter shadow, no blur on mobile sticky header. */
     background: #ffffff;
     -webkit-backdrop-filter: none;
     backdrop-filter: none;
     box-shadow: 0 1px 0 rgba(15,23,42,.06);
     top: calc(env(safe-area-inset-top) + var(--topbar-h, 44px));
     z-index: 20;
   }
   .dialog-header .group { font-size: 15px; }
   .dialog-header .peer  { font-size: 12px; }

   .messages {
     padding: 12px 10px calc(var(--composer-h, 64px) + 18px + env(safe-area-inset-bottom));
     /* perf v1.1: flat background — radial-gradient repaints on every scroll
        and visualViewport resize on iOS. */
     background: var(--app-bg);
     gap: 2px;
   }

   .bubble { max-width: 86vw; padding: 9px 13px 7px; font-size: 15px; line-height: 1.34; }
   .bubble.in {
     background: var(--surface);
     border: 1px solid var(--line);
     box-shadow: 0 2px 10px rgba(15,23,42,.05);
     border-radius: 20px 20px 20px 8px;
   }
   .bubble.out {
     background: linear-gradient(180deg, #dbeafe 0%, #cfe2ff 100%);
     border: 1px solid rgba(37,99,235,.10);
     box-shadow: 0 2px 10px rgba(37,99,235,.10);
     color: var(--text);
     border-radius: 20px 20px 8px 20px;
   }
   .bubble .meta { opacity: .55; font-size: 11px; }

   /* Composer (mobile). perf v1.1: solid bg + light shadow, no blur — keeps
      keyboard-fixed positioning intact (position:fixed + bottom:var(--kb-inset)
      + transition:none). */
   .send {
     position: fixed;
     left: 0;
     right: 0;
     bottom: var(--kb-inset, 0px);
     z-index: 80;
     margin: 0;
     padding: 6px 10px calc(2px + var(--safe-bottom-active, env(safe-area-inset-bottom)));
     background: #ffffff;
     -webkit-backdrop-filter: none;
     backdrop-filter: none;
     border-top: 1px solid var(--line);
     box-shadow: 0 -2px 6px rgba(15,23,42,.06);
     transform: translateZ(0);
     transition: none !important;
     will-change: bottom;
   }
   .send-grid { gap: 8px; align-items: end; }
   .send textarea {
     min-height: 42px; max-height: 118px;
     border-radius: 22px;
     border: 1px solid rgba(15,23,42,.12);
     background: #ffffff;
     padding: 10px 14px;
     font-size: 16px; line-height: 1.28;
     box-shadow: inset 0 1px 2px rgba(15,23,42,.04);
   }
   .send textarea:focus {
     border-color: var(--accent);
     box-shadow: 0 0 0 4px rgba(37,99,235,.12);
   }
   .send-btn {
     width: 44px; height: 44px;
     box-shadow: 0 8px 18px rgba(37,99,235,.30);
   }
   .send-btn:active { box-shadow: 0 2px 6px rgba(37,99,235,.30); }
   .attach-btn {
     width: 42px; height: 42px;
     background: rgba(15,23,42,.05);
     font-size: 18px;
   }

   /* Tech details: keep available, but visually quieter on mobile */
   details.tech { margin: 8px 12px; }

   /* Inbox list cards: keep tight on mobile */
   .cards { padding: 8px; }
   .card { border-radius: 16px; box-shadow: 0 1px 2px rgba(15,23,42,.04); }
 }

 /* === Premium upgrade v2.2 — bubble polish, quick replies, status badges, mobile tabbar === */
 .status-row { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
 .status-badge {
   display: inline-flex; align-items: center; gap: 4px;
   border-radius: 999px; padding: 4px 8px;
   font-size: 12px; font-weight: 700; line-height: 1;
   border: 1px solid var(--line);
 }
 .status-badge.new  { background: #dbeafe; color: #1d4ed8; border-color: rgba(37,99,235,.18); }
 .status-badge.pay  { background: #dcfce7; color: #15803d; border-color: rgba(22,163,74,.18); }
 .status-badge.warn { background: #fef3c7; color: #b45309; border-color: rgba(245,158,11,.18); }
 .status-badge.err  { background: #fee2e2; color: #b91c1c; border-color: rgba(239,68,68,.18); }
 .status-badge.done { background: #f1f5f9; color: #475569; border-color: var(--line); }

 .quick-replies { display: none; }
 .mobile-tabbar { display: none; }

 @media (max-width: 760px) {
   body {
     background:
       radial-gradient(1200px 380px at 18% -8%, rgba(37,99,235,.10), transparent 38%),
       radial-gradient(900px 280px at 86% 14%, rgba(79,70,229,.06), transparent 36%),
       linear-gradient(180deg, #f8fbff 0%, var(--app-bg) 42%, #f6f7fb 100%);
   }

   .topbar {
     background: linear-gradient(180deg, rgba(15,23,42,.96), rgba(15,23,42,.90));
     border-bottom: 1px solid rgba(255,255,255,.08);
   }
   .topbar a { border-radius: 999px; padding: 7px 10px; color: rgba(255,255,255,.82); }
   .topbar a:hover, .topbar a:focus { background: rgba(255,255,255,.10); color: #fff; }
   .topbar .brand { font-weight: 800; letter-spacing: -.02em; }

   .dialog-header {
     z-index: 40;
     min-height: 56px;
     padding: 9px 12px;
     background: rgba(255,255,255,.90);
     box-shadow: 0 8px 22px rgba(15,23,42,.045);
   }

   .messages {
     padding: 14px 10px calc(var(--composer-h, 64px) + 22px + env(safe-area-inset-bottom));
   }

   .bubble { padding: 10px 13px; line-height: 1.35; box-shadow: 0 2px 12px rgba(15,23,42,.045); }
   .bubble.out {
     background: linear-gradient(180deg, #dbeafe 0%, #cfe2ff 100%);
     border: 1px solid rgba(37,99,235,.12);
     box-shadow: 0 4px 14px rgba(37,99,235,.10);
   }
   .bubble.in {
     background: rgba(255,255,255,.96);
     border: 1px solid var(--line);
   }
   .bubble .meta { color: var(--muted-2); font-size: 12px; opacity: .85; }

   /* Quick replies row above composer */
   .quick-replies {
     display: flex; gap: 7px;
     overflow-x: auto;
     padding: 0 4px 7px;
     scrollbar-width: none;
     max-width: 900px; margin: 0 auto;
   }
   .quick-replies::-webkit-scrollbar { display: none; }
   .qr-btn {
     flex: 0 0 auto;
     border: 1px solid rgba(37,99,235,.14);
     background: rgba(37,99,235,.07);
     color: #1d4ed8;
     border-radius: 999px;
     padding: 7px 11px;
     font-size: 13px; font-weight: 600;
     white-space: nowrap;
     cursor: pointer;
     transition: transform .08s ease;
   }
   .qr-btn:active { transform: scale(.97); }

   /* Composer polish (does NOT change v3 keyboard fix) */
   .send-btn {
     background: linear-gradient(180deg, var(--accent), var(--accent-2, #4f46e5));
     box-shadow: 0 10px 22px rgba(37,99,235,.30);
   }
   .send-btn:active { box-shadow: 0 4px 10px rgba(37,99,235,.30); }
   .send textarea {
     box-shadow: inset 0 1px 2px rgba(15,23,42,.035), 0 1px 0 rgba(255,255,255,.70);
   }

   /* Inbox cards: more premium on mobile */
   .cards { gap: 8px; padding: 10px; }
   .card {
     border-radius: 18px;
     border: 1px solid var(--line);
     box-shadow: 0 4px 14px rgba(15,23,42,.05);
     background: var(--surface);
   }

   /* Mobile bottom tabbar */
   .mobile-tabbar {
     display: grid;
     position: fixed;
     left: 10px; right: 10px;
     bottom: calc(8px + env(safe-area-inset-bottom));
     z-index: 70;
     grid-template-columns: repeat(4, 1fr);
     gap: 4px;
     padding: 7px;
     border-radius: 24px;
     /* perf v1.1: solid bg, lighter shadow, no blur. */
     background: #ffffff;
     -webkit-backdrop-filter: none;
     backdrop-filter: none;
     border: 1px solid var(--line);
     box-shadow: 0 4px 14px rgba(15,23,42,.10);
   }
   .mobile-tabbar a {
     text-align: center;
     border-radius: 18px;
     padding: 8px 4px;
     font-size: 12px; font-weight: 700;
     color: var(--muted);
     text-decoration: none;
     line-height: 1.1;
   }
   .mobile-tabbar a.active {
     background: var(--accent-soft, #dbeafe);
     color: #1d4ed8;
   }

   /* Hide tabbar on dialog (composer occupies bottom) */
   body:has(.dialog-header) .mobile-tabbar { display: none; }

   /* On non-dialog pages reserve space for tabbar */
   main:not(:has(.dialog-header)) {
     padding-bottom: calc(86px + env(safe-area-inset-bottom));
   }
 }

 /* === Snippets v2.3 — small button + suggestion + bottom sheet === */
 .snippet-btn {
   width: 38px; height: 38px; flex-shrink: 0;
   display: inline-flex; align-items: center; justify-content: center;
   border: none; border-radius: 50%;
   background: rgba(15,23,42,.06);
   font-size: 17px; cursor: pointer; user-select: none; color: var(--text);
   transition: background-color .14s ease, transform .12s ease;
 }
 .snippet-btn:active { background: rgba(15,23,42,.12); transform: scale(.96); }

 .snippet-suggestion {
   position: fixed;
   left: 12px; right: 12px;
   bottom: calc(var(--composer-h, 64px) + var(--kb-inset, 0px) + 12px);
   z-index: 90;
   max-width: 720px; margin: 0 auto;
   background: rgba(255,255,255,.96);
   -webkit-backdrop-filter: saturate(160%) blur(16px);
   backdrop-filter: saturate(160%) blur(16px);
   border: 1px solid var(--line);
   border-radius: 14px;
   box-shadow: 0 14px 36px rgba(15,23,42,.18);
   padding: 6px;
   display: none;
 }
 .snippet-suggestion.active { display: flex; flex-direction: column; gap: 2px; }
 .snippet-suggestion .row {
   display: flex; align-items: center; gap: 10px;
   padding: 8px 10px; border-radius: 10px; cursor: pointer;
 }
 .snippet-suggestion .row.focused,
 .snippet-suggestion .row:hover { background: var(--accent-soft, #dbeafe); color: #1d4ed8; }
 .snippet-suggestion .trg {
   font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
   font-size: 12px; font-weight: 700; color: var(--accent);
   background: rgba(37,99,235,.08);
   padding: 2px 6px; border-radius: 6px;
 }
 .snippet-suggestion .ttl { font-weight: 700; font-size: 14px; flex-shrink: 0; }
 .snippet-suggestion .prev {
   font-size: 12px; color: var(--muted);
   overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
   flex: 1 1 auto; min-width: 0;
 }

 .snippet-backdrop[hidden],
 .snippet-sheet[hidden] { display: none !important; }
 .snippet-backdrop {
   position: fixed; inset: 0; z-index: 120;
   background: rgba(15,23,42,.30);
   -webkit-backdrop-filter: blur(2px);
   backdrop-filter: blur(2px);
 }

 .snippet-sheet {
   position: fixed;
   left: 10px; right: 10px;
   bottom: calc(var(--composer-h, 64px) + var(--kb-inset, 0px) + 10px);
   z-index: 121;
   max-height: min(70vh, 560px);
   overflow: auto;
   -webkit-overflow-scrolling: touch;
   background: rgba(255,255,255,.98);
   border: 1px solid var(--line);
   border-radius: 22px;
   box-shadow: 0 24px 70px rgba(15,23,42,.24);
   padding: 14px;
   display: flex; flex-direction: column; gap: 10px;
 }
 .snippet-sheet.open { animation: snippetSheetIn .14s ease; }
 @keyframes snippetSheetIn {
   from { opacity: 0; transform: translateY(8px); }
   to   { opacity: 1; transform: translateY(0);  }
 }
 @media (min-width: 761px) {
   .snippet-sheet { left: auto; right: 24px; bottom: 96px; width: 420px; }
 }
 .snippet-sheet .grip {
   width: 38px; height: 4px; border-radius: 999px;
   background: rgba(15,23,42,.18);
   margin: 0 auto 4px;
 }
 .snippet-sheet h3 {
   margin: 0; font-size: 16px; font-weight: 700;
   display: flex; justify-content: space-between; align-items: center;
 }
 .snippet-sheet .close-btn {
   border: none; background: rgba(15,23,42,.05);
   width: 32px; height: 32px; border-radius: 50%;
   font-size: 14px; cursor: pointer; line-height: 1;
 }
 .snippet-sheet .close-btn:active { background: rgba(15,23,42,.10); }
 .snippet-sheet .list {
   flex: 1 1 auto; min-height: 0;
   overflow-y: auto; -webkit-overflow-scrolling: touch;
   display: flex; flex-direction: column; gap: 6px;
   padding-right: 2px;
 }
 .snippet-sheet .item {
   border: 1px solid var(--line);
   border-radius: 12px;
   padding: 10px 12px;
   background: var(--surface);
   display: flex; gap: 10px; align-items: flex-start;
 }
 .snippet-sheet .item-info { flex: 1 1 auto; min-width: 0; }
 .snippet-sheet .item-head {
   display: flex; align-items: center; gap: 8px; margin-bottom: 2px; flex-wrap: wrap;
 }
 .snippet-sheet .item-title { font-weight: 700; font-size: 14px; }
 .snippet-sheet .item-trigger {
   font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
   font-size: 11px; font-weight: 700; color: var(--accent);
   background: rgba(37,99,235,.08);
   padding: 2px 6px; border-radius: 6px;
 }
 .snippet-sheet .item-body {
   font-size: 13px; color: var(--muted); line-height: 1.32;
   max-height: 4.2em; overflow: hidden; text-overflow: ellipsis;
 }
 .snippet-sheet .item-actions {
   display: flex; flex-direction: column; gap: 4px; flex-shrink: 0;
 }
 .snippet-sheet .item-actions button {
   border: none; background: var(--accent); color: #fff;
   border-radius: 8px; padding: 6px 12px; font-size: 12px; font-weight: 600;
   cursor: pointer;
 }
 .snippet-sheet .item-actions button.del {
   background: rgba(15,23,42,.06); color: var(--muted);
 }
 .snippet-sheet .form {
   display: flex; flex-direction: column; gap: 6px;
   border-top: 1px solid var(--line);
   padding-top: 10px;
 }
 .snippet-sheet .form input,
 .snippet-sheet .form textarea {
   border: 1px solid var(--line);
   border-radius: 10px;
   padding: 8px 10px;
   font: inherit; font-size: 14px;
   background: var(--surface);
   resize: none;
   width: 100%;
   box-sizing: border-box;
 }
 .snippet-sheet .form textarea { min-height: 60px; max-height: 120px; }
 .snippet-sheet .form label {
   font-size: 12px; color: var(--muted); margin-top: 4px;
 }
 .snippet-sheet .form .save {
   border: none; background: var(--accent); color: #fff;
   border-radius: 10px; padding: 9px 14px;
   font-size: 14px; font-weight: 700; cursor: pointer;
 }

 @media (max-width: 760px) {
   .snippet-btn { width: 44px; height: 44px; background: rgba(15,23,42,.07); font-size: 18px; }
 }

/* === Mobile visual polish v2 — iOS PWA: brand-only topbar, single dialog
       header, lighter inbox top stack, less white flash on launch. === */
html { background: var(--app-bg); }

@media (max-width: 760px) {
  /* Topbar: keep only the brand. The four nav links overflow on iPhone and
     duplicate the bottom .mobile-tabbar; hiding them removes the right-edge
     overflow scroll and the desktop-admin look. */
  .topbar-row { gap: 0; padding: 6px 14px; overflow: visible; min-height: 44px; }
  .topbar-row a:not(.brand) { display: none; }

  /* Dialog page: drop the dark topbar entirely — .dialog-header becomes
     the only top bar. Background extends to status-bar via padding-top
     because of apple-mobile-web-app-status-bar-style="black-translucent". */
  body:has(.dialog-header) .topbar { display: none; }
  body:has(.dialog-header) .dialog-header {
    top: 0;
    padding-top: calc(8px + env(safe-area-inset-top));
    min-height: calc(54px + env(safe-area-inset-top));
  }

  /* /inbox header zone: compact. h2 + refresh button + chips were producing
     a 3-row stack; tighten margins and font without removing anything. */
  main h2 { font-size: 17px; margin: 4px 4px 6px; }
  .inbox-head { margin: 0 0 6px; }
  .chips { gap: 4px; margin: 0 0 8px; }
  .chip { padding: 5px 8px; min-width: 56px; }
  .chip-num { font-size: 16px; }
  .chip-lbl { font-size: 10px; }
}

/* === Mobile dialog fixed layout v1 — open at bottom + stable composer ===
   Goal: on mobile /dialog the page itself doesn't scroll; .messages is
   the only scroll container, sized between .dialog-header and .send via
   --dialog-header-h, --composer-h and --kb-inset (set by JS). This makes
   the chat open already pinned to the latest messages and keeps the
   composer locked at the bottom while history scrolls. */
@media (max-width: 760px) {
  body:has(.dialog-header) {
    overflow: hidden;
    overscroll-behavior: contain;
  }
  body:has(.dialog-header) main {
    height: 100vh;
    height: 100dvh;
    max-width: 100%;
    padding: 0;
    overflow: hidden;
    position: relative;
  }

  body:has(.dialog-header) .dialog-header {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    z-index: 70;
    margin: 0;
    border-radius: 0;
  }

  body:has(.dialog-header) details.tech { display: none; }

  body:has(.dialog-header) .messages {
    position: fixed;
    left: 0;
    right: 0;
    top: var(--dialog-header-h, calc(62px + env(safe-area-inset-top)));
    /* composer-bottom-positive == kb-px when keyboard is up, 0 otherwise.
       Using a positive-only twin keeps this calc from going negative when
       .send sinks below the viewport edge (--composer-bottom = -12px). */
    bottom: calc(var(--composer-h, 64px) + var(--composer-bottom-positive, 0px));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding: 12px 10px 18px;
    scroll-behavior: auto;
    background: var(--app-bg);
  }

  /* Composer sinks below the viewport edge when the keyboard is closed.
     bottom: var(--composer-bottom) = -12px in idle state pushes the .send
     box 12px past the visible bottom of the screen, so the textarea row
     visually meets the home indicator instead of floating ~30px above
     it with body-bg showing through. -24px clipped the input/send-btn
     too aggressively; -12px keeps the row fully on-screen while still
     killing the empty zone. Padding-bottom 8 stays as a small cushion.
     :focus-within is a failsafe in case visualViewport detection misses
     the keyboard event in standalone PWA — focusing the textarea always
     lifts .send back to bottom 0 (or to keyboard top via JS-set var). */
  body:has(.dialog-header) .send {
    position: fixed;
    left: 0;
    right: 0;
    bottom: var(--composer-bottom, -12px);
    z-index: 90;
    margin: 0;
    background: transparent;
    border-top: 0;
    box-shadow: none;
    padding: 6px 10px 8px;
    transition: none !important;
  }
  body:has(.dialog-header) .send:focus-within {
    bottom: var(--composer-bottom-positive, 0px);
  }

  /* Floating-pill look for the composer row: white rounded background
     wraps attach/textarea/send buttons so the composer reads as a single
     island floating over the dialog area rather than a full-width slab. */
  body:has(.dialog-header) .send-grid {
    background: rgba(255,255,255,.96);
    border: 1px solid rgba(15,23,42,.08);
    border-radius: 999px;
    padding: 4px;
    box-shadow: 0 8px 24px rgba(15,23,42,.12);
  }
}

/* === Mobile inbox/jobs polish v1 — hide the read-only stats chips on
   /inbox (the four little "сегодня / за час / непрочитано / диалогов"
   badges that don't filter anything; the clickable Сегодня/Вчера/Неделя/Всё
   period switcher below them stays visible because that one IS functional),
   and keep non-dialog pages clipped to the viewport so /posting/jobs can't
   bleed horizontally when its table is wider than the screen. */
@media (max-width: 760px) {
  main:not(:has(.dialog-header)) .chips { display: none; }

  body:not(:has(.dialog-header)) { overflow-x: hidden; }
  main:not(:has(.dialog-header)) { overflow-x: hidden; }

  /* Posting jobs: long URLs and many columns blow up the table; scroll
     the table inside its own wrapper instead of pushing the whole page
     off the right edge. The wrapper is added by the template. */
  .jobs-table-wrap {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: 14px;
  }
  .jobs-table { min-width: 560px; }
  .jobs-table th,
  .jobs-table td { white-space: nowrap; }
  .jobs-table td a { font-weight: 600; }
}

/* === Ultra-slim transparent composer v1 — minimal three-control bar ===
   Replaces the earlier 44/46-px slim block; the bottom strip was still
   reading as a heavy white panel. Now the .send container is transparent
   so it dissolves into the dialog area, and the three controls are even
   tighter. KEEPS the existing keyboard logic intact: .send still uses
   position:fixed + bottom:var(--composer-bottom) + transition:none (set
   in the floating-composer block above), focus-within still lifts the
   composer when the keyboard opens, and applyKeyboardInset in app.js
   still drives --kb-inset / --safe-bottom-active / --composer-bottom*.
   The !important flags are needed only to override the floating-composer
   block's background/border-top/box-shadow above (positioning is left
   alone). */
@media (max-width: 760px) {
  body:has(.dialog-header) .send {
    background: transparent !important;
    border-top: 0 !important;
    box-shadow: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    padding: 5px 10px calc(5px + var(--safe-bottom-active, env(safe-area-inset-bottom))) !important;
  }

  body:has(.dialog-header) .send-grid {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) 42px;
    align-items: center;
    gap: 8px;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
  }

  body:has(.dialog-header) .attach-btn {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: 999px;
    display: grid;
    place-items: center;
    background: rgba(241,245,249,.72);
    color: #64748b;
    border: 1px solid rgba(15,23,42,.04);
    box-shadow: none;
    font-size: 20px;
    line-height: 1;
  }

  body:has(.dialog-header) .send textarea {
    box-sizing: border-box;
    min-height: 40px;
    height: 40px;
    max-height: 96px;
    border-radius: 999px;
    border: 1px solid rgba(15,23,42,.12);
    background: rgba(255,255,255,.82);
    padding: 8px 14px;
    font-size: 16px;
    line-height: 1.35;
    color: #111827;
    box-shadow: none;
    outline: none;
  }
  body:has(.dialog-header) .send textarea::placeholder { color: #9ca3af; }
  body:has(.dialog-header) .send textarea:focus {
    background: rgba(255,255,255,.92);
    border-color: rgba(37,99,235,.28);
    box-shadow: 0 0 0 2px rgba(37,99,235,.06);
  }

  body:has(.dialog-header) .send-btn {
    width: 42px;
    height: 42px;
    min-width: 42px;
    border-radius: 999px;
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, #9fb2f8 0%, #8098f2 100%);
    color: #ffffff;
    border: 0;
    box-shadow: 0 4px 10px rgba(99,102,241,.14);
  }
  body:has(.dialog-header) .send-btn svg { width: 19px; height: 19px; }
}

/* REAL_TRANSPARENT_MOBILE_COMPOSER_V1 ===================================
   The earlier ultra-slim block already declares .send transparent under
   body:has(.dialog-header), but on iOS standalone PWA we kept seeing a
   light-gray panel under the composer. The most likely culprit is the
   mobile redesign v2 rule at the top of the @media block which sets
   .send { background: #ffffff } without :has() — if :has() ever fails
   to match (cache, render-tree quirk, older WebKit branch), that white
   bg wins. This block restates the transparency without :has() too,
   targeting form.send directly (form.send selector is already dialog-
   specific because <form class="send"> only exists in DIALOG_TMPL),
   and also nukes any decorative ::before/::after pseudo-elements that
   might be drawing a panel. Positioning/keyboard logic is intentionally
   NOT touched: bottom/position/transition/focus-within and the
   --kb-inset / --safe-bottom-active / --composer-bottom* variables stay
   exactly as before. */
@media (max-width: 760px) {
  form.send,
  body:has(.dialog-header) .send,
  body:has(.dialog-header) form.send {
    background: transparent !important;
    background-color: transparent !important;
    border-top: 0 !important;
    box-shadow: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }

  form.send::before,
  form.send::after,
  body:has(.dialog-header) .send::before,
  body:has(.dialog-header) .send::after,
  body:has(.dialog-header) form.send::before,
  body:has(.dialog-header) form.send::after {
    content: none !important;
    display: none !important;
    background: transparent !important;
    box-shadow: none !important;
    border: 0 !important;
  }

  body:has(.dialog-header) .send-grid,
  body:has(.dialog-header) form.send .send-grid {
    background: transparent !important;
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
  }
}
