/* =====================================================================
   WhatsApp Business Console — styles  (Finup-inspired light SaaS UI)
   ===================================================================== */
:root{
  --blue:#155EEF; --blue-dark:#004EEB; --blue-soft:#EFF4FF; --blue-border:#B2CCFF;
  --ink:#181D27; --ink2:#343846; --ink3:#414651; --muted:#70778F;
  --line:#DEE1ED; --line2:#C8CCDA; --panel:#F2F3F8; --bg:#FFFFFF; --surface:#FFFFFF;
  --green:#079455; --green-soft:#ECFDF3; --green-border:#A6F4C5;
  --amber:#B54708; --amber-soft:#FFFAEB; --amber-border:#FEDF89;
  --red:#D92D20; --red-soft:#FEF3F2; --red-border:#FECDCA;
  --purple:#6938EF;
  --shadow:0 1px 2px rgba(10,13,18,.05);
  --shadow-btn:inset 0 0 0 1px rgb(10 13 18 / 43%),0 1px 2px rgba(10,13,18,.05);
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{font-family:Inter,sans-serif;color:var(--ink);background:var(--bg);
  -webkit-font-smoothing:antialiased}
button{font-family:inherit;cursor:pointer}
input,select,textarea{font-family:inherit}
a{color:var(--blue);text-decoration:none}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:var(--line2);border-radius:8px}

/* ---------- auth screen --------------------------------------------- */
.auth-wrap{min-height:100vh;display:grid;grid-template-columns:1.05fr .95fr}
.auth-art{background:linear-gradient(155deg,var(--blue),var(--blue-dark) 60%,#0B1B5C);
  color:#fff;padding:56px;display:flex;flex-direction:column;justify-content:space-between;
  position:relative;overflow:hidden}
.auth-art::after{content:"";position:absolute;width:520px;height:520px;border-radius:50%;
  right:-180px;top:-160px;background:radial-gradient(circle,rgba(255,255,255,.16),transparent 70%)}
.auth-brand{display:flex;align-items:center;gap:10px;font-weight:700;font-size:18px;z-index:1}
.auth-brand .logo{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;
  background:rgba(255,255,255,.16)}
.auth-headline{z-index:1}
.auth-headline h1{font-size:38px;line-height:1.15;font-weight:700;letter-spacing:-.02em}
.auth-headline p{margin-top:14px;font-size:16px;line-height:1.6;color:rgba(255,255,255,.8);
  max-width:420px}
.auth-points{z-index:1;display:flex;flex-direction:column;gap:12px}
.auth-point{display:flex;align-items:center;gap:10px;font-size:14px;color:rgba(255,255,255,.9)}
.auth-point .dot{width:22px;height:22px;border-radius:50%;background:rgba(255,255,255,.16);
  display:grid;place-items:center;flex-shrink:0}
.auth-form{display:flex;align-items:center;justify-content:center;padding:40px}
.auth-card{width:100%;max-width:392px}
.auth-card h2{font-size:24px;font-weight:700;letter-spacing:-.01em}
.auth-card .sub{color:var(--muted);margin-top:6px;font-size:14px}
.auth-card form{margin-top:24px;display:flex;flex-direction:column;gap:14px}
.auth-switch{margin-top:18px;font-size:14px;color:var(--muted);text-align:center}
.auth-switch b{color:var(--blue);cursor:pointer}
/* social sign-in */
.oauth-sep{display:flex;align-items:center;gap:12px;margin:18px 0 14px;color:var(--muted);font-size:12.5px;text-transform:uppercase;letter-spacing:.04em}
.oauth-sep::before,.oauth-sep::after{content:"";flex:1;height:1px;background:var(--line)}
.oauth-list{display:flex;flex-direction:column;gap:10px}
.oauth-btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;
  padding:11px 14px;border:1px solid var(--line);border-radius:10px;background:var(--surface);
  color:var(--ink);font-size:14px;font-weight:600;cursor:pointer;text-decoration:none;
  transition:background .13s,border-color .13s}
.oauth-btn:hover{background:var(--panel);border-color:var(--line2)}
.oauth-btn svg{flex:none}
/* selectable chips (signup "how did you hear") */
.or-chip{border:1px solid var(--line);background:var(--surface);color:var(--ink3);border-radius:20px;
  padding:7px 14px;font-size:13px;font-weight:500;cursor:pointer;transition:background .13s,border-color .13s,color .13s}
.or-chip:hover{border-color:var(--line2);background:var(--panel)}
.or-chip.on{background:var(--blue);border-color:var(--blue);color:#fff}
.demo-note{margin-top:18px;background:var(--panel);border:1px solid var(--line);
  border-radius:10px;padding:12px 14px;font-size:12.5px;color:var(--ink3);line-height:1.6}

/* ---------- shell --------------------------------------------------- */
/* App shell: exactly the viewport, never more. The page itself does not scroll —
   the sidebar and topbar are always where you left them and only .content moves,
   so there is one scrollbar on screen instead of a page-level one plus whatever
   a panel had. dvh first so a phone's collapsing URL bar cannot add a stray
   100px of empty document underneath. */
.shell{display:flex;height:100vh;height:100dvh;overflow:hidden}
.sidebar{width:252px;border-right:1px solid var(--line);background:var(--surface);
  display:flex;flex-direction:column;height:100%;flex-shrink:0}
.side-head{padding:20px 18px 14px;display:flex;align-items:center;gap:10px}
.side-head .logo{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;
  background:linear-gradient(140deg,var(--blue),var(--purple))}
.side-head .name{font-weight:700;font-size:15px;line-height:1.2}
.side-head .agency{font-size:11px;color:var(--muted);font-weight:500}
.side-nav{flex:1;overflow-y:auto;padding:6px 12px}
.nav-group{margin-bottom:14px}
.nav-label{font-size:11px;font-weight:600;color:var(--muted);padding:4px 8px;
  letter-spacing:.04em}
.nav-item{width:100%;display:flex;align-items:center;gap:10px;padding:8px 10px;
  margin-bottom:2px;border-radius:8px;border:none;background:transparent;text-align:left;
  font-size:14px;font-weight:500;color:var(--ink3);transition:.13s}
.nav-item:hover{background:var(--panel)}
.nav-item.active{background:var(--panel);color:var(--ink);font-weight:600}
.nav-item svg{color:var(--muted)}
.nav-item.active svg{color:var(--blue)}
.side-foot{padding:12px;border-top:1px solid var(--line)}
.side-user{display:flex;align-items:center;gap:10px;padding:8px;border-radius:8px;
  background:var(--panel)}
.side-user .av{width:34px;height:34px;border-radius:50%;background:var(--surface);
  border:1px solid var(--line);display:grid;place-items:center;font-weight:600;
  font-size:13px;color:var(--muted)}
.side-user .meta{flex:1;min-width:0}
.side-user .meta b{font-size:13px;display:block;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.side-user .meta span{font-size:12px;color:var(--muted)}
.side-user .logout{border:none;background:none;color:var(--muted);display:grid;
  place-items:center;padding:4px}

/* min-height:0 or the flex child refuses to shrink and .content never scrolls */
.main{flex:1;display:flex;flex-direction:column;min-width:0;min-height:0}
.topbar{display:flex;align-items:center;justify-content:space-between;padding:12px 28px;
  border-bottom:1px solid var(--line);background:var(--surface);position:sticky;top:0;z-index:5}
.searchbox{position:relative}
.searchbox svg{position:absolute;left:11px;top:9px;color:var(--muted)}
.searchbox input{padding:7px 12px 7px 32px;width:280px}
.topbar-right{display:flex;align-items:center;gap:12px}
.balance-pill{display:flex;align-items:center;gap:7px;padding:6px 12px;border-radius:8px;
  background:var(--green-soft);border:1px solid var(--green-border);
  font-size:13px;font-weight:600;color:var(--green)}
.icon-btn{width:36px;height:36px;border-radius:8px;border:1px solid var(--line);
  background:var(--surface);display:grid;place-items:center}
.user-chip{display:flex;align-items:center;gap:8px;padding:4px 8px 4px 4px;border-radius:8px;
  border:1px solid var(--line);background:var(--surface)}
.user-chip .av{width:40px;height:40px;border-radius:50%;background:var(--panel);
  display:grid;place-items:center;font-weight:600;font-size:14px;color:var(--muted)}
.user-chip .uname{font-size:13px;font-weight:600;line-height:1.1}
.user-chip .urole{font-size:11px;font-weight:500;color:var(--blue)}
.content{padding:28px;flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}

/* ---------- generic components -------------------------------------- */
.page{display:flex;flex-direction:column;gap:24px}
/* an empty mount point (a form that is not open, a hidden notice) must not
   spend one of those gaps */
.page > div:empty{display:none}
.page-head{display:flex;justify-content:space-between;align-items:flex-end;
  flex-wrap:wrap;gap:12px}
.page-head h2{font-size:24px;font-weight:600;letter-spacing:-.01em}
.page-head p{margin-top:4px;color:var(--muted);font-size:15px}

.card{background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--shadow);padding:20px}
.card.flush{padding:0}
.card-head{display:flex;justify-content:space-between;align-items:center;
  padding:16px;border-bottom:1px solid var(--line)}
.card-head h3{font-size:15px;font-weight:600}
.card h3{font-size:15px;font-weight:600}

.grid{display:grid;gap:16px}
.g4{grid-template-columns:repeat(4,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g2{grid-template-columns:1fr 1fr}
.g-21{grid-template-columns:1.6fr 1fr}
.g-12{grid-template-columns:1.4fr 1fr}

.field{display:flex;flex-direction:column;gap:6px}
.field label{font-size:13px;font-weight:600;color:var(--ink3)}
.field .hint{font-size:12px;color:var(--muted)}
input,select,textarea{width:100%;padding:9px 12px;border-radius:8px;
  border:1px solid var(--line);font-size:14px;color:var(--ink);outline:none;
  background:var(--surface);box-shadow:var(--shadow)}
input:focus,select:focus,textarea:focus{border-color:var(--blue-border);
  box-shadow:0 0 0 3px var(--blue-soft)}
textarea{resize:vertical;min-height:90px}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  padding:9px 14px;border-radius:8px;font-size:14px;font-weight:600;border:none;
  transition:.13s;white-space:nowrap}
.btn.sm{padding:7px 11px;font-size:13px}
.btn.primary{background:var(--blue);color:#fff;
  box-shadow:inset 0 0 0 1px rgba(10,13,18,.18),0 1px 2px rgba(10,13,18,.08)}
.btn.primary:hover{background:var(--blue-dark)}
.btn.ghost{background:var(--surface);color:var(--ink3);box-shadow:var(--shadow-btn)}
.btn.ghost:hover{background:var(--panel)}
.btn.soft{background:var(--blue-soft);color:var(--blue);
  box-shadow:inset 0 0 0 1px var(--blue-border)}
.btn.soft.b-sendsave{background:#0794551c;color:#079455;box-shadow:inset 0 0 0 1px #079455}
/* dashboard header: equal-height action buttons */
.head-actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.head-actions>.btn{height:42px;padding:0 16px}
.head-actions .beam-host{height:42px}
/* mobile nav toggle + backdrop (shown only on small screens) */
.nav-toggle{display:none}
.nav-backdrop{display:none}
.btn.danger{background:var(--red-soft);color:var(--red);
  box-shadow:inset 0 0 0 1px var(--red-border)}
.btn[disabled]{opacity:.5;cursor:not-allowed}
.btn.block{width:100%}

.chip{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:6px;
  font-size:12px;font-weight:500;border:1px solid var(--line2);background:var(--surface);color:var(--ink2)}
.chip.blue{background:var(--blue-soft);border-color:var(--blue-border);color:var(--blue)}
.chip.green{background:var(--green-soft);border-color:var(--green-border);color:var(--green)}
.chip.amber{background:var(--amber-soft);border-color:var(--amber-border);color:var(--amber)}
.chip.red{background:var(--red-soft);border-color:var(--red-border);color:var(--red)}
.dot{width:6px;height:6px;border-radius:50%;display:inline-block}

.pill{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:6px;
  font-size:12px;font-weight:600;white-space:nowrap}
.pill.sent{background:var(--panel);color:var(--muted)}
.pill.delivered{background:var(--blue-soft);color:var(--blue)}
.pill.read{background:var(--green-soft);color:var(--green)}
.pill.queued{background:var(--amber-soft);color:var(--amber)}
.pill.failed{background:var(--red-soft);color:var(--red)}
.pill.no_whatsapp{background:#F3E8FF;color:#7C3AED}

table{width:100%;border-collapse:collapse}
thead tr{background:var(--panel)}
th{text-align:left;padding:10px 16px;font-size:12px;font-weight:600;color:var(--muted)}
td{padding:11px 16px;font-size:14px;border-top:1px solid var(--line)}
td .sub{font-size:12px;color:var(--muted)}
.row-strong{font-weight:600}

/* stat cards */
.stat{padding:18px}
.stat .top{display:flex;justify-content:space-between;align-items:center}
.stat .top span{font-size:13px;font-weight:500;color:var(--muted)}
.stat .ico{width:32px;height:32px;border-radius:8px;background:var(--blue-soft);
  display:grid;place-items:center}
.stat .val{font-size:28px;font-weight:600;margin-top:10px}

/* balance card */
.bal-card{background:linear-gradient(160deg,var(--blue),var(--blue-dark));
  border:none;color:#fff}
.bal-card .lbl{font-size:13px;color:rgba(255,255,255,.78)}
.bal-card .amt{font-size:40px;font-weight:600;margin-top:12px}
.bal-card p{font-size:13px;color:rgba(255,255,255,.72);margin:6px 0 16px;line-height:1.5}

/* activity list */
.act{display:flex;align-items:center;gap:12px;padding:11px 0;border-top:1px solid var(--line)}
.act:first-child{border-top:none}
.act .ico{width:34px;height:34px;border-radius:8px;background:var(--panel);
  display:grid;place-items:center;flex-shrink:0}
.act .info{flex:1;min-width:0}
.act .info b{font-size:14px;display:block;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.act .info span{font-size:12px;color:var(--muted)}

/* preview bubble */
.wa-preview{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:14px;
  margin-top:10px}
.wa-preview .head{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.wa-preview .head .av{width:30px;height:30px;border-radius:50%;background:var(--green-soft);
  display:grid;place-items:center}
.wa-bubble{background:#E7FCE3;border-radius:10px 10px 10px 2px;padding:9px 11px;
  font-size:13px;line-height:1.5;color:var(--ink2);white-space:pre-wrap}

/* tabs / filters */
.filters{display:flex;gap:6px;padding:14px;border-bottom:1px solid var(--line);
  flex-wrap:wrap;align-items:center}
.filter{padding:6px 12px;border-radius:7px;border:1px solid var(--line);background:var(--surface);
  font-size:13px;font-weight:600;color:var(--ink3);text-transform:capitalize}
.filter.active{border-color:var(--blue-border);background:var(--blue-soft);color:var(--blue)}

/* checkbox row */
.pick{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;
  border:1px solid var(--line);background:var(--surface)}
.pick.on{background:var(--blue-soft);border-color:var(--blue-border)}
.pick input{width:auto;box-shadow:none}
.pick .info{flex:1}
.pick .info b{font-size:13px}
.pick .info span{font-size:12px;color:var(--muted);display:block}

/* Bulk recipients — selectable contact cards (Finup-style) */
.bc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
  gap:12px;padding:1px}
.pick-card{position:relative;overflow:hidden;border-radius:12px;padding:2px;
  background:none;outline:1px solid var(--line);cursor:pointer;transition:.15s ease-in-out}
.pick-card>input{position:absolute;opacity:0;width:0;height:0;pointer-events:none}
.pick-card:hover{outline-color:var(--line2)}
.pick-card .glow,#bcList .pick .glow{position:absolute;inset:0;border-radius:12px;opacity:0;pointer-events:none;
  transform:scale(2);transition:opacity .2s ease-in-out;
  background:conic-gradient(at 49% 49%,#3DA2FF 1%,#6600F5 10%,#6600F5 43%,
    #3DA2FF 51%,#1A1AFF 59%,#1A1AFF 92%,#3DA2FF 100%)}
.pick-card.on{outline-color:transparent}
.pick-card.on .glow,#bcList .pick.on .glow{opacity:1;animation:pc-spin 3s linear infinite}
@keyframes pc-spin{to{transform:scale(2) rotate(360deg)}}

/* Bulk recipients — list view rows reuse the same glow (scoped) */
/* The list shares .stack, a COLUMN FLEX box, and the container is capped at
 * 420px so it can scroll. Flex items shrink to share that height by default,
 * which crushed 200+ rows into a few pixels each — they have to keep their own
 * size and let the container scroll instead. Card view escaped this because
 * .bc-grid is a grid. */
#bcList.stack{gap:8px}
#bcList.stack>*{flex:none}
/* badges sit beside the number, not stacked under each other — a list view
 * that is as tall as the cards is not a list view */
#bcList .pick .pick-badges{display:flex;align-items:center;justify-content:flex-end;
  flex:none;gap:6px;flex-wrap:wrap;max-width:55%}
#bcList .pick{position:relative;overflow:hidden;border:none;outline:1px solid var(--line);
  border-radius:9px;padding:2px;background:none}
#bcList .pick:hover{outline-color:var(--line2)}
#bcList .pick.on{outline-color:transparent}
#bcList .pick .face{position:relative;z-index:1;flex:1;min-width:0;display:flex;align-items:center;gap:10px;
  padding:8px 10px;border-radius:7px;background:var(--surface)}
/* The face is what HIDES the spinning gradient behind it, leaving only the 2px
 * rim. --blue-soft is a solid hex in light mode but translucent in dark, so a
 * plain background let the whole conic gradient show through a selected row —
 * a huge blue wedge instead of a border. Paint the tint over an opaque base so
 * it covers in both themes. */
#bcList .pick.on .face{background-color:var(--surface);
  background-image:linear-gradient(var(--blue-soft),var(--blue-soft))}
/* The rim keeps spinning in list view too. It is a transform-only animation,
 * so it runs on the compositor without repainting — the cost of a few hundred
 * of them is layer memory, not frame time. If a huge selection ever feels
 * heavy, cap it here rather than freezing the effect outright. */
.pick-card .face{position:relative;z-index:1;display:flex;flex-direction:column;gap:14px;
  background:var(--surface);border-radius:10px;padding:12px 14px;min-height:92px}
.pick-card .pc-top{display:flex;justify-content:space-between;align-items:flex-start;gap:8px}
.pick-card .cbx{flex:none;width:20px;height:20px;border-radius:6px;
  border:1px solid var(--line2);background:var(--surface);display:grid;place-items:center;
  color:transparent;transition:.15s ease-in-out}
.pick-card.on .cbx{background:var(--blue);border-color:var(--blue);color:#fff}
.pick-card .cbx svg{display:block}
.pick-card .pc-badges{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:5px}
.pick-card .pc-id{display:flex;flex-direction:column;gap:2px}
.pick-card .pc-id b{font-size:14px;color:var(--ink);line-height:1.3;word-break:break-word}
.pick-card .pc-id .num{font-size:13px;font-weight:500;color:var(--ink2);
  font-variant-numeric:tabular-nums;unicode-bidi:plaintext}

/* Paste numbers — stacked one-per-line boxes */
/* ---- pasted numbers: a grid of tiles, not an ever-growing column ------
   A few hundred numbers as inline chips made one very tall box that pushed the
   send button off screen and re-rendered on every keystroke. Fixed-width tiles
   keep the block a predictable height and the list is capped — see .bc-more. */
.num-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));
  gap:8px;margin-bottom:10px}
.num-tag{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:9px 11px;border-radius:10px;background:var(--panel);
  border:1px solid var(--line);font-size:12.5px;font-weight:500;
  font-variant-numeric:tabular-nums;min-width:0}
.num-tag>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.num-tag button{flex:none;border:none;background:none;cursor:pointer;line-height:1;
  font-size:15px;color:var(--muted);padding:0 2px;border-radius:5px;transition:.13s}
.num-tag button:hover{color:var(--red);background:var(--red-soft)}

/* "Show more" for any capped list — contacts and pasted numbers both use it */
.bc-more{width:100%;display:flex;align-items:center;justify-content:center;gap:7px;
  padding:9px 12px;border-radius:10px;background:var(--surface);
  border:1px dashed var(--line2);color:var(--ink3);font-size:12.5px;font-weight:600;
  cursor:pointer;transition:border-color .16s,color .16s,background .16s}
.bc-more:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-soft)}
.bc-more i{font-style:normal;font-weight:500;color:var(--muted)}
.bc-more:hover i{color:var(--blue)}

.chip-input.col{flex-direction:column;align-items:stretch;flex-wrap:nowrap;gap:8px}
.chip-input.col .chip-tag{align-self:flex-start;max-width:100%;
  border:1px solid transparent;
  background:linear-gradient(var(--panel),var(--panel)) padding-box,
    linear-gradient(90deg,var(--line2),var(--blue-border),var(--line2)) border-box;
  background-size:auto,200% 100%;background-repeat:no-repeat;
  animation:chip-in .22s ease,chip-sheen 3.6s linear infinite}
.chip-input.col .chip-tag>span{overflow:hidden;text-overflow:ellipsis}
.chip-input.col>input{width:100%;min-width:0}
@keyframes chip-in{from{opacity:0;transform:translateY(-4px) scale(.96)}to{opacity:1;transform:none}}
@keyframes chip-sheen{to{background-position:0 0,-200% 0}}

/* Upload CSV — styled file drop zone */
.file-native{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;pointer-events:none}
.filedrop{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  width:100%;padding:20px 16px;text-align:center;cursor:pointer;border-radius:12px;
  border:1.5px dashed var(--line2);background:var(--panel);color:var(--ink2);transition:.15s ease-in-out}
.filedrop:hover{border-color:var(--blue-border);background:var(--blue-soft)}
.filedrop.drag{border-color:var(--blue);background:var(--blue-soft);box-shadow:0 0 0 3px var(--blue-soft)}
.filedrop .fd-ic{display:grid;place-items:center;width:40px;height:40px;border-radius:10px;
  background:var(--surface);border:1px solid var(--line);color:var(--blue)}
.filedrop .fd-main{font-size:14px;color:var(--ink2)}
.filedrop .fd-main b{color:var(--blue);font-weight:600}
.filedrop .fd-name{font-size:12px;color:var(--muted);max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.filedrop.has{border-style:solid;border-color:var(--blue-border);background:var(--blue-soft)}
.filedrop.has .fd-name{color:var(--blue);font-weight:600}

/* WhatsApp-style message preview */
.wa-phone{width:100%;border:1px solid var(--line);border-radius:14px;
  overflow:hidden;box-shadow:0 6px 22px rgba(11,20,26,.09)}
.wa-head[dir="rtl"] .wa-back svg{transform:scaleX(-1)}
.wa-head{display:flex;align-items:center;gap:10px;padding:9px 12px;background:#008069;color:#fff}
.wa-head .wa-back{display:flex;align-items:center;margin-right:-2px;opacity:.95}
.wa-av{flex:none;width:34px;height:34px;border-radius:50%;background:#cfe9df;color:#075e54;
  display:grid;place-items:center;font-weight:700;font-size:15px}
.wa-id{display:flex;flex-direction:column;line-height:1.2;flex:1;min-width:0}
.wa-id b{font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wa-id i{font-size:11px;font-style:normal;color:rgba(255,255,255,.82)}
.wa-acts{display:flex;align-items:center;gap:15px;opacity:.95}
.wa-body{display:flex;justify-content:flex-end;align-items:flex-start;padding:16px 10px;min-height:120px;
  background-color:#efeae2;
  background-image:radial-gradient(rgba(11,20,26,.035) 1px,transparent 1px);background-size:22px 22px}
.wa-phone .wa-bubble{position:relative;max-width:90%;background:#d9fdd3;color:#111b21;
  border-radius:8px;border-top-right-radius:0;padding:6px 10px 18px;
  font-size:14px;line-height:1.55;word-break:break-word;unicode-bidi:plaintext;
  box-shadow:0 1px 1px rgba(11,20,26,.13)}
.wa-phone .wa-bubble::after{content:"";position:absolute;top:0;right:-8px;width:0;height:0;
  border:8px solid transparent;border-top-color:#d9fdd3;border-right-width:0}
.wa-phone .wa-text{white-space:pre-line;unicode-bidi:plaintext}
.wa-phone .wa-time{position:absolute;bottom:4px;right:10px;font-size:11px;color:#667781;
  display:inline-flex;align-items:center;gap:3px;line-height:1}
.wa-phone .wa-time svg{color:#53bdeb}
.wa-phone .wa-empty{color:#667781;font-style:italic}
.wa-phone .pv-var{background:rgba(7,94,70,.13);color:#0a6b4f;border-radius:4px;
  padding:0 4px;font-weight:600;unicode-bidi:plaintext}
.wa-phone .pv-var.empty{display:inline;background:none;padding:0;border-radius:0;
  color:#9aa7a0;font-weight:600}
/* an example value standing in for a blank: readable as part of the sentence,
   but visibly the part that changes per customer */
.wa-phone .pv-fill{background:rgba(7,94,70,.10);border-radius:3px;padding:0 3px;
  unicode-bidi:plaintext}
.vmap-sug{font-weight:400;font-size:11px;color:var(--blue)}

/* Cards/list view toggle */
.seg{display:inline-flex;border:1px solid var(--line);border-radius:8px;
  overflow:hidden;background:var(--surface);box-shadow:var(--shadow-btn)}
.seg-btn{display:grid;place-items:center;width:34px;height:30px;border:none;
  background:var(--surface);color:var(--muted);cursor:pointer;transition:.13s}
.seg-btn+.seg-btn{border-left:1px solid var(--line)}
.seg-btn:hover{color:var(--ink2)}
.seg-btn.active{background:var(--blue-soft);color:var(--blue)}

/* sleek segmented control (settings toggles) */
.segpill{display:inline-flex;gap:4px;padding:4px;background:var(--panel);
  border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-btn)}
.segpill button{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  min-width:106px;padding:8px 18px;border:none;background:transparent;color:var(--muted);
  font-size:13.5px;font-weight:600;border-radius:9px;cursor:pointer;
  transition:background .15s,color .15s,box-shadow .15s}
.segpill button:hover{color:var(--ink2)}
.segpill button.active{background:var(--surface);color:var(--blue);
  box-shadow:0 1px 3px rgba(16,24,40,.12)}
body.dark .segpill{background:var(--bg)}
body.dark .segpill button.active{background:var(--line);color:#fff}
.segpill button svg{width:15px;height:15px;flex-shrink:0}

/* USDT network picker */
.netgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.netchip{display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 4px;
  border:1px solid var(--line);border-radius:10px;background:var(--surface);cursor:pointer;
  font-size:11px;font-weight:600;color:var(--muted);transition:border-color .15s,background .15s,color .15s}
.netchip svg{width:22px;height:22px}
.netchip:hover{border-color:var(--blue-border)}
.netchip.active{border-color:var(--blue);background:var(--blue-soft);color:var(--blue)}
@media(max-width:420px){.netgrid{grid-template-columns:repeat(3,1fr)}}

/* Website settings — tag colours */
.tc-list{display:flex;flex-direction:column;gap:10px}
.tc-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.tc-chip{min-width:72px;justify-content:center}
.tc-sws{display:flex;gap:6px}
.tc-sw{width:22px;height:22px;border-radius:50%;border:2px solid #fff;
  box-shadow:0 0 0 1px var(--line);cursor:pointer;padding:0;transition:transform .1s}
.tc-sw:hover{transform:scale(1.14)}
.tc-input{width:44px;height:30px;padding:2px;border:1px solid var(--line);
  border-radius:8px;background:var(--surface);cursor:pointer}
.ws-check{display:flex;align-items:center;gap:8px;margin-top:16px;cursor:pointer;font-size:14px}
.ws-check input{width:auto}
.ws-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media (max-width:640px){.ws-grid{grid-template-columns:1fr}}
.tc-sw.on{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--blue)}
.reduce-motion *,.reduce-motion *::before,.reduce-motion *::after{
  animation:none!important;transition-duration:.01ms!important}
.ws-actions{position:sticky;bottom:0;display:flex;align-items:center;justify-content:flex-end;
  gap:12px;margin-top:16px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;
  background:color-mix(in srgb, var(--surface) 90%, transparent);backdrop-filter:blur(6px)}
.ws-unsaved{margin-right:auto;font-size:13px;font-weight:600;color:var(--amber)}

.empty{padding:48px;text-align:center;color:var(--muted)}
.empty b{display:block;color:var(--ink);font-size:15px;margin-bottom:4px}

.alert{display:flex;align-items:center;gap:8px;padding:10px 12px;border-radius:8px;
  font-size:13px;font-weight:600}
.alert.ok{background:var(--green-soft);border:1px solid var(--green-border);color:var(--green)}
.alert.err{background:var(--red-soft);border:1px solid var(--red-border);color:var(--red)}
.alert.info{background:var(--blue-soft);border:1px solid var(--blue-border);color:var(--blue)}
.alert.amber{background:var(--amber-soft);border:1px solid var(--amber-border);color:var(--amber)}
/* in-flight send: the button spins and the alert breathes, so the wait is
   visibly the network and not a dead click */
.btn-spin{display:inline-block;width:14px;height:14px;flex:none;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;opacity:.85;
  animation:btnSpin .6s linear infinite}
@keyframes btnSpin{to{transform:rotate(360deg)}}
.alert.sending{animation:sendPulse 1.4s ease-in-out infinite}
@keyframes sendPulse{50%{opacity:.62}}
@media (prefers-reduced-motion:reduce){
  .btn-spin{animation-duration:1.6s}.alert.sending{animation:none}}
@keyframes bfaShake{10%,90%{transform:translateX(-2px)}20%,80%{transform:translateX(3px)}30%,50%,70%{transform:translateX(-7px)}40%,60%{transform:translateX(7px)}}
.shake{animation:bfaShake .45s cubic-bezier(.36,.07,.19,.97) both}
@media (prefers-reduced-motion:reduce){.shake{animation:none}}

/* ===== Support tickets ===== */
@keyframes tkIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes tkBub{from{opacity:0;transform:translateY(10px) scale(.97)}to{opacity:1;transform:none}}
@keyframes tkPop{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
@keyframes tkFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}
@keyframes tkOvIn{from{opacity:0}to{opacity:1}}
.tk-filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px}
.tk-fbadge{background:var(--red);color:#fff;border-radius:999px;font-size:10.5px;font-weight:700;padding:1px 6px;margin-left:3px}
.tk-list{display:flex;flex-direction:column;gap:12px}
.tk-card{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:15px 18px;cursor:pointer;
  box-shadow:var(--shadow);transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;
  animation:tkIn .45s cubic-bezier(.2,.7,.3,1) both}
.tk-card:hover{transform:translateY(-2px);box-shadow:0 10px 26px rgba(16,24,40,.10);border-color:var(--line2)}
.tk-card:active{transform:translateY(0);transition-duration:.05s}
.tk-card-top{display:flex;align-items:center;gap:10px;justify-content:space-between;margin-bottom:6px}
.tk-card-subj{font-weight:650;font-size:15px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tk-card-prev{font-size:13px;color:var(--ink2);line-height:1.5;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.tk-card-prev b{color:var(--muted);font-weight:600}
.tk-card-meta{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:9px;font-size:11.5px;color:var(--muted)}
.tk-card-meta svg{vertical-align:-2px}
.tk-cat{background:var(--panel);border:1px solid var(--line);border-radius:6px;padding:1px 8px;font-weight:600;color:var(--ink3)}
.tk-biz{display:inline-flex;align-items:center;gap:4px;font-weight:600;color:var(--ink3)}
.tk-when{margin-left:auto}
.tk-status{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:3px 10px;border-radius:999px;white-space:nowrap;flex:none}
.tk-status.open{background:var(--amber-soft);color:var(--amber);border:1px solid var(--amber-border)}
.tk-status.answered{background:var(--green-soft);color:var(--green);border:1px solid var(--green-border)}
.tk-status.closed{background:var(--panel);color:var(--muted);border:1px solid var(--line)}
.tk-empty{text-align:center;padding:56px 24px;animation:tkIn .5s both}
.tk-empty-ic{width:80px;height:80px;border-radius:50%;margin:0 auto 18px;display:grid;place-items:center;
  background:var(--blue-soft);color:var(--blue);animation:tkFloat 3.5s ease-in-out infinite}
.tk-empty h3{font-size:19px;margin-bottom:6px;color:var(--ink)}
.tk-empty p{color:var(--muted);font-size:14px;max-width:340px;margin:0 auto 20px;line-height:1.55}
.tk-overlay{position:fixed;inset:0;z-index:80;background:rgba(15,23,42,.5);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;padding:20px;animation:tkOvIn .18s ease}
.tk-modal{background:var(--surface);border-radius:16px;width:100%;max-width:600px;height:min(88vh,720px);
  display:flex;flex-direction:column;overflow:hidden;box-shadow:0 24px 60px rgba(0,0,0,.32);animation:tkPop .32s cubic-bezier(.2,.7,.3,1) both}
.tk-modal-sm{height:auto;max-width:480px}
.tk-modal-head{display:flex;align-items:center;gap:12px;padding:16px 18px;border-bottom:1px solid var(--line);flex:none}
.tk-modal-title{font-size:16px;font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tk-modal-sub{font-size:12px;color:var(--muted);margin-top:3px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.tk-x{width:32px;height:32px;border-radius:8px;border:none;background:var(--panel);color:var(--muted);font-size:20px;line-height:1;flex:none;cursor:pointer;transition:background .15s}
.tk-x:hover{background:var(--line);color:var(--ink)}
.tk-thread{flex:1;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:10px;background:var(--panel)}
.tk-bubble{max-width:80%;padding:9px 13px;border-radius:15px;box-shadow:var(--shadow);animation:tkBub .34s cubic-bezier(.2,.7,.3,1) both}
.tk-bubble .who{font-size:10.5px;font-weight:700;opacity:.65;margin-bottom:2px}
.tk-bubble .txt{font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word}
.tk-bubble .time{font-size:10px;opacity:.6;margin-top:3px;text-align:right}
.tk-bubble.them{align-self:flex-start;background:var(--surface);border:1px solid var(--line);color:var(--ink);border-bottom-left-radius:5px}
.tk-bubble.bot{background:var(--blue-soft);border:1px solid var(--blue-border);border-left:3px solid var(--blue)}
.tk-actions{display:flex;gap:7px;flex-wrap:wrap;margin-top:10px}
.tk-act{display:inline-flex;align-items:center;gap:6px;padding:7px 13px;border-radius:9px;border:1px solid var(--blue);
  background:var(--blue);color:#fff;font-size:12.5px;font-weight:650;cursor:pointer;
  transition:transform .1s ease,filter .15s ease,background .15s ease}
.tk-act:hover{filter:brightness(1.08)}
.tk-act:active{transform:scale(.95)}
.tk-act svg{flex:none}
.tk-act.ghost{background:transparent;color:var(--blue);border-color:var(--blue-border)}
.tk-act.ghost:hover{background:#fff;filter:none}
.tk-act:disabled{opacity:.55;cursor:default}
.tk-bubble.bot .who{color:var(--blue);opacity:1;display:flex;align-items:center;gap:4px}
.tk-bubble.bot .who svg{flex:none}
.tk-bubble.me{align-self:flex-end;background:var(--blue);color:#fff;border-bottom-right-radius:5px}
.tk-empty-thread{text-align:center;color:var(--muted);font-size:13px;margin:auto}
.tk-compose{flex:none;display:flex;flex-direction:column;gap:8px;padding:12px 14px;border-top:1px solid var(--line);background:var(--surface)}
.tk-compose-row{display:flex;align-items:flex-end;gap:9px}
.tk-attach{flex:none;width:42px;height:42px;border-radius:12px;border:1px solid var(--line);background:var(--surface);color:var(--muted);display:grid;place-items:center;cursor:pointer;transition:background .15s,color .15s}
.tk-attach:hover{background:var(--panel);color:var(--blue)}
.tk-img{max-width:230px;max-height:270px;border-radius:11px;margin:3px 0 4px;cursor:zoom-in;display:block;object-fit:cover}
.tk-preview{display:flex;gap:8px;flex-wrap:wrap}
.tk-prev-item{position:relative;width:64px;height:64px;border-radius:10px;overflow:hidden;border:1px solid var(--line)}
.tk-prev-item img{width:100%;height:100%;object-fit:cover;display:block}
.tk-prev-x{position:absolute;top:2px;right:2px;width:20px;height:20px;border-radius:50%;border:none;background:rgba(0,0,0,.6);color:#fff;font-size:14px;line-height:1;cursor:pointer;display:grid;place-items:center}
.tk-attach-row{display:flex;align-items:center;gap:10px;margin-top:12px}
.tk-lightbox{position:fixed;inset:0;z-index:90;background:rgba(0,0,0,.85);display:flex;align-items:center;justify-content:center;padding:24px;cursor:zoom-out;animation:tkOvIn .18s ease}
.tk-lightbox img{max-width:96vw;max-height:92vh;border-radius:8px;box-shadow:0 10px 40px rgba(0,0,0,.5)}
.tk-lb-x{position:fixed;top:16px;right:18px;width:40px;height:40px;border-radius:50%;border:none;background:rgba(255,255,255,.16);color:#fff;font-size:24px;line-height:1;cursor:pointer}
.tk-reply{flex:1;resize:none;border:1px solid var(--line);border-radius:12px;padding:11px 14px;font-size:14px;font-family:inherit;
  color:var(--ink);background:var(--surface);outline:none;max-height:140px;line-height:1.4;transition:border-color .15s}
.tk-reply:focus{border-color:var(--blue)}
.tk-send{flex:none;width:42px;height:42px;border-radius:12px;border:none;background:var(--blue);color:#fff;display:grid;place-items:center;cursor:pointer;transition:background .15s,transform .1s}
.tk-send:hover{background:var(--blue-dark)}
.tk-send:active{transform:scale(.92)}
.tk-send.sending{opacity:.6}
.tk-closed{flex:1;text-align:center;color:var(--muted);font-size:13px;display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap}
.tk-newbody{padding:18px;display:flex;flex-direction:column}
.tk-lbl{font-size:12.5px;font-weight:600;color:var(--ink3);margin:12px 0 6px}
.tk-lbl:first-child{margin-top:0}
.tk-cats{display:flex;gap:8px;flex-wrap:wrap}
.tk-chip{padding:7px 14px;border-radius:999px;border:1px solid var(--line);background:var(--surface);color:var(--ink2);font-size:13px;font-weight:600;cursor:pointer;transition:all .14s}
.tk-chip:hover{border-color:var(--line2)}
.tk-chip.on{background:var(--blue);border-color:var(--blue);color:#fff}
.tk-input{border:1px solid var(--line);border-radius:10px;padding:11px 13px;font-size:14px;font-family:inherit;color:var(--ink);background:var(--surface);outline:none;transition:border-color .15s;resize:vertical}
.tk-input:focus{border-color:var(--blue)}
.tk-err{color:var(--red);font-size:13px;min-height:18px;margin-top:8px}
.tk-modal-foot{display:flex;justify-content:flex-end;gap:10px;padding:14px 18px;border-top:1px solid var(--line);flex:none}
@media (prefers-reduced-motion:reduce){.tk-card,.tk-bubble,.tk-modal,.tk-empty,.tk-empty-ic,.tk-overlay{animation:none}}
@media (max-width:560px){.tk-modal{height:100vh;max-width:none;border-radius:0}.tk-overlay{padding:0}}

.dashed-card{border:1.5px dashed var(--line2);box-shadow:none;display:grid;
  place-items:center;min-height:180px}

/* ---- toast ---------------------------------------------------------
   Its own fixed palette, never --ink/--surface: those flip with the theme
   and used to leave white text on a near-white pill in dark mode. A dark
   pill reads on both themes; the icon chip carries the success/error colour. */
.toast{position:fixed;bottom:26px;left:50%;transform:translateX(-50%);z-index:200;
  display:flex;align-items:center;gap:11px;
  max-width:min(460px,calc(100vw - 28px));padding:11px 16px 11px 12px;
  border-radius:13px;font-size:13.5px;font-weight:500;line-height:1.45;
  --tst-bg:#1A2030; --tst-ink:#F7F9FC; --tst-bd:rgba(255,255,255,.13);
  --tst-ic:#4ADE97; --tst-ic-bg:rgba(74,222,151,.16);
  background:var(--tst-bg);color:var(--tst-ink);border:1px solid var(--tst-bd);
  box-shadow:0 14px 36px rgba(10,13,18,.26),0 3px 8px rgba(10,13,18,.14);
  cursor:pointer;user-select:none;-webkit-user-select:none}
body.dark .toast{--tst-bg:#242C3A; --tst-bd:rgba(255,255,255,.11);
  box-shadow:0 14px 38px rgba(0,0,0,.55),0 2px 6px rgba(0,0,0,.4)}
.toast[hidden]{display:none}
.toast.err{--tst-ic:#FF8F84; --tst-ic-bg:rgba(255,143,132,.18);
  --tst-bd:rgba(255,143,132,.34)}
.toast-ic{flex:none;display:grid;place-items:center;width:26px;height:26px;
  border-radius:8px;background:var(--tst-ic-bg);color:var(--tst-ic)}
.toast-tx{min-width:0;overflow-wrap:anywhere}
/* the -50% has to ride along inside the keyframes or the pill jumps off-centre */
@keyframes toastIn{from{opacity:0;transform:translate(-50%,16px) scale(.96)}
  to{opacity:1;transform:translate(-50%,0) scale(1)}}
@keyframes toastOut{from{opacity:1;transform:translate(-50%,0) scale(1)}
  to{opacity:0;transform:translate(-50%,10px) scale(.98)}}
.toast.in{animation:toastIn .28s cubic-bezier(.2,.85,.25,1) both}
.toast.out{animation:toastOut .18s ease both}
@media (max-width:560px){.toast{bottom:16px;width:calc(100vw - 24px);
  max-width:none;font-size:13px}}
@media (prefers-reduced-motion:reduce){.toast.in,.toast.out{animation:none}}

.muted{color:var(--muted)}
.spread{display:flex;justify-content:space-between;align-items:center}
.stack{display:flex;flex-direction:column;gap:14px}
.rowflex{display:flex;gap:8px;flex-wrap:wrap}

/* responsive */
@media(max-width:1100px){
  .g4{grid-template-columns:repeat(2,1fr)}
  .g3{grid-template-columns:1fr 1fr}
  .g-21,.g-12,.g2{grid-template-columns:1fr}
  .auth-wrap{grid-template-columns:1fr}
  .auth-art{display:none}
}
@media(max-width:680px){
  .sidebar{position:fixed;z-index:20;transform:translateX(-100%);transition:.2s;
    box-shadow:0 12px 40px rgba(10,13,18,.25)}
  .sidebar.open{transform:translateX(0)}
  .nav-toggle{display:inline-flex}
  body.nav-open .nav-backdrop{display:block;position:fixed;inset:0;
    background:rgba(10,13,18,.42);z-index:19}
  .g4{grid-template-columns:1fr}
  /* only the global topbar search folds away on a phone (the hamburger and the
     balance need that room). A page's OWN search box must stay — hiding it left
     Contacts, Logs, Templates and the library unsearchable on mobile. */
  .topbar .searchbox{display:none}
  .content{padding:18px}
  .topbar{padding:10px 16px}
  .user-chip .uname,.user-chip .urole{display:none}
  .page-head{align-items:flex-start}
  .head-actions{width:100%}
  .head-actions>.btn,.head-actions .beam-host{flex:1 1 0;min-width:0}
  .head-actions .beam-wrap,.head-actions .beam-btn{width:100%}
  .bal-card .amt{font-size:32px}
  .stat .val{font-size:24px}
}

/* ---- Batch 1: dashboard stat icon colours ------------------------- */
.stat .ico.s-green {background:var(--green-soft);color:var(--green)}
.stat .ico.s-blue  {background:var(--blue-soft); color:var(--blue)}
.stat .ico.s-yellow{background:var(--amber-soft);color:var(--amber)}
.stat .ico.s-red   {background:var(--red-soft);  color:var(--red)}

/* ---- header balance: bigger + colour by amount -------------------- */
.balance-pill{font-size:15.5px;font-weight:700;padding:7px 14px}
.balance-pill.bal-red{background:var(--red-soft);border-color:var(--red-border);color:var(--red)}
.balance-pill.bal-yellow{background:var(--amber-soft);border-color:var(--amber-border);color:var(--amber)}
.balance-pill.bal-green{background:var(--green-soft);border-color:var(--green-border);color:var(--green)}

/* ---- animated beam button (dashboard "New Message") --------------- */
.beam-host{position:relative;display:inline-flex;border-radius:14px;--beam-speed:1.3s;
  box-shadow:0 0 26px rgba(185,192,205,.60)}
.beam-wrap{position:relative;display:inline-flex;border-radius:14px;padding:3px;overflow:hidden}
.beam-wrap::before{content:"";position:absolute;left:50%;top:50%;width:200%;height:0;padding-bottom:200%;
  transform:translate(-50%,-50%);transform-origin:center;will-change:transform;filter:blur(1.5px);
  background:conic-gradient(from 0deg,#ffffff,#c4cad6,#5b616e,#c4cad6,#ffffff);
  animation:beam-spin var(--beam-speed) linear infinite}
.beam-wrap::after{content:"";position:absolute;inset:3px;border-radius:11px;
  background:#155EEF;z-index:1}
@keyframes beam-spin{to{transform:translate(-50%,-50%) rotate(360deg)}}
.beam-btn{position:relative;z-index:2;display:inline-flex;align-items:center;justify-content:center;gap:9px;
  background:transparent;color:#fff;border:none;border-radius:11px;height:36px;padding:0 20px;
  font-size:14px;font-weight:600;cursor:pointer;font-family:inherit;white-space:nowrap;box-sizing:border-box}
.beam-label{position:relative;z-index:2;display:inline-flex;align-items:center;gap:9px}
.cb-ar{display:inline-flex;transition:transform .2s}
.beam-host:hover .cb-ar{transform:translateX(3px)}
@media (prefers-reduced-motion: reduce){.beam-wrap::before{animation-duration:2.2s}}

/* ---- Batch 3: avatars + profile dropdown -------------------------- */
.av.lg{width:56px;height:56px;font-size:18px}
.user-menu{position:relative}
.user-chip{cursor:pointer;border:none;background:none;font:inherit}
.user-dd{position:absolute;right:0;top:calc(100% + 8px);z-index:55;min-width:212px;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 16px 40px rgba(0,0,0,.16);padding:6px;display:flex;flex-direction:column;gap:2px}
.user-dd[hidden]{display:none}
.dd-item{display:flex;align-items:center;gap:10px;padding:9px 10px;border:none;background:none;
  font:inherit;font-size:13.5px;color:var(--ink2);border-radius:8px;cursor:pointer;
  text-align:left;width:100%}
.dd-item:hover{background:var(--panel)}
.dd-item.danger{color:var(--red)}
.dd-item.danger:hover{background:var(--red-soft)}
.dd-sep{height:1px;background:var(--line);margin:4px 0}

/* ---- Batch 5: module picker (card modal) -------------------------- */
/* closed-state trigger (replaces the native <select>) */
.cs{position:relative;width:100%}
.cs-btn{width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:9px 12px;border:1px solid var(--line);border-radius:10px;background:var(--surface);
  font:inherit;font-size:13.5px;color:var(--ink);cursor:pointer;text-align:start}
.cs-btn:hover{border-color:var(--blue-border)}
.cs-cur{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start}
.cs-car{opacity:.55;flex:none}

/* the picker modal */
/* the select picker is spawned FROM inside dialogs (.ui-ov 90, .dw-ov 90,
   .pn-ov 92), so it has to sit above all of them or tapping a select inside a
   modal opens a picker nobody can see. Below the toast (200) only. */
.csm-ov{position:fixed;inset:0;z-index:150;background:rgba(15,23,42,.45);
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  display:flex;align-items:center;justify-content:center;padding:24px}
.csm{width:100%;max-width:680px;max-height:82vh;display:flex;flex-direction:column;
  background:var(--surface);border-radius:22px;overflow:hidden;
  box-shadow:0 30px 80px rgba(0,0,0,.28)}
.csm-head{display:flex;align-items:center;justify-content:space-between;padding:20px 24px 4px}
.csm-head h3{font-size:20px;font-weight:700;margin:0}
.csm-x{width:38px;height:38px;border-radius:50%;border:none;background:var(--panel);
  display:grid;place-items:center;cursor:pointer;color:var(--ink2)}
.csm-x:hover{background:var(--line)}
.csm-search{display:flex;align-items:center;gap:10px;margin:14px 24px 4px;padding:14px 18px;
  background:var(--surface);border:1px solid var(--line);border-radius:16px;color:var(--muted);
  box-shadow:0 4px 16px rgba(0,0,0,.04)}
.csm-search input{flex:1;border:none;outline:none;background:none;font:inherit;
  font-size:15px;color:var(--ink)}
.csm-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;padding:16px 24px 24px;overflow:auto}
.csm-opt{display:flex;align-items:center;gap:12px;padding:18px 20px;border-radius:16px;
  background:var(--surface);border:1px solid var(--line);box-shadow:0 4px 16px rgba(0,0,0,.04);
  cursor:pointer;font:inherit;font-size:16px;font-weight:600;color:var(--ink);text-align:start}
.csm-opt:hover{border-color:var(--blue-border);transform:translateY(-1px)}
.csm-opt .csm-tx{flex:1}
.csm-opt .csm-ck{width:26px;height:26px;border-radius:50%;background:var(--surface);color:var(--blue);
  display:grid;place-items:center;flex:none}
.csm-opt.sel{background:var(--blue);border-color:var(--blue);color:#fff;
  box-shadow:0 12px 28px rgba(21,94,239,.32)}
.csm-empty{grid-column:1/-1;text-align:center;color:var(--muted);padding:24px;font-size:14px}
@media(max-width:560px){.csm-grid{grid-template-columns:1fr}.csm-head h3{font-size:17px}}

/* ---- Bulk messaging: grouped modules (compose + CSV help) ---------- */
.bulk-meta{display:grid;grid-template-columns:1fr 1fr;gap:10px 12px;margin-bottom:4px}
.bulk-meta>div:nth-child(3){grid-column:1/-1}
.bulk-meta #bFrom .field{margin:0}
.bulk-summary{display:flex;gap:10px;background:var(--panel);
  border-radius:12px;padding:10px 14px}
.bulk-summary>div{flex:1;display:flex;flex-direction:column;gap:2px}
.bulk-summary span{font-size:12px;color:var(--muted)}
.bulk-summary b{font-size:16px;color:var(--ink)}
.bulk-actions{display:flex;flex-wrap:wrap;gap:8px}
.bulk-actions .btn{margin:0;min-width:0}
.bulk-actions .b-send{flex:2 1 190px}
.bulk-actions .b-sendsave{flex:2 1 190px}
/* labels here vary in length ("Save list (251 numbers)"), so let each button
 * hold its own content and wrap onto a new row instead of overlapping */
.bulk-actions .b-save{flex:1 1 120px;min-width:max-content}
/* Schedule + Restricted always sit together on their own row. A zero-height
 * full-width item ends the line before them, so where they land never depends
 * on how wide the panel happens to be or on how long "Save list (251
 * numbers)" has grown. flex-basis:0 then splits the new line evenly — and if
 * a role has no scheduling right, the survivor simply fills it. */
.bulk-actions .flex-break{flex:0 0 100%;height:0;margin:-4px 0}
.bulk-actions .b-schedule,
.bulk-actions .b-blocked{flex:1 1 0;min-width:max-content}
@media (max-width:520px){
  .bulk-actions .b-schedule,
  .bulk-actions .b-blocked{flex:1 1 100%}
}
.csv-need{display:flex;align-items:center;gap:8px;font-size:12.5px;
  color:var(--red);background:var(--red-soft);border:1px solid var(--red-border);
  border-radius:10px;padding:8px 10px;margin-top:8px}
.csv-sample{margin-top:10px;border:1px solid var(--line);border-radius:10px;padding:10px}
.csv-sample-h{display:flex;align-items:center;gap:6px;font-size:12.5px;
  font-weight:600;margin-bottom:6px;color:var(--muted)}
.csv-tbl{width:100%;border-collapse:collapse;font-size:12px}
.csv-tbl th,.csv-tbl td{border:1px solid var(--line);padding:4px 8px;
  text-align:left;white-space:nowrap}
.csv-tbl th{background:var(--panel);font-weight:600;color:var(--ink2)}
@media (max-width:560px){
  .bulk-meta{grid-template-columns:1fr}
  .bulk-meta>div:nth-child(3){grid-column:auto}
}

/* ---- copyable public user ID chip --------------------------------- */
.uid{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:12px;background:var(--panel);border:1px solid var(--line);
  border-radius:6px;padding:2px 7px;cursor:pointer;color:var(--ink2);
  white-space:nowrap;display:inline-block}
.uid:hover{border-color:var(--blue);color:var(--blue)}

/* ---- Bulk saved-contacts: grouped Filters module ------------------ */
.bulk-mod{border:1px solid var(--line);border-radius:12px;margin-bottom:8px;overflow:hidden}
.bulk-mod>summary{list-style:none;cursor:pointer;padding:8px 12px;font-size:12.5px;
  font-weight:600;color:var(--ink2);background:var(--panel);
  display:flex;align-items:center;gap:8px}
.bulk-mod>summary::-webkit-details-marker{display:none}
.bulk-mod>summary::after{content:'▾';margin-left:auto;color:var(--muted)}
.bulk-mod[open]>summary::after{content:'▴'}
.bulk-mod-body{padding:10px 12px;display:flex;flex-direction:column;gap:8px}
.bulk-mod-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12px}
.bulk-mod-row>.muted:first-child{min-width:54px}
.bulk-mod-tags{display:flex;gap:5px;flex-wrap:wrap;font-size:12.5px}
.bulk-mod-tags:empty{display:none}

/* Filters button (in the recipients card header) */
#bcFilterBtn.active{background:var(--blue-soft);color:var(--blue);
  box-shadow:inset 0 0 0 1px var(--blue-border)}
#bcFilters{margin-bottom:8px}

/* Paste-numbers chip input */
.chip-input{display:flex;flex-wrap:wrap;gap:6px;align-items:center;width:100%;
  min-height:42px;padding:6px;border:1px solid var(--line);border-radius:8px;
  background:var(--surface);box-shadow:var(--shadow);cursor:text}
.chip-input:focus-within{border-color:var(--blue-border);box-shadow:0 0 0 3px var(--blue-soft)}
.chip-input .chip-tag{display:inline-flex;align-items:center;gap:6px;
  background:var(--panel);border:1px solid var(--line);border-radius:7px;
  padding:4px 6px 4px 10px;font-size:13px;font-variant-numeric:tabular-nums;
  unicode-bidi:plaintext}
.chip-input .chip-tag button{border:none;background:none;cursor:pointer;
  color:var(--muted);font-size:16px;line-height:1;padding:0 2px}
.chip-input .chip-tag button:hover{color:var(--red)}
.chip-input>input{flex:1;min-width:150px;border:none;outline:none;box-shadow:none;
  padding:6px 4px;font-size:14px;background:transparent}
.chip-input>input:focus{box-shadow:none;border:none}

/* ===== Kurdish / Arabic-script support ============================== *
 * The bfa font is scoped by unicode-range to Arabic-script codepoints,
 * so Latin text keeps using Inter and only Kurdish/Arabic glyphs render
 * in bfa — automatically, everywhere, no markup changes needed.        */
@font-face{
  font-family:'BFAKurdish';
  src:url('bfa.ttf') format('truetype');
  font-weight:100 900;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0600-06FF,U+0660-0669,U+06F0-06F9,U+0750-077F,U+08A0-08FF,
    U+FB50-FDFF,U+FE70-FEFF,U+200C-200D,U+FDF2,U+FDFC;
}
/* extend the global stack: Latin->Inter, Arabic/Kurdish->bfa */
body{font-family:Inter,'BFAKurdish',sans-serif}

/* Auto-direction: any field or content block whose text is Kurdish/Arabic
 * lays out right-to-left (starts from the right); English stays left. */
input,textarea,select,
.cs-btn,.csm-opt,
.wa-bubble,.wa-preview .head b,
.info b,.info span,.uname,.row-strong,
td,.pick .info,.dd-item{
  unicode-bidi:plaintext;
  text-align:start;
}

/* ===== Contacts: applied-filter chips + slide-in filter panel ===== */
.fchips{display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 12px}
.fchips:empty{display:none}
.fchip{display:inline-flex;align-items:center;gap:6px;background:var(--blue-soft);
  color:var(--blue-dark);border:1px solid var(--blue-border);border-radius:999px;
  padding:3px 10px;font-size:12px;font-weight:600;cursor:pointer;user-select:none}
.fchip b{font-weight:700;opacity:.6}
.fchip:hover b{opacity:1}
.fchip-clear{background:none;border:none;color:var(--muted);font-size:12px;
  font-weight:600;cursor:pointer;padding:3px 6px;text-decoration:underline}
.fcount{display:inline-flex;align-items:center;justify-content:center;min-width:18px;
  height:18px;padding:0 5px;border-radius:999px;background:var(--blue);color:#fff;
  font-size:11px;font-weight:700;margin-left:2px}
.iconbtn{background:none;border:none;color:var(--ink3);cursor:pointer;padding:4px;
  border-radius:8px;display:inline-flex;align-items:center}
.iconbtn:hover{background:var(--panel);color:var(--ink)}

.slidewrap{position:fixed;inset:0;z-index:70}
.slide-backdrop{position:absolute;inset:0;background:rgba(15,23,42,.42);
  opacity:0;transition:opacity .22s ease}
.slidewrap.open .slide-backdrop{opacity:1}
.slide-panel{position:absolute;top:0;right:0;height:100%;width:360px;max-width:90vw;
  background:var(--surface);box-shadow:-12px 0 40px rgba(0,0,0,.18);display:flex;
  flex-direction:column;transform:translateX(100%);transition:transform .22s ease}
.slidewrap.open .slide-panel{transform:translateX(0)}
.slide-head{display:flex;align-items:center;justify-content:space-between;
  padding:16px 18px;border-bottom:1px solid var(--line)}
.slide-head h3{margin:0;font-size:16px}
.slide-body{flex:1;overflow-y:auto;padding:6px 18px 18px}
.slide-foot{display:flex;flex-direction:column;gap:8px;padding:12px 18px;border-top:1px solid var(--line)}
.slide-foot>.btn{width:100%;justify-content:center}

.fgrp{border-bottom:1px solid var(--line);padding:4px 0}
.fgrp summary{display:flex;align-items:center;justify-content:space-between;
  cursor:pointer;padding:10px 2px;font-size:13px;font-weight:600;color:var(--ink);
  list-style:none}
.fgrp summary::-webkit-details-marker{display:none}
.fgrp summary svg{color:var(--muted);transition:transform .18s ease}
.fgrp[open] summary svg{transform:rotate(180deg)}
.fopts{display:flex;flex-direction:column;gap:2px;padding:2px 2px 10px}
.fopt{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ink2);
  padding:5px 6px;border-radius:8px;cursor:pointer}
.fopt:hover{background:var(--panel)}
.fopt input{width:15px;height:15px;accent-color:var(--blue);cursor:pointer}

.fgrp-saved{padding:12px 0 14px;border-bottom:1px solid var(--line)}
.fgrp-title{font-size:13px;font-weight:600;color:var(--ink);margin-bottom:8px}
.fsaved-list{display:flex;flex-wrap:wrap;gap:6px}
.fsaved{display:inline-flex;align-items:center;gap:6px;background:var(--panel);
  border:1px solid var(--line);border-radius:999px;padding:3px 6px 3px 10px;font-size:12px}
.fsaved span{cursor:pointer;font-weight:600;color:var(--ink2)}
.fsaved span:hover{color:var(--blue)}
.fsaved b{cursor:pointer;color:var(--muted);font-weight:700;padding:0 2px}
.fsaved b:hover{color:var(--red)}

/* ===== Contacts: export dropdown ===== */
.expwrap{position:relative;display:inline-block}
.expmenu{position:absolute;right:0;top:calc(100% + 6px);z-index:30;min-width:172px;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:6px;
  box-shadow:0 16px 40px rgba(15,23,42,.16);display:flex;flex-direction:column;gap:2px}
.expmenu[hidden]{display:none}
.expmenu button{display:flex;align-items:center;gap:9px;width:100%;text-align:left;
  background:none;border:none;cursor:pointer;font-size:13px;font-weight:500;
  color:var(--ink2);padding:9px 10px;border-radius:8px}
.expmenu button:hover{background:var(--panel);color:var(--ink)}
.expmenu button svg{color:var(--muted)}

/* ===== Contacts: imported badge + import drop zone ===== */
.tag-imported{display:inline-block;margin-top:3px;font-size:10px;font-weight:600;
  color:var(--ink3);background:var(--panel);border:1px solid var(--line);
  border-radius:6px;padding:1px 7px;letter-spacing:.02em;text-transform:lowercase}
.imdrop{display:flex;align-items:center;gap:12px;padding:16px;cursor:pointer;
  border:1.5px dashed var(--line2);border-radius:12px;background:var(--panel);
  color:var(--ink2);transition:border-color .15s,background .15s}
.imdrop:hover{border-color:var(--blue);background:var(--blue-soft)}
.imdrop.drag{border-color:var(--blue);background:var(--blue-soft)}
.imdrop.has{border-style:solid;border-color:var(--green-border);background:var(--green-soft)}
.imdrop svg{color:var(--muted);flex:none}
.imdrop.has svg{color:var(--green)}

/* ===== Filter panels: in-app date-range calendar ===== */
.dpwrap{margin-top:8px}
.dp{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:12px}
.dp-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.dp-title{font-size:13.5px;font-weight:700;color:var(--ink);display:inline-flex;align-items:center;gap:6px}
.dp-year{border:1px solid var(--line);border-radius:7px;padding:2px 6px;font-size:13px;
  font-weight:700;color:var(--ink);background:var(--surface);font-family:inherit;cursor:pointer}
.dp-year:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft)}
.dp-nav{width:30px;height:30px;border:1px solid var(--line);background:var(--surface);border-radius:8px;
  cursor:pointer;font-size:18px;line-height:1;color:var(--ink2);display:flex;
  align-items:center;justify-content:center}
.dp-nav:hover{background:var(--blue-soft);border-color:var(--blue);color:var(--blue)}
.dp-dow{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}
.dp-dow span{text-align:center;font-size:11px;font-weight:600;color:var(--muted)}
.dp-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.dp-day{height:36px;border:none;background:none;border-radius:9px;cursor:pointer;
  font-size:13px;color:var(--ink);display:flex;align-items:center;justify-content:center;
  font-family:inherit;padding:0}
.dp-day.empty{visibility:hidden}
.dp-day:hover:not(.empty){background:var(--blue-soft)}
.dp-day.today{font-weight:700;box-shadow:inset 0 0 0 1.5px var(--blue-border)}
.dp-day.in-range{background:var(--blue-soft);border-radius:0}
.dp-day.start,.dp-day.end,.dp-day.sel{background:var(--blue);color:#fff;font-weight:700}
.dp-day.start{border-radius:9px 0 0 9px}
.dp-day.end{border-radius:0 9px 9px 0}
.dp-day.sel{border-radius:9px}
.dp-foot{display:flex;align-items:center;justify-content:space-between;margin-top:10px;
  padding-top:10px;border-top:1px solid var(--line)}
.dp-sum{font-size:12px;font-weight:600;color:var(--ink2)}
.dp-clear{background:none;border:none;color:var(--blue);font-size:12px;font-weight:600;cursor:pointer;padding:2px 4px}
.dp-clear:hover{text-decoration:underline}

/* ===== Reports: date-range popover trigger ===== */
.drpop{position:relative}
.drpop-btn{display:inline-flex;align-items:center;gap:8px;height:38px;padding:0 12px;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--ink);
  font-size:13.5px;font-weight:600;font-family:inherit;cursor:pointer;width:100%;
  justify-content:space-between}
.drpop-btn:hover{border-color:var(--blue)}
.drpop-btn>span{flex:1;text-align:left}
.drpop-btn svg{color:var(--muted);flex:none}
.drpop-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:40;width:300px;max-width:88vw}
.drpop-menu[hidden]{display:none}
.drpop-menu .dp{box-shadow:0 16px 40px rgba(15,23,42,.18)}

/* ===== Team & Roles ===== */
.rolechip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;
  padding:3px 10px;border-radius:999px;color:var(--rc,#155EEF);
  background:color-mix(in srgb, var(--rc,#155EEF) 15%, var(--surface));
  border:1px solid color-mix(in srgb, var(--rc,#155EEF) 30%, #fff)}
.role-picks{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
.role-pick{font-size:13px;font-weight:600;padding:6px 12px;border-radius:999px;cursor:pointer;
  color:var(--ink2);background:var(--surface);border:1.5px solid var(--line);font-family:inherit;transition:all .12s}
.role-pick:hover{border-color:var(--rc,var(--blue))}
.role-pick.on{color:#fff;background:var(--rc,var(--blue));border-color:var(--rc,var(--blue))}
.perm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(225px,1fr));gap:12px;margin-top:6px;
  max-height:58vh;overflow:auto;padding:2px}
.perm-grp{border:1px solid var(--line);border-radius:10px;padding:10px 12px}
.perm-grp-h{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:700;color:var(--ink);
  text-transform:uppercase;letter-spacing:.03em;margin-bottom:6px;cursor:pointer;
  padding-bottom:6px;border-bottom:1px solid var(--line)}
.perm-grp-h input{width:15px;height:15px;accent-color:var(--blue);cursor:pointer}
.perm-opt{display:flex;align-items:center;gap:9px;font-size:13px;color:var(--ink2);
  padding:4px 2px;cursor:pointer}
.perm-opt input{width:15px;height:15px;accent-color:var(--blue);cursor:pointer}
@media(max-width:560px){.perm-grid{grid-template-columns:1fr}}

/* ===== Role editor (luxury / Finup) ===== */
.re-modal{display:flex;flex-direction:column;animation:reIn .24s cubic-bezier(.16,.84,.34,1)}
@keyframes reIn{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}
.re-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:16px 20px 16px 22px;border-bottom:1px solid var(--line)}
.re-x{width:32px;height:32px;border-radius:9px;border:1px solid var(--line);background:var(--surface);
  color:var(--ink3);font-size:20px;line-height:1;display:grid;place-items:center;flex-shrink:0;
  transition:background .14s,color .14s}
.re-x:hover{background:var(--panel);color:var(--ink)}
.re-preview{display:flex;align-items:center;gap:12px;min-width:0}
.re-prevchip{padding:6px 16px;border-radius:999px;font-weight:600;font-size:13px;
  background:var(--rc,#155EEF);color:#fff;box-shadow:0 2px 8px rgba(21,94,239,.18);
  max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:background .18s}
.re-prevcount{font-size:12.5px;color:var(--muted);white-space:nowrap}

.re-body{padding:20px 26px;display:flex;flex-direction:column;gap:16px}
.re-row2{display:grid;grid-template-columns:1.45fr 1fr;gap:18px}
.re-field label{display:block;font-size:12.5px;font-weight:600;color:var(--ink3);margin-bottom:7px}
.re-input{width:100%;height:42px;border:1.5px solid var(--line);border-radius:9px;padding:0 14px;
  font-size:14px;color:var(--ink);transition:border .14s,box-shadow .14s}
.re-input:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft)}
.re-colorbox{display:flex;flex-direction:column;gap:11px}
.re-swatches{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.re-sw{width:26px;height:26px;border-radius:50%;background:var(--sw);border:none;cursor:pointer;
  position:relative;box-shadow:0 0 0 1px rgba(10,13,18,.08);transition:transform .12s,box-shadow .12s}
.re-sw:hover{transform:scale(1.14)}
.re-sw.on{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--sw);transform:scale(1.06)}
.re-sw.on::after{content:"";position:absolute;left:50%;top:47%;width:5px;height:9px;
  border:solid #fff;border-width:0 2px 2px 0;transform:translate(-50%,-50%) rotate(45deg)}
.re-hexgrp{display:flex;align-items:center;gap:9px}
.re-color-chip{position:relative;width:38px;height:38px;border-radius:9px;cursor:pointer;
  overflow:hidden;border:1.5px solid var(--line);flex-shrink:0;box-shadow:inset 0 0 0 2px #fff}
.re-color-chip input{position:absolute;inset:0;opacity:0;cursor:pointer;border:none;padding:0}
.re-hexin{display:flex;align-items:center;gap:3px;height:38px;border:1.5px solid var(--line);
  border-radius:9px;padding:0 13px;background:var(--surface);transition:border .14s,box-shadow .14s}
.re-hexin:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft)}
.re-hexin[hidden]{display:none}
.re-hexin span{color:var(--muted);font-size:14px;font-weight:600}
.re-hexin input{border:none;outline:none;width:80px;font-size:14px;font-weight:600;
  letter-spacing:.05em;text-transform:uppercase;color:var(--ink);background:none;padding:0}

.re-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:11px 15px;border-radius:10px;background:var(--panel);border:1px solid var(--line)}
.re-meta{font-size:13px;color:var(--ink2)} .re-meta b{color:var(--blue);font-weight:700}
.re-tools{display:flex;align-items:center;gap:10px}
.re-link{border:none;background:none;color:var(--blue);font-weight:600;font-size:13px;padding:2px}
.re-link:hover{text-decoration:underline}
.re-dot{color:var(--line2);font-size:10px}

.re-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(258px,1fr));gap:14px}
.re-card{border:1px solid var(--line);border-radius:10px;background:var(--surface);overflow:hidden;
  transition:box-shadow .16s,border-color .16s,transform .16s}
.re-card:hover{border-color:var(--line2);box-shadow:0 6px 18px rgba(10,13,18,.07);transform:translateY(-1px)}
.re-card.full{border-color:var(--blue-border);box-shadow:0 0 0 1px var(--blue-border),0 6px 18px rgba(21,94,239,.10)}
.re-card-h{display:flex;align-items:center;gap:10px;padding:12px 13px;border-bottom:1px solid var(--line);
  background:var(--panel)}
.re-card-ic{width:30px;height:30px;border-radius:9px;background:var(--blue-soft);color:var(--blue);
  display:grid;place-items:center;flex-shrink:0}
.re-card.full .re-card-ic{background:var(--blue);color:#fff}
.re-card-t{font-size:13.5px;font-weight:700;color:var(--ink);flex:1}
.re-badge{font-size:11px;font-weight:600;color:var(--muted);background:var(--panel);
  border:1px solid var(--line);border-radius:999px;padding:2px 9px;transition:all .14s}
.re-badge.on{color:var(--blue);background:var(--blue-soft);border-color:var(--blue-border)}
.re-opts{padding:7px 7px 9px}
.re-opt{display:flex;align-items:center;gap:11px;padding:7px 8px;border-radius:9px;cursor:pointer;transition:background .12s}
.re-opt:hover{background:var(--blue-soft)}
.re-opt input{position:absolute;opacity:0;width:0;height:0}
.re-check{width:19px;height:19px;border-radius:6px;border:1.7px solid var(--line2);background:var(--surface);
  display:grid;place-items:center;flex-shrink:0;transition:all .14s}
.re-check::after{content:"";width:5px;height:9px;border:solid #fff;border-width:0 2px 2px 0;
  transform:rotate(45deg) scale(0);margin-top:-2px;transition:transform .14s}
.re-opt input:checked + .re-check{background:var(--blue);border-color:var(--blue)}
.re-opt input:checked + .re-check::after{transform:rotate(45deg) scale(1)}
.re-opt-l{font-size:13px;color:var(--ink2)}
.re-switch{position:relative;display:inline-flex;flex-shrink:0}
.re-switch input{position:absolute;opacity:0;width:0;height:0}
.re-slider{width:38px;height:22px;border-radius:999px;background:var(--line2);position:relative;transition:background .16s}
.re-slider::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;
  background:var(--surface);box-shadow:0 1px 3px rgba(0,0,0,.3);transition:transform .16s}
.re-switch input:checked + .re-slider{background:var(--blue)}
.re-switch input:checked + .re-slider::after{transform:translateX(16px)}
.re-switch input:indeterminate + .re-slider{background:var(--blue-border)}
.re-switch input:indeterminate + .re-slider::after{transform:translateX(8px)}

.re-full{display:flex;align-items:center;gap:15px;padding:20px;border-radius:10px;
  background:linear-gradient(135deg,var(--blue-soft),var(--surface));border:1px solid var(--blue-border)}
.re-full-ic{width:46px;height:46px;border-radius:13px;background:var(--blue);color:#fff;display:grid;place-items:center;flex-shrink:0}
.re-full b{font-size:15px;color:var(--ink)} .re-full p{font-size:13px;color:var(--ink3);margin-top:3px;line-height:1.5}

.re-foot{padding:14px 26px;border-top:1px solid var(--line);display:flex;gap:10px;justify-content:flex-end;background:var(--surface)}
.re-save{box-shadow:0 8px 20px rgba(21,94,239,.28)}
@media(max-width:560px){.re-row2{grid-template-columns:1fr}.re-grid{grid-template-columns:1fr}}

@keyframes reFade{from{opacity:0}to{opacity:1}}

/* team list search */
.tm-search{height:34px;border:1.5px solid var(--line);border-radius:9px;padding:0 12px;font-size:13px;
  min-width:190px;color:var(--ink);background:var(--surface);transition:border .14s,box-shadow .14s}
.tm-search:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft)}
@media(max-width:560px){.tm-search{min-width:0;width:130px}}

/* Profile & API — two columns. The profile is a short list of small fields,
   so it gets a capped narrow column; the API card keeps the rest of the width
   because that is where the code examples need room. */
.ps-grid{display:grid;grid-template-columns:minmax(280px,460px) minmax(0,1fr);
  gap:18px;align-items:start}
.ps-grid .ps-prof{grid-column:1;grid-row:1 / span 2}
.ps-grid .ps-bal{grid-column:2;grid-row:1}
.ps-grid .ps-api{grid-column:2;grid-row:2}
/* denser than the default form rhythm — the card is a settings list, not a page */
.ps-prof{gap:11px;padding:16px 18px}
.ps-prof h3{font-size:14px}
.ps-prof .field{gap:4px}
.ps-prof .field label{font-size:12px}
.ps-prof input{padding:7px 10px;font-size:13px;border-radius:7px}
.ps-prof .hint{font-size:11px;line-height:1.45}
/* .av only ever got a size — give the profile one the avatar chrome too */
.ps-prof .av.lg{width:42px;height:42px;font-size:15px;flex:none;display:grid;
  place-items:center;border-radius:50%;overflow:hidden;font-weight:600;
  color:var(--ink2);background:var(--panel);border:1px solid var(--line)}
.ps-prof .btn.sm{padding:5px 9px;font-size:12px}
.ps-prof #pSave{align-self:flex-start;margin-top:2px;padding:7px 14px;font-size:13px}
@media(max-width:860px){.ps-grid{grid-template-columns:1fr}
  .ps-grid .ps-prof,.ps-grid .ps-bal,.ps-grid .ps-api{grid-column:auto;grid-row:auto}}

tr.log-group:hover{background:var(--blue-soft)}

/* ---- dark mode ---------------------------------------------------- */
body.dark{
  --bg:#0F1216; --surface:#181C22; --panel:#20252D;
  --ink:#E6E9EF; --ink2:#C7CDD8; --ink3:#AEB6C4; --muted:#828B9C;
  --line:#2A303A; --line2:#39404C;
  --blue-soft:rgba(21,94,239,.20); --blue-border:rgba(120,160,255,.45);
  --green:#3CCB7F; --green-soft:rgba(7,148,85,.18); --green-border:rgba(60,203,127,.35);
  --amber:#FDB022; --amber-soft:rgba(181,71,8,.24); --amber-border:rgba(253,176,34,.3);
  --red:#F97066; --red-soft:rgba(217,45,32,.22); --red-border:rgba(249,112,102,.3);
  --purple:#A48AFB;
  --shadow:0 1px 2px rgba(0,0,0,.45);
  --shadow-btn:inset 0 0 0 1px rgba(255,255,255,.14),0 1px 2px rgba(0,0,0,.5);
  color-scheme:dark;
}

/* library drag-to-reorder */
.lib-grip{user-select:none}
.lib-grip:active{cursor:grabbing}
.lib-drag-ghost{opacity:.4}

/* =====================================================================
   GLOBAL SEARCH  — command-palette dropdown under the topbar search box
   ===================================================================== */
.search-results{position:absolute;top:calc(100% + 8px);left:0;width:340px;max-width:80vw;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 14px 38px rgba(10,13,18,.16);padding:6px;z-index:40;
  max-height:min(62vh,440px);overflow-y:auto;
  visibility:hidden;opacity:0;transform:translateY(-6px);
  transition:opacity .15s ease,transform .15s ease,visibility 0s linear .15s}
.search-results.show{visibility:visible;opacity:1;transform:translateY(0);
  transition:opacity .15s ease,transform .15s ease,visibility 0s}
.sr-item{display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;
  border:none;background:transparent;border-radius:8px;cursor:pointer;text-align:left;
  font-family:inherit;font-size:13.5px;color:var(--ink2);transition:background .1s}
.sr-item .sr-ic{color:var(--muted);display:grid;place-items:center;flex-shrink:0}
.sr-item .sr-label{color:var(--ink);font-weight:500;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.sr-item .sr-group{margin-left:auto;padding-left:8px;font-size:10.5px;color:var(--muted);
  font-weight:600;letter-spacing:.04em}
.sr-item:hover,.sr-item.active{background:var(--panel)}
.sr-item.active .sr-ic{color:var(--blue)}
.sr-item mark.sr-hl{background:var(--blue-soft);color:var(--blue);border-radius:3px;padding:0 1px}
.sr-empty{padding:14px 10px;text-align:center;font-size:13px;color:var(--muted)}
.sr-foot{margin-top:4px;padding:7px 10px 4px;border-top:1px solid var(--line);
  font-size:11px;color:var(--muted);display:flex;gap:12px;flex-wrap:wrap}
.sr-foot kbd{font-family:inherit;background:var(--panel);border:1px solid var(--line);
  border-radius:5px;padding:1px 5px;font-size:10.5px;color:var(--ink3)}

/* =====================================================================
   TOP-UP modal — clean, stepped, FARFETCH-style checkout
   ===================================================================== */
.tu-h{font-size:12.5px;color:var(--muted);font-weight:600;margin:0 0 10px}
.tu-methods{display:flex;flex-direction:column;gap:10px;margin:2px 0 4px}
.tu-method{display:flex;align-items:center;gap:12px;width:100%;padding:13px 15px;
  border:1px solid var(--line);border-radius:12px;background:var(--surface);
  cursor:pointer;text-align:left;transition:.13s;font-family:inherit}
.tu-method:hover{border-color:var(--line2)}
.tu-method.sel{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.tu-method .mlogo{flex:none;display:grid;place-items:center}
.tu-method .mname{flex:1;font-size:14.5px;font-weight:600;color:var(--ink);line-height:1.25}
.tu-method .msub{font-size:11.5px;color:var(--muted);font-weight:400;margin-top:2px}
.tu-radio{flex:none;width:20px;height:20px;border-radius:50%;border:2px solid var(--line2);
  display:grid;place-items:center}
.tu-method.sel .tu-radio{border-color:var(--ink)}
.tu-method.sel .tu-radio::after{content:"";width:10px;height:10px;border-radius:50%;background:var(--ink)}
.tu-next{width:100%;padding:14px;border:none;border-radius:999px;background:var(--ink);
  color:var(--bg);font-size:15px;font-weight:600;cursor:pointer;font-family:inherit;transition:.13s}
.tu-next:hover{opacity:.88}
.tu-next:disabled{opacity:.5;cursor:not-allowed}
.tu-due{display:flex;justify-content:space-between;align-items:flex-start;
  padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:16px}
.tu-due .k{font-size:12.5px;color:var(--muted)}
.tu-due .big{font-size:20px;font-weight:700;color:var(--ink);margin-top:3px}
.tu-due .sm{font-size:13.5px;font-weight:600;margin-top:3px}
.tu-badge{background:#1BA97A;color:#fff;text-align:center;padding:9px 12px;
  border-radius:10px 10px 0 0;font-size:12.5px;font-weight:600}
.tu-addr{border:1px dashed #1BA97A;border-top:none;border-radius:0 0 10px 10px;
  padding:12px 14px;display:flex;align-items:center;gap:10px}
.tu-addr code{flex:1;font-family:ui-monospace,monospace;font-size:12.5px;
  word-break:break-all;line-height:1.55;color:var(--ink)}
.tu-addr button{flex:none;background:none;border:none;cursor:pointer;color:var(--muted);
  padding:5px;border-radius:6px}
.tu-addr button:hover{background:var(--panel);color:var(--ink)}
.tu-warn{font-size:11.5px;color:var(--muted);text-align:center;margin:10px 6px 0;line-height:1.5}
.tu-qr-wrap{text-align:center;margin:18px 0 4px}
.tu-qr-wrap .lbl{font-size:13px;color:var(--muted);margin-bottom:10px}
.tu-qr-wrap img{width:168px;height:168px;border-radius:12px;border:1px solid var(--line)}
.tu-timer{display:flex;justify-content:center;gap:14px;align-items:center;flex-wrap:wrap;
  background:var(--panel);border-radius:10px;padding:9px 12px;margin-top:14px;
  font-size:12px;color:var(--ink3);font-weight:500}
.tu-timer .clk{display:inline-flex;align-items:center;gap:5px}
.tu-success{text-align:center;padding:28px 10px 12px}
.tu-check{width:66px;height:66px;border-radius:50%;background:#1BA97A;display:grid;
  place-items:center;margin:0 auto 18px;animation:tuPop .3s ease}
@keyframes tuPop{from{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}
.tu-success h3{font-size:20px;font-weight:700;margin:0 0 6px}
.tu-success p{font-size:13.5px;color:var(--muted);margin:0;line-height:1.55}

/* ===================================================================== */
/*  Manage Business modal — tabbed, near full-screen                     */
/* ===================================================================== */
.mg-tabs{display:flex;gap:2px;padding:0 14px;border-bottom:1px solid var(--line);
  overflow-x:auto;flex:none;background:var(--surface)}
.mg-tab{padding:13px 16px;border:none;background:none;font-family:inherit;font-size:13.5px;
  font-weight:600;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;
  white-space:nowrap;display:inline-flex;align-items:center;gap:7px;transition:.12s}
.mg-tab:hover{color:var(--ink2)}
.mg-tab svg{opacity:.85}
.mg-tab.active{color:var(--blue);border-bottom-color:var(--blue)}
.mg-tab.danger.active{color:var(--red);border-bottom-color:var(--red)}
.mg-body{padding:18px 22px;overflow:auto;flex:1;min-height:0;background:var(--panel)}
.mg-panel{display:flex;flex-direction:column;gap:16px}
.mg-panel[hidden]{display:none}
@media(max-width:560px){
  .mg-tab{padding:11px 12px;font-size:12.5px}
  .mg-body{padding:14px}
}

/* =====================================================================
   RESPONSIVE HARDENING  — make the whole console usable on phones/tablets.
   Appended last so these rules win on equal specificity. Additive only.
   ===================================================================== */

/* ---- data tables: scroll inside the card, never the whole page ------ */
@media(max-width:820px){
  /* every console table becomes its own horizontal scroll region */
  .content table{display:block;width:100%;max-width:100%;
    overflow-x:auto;-webkit-overflow-scrolling:touch}
  .content table thead,.content table tbody{display:table;width:100%;min-width:max-content}
}
@media(max-width:680px){
  .content th{padding:8px 10px;font-size:11px}
  .content td{padding:9px 10px;font-size:13px}
  .content td .sub{font-size:11px}
  .page-head h2{font-size:20px}
  .page-head p{font-size:13.5px}
  /* Reports page: collapse the inline fixed-count grids (beat inline via !important) */
  .content [style*="repeat(5,1fr)"]{grid-template-columns:repeat(2,1fr)!important}
  .content [style*="grid-template-columns:1fr 1fr"]{grid-template-columns:1fr!important}
  /* class-less fixed-width filters / selects -> full width & tappable */
  #ntFilter,#aUser,#aAction,#rLang,#cSearch,#lSearch,#libQ,#libSearch{width:100%!important}
  .rowflex>[style*="width:170px"]{width:100%!important;margin-inline-start:0!important}
}
@media(max-width:430px){
  .content [style*="repeat(5,1fr)"]{grid-template-columns:1fr!important}
}

/* ---- CSV / preview tables live in body-level modals (outside .content) */
.csv-tbl{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
.csv-tbl>*{min-width:max-content}

/* ---- impersonation banner: wrap instead of overflowing the topbar ---- */
.imp-banner{gap:10px}
@media(max-width:560px){
  .imp-banner{flex-wrap:wrap;padding:9px 14px!important;font-size:12.5px!important}
  .imp-banner>span{min-width:0}
  .imp-banner .btn.sm{width:100%}
}

/* ---- drawer polish: lock body scroll + cap width on tiny phones ------ */
@media(max-width:820px){
  body.nav-open{overflow:hidden}
  .sidebar{width:min(252px,86vw)}
  .nav-item{min-height:44px}
  .side-user .logout{min-width:40px;min-height:40px;display:grid;place-items:center}
}

/* ---- fluid topbar search so it shrinks before it is hidden ---------- */
.searchbox{min-width:0}
.searchbox input{max-width:280px}

/* ---- auth screen padding / type on small phones --------------------- */
@media(max-width:480px){
  .auth-form{padding:24px 18px}
  .auth-card h2{font-size:21px}
}

/* ---- modals / dialogs: footers wrap, controls become touch-sized ---- */
@media(max-width:560px){
  .re-toolbar{flex-wrap:wrap;justify-content:flex-start;gap:8px}
  .re-tools{width:100%;justify-content:flex-start}
  .re-foot{flex-wrap:wrap;flex-direction:column-reverse;gap:8px}
  .re-foot>.btn{width:100%}
  #aUser,#aAction{width:100%!important}
  input,select,textarea{font-size:16px}   /* >=16px stops iOS focus-zoom */
  input:not(.tc-input),select,textarea{min-height:44px}
  .btn{min-height:44px}
  .btn.sm{min-height:38px}
  /* stack paired custom-field / variable-map controls */
  .bVarCol,.cfKey{max-width:none!important;width:100%!important}
  #leLang{max-width:none!important;width:100%!important}
  #bcCC{min-width:0!important}
  /* long wallet / reference strings inside payment modals must wrap */
  .modal-card img,[style*="max-width:420px"] img,[style*="max-width:780px"] img{max-width:100%;height:auto}
}
/* =====================================================================
   TOP UP — redesigned shell, stepper, amount field, methods, animations
   Appended last so it wins over the earlier .tu-* rules.
   ===================================================================== */
@keyframes tuOv{from{opacity:0}to{opacity:1}}
@keyframes tuIn{from{opacity:0;transform:translateY(16px) scale(.97)}to{opacity:1;transform:none}}
@keyframes tuUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes tuRing{0%{transform:scale(.85);opacity:.55}100%{transform:scale(1.75);opacity:0}}
@keyframes tuDraw{to{stroke-dashoffset:0}}
@keyframes tuSpin{to{transform:rotate(360deg)}}
@keyframes tuPulse{0%,100%{opacity:1}50%{opacity:.5}}
@keyframes tuQr{from{opacity:0;transform:scale(.93)}to{opacity:1;transform:none}}

.tu-overlay{position:fixed;inset:0;z-index:70;background:rgba(15,23,42,.55);
  backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);
  display:flex;align-items:center;justify-content:center;padding:22px;animation:tuOv .18s ease}
.tu-modal{background:var(--surface);border-radius:20px;width:100%;max-width:430px;max-height:92vh;
  display:flex;flex-direction:column;overflow:hidden;box-shadow:0 28px 70px rgba(0,0,0,.34);
  animation:tuIn .38s cubic-bezier(.2,.75,.3,1) both}
.tu-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;flex:none}
.tu-title{display:flex;align-items:center;gap:9px;font-size:17px;font-weight:750;color:var(--ink)}
.tu-title svg{color:var(--blue)}
.tu-x{width:32px;height:32px;border-radius:9px;border:none;background:var(--panel);color:var(--muted);
  font-size:20px;line-height:1;cursor:pointer;transition:background .15s,color .15s}
.tu-x:hover{background:var(--line);color:var(--ink)}

.tu-steps{display:flex;align-items:center;gap:7px;padding:0 20px 14px;flex:none}
.tu-step{display:flex;align-items:center;gap:7px;flex:none}
.tu-step i{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;font-style:normal;
  font-size:11px;font-weight:700;background:var(--panel);color:var(--muted);border:1px solid var(--line);
  transition:background .25s ease,color .25s ease,border-color .25s ease,transform .25s ease}
.tu-step b{font-size:11.5px;font-weight:650;color:var(--muted);transition:color .25s ease}
.tu-step.on i{background:var(--blue);color:#fff;border-color:var(--blue);transform:scale(1.09)}
.tu-step.on b{color:var(--ink)}
.tu-step.done i{background:var(--green);border-color:var(--green);color:#fff}
.tu-step.done b{color:var(--ink3)}
.tu-step-line{flex:1;height:2px;border-radius:2px;background:var(--line);position:relative;overflow:hidden}
.tu-step-line::after{content:'';position:absolute;inset:0;background:var(--green);
  transform:scaleX(0);transform-origin:left;transition:transform .45s cubic-bezier(.2,.7,.3,1)}
.tu-step-line.done::after{transform:scaleX(1)}

.tu-body{padding:4px 20px 20px;overflow:auto;flex:1;min-height:0}
.tu-body > *{animation:tuUp .42s cubic-bezier(.2,.7,.3,1) both}
.tu-body > *:nth-child(1){animation-delay:.02s}
.tu-body > *:nth-child(2){animation-delay:.08s}
.tu-body > *:nth-child(3){animation-delay:.14s}
.tu-body > *:nth-child(4){animation-delay:.20s}

.tu-sec{margin-bottom:18px}
.tu-amt-lbl{font-size:12.5px;font-weight:650;color:var(--muted);margin-bottom:8px}
.tu-amt-field{display:flex;align-items:center;gap:8px;border:1.5px solid var(--line);border-radius:14px;
  background:var(--surface);padding:12px 16px;transition:border-color .18s ease,box-shadow .18s ease}
.tu-amt-field:focus-within{border-color:var(--blue);box-shadow:0 0 0 4px var(--blue-soft)}
.tu-amt-field.err{border-color:var(--red);box-shadow:0 0 0 4px var(--red-soft)}
.tu-amt-field input{flex:1;border:none;outline:none;background:none;font-family:inherit;
  font-size:26px;font-weight:750;color:var(--ink);letter-spacing:-.02em;min-width:0;padding:0}
.tu-amt-field input::-webkit-outer-spin-button,
.tu-amt-field input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.tu-amt-field input[type=number]{-moz-appearance:textfield}
.tu-cur{flex:none;font-size:13px;font-weight:700;color:var(--muted);letter-spacing:.03em}

.tu-presets{display:flex;gap:8px;flex-wrap:wrap;margin-top:11px}
.tu-preset{padding:8px 14px;border-radius:999px;border:1px solid var(--line);background:var(--surface);
  color:var(--ink2);font-family:inherit;font-size:13px;font-weight:650;cursor:pointer;
  transition:transform .12s ease,background .16s ease,border-color .16s ease,color .16s ease}
.tu-preset:hover{border-color:var(--line2);transform:translateY(-1px)}
.tu-preset:active{transform:scale(.95)}
.tu-preset.on{background:var(--blue);border-color:var(--blue);color:#fff}
.tu-custom{display:inline-flex;align-items:center;gap:5px;color:var(--blue);border-style:dashed}
.tu-custom:hover{background:var(--blue-soft)}

.tu-method{transition:border-color .16s ease,box-shadow .16s ease,transform .12s ease,background .16s ease}
.tu-method:hover{transform:translateY(-1px)}
.tu-method.sel{border-color:var(--blue);background:var(--blue-soft);
  box-shadow:inset 0 0 0 1px var(--blue),0 4px 14px rgba(21,94,239,.10)}
.tu-method.sel .tu-radio{border-color:var(--blue)}
.tu-method.sel .tu-radio::after{background:var(--blue);animation:tuPop .22s cubic-bezier(.18,.89,.32,1.28)}
.tu-radio{transition:border-color .16s ease}

.tu-next{width:100%;padding:15px;border:none;border-radius:14px;background:var(--ink);color:#fff;
  font-family:inherit;font-size:15px;font-weight:700;cursor:pointer;margin-top:4px;
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  transition:transform .12s ease,filter .16s ease,opacity .16s ease}
.tu-next:hover{filter:brightness(1.12)}
.tu-next:active{transform:scale(.98)}
.tu-next:disabled{opacity:.6;cursor:default;transform:none}
.tu-next.loading::before{content:'';width:15px;height:15px;border-radius:50%;flex:none;
  border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:tuSpin .7s linear infinite}

.tu-qr-wrap img{animation:tuQr .45s cubic-bezier(.2,.7,.3,1) both}
.tu-timer .clk{animation:tuPulse 2s ease-in-out infinite}

.tu-check{position:relative;animation:tuPop .55s cubic-bezier(.18,.89,.32,1.28) both;
  box-shadow:0 12px 30px rgba(27,169,122,.35)}
.tu-check::before{content:'';position:absolute;inset:0;border-radius:50%;border:2px solid #1BA97A;
  animation:tuRing .95s .15s ease-out both}
.tu-check path{stroke-dasharray:1;stroke-dashoffset:1;animation:tuDraw .5s .35s ease forwards}

@media (prefers-reduced-motion:reduce){
  .tu-overlay,.tu-modal,.tu-body > *,.tu-check,.tu-check::before,.tu-qr-wrap img,.tu-timer .clk{animation:none}
  .tu-check path{stroke-dashoffset:0}
}
@media (max-width:480px){
  .tu-overlay{padding:0;align-items:flex-end}
  .tu-modal{max-width:none;border-radius:20px 20px 0 0;max-height:94vh}
  .tu-amt-field input{font-size:23px}
}

/* Top Up — dark-mode fix + stacked FIB links -------------------------- */
/* In dark mode --ink flips to near-white, so background:var(--ink) with
   white text became invisible. Use the app's primary blue there instead. */
body.dark .tu-next{background:var(--blue);color:#fff}
body.dark .tu-next:hover{background:var(--blue-dark);filter:none}
body.dark .tu-next:disabled{background:var(--blue);opacity:.5}

/* FIB app links stacked one under the other, full width */
.tu-fiblinks{display:flex;flex-direction:column;gap:8px;margin-top:2px}
.tu-fiblinks .btn{width:100%;justify-content:center}

/* =====================================================================
   TOP UP — brand-coloured buttons. --tu-accent is set from JS to the
   selected provider's colour: FIB #009B90, Tether #50AF95, PayPal #0070BA.
   Appended last so it overrides the earlier blue/ink rules (incl. body.dark).
   ===================================================================== */
.tu-modal{--tu-accent:#009B90;--tu-accent-soft:rgba(0,155,144,.12);--tu-accent-ring:rgba(0,155,144,.22)}

.tu-next{background:var(--tu-accent);color:#fff}
.tu-next:hover{background:var(--tu-accent);filter:brightness(1.12)}
.tu-next:disabled{background:var(--tu-accent);opacity:.55}
body.dark .tu-next{background:var(--tu-accent);color:#fff}
body.dark .tu-next:hover{background:var(--tu-accent);filter:brightness(1.15)}
body.dark .tu-next:disabled{background:var(--tu-accent);opacity:.5}

.tu-title svg{color:var(--tu-accent)}
.tu-step.on i{background:var(--tu-accent);border-color:var(--tu-accent);color:#fff}

.tu-amt-field:focus-within{border-color:var(--tu-accent);box-shadow:0 0 0 4px var(--tu-accent-ring)}
.tu-preset.on{background:var(--tu-accent);border-color:var(--tu-accent);color:#fff}
.tu-custom{color:var(--tu-accent)}
.tu-custom:hover{background:var(--tu-accent-soft)}

.tu-method.sel{border-color:var(--tu-accent);background:var(--tu-accent-soft);
  box-shadow:inset 0 0 0 1px var(--tu-accent),0 4px 14px var(--tu-accent-soft)}
.tu-method.sel .tu-radio{border-color:var(--tu-accent)}
.tu-method.sel .tu-radio::after{background:var(--tu-accent)}

/* pay screen */
.tu-fiblinks .btn.primary{background:var(--tu-accent);border-color:var(--tu-accent);color:#fff;box-shadow:none}
.tu-fiblinks .btn.primary:hover{background:var(--tu-accent);filter:brightness(1.1)}
.tu-badge{background:var(--tu-accent)}
.tu-addr{border-color:var(--tu-accent)}
.netchip.active{border-color:var(--tu-accent);background:var(--tu-accent-soft);color:var(--tu-accent)}

/* FIB app links — each button in its own app's brand colour.
   Colours sampled from the official FIB app icons on Google Play:
     personal  #11998F (teal, same as our fib.svg logo)
     business  #0174B5 (blue)
     corporate #3F5EAF (indigo)                                        */
.tu-fiblinks .btn{width:100%;justify-content:center;color:#fff;border:1px solid transparent;
  box-shadow:none;font-weight:650;transition:filter .15s ease,transform .1s ease}
.tu-fiblinks .btn:hover{color:#fff;filter:brightness(1.10)}
.tu-fiblinks .btn:active{transform:scale(.985)}
.tu-fiblinks .fib-personal{background:#11998F}
.tu-fiblinks .fib-business{background:#0174B5}
.tu-fiblinks .fib-corporate{background:#3F5EAF}

/* FIB fee notice — amber tint + amber icon, but DARK readable body text
   (the plain .alert.amber colours the text amber, which reads poorly).
   Specificity kept at .alert.amber.tu-fee so it beats .alert.amber. */
.alert.amber.tu-fee{align-items:flex-start;gap:9px;line-height:1.55;font-size:12.5px;
  margin-bottom:14px;text-align:left;color:var(--ink2)}
.alert.amber.tu-fee svg{flex:none;margin-top:1px;color:var(--amber)}
.alert.amber.tu-fee b{font-weight:750;color:var(--ink)}

/* QR — a scanner needs dark modules on a LIGHT background, so the QR stays
   light. Instead of a harsh white block we present it as a compact rounded
   "scan card": soft off-white, padded (which also gives the code the quiet
   zone FIB's image ships without), with a gentle shadow so it sits calmly on
   the dark surface rather than glaring. */
.tu-qr-wrap img{width:186px;height:186px;padding:13px;border:none;border-radius:18px;
  background:#fff;box-shadow:0 4px 14px rgba(16,24,40,.10)}
/* dark: card matches the softened QR white (#F3F6F8 from softenQr) — no seam,
   and a soft shadow so the tile sits on the surface instead of glaring */
body.dark .tu-qr-wrap img{background:#F3F6F8;box-shadow:0 10px 30px rgba(0,0,0,.5)}

/* status + countdown merged into a single bar */
.tu-status{display:flex;align-items:center;justify-content:space-between;gap:10px}
.tu-status .tu-status-l{display:inline-flex;align-items:center;gap:7px;font-weight:650}
.tu-status .tu-status-c{font-variant-numeric:tabular-nums;font-weight:700;opacity:.85;
  white-space:nowrap;font-size:12.5px}

/* balance went up — a brief pulse so the live update is noticeable.
   Scale only (no colour change): the figures sit on white, on the blue
   balance card and inside the header pill, so a tint would clash somewhere. */
@keyframes balBump{0%{transform:scale(1)}38%{transform:scale(1.08)}100%{transform:scale(1)}}
.bal-bump{animation:balBump .55s cubic-bezier(.2,.7,.3,1);display:inline-block}
.bal-card .bal-bump,.balance-pill.bal-bump{display:block}
@media (prefers-reduced-motion:reduce){.bal-bump{animation:none}}

/* =====================================================================
   Account balance card — "aurora glass".
   Mesh gradient (cyan + violet blooms over the brand blue), a fine grid
   that fades away, a slow light sweep, and frosted-glass action buttons.
   ===================================================================== */
/* sit at natural height instead of stretching to match the recent-activity
   card beside it — grid items default to align-self:stretch */
.g-21>.bal-card{align-self:start}
.bal-card{
  position:relative;
  overflow:hidden;
  border:none;
  color:#fff;
  background:
    radial-gradient(85% 70% at 88% 4%,  rgba(56,189,248,.38), transparent 58%),
    radial-gradient(75% 70% at 2% 98%,  rgba(139,92,246,.36), transparent 58%),
    radial-gradient(60% 55% at 55% 45%, rgba(255,255,255,.07), transparent 62%),
    linear-gradient(150deg, #1C63F2 0%, #0E3FB4 52%, #232A82 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22), 0 14px 34px rgba(16,45,120,.30);
}
/* fine grid, masked so it fades out toward the bottom-left */
.bal-card::before{
  content:'';position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:
    linear-gradient(rgba(255,255,255,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.07) 1px, transparent 1px);
  background-size:24px 24px;
  -webkit-mask-image:radial-gradient(115% 90% at 82% 10%, #000 25%, transparent 78%);
          mask-image:radial-gradient(115% 90% at 82% 10%, #000 25%, transparent 78%);
}
/* slow light sweep, like the sheen on a real card */
.bal-card::after{
  content:'';position:absolute;top:-70%;left:0;width:45%;height:240%;z-index:0;pointer-events:none;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.13), transparent);
  transform:translateX(-120%) rotate(18deg);
  animation:balSheen 9s ease-in-out infinite;
}
@keyframes balSheen{0%,58%{transform:translateX(-120%) rotate(18deg)}100%{transform:translateX(330%) rotate(18deg)}}
.bal-card > *{position:relative;z-index:1}

.bal-card .lbl{font-size:11.5px;font-weight:650;letter-spacing:.08em;text-transform:uppercase;
  color:rgba(255,255,255,.70)}
.bal-card .amt{font-size:42px;font-weight:750;letter-spacing:-.025em;margin-top:10px;
  text-shadow:0 2px 18px rgba(0,0,0,.20)}
.bal-card p{font-size:12.8px;color:rgba(255,255,255,.72);margin:8px 0 18px;line-height:1.55}

/* frosted-glass actions; Top Up is the solid CTA */
.bal-actions{display:flex;gap:10px}
.bal-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:11px 14px;border-radius:11px;font-family:inherit;font-size:13.5px;font-weight:650;
  color:#fff;cursor:pointer;border:1px solid rgba(255,255,255,.28);
  background:rgba(255,255,255,.10);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  transition:background .16s ease,border-color .16s ease,transform .1s ease}
.bal-btn:hover{background:rgba(255,255,255,.20);border-color:rgba(255,255,255,.45)}
.bal-btn:active{transform:scale(.97)}
.bal-btn svg{flex:none}
.bal-btn.primary{background:rgba(255,255,255,.94);color:#14318A;border-color:transparent;
  box-shadow:0 6px 16px rgba(0,0,0,.18)}
.bal-btn.primary:hover{background:#fff}

/* rates + fee note under the actions */
.bal-fees{margin-top:18px;padding-top:14px;border-top:1px solid rgba(255,255,255,.16)}
.bal-fees .bf-t{font-size:10.5px;font-weight:650;letter-spacing:.08em;text-transform:uppercase;
  color:rgba(255,255,255,.62);margin-bottom:7px}
.bf-row{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  font-size:12.5px;line-height:1.5;padding:2.5px 0;color:rgba(255,255,255,.80)}
.bf-row b{font-weight:650;color:#fff;white-space:nowrap}
.bal-card p.bf-note{font-size:11.8px;line-height:1.6;color:rgba(255,255,255,.60);
  margin:10px 0 0}
.bal-card p.bf-note b{font-weight:650;color:rgba(255,255,255,.82)}

@media (prefers-reduced-motion:reduce){.bal-card::after{animation:none;opacity:0}}
@media (max-width:560px){.bal-card .amt{font-size:34px}}

/* =====================================================================
   Collapsible sidebar — collapses to a 72px icon rail.
   The labels don't just disappear: they FADE and SQUEEZE in step with the
   width, so both directions feel like one motion.
     collapsing -> text fades fast (no delay), width follows
     expanding  -> width opens first, text fades in after (delay), so the
                   labels never fight for space that isn't there yet.
   Desktop only (below 680px the sidebar is a slide-out drawer).
   ===================================================================== */
:root{--rail-ease:cubic-bezier(.22,.61,.36,1);--rail-dur:.32s}

.sidebar{transition:width var(--rail-dur) var(--rail-ease)}
.side-head{overflow:hidden;white-space:nowrap;
  transition:padding var(--rail-dur) var(--rail-ease)}

/* the round toggle, pinned on the sidebar's right edge */
.side-min{position:absolute;top:30px;right:-12px;width:24px;height:24px;padding:0;
  border-radius:50%;border:1px solid var(--line);background:var(--surface);color:var(--muted);
  display:grid;place-items:center;cursor:pointer;z-index:22;
  box-shadow:0 2px 8px rgba(10,13,18,.10);
  transition:color .15s ease,background .15s ease,border-color .15s ease}
.side-min:hover{color:var(--blue);border-color:var(--blue-border);background:var(--blue-soft)}
.side-min svg{transition:transform var(--rail-dur) var(--rail-ease)}
body.nav-min .side-min svg{transform:rotate(180deg)}

/* ---------- the pieces that fade + squeeze ---------- */
.side-brand{min-width:0;max-width:170px;overflow:hidden;white-space:nowrap;opacity:1;
  transition:max-width var(--rail-dur) var(--rail-ease),
             opacity .22s ease .10s, margin var(--rail-dur) var(--rail-ease)}
body.nav-min .side-brand{max-width:0;opacity:0;margin-left:-10px;
  transition:max-width var(--rail-dur) var(--rail-ease), opacity .12s ease, margin var(--rail-dur) var(--rail-ease)}

.nav-txt{display:inline-block;max-width:170px;overflow:hidden;white-space:nowrap;
  opacity:1;transform:translateX(0);
  transition:max-width var(--rail-dur) var(--rail-ease),
             opacity .22s ease .10s,
             transform .26s var(--rail-ease) .06s}
body.nav-min .nav-txt{max-width:0;opacity:0;transform:translateX(-8px);
  transition:max-width var(--rail-dur) var(--rail-ease),
             opacity .12s ease, transform .16s ease}

.nav-label{overflow:hidden;max-height:26px;opacity:1;
  transition:max-height var(--rail-dur) var(--rail-ease),
             opacity .2s ease .10s, padding var(--rail-dur) var(--rail-ease)}
body.nav-min .nav-label{max-height:0;opacity:0;padding-top:0;padding-bottom:0;
  transition:max-height var(--rail-dur) var(--rail-ease), opacity .1s ease,
             padding var(--rail-dur) var(--rail-ease)}

.side-user .meta{max-width:150px;overflow:hidden;white-space:nowrap;opacity:1;
  transition:max-width var(--rail-dur) var(--rail-ease), opacity .22s ease .10s}
body.nav-min .side-user .meta{max-width:0;opacity:0;
  transition:max-width var(--rail-dur) var(--rail-ease), opacity .12s ease}

/* containers animate their spacing so nothing jumps */
.nav-item{position:relative;
  transition:background .14s ease,color .14s ease,
             gap var(--rail-dur) var(--rail-ease),
             padding var(--rail-dur) var(--rail-ease)}
.side-user{transition:padding var(--rail-dur) var(--rail-ease),
             gap var(--rail-dur) var(--rail-ease)}
.side-nav{transition:padding var(--rail-dur) var(--rail-ease)}

/* ---------- collapsed rail ---------- */
body.nav-min .sidebar{width:72px}
body.nav-min .side-head{padding:20px 0 14px;justify-content:center}
body.nav-min .side-nav{padding:6px 10px;overflow:visible}   /* let tooltips escape */
body.nav-min .nav-group{margin-bottom:10px}
body.nav-min .nav-item{justify-content:center;padding:11px 0;gap:0}
body.nav-min .side-foot{padding:12px 8px}
body.nav-min .side-user{flex-direction:column;gap:8px;padding:10px 0}

/* hover tooltips — only once the rail is closed */
body.nav-min .nav-item::after{
  content:attr(data-tip);position:absolute;left:calc(100% + 12px);top:50%;
  transform:translateY(-50%) translateX(-4px);
  background:var(--ink);color:var(--bg);font-size:12px;font-weight:600;white-space:nowrap;
  padding:6px 10px;border-radius:8px;opacity:0;pointer-events:none;z-index:30;
  box-shadow:0 8px 22px rgba(10,13,18,.22);
  transition:opacity .15s ease,transform .15s ease}
body.nav-min .nav-item:hover::after{opacity:1;transform:translateY(-50%) translateX(0)}

/* unread count becomes a corner dot on the icon */
body.nav-min .notif-badge{position:absolute;top:4px;right:11px;margin:0 !important;
  min-width:16px;height:16px;font-size:9.5px;padding:0 4px;border:2px solid var(--surface)}

/* never collapse on mobile — there the sidebar is a drawer */
@media(max-width:680px){
  .side-min{display:none}
  body.nav-min .sidebar{width:252px}
  body.nav-min .side-head{padding:20px 18px 14px;justify-content:flex-start}
  body.nav-min .side-brand{max-width:170px;opacity:1;margin-left:0}
  body.nav-min .side-nav{padding:6px 12px;overflow-y:auto}
  body.nav-min .nav-label{max-height:26px;opacity:1;padding:4px 8px}
  body.nav-min .nav-item{justify-content:flex-start;padding:8px 10px;gap:10px}
  body.nav-min .nav-txt{max-width:170px;opacity:1;transform:none}
  body.nav-min .nav-item::after{display:none}
  body.nav-min .side-user{flex-direction:row;padding:8px}
  body.nav-min .side-user .meta{max-width:150px;opacity:1}
  body.nav-min .notif-badge{position:static;margin-left:auto !important;border:none}
}
@media (prefers-reduced-motion:reduce){
  .sidebar,.side-min svg,.nav-txt,.side-brand,.nav-label,.side-user .meta,
  .nav-item,.side-user,.side-nav,.side-head{transition:none}
}

/* Top Up presets — fit all four (incl. Custom) on one row.
   The currency is already shown in the amount field, so the chips are
   just the number. Tighter padding/gap gives Custom room beside 100,000. */
.tu-presets{gap:7px}
.tu-preset{padding:8px 12px}


/* ==================================================================== *
 *  In-app dialogs — replaces window.alert / confirm / prompt
 * ==================================================================== */
.ui-ov{position:fixed;inset:0;z-index:90;background:rgba(15,23,42,.5);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;padding:24px;
  animation:uiFade .16s ease}
.ui-ov.closing{animation:uiFadeOut .13s ease forwards}
.ui-card{background:var(--surface);border-radius:14px;width:100%;
  max-height:92vh;overflow:auto;box-shadow:0 24px 60px rgba(0,0,0,.32);
  animation:uiRise .18s cubic-bezier(.2,.9,.3,1.1) both}
.ui-card .ui-head{padding:18px 22px 0}
.ui-card .ui-head h3{margin:0;font-size:17px;font-weight:700;
  letter-spacing:-.01em;color:var(--ink);line-height:1.35}
.ui-card .ui-body{padding:10px 22px 4px;font-size:14px;line-height:1.6;
  color:var(--ink3);white-space:pre-line}
.ui-card .ui-body .ui-msg{margin:0 0 12px}
.ui-card .ui-body .field{margin-top:2px}
.ui-card .ui-foot{padding:16px 22px 18px;display:flex;gap:8px;
  justify-content:flex-end}
.ui-card .ui-foot .btn[disabled]{opacity:.5;pointer-events:none}
@keyframes uiFade{from{opacity:0}to{opacity:1}}
@keyframes uiFadeOut{to{opacity:0}}
@keyframes uiRise{from{opacity:0;transform:translateY(10px) scale(.97)}
  to{opacity:1;transform:none}}

/* ---- full-screen progress ring -> tick ---- */
.ui-ov-plain{background:rgba(15,23,42,.62)}
.ui-prog{display:flex;flex-direction:column;align-items:center;gap:20px}
.ui-ring{width:104px;height:104px;border-radius:50%;position:relative;
  display:grid;place-items:center;
  border:5px solid rgba(255,255,255,.18);border-top-color:#fff;
  animation:uiSpin .75s linear infinite;
  transition:border-color .28s ease,background .28s ease}
.ui-ring.ok,.ui-ring.err{animation:uiPop .42s cubic-bezier(.18,.89,.32,1.28) both;
  border-color:transparent}
.ui-ring.ok{background:var(--green,#12B76A);box-shadow:0 14px 40px rgba(18,183,106,.45)}
.ui-ring.err{background:var(--red,#F04438);box-shadow:0 14px 40px rgba(240,68,56,.45)}
.ui-ring .ui-mark{width:52px;height:52px}
.ui-ring .ui-mark path{fill:none;stroke:#fff;stroke-width:5;stroke-linecap:round;
  stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:1;pathLength:1}
.ui-ring.ok .ui-mark path,.ui-ring.err .ui-mark path{
  animation:uiDraw .34s .18s ease forwards}
.ui-prog-msg{color:#fff;font-size:15.5px;font-weight:600;text-align:center;
  max-width:320px;line-height:1.5;text-shadow:0 1px 12px rgba(0,0,0,.3)}
@keyframes uiSpin{to{transform:rotate(360deg)}}
@keyframes uiPop{0%{transform:scale(.6);opacity:.7}60%{transform:scale(1.06)}
  100%{transform:scale(1);opacity:1}}
@keyframes uiDraw{to{stroke-dashoffset:0}}

@media (prefers-reduced-motion:reduce){
  .ui-ov,.ui-card,.ui-ring,.ui-ring .ui-mark path{animation:none}
  .ui-ring{border-top-color:#fff}
  .ui-ring .ui-mark path{stroke-dashoffset:0}
}

/* ---- OAuth "finishing sign-in" waiter -------------------------------
   Bottom-right card rather than a centred full-screen overlay: the
   provider's own popup opens centred, so anything in the middle sits
   directly behind it. Non-blocking by design — the popup has focus. */
.oauth-wait{position:fixed;right:20px;bottom:20px;z-index:88;
  display:flex;align-items:center;gap:12px;
  padding:13px 15px;border-radius:12px;
  background:var(--surface);border:1px solid var(--line);
  box-shadow:0 12px 34px rgba(0,0,0,.22);
  max-width:min(340px,calc(100vw - 40px));
  animation:owIn .22s cubic-bezier(.2,.9,.3,1.1) both}
.oauth-wait-spin{flex:none;width:26px;height:26px;border-radius:50%;
  border:2.5px solid var(--line2);border-top-color:var(--blue);
  animation:uiSpin .7s linear infinite}
.oauth-wait-txt{display:flex;flex-direction:column;gap:1px;min-width:0;line-height:1.4}
.oauth-wait-txt b{font-size:13.5px;font-weight:650;color:var(--ink)}
.oauth-wait-txt span{font-size:11.5px;color:var(--muted)}
.oauth-wait-x{flex:none;margin-left:2px;background:none;border:none;cursor:pointer;
  color:var(--muted);font-size:12.5px;font-weight:600;padding:5px 7px;border-radius:7px}
.oauth-wait-x:hover{background:var(--panel);color:var(--ink)}
@keyframes owIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media (max-width:520px){
  .oauth-wait{left:16px;right:16px;bottom:16px;max-width:none}
}
@media (prefers-reduced-motion:reduce){
  .oauth-wait,.oauth-wait-spin{animation:none}
}

/* ---- OAuth waiting state, taking over the sign-in card --------------
   The card's own contents fade out and the loader sits in their place, so
   the card keeps its size and the page doesn't jump. */
.auth-card.oauth-busy{position:relative}
.auth-card.oauth-busy > *:not(#oauthLoading){
  opacity:0;visibility:hidden;transition:opacity .18s ease}
.oauth-inline{position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:8px;gap:0;
  animation:owIn .22s cubic-bezier(.2,.9,.3,1.1) both}
.oauth-inline-h{margin-top:20px;font-size:16.5px;font-weight:700;
  letter-spacing:-.01em;color:var(--ink)}
.oauth-inline-p{margin-top:7px;font-size:13px;line-height:1.55;color:var(--muted);
  max-width:270px}
.oauth-inline .oauth-wait-x{margin-top:18px;font-size:13px}
@media (prefers-reduced-motion:reduce){
  .oauth-inline{animation:none}
}

/* ---- orbiting-dots loader -------------------------------------------
   Dots travel one flattened ellipse. Scale + opacity are keyed to the same
   cycle, so a dot swells and brightens along the near edge and shrinks across
   the far one — a ring seen at a steep angle. The far side stays visible
   enough that the complete circle reads, not just the near crescent. */
.ldots{position:relative;width:132px;height:82px;flex:none}
.ld{position:absolute;top:0;left:0;width:8px;height:8px;margin:-4px 0 0 -4px;
  border-radius:50%;background:var(--blue);
  offset-path:path("M 7,41 a 58,30 0 1,1 116,0 a 58,30 0 1,1 -116,0");
  offset-rotate:0deg;
  animation:ldRun var(--ldT,2.9s) linear infinite,
            ldDepth var(--ldT,2.9s) ease-in-out infinite;
  animation-delay:calc(var(--i) * (var(--ldT,2.9s) / -30));
}
@keyframes ldRun{to{offset-distance:100%}}
/* Phase measured off the path: 25% is the top of the ellipse (far side),
   75% is the bottom (near side), 0%/50% are the left/right extremes. */
@keyframes ldDepth{
  0%  {transform:scale(.88);opacity:.80}
  25% {transform:scale(.72);opacity:.62}   /* far edge — still clearly visible,
                                              so the ring reads as a full circle */
  50% {transform:scale(.88);opacity:.80}
  75% {transform:scale(1.22);opacity:1}    /* near edge — front of the ring */
  100%{transform:scale(.88);opacity:.80}
}
/* motion paths unavailable: fall back to a plain ring so nothing piles up */
@supports not (offset-path: path("M0,0 L1,1")){
  .ldots{width:52px;height:52px;border-radius:50%;
    border:3px solid var(--line2);border-top-color:var(--blue);
    animation:uiSpin .8s linear infinite}
  .ld{display:none}
}
@media (prefers-reduced-motion:reduce){
  .ld{animation-duration:5.6s}
}

/* =====================================================================
   Account switcher — one "Switch account" row in the user menu that
   slides a right-hand drawer in, listing every business on the login.
   ===================================================================== */
.dd-stack{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;text-align:left}
.dd-stack>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dd-sub{font-size:11.5px;color:var(--muted);font-weight:500}
.dd-count{flex:none;min-width:20px;height:20px;padding:0 6px;border-radius:6px;
  background:var(--panel);color:var(--muted);font-size:11px;font-weight:700;
  display:grid;place-items:center}
.dd-item:hover .dd-count{background:var(--surface)}

/* ---- the drawer shell (uiDrawer) ---- */
/* only where the body itself scrolls — on desktop the shell scrolls its own
   panes, and toggling overflow there would pop the scrollbar and shift layout */
@media(max-width:820px){body.dw-open{overflow:hidden}}
/* Keyframes, not a class-flip transition: an animation starts the moment the
   element is inserted, so it can never be skipped by the browser folding the
   before/after styles into one pass. Only opacity + transform move, and the
   scrim is a flat dim — animating backdrop-filter re-blurs the whole viewport
   every frame, which is what makes drawers stutter. */
/* the panel slides its full width in and out; the scrim dims underneath it,
   both on the same .34s cubic-bezier(.4,.9,.3,1) so they move as one piece */
.dw-ov{position:fixed;inset:0;z-index:90;background:rgba(15,23,42,.44);
  display:flex;justify-content:flex-end;
  animation:dwFade .34s cubic-bezier(.4,.9,.3,1) both}
.dw-panel{position:relative;width:100%;height:100%;background:var(--surface);
  display:flex;flex-direction:column;box-shadow:-20px 0 50px rgba(40,40,80,.14);
  animation:dwIn .34s cubic-bezier(.4,.9,.3,1) both}
.dw-ov.closing{animation:dwFadeOut .34s cubic-bezier(.4,.9,.3,1) forwards}
.dw-ov.closing .dw-panel{animation:dwOut .34s cubic-bezier(.4,.9,.3,1) forwards}
@keyframes dwFade{from{opacity:0}to{opacity:1}}
@keyframes dwFadeOut{to{opacity:0}}
@keyframes dwIn{from{transform:translateX(100%)}to{transform:translateX(0)}}
@keyframes dwOut{to{transform:translateX(100%)}}
.dw-panel .dr-head{flex:none;display:flex;align-items:center;gap:12px;
  padding:16px 18px;border-bottom:1px solid var(--line)}
.dr-title{flex:1;min-width:0;font-size:16px;font-weight:700;color:var(--ink);
  letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dr-title span{display:block;font-size:11px;font-weight:600;color:var(--muted);
  letter-spacing:.04em;text-transform:uppercase;margin-bottom:2px}
.dr-x{flex:none;width:32px;height:32px;border-radius:9px;border:1px solid var(--line);
  background:var(--surface);color:var(--muted);display:grid;place-items:center;
  transition:background .13s,color .13s,border-color .13s}
.dr-x:hover{background:var(--panel);color:var(--ink);border-color:var(--line2)}
.dr-body{flex:1;min-height:0;overflow:auto;padding:18px}
.dr-foot{flex:none;display:flex;gap:8px;justify-content:space-between;align-items:center;
  padding:14px 18px;border-top:1px solid var(--line);background:var(--surface)}
.dr-foot .btn.ghost{display:inline-flex;align-items:center;gap:6px}
.field-label{display:flex;align-items:center;gap:8px;font-size:11px;font-weight:700;
  color:var(--muted);letter-spacing:.04em;text-transform:uppercase;margin-bottom:10px}
.acct-count{min-width:19px;height:19px;padding:0 6px;border-radius:6px;background:var(--panel);
  color:var(--muted);font-size:10.5px;font-weight:700;display:grid;place-items:center;
  letter-spacing:0}

/* ---- account rows ---- */
.acct-search{display:flex;align-items:center;gap:8px;padding:0 11px;margin-bottom:10px;
  border:1px solid var(--line);border-radius:10px;background:var(--panel);color:var(--muted);
  transition:border-color .13s}
.acct-search:focus-within{border-color:var(--blue-border)}
.acct-search input{flex:1;min-width:0;border:none;background:none;outline:none;box-shadow:none;
  -webkit-appearance:none;appearance:none;color:var(--ink);font-size:13.5px;padding:9px 0}
.acct-list{display:flex;flex-direction:column;gap:8px}

.acct-row{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:12px;
  border:1px solid var(--line);background:var(--surface);
  transition:border-color .14s,background .14s,box-shadow .14s}
.acct-row:hover{background:var(--panel);border-color:var(--line2)}
.acct-row.on{border-color:var(--blue-border);background:var(--blue-soft)}

.acct-pic{flex:none;position:relative;border:none;background:none;padding:0;line-height:0;
  border-radius:50%}
.acct-av{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;
  background:var(--panel);background-size:cover;background-position:center;
  color:var(--ink2);font-size:13.5px;font-weight:700;letter-spacing:.02em;
  border:1px solid var(--line)}
.acct-av[data-h="0"]{background:rgba(21,94,239,.14);color:var(--blue)}
.acct-av[data-h="1"]{background:rgba(105,56,239,.14);color:var(--purple)}
.acct-av[data-h="2"]{background:var(--green-soft);color:var(--green)}
.acct-av[data-h="3"]{background:var(--amber-soft);color:var(--amber)}
.acct-av[data-h="4"]{background:var(--red-soft);color:var(--red)}
.acct-av[data-h="5"]{background:var(--panel);color:var(--ink2)}
.acct-cam{position:absolute;right:-2px;bottom:-2px;width:17px;height:17px;border-radius:50%;
  background:var(--ink);color:var(--bg);display:grid;place-items:center;
  border:2px solid var(--surface);opacity:0;transform:scale(.7);
  transition:opacity .13s,transform .13s}
.acct-pic:hover .acct-cam,.acct-pic:focus-visible .acct-cam{opacity:1;transform:none}

.acct-main{flex:1;min-width:0;border:none;background:none;padding:0;text-align:left;
  display:flex;flex-direction:column;gap:2px}
.acct-name{font-size:13.5px;font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acct-bal{font-size:12px;color:var(--muted)}
.acct-off{font-size:9.5px;vertical-align:middle;margin-left:4px}
.acct-cur{flex:none;display:inline-flex;align-items:center;gap:4px;font-size:11.5px;
  font-weight:600;color:var(--blue)}
.acct-chev{flex:none;color:var(--muted);display:grid;place-items:center;
  transition:transform .14s,color .14s}
.acct-row:hover .acct-chev{color:var(--ink3);transform:translateX(2px)}
.acct-empty{padding:22px 4px;text-align:center;color:var(--muted);font-size:13px}
.acct-hint{margin-top:14px;font-size:12px;line-height:1.55;color:var(--muted)}

@media (max-width:560px){
  .dw-panel{max-width:none !important}
  .acct-cur span{display:none}
}
/* touch devices have no hover — keep the "change picture" hint visible */
@media (hover:none){.acct-cam{opacity:1;transform:none}}
/* NOTE: deliberately no prefers-reduced-motion override here. It used to cut
   the open animation to 0.01ms, which made the drawer appear instantly for
   anyone with the OS "reduce motion" setting on — while the close still ran,
   because .dw-ov.closing out-specifies it. The slide is requested behaviour. */

/* =====================================================================
   Service alerts — owner broadcasts (outages, maintenance, fixes).
   Banner stack under the topbar + the topbar bell panel + owner console.
   ===================================================================== */
/* level palette, shared by banners, bell rows and the owner list */
.ann-info{--al:var(--blue);--al-bg:var(--blue-soft);--al-bd:var(--blue-border)}
.ann-success{--al:var(--green);--al-bg:var(--green-soft);--al-bd:var(--green-border)}
.ann-warning{--al:var(--amber);--al-bg:var(--amber-soft);--al-bd:var(--amber-border)}
.ann-critical{--al:var(--red);--al-bg:var(--red-soft);--al-bd:var(--red-border)}

/* ---- banner stack ---- */
#annHost{display:flex;flex-direction:column;gap:1px}
.ann{display:flex;align-items:flex-start;gap:11px;padding:11px 20px;
  background:var(--al-bg);color:var(--ink);border-bottom:1px solid var(--al-bd);
  animation:annIn .32s cubic-bezier(.4,.9,.3,1) both}
@keyframes annIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.ann-ic{flex:none;color:var(--al);display:grid;place-items:center;margin-top:1px}
.ann-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.ann-tx b{font-size:13.5px;font-weight:650;line-height:1.4}
.ann-tx span{font-size:12.5px;line-height:1.55;color:var(--ink3)}
.ann-x{flex:none;width:26px;height:26px;border-radius:7px;border:none;background:none;
  color:var(--muted);display:grid;place-items:center;transition:background .13s,color .13s}
.ann-x:hover{background:rgba(0,0,0,.06);color:var(--ink)}
body.dark .ann-x:hover{background:rgba(255,255,255,.10)}
.ann-pin{flex:none;color:var(--al);opacity:.55;display:grid;place-items:center}

/* ---- topbar bell ---- */
.bell-menu{position:relative}
.bell-dot{position:absolute;top:3px;right:3px;min-width:16px;height:16px;padding:0 4px;
  border-radius:8px;background:var(--red);color:#fff;font-size:10px;font-weight:700;
  display:grid;place-items:center;border:2px solid var(--surface);box-sizing:content-box}
.bell-dot[hidden]{display:none}
.bell-dd{position:absolute;right:0;top:calc(100% + 8px);z-index:55;width:330px;max-height:420px;
  overflow:auto;background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 16px 40px rgba(0,0,0,.16);padding:6px}
.bell-dd[hidden]{display:none}
.bell-head{font-size:10.5px;font-weight:700;color:var(--muted);letter-spacing:.04em;
  text-transform:uppercase;padding:8px 10px 6px}
.bell-row{display:flex;gap:9px;padding:9px 10px;border-radius:9px}
.bell-row+.bell-row{margin-top:2px}
.bell-row:hover{background:var(--panel)}
.bell-row.seen{opacity:.55}
.bell-ic{flex:none;color:var(--al);margin-top:2px}
.bell-tx{min-width:0;display:flex;flex-direction:column;gap:2px}
.bell-tx b{font-size:13px;font-weight:650;color:var(--ink);line-height:1.4}
.bell-tx span{font-size:12px;line-height:1.5;color:var(--ink3)}
.bell-tx small{font-size:11px;color:var(--muted)}
.bell-empty{display:flex;flex-direction:column;align-items:center;gap:5px;padding:26px 16px;
  text-align:center;color:var(--muted)}
.bell-empty svg{color:var(--green)}
.bell-empty span{font-size:13px;font-weight:600;color:var(--ink2)}
.bell-empty small{font-size:11.5px;line-height:1.5}

/* ---- owner console ---- */
.al-form{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.al-form .wide{grid-column:1/-1}
.al-levels{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.al-lv{display:flex;flex-direction:column;gap:1px;align-items:flex-start;padding:9px 10px;
  border:1px solid var(--line);border-radius:10px;background:var(--surface);text-align:left;
  font-family:inherit;transition:border-color .13s,background .13s}
.al-lv b{font-size:12.5px;font-weight:650;color:var(--ink)}
.al-lv span{font-size:10.5px;color:var(--muted);line-height:1.35}
.al-lv:hover{border-color:var(--line2)}
.al-lv.on{border-color:var(--al-bd);background:var(--al-bg)}
.al-lv.on b{color:var(--al)}
.al-row{display:flex;align-items:center;justify-content:space-between;gap:14px}
.al-chk{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--ink3);cursor:pointer}
.al-chk input{width:16px;height:16px;accent-color:var(--blue)}

.al-item{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid var(--line);position:relative}
.al-item:last-child{border-bottom:none}
.al-item.off{opacity:.55}
.al-bar{flex:none;width:3px;border-radius:3px;background:var(--al)}
.al-main{flex:1;min-width:0}
.al-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.al-top b{font-size:13.5px;font-weight:650;color:var(--ink)}
.al-main p{font-size:12.5px;line-height:1.55;color:var(--ink3);margin:5px 0 0}
.al-meta{font-size:11.5px;color:var(--muted);margin-top:5px}
.al-act{flex:none;display:flex;gap:6px;align-items:flex-start}
.al-act .btn.danger{color:var(--red)}

@media (max-width:820px){
  .al-form{grid-template-columns:1fr}
  .al-levels{grid-template-columns:repeat(2,1fr)}
  .ann{padding:10px 14px}
  .bell-dd{width:min(320px,calc(100vw - 24px))}
  .al-item{flex-wrap:wrap}
}

/* ---- loading skeletons (every tab) ---------------------------------- *
   Generalised from the Phone Numbers tab, which was the only screen that did
   this properly: paint something shaped like the content the instant the tab
   opens, then let the real thing fade up in its place. Everywhere else used to
   show a centred "Loading…" on an empty canvas for the whole round trip.

   Three parts, and they are deliberately independent:
     .sk-*    the placeholder shapes (shimmering bars in a page-shaped layout)
     .sk      marks a placeholder; go() holds it back ~120ms, so a screen that
              answers quickly never shows one at all
     .page>*  the entrance for the REAL content, staggered by position, which
              needs no markup changes in any view

   The shimmer reuses @keyframes nmShim (defined with the number cards below)
   rather than declaring a second identical one.                            */
/* Eases in rather than snapping. Deliberately NO animation-fill-mode: without
   it the element's resting opacity is 1, so it is visible whether or not the
   animation ever runs — a fade built on fill-mode:both leaves a blank screen
   anywhere animations do not start, which is what this used to get wrong. A
   freshly inserted element begins at frame 0, so there is no flash either. */
.sk{pointer-events:none;user-select:none;animation:skFade .2s ease}
@keyframes skFade{from{opacity:0}to{opacity:1}}
/* The bar is a SOLID block with the shimmer travelling over it, not a moving
   gradient that happens to look like a bar. A gradient-positioned bar is only
   visible while its animation is running — which meant it all but vanished for
   anyone on prefers-reduced-motion, and for the first frames after paint. */
.sk-bar{display:block;height:13px;border-radius:7px;background:var(--line);
  position:relative;overflow:hidden}
.sk-bar::after,.sk-dot::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.6),transparent);
  transform:translateX(-100%);animation:skSheen 1.5s ease-in-out infinite}
body.dark .sk-bar::after,body.dark .sk-dot::after{
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.09),transparent)}
@keyframes skSheen{to{transform:translateX(100%)}}
.sk-head{display:flex;flex-direction:column;gap:9px;margin-bottom:2px}
.sk-head .sk-bar:first-child{height:26px;width:min(280px,42%)}
.sk-head .sk-bar:last-child{height:13px;width:min(460px,68%)}

.sk-card{background:var(--surface);border:1px solid var(--line);border-radius:14px;
  padding:16px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:11px}
.sk-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}
.sk-grid .sk-bar:nth-child(1){height:30px;width:58%}
.sk-grid .sk-bar:nth-child(2){width:88%}
.sk-grid .sk-bar:nth-child(3){height:34px;width:100%}

/* a table: the header strip, then rows of decreasing certainty */
.sk-tbl{background:var(--surface);border:1px solid var(--line);border-radius:14px;
  overflow:hidden;box-shadow:var(--shadow)}
.sk-tbl-h{display:flex;gap:18px;padding:14px 18px;background:var(--panel);
  border-bottom:1px solid var(--line)}
.sk-tbl-h .sk-bar{height:11px;flex:1}
.sk-row{display:flex;align-items:center;gap:18px;padding:15px 18px;
  border-bottom:1px solid var(--line)}
.sk-row:last-child{border-bottom:none}
.sk-row .sk-bar{flex:1}
.sk-row .sk-bar:first-child{flex:2}
.sk-dot{width:32px;height:32px;border-radius:50%;flex:none;background:var(--line);
  position:relative;overflow:hidden}

/* KPI tiles above the body — dashboards and reports both open this way */
.sk-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:14px}
.sk-stats .sk-card{gap:9px}
.sk-stats .sk-bar:first-child{height:11px;width:52%}
.sk-stats .sk-bar:last-child{height:24px;width:74%}

/* a stack of labelled fields inside one card */
.sk-form{display:flex;flex-direction:column;gap:16px}
.sk-form .sk-fld{display:flex;flex-direction:column;gap:7px}
.sk-form .sk-fld .sk-bar:first-child{height:11px;width:120px}
.sk-form .sk-fld .sk-bar:last-child{height:38px;width:100%;border-radius:9px}

/* two-column composer: pick recipients on the left, write on the right */
.sk-split{display:grid;grid-template-columns:1fr 1fr;gap:20px}
@media(max-width:1100px){.sk-split{grid-template-columns:1fr}}

/* The real content arriving. Staggering on :nth-child rather than a --i custom
   property means no view has to change its markup to take part. */
.page > *{animation:nmIn .35s ease-out both}
.page > *:nth-child(1){animation-delay:0s}
.page > *:nth-child(2){animation-delay:.05s}
.page > *:nth-child(3){animation-delay:.10s}
.page > *:nth-child(4){animation-delay:.15s}
.page > *:nth-child(5){animation-delay:.18s}
.page > *:nth-child(n+6){animation-delay:.20s}
/* the placeholder is already the "waiting" state — it must not fade up as well */
.page.sk > *{animation:none}

/* Containers whose CHILDREN already have their own entrance must not fade too:
   two 0→1 opacity ramps multiply, so at the midpoint the content sits at ~0.25
   instead of 0.5 and the per-item stagger is lost in the mush. Phone Numbers is
   the case that matters — its cards arrive one by one via --i, and that stagger
   is the whole effect. Let the container hold still and let the cards do it. */
.page > #nmBody{animation:none}
/* set while the live poller repaints in the background: the content changes
   under the reader without the page appearing to reload itself */
#view.view-quiet .page > *{animation:none}

@media (prefers-reduced-motion:reduce){
  /* the bars stay perfectly visible without it — only the sheen is dropped */
  .sk-bar::after,.sk-dot::after{animation:none;opacity:0}
  .sk{animation:none}
  .page > *{animation:none}
}

/* ---- Number rentals (customer "Phone Numbers" tab) ----------------- *
   Cards fade up in sequence via --i, patch in place afterwards, and every
   animation is dropped under prefers-reduced-motion.                     */
.nm-bal{display:inline-flex;align-items:center;gap:7px;padding:7px 13px;border-radius:10px;
  background:var(--panel);border:1px solid var(--line);font-size:13px;color:var(--ink2)}
.nm-bal b{color:var(--ink);font-variant-numeric:tabular-nums}
.nm-sect+.nm-sect{margin-top:26px}
.nm-h{display:flex;align-items:center;gap:9px;font-size:13px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--muted);margin-bottom:13px}
.nm-h span{display:inline-grid;place-items:center;min-width:20px;height:20px;padding:0 6px;
  border-radius:6px;background:var(--panel);border:1px solid var(--line);
  font-size:11px;font-weight:700;letter-spacing:0;color:var(--ink2)}
/* wide enough that a full +964 number never has to truncate */
.nm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(318px,1fr));gap:14px}

.nm-card{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:16px;
  display:flex;flex-direction:column;gap:13px;box-shadow:var(--shadow);
  animation:nmIn .35s ease-out both;
  animation-delay:calc(var(--i,0) * 50ms);
  transition:transform .18s cubic-bezier(.2,.8,.25,1),box-shadow .18s,border-color .18s}
/* Matches the reference build's ui-fade-in exactly: a 6px lift and nothing
   else. The scale(.985) that used to be here read as a zoom on wide cards. */
@keyframes nmIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.nm-avail:hover{transform:translateY(-3px);border-color:var(--line2);
  box-shadow:0 12px 26px rgba(10,13,18,.13)}
body.dark .nm-avail:hover{box-shadow:0 12px 30px rgba(0,0,0,.42)}
.nm-mine{background:linear-gradient(180deg,var(--green-soft),transparent 62%),var(--surface);
  border-color:var(--green-border)}
.nm-poor{opacity:.72}

/* the chip drops to its own line before the number is allowed to shrink */
.nm-top{display:flex;align-items:center;gap:11px;flex-wrap:wrap}
.nm-ic{flex:none;display:grid;place-items:center;width:36px;height:36px;border-radius:11px;
  background:var(--panel);color:var(--ink3)}
.nm-ic.on{background:var(--green-soft);color:var(--green)}
.nm-head{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.nm-head b{font-size:15.5px;font-weight:600;font-variant-numeric:tabular-nums;
  white-space:nowrap}
.nm-head span{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.nm-price{display:flex;align-items:baseline;gap:7px;padding:11px 13px;border-radius:11px;
  background:var(--panel);border:1px solid var(--line)}
.nm-price b{font-size:21px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.nm-price span{font-size:12px;color:var(--muted)}
.nm-mid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.nm-fact{display:flex;flex-direction:column;gap:2px;min-width:0}
.nm-fact span{font-size:11px;color:var(--muted)}
.nm-fact b{font-size:13.5px;font-weight:600;white-space:nowrap;font-variant-numeric:tabular-nums}
.nm-fact i{font-size:11px;font-style:normal;color:var(--muted)}
.nm-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding-top:11px;border-top:1px solid var(--line)}

/* auto-renew switch */
.nm-sw{display:inline-flex;align-items:center;gap:8px;cursor:pointer;user-select:none}
.nm-sw input{position:absolute;opacity:0;width:0;height:0}
.nm-sw-t{position:relative;width:36px;height:20px;border-radius:11px;background:var(--line2);
  transition:background .2s;flex:none}
.nm-sw-t::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;
  border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3);
  transition:transform .2s cubic-bezier(.2,.8,.25,1)}
.nm-sw input:checked+.nm-sw-t{background:var(--green)}
.nm-sw input:checked+.nm-sw-t::after{transform:translateX(16px)}
.nm-sw input:disabled+.nm-sw-t{opacity:.5;cursor:not-allowed}
.nm-sw-l{font-size:12.5px;color:var(--ink3)}

/* just-rented pop, and released fade-out */
.nm-won{animation:nmWon .42s cubic-bezier(.2,.9,.3,1) both;border-color:var(--green-border)}
@keyframes nmWon{40%{transform:scale(1.035)}to{transform:scale(1)}}
.nm-out{animation:nmOut .24s ease both;pointer-events:none}
@keyframes nmOut{to{opacity:0;transform:translateY(-8px) scale(.97)}}

/* loading skeletons — same footprint as a card, so nothing jumps on swap */
.nm-skel{gap:11px;pointer-events:none}
.nm-skel span{display:block;height:13px;border-radius:7px;
  background:linear-gradient(90deg,var(--panel) 25%,var(--line) 37%,var(--panel) 63%);
  background-size:400% 100%;animation:nmShim 1.3s ease-in-out infinite}
.nm-skel span:first-child{height:34px;width:60%}
.nm-skel span:nth-child(2){width:88%}
.nm-skel span:nth-child(3){height:36px;width:100%}
@keyframes nmShim{from{background-position:100% 0}to{background-position:0 0}}

/* the owner's short description of a number, under its title */
.nm-desc{font-size:12.5px;line-height:1.5;color:var(--ink3);margin:-4px 0 0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.nm-empty{display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;
  padding:34px 20px}
.nm-empty-ic{display:grid;place-items:center;width:46px;height:46px;border-radius:14px;
  background:var(--panel);color:var(--muted);margin-bottom:2px}
.nm-empty b{font-size:14px}
.nm-empty span{font-size:12.5px;max-width:380px;line-height:1.55}
/* the way out of "Balance too low" — sits above the cards it explains */
.nm-topup{display:flex;align-items:center;gap:13px;flex-wrap:wrap;margin-bottom:14px;
  padding:13px 15px;border-radius:14px;background:var(--surface);
  border:1px solid var(--blue-border,var(--line));box-shadow:0 1px 2px rgba(16,24,40,.04)}
.nm-topup .nm-empty-ic{flex:none;width:40px;height:40px;margin:0;border-radius:50%;
  background:var(--blue-soft);color:var(--blue)}
.nm-topup-t{flex:1;min-width:180px;display:flex;flex-direction:column;gap:2px}
.nm-topup-t b{font-size:13.5px}
.nm-topup-t span{font-size:12px;line-height:1.55}
.nm-note{font-size:12px;line-height:1.6;margin-top:18px;display:flex;gap:7px;align-items:flex-start}
.nm-note svg{flex:none;margin-top:2px}

/* ---- live sending health, per number -------------------------------
   "Can this send right now", answered by Meta instead of by a failed message.
   The card is already green-washed, so the healthy state stays on plain surface
   with only the dot and label in green — that keeps amber and red loud.      */
.nm-hzw{display:flex;flex-direction:column;gap:8px}
.nm-hz{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:11px;
  background:var(--panel);border:1px solid transparent;
  transition:background .22s,border-color .22s}
.nm-hz-dot{flex:none;width:9px;height:9px;border-radius:50%;background:var(--muted);
  box-shadow:0 0 0 3px rgba(112,119,143,.16)}
.nm-hz-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.nm-hz-t b{font-size:12.5px;font-weight:600;line-height:1.3}
.nm-hz-t span{font-size:11px;color:var(--muted);line-height:1.4;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.nm-hz-ok{background:var(--surface);border-color:var(--green-border)}
.nm-hz-ok .nm-hz-dot{background:var(--green);box-shadow:0 0 0 3px rgba(7,148,85,.18)}
.nm-hz-ok .nm-hz-t b{color:var(--green)}

.nm-hz-warn{background:var(--amber-soft);border-color:var(--amber-border)}
.nm-hz-warn .nm-hz-dot{background:var(--amber);box-shadow:0 0 0 3px rgba(181,71,8,.18)}
.nm-hz-warn .nm-hz-t b{color:var(--amber)}

.nm-hz-bad{background:var(--red-soft);border-color:var(--red-border)}
.nm-hz-bad .nm-hz-dot{background:var(--red);box-shadow:0 0 0 3px rgba(217,45,32,.18)}
.nm-hz-bad .nm-hz-t b{color:var(--red)}

.nm-hz-unknown{border-color:var(--line)}

/* still asking Meta — the dot breathes, so the row reads as busy, not broken */
.nm-hz-wait .nm-hz-dot{animation:nmPulse 1.15s ease-in-out infinite}
@keyframes nmPulse{0%,100%{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}

/* what Meta says is wrong, and Meta's own suggested fix underneath */
.nm-hz-x{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.nm-hz-x li{display:flex;flex-direction:column;gap:4px;padding:10px 11px;border-radius:10px;
  background:var(--panel);border:1px solid var(--line)}
.nm-hz-w{align-self:flex-start;font-size:9.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);padding:2px 7px;border-radius:6px;
  background:var(--surface);border:1px solid var(--line)}
.nm-hz-x li b{font-size:12px;font-weight:600;line-height:1.45;color:var(--ink2)}
.nm-hz-x li i{font-size:11.5px;font-style:normal;color:var(--muted);line-height:1.5}
/* a fault is charged to someone; a note is Meta explaining an intended limit.
   Qualified with li so the shared border above cannot outrank the accent. */
.nm-hz-x li.nm-hz-e{border-left:3px solid var(--red)}
.nm-hz-x li.nm-hz-n{border-left:3px solid var(--line2)}

/* The health block is the only part of a held card whose height varies, so the
   footers in a row would otherwise sit at four different heights. */
.nm-mine .nm-foot{margin-top:auto}

/* nothing can go out of this one — it should not read as fine from across the room */
.nm-mine.nm-h-bad{background:var(--surface);border-color:var(--red-border)}
.nm-mine.nm-h-bad .nm-ic.on{background:var(--red-soft);color:var(--red)}

/* Recheck sits in the section heading: one request covers every number, so a
   per-card button would have been a lie about what it refreshes. */
.nm-recheck{margin-left:auto;display:inline-flex;align-items:center;gap:6px;
  padding:5px 10px;border-radius:8px;background:var(--surface);border:1px solid var(--line);
  color:var(--ink3);font:inherit;font-size:11.5px;font-weight:600;letter-spacing:0;
  text-transform:none;cursor:pointer;
  transition:border-color .18s,color .18s,background .18s,opacity .18s}
.nm-recheck:hover{border-color:var(--line2);color:var(--ink)}
.nm-recheck:disabled{opacity:.55;cursor:default}
.nm-recheck svg{flex:none}
.nm-recheck.busy svg{animation:nmSpin .8s linear infinite}
@keyframes nmSpin{to{transform:rotate(360deg)}}

@media (max-width:560px){.nm-grid{grid-template-columns:1fr}.nm-mid{grid-template-columns:1fr 1fr}}
@media (prefers-reduced-motion:reduce){
  .nm-card,.nm-won,.nm-out{animation:none}
  .nm-avail:hover{transform:none}
  .nm-skel span{animation:none}
  .nm-sw-t,.nm-sw-t::after{transition:none}
  .nm-hz-wait .nm-hz-dot,.nm-recheck.busy svg{animation:none}
}

/* ---- Phone Numbers: a list of numbers, and one number in full ------ */
.pn-list{overflow:hidden}
.pn-row{display:flex;align-items:center;gap:14px;width:100%;padding:14px 18px;border:none;
  background:none;font-family:inherit;text-align:left;border-bottom:1px solid var(--line);
  transition:background .13s}
.pn-row:last-child{border-bottom:none}
.pn-row:hover{background:var(--panel)}
.pn-ic{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:10px;
  background:var(--green-soft);color:var(--green)}
.pn-num{flex:none;font-size:16px;font-weight:600;color:var(--ink);letter-spacing:.01em;
  font-variant-numeric:tabular-nums}
.pn-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap;flex:1;min-width:0}
.pn-meta{flex:none;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.pn-go{flex:none;display:grid;place-items:center;color:var(--muted);transition:transform .15s}
.pn-row:hover .pn-go{transform:translateX(3px);color:var(--ink2)}

.pn-ov{position:fixed;inset:0;z-index:92;background:rgba(15,23,42,.55);
  backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);display:flex;
  align-items:flex-start;justify-content:center;padding:34px 20px;overflow:auto;
  animation:pnFade .16s ease}
@keyframes pnFade{from{opacity:0}to{opacity:1}}
.pn-modal{background:var(--surface);border:1px solid var(--line);border-radius:16px;width:100%;
  max-width:880px;box-shadow:0 28px 70px rgba(0,0,0,.34);animation:pnRise .2s cubic-bezier(.2,.8,.25,1) both}
@keyframes pnRise{from{opacity:0;transform:translateY(12px) scale(.99)}to{opacity:1;transform:none}}
.pn-load{padding:34px;display:flex;align-items:center;gap:10px;color:var(--muted);font-size:14px}
.pn-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
  padding:20px 22px;border-bottom:1px solid var(--line)}
.pn-head h2{font-size:22px;font-weight:600;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.pn-head p{margin-top:3px;font-size:13px;color:var(--muted)}
.pn-x{border:none;background:none;font-size:26px;line-height:1;color:var(--muted);
  padding:0 4px;border-radius:8px;transition:color .13s,background .13s}
.pn-x:hover{color:var(--ink);background:var(--panel)}
.pn-body{padding:6px 22px 22px}
.pn-sect{padding:16px 0;border-bottom:1px solid var(--line)}
.pn-sect:last-child{border-bottom:none;padding-bottom:2px}
.pn-sect h3{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted);margin-bottom:12px}
.pn-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px 20px}
.pn-fact{display:flex;flex-direction:column;gap:3px;min-width:0}
.pn-fact span{font-size:11.5px;color:var(--muted)}
.pn-fact b{font-size:13px;font-weight:600;color:var(--ink);overflow-wrap:anywhere}
.pn-biz{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:13px 15px;
  border:1px solid var(--line);border-radius:12px;background:var(--panel)}
.pn-biz-ic{flex:none;display:grid;place-items:center;width:36px;height:36px;border-radius:10px;
  background:var(--blue-soft);color:var(--blue)}
.pn-biz-tx{flex:1;min-width:140px;display:flex;flex-direction:column;gap:2px}
.pn-biz-tx b{font-size:14px}
.pn-biz-tx span{font-size:12px}
.pn-assign{padding:14px 15px;border:1px dashed var(--line2);border-radius:12px}
.pn-check{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink3);
  white-space:nowrap;padding-bottom:9px}
.pn-check input{width:auto;box-shadow:none}
.pn-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(108px,1fr));gap:10px}
.pn-tile{padding:11px 13px;border:1px solid var(--line);border-radius:11px;background:var(--panel);
  display:flex;flex-direction:column;gap:4px}
.pn-tile span{font-size:11.5px;color:var(--muted)}
.pn-tile b{font-size:19px;font-weight:600;font-variant-numeric:tabular-nums}
.pn-tile.ok b{color:var(--green)}
.pn-tile.bad b{color:var(--red)}
.pn-msgs{margin-top:14px;max-height:min(46vh,420px);overflow:auto;border:1px solid var(--line);
  border-radius:12px}
.pn-msgs table{width:100%}
.pn-msgs thead th{position:sticky;top:0;z-index:1;background:var(--panel)}
.pn-body-tx{font-size:12.5px;color:var(--ink2);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;max-width:280px}
@media (max-width:700px){
  .pn-row{flex-wrap:wrap;gap:8px 10px}
  .pn-meta,.pn-go{display:none}
  .pn-num{font-size:15px}
  .pn-ov{padding:0}
  .pn-modal{max-width:none;border-radius:0;min-height:100%}
  .pn-body-tx{max-width:150px}
}

/* owner: per-number settings — plain rows, and choices you tap once rather than
   dropdowns that open a picker on top of a modal */
.pn-form{display:flex;flex-direction:column;gap:14px}
.pn-two{display:grid;grid-template-columns:1fr 190px;gap:14px}
.pn-form textarea{min-height:58px;line-height:1.5}
.pn-form .field label .muted{font-weight:400}

/* price with the currency parked inside the field */
.pn-money{position:relative;display:flex;align-items:center}
.pn-money input{padding-right:46px;font-variant-numeric:tabular-nums}
.pn-money span{position:absolute;right:12px;font-size:12px;font-weight:600;color:var(--muted);
  pointer-events:none}

/* segmented choice */
.pn-seg{display:inline-flex;align-self:flex-start;max-width:100%;flex-wrap:wrap;gap:3px;
  padding:3px;border-radius:11px;background:var(--panel);border:1px solid var(--line)}
.pn-seg button{border:none;background:none;font-family:inherit;font-size:12.5px;font-weight:600;
  color:var(--muted);padding:7px 13px;border-radius:8px;white-space:nowrap;
  transition:background .14s,color .14s,box-shadow .14s}
.pn-seg button:hover{color:var(--ink2)}
.pn-seg button.on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow)}

.pn-allow{display:flex;flex-wrap:wrap;gap:7px;padding:10px 11px;border:1px solid var(--line);
  border-radius:11px;background:var(--panel);max-height:150px;overflow:auto;margin-top:6px}
.pn-allow[hidden]{display:none}
.pn-allow-i{display:inline-flex;align-items:center;gap:7px;padding:5px 10px;border-radius:9px;
  background:var(--surface);border:1px solid var(--line);font-size:12.5px;cursor:pointer;
  transition:border-color .13s,background .13s}
.pn-allow-i:hover{border-color:var(--line2)}
.pn-allow-i input{width:auto;box-shadow:none;margin:0}
.pn-allow-i input:checked+span{color:var(--blue);font-weight:600}

/* a value the presets do not cover: number box revealed under the segment */
.pn-custom{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:8px;
  font-size:12.5px;color:var(--muted);animation:pnGrow .18s ease both}
.pn-custom[hidden]{display:none}
@keyframes pnGrow{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.pn-custom input{width:96px;padding:7px 10px;font-size:13px;text-align:center;
  font-variant-numeric:tabular-nums}
.pn-custom-l{white-space:nowrap}

/* one holder, with the owner's remove button */
.pn-holder{display:inline-flex;align-items:center;gap:7px;padding:5px 6px 5px 11px;
  border-radius:999px;border:1px solid var(--line);background:var(--surface);font-size:12px}
.pn-holder.paid{border-color:var(--green-border);background:var(--green-soft)}
.pn-holder b{font-weight:600;color:var(--ink)}
.pn-holder i{font-style:normal;color:var(--muted)}
.pn-kick{display:grid;place-items:center;width:20px;height:20px;border:none;border-radius:50%;
  background:none;color:var(--muted);transition:background .13s,color .13s}
.pn-kick:hover{background:var(--red-soft);color:var(--red)}
.pn-kick:disabled{opacity:.4}

.pn-holders{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:14px;
  padding:11px 13px;border:1px solid var(--line);border-radius:11px;background:var(--panel)}
.pn-holders b{font-size:12.5px;white-space:nowrap}
.pn-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
@media (max-width:620px){.pn-two{grid-template-columns:1fr}}

/* ---- Templates: the About dialog ----------------------------------- *
   The grid of template cards is unchanged; this is the panel behind each
   card's About button — what the template is for, what the customer sees,
   and what has to be typed in each time. */
.tp-ahead{display:flex;align-items:center;gap:12px;padding:16px 18px 14px !important;
  border-bottom:1px solid var(--line)}
.tp-aic{flex:none;display:grid;place-items:center;width:38px;height:38px;border-radius:50%;
  background:var(--panel);color:var(--ink2)}
.tp-atit{flex:1;min-width:0}
.tp-atit h3{margin:0;font-size:16px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tp-atit p{margin:2px 0 0;font-size:12px;color:var(--muted)}
.tp-ahead .chip{flex:none;white-space:nowrap}
.tp-ax{flex:none;border:none;background:none;color:var(--muted);padding:5px;
  border-radius:8px;transition:color .13s,background .13s}
.tp-ax:hover{color:var(--ink);background:var(--panel)}
/* .ui-body keeps newlines for plain confirm text; this one is real markup */
.tp-about{white-space:normal !important;padding:16px 18px 4px !important;color:var(--ink2) !important}
.tp-afoot{border-top:1px solid var(--line);margin-top:14px;justify-content:flex-start !important;
  flex-wrap:wrap;padding:14px 18px 16px !important}

.tp-grid{display:grid;grid-template-columns:minmax(0,290px) minmax(0,1fr);gap:22px}
.tp-seg{display:inline-flex;background:var(--panel);border-radius:9px;padding:3px;gap:3px}
.tp-seg button{border:none;background:none;font-family:inherit;font-size:11.5px;
  font-weight:600;color:var(--muted);padding:5px 10px;border-radius:7px;
  transition:background .13s,color .13s}
.tp-seg button:hover{color:var(--ink2)}
.tp-seg button.on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow)}
.tp-tip{display:flex;gap:6px;align-items:flex-start;margin:9px 0 0;font-size:11.5px;
  line-height:1.55;color:var(--muted)}
.tp-tip svg{flex:none;margin-top:2px}
/* the words that change per customer, shown filled in */
.wa-phone .pv-fill{background:rgba(7,94,70,.10);border-radius:4px;padding:0 3px;
  font-weight:600;unicode-bidi:plaintext}

.tp-facts{display:flex;flex-direction:column;gap:15px;min-width:0}
.tp-fact h5{margin:0 0 4px;font-size:10.5px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--muted)}
.tp-fact p{margin:0;font-size:13px;line-height:1.6;color:var(--ink2)}
.tp-vars{display:flex;flex-direction:column}
.tp-var{display:flex;gap:9px;align-items:flex-start;padding:7px 0}
.tp-var+.tp-var{border-top:1px dashed var(--line)}
.tp-vn{flex:none;width:20px;height:20px;border-radius:50%;background:var(--blue-soft);
  color:var(--blue);font-size:11px;font-weight:700;display:grid;place-items:center;
  margin-top:1px}
.tp-var b{font-size:12.5px;font-weight:600;color:var(--ink);display:block}
.tp-var i{font-style:normal;font-size:11.5px;color:var(--muted);display:block;
  margin-top:1px;line-height:1.5}
.tp-var .pv-var{background:var(--blue-soft);color:var(--blue);border-radius:3px;
  padding:0 4px;font-weight:700}
/* the other blanks in the quoted sentence stay quiet — only this row's is blue */
.tp-var .pv-var.alt{background:var(--panel);color:var(--muted)}
.tp-vnote{margin-top:8px !important;font-size:11.5px !important;color:var(--muted) !important}
.tp-name{margin-top:7px !important;font-size:11.5px !important;color:var(--muted) !important}
.tp-name code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11px;background:var(--panel);border-radius:5px;padding:1px 5px;color:var(--ink2)}

@media (max-width:820px){
  .tp-grid{grid-template-columns:1fr;gap:18px}
}
@media (max-width:560px){
  /* a truncated title helps nobody on a phone — let it wrap instead */
  .tp-atit h3{white-space:normal;font-size:15px}
  .tp-ahead{padding:14px 15px 12px !important;flex-wrap:wrap}
  .tp-about{padding:14px 15px 4px !important}
  .tp-afoot{padding:12px 15px 14px !important}
}

/* ---- API quick-start: language tabs + snippets --------------------- */
/* the snippet palette lives on the card, so both themes only override vars */
.qs-card{background:var(--panel);box-shadow:none;margin-top:10px;
  --qs-bg:#FAFBFD; --qs-gut:#A8B0C2; --qs-gut-line:#E4E7F0; --qs-track:#E4E7F1;
  --qs-com:#8B93A7; --qs-str:#0B7A55; --qs-kw:#7C3AED; --qs-num:#B45309;
  --qs-fn:#155EEF; --qs-cst:#C2410C; --qs-typ:#0E7490; --qs-vr:#BE1D6B;
  --qs-op:#98A0B3; --qs-tg:#6938EF;
  --qs-font:ui-monospace,SFMono-Regular,"SF Mono","JetBrains Mono",Menlo,Consolas,monospace}
body.dark .qs-card{
  --qs-bg:#12161C; --qs-gut:#4C5566; --qs-gut-line:#242A33; --qs-track:#0E1217;
  --qs-com:#697386; --qs-str:#7FE0B0; --qs-kw:#C0A8FF; --qs-num:#FDB77E;
  --qs-fn:#82B1FF; --qs-cst:#FFBE7B; --qs-typ:#6FD3E8; --qs-vr:#FF9CC7;
  --qs-op:#7A8497; --qs-tg:#A48AFB}
.qs-top{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-bottom:10px}
.qs-top h3{font-size:13px;margin:0}
/* one track per language, so every tab is exactly the same width */
.qs-langs{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:4px;
  background:var(--qs-track);border-radius:9px;padding:3px}
.qs-lang{border:none;background:none;font-family:inherit;font-size:12px;font-weight:600;
  color:var(--muted);padding:5px 12px;border-radius:7px;white-space:nowrap;
  transition:background .13s,color .13s}
.qs-lang:hover{color:var(--ink2)}
.qs-lang.on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow)}

/* Twenty endpoints, presented as a list of things: underlined tabs choose the
   area, one panel holds the calls, hairline dividers between them, and a round
   glyph carries the verb. */
.qs-groups{display:flex;gap:0;overflow-x:auto;border-bottom:1px solid var(--line);
  margin-bottom:2px;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent);
  mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent)}
.qs-groups::-webkit-scrollbar{display:none}
.qs-tab{position:relative;display:inline-flex;align-items:center;gap:6px;flex:none;
  border:none;background:none;font-family:inherit;font-size:13px;font-weight:600;
  color:var(--muted);padding:10px 9px 11px;border-radius:9px 9px 0 0;
  white-space:nowrap;transition:color .14s,background .14s}
.qs-tab:hover{color:var(--ink2);background:var(--panel)}
.qs-tab i{font-style:normal;font-size:11px;font-weight:700;min-width:17px;height:17px;
  display:grid;place-items:center;border-radius:999px;background:var(--panel);
  color:var(--muted);padding:0 4px;transition:background .14s,color .14s}
.qs-tab.on{color:var(--ink)}
.qs-tab.on i{background:var(--ink);color:var(--surface)}
.qs-tab.on::after{content:"";position:absolute;left:9px;right:9px;bottom:-1px;height:2px;
  border-radius:2px;background:var(--ink)}

.qs-list{background:var(--surface);border:1px solid var(--line);border-radius:14px;
  overflow:hidden;margin-top:14px;box-shadow:0 1px 2px rgba(16,24,40,.04),
  0 6px 18px -8px rgba(16,24,40,.10)}
body.dark .qs-list{box-shadow:0 1px 2px rgba(0,0,0,.4)}
.qs-item+.qs-item{border-top:1px solid var(--line)}
.qs-r{display:flex;align-items:center;gap:13px;width:100%;padding:13px 15px;border:none;
  background:none;font-family:inherit;text-align:left;transition:background .13s}
.qs-r:hover{background:var(--panel)}
.qs-av{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:50%;
  background:var(--panel);color:var(--ink2);transition:background .13s,color .13s}
.qs-av.get{color:var(--blue)}
.qs-av.post{color:var(--green)}
.qs-av.put{color:var(--amber)}
.qs-av.delete{color:var(--red)}
.qs-item.open .qs-av{background:var(--ink);color:var(--surface)}
.qs-rt{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.qs-rt b{font-size:14px;font-weight:600;color:var(--ink);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.qs-rt i{font-style:normal;font-size:11.5px;color:var(--muted);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.qs-rv{flex:none;font-size:10.5px;font-weight:700;letter-spacing:.04em;padding:3px 8px;
  border-radius:999px;background:var(--panel);color:var(--muted)}
.qs-rv.get{color:var(--blue)}
.qs-rv.post{color:var(--green)}
.qs-rv.put{color:var(--amber)}
.qs-rv.delete{color:var(--red)}
.qs-rc{flex:none;display:grid;place-items:center;color:var(--line2);
  transition:transform .18s ease,color .13s}
.qs-r:hover .qs-rc{color:var(--muted)}
.qs-item.open .qs-rc{transform:rotate(90deg);color:var(--ink3)}
@media (max-width:560px){
  .qs-rv{display:none}
  .qs-r{padding:12px}
}
.qs-more{margin:12px 2px 0;font-size:12px}
.qs-more a{font-weight:600;white-space:nowrap}
.qs-panel[hidden]{display:none}
.qs-panel{animation:qsOpen .2s ease both}
@keyframes qsOpen{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}

/* the box carries the language's own colour: accent bar, dot and border */
.qs-box{border:1px solid var(--line);overflow:hidden;border-radius:12px;
  background:var(--qs-bg);margin:0 15px 15px 62px}
.qs-bar{display:flex;align-items:center;gap:7px;padding:7px 11px;
  background:var(--panel);border-bottom:1px solid var(--line)}
.qs-name{font-size:11px;font-weight:700;letter-spacing:.03em;color:var(--ql,var(--ink2));
  text-transform:uppercase}
.qs-copy{margin-left:auto;display:inline-flex;align-items:center;gap:5px;border:none;
  background:none;color:var(--muted);font-family:inherit;font-size:11px;font-weight:600;
  padding:2px 6px;border-radius:6px;transition:color .13s,background .13s}
.qs-copy:hover{color:var(--ink);background:rgba(127,127,127,.14)}

/* the box fits its own snippet and only scrolls past 26 lines, so short calls
   are not mostly empty and long ones never run the card off the page */
.qs-pre{font-size:11.5px;overflow:auto;background:var(--qs-bg);padding:10px 0;
  line-height:1.55;margin:0;
  max-height:var(--qs-h,calc(26 * 1.55em + 32px));
  font-family:var(--qs-font);color:var(--ink2);
  white-space:pre;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  tab-size:4;counter-reset:qsl}
.qs-pre::-webkit-scrollbar{width:9px;height:9px}
.qs-pre::-webkit-scrollbar-thumb{background:var(--qs-gut-line);border-radius:8px}
.qs-pre::-webkit-scrollbar-thumb:hover{background:var(--qs-gut)}
/* max-content keeps every line one row: the longest one sets the scroll width */
.qs-code{display:block;width:max-content;min-width:100%}
.qs-l{display:block;min-height:1.55em;padding-right:14px}
/* numbered gutter — sticky so it stays put while a long line scrolls under it */
.qs-l::before{counter-increment:qsl;content:counter(qsl);
  position:sticky;left:0;display:inline-block;width:3.4em;padding-right:1.1em;
  margin-right:.9em;text-align:right;color:var(--qs-gut);background:var(--qs-bg);
  border-right:1px solid var(--qs-gut-line);user-select:none;-webkit-user-select:none}
.qs-l:hover::before{color:var(--ink3)}

/* token colours */
.qs-com{color:var(--qs-com);font-style:italic}
.qs-dir{color:var(--qs-cst)}
.qs-tag{color:var(--qs-tg);font-weight:600}
.qs-flag{color:var(--qs-kw);font-weight:600}
.qs-str{color:var(--qs-str)}
.qs-kw{color:var(--qs-kw);font-weight:600}
.qs-fn{color:var(--qs-fn)}
.qs-const{color:var(--qs-cst)}
.qs-type{color:var(--qs-typ)}
.qs-var{color:var(--qs-vr)}
.qs-num{color:var(--qs-num)}
.qs-op{color:var(--qs-op)}

/* per-language accent, used for the snippet's name label */
.qs-item[data-l="curl"]  {--ql:#6E7891}
.qs-item[data-l="php"]   {--ql:#8892BF}
.qs-item[data-l="node"]  {--ql:#57A143}
.qs-item[data-l="python"]{--ql:#3B7DBF}
.qs-item[data-l="java"]  {--ql:#E1701A}
.qs-item[data-l="csharp"]{--ql:#9B4DCA}
.qs-item[data-l="cpp"]   {--ql:#2E77BC}
/* the mid-tone accents read on white; lift them a little on the dark theme */
body.dark .qs-item[data-l="curl"]  {--ql:#98A2BD}
body.dark .qs-item[data-l="csharp"]{--ql:#BE7BE4}
body.dark .qs-item[data-l="cpp"]   {--ql:#5EA0DE}
body.dark .qs-item[data-l="python"]{--ql:#63A3DC}

@media (max-width:640px){
  .qs-top{align-items:stretch;flex-direction:column}
  .qs-box{margin:0 12px 12px}
  .qs-langs{overflow-x:auto;grid-auto-columns:minmax(64px,1fr)}
  .qs-l::before{width:2.4em;padding-right:.7em;margin-right:.6em}
}

/* ---------- live campaign progress (Bulk) ---------------------------- *
 * The run happens on the server; this panel only reports it. Every
 * recipient lands as a chip that fills green (sent) or red (failed), so a
 * long campaign reads as movement rather than a frozen spinner.          */
.cp-card{margin-top:12px;border:1px solid var(--line);border-radius:12px;
  background:var(--surface);box-shadow:var(--shadow);overflow:hidden;
  animation:cpIn .28s cubic-bezier(.2,.7,.3,1) both}
@keyframes cpIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.cp-top{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:12px 14px 10px;flex-wrap:wrap}
.cp-title{display:flex;align-items:center;gap:8px;font-size:14px;min-width:0}
.cp-title b{font-weight:600;color:var(--ink)}
.cp-sub{color:var(--muted);font-size:12.5px;font-variant-numeric:tabular-nums}
/* the pulsing dot is the "still working" signal while the bar is between ticks */
.cp-live{width:9px;height:9px;border-radius:50%;background:var(--green);flex:none;
  box-shadow:0 0 0 0 var(--green-border);animation:cpPulse 1.6s ease-out infinite}

@keyframes cpPulse{0%{box-shadow:0 0 0 0 var(--green-border)}
  70%{box-shadow:0 0 0 7px transparent}100%{box-shadow:0 0 0 0 transparent}}
.cp-card.done .cp-live{animation:none;background:var(--line2)}

.cp-bar{height:7px;background:var(--panel);position:relative;overflow:hidden}
.cp-bar i{display:block;height:100%;width:0;border-radius:0 4px 4px 0;
  background:linear-gradient(90deg,var(--green),#12B76A);
  transition:width .45s cubic-bezier(.3,.8,.3,1)}
/* a sheen travelling over the filled part, so 1%/second still looks alive */
.cp-bar i::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.45),transparent);
  transform:translateX(-100%);animation:cpSheen 1.7s linear infinite}
.cp-card.done .cp-bar i::after{animation:none}

.cp-stats{display:flex;gap:16px;padding:10px 14px 0;font-size:12.5px;color:var(--muted)}
.cp-stat b{font-weight:600;color:var(--ink2);font-variant-numeric:tabular-nums;margin-right:3px}
.cp-stat.ok b{color:var(--green)}
.cp-stat.bad b{color:var(--red)}

.cp-nums{display:flex;flex-wrap:wrap;gap:6px;padding:12px 14px;max-height:190px;
  overflow-y:auto;scroll-behavior:smooth}
.cp-num{position:relative;font-size:12px;font-variant-numeric:tabular-nums;
  padding:4px 9px;border-radius:20px;border:1px solid var(--line);color:var(--ink2);
  background:var(--surface);overflow:hidden;isolation:isolate;
  animation:cpPop .34s cubic-bezier(.2,.8,.3,1.2) both}
/* the fill sweep: a coloured wipe runs left-to-right under the number */
.cp-num::before{content:"";position:absolute;inset:0;z-index:-1;transform-origin:left;
  transform:scaleX(0);animation:cpFill .45s cubic-bezier(.3,.8,.3,1) both;
  animation-delay:inherit}
.cp-num.ok{border-color:var(--green-border);color:var(--green)}
.cp-num.ok::before{background:var(--green-soft)}
.cp-num.bad{border-color:var(--red-border);color:var(--red)}
.cp-num.bad::before{background:var(--red-soft)}
@keyframes cpPop{from{opacity:0;transform:scale(.82)}to{opacity:1;transform:none}}
@keyframes cpFill{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes cpSheen{to{transform:translateX(100%)}}

.cp-foot{padding:0 14px 12px;margin:0;font-size:12px;color:var(--muted);
  display:flex;align-items:center;gap:6px}
.cp-foot svg{flex:none;color:var(--green)}

/* ---- Logs: watch a campaign that this tab did not start ------------- */
.lg-live{display:inline-flex;align-items:center;gap:8px;white-space:nowrap}
.lg-live.on{border-color:var(--green-border);color:var(--green);background:var(--green-soft)}
/* .btn sets display:inline-flex, which outranks the UA's [hidden] rule — both
   of these are toggled with the attribute, so they need it spelled out */
.lg-live[hidden],.lg-head .btn[hidden]{display:none}
.lg-ov .lg-modal{background:var(--surface);border-radius:12px;width:100%;max-width:720px;
  max-height:88vh;display:flex;flex-direction:column;overflow:hidden;
  box-shadow:0 24px 60px rgba(0,0,0,.3)}
.lg-head{display:flex;align-items:center;gap:12px;padding:14px 18px;
  border-bottom:1px solid var(--line)}
.lg-head h2{flex:1;min-width:0;font-size:16px;margin:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lg-body{padding:16px 18px 18px;overflow:auto}
/* the shared card carries its own top margin for the inline (Bulk) case */
.lg-body .cp-card{margin-top:0}

.lg-list{display:flex;flex-direction:column;gap:8px}
.lg-item{display:flex;align-items:center;justify-content:space-between;gap:14px;
  width:100%;text-align:left;padding:11px 13px;border-radius:11px;
  border:1px solid var(--line);background:var(--surface);cursor:pointer;
  transition:border-color .16s,background .16s}
.lg-item:hover{border-color:var(--line2);background:var(--panel)}
.lg-it-main{display:flex;flex-direction:column;gap:2px;min-width:0}
.lg-it-main b{font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lg-it-main span{font-size:11.5px}
.lg-it-right{display:flex;flex-direction:column;align-items:flex-end;gap:3px;flex:none}
.lg-it-right .chip{display:inline-flex;align-items:center;gap:6px}
@media(max-width:560px){
  .lg-item{flex-direction:column;align-items:stretch}
  .lg-it-right{align-items:flex-start}
}

@media (prefers-reduced-motion:reduce){
  .cp-card,.cp-num,.cp-num::before{animation:none}
  .cp-num::before{transform:scaleX(1)}
  .cp-live{animation:none}
  .cp-bar i{transition:none}
  .cp-bar i::after{animation:none;opacity:0}
}
@media (max-width:640px){
  .cp-top{flex-direction:column;align-items:stretch}
  .cp-nums{max-height:150px}
}

/* ---------- restricted numbers --------------------------------------- */
.b-blocked{position:relative}
.bl-count{margin-left:6px;min-width:19px;height:19px;padding:0 6px;border-radius:20px;
  background:var(--red-soft);color:var(--red);border:1px solid var(--red-border);
  font-size:11.5px;font-weight:600;display:inline-flex;align-items:center;
  justify-content:center;font-variant-numeric:tabular-nums}

/* the pre-send warning: says what will happen before it happens */
.bl-hint{display:flex;align-items:flex-start;gap:8px;margin-top:10px;padding:9px 11px;
  border:1px solid var(--amber-border);background:var(--amber-soft);border-radius:10px;
  font-size:12.5px;color:var(--ink2);line-height:1.5}
.bl-hint svg{flex:none;margin-top:2px;color:var(--amber)}
.bl-hint b{font-weight:600}

.bl-head{display:flex;align-items:center;gap:11px}
.bl-hic{width:34px;height:34px;border-radius:9px;flex:none;display:grid;place-items:center;
  background:var(--red-soft);color:var(--red);border:1px solid var(--red-border)}
.bl-htit{flex:1;min-width:0}
.bl-htit h3{font-size:15px;margin:0}
.bl-htit p{margin:1px 0 0;font-size:12.5px;color:var(--muted)}
.bl-close{background:none;border:0;color:var(--muted);cursor:pointer;padding:4px;
  border-radius:7px;flex:none}
.bl-close:hover{background:var(--panel);color:var(--ink)}

.bl-body{padding-top:14px}
.bl-add{background:var(--panel);border:1px solid var(--line);border-radius:11px;
  padding:12px;margin-bottom:14px}
.bl-add label{display:block;font-size:12.5px;font-weight:600;color:var(--ink2);
  margin-bottom:6px}
.bl-add textarea{width:100%;resize:vertical;padding:9px 11px;border-radius:9px;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);
  font-family:inherit;font-size:13px}
.bl-addrow{display:flex;gap:8px;margin-top:8px}
.bl-addrow input{flex:1;min-width:0;padding:9px 11px;border-radius:9px;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);font-size:13px}
.bl-add .hint{display:block;margin-top:7px;font-size:11.5px;color:var(--muted)}

.bl-listhead{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.bl-search{flex:1;min-width:0;padding:8px 11px;border-radius:9px;border:1px solid var(--line);
  background:var(--surface);color:var(--ink);font-size:13px}
.bl-listhead .muted{font-size:12px;white-space:nowrap}

.bl-list{max-height:280px;overflow-y:auto;border:1px solid var(--line);border-radius:11px}
.bl-row{display:flex;align-items:center;gap:10px;padding:9px 11px;
  border-bottom:1px solid var(--line);animation:blIn .2s ease both}
.bl-row:last-child{border-bottom:0}
.bl-row:hover{background:var(--panel)}
@keyframes blIn{from{opacity:0;transform:translateX(-4px)}to{opacity:1;transform:none}}
.bl-ic{width:26px;height:26px;border-radius:7px;flex:none;display:grid;place-items:center;
  background:var(--red-soft);color:var(--red)}
.bl-meta{flex:1;min-width:0;display:flex;flex-direction:column}
.bl-meta b{font-size:13px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.bl-meta i{font-style:normal;font-size:11.5px;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bl-x{background:none;border:1px solid transparent;color:var(--muted);cursor:pointer;
  padding:5px;border-radius:7px;flex:none;line-height:0}
.bl-x:hover{background:var(--red-soft);color:var(--red);border-color:var(--red-border)}
.bl-x:disabled{opacity:.4;cursor:default}

.bl-empty{padding:26px 18px;text-align:center;display:flex;flex-direction:column;
  align-items:center;gap:6px}
.bl-empty svg{color:var(--line2)}
.bl-empty b{font-size:13.5px;color:var(--ink2)}
.bl-empty span{font-size:12.5px;color:var(--muted);max-width:340px;line-height:1.55}

@media (prefers-reduced-motion:reduce){.bl-row{animation:none}}
@media (max-width:560px){.bl-addrow{flex-direction:column}}

/* ---------- recipient identity in Logs ------------------------------- *
 * WhatsApp exposes no customer profile photo through any API, so the face
 * here is initials on a tint derived from the number — stable, so the same
 * person is recognisable at a glance down a long list.                   */
.idc{display:flex;align-items:center;gap:9px;min-width:0}
.idc-av{width:30px;height:30px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-size:11.5px;font-weight:700;letter-spacing:.2px;position:relative}
.idc-txt{display:flex;flex-direction:column;min-width:0}
.idc-txt b{font-size:13px;font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.idc-txt i{font-style:normal;font-size:11.5px;color:var(--muted);
  font-variant-numeric:tabular-nums}
/* a name that came from the person's own WhatsApp profile, not from our records */
.idc-wa{flex:none;width:15px;height:15px;border-radius:50%;display:grid;place-items:center;
  background:var(--green);color:#fff;line-height:0}
.idc-av[data-wa]{box-shadow:0 0 0 2px var(--surface),0 0 0 3.5px var(--green-border)}

/* ---------- retry strip inside the campaign modal -------------------- */
.cm-retry{padding:12px 20px;border-bottom:1px solid var(--line);background:var(--panel);
  animation:cpIn .24s cubic-bezier(.2,.7,.3,1) both}
.cm-rtop{display:flex;align-items:center;gap:9px;margin-bottom:8px}
.cm-rtop b{font-size:13.5px;font-weight:600;color:var(--ink)}
.cm-rtop .btn{margin-left:auto}
.cm-retry .cp-bar{border-radius:4px}
.cm-retry.done .cp-live{animation:none;background:var(--line2)}
.cm-rnote{margin:8px 0 0;font-size:12px;color:var(--muted);display:flex;align-items:center;gap:6px}

/* ---------- restricted-recipients decision --------------------------- */
.bl-choice{display:flex;flex-direction:column;gap:8px;margin-top:14px}
.bl-choice .btn{width:100%;justify-content:center}
.bl-danger{color:var(--red);border-color:var(--red-border)}
.bl-danger:hover{background:var(--red-soft);border-color:var(--red)}
.bl-warnnote{display:flex;align-items:flex-start;gap:7px;margin:12px 0 0;
  font-size:11.5px;line-height:1.55;color:var(--muted)}
.bl-warnnote svg{flex:none;margin-top:2px;color:var(--amber)}

/* ---------- Meta API call trace (Send Message) ------------------------
   The exact request this app put on the wire and the exact answer Meta gave.
   Meta's App Review for whatsapp_business_messaging / _management asks to see
   both, so the panel is built to be screen-recorded: readable at 100% zoom,
   monospace payloads, nothing that needs hovering to reveal. */
.mtr{margin-top:10px;border:1px solid var(--line);border-radius:12px;
  background:var(--surface);overflow:hidden;
  animation:mtrIn .24s cubic-bezier(.2,.7,.3,1) both}
@keyframes mtrIn{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:none}}
.mtr-head{display:flex;align-items:center;gap:8px;padding:10px 14px;
  background:var(--panel);border-bottom:1px solid var(--line)}
.mtr-head b{font-size:13px;font-weight:600;color:var(--ink)}
.mtr-head svg{flex:none}
.mtr.ok .mtr-head svg{color:var(--green)}
.mtr.bad .mtr-head svg{color:var(--red)}
.mtr-live{margin-left:auto;font-size:10px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap}
.mtr-kv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:5px 16px;
  padding:12px 14px}
.mtr-kv dt{font-size:11.5px;color:var(--muted);white-space:nowrap}
.mtr-kv dd{font-size:11.5px;color:var(--ink2);min-width:0;overflow-wrap:anywhere;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.mtr-kv dd .m-ok{color:var(--green);font-weight:600}
.mtr-kv dd .m-bad{color:var(--red);font-weight:600}
.mtr details{border-top:1px solid var(--line)}
.mtr summary{list-style:none;cursor:pointer;padding:9px 14px;font-size:12px;
  font-weight:600;color:var(--blue);display:flex;align-items:center;gap:6px}
.mtr summary::-webkit-details-marker{display:none}
.mtr summary svg{flex:none;transition:transform .18s ease}
.mtr details[open] summary svg{transform:rotate(90deg)}
.mtr summary:hover{background:var(--panel)}
.mtr-copy{margin-left:auto;border:1px solid var(--line);background:var(--surface);
  color:var(--muted);font-family:inherit;font-size:11px;font-weight:600;
  padding:3px 8px;border-radius:6px;transition:color .13s,background .13s}
.mtr-copy:hover{color:var(--ink);background:var(--panel)}
/* the payload scrolls inside its own box — a long template never pushes the
   Send button off the screen */
.mtr-pre{margin:0 14px 14px;padding:11px 13px;border:1px solid var(--line);
  border-radius:9px;background:var(--panel);color:var(--ink2);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11.5px;line-height:1.6;white-space:pre;overflow:auto;max-height:340px;
  -webkit-overflow-scrolling:touch;overscroll-behavior:contain;tab-size:2}
@media(max-width:560px){
  .mtr-kv{grid-template-columns:1fr;gap:1px}
  .mtr-kv dt{margin-top:7px}
  .mtr-live{display:none}
}
