/* ============ Design tokens ============ */
:root{
  --bg:#ffffff; --bg-elev:#ffffff; --fg:#0a0a0a; --muted:#6b7280; --muted-2:#9ca3af;
  --card:#ffffff; --border:#ececef; --border-strong:#d4d4d8;
  --input:#f5f5f7; --input-focus:#eef0f3;
  --accent:#2563eb; --accent-fg:#ffffff; --accent-soft:#eff6ff;
  --success:#10b981; --success-soft:#ecfdf5; --success-border:#a7f3d0;
  --danger:#ef4444; --danger-soft:#fef2f2; --danger-border:#fecaca;
  --warn:#f59e0b; --warn-soft:#fffbeb;
  --radius:12px; --radius-sm:8px; --radius-xs:6px;
  --shadow-xs:0 1px 2px rgba(0,0,0,.04);
  --shadow-sm:0 1px 3px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.04);
  --shadow-md:0 4px 12px rgba(0,0,0,.06),0 2px 4px rgba(0,0,0,.04);
  --shadow-lg:0 10px 32px rgba(0,0,0,.10),0 4px 12px rgba(0,0,0,.06);
  --t-fast:.15s ease; --t-med:.25s ease; --t-slow:.4s cubic-bezier(.5,1.6,.5,1);
  --font:14px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --mono:"SF Mono",ui-monospace,"JetBrains Mono","Cascadia Code",Menlo,Consolas,monospace;
}
html[data-dark-mode="true"]{
  --bg:#0a0a0b; --bg-elev:#131316; --fg:#fafafa; --muted:#9ca3af; --muted-2:#6b7280;
  --card:#161619; --border:#27272a; --border-strong:#3f3f46;
  --input:#1c1c20; --input-focus:#222227;
  --accent:#3b82f6; --accent-fg:#ffffff; --accent-soft:rgba(59,130,246,.15);
  --success:#34d399; --success-soft:rgba(16,185,129,.12); --success-border:rgba(16,185,129,.35);
  --danger:#f87171; --danger-soft:rgba(239,68,68,.12); --danger-border:rgba(239,68,68,.35);
  --warn:#fbbf24; --warn-soft:rgba(245,158,11,.12);
  --shadow-xs:0 1px 2px rgba(0,0,0,.3);
  --shadow-sm:0 1px 3px rgba(0,0,0,.4),0 1px 2px rgba(0,0,0,.3);
  --shadow-md:0 4px 12px rgba(0,0,0,.45),0 2px 4px rgba(0,0,0,.3);
  --shadow-lg:0 10px 32px rgba(0,0,0,.55),0 4px 12px rgba(0,0,0,.4);
}
*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;font:var(--font);background:var(--bg);color:var(--fg);
  min-height:100vh;display:flex;flex-direction:column;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}
input,button,textarea,select{font:inherit;color:inherit}

/* ============ Header ============ */
header{position:sticky;top:0;z-index:20;
  background:color-mix(in srgb,var(--bg) 88%,transparent);
  backdrop-filter:saturate(180%) blur(12px);-webkit-backdrop-filter:saturate(180%) blur(12px);
  border-bottom:1px solid var(--border)
}
.header-in{max-width:1280px;margin:0 auto;padding:0 24px;height:50px;
  display:flex;align-items:center;gap:16px}
.tabs{display:flex;align-items:center;gap:0;height:100%}
.tabs a{padding:0 18px;height:100%;display:flex;align-items:center;
  cursor:pointer;font-weight:500;font-size:14px;color:var(--muted);
  border-bottom:2px solid transparent;transition:var(--t-fast);user-select:none;
  margin-bottom:-1px; text-decoration:none;}
.tabs a:hover{color:var(--fg)}
.tabs a.active{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}


/* === Правая часть header: theme-toggle + user-menu === */
.header-right{
  position:absolute;
  right:0;
  top:0;
  height:50px;             /* совпадает с .header-in height */
  padding-right:16px;      /* минимальный визуальный отступ от края страницы; поставь 0 если надо совсем впритык */
  display:flex;
  align-items:center;      /* вертикальное центрирование */
  justify-content:flex-end;
  gap:8px;
  z-index:21               /* выше .header-in чтобы клики ловил */
}

/* Theme toggle: убираем baseline-выравнивание кнопки, центрируем по flex */
.header-right .toggle{
  display:flex;
  align-items:center;
  margin:0;
}

/* ============ Main ============ */
main{flex:1;max-width:1280px;margin:0 auto;width:100%;padding:24px 24px 80px}

/* ============ Global Shared Components ============ */
.token-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px;padding:4px 0}
.token-row.active{color:var(--success)}
.token-row .dot{width:8px;height:8px;border-radius:50%;background:currentColor;flex-shrink:0}
.token-row .lbl{font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;font-size:11px}
.token-row.active .lbl{color:var(--success)}
.token-row input[type=password]{flex:1;min-width:200px;padding:8px 12px;
  border:1px solid var(--border);border-radius:var(--radius-xs);
  background:var(--input);color:var(--fg);font-family:var(--mono);font-size:13px;
  transition:var(--t-fast)}
.token-row input[type=password]:focus{outline:none;border-color:var(--accent);
  background:var(--input-focus);box-shadow:0 0 0 3px var(--accent-soft)}
.token-actions{display:flex;gap:4px;margin-left:auto}

.btn{padding:8px 14px;border:1px solid var(--border);border-radius:var(--radius-xs);
  background:var(--card);color:var(--fg);cursor:pointer;
  font-size:13px;font-weight:500;font-family:inherit;
  transition:var(--t-fast);display:inline-flex;align-items:center;justify-content:center;gap:6px}
.btn:hover{background:var(--input);border-color:var(--border-strong)}
.btn:active{transform:translateY(0.5px)}
.btn.primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
.btn.primary:hover{filter:brightness(1.08)}
.btn.primary:disabled{opacity:.45;cursor:not-allowed;transform:none}
.btn.ghost{background:transparent;border:none}
.btn.ghost:hover{background:var(--input)}
.btn.ghost.danger:hover{color:var(--danger);background:var(--danger-soft)}
.btn.sm{padding:6px 11px;font-size:12px}

.section-label{font-size:11px;color:var(--muted);font-weight:700;
  text-transform:uppercase;letter-spacing:.08em;margin:0 0 12px}
.zone-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;gap:8px}
.zone-head h3{margin:0;font-size:14px;font-weight:700;letter-spacing:-.01em}
.counter{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;
  padding:2px 8px;background:var(--input);border-radius:999px}
.counter.warn{color:var(--warn);background:var(--warn-soft)}
.counter.err{color:var(--danger);background:var(--danger-soft)}
.hint{font-size:12px;color:var(--muted);margin-top:8px}

.zone{display:flex;flex-direction:column;min-width:0}
textarea{width:100%;padding:12px;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:var(--input);color:var(--fg);
  resize:vertical;font:inherit;transition:var(--t-fast);line-height:1.6}
textarea:focus,select:focus,input[type=text]:focus,.token-row input:focus{
  outline:none;border-color:var(--accent);background:var(--input-focus);
  box-shadow:0 0 0 3px var(--accent-soft)}

.fields{display:grid;grid-gap:14px;gap:14px}
.field{display:grid;grid-gap:5px;gap:5px}
.field label{font-size:12px;color:var(--muted);font-weight:600}
select,input[type=text]{width:100%;padding:8px 12px;border:1px solid var(--border);
  border-radius:var(--radius-xs);background:var(--input);color:var(--fg);font:inherit;
  transition:var(--t-fast);cursor:pointer}
select{appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;padding-right:32px}
.row{display:flex;align-items:center;gap:8px}
.ext{font-family:var(--mono);color:var(--muted);font-size:13px;white-space:nowrap;
  padding:8px 12px;background:var(--input);border:1px solid var(--border);
  border-radius:var(--radius-xs)}
.mono{font-family:var(--mono)}
.sep{height:1px;background:var(--border);margin:6px 0}
input[type=range]{width:100%;accent-color:var(--accent);cursor:pointer}
.range-row{display:flex;align-items:center;gap:12px}
.range-val{font-variant-numeric:tabular-nums;font-size:12px;color:var(--fg);
  min-width:44px;text-align:right;padding:3px 8px;background:var(--input);
  border-radius:var(--radius-xs);font-weight:600}

/* ============ Queue FAB (Общий каркас) ============ */
/* Animation order:
   - OPEN:  width grows first (0→250ms), then body slides down (250→500ms).
   - CLOSE: body collapses first (0→250ms), then width shrinks (250→500ms).
   Achieved by:
   - .queue-fab (closed)  → width transition delayed by t-med
   - .queue-fab[open]     → width transition NO delay
   - .q-fab-body (closed) → max-height transition NO delay
   - .q-fab-body[open]    → max-height transition delayed by t-med
*/
.queue-fab{
  position:fixed;bottom:20px;right:20px;z-index:50;width:300px;
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);overflow:hidden;
  /* CLOSED: ждём пока body схлопнется, потом сжимаем ширину */
  transition:width var(--t-med) ease var(--t-med);
}
.queue-fab[open]{
  width:min(640px,calc(100vw - 40px));
  /* OPEN: ширину растим сразу, без задержки */
  transition:width var(--t-med) ease 0s;
}
.queue-fab summary{list-style:none;cursor:pointer;padding:11px 14px;
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  font-size:13px;font-weight:600;background:var(--card);transition:var(--t-fast)}
.queue-fab summary::-webkit-details-marker{display:none}
.queue-fab summary:hover{background:var(--input)}
.q-left{display:flex;align-items:center;gap:8px;min-width:0}
.q-left .q-ic{font-size:14px;flex-shrink:0}
.q-left .q-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.q-left .chip{display:inline-flex;align-items:center;gap:5px;
  padding:2px 8px;background:var(--accent-soft);color:var(--accent);
  border-radius:999px;font-size:11px;font-weight:700;flex-shrink:0}
.q-left .chip.proc{background:var(--success-soft);color:var(--success)}
.q-chev{transition:transform var(--t-med);color:var(--muted);flex-shrink:0}
.queue-fab[open] summary .q-chev{transform:rotate(180deg)}

.q-fab-body{
  /* CLOSED: мгновенно (без задержки) схлопываем body, чтобы width начал уменьшаться после */
  max-height:0;opacity:0;overflow:hidden;border-top:0 solid transparent;
  transition:max-height var(--t-med) ease 0s,
             opacity var(--t-fast) ease 0s,
             border-top-width 0s ease 0s;
  scrollbar-width:thin;scrollbar-color:var(--border) transparent;
}
.queue-fab[open] .q-fab-body{
  /* OPEN: ждём пока width растянется (var(--t-med)), потом растим body */
  max-height:min(50vh,440px);opacity:1;overflow:auto;
  border-top-width:1px;border-top-color:var(--border);
  transition:max-height var(--t-med) ease var(--t-med),
             opacity var(--t-fast) ease var(--t-med),
             border-top-width 0s ease var(--t-med),
             border-top-color 0s ease var(--t-med);
}
.q-fab-body::-webkit-scrollbar{width:8px;height:8px}
.q-fab-body::-webkit-scrollbar-thumb{background:var(--border);border-radius:999px}
table{width:100%;border-collapse:collapse;font-size:13px;table-layout:auto}
th,td{padding:10px 14px;text-align:left;border-bottom:1px solid var(--border);vertical-align:middle}
th:last-child,td:last-child{text-align:right}
th{font-weight:700;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em;
  background:var(--input);position:sticky;top:0;z-index:1}
tbody tr{transition:background var(--t-fast)}
tbody tr:hover{background:var(--input)}
tbody tr:last-child td{border-bottom:none}
td.idx{color:var(--muted);font-variant-numeric:tabular-nums;width:32px}
td.name .nm{font-family:var(--mono);font-weight:600;font-size:13px}
td.name .det{color:var(--muted);font-size:11px;margin-top:2px}
.badge{display:inline-flex;align-items:center;gap:6px;padding:3px 9px;border-radius:999px;
  font-size:11px;font-weight:700;white-space:nowrap}
.badge.done{background:var(--success-soft);color:var(--success)}
.badge.proc{background:var(--accent);color:var(--accent-fg)}
.badge.proc .pulse{width:6px;height:6px;border-radius:50%;background:currentColor;animation:p 1.2s infinite}
@keyframes p{0%,100%{opacity:1}50%{opacity:.3}}
.badge.queued{background:var(--accent-soft);color:var(--accent)}
.badge.queued .pulse{width:6px;height:6px;border-radius:50%;background:currentColor;animation:p 1.2s infinite}
.badge.idle{background:var(--input);color:var(--muted);border:1px solid var(--border)}
.progress-cell{display:flex;align-items:center;gap:10px;min-width:130px}
.pbar{height:5px;background:var(--input);border-radius:999px;overflow:hidden;flex:1;min-width:50px}
.pbar > i{display:block;height:100%;background:var(--accent);border-radius:999px;transition:width var(--t-med)}
.pbar.done > i{background:var(--success)}
.pos{color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums}
.actions{text-align:right;white-space:nowrap}
.actions .iconbtn{margin-left:2px;vertical-align:middle}
.actions .iconbtn:first-child{margin-left:0}
.iconbtn{width:28px;height:28px;border:none;background:transparent;color:var(--muted);cursor:pointer;
  border-radius:var(--radius-xs);display:inline-flex;align-items:center;justify-content:center;
  font-size:13px;transition:var(--t-fast);flex-shrink:0}
.iconbtn:hover{background:var(--card);color:var(--fg);box-shadow:var(--shadow-xs)}
.iconbtn.danger:hover{color:var(--danger);background:var(--danger-soft)}


/* === Per-service token gating === *\/

/*TTS: разблокируется только когда body[data-token-tts="valid"]*/
body:not([data-token-tts="valid"]) .token-gated-tts { display: none !important; }
/*A2V: разблокируется только когда body[data-token-a2v="valid"]*/
body:not([data-token-a2v="valid"]) .token-gated-a2v { display: none !important; }
/*Совместимость: .token-gated без суффикса = тоже относится к TTS*/
/*(на случай, если где-то забыли обновить класс).*/
/*body:not([data-token-tts="valid"]) .token-gated { display: none !important; }*/
