/* TeleSpace Admin — Liquid Glass workspace.
   Implements UI_DESIGN_SYSTEM.md v1.0: ambient canvas, floating glass sidebar,
   semantic tokens, Telegram-blue accent, violet workspace identity.
   Class names are unchanged — this file is styling only. */

:root{
  /* ---- primitives ---- */
  --tf-blue-500:#229ED9; --tf-blue-600:#168AC2;
  --tf-violet-500:#6D5DFB; --tf-violet-600:#5848E6;
  --tf-pink-400:#E98BC2; --tf-cyan-300:#8BE1F5;
  --tf-ink-950:#15161A; --tf-ink-800:#30323A; --tf-ink-600:#60636F; --tf-ink-400:#9296A3;
  --tf-cloud-50:#FBFCFF; --tf-cloud-100:#F4F6FB; --tf-cloud-200:#E9ECF4; --tf-white:#FFFFFF;

  /* ---- semantic colour ----
     Three text steps, each AA-verified against the glass-over-canvas background
     (~#F7F8FC): primary ≈16:1, secondary ≈6.4:1, tertiary ≈4.5:1. */
  --tf-color-canvas:#F4F6FB;
  --tf-color-text-primary:#15161A;
  --tf-color-text-secondary:#565A66;
  --tf-color-text-tertiary:#6E7280;
  --tf-color-text-inverse:#FFFFFF;
  --tf-color-accent:#229ED9;
  --tf-color-accent-strong:#168AC2;
  --tf-color-ai:#6D5DFB;
  --tf-color-focus:#229ED9;
  --tf-color-success:#2E9B65;
  --tf-color-warning:#BD7411;
  --tf-color-danger:#D94B59;
  --tf-color-info:#3A83E8;
  --tf-color-hairline:rgba(21,22,26,.09);

  /* ---- glass material ---- */
  --tf-glass-fill:rgba(255,255,255,.54);
  --tf-glass-fill-strong:rgba(255,255,255,.72);
  --tf-glass-fill-subtle:rgba(255,255,255,.34);
  --tf-glass-border:rgba(255,255,255,.72);
  --tf-glass-highlight:rgba(255,255,255,.55);
  --tf-glass-blur:24px;
  --tf-glass-blur-heavy:40px;

  /* ---- elevation ---- */
  --tf-shadow-float:0 16px 48px rgba(38,46,70,.14);
  --tf-shadow-overlay:0 28px 88px rgba(27,34,58,.20);
  --tf-shadow-press:0 6px 16px rgba(38,46,70,.12);

  /* ---- radius ---- */
  --tf-radius-control:12px; --tf-radius-card:20px; --tf-radius-panel:28px;
  --tf-radius-sidebar:32px; --tf-radius-pill:999px;

  /* ---- spacing ---- */
  --tf-space-4:4px; --tf-space-8:8px; --tf-space-12:12px; --tf-space-16:16px;
  --tf-space-20:20px; --tf-space-24:24px; --tf-space-32:32px; --tf-space-40:40px;
  --tf-space-48:48px; --tf-space-64:64px; --tf-space-80:80px; --tf-space-96:96px;

  /* ---- type ----
     Inter carries Latin; Noto Sans SC carries 中文 (Inter has no CJK glyphs, so
     without this the UI mixes two unrelated typefaces). System faces follow as
     offline fallbacks so the interface stays correct with no network. */
  --tf-font-sans:"Inter","Noto Sans SC",ui-sans-serif,-apple-system,BlinkMacSystemFont,
    "Segoe UI Variable Text","Segoe UI",Roboto,"PingFang SC","Hiragino Sans GB",
    "Microsoft YaHei UI","Microsoft YaHei",sans-serif;
  --tf-font-mono:ui-monospace,SFMono-Regular,"SF Mono","Cascadia Mono",Menlo,Consolas,monospace;
  --tf-font-display:48px; --tf-font-h1:32px; --tf-font-h2:24px; --tf-font-h3:18px;
  --tf-font-body:15px; --tf-font-body-sm:13px; --tf-font-label:12px; --tf-font-metric:36px;
  --tf-leading-tight:1.08; --tf-leading-heading:1.18; --tf-leading-body:1.48; --tf-leading-caption:1.35;

  /* ---- motion ---- */
  --tf-motion-instant:100ms; --tf-motion-fast:160ms; --tf-motion-standard:240ms;
  --tf-motion-panel:360ms; --tf-motion-hero:520ms;
  --tf-ease-spring:cubic-bezier(.22,1,.36,1);
  --tf-ease-enter:cubic-bezier(.16,1,.3,1);
  --tf-ease-exit:cubic-bezier(.7,0,.84,0);

  /* ---- layout ---- */
  --tf-sidebar-width:272px; --tf-content-max:1600px; --tf-reading-max:760px;

  /* ---- legacy aliases (a few inline styles in app.js still read these) ---- */
  --bg:var(--tf-color-canvas); --surface:var(--tf-glass-fill); --surface-2:var(--tf-cloud-100);
  --border:var(--tf-color-hairline); --text:var(--tf-color-text-primary);
  --muted:var(--tf-color-text-secondary); --primary:var(--tf-color-accent);
  --primary-hover:var(--tf-color-accent-strong); --accent:var(--tf-color-ai);
  --success:var(--tf-color-success); --warning:var(--tf-color-warning);
  --danger:var(--tf-color-danger); --info:var(--tf-color-info);
  --radius:var(--tf-radius-card); --radius-sm:var(--tf-radius-control);
  --shadow:var(--tf-shadow-float);
}

*{ box-sizing:border-box; }
html,body{ margin:0; height:100%; }
body{
  background:var(--tf-color-canvas); color:var(--tf-color-text-primary);
  font-family:var(--tf-font-sans);
  font-size:var(--tf-font-body); line-height:var(--tf-leading-body); font-weight:400;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  font-optical-sizing:auto;
  /* contextual alternates + proportional lining figures for running text */
  font-variant-numeric:lining-nums proportional-nums;
}

/* ---------- Ambient canvas (static, behind everything) ---------- */
body::before,body::after{
  content:""; position:fixed; inset:0; z-index:-1; pointer-events:none;
}
body::before{
  background:
    radial-gradient(1100px 720px at 12% -8%, rgba(34,158,217,.16), transparent 62%),
    radial-gradient(900px 640px at 92% 4%, rgba(109,93,251,.14), transparent 60%);
}
body::after{
  background:
    radial-gradient(820px 560px at 78% 92%, rgba(233,139,194,.12), transparent 62%),
    radial-gradient(700px 520px at 4% 84%, rgba(139,225,245,.12), transparent 60%);
}

.muted{ color:var(--tf-color-text-secondary); }
.small{ font-size:var(--tf-font-body-sm); line-height:var(--tf-leading-caption); }
[hidden]{ display:none !important; }

/* Visible focus everywhere (accessibility requirement) */
:focus-visible{ outline:2px solid var(--tf-color-focus); outline-offset:2px; border-radius:6px; }

/* ---------- Glass material primitives ---------- */
.panel,.card,.kpi,.tbl-wrap,.click-card,.tile,.queue-details,.modal,.login-card{
  background:var(--tf-glass-fill);
  -webkit-backdrop-filter:blur(var(--tf-glass-blur)) saturate(180%);
  backdrop-filter:blur(var(--tf-glass-blur)) saturate(180%);
  border:1px solid var(--tf-glass-border);
  box-shadow:var(--tf-shadow-float), inset 0 1px 0 var(--tf-glass-highlight);
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .panel,.card,.kpi,.tbl-wrap,.click-card,.tile,.queue-details,.modal,.login-card,.sidebar{
    background:rgba(255,255,255,.94);
  }
}

/* ---------- Login ---------- */
/* Its own small palette: the login page is the one screen that isn't the admin
   shell, and hard-coding these keeps a later token change from quietly
   restyling it. */
.login-wrap{
  --lp-primary:#356DFF;
  --lp-secondary:#6C63FF;
  --lp-ink:#172554;
  --lp-ink-soft:#5A6B93;

  position:relative; min-height:100vh; min-height:100dvh;
  display:flex; align-items:center; justify-content:center;
  padding:var(--tf-space-40) var(--tf-space-24) var(--tf-space-64);
  /* Three stops, not two: a straight two-stop ramp reads as a cheap gradient,
     the lighter band through the middle is what makes it look lit. */
  background:linear-gradient(160deg,#EEF5FF 0%,#F7F9FF 48%,#EAF1FF 100%);
  /* Only sideways. Clipping vertically would cut the card off on a short laptop
     screen instead of letting the page scroll; the decorations are clipped by
     .lp-bg, which is what overflow:hidden was actually for. */
  overflow-x:hidden;
}

/* ---- background decoration ---- */
.lp-bg{ position:absolute; inset:0; pointer-events:none; overflow:hidden; }
.lp-canvas{ position:absolute; inset:0; width:100%; height:100%; }
.lp-orbits{ position:absolute; inset:-10%; width:120%; height:120%; opacity:.5; }
.lp-orbit-spin{ transform-origin:600px 400px; animation:lp-spin 90s linear infinite; }
@keyframes lp-spin{ to{ transform:rotate(360deg) } }

/* Round white badges resting on the map. Each gets its own duration and delay —
   matched timings make them bob in lockstep, which reads as a loading spinner
   rather than atmosphere. */
.lp-badge{ position:absolute; display:grid; place-items:center;
  width:60px; height:60px; border-radius:50%;
  background:rgba(255,255,255,.72); color:var(--lp-primary);
  border:1px solid rgba(255,255,255,.9);
  box-shadow:0 10px 26px rgba(80,100,180,.14);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px); }
.lp-badge svg{ width:26px; height:26px; }
.lp-b1{ top:24%; left:19%;  animation:lp-drift 19s ease-in-out infinite; }
.lp-b2{ top:44%; left:13%;  animation:lp-drift 24s ease-in-out infinite -6s; }
.lp-b3{ top:27%; right:16%; animation:lp-drift 21s ease-in-out infinite -11s; }
.lp-b4{ top:62%; right:14%; animation:lp-drift 27s ease-in-out infinite -3s; }

.lp-plane{ position:absolute; color:#fff;
  filter:drop-shadow(0 6px 14px rgba(80,110,200,.35)); }
.lp-plane svg{ width:100%; height:100%; display:block; }
.lp-p1{ width:56px; height:56px; top:52%; left:8%;  transform:rotate(-8deg);
  animation:lp-fly 26s ease-in-out infinite; }
.lp-p2{ width:64px; height:64px; top:40%; right:6%; transform:scaleX(-1) rotate(-8deg);
  animation:lp-fly 31s ease-in-out infinite -12s; }
@keyframes lp-drift{
  0%,100%{ transform:translate3d(0,0,0) }
  50%    { transform:translate3d(0,-20px,0) }
}
@keyframes lp-fly{
  0%,100%{ translate:0 0 }
  50%    { translate:16px -26px }
}
@media (max-width:1180px){ .lp-b2, .lp-b4{ display:none; } }
@media (max-width:820px){ .lp-badge, .lp-plane{ display:none; } }

/* ---- corner chrome ---- */
.lp-chip{ position:absolute; z-index:2; display:inline-flex; align-items:center;
  gap:var(--tf-space-8); padding:10px var(--tf-space-16);
  border-radius:var(--tf-radius-pill); font-family:inherit;
  font-size:var(--tf-font-body-sm); font-weight:500; color:var(--lp-ink);
  background:rgba(255,255,255,.72); border:1px solid rgba(255,255,255,.9);
  box-shadow:0 8px 22px rgba(80,100,180,.12);
  -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px); }
.lp-chip svg{ width:16px; height:16px; color:var(--lp-primary); flex:none; }
.lp-chip-tl{ top:var(--tf-space-24); left:var(--tf-space-24); }
.lp-chip-tr{ top:var(--tf-space-24); right:var(--tf-space-24); cursor:pointer;
  transition:transform 200ms ease, box-shadow 200ms ease; }
.lp-chip-tr:hover{ transform:translateY(-1px); box-shadow:0 12px 26px rgba(80,100,180,.2); }
.lp-chip-tr:focus-visible{ outline:2px solid var(--lp-primary); outline-offset:3px; }

@media (max-width:640px){
  .lp-chip-tl{ display:none; }
  .lp-chip-tr{ top:var(--tf-space-16); right:var(--tf-space-16); }
}

/* ---- the card ---- */
.login-card{
  position:relative; z-index:1;
  /* 440, not the 540 the guide asked for: at 540 the fields stretched so wide
     that a short username looked lost in them. Narrower reads as a login box. */
  width:440px; max-width:min(460px,100%);
  border-radius:28px; padding:var(--tf-space-40) var(--tf-space-32); text-align:center;
  background:rgba(255,255,255,.82);
  -webkit-backdrop-filter:blur(30px) saturate(150%);
  backdrop-filter:blur(30px) saturate(150%);
  border:1px solid rgba(255,255,255,.45);
  box-shadow:0 35px 80px rgba(80,100,180,.18);
  animation:lp-card-in 620ms cubic-bezier(.16,.84,.44,1) both;
}
@keyframes lp-card-in{
  from{ opacity:0; transform:translateY(18px) scale(.985) }
  to  { opacity:1; transform:none }
}
.login-logo{ width:150px; max-width:60%; height:auto; display:block;
  margin:0 auto var(--tf-space-12); }
.lp-tagline{ font-size:11px; font-weight:600; letter-spacing:.22em;
  color:var(--lp-ink-soft); margin-bottom:var(--tf-space-32); }

/* ---- fields ---- */
/* The icon sits inside the box, so the input carries the left padding rather
   than the wrapper — otherwise the caret starts underneath the glyph. */
.lp-field{ position:relative; margin-bottom:var(--tf-space-20); }
/* z-index, not decoration: the input is a later sibling that paints its own
   background, so without this it covers the icon completely. */
.lp-field-ic{ position:absolute; z-index:2; left:18px; top:50%; transform:translateY(-50%);
  width:19px; height:19px; color:#93A1C4; pointer-events:none;
  transition:color 200ms linear; }
.login-wrap .lp-field input{
  position:relative; z-index:1;
  width:100%; height:56px; box-sizing:border-box;
  padding:0 52px 0 50px;
  border-radius:14px; border:1px solid #E5E7EB; background:#fff;
  font-family:inherit; font-size:var(--tf-font-body); color:var(--lp-ink);
  transition:border-color 200ms linear, box-shadow 200ms linear;
}
.login-wrap .lp-field input::placeholder{ color:#9AA6C2; }
/* One ring, not two. The app-wide input:focus rule paints a teal 3px halo; this
   is the same idea in the login palette, tightened so it reads as a highlight
   rather than a second border. */
.login-wrap .lp-field input:focus{
  outline:none; border-color:var(--lp-primary);
  box-shadow:0 0 0 3px rgba(53,109,255,.16);
}
.lp-field:focus-within .lp-field-ic{ color:var(--lp-primary); }
.login-wrap .field-label{ font-size:13px; font-weight:500; color:var(--lp-ink);
  margin-bottom:var(--tf-space-8); }

.lp-eye{ position:absolute; z-index:2; right:8px; top:50%; transform:translateY(-50%);
  width:38px; height:38px; display:grid; place-items:center;
  background:transparent; border:none; border-radius:10px; cursor:pointer;
  color:#93A1C4; transition:color 200ms linear, background 200ms linear; }
.lp-eye svg{ width:19px; height:19px; }
.lp-eye:hover{ color:var(--lp-primary); background:rgba(53,109,255,.08); }
.lp-eye:focus-visible{ outline:2px solid var(--lp-primary); outline-offset:1px; }

/* ---- remember me ---- */
/* The real checkbox stays in the DOM (keyboard, forms, screen readers all rely
   on it) but is hidden behind a drawn box, since a native checkbox cannot be
   given this shape. */
.lp-remember{ display:flex; align-items:center; gap:var(--tf-space-8);
  margin:calc(var(--tf-space-4) * -1) 0 var(--tf-space-8);
  font-size:var(--tf-font-body-sm); color:var(--lp-ink-soft); cursor:pointer;
  user-select:none; text-align:left; }
.lp-remember input{ position:absolute; opacity:0; width:0; height:0; }
.lp-remember-box{ flex:none; display:grid; place-items:center;
  width:19px; height:19px; border-radius:6px;
  border:1.5px solid #D3DAEA; background:#fff; color:#fff;
  transition:background 160ms linear, border-color 160ms linear; }
.lp-remember-box svg{ width:12px; height:12px; opacity:0;
  transition:opacity 160ms linear; }
.lp-remember input:checked + .lp-remember-box{
  background:var(--lp-primary); border-color:var(--lp-primary); }
.lp-remember input:checked + .lp-remember-box svg{ opacity:1; }
.lp-remember input:focus-visible + .lp-remember-box{
  outline:2px solid var(--lp-primary); outline-offset:2px; }
.lp-remember:hover .lp-remember-box{ border-color:var(--lp-primary); }

/* ---- submit ---- */
.lp-submit{
  width:100%; height:56px; border:none; border-radius:16px; cursor:pointer;
  display:flex; align-items:center; justify-content:center; gap:var(--tf-space-8);
  font-family:inherit; font-size:15px; font-weight:600; color:#fff;
  background:linear-gradient(135deg,#4D8DFF,#2E5FFF);
  box-shadow:0 8px 20px rgba(46,95,255,.26);
  margin-top:var(--tf-space-8);
  transition:transform 250ms ease, box-shadow 250ms ease, filter 250ms ease;
}
.lp-submit svg{ width:18px; height:18px; transition:transform 250ms ease; }
.lp-submit:hover{ transform:translateY(-2px); filter:brightness(1.05);
  box-shadow:0 14px 32px rgba(46,95,255,.38); }
.lp-submit:hover svg{ transform:translateX(3px); }
.lp-submit:active{ transform:translateY(0); box-shadow:0 6px 16px rgba(46,95,255,.3); }
.lp-submit:focus-visible{ outline:2px solid var(--lp-primary); outline-offset:3px; }

.lp-newhere{ margin:var(--tf-space-20) 0 0; font-size:var(--tf-font-body-sm);
  color:var(--lp-ink-soft); }
.lp-newhere b{ color:var(--lp-primary); font-weight:600; }


@media (max-width:600px){
  .login-card{ padding:var(--tf-space-32) var(--tf-space-24); border-radius:22px; }
  .lp-tagline{ margin-bottom:var(--tf-space-24); letter-spacing:.16em; }
}
/* Atmosphere is never worth overriding this. The canvas checks the same query
   in JS and stops its loop. */
@media (prefers-reduced-motion: reduce){
  .lp-orbit-spin, .lp-badge, .lp-plane{ animation:none; }
  .login-card{ animation:none; }
}
.login-brand{ font-size:var(--tf-font-h1); font-weight:600; letter-spacing:-.02em;
  line-height:var(--tf-leading-heading); text-align:center; margin-bottom:var(--tf-space-4);
  background:linear-gradient(100deg,var(--tf-blue-500),var(--tf-violet-500));
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
.login-card h1{ font-size:var(--tf-font-h3); margin:0 0 var(--tf-space-4); font-weight:600; }
.login-card p{ margin:0 0 var(--tf-space-20); font-size:var(--tf-font-body-sm); color:var(--tf-color-text-secondary); }
.field-label{ display:block; text-align:left; font-size:var(--tf-font-label);
  color:var(--tf-color-text-secondary); margin:0 0 var(--tf-space-8); font-weight:500;
  letter-spacing:.01em; }
.login-err{ color:var(--tf-color-danger); font-size:var(--tf-font-body-sm); margin-top:var(--tf-space-12); }
.auth-tabs{ display:flex; gap:var(--tf-space-4); background:var(--tf-glass-fill-subtle);
  border:1px solid var(--tf-glass-border); border-radius:var(--tf-radius-control);
  padding:var(--tf-space-4); margin:var(--tf-space-4) 0 var(--tf-space-20); }
.auth-tab{ flex:1; background:transparent; border:none; color:var(--tf-color-text-secondary);
  font-weight:500; font-size:var(--tf-font-body-sm); padding:var(--tf-space-8) var(--tf-space-12);
  border-radius:var(--tf-space-8); cursor:pointer; font-family:inherit;
  transition:background var(--tf-motion-fast) var(--tf-ease-spring), color var(--tf-motion-fast) linear; }
.auth-tab.active{ background:var(--tf-white); color:var(--tf-color-text-primary);
  box-shadow:var(--tf-shadow-press); }
.auth-pane{ text-align:left; }
.auth-msg{ font-size:var(--tf-font-body-sm); margin-top:var(--tf-space-12); line-height:var(--tf-leading-body); }
.auth-msg.ok{ color:var(--tf-color-success); }
.auth-msg.bad{ color:var(--tf-color-danger); }
.auth-foot{ margin-top:var(--tf-space-16); color:var(--tf-color-text-secondary); }
.auth-foot a{ color:var(--tf-color-accent); text-decoration:none; font-weight:500; }
.role-pill{ display:inline-block; margin-top:var(--tf-space-4); font-size:var(--tf-font-label);
  font-weight:500; color:var(--tf-violet-600); background:rgba(109,93,251,.12);
  border-radius:var(--tf-radius-pill); padding:2px 10px; }
.nav-badge{ margin-left:auto; background:var(--tf-color-danger); color:var(--tf-white);
  font-size:var(--tf-font-label); font-weight:600; min-width:20px; height:20px;
  border-radius:var(--tf-radius-pill); display:inline-flex; align-items:center;
  justify-content:center; padding:0 6px; }
.role-sel{ width:auto; min-width:170px; }
#whoami{ padding-bottom:var(--tf-space-12); border-bottom:1px solid var(--tf-color-hairline);
  margin-bottom:var(--tf-space-4); line-height:var(--tf-leading-caption);
  color:var(--tf-color-text-secondary); }

/* ---------- Controls ---------- */
/* `<input>` with no type attribute is still a text box, but `input[type=text]`
   does NOT match it — which silently left a third of the fields on browser
   defaults. `input:not([type])` covers them at the same specificity as the
   typed selectors, so later rules like `.filters input` still win. */
input:not([type]),
input[type=text],input[type=password],input[type=number],
input[type=datetime-local],input[type=date],input[type=time],
input[type=tel],input[type=email],
input[type=search],input[type=url],
textarea,select{
  width:100%; box-sizing:border-box;
  /* Hairline for the edge (a white glass-border would vanish on a light panel);
     the translucent fill plus the inner top highlight carry the glass look. */
  background:var(--tf-glass-fill-strong); border:1px solid var(--tf-color-hairline);
  -webkit-backdrop-filter:blur(var(--tf-glass-blur)); backdrop-filter:blur(var(--tf-glass-blur));
  box-shadow:inset 0 1px 0 var(--tf-glass-highlight);
  color:var(--tf-color-text-primary); border-radius:var(--tf-radius-control);
  padding:var(--tf-space-12) var(--tf-space-16); font:inherit; font-size:var(--tf-font-body);
  min-height:44px; outline:none;
  transition:border-color var(--tf-motion-fast) linear, box-shadow var(--tf-motion-fast) linear,
             background var(--tf-motion-fast) linear; }
input::placeholder,textarea::placeholder{ color:var(--tf-color-text-tertiary); }
input:focus,textarea:focus,select:focus{
  background:var(--tf-white,#fff); border-color:var(--tf-color-focus);
  box-shadow:0 0 0 3px rgba(34,158,217,.22), inset 0 1px 0 var(--tf-glass-highlight);
  outline:none; }
input:disabled,textarea:disabled,select:disabled{ opacity:.55; cursor:not-allowed; }
textarea{ resize:vertical; min-height:130px; line-height:var(--tf-leading-body); }
select{ cursor:pointer; }

/* ---------- Buttons ---------- */
.btn-primary{ background:var(--tf-color-accent); color:var(--tf-color-text-inverse); border:none;
  font-weight:500; border-radius:var(--tf-radius-control); padding:var(--tf-space-12) var(--tf-space-20);
  cursor:pointer; font-size:var(--tf-font-body); font-family:inherit; min-height:40px;
  box-shadow:var(--tf-shadow-press);
  transition:background var(--tf-motion-fast) linear, transform var(--tf-motion-fast) var(--tf-ease-spring); }
.btn-primary:hover{ background:var(--tf-color-accent-strong); transform:scale(1.01); }
.btn-primary:active{ transform:scale(.985); }
.btn-primary:disabled{ opacity:.45; cursor:not-allowed; transform:none; box-shadow:none; }
.btn-ghost{ background:var(--tf-glass-fill-subtle); color:var(--tf-color-text-primary);
  border:1px solid var(--tf-glass-border); border-radius:var(--tf-radius-control);
  padding:var(--tf-space-8) var(--tf-space-16); cursor:pointer; font-weight:500;
  font-size:var(--tf-font-body-sm); font-family:inherit; min-height:36px;
  transition:background var(--tf-motion-fast) linear, transform var(--tf-motion-fast) var(--tf-ease-spring); }
.btn-ghost:hover{ background:var(--tf-white); transform:scale(1.01); }
.btn-ghost:active{ transform:scale(.985); }
.btn-block{ width:100%; margin-top:var(--tf-space-16); display:block; }
.btn-sm{ padding:var(--tf-space-8) var(--tf-space-12); font-size:var(--tf-font-body-sm); min-height:32px; }
.btn-danger{ color:var(--tf-color-danger); border-color:rgba(217,75,89,.32); }
.btn-danger:hover{ background:rgba(217,75,89,.10); }
.btn-danger-solid{ background:var(--tf-color-danger); color:var(--tf-white); border:none;
  font-weight:500; border-radius:var(--tf-radius-control); padding:var(--tf-space-8) var(--tf-space-16);
  cursor:pointer; font-size:var(--tf-font-body-sm); font-family:inherit; min-height:36px; }
.btn-danger-solid:hover{ background:#c33f4d; }
.btn-alt{ background:var(--tf-color-ai); color:var(--tf-white); border:none;
  border-radius:var(--tf-radius-control); cursor:pointer; font-weight:500; font-family:inherit; }
.btn-alt:hover{ background:var(--tf-violet-600); }

/* ---------- App shell: floating sidebar over ambient canvas ---------- */
.app{ display:grid; grid-template-columns:calc(var(--tf-sidebar-width) + var(--tf-space-32)) 1fr;
  min-height:100vh; }
.sidebar{
  position:sticky; top:var(--tf-space-16); height:calc(100vh - var(--tf-space-32));
  width:var(--tf-sidebar-width); margin:var(--tf-space-16);
  display:flex; flex-direction:column; padding:var(--tf-space-16);
  border-radius:var(--tf-radius-sidebar);
  background:linear-gradient(180deg, rgba(109,93,251,.10), rgba(255,255,255,.02)), var(--tf-glass-fill);
  -webkit-backdrop-filter:blur(var(--tf-glass-blur-heavy)) saturate(180%);
  backdrop-filter:blur(var(--tf-glass-blur-heavy)) saturate(180%);
  border:1px solid var(--tf-glass-border);
  box-shadow:var(--tf-shadow-float), inset 0 1px 0 var(--tf-glass-highlight);
}
.brand{ display:flex; flex-direction:row; align-items:center; gap:var(--tf-space-12);
  padding:var(--tf-space-8) var(--tf-space-12) var(--tf-space-20); }
.brand-mark{ width:40px; height:auto; flex:none; display:block; }
.brand-text{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.brand-name{ font-size:var(--tf-font-h3); font-weight:600; letter-spacing:-.02em;
  line-height:var(--tf-leading-heading);
  background:linear-gradient(100deg,var(--tf-violet-500),var(--tf-blue-500));
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
.brand-img{ width:160px; max-width:100%; height:auto; display:block; }
.brand-sub{ font-size:var(--tf-font-label); letter-spacing:.06em; text-transform:uppercase;
  color:var(--tf-color-text-tertiary); font-weight:500; }
.nav{ display:flex; flex-direction:column; gap:2px; margin-top:var(--tf-space-4); flex:1;
  overflow-y:auto; overflow-x:hidden; }
.nav a{ display:flex; align-items:center; gap:var(--tf-space-12);
  min-height:44px; padding:0 var(--tf-space-12); border-radius:var(--tf-radius-control);
  color:var(--tf-color-text-secondary); text-decoration:none; font-weight:500;
  font-size:var(--tf-font-body); cursor:pointer;
  transition:background var(--tf-motion-fast) linear, color var(--tf-motion-fast) linear,
             transform var(--tf-motion-fast) var(--tf-ease-spring); }
.nav a .ic{ width:18px; text-align:center; }
.nav a:hover{ background:var(--tf-glass-fill-subtle); color:var(--tf-color-text-primary); }
.nav a:active{ transform:scale(.99); }
/* selected = light liquid capsule (not a thin left bar) */
.nav a.active{ background:var(--tf-white); color:var(--tf-color-text-primary); font-weight:600;
  box-shadow:var(--tf-shadow-press), inset 0 1px 0 var(--tf-glass-highlight); }
.nav-group{ padding:var(--tf-space-16) var(--tf-space-12) var(--tf-space-4);
  font-size:var(--tf-font-label); font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  color:var(--tf-color-text-tertiary); }
.nav-group:first-child{ padding-top:var(--tf-space-4); }

/* --- group trigger rows: same shape as a nav item, plus a caret --- */
.nav-group-btn{ display:flex; align-items:center; gap:var(--tf-space-12); width:100%;
  min-height:44px; padding:0 var(--tf-space-12); border:none; background:transparent;
  border-radius:var(--tf-radius-control); color:var(--tf-color-text-secondary);
  font:inherit; font-size:var(--tf-font-body); font-weight:500; text-align:left; cursor:pointer;
  transition:background var(--tf-motion-fast) linear, color var(--tf-motion-fast) linear; }
.nav-group-btn:hover{ background:var(--tf-glass-fill-subtle); color:var(--tf-color-text-primary); }
.nav-group-btn .nav-caret{ margin-left:auto; color:var(--tf-color-text-tertiary);
  transition:transform var(--tf-motion-fast) var(--tf-ease-spring); }
.nav-group-btn.open .nav-caret{ transform:rotate(90deg); }
/* Merely expanded: a quiet emphasis only — it must NOT read as "you are here". */
.nav-group-btn.open{ background:var(--tf-glass-fill-subtle); color:var(--tf-color-text-primary); }
/* Current location: the white capsule. Declared last so it wins over .open, and
   only ever one item in the sidebar carries it. */
.nav-group-btn.active{ background:var(--tf-white); color:var(--tf-color-text-primary);
  font-weight:600; box-shadow:var(--tf-shadow-press), inset 0 1px 0 var(--tf-glass-highlight); }

/* --- inline group expansion: children slide open under their group --- */
.nav-children{ display:flex; flex-direction:column; gap:2px;
  margin:2px 0 var(--tf-space-8) var(--tf-space-12);
  padding-left:var(--tf-space-8); border-left:2px solid var(--tf-color-hairline);
  /* Resting state is the OPEN state, so children stay usable even if the
     animation never runs (paused tab, no animation support). */
  animation:navChildrenIn var(--tf-motion-standard) var(--tf-ease-enter); }
@keyframes navChildrenIn{
  from{ opacity:0; transform:translateY(-4px); }
  to{ opacity:1; transform:none; }
}
.nav-child{ display:flex; align-items:center; min-height:38px;
  padding:0 var(--tf-space-12); border-radius:var(--tf-radius-control);
  color:var(--tf-color-text-secondary); text-decoration:none; cursor:pointer;
  font-size:var(--tf-font-body-sm); font-weight:500;
  transition:background var(--tf-motion-fast) linear, color var(--tf-motion-fast) linear; }
.nav-child:hover{ background:var(--tf-glass-fill-subtle); color:var(--tf-color-text-primary); }
.nav-child.active{ background:var(--tf-white); color:var(--tf-color-text-primary); font-weight:600;
  box-shadow:var(--tf-shadow-press), inset 0 1px 0 var(--tf-glass-highlight); }

/* --- Message Studio: library list + preview --- */
.ms-split{ display:grid; grid-template-columns:minmax(260px,360px) 1fr; gap:var(--tf-space-24);
  align-items:start; }
.ms-list{ display:flex; flex-direction:column; gap:var(--tf-space-4); max-height:62vh; overflow-y:auto; }
.ms-row{ display:flex; align-items:flex-start; gap:var(--tf-space-12); width:100%; text-align:left;
  padding:var(--tf-space-12); border:none; background:transparent; cursor:pointer; font:inherit;
  border-radius:var(--tf-radius-control); border-left:3px solid transparent;
  transition:background var(--tf-motion-fast) linear; }
.ms-row:hover{ background:var(--tf-glass-fill-subtle); }
.ms-row.active{ background:var(--tf-white); border-left-color:var(--tf-color-accent);
  box-shadow:var(--tf-shadow-press); }
.ms-row-ic{ flex:none; }
.ms-row-main{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.ms-row-name{ font-size:var(--tf-font-body); font-weight:500; color:var(--tf-color-text-primary); }
.ms-row-snip{ font-size:var(--tf-font-body-sm); color:var(--tf-color-text-secondary);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
@media (max-width:1024px){ .ms-split{ grid-template-columns:1fr; } }
.sidebar-foot{ border-top:1px solid var(--tf-color-hairline); padding-top:var(--tf-space-16);
  margin-top:var(--tf-space-8); display:flex; flex-direction:column; gap:var(--tf-space-8); }
.sidebar-foot .btn-block{ margin-top:0; }

.main{ min-width:0; }
.view{ padding:var(--tf-space-32) var(--tf-space-32) var(--tf-space-64); max-width:var(--tf-content-max); }

/* ---------- Section header ---------- */
.sec-h{ display:flex; align-items:center; gap:var(--tf-space-12); }
.sec-h .ic{ font-size:var(--tf-font-h2); }
.sec-h h2{ font-size:var(--tf-font-h1); font-weight:600; margin:0; letter-spacing:-.02em;
  line-height:var(--tf-leading-heading); }
.sec-sub{ color:var(--tf-color-text-secondary); margin:var(--tf-space-8) 0 0; font-size:var(--tf-font-body);
  max-width:var(--tf-reading-max); }
.sec-rule{ height:1px; background:var(--tf-color-hairline); border:0; margin:var(--tf-space-24) 0 var(--tf-space-32); }

/* ---------- Cards / panels ---------- */
.card{ border-radius:var(--tf-radius-card); padding:var(--tf-space-24); }
.panel{ border-radius:var(--tf-radius-panel); padding:var(--tf-space-24);
  margin-bottom:var(--tf-space-24); }
.panel-title{ font-size:var(--tf-font-h3); font-weight:600; margin:0 0 var(--tf-space-16);
  letter-spacing:-.01em; }

/* ---------- Community: group cards ---------- */
.cm-bar{ margin-bottom:var(--tf-space-16); flex-wrap:wrap; gap:var(--tf-space-12); }
.cm-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(340px,1fr));
  gap:var(--tf-space-20); align-items:start; }
/* the grid supplies the gaps — the panel's own bottom margin would double them */
.cm-grid > .panel{ margin-bottom:0; }
.cm-card{ cursor:pointer; transition:transform var(--tf-motion-fast) var(--tf-ease-spring),
  box-shadow var(--tf-motion-fast) linear; }
.cm-card:hover{ transform:translateY(-2px); box-shadow:var(--tf-shadow-overlay); }
.cm-name{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:var(--tf-font-body); }
.cm-meta{ display:flex; gap:var(--tf-space-20); flex-wrap:wrap;
  margin-top:var(--tf-space-16); padding-top:var(--tf-space-12);
  border-top:1px solid var(--tf-color-hairline); font-size:var(--tf-font-body-sm); }
.cm-actions{ margin-top:var(--tf-space-16); }
/* ---------- Group message filters ---------- */
.gf-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:var(--tf-space-4) var(--tf-space-20); }
.gf-item{ align-items:flex-start; padding:var(--tf-space-12) 0;
  border-bottom:1px solid var(--tf-color-hairline); }
.gf-item .sw{ margin-top:2px; }

/* chat-kind chips: quieter than a status badge, but a basic group is called out
   because Telegram simply can't mute in one */
.ck-row{ display:flex; gap:var(--tf-space-4); flex-wrap:wrap; margin:var(--tf-space-4) 0; }
.ck{ display:inline-block; padding:2px 8px; border-radius:var(--tf-radius-pill);
  font-size:var(--tf-font-label); font-weight:500; white-space:nowrap; }
.ck-ok{ color:var(--tf-color-text-secondary); background:var(--tf-glass-fill-subtle);
  border:1px solid var(--tf-color-hairline); }
.ck-warn{ color:#8a540c; background:rgba(189,116,17,.14); }
.ck-alert{ color:#a3323f; background:rgba(217,75,89,.14); margin-left:var(--tf-space-4); }
.ck-chan{ color:var(--tf-violet-600,#6d5dfb); background:rgba(109,93,251,.12); }

/* inline "Change" next to the handling bot — a link, not a competing button */
.cm-chbot{ background:none; border:none; padding:0 0 0 var(--tf-space-4); cursor:pointer;
  font:inherit; font-size:var(--tf-font-body-sm); color:var(--tf-color-accent);
  text-decoration:underline; }

/* ---------- Bot welcome-button rows ---------- */
/* Each menu screen is its own card; a nested one is nudged in and marked with a
   rail, so the relationship reads without having to measure indentation. */
.bmn-card + .bmn-card{ margin-left:var(--tf-space-24);
  border-left:3px solid var(--tf-color-accent, #2f6fd0); }
.bmn-auto{ margin-top:var(--tf-space-8); padding:var(--tf-space-8) var(--tf-space-12);
  border:1px dashed var(--tf-color-hairline); border-radius:var(--tf-radius-control);
  color:var(--tf-color-text-secondary); font-size:var(--tf-font-body-sm); }

.bmn-row{ display:flex; align-items:center; gap:var(--tf-space-12);
  padding:var(--tf-space-12); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-control); margin-bottom:var(--tf-space-8); }
.bmn-ord{ display:flex; flex-direction:column; gap:2px; flex:none; }
.bmn-ord button{ min-width:28px; padding:0 var(--tf-space-4); line-height:1.4; }
.bmn-main{ flex:1; min-width:0; }
.bmn-main .muted{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* ---------- Vertical rhythm between stacked blocks ----------
   Several block types carry a bottom margin but no top one (.panel), or no
   margin at all (.kpis, .seg, .tbl-wrap), so two of them in a row ended up
   touching. Sibling-only rules fix that without side effects: an element that
   sets its own margin inline still wins, the first block in a view stays flush,
   and adjacent margins collapse so nothing doubles up. */
.kpis + .panel,    .kpis + .kpis,     .kpis + .tbl-wrap, .kpis + .stack,
.kpis + .filters,  .kpis + .seg,      .kpis + .bulk-bar, .kpis + .empty,
.seg + .panel,     .seg + .kpis,      .seg + .tbl-wrap,  .seg + .stack,
.seg + .filters,   .seg + .empty,
.tbl-wrap + .panel, .tbl-wrap + .kpis, .tbl-wrap + .stack, .tbl-wrap + .tbl-wrap,
.stack + .panel,   .stack + .kpis,    .stack + .tbl-wrap,
.filters + .tbl-wrap, .filters + .kpis, .filters + .stack, .filters + .panel,
.panel + .kpis,    .panel + .tbl-wrap, .panel + .stack,   .panel + .seg,
.bulk-bar + .tbl-wrap, .empty + .panel{
  margin-top:var(--tf-space-24);
}

/* ---------- Metric cards ---------- */
.kpis{ display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:var(--tf-space-16); }
.kpi{ border-radius:var(--tf-radius-card); padding:var(--tf-space-20); }
.kpi-top{ display:flex; align-items:center; gap:var(--tf-space-8); margin-bottom:var(--tf-space-12); }
.kpi-ic{ display:none; }
.kpi-ic-hidden{ display:none; }
.kpi-label{ font-size:var(--tf-font-label); text-transform:uppercase; letter-spacing:.05em;
  color:var(--tf-color-text-secondary); font-weight:500; line-height:var(--tf-leading-caption); }
.kpi-value{ font-size:var(--tf-font-metric); font-weight:600; letter-spacing:-.02em;
  line-height:var(--tf-leading-tight); font-variant-numeric:tabular-nums; }
.kpi.accent .kpi-value{ color:var(--tf-color-ai); }
.kpi-delta{ margin-top:var(--tf-space-8); font-size:var(--tf-font-body-sm); font-weight:500;
  color:var(--tf-color-success); }
.kpi-delta.flat{ color:var(--tf-color-text-tertiary); }

/* ---------- Schedule progress ---------- */
.kpis-sm{ grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); }
.kpis-sm .kpi-value{ font-size:var(--tf-font-h2); }
.progc{ display:flex; align-items:center; gap:var(--tf-space-12); }
.frac{ font-weight:600; min-width:44px; font-variant-numeric:tabular-nums; }
.frac.done{ color:var(--tf-color-success); }
.prog{ flex:1; min-width:80px; height:8px; background:var(--tf-cloud-200);
  border-radius:var(--tf-radius-pill); overflow:hidden; }
.prog-fill{ height:100%; background:linear-gradient(90deg,var(--tf-blue-500),var(--tf-violet-500));
  border-radius:var(--tf-radius-pill); transition:width var(--tf-motion-standard) var(--tf-ease-spring); }
.queue-details{ margin-top:var(--tf-space-24); border-radius:var(--tf-radius-card);
  padding:var(--tf-space-16) var(--tf-space-24); }
.queue-details summary{ cursor:pointer; font-weight:500; font-size:var(--tf-font-body);
  color:var(--tf-color-text-secondary); }
.queue-details summary:hover{ color:var(--tf-color-text-primary); }
.queue-details[open] summary{ color:var(--tf-color-text-primary); margin-bottom:var(--tf-space-8); }

/* ---------- Segmented control ---------- */
.seg{ display:inline-flex; gap:var(--tf-space-4); background:var(--tf-glass-fill-subtle);
  border:1px solid var(--tf-glass-border); border-radius:var(--tf-radius-control);
  padding:var(--tf-space-4); flex-wrap:wrap;
  -webkit-backdrop-filter:blur(var(--tf-glass-blur)); backdrop-filter:blur(var(--tf-glass-blur)); }
.seg-btn{ background:transparent; border:none; color:var(--tf-color-text-secondary); font-weight:500;
  font-size:var(--tf-font-body-sm); padding:var(--tf-space-8) var(--tf-space-16);
  border-radius:var(--tf-space-8); cursor:pointer; font-family:inherit; min-height:36px;
  transition:background var(--tf-motion-fast) var(--tf-ease-spring), color var(--tf-motion-fast) linear; }
.seg-btn:hover{ color:var(--tf-color-text-primary); background:var(--tf-glass-fill-subtle); }
.seg-btn.active{ background:var(--tf-white); color:var(--tf-color-text-primary); font-weight:600;
  box-shadow:var(--tf-shadow-press); }
.tab.disabled{ opacity:.4; pointer-events:none; }

/* ---------- Welcome tour + guide page ---------- */
/* Wider than a form dialog: this one is read, not filled in, and at 560px the
   Chinese intro broke into three cramped lines. Doubled-up selector on purpose —
   plain `.modal-tour` ties with `.modal{width:560px}`, which is declared later
   in this file and would quietly win. */
.modal.modal-tour{ width:660px; }
/* Shared by the tour dialog and the guide page, so the base rule carries only
   rhythm. The gutter belongs to the dialog alone — the page already sits inside
   a .panel that has its own padding, and adding it here would double it up. */
.tr-list{ display:flex; flex-direction:column; gap:var(--tf-space-20); }
/* In the dialog the list is what scrolls, so it needs the side gutter the head
   has (without it the text sits flush against the glass edge while the title is
   indented — that mismatch is what read as "narrow") plus min-height:0, or a
   long step pushes the buttons off the bottom instead of scrolling. */
.modal-tour .tr-list{ padding:var(--tf-space-24) var(--tf-space-32);
  overflow-y:auto; min-height:0; }
.tr-item{ display:flex; flex-direction:column; gap:var(--tf-space-4); }
.tr-k{ font-weight:600; font-size:var(--tf-font-body); line-height:1.5;
  color:var(--tf-color-text-primary); }
.tr-v{ font-size:var(--tf-font-body-sm); color:var(--tf-color-text-secondary);
  line-height:1.7; }

.tr-foot{ display:flex; align-items:center; justify-content:space-between;
  gap:var(--tf-space-16); flex-wrap:wrap;
  padding:var(--tf-space-16) var(--tf-space-32) var(--tf-space-24);
  border-top:1px solid var(--tf-color-hairline); }
.tr-dots{ display:flex; gap:var(--tf-space-8); }
.tr-dot{ width:7px; height:7px; border-radius:50%;
  background:var(--tf-color-hairline); transition:background var(--tf-motion-fast) linear; }
.tr-dot.on{ background:var(--tf-violet-600,#6d5dfb); }
.tr-btns{ display:flex; gap:var(--tf-space-8); margin-left:auto; }

.modal-tour .modal-head{ padding:var(--tf-space-32) var(--tf-space-32) var(--tf-space-20); }
.modal-tour .modal-head h3{ margin-bottom:var(--tf-space-8); }
.modal-tour .modal-head .muted{ line-height:1.7; max-width:58ch; }
/* #tr-body wraps head/list/foot, so it has to be the flex column the modal's
   own max-height expects — otherwise the list can't scroll and a long step
   pushes the buttons off the bottom of the screen. */
.modal-tour > #tr-body{ display:flex; flex-direction:column; min-height:0; }

@media (max-width:700px){
  /* Scoped the same way as the rule above, or it would both leak onto the guide
     page and lose to `.modal-tour .tr-list` on specificity anyway. */
  .modal-tour .tr-list{ padding:var(--tf-space-20) var(--tf-space-24); }
  .tr-foot{ padding:var(--tf-space-16) var(--tf-space-24) var(--tf-space-20); }
  .modal-tour .modal-head{ padding:var(--tf-space-24) var(--tf-space-24) var(--tf-space-16); }
}
@media (max-width:520px){
  .tr-foot{ flex-direction:column; align-items:stretch; }
  .tr-btns{ margin-left:0; }
  .tr-btns .btn-primary, .tr-btns .btn-ghost{ flex:1; }
}

/* ---------- Date range picker (group Overview + Members) ---------- */
.dr{ display:flex; align-items:center; gap:var(--tf-space-16); flex-wrap:wrap;
  margin-bottom:var(--tf-space-20); }
.dr-custom{ display:flex; align-items:center; gap:var(--tf-space-8); }
.dr-arrow{ color:var(--tf-color-text-secondary); font-size:var(--tf-font-body-sm); }
/* Native date inputs are narrow by default and the calendar glyph crowds the
   text, so they get a floor width rather than the shared input sizing. */
.dr-custom input[type=date]{ min-width:150px; min-height:36px;
  padding:var(--tf-space-8) var(--tf-space-12); }
@media (max-width:640px){
  .dr{ gap:var(--tf-space-12); }
  .dr-custom{ width:100%; }
  .dr-custom input[type=date]{ flex:1; min-width:0; }
}

/* ---------- Connection widgets ---------- */
.conn-card .row-between{ flex-wrap:wrap; gap:var(--tf-space-12); }
#wa-conn-line,#tg-conn-line{ font-size:var(--tf-font-body); }
#wa-conn-line code,#tg-conn-line code{ background:var(--tf-cloud-200); padding:2px 7px;
  border-radius:6px; font-family:var(--tf-font-mono); font-size:.85em; }
.conn-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--tf-space-16) var(--tf-space-20); }
@media (max-width:820px){ .conn-grid{ grid-template-columns:1fr; } }

/* ---------- WhatsApp (hidden from nav, styles kept) ---------- */
.wa-banner{ border-radius:var(--tf-radius-control); padding:var(--tf-space-12) var(--tf-space-16);
  font-size:var(--tf-font-body-sm); margin-bottom:var(--tf-space-20); border:1px solid var(--tf-color-hairline); }
.wa-banner.ok{ background:rgba(46,155,101,.10); border-color:rgba(46,155,101,.30); }
.wa-banner.warn{ background:rgba(189,116,17,.10); border-color:rgba(189,116,17,.30); }
.wa-banner code{ background:var(--tf-cloud-200); padding:2px 7px; border-radius:6px; }
.wa-phone{ background:var(--tf-cloud-100); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-card); padding:var(--tf-space-16); min-height:130px; }
.wa-bubble{ background:#DCF8C6; color:#0f2a16; border-radius:14px 14px 4px 14px;
  padding:var(--tf-space-8) var(--tf-space-12); max-width:88%; margin-left:auto;
  line-height:var(--tf-leading-body); font-size:var(--tf-font-body-sm);
  box-shadow:var(--tf-shadow-press); word-break:break-word; }
.wa-bubble .wa-time{ display:block; text-align:right; font-size:var(--tf-font-label);
  color:#4c7a55; margin-top:var(--tf-space-4); }
.wa-setup ol{ margin:var(--tf-space-8) 0 var(--tf-space-12); padding-left:20px;
  line-height:1.7; font-size:var(--tf-font-body-sm); }
.wa-setup li{ margin-bottom:var(--tf-space-8); }
.wa-setup pre{ background:var(--tf-cloud-100); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-space-8); padding:var(--tf-space-12); font-size:var(--tf-font-body-sm);
  overflow-x:auto; margin:var(--tf-space-8) 0; color:var(--tf-color-text-primary); }
.wa-setup code,.wa-setup pre{ font-family:var(--tf-font-mono); }
.wa-setup code{ background:var(--tf-cloud-200); padding:2px 7px; border-radius:6px; font-size:.85em; }

/* ---------- Bars ---------- */
.bars{ display:flex; align-items:flex-end; gap:var(--tf-space-20); height:200px; padding:var(--tf-space-8) var(--tf-space-4) 0; }
.bar-col{ flex:1; display:flex; flex-direction:column; align-items:center; gap:var(--tf-space-8);
  height:100%; justify-content:flex-end; }
.bar{ width:100%; max-width:54px; background:linear-gradient(180deg,var(--tf-blue-500),var(--tf-violet-500));
  border-radius:var(--tf-space-8) var(--tf-space-8) 0 0; min-height:4px; }
.bar-val{ font-size:var(--tf-font-body-sm); color:var(--tf-color-text-primary); font-weight:600;
  font-variant-numeric:tabular-nums; }
.bar-lab{ font-size:var(--tf-font-label); color:var(--tf-color-text-secondary); text-align:center; white-space:nowrap; }

/* ---------- Click cards ---------- */
.clicks{ display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:var(--tf-space-16); }
.click-card{ border-radius:var(--tf-radius-card); padding:var(--tf-space-20); }
.click-card .spark{ margin-top:var(--tf-space-8); }

/* ---------- Tables ---------- */
.tbl-wrap{ border-radius:var(--tf-radius-card); overflow-x:auto; }
.tbl th,.tbl td{ white-space:nowrap; }
table.tbl{ width:100%; border-collapse:separate; border-spacing:0; font-size:var(--tf-font-body-sm); }
.tbl th{ text-align:left; text-transform:uppercase; letter-spacing:.05em; font-size:var(--tf-font-label);
  color:var(--tf-color-text-secondary); font-weight:600; padding:var(--tf-space-12) var(--tf-space-20);
  border-bottom:1px solid var(--tf-color-hairline); background:transparent; }
.tbl td{ padding:var(--tf-space-12) var(--tf-space-20); border-bottom:1px solid var(--tf-color-hairline);
  color:var(--tf-color-text-primary); vertical-align:middle; }
.tbl tr:last-child td{ border-bottom:none; }
.tbl tbody tr{ transition:background var(--tf-motion-fast) linear; }
.tbl tbody tr:hover td{ background:var(--tf-glass-fill-subtle); }
.tbl tbody tr:hover td:first-child{ border-radius:var(--tf-radius-control) 0 0 var(--tf-radius-control); }
.tbl tbody tr:hover td:last-child{ border-radius:0 var(--tf-radius-control) var(--tf-radius-control) 0; }
.mono{ font-family:var(--tf-font-mono); color:var(--tf-color-text-secondary);
  font-size:.92em; font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
.num{ font-variant-numeric:tabular-nums; }
/* data columns line up: figures in tables are always tabular */
.tbl td,.tbl th{ font-variant-numeric:tabular-nums; }

/* ---------- Badges (always paired with a label, never colour alone) ---------- */
.badge{ display:inline-block; padding:3px 10px; border-radius:var(--tf-radius-pill);
  font-size:var(--tf-font-label); font-weight:500; letter-spacing:.01em; }
.b-active,.b-sent{ color:#1f6b47; background:rgba(46,155,101,.14); }
.b-pending{ color:#8a540c; background:rgba(189,116,17,.14); }
.b-blocked,.b-failed,.b-error,.b-inactive{ color:#a3323f; background:rgba(217,75,89,.14); }
.b-cancelled,.b-optedout{ color:#2a5fa8; background:rgba(58,131,232,.14); }
.b-converted{ color:#4a3ec4; background:rgba(109,93,251,.14); }
.b-reply{ color:#2a5fa8; background:rgba(58,131,232,.14); }
.src-tag{ display:inline-block; padding:2px 10px; border-radius:var(--tf-radius-pill);
  font-size:var(--tf-font-label); font-weight:500; color:var(--tf-color-text-secondary);
  background:var(--tf-cloud-100); border:1px solid var(--tf-color-hairline); white-space:nowrap; }
.tags-box{ display:flex; flex-wrap:wrap; gap:var(--tf-space-8); }

/* ---------- Modal / sheet / popover ---------- */
#ct-table tbody tr{ cursor:pointer; }
.modal-overlay{ position:fixed; inset:0; background:rgba(21,22,26,.28);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  display:flex; align-items:center; justify-content:center; z-index:100; padding:var(--tf-space-24);
  animation:fadein var(--tf-motion-fast) var(--tf-ease-enter); }
@keyframes fadein{ from{ opacity:0 } to{ opacity:1 } }
.modal{ border-radius:var(--tf-radius-panel); width:560px; max-width:100%; max-height:84vh;
  display:flex; flex-direction:column; background:var(--tf-glass-fill-strong);
  /* the crisp lit edge is what makes a glass panel read as glass rather than
     as a plain grey box floating on a blur */
  border:1px solid var(--tf-glass-border);
  -webkit-backdrop-filter:blur(var(--tf-glass-blur-heavy)) saturate(180%);
  backdrop-filter:blur(var(--tf-glass-blur-heavy)) saturate(180%);
  box-shadow:var(--tf-shadow-overlay), inset 0 1px 0 var(--tf-glass-highlight);
  animation:modalin var(--tf-motion-standard) var(--tf-ease-enter); }
@keyframes modalin{ from{ opacity:0; transform:translateY(10px) scale(.985) } to{ opacity:1; transform:none } }
.modal-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--tf-space-12);
  padding:var(--tf-space-24) var(--tf-space-24) var(--tf-space-16); border-bottom:1px solid var(--tf-color-hairline); }
.modal-head h3{ margin:0 0 var(--tf-space-4); font-size:var(--tf-font-h3); font-weight:600; }
.modal-close{ background:transparent; border:none; color:var(--tf-color-text-secondary);
  font-size:var(--tf-font-body); cursor:pointer; line-height:1; padding:var(--tf-space-8);
  border-radius:var(--tf-space-8); min-width:36px; min-height:36px; }
.modal-close:hover{ background:var(--tf-cloud-100); color:var(--tf-color-text-primary); }
.modal-sub{ display:flex; align-items:center; gap:var(--tf-space-12); flex-wrap:wrap;
  padding:var(--tf-space-12) var(--tf-space-24); border-bottom:1px solid var(--tf-color-hairline); }
.tl{ padding:var(--tf-space-20) var(--tf-space-24) var(--tf-space-24); overflow-y:auto; }
/* Form rhythm inside a dialog: a label that follows a control needs air above
   it, otherwise fields run together in one grey block. */
.tl input + .field-label, .tl textarea + .field-label, .tl select + .field-label,
.tl .seg + .field-label, .tl .uploader + .field-label, .tl div + .field-label{
  margin-top:var(--tf-space-20); }
.tl .seg{ width:100%; }
.tl .seg .seg-btn{ flex:1; }
.tl-item{ border-left:2px solid var(--tf-color-hairline); padding:0 0 var(--tf-space-20) var(--tf-space-16);
  position:relative; }
.tl-item:last-child{ padding-bottom:2px; }
.tl-item::before{ content:""; position:absolute; left:-5px; top:6px; width:8px; height:8px;
  border-radius:50%; background:var(--tf-color-text-tertiary); }
.tl-item.sent{ border-left-color:rgba(46,155,101,.45); }
.tl-item.sent::before{ background:var(--tf-color-success); }
.tl-item.failed,.tl-item.blocked{ border-left-color:rgba(217,75,89,.45); }
.tl-item.failed::before,.tl-item.blocked::before{ background:var(--tf-color-danger); }
.tl-item.inbound{ border-left-color:rgba(58,131,232,.45); }
.tl-item.inbound::before{ background:var(--tf-color-info); }
.tl-msg{ margin-top:var(--tf-space-8); font-size:var(--tf-font-body); line-height:var(--tf-leading-body);
  white-space:pre-wrap; word-break:break-word; }
.tl-msg.in{ background:var(--tf-white); border:1px solid var(--tf-color-hairline);
  border-radius:4px 14px 14px 14px; padding:var(--tf-space-8) var(--tf-space-12);
  display:inline-block; max-width:90%; }
.modal-foot{ display:flex; align-items:center; justify-content:space-between; gap:var(--tf-space-12);
  padding:var(--tf-space-16) var(--tf-space-24); border-top:1px solid var(--tf-color-hairline); }
.modal.modal-lg{ width:720px; }
/* Same body treatment as .tl — the campaign builder was the odd one out. */
.cmp-modal-body{ padding:var(--tf-space-20) var(--tf-space-24) var(--tf-space-24); overflow-y:auto; }

/* Most dialogs keep their Save/Cancel row inside the scrolling body rather than
   in a real .modal-foot. Give that last row the same rule and breathing space
   so every dialog closes with an identical action bar. */
.tl > .tile-actions:last-child,
.cmp-modal-body > .tile-actions:last-child{
  margin-top:var(--tf-space-24); padding-top:var(--tf-space-20);
  border-top:1px solid var(--tf-color-hairline);
  /* Those rows are written [Primary][Cancel]; the real footers put the primary
     on the right. Reversing here lines every dialog up the same way — confirm
     on the right — without rewriting nine blocks of markup. */
  flex-direction:row-reverse; justify-content:flex-start; }

/* Dialog buttons are touch-sized and never squeezed by a narrow field row. */
.modal .tile-actions .btn-primary,.modal .tile-actions .btn-ghost,
.modal-foot .btn-primary,.modal-foot .btn-ghost{ min-height:42px; padding-left:var(--tf-space-20);
  padding-right:var(--tf-space-20); }

/* two-way chat composer inside the contact sheet */
.chat-compose{ display:flex; gap:var(--tf-space-8); align-items:flex-end;
  padding:var(--tf-space-16) var(--tf-space-24); border-top:1px solid var(--tf-color-hairline); }
.chat-compose textarea{ flex:1; min-height:44px; resize:vertical; }

/* ---------- Campaign sequence rows ---------- */
.cmp-seq{ display:flex; flex-direction:column; gap:var(--tf-space-8); }
.seq-row{ display:flex; align-items:center; gap:var(--tf-space-12); background:var(--tf-white);
  border:1px solid var(--tf-color-hairline); border-radius:var(--tf-radius-control);
  padding:var(--tf-space-8) var(--tf-space-12); }
.seq-n{ width:24px; height:24px; flex:none; border-radius:50%; background:var(--tf-color-accent);
  color:var(--tf-white); font-weight:600; font-size:var(--tf-font-label); display:flex;
  align-items:center; justify-content:center; }
.seq-name{ flex:1; font-size:var(--tf-font-body-sm); font-weight:500; }
.seq-day{ display:flex; align-items:center; gap:var(--tf-space-8); font-size:var(--tf-font-body-sm);
  color:var(--tf-color-text-secondary); }
.seq-day input{ width:68px; padding:var(--tf-space-8); text-align:center; }
.seq-actions{ display:flex; gap:var(--tf-space-4); }
.seq-grip{ flex:none; display:flex; align-items:center; justify-content:center; width:20px; height:26px;
  color:var(--tf-color-text-tertiary); cursor:grab; border-radius:6px; touch-action:none; }
.seq-grip:hover{ color:var(--tf-color-text-primary); background:var(--tf-cloud-100); }
.seq-grip:active{ cursor:grabbing; }
.seq-grip .grip-ic{ pointer-events:none; }
.seq-row.lift{ box-sizing:border-box; box-shadow:var(--tf-shadow-float);
  border-color:var(--tf-color-accent); transform:scale(1.015); }
.seq-ph{ box-sizing:border-box; border:1.5px dashed var(--tf-color-accent);
  border-radius:var(--tf-radius-control); background:rgba(34,158,217,.06); }
.cmp-section-head{ font-size:var(--tf-font-label); font-weight:600; letter-spacing:.05em;
  text-transform:uppercase; color:var(--tf-color-text-secondary); margin:var(--tf-space-4) 0 var(--tf-space-12); }
.tile-draft{ border-style:dashed; }

/* ---------- Kebab menus (elevated glass popover) ---------- */
.kebab-wrap{ position:absolute; top:var(--tf-space-12); right:var(--tf-space-12); }
.kebab{ background:transparent; border:none; color:var(--tf-color-text-secondary);
  font-size:var(--tf-font-h3); line-height:1; cursor:pointer; padding:var(--tf-space-4) var(--tf-space-8);
  border-radius:var(--tf-space-8); min-width:36px; min-height:36px; }
.kebab:hover{ background:var(--tf-cloud-100); color:var(--tf-color-text-primary); }
.kebab-menu{ position:absolute; right:0; top:32px; background:var(--tf-glass-fill-strong);
  -webkit-backdrop-filter:blur(var(--tf-glass-blur-heavy)); backdrop-filter:blur(var(--tf-glass-blur-heavy));
  border:1px solid var(--tf-glass-border); border-radius:var(--tf-radius-card);
  box-shadow:var(--tf-shadow-overlay); padding:var(--tf-space-4); display:flex; flex-direction:column;
  gap:2px; z-index:20; min-width:150px;
  animation:popin var(--tf-motion-fast) var(--tf-ease-enter); }
@keyframes popin{ from{ opacity:0; transform:translateY(-6px) scale(.98) } to{ opacity:1; transform:none } }
.kebab-menu button{ background:transparent; border:none; color:var(--tf-color-text-primary);
  text-align:left; font-size:var(--tf-font-body-sm); font-family:inherit;
  padding:var(--tf-space-8) var(--tf-space-12); border-radius:var(--tf-space-8); cursor:pointer;
  min-height:36px; }
.kebab-menu button:hover{ background:var(--tf-cloud-100); }
.kebab-menu .km-del,.kebab-menu .rk-del{ color:var(--tf-color-danger); }

/* ---------- Contact form grid ---------- */
.cf-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--tf-space-20) var(--tf-space-20); }
.cf-field{ display:flex; flex-direction:column; }
.cf-field .field-label{ margin-bottom:var(--tf-space-8); }
.cf-field input{ width:100%; box-sizing:border-box; }
.row-actions{ text-align:right; }
.row-menu{ position:relative; display:inline-block; }
.row-menu .kebab-menu{ top:34px; }

/* ---------- Channel chooser + contact picker ---------- */
.ch-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--tf-space-12); }
.ch-btn{ display:flex; flex-direction:column; align-items:center; gap:var(--tf-space-4);
  background:var(--tf-white); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-card); padding:var(--tf-space-20) var(--tf-space-12); cursor:pointer;
  color:var(--tf-color-text-primary); font-family:inherit;
  transition:border-color var(--tf-motion-fast) linear, transform var(--tf-motion-fast) var(--tf-ease-spring); }
.ch-btn:hover{ border-color:var(--tf-color-accent); transform:scale(1.01); }
.ch-btn span{ font-size:var(--tf-font-body); font-weight:600; }
.ch-btn small{ font-size:var(--tf-font-body-sm); color:var(--tf-color-text-secondary); }
.pk-row{ display:flex; align-items:center; gap:var(--tf-space-12);
  padding:var(--tf-space-12) var(--tf-space-8); border-bottom:1px solid var(--tf-color-hairline);
  cursor:pointer; font-size:var(--tf-font-body-sm); border-radius:var(--tf-radius-control); }
.pk-row:hover{ background:var(--tf-glass-fill-subtle); }
.pk-row input{ width:auto; }
.pk-row:last-child{ border-bottom:none; }

/* ---------- Bulk bar ---------- */
.bulk-bar{ display:flex; align-items:center; gap:var(--tf-space-12); flex-wrap:wrap;
  background:var(--tf-glass-fill-strong); border:1px solid var(--tf-color-accent);
  border-radius:var(--tf-radius-card); padding:var(--tf-space-12) var(--tf-space-16);
  margin:var(--tf-space-16) 0 var(--tf-space-4); box-shadow:var(--tf-shadow-press);
  -webkit-backdrop-filter:blur(var(--tf-glass-blur)); backdrop-filter:blur(var(--tf-glass-blur)); }
.bulk-n{ font-size:var(--tf-font-body-sm); }
.chk-col{ width:40px; text-align:center; }
.chk-col input{ width:auto; cursor:pointer; }
#q-table tbody tr{ cursor:pointer; }

/* ---------- Toolbar / filters ---------- */
.toolbar{ display:flex; align-items:center; gap:var(--tf-space-12); margin-bottom:var(--tf-space-16); }
.search{ flex:1; }
.filters{ display:flex; flex-wrap:wrap; gap:var(--tf-space-12); align-items:center;
  margin-bottom:var(--tf-space-8); }
.filters select,.filters input{ width:auto; min-width:150px; }
.filters .search{ flex:1; min-width:230px; }
th[data-k]{ user-select:none; cursor:pointer; }
.row-between{ display:flex; align-items:center; justify-content:space-between; gap:var(--tf-space-12); }
.row{ display:flex; }

/* ---------- Tabs ---------- */
.tabs{ display:flex; gap:var(--tf-space-8); border-bottom:1px solid var(--tf-color-hairline);
  margin:var(--tf-space-8) 0 var(--tf-space-20); }
.tab{ padding:var(--tf-space-12) var(--tf-space-16); cursor:pointer; color:var(--tf-color-text-secondary);
  font-weight:500; font-size:var(--tf-font-body); border-bottom:2px solid transparent;
  transition:color var(--tf-motion-fast) linear, border-color var(--tf-motion-fast) linear; }
.tab:hover{ color:var(--tf-color-text-primary); }
.tab.active{ color:var(--tf-color-accent); border-bottom-color:var(--tf-color-accent); }

/* ---------- Uploader / previews ---------- */
.uploader{ margin-top:var(--tf-space-12); }
/* Thumbnails rather than one big preview: with up to ten of them, full-size
   images would push the send button off the screen. */
.up-grid{ display:flex; flex-wrap:wrap; gap:var(--tf-space-8);
  margin-bottom:var(--tf-space-12); }
.up-thumb{ position:relative; width:96px; height:96px; }
.up-thumb img{ width:100%; height:100%; object-fit:cover; display:block;
  border-radius:var(--tf-radius-control); border:1px solid var(--tf-color-hairline); }
/* The order they were attached is the order Telegram shows them in, so it is
   worth being able to see it. */
.up-num{ position:absolute; left:var(--tf-space-4); bottom:var(--tf-space-4);
  min-width:18px; height:18px; padding:0 5px; border-radius:9px;
  background:rgba(21,22,26,.66); color:var(--tf-white);
  font-size:var(--tf-font-label); line-height:18px; text-align:center; }
.up-remove{ position:absolute; top:var(--tf-space-4); right:var(--tf-space-4);
  width:24px; height:24px; display:flex; align-items:center; justify-content:center;
  border-radius:50%; background:rgba(21,22,26,.62); color:var(--tf-white); border:none;
  cursor:pointer; line-height:1; padding:0; }
.up-remove:hover{ background:var(--tf-color-danger); }
.up-remove svg{ width:13px; height:13px; }
.up-hint{ margin-top:var(--tf-space-8); }
.prev-banner{ width:100%; max-height:180px; object-fit:cover; border-radius:var(--tf-radius-control);
  margin-bottom:var(--tf-space-8); display:block; }
/* Telegram lays an album out as a tight mosaic, not a stack. Two side by side,
   three or more in a 3-wide grid — close enough to set expectations. */
/* Checkbox + explanation, sitting on one row. The label is what the whole
   block reacts to, so the text is clickable too. */
.kw-conv{ display:flex; gap:var(--tf-space-10); align-items:flex-start;
  margin-top:var(--tf-space-16); cursor:pointer; }
.kw-conv input{ margin-top:3px; flex:0 0 auto; }
.kw-conv-t{ display:block; }
.kw-conv .field-label{ margin:0 0 2px; display:block; }
.kw-conv .muted{ display:block; line-height:1.5; }

.prev-album{ display:grid; grid-template-columns:repeat(3, 1fr); gap:2px;
  border-radius:var(--tf-radius-control); overflow:hidden;
  margin-bottom:var(--tf-space-8); }
.prev-album.two{ grid-template-columns:repeat(2, 1fr); }
.prev-album img{ width:100%; height:76px; object-fit:cover; display:block; }
.prev-split{ font-size:11px; color:var(--tf-color-text-muted); text-align:center;
  margin:var(--tf-space-8) 0; position:relative; }
.prev-split::before, .prev-split::after{ content:""; position:absolute; top:50%;
  width:22%; height:1px; background:var(--tf-color-hairline); }
.prev-split::before{ left:0; } .prev-split::after{ right:0; }

.tpl-thumb{ width:100%; max-height:120px; object-fit:cover; border-radius:var(--tf-space-8);
  margin:var(--tf-space-4) 0 var(--tf-space-8); display:block; }
.pager{ display:flex; align-items:center; justify-content:center; gap:var(--tf-space-16);
  margin:var(--tf-space-20) 0 var(--tf-space-4); }
.camp-preview{ margin-top:var(--tf-space-12); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-control); padding:var(--tf-space-12); background:var(--tf-cloud-100);
  max-height:340px; overflow:auto; }
.camp-prev-head{ font-weight:600; font-size:var(--tf-font-body-sm); margin-bottom:var(--tf-space-8); }
.camp-prev-step{ border:1px solid var(--tf-color-hairline); border-radius:var(--tf-space-12);
  padding:var(--tf-space-12); margin-bottom:var(--tf-space-8); background:var(--tf-white); }
.camp-prev-step:last-child{ margin-bottom:0; }
.cps-top{ display:flex; align-items:center; gap:var(--tf-space-8); margin-bottom:var(--tf-space-8); }
.cps-name{ font-weight:500; font-size:var(--tf-font-body-sm); flex:1; }
.cps-day{ flex:none; }
.cps-body{ font-size:var(--tf-font-body-sm); color:var(--tf-color-text-secondary);
  line-height:var(--tf-leading-body); white-space:pre-wrap; }
.camp-prev-step .tpl-thumb{ max-height:72px; width:auto; margin:2px 0 var(--tf-space-8); }

/* ---------- Personal Telegram: conversations | thread | customer ---------- */
.tu-grid{ display:grid; grid-template-columns:minmax(240px,300px) minmax(320px,1fr) minmax(260px,320px);
  gap:var(--tf-space-16); align-items:stretch; height:min(72vh, 780px); }
.tu-list,.tu-thread,.tu-customer{ margin-bottom:0; padding:0; display:flex; flex-direction:column;
  overflow:hidden; }
.tu-list{ padding:var(--tf-space-12); }
.tu-list .search{ flex:none; margin-bottom:var(--tf-space-8); }
.tu-dialogs{ flex:1; overflow-y:auto; display:flex; flex-direction:column; gap:2px; }
.tu-dialog{ display:flex; align-items:center; gap:var(--tf-space-12); width:100%; text-align:left;
  padding:var(--tf-space-8) var(--tf-space-12); border:none; background:transparent; cursor:pointer;
  font:inherit; border-radius:var(--tf-radius-control);
  transition:background var(--tf-motion-fast) linear; }
.tu-dialog:hover{ background:var(--tf-glass-fill-subtle); }
.tu-dialog.active{ background:var(--tf-white); box-shadow:var(--tf-shadow-press); }
.tu-avatar{ width:36px; height:36px; flex:none; border-radius:50%; display:flex; align-items:center;
  justify-content:center; font-weight:600; color:var(--tf-white); font-size:var(--tf-font-body-sm);
  background:linear-gradient(135deg,var(--tf-blue-500),var(--tf-violet-500)); }
.tu-dialog-main{ display:flex; flex-direction:column; gap:2px; min-width:0; flex:1; }
.tu-dialog-top{ display:flex; align-items:baseline; gap:var(--tf-space-8); }
.tu-dialog-name{ font-size:var(--tf-font-body-sm); font-weight:600; color:var(--tf-color-text-primary);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; }
.tu-dialog-time{ font-size:var(--tf-font-label); color:var(--tf-color-text-tertiary); flex:none; }
.tu-dialog-prev{ font-size:var(--tf-font-label); color:var(--tf-color-text-secondary);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.tu-thread-head{ flex:none; padding:var(--tf-space-16) var(--tf-space-20);
  border-bottom:1px solid var(--tf-color-hairline); }
.tu-thread-body{ flex:1; overflow-y:auto; padding:var(--tf-space-16) var(--tf-space-20);
  display:flex; flex-direction:column; gap:var(--tf-space-8); }
.tu-thread .chat-compose{ flex:none; padding:var(--tf-space-12) var(--tf-space-20); }
.tu-daysep{ text-align:center; margin:var(--tf-space-12) 0 var(--tf-space-4); }
.tu-daysep span{ font-size:var(--tf-font-label); color:var(--tf-color-text-tertiary);
  background:var(--tf-cloud-100); border-radius:var(--tf-radius-pill); padding:3px 12px; }
.tu-msg{ display:flex; flex-direction:column; align-items:flex-start; max-width:78%; }
.tu-msg.out{ align-self:flex-end; align-items:flex-end; }
.tu-bubble{ background:var(--tf-white); border:1px solid var(--tf-color-hairline);
  border-radius:14px 14px 14px 4px; padding:var(--tf-space-8) var(--tf-space-12);
  font-size:var(--tf-font-body-sm); line-height:var(--tf-leading-body);
  white-space:pre-wrap; word-break:break-word; }
.tu-msg.out .tu-bubble{ background:rgba(34,158,217,.12); border-color:rgba(34,158,217,.28);
  border-radius:14px 14px 4px 14px; }
.tu-time{ font-size:var(--tf-font-label); color:var(--tf-color-text-tertiary); margin-top:2px; }
.tu-customer{ padding:var(--tf-space-20); overflow-y:auto; }
.tu-cust-hist{ display:flex; flex-direction:column; }

@media (max-width:1280px){
  .tu-grid{ grid-template-columns:minmax(220px,280px) 1fr; height:auto; }
  .tu-customer{ grid-column:1 / -1; }
  .tu-thread{ min-height:460px; }
}
@media (max-width:820px){
  .tu-grid{ grid-template-columns:1fr; }
  .tu-list{ max-height:320px; }
}

/* ---------- Campaign builder: horizontal step timeline ---------- */
.cb-name{ font-size:var(--tf-font-h2); font-weight:600; letter-spacing:-.02em;
  border:none; background:transparent; padding:0; width:100%; }
.cb-name:focus{ outline:none; box-shadow:none; border-bottom:2px solid var(--tf-color-accent); }
.cb-timeline{ display:flex; gap:var(--tf-space-16); overflow-x:auto; padding-bottom:var(--tf-space-12);
  align-items:stretch; }
.cb-step{ flex:0 0 260px; display:flex; flex-direction:column; gap:var(--tf-space-8);
  background:var(--tf-glass-fill); border:1px solid var(--tf-glass-border);
  border-radius:var(--tf-radius-card); padding:var(--tf-space-16);
  box-shadow:var(--tf-shadow-float), inset 0 1px 0 var(--tf-glass-highlight);
  position:relative; }
/* the arrow between steps reads as "then, N days later" */
.cb-step:not(:last-child)::after{ content:"→"; position:absolute; right:calc(var(--tf-space-16) * -1 + 1px);
  top:50%; transform:translate(50%,-50%); color:var(--tf-color-text-tertiary);
  font-size:var(--tf-font-h3); pointer-events:none; }
.cb-step-head{ display:flex; align-items:center; gap:var(--tf-space-8); }
.cb-day{ width:72px; text-align:center; padding:var(--tf-space-8); }
.cb-step-name{ font-size:var(--tf-font-body); font-weight:600; }
.cb-step-prev{ flex:1; font-size:var(--tf-font-body-sm); line-height:var(--tf-leading-body);
  background:var(--tf-white); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-control); padding:var(--tf-space-12); min-height:84px; }
.cb-step-prev .tpl-thumb{ max-height:56px; margin:0 0 var(--tf-space-8); }
.cb-step-actions{ display:flex; gap:var(--tf-space-4); flex-wrap:wrap; }
.cb-step-actions .btn-sm{ padding:var(--tf-space-4) var(--tf-space-8); min-height:30px; }

/* ---------- Settings: narrow reading width ---------- */
.settings-wrap{ max-width:var(--tf-reading-max); display:flex; flex-direction:column; }

/* ---------- Delivery Center: list + detail inspector ---------- */
.dc-split{ display:grid; grid-template-columns:1fr; gap:var(--tf-space-24); align-items:start; }
.dc-split:has(.dc-inspector:not([hidden])){ grid-template-columns:1fr minmax(320px,380px); }
.dc-main{ min-width:0; }
.dc-inspector{ position:sticky; top:var(--tf-space-16); max-height:calc(100vh - var(--tf-space-48));
  display:flex; flex-direction:column; padding:0; overflow:hidden;
  animation:inspIn var(--tf-motion-standard) var(--tf-ease-enter); }
.dc-rows{ display:flex; flex-direction:column; gap:var(--tf-space-8); }
.dc-rows > div{ display:flex; justify-content:space-between; gap:var(--tf-space-16);
  font-size:var(--tf-font-body-sm); padding:var(--tf-space-8) 0;
  border-bottom:1px solid var(--tf-color-hairline); }
.dc-rows > div:last-child{ border-bottom:none; }
.insp-foot{ display:flex; gap:var(--tf-space-8); flex-wrap:wrap;
  padding:var(--tf-space-12) var(--tf-space-20); border-top:1px solid var(--tf-color-hairline); }
@media (max-width:1200px){
  .dc-split:has(.dc-inspector:not([hidden])){ grid-template-columns:1fr; }
  .dc-inspector{ position:static; max-height:none; }
}

/* ---------- Inspector panel (Delivery Center) ----------
   The contact list used to have one of these too; it opens a centred modal now,
   so what is left here is shared by the Delivery Center alone. */
@keyframes inspIn{ from{ opacity:0; transform:translateX(10px); } to{ opacity:1; transform:none; } }
.insp-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--tf-space-12);
  padding:var(--tf-space-20) var(--tf-space-20) var(--tf-space-12);
  border-bottom:1px solid var(--tf-color-hairline); }
.insp-head h3{ margin:0 0 var(--tf-space-4); font-size:var(--tf-font-h3); font-weight:600; }
.insp-sub{ display:flex; align-items:center; gap:var(--tf-space-12); flex-wrap:wrap;
  padding:var(--tf-space-12) var(--tf-space-20); border-bottom:1px solid var(--tf-color-hairline); }
.insp-body{ padding:var(--tf-space-16) var(--tf-space-20); overflow-y:auto; flex:1; }
.tbl tbody tr.row-selected td{ background:rgba(34,158,217,.10); }
.tbl tbody tr.row-selected td:first-child{ box-shadow:inset 3px 0 0 var(--tf-color-accent); }

/* ---------- Home: task-first starting point ---------- */
.home-hero{ display:flex; align-items:flex-start; justify-content:space-between;
  gap:var(--tf-space-24); flex-wrap:wrap; }
.home-greet{ font-size:var(--tf-font-h1); font-weight:600; letter-spacing:-.02em;
  line-height:var(--tf-leading-heading); margin:0; }
.home-todo{ display:flex; flex-direction:column; }
.home-todo-row{ display:flex; align-items:center; gap:var(--tf-space-12);
  padding:var(--tf-space-12) 0; border-bottom:1px solid var(--tf-color-hairline); }
.home-todo-row:last-child{ border-bottom:none; }
.home-todo-txt{ flex:1; min-width:0; font-size:var(--tf-font-body); }
.home-dot{ width:8px; height:8px; flex:none; border-radius:50%; background:var(--tf-color-accent); }
.home-dot.warn{ background:var(--tf-color-warning); }
.home-cols{ display:grid; grid-template-columns:1fr 1fr; gap:var(--tf-space-24); align-items:start; }
.home-cols .panel{ margin-bottom:var(--tf-space-24); }
.home-list{ display:flex; flex-direction:column; }
.home-list-row{ display:flex; align-items:center; gap:var(--tf-space-12);
  padding:var(--tf-space-8) 0; border-bottom:1px solid var(--tf-color-hairline); }
.home-list-row:last-child{ border-bottom:none; }
.home-list-txt{ flex:1; min-width:0; font-size:var(--tf-font-body-sm);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
@media (max-width:900px){ .home-cols{ grid-template-columns:1fr; } }

/* ---------- Create broadcast: three-pane creation workspace ---------- */
.bc-grid{ display:grid; grid-template-columns:minmax(320px,1.1fr) minmax(300px,1fr) minmax(300px,340px);
  gap:var(--tf-space-24); align-items:start; }
.bc-editor,.bc-preview,.bc-audience{ margin-bottom:0; }
.bc-body{ min-height:280px; font-size:var(--tf-font-body); }
.bc-meta{ margin-top:var(--tf-space-8); }
.bc-more{ margin-top:var(--tf-space-16); border-top:1px solid var(--tf-color-hairline);
  padding-top:var(--tf-space-12); }
.bc-more summary{ cursor:pointer; font-size:var(--tf-font-body-sm); font-weight:500;
  color:var(--tf-color-text-secondary); }
.bc-more summary:hover{ color:var(--tf-color-text-primary); }
.bc-editor-foot{ margin-top:var(--tf-space-16); border-top:1px solid var(--tf-color-hairline);
  padding-top:var(--tf-space-16); }

/* preview framed as a Telegram-like context (not a copy of the app) */
.tg-frame{ background:var(--tf-cloud-100); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-card); padding:var(--tf-space-12); }
.tg-frame-head{ display:flex; align-items:center; gap:var(--tf-space-8);
  padding:0 var(--tf-space-4) var(--tf-space-12); }
.tg-avatar{ width:28px; height:28px; flex:none; border-radius:50%; display:flex;
  align-items:center; justify-content:center; font-size:.85rem;
  background:linear-gradient(135deg,var(--tf-blue-500),var(--tf-violet-500)); }
.tg-ident{ font-size:var(--tf-font-body-sm); font-weight:600; color:var(--tf-color-text-primary); }

/* audience pane */
.bc-modes{ display:flex; flex-wrap:wrap; width:100%; }
.bc-modes .seg-btn{ flex:1 1 auto; text-align:center; }
.bc-estimate{ display:flex; align-items:center; justify-content:space-between; gap:var(--tf-space-12);
  margin:var(--tf-space-20) 0 var(--tf-space-8); padding:var(--tf-space-16);
  border-radius:var(--tf-radius-card); background:rgba(34,158,217,.08);
  border:1px solid rgba(34,158,217,.20); }
.bc-est-label{ font-size:var(--tf-font-body-sm); color:var(--tf-color-text-secondary); }
.bc-est-n{ font-size:var(--tf-font-h2); font-weight:600; color:var(--tf-color-accent-strong);
  letter-spacing:-.02em; }
.bc-audience .btn-block{ margin-top:var(--tf-space-12); }
.bc-audience input[type=datetime-local]{ margin-top:var(--tf-space-8); }

/* send confirmation summary */
.bc-review{ display:flex; flex-direction:column; gap:var(--tf-space-8);
  padding:var(--tf-space-16); border-radius:var(--tf-radius-card);
  background:var(--tf-cloud-100); border:1px solid var(--tf-color-hairline); }
.bc-review > div{ display:flex; justify-content:space-between; gap:var(--tf-space-16);
  font-size:var(--tf-font-body-sm); }

@media (max-width:1400px){
  .bc-grid{ grid-template-columns:1fr 1fr; }
  .bc-audience{ grid-column:1 / -1; }
}
@media (max-width:900px){ .bc-grid{ grid-template-columns:1fr; } }

/* ---------- Compose: editor + live Telegram preview ---------- */
.grid-2{ display:grid; grid-template-columns:1fr 1fr; gap:var(--tf-space-24); }
.preview-msg{ background:var(--tf-white); border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-card); padding:var(--tf-space-16); line-height:var(--tf-leading-body);
  box-shadow:var(--tf-shadow-press); }
.pill-btn{ display:flex; align-items:center; justify-content:center; gap:var(--tf-space-8);
  background:rgba(34,158,217,.10); border:1px solid rgba(34,158,217,.28);
  color:var(--tf-color-accent-strong); border-radius:var(--tf-radius-control);
  padding:var(--tf-space-12); margin-top:var(--tf-space-8); font-weight:500;
  font-size:var(--tf-font-body-sm); }

/* ---------- Tiles ---------- */
.stack{ display:flex; flex-direction:column; gap:var(--tf-space-12); }
.tile{ border-radius:var(--tf-radius-card); padding:var(--tf-space-20); position:relative; }
.tile h4{ margin:0 0 var(--tf-space-4); font-size:var(--tf-font-body); font-weight:600; }
.tile .snippet{ color:var(--tf-color-text-secondary); font-size:var(--tf-font-body-sm);
  line-height:var(--tf-leading-body); margin-bottom:var(--tf-space-12); }
.tile-actions{ display:flex; gap:var(--tf-space-8); flex-wrap:wrap; }
.checkbox{ display:flex; align-items:center; gap:var(--tf-space-12); margin:var(--tf-space-16) 0;
  font-size:var(--tf-font-body); cursor:pointer; }
.checkbox input{ width:auto; }

/* ---------- Toast (bottom-right safe area) ---------- */
.toast{ position:fixed; right:var(--tf-space-24); bottom:var(--tf-space-24);
  background:var(--tf-glass-fill-strong);
  -webkit-backdrop-filter:blur(var(--tf-glass-blur-heavy)); backdrop-filter:blur(var(--tf-glass-blur-heavy));
  border:1px solid var(--tf-glass-border); border-left:3px solid var(--tf-color-accent);
  border-radius:var(--tf-radius-control); padding:var(--tf-space-16) var(--tf-space-20);
  box-shadow:var(--tf-shadow-overlay); font-size:var(--tf-font-body-sm); max-width:360px; z-index:200;
  animation:slidein var(--tf-motion-standard) var(--tf-ease-enter); }
@keyframes slidein{ from{ transform:translateY(12px); opacity:0 } to{ transform:none; opacity:1 } }

/* ---------- Bot identity (avatar pulled from Telegram) ---------- */
.bot-cell{ display:flex; align-items:center; gap:var(--tf-space-12); }
.bot-ava{ flex:none; border-radius:50%; object-fit:cover; display:block;
  background:var(--tf-glass-fill-subtle); border:1px solid var(--tf-color-hairline); }
.bot-ava-fb{ display:flex; align-items:center; justify-content:center; font-weight:600;
  color:var(--tf-color-text-secondary); letter-spacing:0; }
.bot-found{ display:flex; align-items:center; gap:var(--tf-space-12); margin-top:var(--tf-space-12);
  padding:var(--tf-space-12); border-radius:var(--tf-radius-control);
  background:var(--tf-glass-fill-subtle); border:1px solid var(--tf-color-hairline); }
.bot-found-name{ font-weight:600; }

/* ---------- Delivery Center: personal run tiles ---------- */
.dc-msg{ padding:var(--tf-space-12) 0; border-bottom:1px solid var(--tf-color-hairline); }
.dc-msg:last-child{ border-bottom:none; }


.dc-job{ cursor:pointer; }
.dc-bar{ height:6px; border-radius:var(--tf-radius-pill); overflow:hidden;
  background:var(--tf-color-hairline); margin-top:var(--tf-space-8); }
.dc-bar span{ display:block; height:100%; background:var(--tf-color-success,#2e9b65);
  transition:width var(--tf-motion-standard) linear; }

/* ---------- Personal follow-up composer ---------- */
.cx-modes{ margin-bottom:var(--tf-space-20); max-width:420px; }
.px-grid{ display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:var(--tf-space-20);
  align-items:start; }
.px-item{ border:1px solid var(--tf-color-hairline); border-radius:var(--tf-radius-control);
  padding:var(--tf-space-12); margin-top:var(--tf-space-8); }
.px-item textarea{ width:100%; box-sizing:border-box; margin-top:var(--tf-space-8); }
.px-log{ max-height:220px; overflow-y:auto; margin-top:var(--tf-space-8);
  border-top:1px solid var(--tf-color-hairline); }
.px-log-row{ display:flex; justify-content:space-between; gap:var(--tf-space-8);
  padding:var(--tf-space-4) 0; font-size:var(--tf-font-body-sm);
  border-bottom:1px solid var(--tf-color-hairline); }
@media (max-width:1024px){ .px-grid{ grid-template-columns:1fr; } }

/* ---------- Personal Telegram: account strip ---------- */
.tu-accts{ display:flex; gap:var(--tf-space-8); flex-wrap:wrap;
  margin-bottom:var(--tf-space-16); }
/* Which project the selected account belongs to. Sits right under the strip so
   it clearly applies to the account above it, not to the page. */
.tu-proj{ display:flex; align-items:center; gap:var(--tf-space-12); flex-wrap:wrap;
  margin:calc(var(--tf-space-8) * -1) 0 var(--tf-space-16); }
.tu-proj select{ width:auto; min-width:190px; }
.tu-acct{ display:flex; align-items:center; gap:var(--tf-space-8); cursor:pointer;
  padding:var(--tf-space-8) var(--tf-space-16); border-radius:var(--tf-radius-pill);
  border:1px solid var(--tf-color-hairline); background:transparent; font-family:inherit;
  font-size:var(--tf-font-body-sm); color:var(--tf-color-text-primary); }
.tu-acct:hover{ background:var(--tf-glass-fill-subtle); }
.tu-acct.active{ background:var(--tf-white,#fff); border-color:transparent;
  box-shadow:var(--tf-shadow-overlay); font-weight:600; }
.tu-acct-dot{ width:8px; height:8px; border-radius:50%; flex:none; }
.tu-acct-dot.on{ background:var(--tf-color-success,#2e9b65); }
.tu-acct-dot.off{ background:var(--tf-color-hairline); }
.tu-acct-name{ white-space:nowrap; }
.tu-acct-add{ border-style:dashed; color:var(--tf-color-text-secondary); }

/* ---------- Rich message editor ---------- */
.rt-wrap{ border:1px solid var(--tf-color-hairline); border-radius:var(--tf-radius-control);
  overflow:hidden; background:var(--tf-color-surface, transparent); }
.rt-small .rt-body{ min-height:110px; }
.rt-body{ min-height:200px; max-height:420px; overflow-y:auto; padding:var(--tf-space-16);
  font-size:var(--tf-font-body); line-height:var(--tf-leading-body); outline:none;
  white-space:pre-wrap; word-break:break-word; color:var(--tf-color-text-primary); }
.rt-body:empty::before{ content:attr(data-ph); color:var(--tf-color-text-secondary); }
.rt-body code{ font-family:var(--tf-font-mono); font-size:.92em;
  background:var(--tf-glass-fill-subtle); padding:1px 4px; border-radius:4px; }
.rt-body a{ color:var(--tf-color-accent, #2f6fd0); text-decoration:underline; }
.rt-bar{ display:flex; align-items:center; gap:2px; flex-wrap:wrap;
  padding:var(--tf-space-8); border-top:1px solid var(--tf-color-hairline);
  background:var(--tf-glass-fill-subtle); }
/* ---------- Inline SVG icons ---------- */
/* Icons replaced emoji on toolbars and buttons. Emoji are text: they inherit a
   font, carry their own colour, and land on a baseline — so they sat slightly
   low and drew in full colour against a flat panel. These are artwork that
   inherits currentColor and centres properly. */
.ic{ display:block; flex:none; }
/* The buttons holding them were laid out for a text glyph. */
.rt-btn, .modal-close{ display:inline-flex; align-items:center; justify-content:center; }
.ms-row-ic{ display:flex; align-items:center; color:var(--tf-color-text-secondary); }
.rt-btn{ min-width:32px; height:30px; padding:0 var(--tf-space-8); border:none; cursor:pointer;
  background:transparent; border-radius:var(--tf-radius-control);
  color:var(--tf-color-text-primary); font-size:var(--tf-font-body-sm); line-height:1; }
.rt-btn:hover{ background:var(--tf-glass-fill-strong, rgba(0,0,0,.06)); }
.rt-sep{ width:1px; height:18px; margin:0 var(--tf-space-4);
  background:var(--tf-color-hairline); }
/* Spoiler: shown blurred in the editor and preview, like Telegram does. */
.tg-spoiler{ background:var(--tf-glass-fill-strong, rgba(0,0,0,.12)); border-radius:4px;
  padding:0 2px; }

/* ---------- Interaction buttons ---------- */
.btn-rows{ display:flex; flex-direction:column; gap:var(--tf-space-8); }
.btn-row{ display:flex; gap:var(--tf-space-8); align-items:center; }
.btn-row input{ flex:1; min-width:0; }
.btn-row .br-del{ flex:none; }
.pill-btn.reply{ border-style:dashed; }

/* ---------- Toggle switch ---------- */
.sw-row{ display:flex; align-items:center; gap:var(--tf-space-12); cursor:pointer;
  padding:var(--tf-space-8) 0; font-size:var(--tf-font-body-sm); }
.sw{ position:relative; flex:none; width:38px; height:22px; }
.sw input{ position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer; }
.sw-track{ position:absolute; inset:0; border-radius:var(--tf-radius-pill);
  background:var(--tf-color-hairline); transition:background var(--tf-motion-fast) linear;
  pointer-events:none; }
.sw-track::after{ content:""; position:absolute; top:3px; left:3px; width:16px; height:16px;
  border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.25);
  transition:transform var(--tf-motion-fast) var(--tf-ease-enter); }
.sw input:checked + .sw-track{ background:var(--tf-color-success, #2e9b65); }
.sw input:checked + .sw-track::after{ transform:translateX(16px); }

/* ---------- Group picker (broadcast → Groups) ---------- */
.grp-list{ max-height:260px; overflow-y:auto; border:1px solid var(--tf-color-hairline);
  border-radius:var(--tf-radius-control); padding:var(--tf-space-4); }
.grp-item{ display:flex; align-items:center; gap:var(--tf-space-8); margin:0;
  padding:var(--tf-space-8) var(--tf-space-8); border-radius:var(--tf-radius-control);
  cursor:pointer; font-size:var(--tf-font-body-sm); }
.grp-item:hover{ background:var(--tf-glass-fill-subtle); }
.grp-name{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.grp-type{ flex:none; }

/* ---------- Empty / loading states ---------- */
.empty{ color:var(--tf-color-text-secondary); padding:var(--tf-space-32) var(--tf-space-8);
  text-align:center; font-size:var(--tf-font-body); }

/* ---------- Responsive ---------- */
@media (max-width:1024px){
  .view{ padding:var(--tf-space-16) var(--tf-space-24) var(--tf-space-48); }
  .topbar{ padding:var(--tf-space-20) var(--tf-space-24) 0; }
  .grid-2{ grid-template-columns:1fr; }
}
@media (max-width:820px){
  .app{ grid-template-columns:1fr; }
  .sidebar{ position:static; height:auto; width:auto; margin:var(--tf-space-12);
    flex-direction:row; flex-wrap:wrap; align-items:center; gap:var(--tf-space-8);
    border-radius:var(--tf-radius-panel); }
  .brand{ padding:var(--tf-space-4) var(--tf-space-8); }
  .nav{ flex-direction:row; flex-wrap:wrap; flex:1 1 100%; overflow:visible; }
  .nav a{ min-height:40px; }
  .nav-group{ width:100%; padding:var(--tf-space-8) var(--tf-space-8) 0; }
  .sidebar-foot{ flex:1 1 100%; flex-direction:row; flex-wrap:wrap; border-top:none; padding-top:0; }
  .sidebar-foot .btn-block{ width:auto; flex:1; }
  #whoami{ flex:1 1 100%; border-bottom:none; }
  .cf-grid,.ch-grid{ grid-template-columns:1fr; }
  .view{ padding:var(--tf-space-12) var(--tf-space-16) var(--tf-space-48); }
  .topbar{ padding:var(--tf-space-16) var(--tf-space-16) 0; }
  .modal-overlay{ padding:var(--tf-space-12); }
  .btn-sm{ min-height:36px; }
}

/* ---------- Reduced motion / transparency ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important; }
  .btn-primary:hover,.btn-ghost:hover,.ch-btn:hover,.nav a:active,.seq-row.lift{ transform:none !important; }
}
@media (prefers-reduced-transparency:reduce){
  .panel,.card,.kpi,.tbl-wrap,.click-card,.tile,.queue-details,.modal,.login-card,.sidebar,
  .kebab-menu,.toast,.bulk-bar,.seg{
    background:var(--tf-white) !important;
    -webkit-backdrop-filter:none !important; backdrop-filter:none !important; }
  body::before,body::after{ opacity:.5; }
}
