/**
 *                          ___                   _       _         _ 
 *                         / __)                 | |     | |       | |
 *     _ _ _ _ _ _ _ _ _ _| |__ _____  ____ _   _| |  _  | |__   __| |
 *    | | | | | | | | | (_   __|____ |/ ___) | | | |_/ ) |  _ \ / _  |
 *    | | | | | | | | | | | |  / ___ | |   | |_| |  _ ( _| |_) | (_| |
 *     \___/ \___/ \___(_)|_|  \_____|_|   |____/|_| \_|_)____/ \____|
 *                                                                    
 *
 * 	Author: MD OMAR FARUK
 * 	Author URI: www.faruk.bd
 * 	Author Contact: https://faruk.bd/#contact
 * 	Author Email: info@faruk.bd | farukmr@gmail.com
 * 	Copyright © 2026
 *                          ___                   _       _         _ 
 *                         / __)                 | |     | |       | |
 *     _ _ _ _ _ _ _ _ _ _| |__ _____  ____ _   _| |  _  | |__   __| |
 *    | | | | | | | | | (_   __|____ |/ ___) | | | |_/ ) |  _ \ / _  |
 *    | | | | | | | | | | | |  / ___ | |   | |_| |  _ ( _| |_) | (_| |
 *     \___/ \___/ \___(_)|_|  \_____|_|   |____/|_| \_|_)____/ \____|
 *                                                                    
 */
/* =====================================================================
   Hearing Center Business Suite - UI
   Colour tokens are injected by includes/theme.php (--brand, --accent, ...)
   ===================================================================== */

:root{
  --brand:#0f766e; --brand-rgb:15,118,110; --brand-dark:#0b5a54; --brand-light:#d7f0ed;
  --accent:#f59e0b; --accent-rgb:245,158,11; --accent-dark:#c47f08;
  --sidebar:#0b1220; --sidebar-2:#141d2f;
  --radius:14px;
  --font:'Segoe UI', system-ui, -apple-system, 'Noto Sans Bengali', sans-serif;

  --bg:#f4f6fb;
  --surface:#ffffff;
  --surface-2:#f8fafc;
  --line:#e4e8f0;
  --line-2:#eef1f6;
  --text:#0f172a;
  --text-2:#475569;
  --muted:#7b879c;
  --ok:#15803d; --ok-bg:#dcfce7;
  --warn:#b45309; --warn-bg:#fef3c7;
  --danger:#b91c1c; --danger-bg:#fee2e2;
  --info:#1d4ed8; --info-bg:#dbeafe;
  --shadow:0 1px 2px rgba(15,23,42,.04), 0 8px 24px rgba(15,23,42,.06);
  --shadow-lg:0 12px 40px rgba(15,23,42,.16);
  --sb-w:262px;
}

*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:var(--font);
  background:var(--bg);
  color:var(--text);
  font-size:14.5px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
a{color:var(--brand);text-decoration:none}
a:hover{text-decoration:underline}
img{max-width:100%}
h1,h2,h3,h4{margin:0 0 .5rem;line-height:1.3;font-weight:700;letter-spacing:-.01em}
h1{font-size:1.5rem} h2{font-size:1.22rem} h3{font-size:1.05rem} h4{font-size:.95rem}
p{margin:0 0 .8rem}
code{background:var(--surface-2);border:1px solid var(--line);border-radius:6px;padding:1px 6px;font-size:.88em}
hr{border:0;border-top:1px solid var(--line);margin:1.25rem 0}
.muted{color:var(--muted)}
.small{font-size:.84rem}
.bn{font-family:'Noto Sans Bengali',var(--font)}
.nowrap{white-space:nowrap}
.right{text-align:right} .center{text-align:center}
.mt0{margin-top:0} .mb0{margin-bottom:0}
.mt1{margin-top:.6rem} .mt2{margin-top:1.2rem} .mb2{margin-bottom:1.2rem}

/* ------------------------------------------------------------ layout */
.app{display:flex;min-height:100vh}

.sidebar{
  width:var(--sb-w);flex:0 0 var(--sb-w);
  background:linear-gradient(180deg,var(--sidebar) 0%,var(--sidebar-2) 100%);
  color:#c7d2e3;display:flex;flex-direction:column;
  /* The sidebar itself no longer scrolls: the brand and the menu
     filter used to scroll away with the menu, so searching again
     from the bottom of a sixty-entry list meant scrolling all the
     way back up first. Only .nav scrolls now. */
  position:sticky;top:0;height:100vh;overflow:hidden;z-index:40;
}
.sidebar::-webkit-scrollbar{width:6px}
.sidebar::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14);border-radius:3px}

.brand{
  display:flex;align-items:center;gap:.6rem;padding:1.05rem 1.15rem;
  color:#fff;font-weight:700;font-size:1.02rem;letter-spacing:-.01em;
  border-bottom:1px solid rgba(255,255,255,.08);
}
.brand img{max-height:34px;width:auto;border-radius:6px}
.brand-mark{
  width:34px;height:34px;border-radius:10px;flex:0 0 34px;
  background:linear-gradient(135deg,var(--brand),var(--accent));
  display:grid;place-items:center;color:#fff;font-weight:800;font-size:1rem;
}
.brand span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.nav{
  padding:.7rem .6rem 1.6rem;
  /* min-height:0 is what lets a flex child actually shrink and
     therefore scroll; without it the menu pushes the sidebar
     taller than the screen and nothing scrolls at all. */
  flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
}
.nav::-webkit-scrollbar{width:6px}
.nav::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14);border-radius:3px}

/* The block above the menu: brand and filter, always visible. */
.sb-top{flex:0 0 auto;background:rgba(0,0,0,.12);padding-bottom:.55rem}
.sb-top .brand{border-bottom:1px solid rgba(255,255,255,.08);margin-bottom:.55rem}
.sb-top .nav-find{margin:0 .6rem}
.sb-top .nav-find-none{margin:0 .6rem}
.nav-group{
  font-size:.68rem;text-transform:uppercase;letter-spacing:.12em;
  color:#66748d;padding:1rem .7rem .35rem;font-weight:700;
}
.nav a{
  display:flex;align-items:center;gap:.65rem;
  padding:.56rem .72rem;margin-bottom:2px;border-radius:10px;
  color:#c1cde0;font-size:.9rem;font-weight:500;text-decoration:none;
  transition:background .15s,color .15s;
}
.nav a:hover{background:rgba(255,255,255,.07);color:#fff;text-decoration:none}
.nav a.active{
  background:linear-gradient(90deg,rgba(var(--brand-rgb),.95),rgba(var(--brand-rgb),.55));
  color:#fff;box-shadow:0 4px 14px rgba(var(--brand-rgb),.35);
}
.nav .ico{width:20px;text-align:center;font-size:1.02rem;flex:0 0 20px}
.nav .pill{
  margin-left:auto;background:var(--accent);color:#231603;
  font-size:.66rem;font-weight:800;border-radius:20px;padding:1px 7px;
}
.nav a.active .pill{background:#fff;color:var(--brand-dark)}

.sb-foot{
  padding:.85rem 1.1rem;border-top:1px solid rgba(255,255,255,.08);
  font-size:.75rem;color:#7c8aa3;
}
.sb-foot strong{color:#aebbd0;display:block;font-size:.8rem}

.main{flex:1;min-width:0;display:flex;flex-direction:column}

.topbar{
  background:var(--surface);border-bottom:1px solid var(--line);
  padding:.7rem 1.3rem;display:flex;align-items:center;gap:.9rem;
  position:sticky;top:0;z-index:30;
}
.topbar h1{font-size:1.12rem;margin:0}
.topbar .sub{font-size:.78rem;color:var(--muted);margin-top:-2px}
.topbar-spacer{flex:1}
.menu-btn{
  display:none;background:none;border:1px solid var(--line);border-radius:9px;
  width:38px;height:38px;font-size:1.15rem;cursor:pointer;color:var(--text-2);
}

.content{padding:1.3rem;flex:1}
.content-narrow{max-width:900px}

/* --------------------------------------------------------- status chips */
.sync-chip,.lic-chip{
  display:inline-flex;align-items:center;gap:.4rem;font-size:.74rem;font-weight:700;
  padding:.28rem .6rem;border-radius:20px;border:1px solid var(--line);
  background:var(--surface-2);color:var(--text-2);white-space:nowrap;
}
.sync-chip .dot{width:8px;height:8px;border-radius:50%;background:var(--ok)}
.sync-chip.off .dot{background:var(--danger)}
.sync-chip.busy .dot{background:var(--accent);animation:pulse 1s infinite}
@keyframes pulse{50%{opacity:.25}}
.lic-chip.ok{background:var(--ok-bg);color:var(--ok);border-color:transparent}
.lic-chip.warn{background:var(--warn-bg);color:var(--warn);border-color:transparent}
.lic-chip.danger{background:var(--danger-bg);color:var(--danger);border-color:transparent}

/* ------------------------------------------------------------ user menu */
.umenu{position:relative}
.umenu-btn{
  display:flex;align-items:center;gap:.55rem;background:none;border:1px solid var(--line);
  border-radius:30px;padding:.25rem .7rem .25rem .3rem;cursor:pointer;font:inherit;color:var(--text);
}
.umenu-btn:hover{background:var(--surface-2)}
.avatar{
  width:32px;height:32px;border-radius:50%;flex:0 0 32px;object-fit:cover;
  background:linear-gradient(135deg,var(--brand),var(--accent));
  display:grid;place-items:center;color:#fff;font-weight:700;font-size:.85rem;
}
.umenu-name{font-size:.85rem;font-weight:600;line-height:1.15;text-align:left}
.umenu-name small{display:block;font-weight:400;color:var(--muted);font-size:.72rem}
.dropdown{
  position:absolute;right:0;top:calc(100% + 8px);min-width:230px;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--shadow-lg);padding:.4rem;display:none;z-index:60;
}
.dropdown.open{display:block}
.dropdown a,.dropdown button{
  display:flex;align-items:center;gap:.55rem;width:100%;
  padding:.5rem .65rem;border-radius:8px;font-size:.87rem;color:var(--text);
  background:none;border:0;cursor:pointer;font:inherit;text-align:left;text-decoration:none;
}
.dropdown a:hover,.dropdown button:hover{background:var(--surface-2);text-decoration:none}
.dropdown .sep{height:1px;background:var(--line);margin:.35rem 0}

/* --------------------------------------------------------- notifications */
.bell{
  position:relative;background:none;border:1px solid var(--line);border-radius:10px;
  width:38px;height:38px;cursor:pointer;font-size:1.05rem;color:var(--text-2);
}
.bell:hover{background:var(--surface-2)}
.bell .count{
  position:absolute;top:-6px;right:-6px;background:var(--danger);color:#fff;
  font-size:.65rem;font-weight:800;border-radius:20px;padding:1px 5px;min-width:17px;
}
.notif-panel{
  position:absolute;right:0;top:calc(100% + 8px);width:340px;max-width:calc(100vw - 24px);
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--shadow-lg);display:none;z-index:60;overflow:hidden;
}
.notif-panel.open{display:block}
.notif-panel header{
  padding:.7rem .9rem;border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;font-weight:700;font-size:.9rem;
}
.notif-list{max-height:60vh;overflow-y:auto}
.notif-item{display:flex;gap:.65rem;padding:.7rem .9rem;border-bottom:1px solid var(--line-2)}
.notif-item.unread{background:rgba(var(--brand-rgb),.05)}
.notif-item .ni{font-size:1.15rem;line-height:1}
.notif-item h5{margin:0 0 2px;font-size:.86rem;font-weight:700}
.notif-item p{margin:0;font-size:.8rem;color:var(--text-2)}
.notif-item time{font-size:.72rem;color:var(--muted)}
.notif-empty{padding:1.6rem;text-align:center;color:var(--muted);font-size:.86rem}

/* ------------------------------------------------------------- cards */
.card{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow);margin-bottom:1.1rem;overflow:hidden;
}
.card-h{
  padding:.85rem 1.1rem;border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;
}
.card-h h2,.card-h h3{margin:0;font-size:1rem}
.card-h .spacer{flex:1}
.card-b{padding:1.1rem}
.card-b.tight{padding:0}
.card-f{padding:.8rem 1.1rem;border-top:1px solid var(--line);background:var(--surface-2)}

.grid{display:grid;gap:1.1rem}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
.g-2-1{grid-template-columns:2fr 1fr}
.g-1-2{grid-template-columns:1fr 2fr}

/* --------------------------------------------------------- stat tiles */
.stats{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:1rem;margin-bottom:1.2rem}
.stat{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:1rem 1.1rem;box-shadow:var(--shadow);position:relative;overflow:hidden;
  display:block;color:inherit;text-decoration:none;transition:transform .15s,box-shadow .15s;
}
a.stat:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg);text-decoration:none}
.stat::after{content:'';position:absolute;inset:0 auto 0 0;width:4px;background:var(--brand)}
.stat.a::after{background:var(--accent)}
.stat.g::after{background:var(--ok)}
.stat.r::after{background:var(--danger)}
.stat.b::after{background:var(--info)}
.stat .lbl{font-size:.76rem;color:var(--muted);text-transform:uppercase;letter-spacing:.07em;font-weight:700}
.stat .val{font-size:1.65rem;font-weight:800;letter-spacing:-.02em;line-height:1.25}
.stat .sub{font-size:.78rem;color:var(--text-2)}
.stat .ico{position:absolute;right:.9rem;top:.85rem;font-size:1.5rem;opacity:.24}

/* ------------------------------------------------------------ tables */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
table.tbl{width:100%;border-collapse:collapse;font-size:.88rem;min-width:600px}
table.tbl th{
  text-align:left;padding:.68rem .85rem;background:var(--surface-2);
  border-bottom:1px solid var(--line);font-weight:700;font-size:.76rem;
  text-transform:uppercase;letter-spacing:.06em;color:var(--text-2);white-space:nowrap;
}
table.tbl td{padding:.68rem .85rem;border-bottom:1px solid var(--line-2);vertical-align:middle}
table.tbl tbody tr:hover{background:rgba(var(--brand-rgb),.035)}
table.tbl tbody tr:last-child td{border-bottom:0}
table.tbl .num{text-align:right;font-variant-numeric:tabular-nums}
table.tbl .actions{white-space:nowrap;text-align:right}
.tbl-title{font-weight:600;color:var(--text)}
.tbl-sub{font-size:.78rem;color:var(--muted)}
.empty{padding:2.6rem 1rem;text-align:center;color:var(--muted)}
.empty .big{font-size:2.2rem;display:block;margin-bottom:.4rem;opacity:.55}

/* ------------------------------------------------------------ badges */
.badge{
  display:inline-block;padding:.2rem .55rem;border-radius:20px;
  font-size:.72rem;font-weight:700;letter-spacing:.01em;white-space:nowrap;
}
.badge-ok{background:var(--ok-bg);color:var(--ok)}
.badge-warn{background:var(--warn-bg);color:var(--warn)}
.badge-danger{background:var(--danger-bg);color:var(--danger)}
.badge-info{background:var(--info-bg);color:var(--info)}
.badge-muted{background:#eef1f6;color:var(--muted)}
.badge-brand{background:var(--brand-light);color:var(--brand-dark)}

/* ------------------------------------------------------------ buttons */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.45rem;
  padding:.52rem 1rem;border-radius:10px;border:1px solid transparent;
  font:inherit;font-size:.87rem;font-weight:600;cursor:pointer;
  text-decoration:none;transition:filter .15s,box-shadow .15s,background .15s;white-space:nowrap;
}
.btn:hover{text-decoration:none;filter:brightness(1.06)}
.btn:active{transform:translateY(1px)}
.btn:disabled{opacity:.55;cursor:not-allowed}
.btn-primary{background:var(--brand);color:#fff;box-shadow:0 3px 12px rgba(var(--brand-rgb),.3)}
.btn-accent{background:var(--accent);color:#231603;box-shadow:0 3px 12px rgba(var(--accent-rgb),.3)}
.btn-light{background:var(--surface);color:var(--text);border-color:var(--line)}
.btn-light:hover{background:var(--surface-2)}
.btn-danger{background:var(--danger);color:#fff}
.btn-ok{background:var(--ok);color:#fff}
.btn-wa{background:#25d366;color:#062e15}
.btn-outline{background:transparent;color:var(--brand);border-color:var(--brand)}
.btn-sm{padding:.34rem .7rem;font-size:.79rem;border-radius:8px}
.btn-xs{padding:.2rem .5rem;font-size:.73rem;border-radius:7px}
.btn-block{width:100%}
.btn-icon{width:34px;height:34px;padding:0;border-radius:9px}
.btn-row{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}

/* ------------------------------------------------------------- forms */
.form-grid{display:grid;gap:1rem}
.f2{grid-template-columns:repeat(2,minmax(0,1fr))}
.f3{grid-template-columns:repeat(3,minmax(0,1fr))}
.field{display:flex;flex-direction:column;gap:.32rem;min-width:0}
.field.span2{grid-column:span 2}
.field.span3{grid-column:span 3}
label{font-size:.83rem;font-weight:600;color:var(--text-2)}
label .req{color:var(--danger)}
.hint{font-size:.76rem;color:var(--muted)}
input[type=text],input[type=email],input[type=password],input[type=number],input[type=date],
input[type=time],input[type=url],input[type=tel],input[type=search],input[type=datetime-local],
select,textarea{
  width:100%;padding:.55rem .72rem;border:1px solid var(--line);border-radius:10px;
  font:inherit;font-size:.88rem;background:var(--surface);color:var(--text);
  transition:border-color .15s,box-shadow .15s;
}
input:focus,select:focus,textarea:focus{
  outline:0;border-color:var(--brand);box-shadow:0 0 0 3px rgba(var(--brand-rgb),.16);
}
input[readonly],input:disabled,select:disabled,textarea:disabled{background:var(--surface-2);color:var(--muted)}
textarea{resize:vertical;min-height:92px}
input[type=color]{width:56px;height:38px;padding:2px;border-radius:9px;border:1px solid var(--line);background:var(--surface);cursor:pointer}
input[type=file]{font-size:.84rem}
.check{display:flex;align-items:center;gap:.5rem;font-size:.87rem;font-weight:500;color:var(--text)}
.check input{width:auto;margin:0}
.checks{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:.4rem .9rem}
.switch{position:relative;display:inline-block;width:44px;height:24px;flex:0 0 44px}
.switch input{opacity:0;width:0;height:0}
.switch .sl{
  position:absolute;inset:0;background:#cbd5e1;border-radius:24px;
  cursor:pointer;transition:background .18s;
}
.switch .sl::before{
  content:'';position:absolute;height:18px;width:18px;left:3px;top:3px;
  background:#fff;border-radius:50%;transition:transform .18s;
}
.switch input:checked + .sl{background:var(--brand)}
.switch input:checked + .sl::before{transform:translateX(20px)}
.input-group{display:flex;gap:.4rem}
.input-group .btn{flex:0 0 auto}

/* ------------------------------------------------------------- flash */
.flash{
  display:flex;align-items:flex-start;gap:.6rem;padding:.7rem 1rem;border-radius:11px;
  margin-bottom:.8rem;font-size:.88rem;border:1px solid transparent;
}
.flash span{flex:1}
.flash-x{background:none;border:0;font-size:1.2rem;line-height:1;cursor:pointer;color:inherit;opacity:.6}
.flash-success{background:var(--ok-bg);color:#14532d;border-color:#bbf7d0}
.flash-error{background:var(--danger-bg);color:#7f1d1d;border-color:#fecaca}
.flash-warning{background:var(--warn-bg);color:#78350f;border-color:#fde68a}
.flash-info{background:var(--info-bg);color:#1e3a8a;border-color:#bfdbfe}

/* ------------------------------------------------------------- misc */
.toolbar{
  display:flex;gap:.6rem;flex-wrap:wrap;align-items:center;margin-bottom:1rem;
}
.toolbar form{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}
.toolbar .grow{flex:1;min-width:180px}
.pager{display:flex;gap:.3rem;justify-content:center;padding:1rem;flex-wrap:wrap}
.pager a,.pager span{
  padding:.34rem .7rem;border-radius:8px;border:1px solid var(--line);
  font-size:.83rem;color:var(--text-2);text-decoration:none;background:var(--surface);
}
.pager a:hover{background:var(--surface-2);text-decoration:none}
.pager .cur{background:var(--brand);color:#fff;border-color:var(--brand);font-weight:700}
.pager .off{opacity:.45}
.tabs{display:flex;gap:.3rem;border-bottom:1px solid var(--line);margin-bottom:1.1rem;overflow-x:auto}
.tabs a{
  padding:.55rem .95rem;font-size:.87rem;font-weight:600;color:var(--text-2);
  border-bottom:2px solid transparent;white-space:nowrap;text-decoration:none;
}
.tabs a:hover{color:var(--brand);text-decoration:none}
.tabs a.active{color:var(--brand);border-bottom-color:var(--brand)}
.kv{display:grid;grid-template-columns:auto 1fr;gap:.45rem 1rem;font-size:.88rem}
.kv dt{color:var(--muted);font-weight:600}
.kv dd{margin:0;font-weight:500}
.thumb{width:42px;height:42px;border-radius:9px;object-fit:cover;border:1px solid var(--line);background:var(--surface-2)}
.thumb-lg{width:76px;height:76px;border-radius:12px;object-fit:cover;border:1px solid var(--line)}
.chip{
  display:inline-flex;align-items:center;gap:.3rem;background:var(--surface-2);
  border:1px solid var(--line);border-radius:20px;padding:.16rem .6rem;font-size:.76rem;
}
.progress{height:7px;background:var(--line-2);border-radius:10px;overflow:hidden}
.progress i{display:block;height:100%;background:var(--brand);border-radius:10px}
.color-row{display:flex;align-items:center;gap:.5rem}
.color-row input[type=text]{max-width:120px}

/* ------------------------------------------------------------ modals */
.modal-backdrop{
  position:fixed;inset:0;background:rgba(15,23,42,.55);backdrop-filter:blur(2px);
  display:grid;place-items:center;padding:1.2rem;z-index:100;
}
.modal-card{
  background:var(--surface);border-radius:18px;max-width:440px;width:100%;
  padding:1.7rem;text-align:center;box-shadow:var(--shadow-lg);
}
.modal-card.wide{max-width:760px;text-align:left}
.modal-icon{font-size:2.6rem;margin-bottom:.4rem}
.modal-window{background:var(--warn-bg);color:var(--warn);border-radius:9px;padding:.45rem;font-size:.86rem}
.modal-msg{color:var(--text-2);font-size:.88rem}
.modal-actions{display:flex;gap:.55rem;justify-content:center;margin-top:1.1rem;flex-wrap:wrap}

/* ------------------------------------------------- centred state pages */
.page-center{display:grid;place-items:center;min-height:100vh;padding:1.5rem;background:var(--bg)}
.state-card{
  background:var(--surface);border:1px solid var(--line);border-radius:20px;
  box-shadow:var(--shadow-lg);padding:2.2rem;max-width:520px;width:100%;text-align:center;
}
.state-icon{font-size:3rem;margin-bottom:.5rem}
.state-actions{display:flex;gap:.6rem;justify-content:center;margin-top:1.3rem;flex-wrap:wrap}
.license-card{max-width:640px;text-align:left}
.license-card h1,.license-card > p{text-align:center}
.license-card .state-icon{text-align:center}
.license-meta{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.7rem;
  background:var(--surface-2);border-radius:12px;padding:.9rem;margin:1.1rem 0;
}
.license-meta span{display:block;font-size:.72rem;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}
.license-meta strong{font-size:.9rem;word-break:break-all}
.license-note{background:var(--warn-bg);color:var(--warn);border-radius:10px;padding:.6rem .85rem;font-size:.85rem}
.support-box{border:1px dashed var(--line);border-radius:12px;padding:1rem;margin-top:1rem}
.support-box h3{margin:0 0 .6rem;font-size:.92rem}
.support-box ul{list-style:none;margin:0;padding:0;display:grid;gap:.4rem;font-size:.87rem}
.support-box li{display:flex;gap:.6rem}
.support-box li span{color:var(--muted);min-width:80px}

/* -------------------------------------------------------- auth pages */
.auth{
  min-height:100vh;display:grid;grid-template-columns:1.05fr .95fr;
  background:var(--bg);
}
.auth-art{
  background:linear-gradient(150deg,var(--sidebar) 0%,var(--brand-dark) 65%,var(--brand) 100%);
  color:#fff;padding:3rem 3.2rem;display:flex;flex-direction:column;justify-content:center;position:relative;overflow:hidden;
}
.auth-art::before,.auth-art::after{
  content:'';position:absolute;border-radius:50%;opacity:.16;
}
.auth-art::before{width:420px;height:420px;background:var(--accent);right:-140px;top:-120px}
.auth-art::after{width:320px;height:320px;background:#fff;left:-120px;bottom:-110px;opacity:.07}
.auth-art .brand{border:0;padding:0;margin-bottom:2rem;position:relative}
.auth-art h2{font-size:2rem;line-height:1.25;position:relative;margin-bottom:.8rem}
.auth-art p{color:rgba(255,255,255,.82);font-size:.98rem;position:relative;max-width:44ch}
.auth-points{list-style:none;padding:0;margin:1.8rem 0 0;display:grid;gap:.75rem;position:relative}
.auth-points li{display:flex;gap:.7rem;align-items:flex-start;font-size:.9rem;color:rgba(255,255,255,.9)}
.auth-points .tick{
  width:22px;height:22px;border-radius:50%;background:rgba(255,255,255,.16);
  display:grid;place-items:center;flex:0 0 22px;font-size:.72rem;
}
.auth-form{display:flex;align-items:center;justify-content:center;padding:2.4rem 1.5rem}
.auth-box{width:100%;max-width:400px}
.auth-box h1{font-size:1.55rem;margin-bottom:.25rem}
.auth-box .lead{color:var(--muted);margin-bottom:1.4rem;font-size:.9rem}
.auth-box .field{margin-bottom:.9rem}
.auth-alt{margin-top:1.2rem;text-align:center;font-size:.86rem;color:var(--muted)}
.auth-foot{margin-top:1.6rem;text-align:center;font-size:.76rem;color:var(--muted)}
.pw-wrap{position:relative}
.pw-wrap input{padding-right:2.6rem}
.pw-toggle{
  position:absolute;right:.4rem;top:50%;transform:translateY(-50%);
  background:none;border:0;cursor:pointer;font-size:1rem;color:var(--muted);padding:.3rem;
}

/* ------------------------------------------------------------ invoice */
.inv-sheet{background:#fff;padding:2rem;max-width:820px;margin:0 auto;color:#0f172a}
.inv-head{display:flex;justify-content:space-between;gap:1.5rem;flex-wrap:wrap;border-bottom:2px solid var(--brand);padding-bottom:1rem;margin-bottom:1.2rem}
.inv-head h1{color:var(--brand);font-size:1.7rem;margin:0}
.inv-logo{max-height:64px}
.inv-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:1.2rem;margin-bottom:1.2rem}
.inv-meta h4{font-size:.72rem;text-transform:uppercase;letter-spacing:.09em;color:var(--muted);margin-bottom:.3rem}
table.inv-tbl{width:100%;border-collapse:collapse;font-size:.87rem}
table.inv-tbl th{background:var(--brand);color:#fff;padding:.55rem .7rem;text-align:left;font-size:.76rem;text-transform:uppercase;letter-spacing:.05em}
table.inv-tbl td{padding:.55rem .7rem;border-bottom:1px solid var(--line)}
table.inv-tbl .num{text-align:right;font-variant-numeric:tabular-nums}
.inv-total{margin-left:auto;max-width:320px;margin-top:1rem}
.inv-total .row{display:flex;justify-content:space-between;padding:.35rem 0;font-size:.9rem}
.inv-total .row.grand{border-top:2px solid var(--brand);margin-top:.4rem;padding-top:.6rem;font-size:1.1rem;font-weight:800;color:var(--brand)}
.inv-serials{font-size:.76rem;color:var(--muted);display:block}

/* ------------------------------------------------------- module cards */
.mod-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:1.1rem}
.mod{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:1.15rem;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:.6rem;position:relative;
}
.mod.on{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand),var(--shadow)}
.mod .mh{display:flex;align-items:flex-start;gap:.7rem}
.mod .mico{
  width:44px;height:44px;border-radius:12px;flex:0 0 44px;display:grid;place-items:center;
  background:var(--brand-light);font-size:1.4rem;
}
.mod h3{margin:0;font-size:1rem}
.mod .ver{font-size:.74rem;color:var(--muted)}
.mod p{font-size:.85rem;color:var(--text-2);margin:0;flex:1}
.mod .mf{display:flex;gap:.45rem;align-items:center;flex-wrap:wrap;padding-top:.55rem;border-top:1px solid var(--line-2)}
.tier{position:absolute;top:.9rem;right:.9rem}

/* ----------------------------------------------------------- tickets */
.thread{display:grid;gap:.9rem}
.msg{border:1px solid var(--line);border-radius:12px;overflow:hidden}
.msg header{
  padding:.55rem .85rem;background:var(--surface-2);border-bottom:1px solid var(--line);
  display:flex;gap:.6rem;align-items:center;font-size:.83rem;
}
.msg header .who{font-weight:700}
.msg header time{margin-left:auto;color:var(--muted);font-size:.76rem}
.msg .body{padding:.9rem;font-size:.9rem;white-space:pre-wrap;word-break:break-word}
.msg.staff{border-color:var(--brand)}
.msg.staff header{background:var(--brand-light);color:var(--brand-dark)}
.attach{display:flex;gap:.45rem;flex-wrap:wrap;padding:0 .9rem .8rem}
.attach a{
  display:inline-flex;align-items:center;gap:.35rem;font-size:.78rem;
  background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:.25rem .55rem;
}

/* --------------------------------------------------------- printing */
@media print{
  .sidebar,.topbar,.no-print,.toolbar,.pager{display:none !important}
  body{background:#fff}
  .content{padding:0}
  .card{border:0;box-shadow:none;margin:0}
  .inv-sheet{padding:0;max-width:100%}
  @page{margin:12mm}
}

/* -------------------------------------------------------- responsive */
@media (max-width:1200px){
  .g4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:1024px){
  .g-2-1,.g-1-2,.g3{grid-template-columns:1fr}
}
@media (max-width:900px){
  .menu-btn{display:block}
  .sidebar{
    position:fixed;left:0;top:0;bottom:0;transform:translateX(-100%);
    transition:transform .22s ease;box-shadow:var(--shadow-lg);
  }
  .sidebar.open{transform:translateX(0)}
  .sb-overlay{
    position:fixed;inset:0;background:rgba(15,23,42,.5);z-index:35;display:none;
  }
  .sb-overlay.show{display:block}
  .g2,.g3,.g4,.f2,.f3{grid-template-columns:1fr}
  .field.span2,.field.span3{grid-column:span 1}
  .content{padding:.9rem}
  .topbar{padding:.6rem .9rem}
  .umenu-name{display:none}
}
@media (max-width:600px){
  .stats{grid-template-columns:1fr 1fr;gap:.7rem}
  .stat{padding:.8rem}
  .stat .val{font-size:1.3rem}
  .card-b{padding:.85rem}
  .topbar h1{font-size:1rem}
}

/* ------------------------------------------------------ currency switch */
.cur-toggle{display:inline-flex;border:1px solid var(--line);border-radius:30px;overflow:hidden;background:var(--surface)}
.cur-toggle a{
  padding:.3rem .85rem;font-size:.8rem;font-weight:700;color:var(--text-2);
  text-decoration:none;transition:background .15s,color .15s;
}
.cur-toggle a:hover{background:var(--surface-2);text-decoration:none}
.cur-toggle a.on{background:var(--brand);color:#fff}

/* -------------------------------------------------------- addon banners
   Drawn by includes/addon-banner.php — the same file, byte for byte, as the
   one in the suite, so an addon looks the same in the store as it does in the
   customer's own panel. The box keeps its aspect ratio inline because the
   ratio changes with where it is used. */
.addon-banner{
  position:relative;overflow:hidden;border-radius:12px;line-height:0;
  background:var(--surface-2);
}
.addon-banner svg,
.addon-banner img{width:100%;height:100%;display:block;object-fit:cover}
.addon-banner.flush{border-radius:0}

/* A banner small enough to sit inside a table row, next to the addon's name. */
.addon-chip{
  width:104px;flex:0 0 104px;border-radius:8px;overflow:hidden;line-height:0;
  aspect-ratio:3 / 1;
}
.addon-chip svg,.addon-chip img{width:100%;height:100%;display:block;object-fit:cover}
.tbl-with-chip{display:flex;align-items:center;gap:.7rem;min-width:0}

/* ---------------------------------------------------------- addon store */
.store-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1.1rem}
.scard{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);display:flex;flex-direction:column;overflow:hidden;position:relative;
}
.scard .cover{
  background:linear-gradient(135deg,var(--brand-light),var(--surface-2));
  display:grid;place-items:center;font-size:2.6rem;border-bottom:1px solid var(--line);
  aspect-ratio:3 / 1;
}
.scard .cover img{width:100%;height:100%;object-fit:cover}
.scard .cover .addon-banner{border-radius:0;width:100%;height:100%}
.scard .sb{padding:1rem;display:flex;flex-direction:column;gap:.5rem;flex:1}
.scard h3{margin:0;font-size:1rem}
.scard .tag{font-size:.82rem;color:var(--muted);margin:0;flex:1}
.scard .price{font-size:1.25rem;font-weight:800;color:var(--brand);letter-spacing:-.02em}
.scard .price small{font-size:.72rem;font-weight:600;color:var(--muted);letter-spacing:0}
.scard .sf{padding:.75rem 1rem;border-top:1px solid var(--line-2);display:flex;gap:.45rem;flex-wrap:wrap}
.scard .owned{position:absolute;top:.7rem;right:.7rem}

/* --------------------------------------------------------- product page */
.pp-hero{display:grid;grid-template-columns:1.4fr 1fr;gap:1.6rem;align-items:start}
.pp-hero h1{font-size:1.9rem;margin-bottom:.3rem}
.pp-lead{font-size:1.02rem;color:var(--text-2)}
.pp-buy{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
        padding:1.2rem;box-shadow:var(--shadow);position:sticky;top:1rem}
.pp-buy .price{font-size:2rem;font-weight:800;color:var(--brand);letter-spacing:-.02em;line-height:1.1}
.pp-shots{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:.8rem}
.pp-shots a{display:block;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--surface-2)}
.pp-shots img{display:block;width:100%;height:150px;object-fit:cover}
.pp-body{font-size:.95rem;line-height:1.75;white-space:pre-line}
.feat-list{list-style:none;padding:0;margin:0;display:grid;gap:.45rem;font-size:.9rem}
.feat-list li::before{content:'\2713';color:var(--ok);font-weight:700;margin-right:.5rem}
@media(max-width:900px){.pp-hero{grid-template-columns:1fr}.pp-buy{position:static}}

/* ------------------------------------------------------------- checkout */
.co-sum{background:var(--surface-2);border-radius:12px;padding:1rem}
.co-sum .row{display:flex;justify-content:space-between;padding:.3rem 0;font-size:.9rem}
.co-sum .row.total{border-top:2px solid var(--brand);margin-top:.5rem;padding-top:.6rem;
                   font-size:1.15rem;font-weight:800;color:var(--brand)}
.gw-list{display:grid;gap:.6rem}
.gw{border:1px solid var(--line);border-radius:12px;padding:.85rem;cursor:pointer;display:flex;gap:.7rem;align-items:flex-start}
.gw:hover{background:var(--surface-2)}
.gw input{margin-top:.25rem}
.gw .gi{font-size:1.5rem}
.gw h4{margin:0 0 .15rem;font-size:.94rem}
.gw p{margin:0;font-size:.82rem;color:var(--muted)}
.gw.on{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand)}

/* ---- notifications: a bell row is a link to the full text ---- */
a.notif-item{color:inherit;text-decoration:none;transition:background .12s}
a.notif-item:hover{background:var(--surface-2);text-decoration:none}
.notif-foot{
  padding:.55rem .9rem;border-top:1px solid var(--line-2);text-align:center;
  background:var(--surface-2);border-radius:0 0 var(--radius) var(--radius);
}
.notif-foot a{font-size:.8rem;font-weight:600}
.notif-full{white-space:pre-wrap;line-height:1.7;font-size:.95rem}
.notif-full a{word-break:break-word}
.notif-meta{
  display:flex;flex-wrap:wrap;gap:.5rem 1.2rem;font-size:.78rem;color:var(--muted);
  border-top:1px solid var(--line-2);margin-top:1.1rem;padding-top:.8rem;
}
.notif-hero{display:flex;gap:.9rem;align-items:flex-start}
.notif-hero .big-ico{
  font-size:1.7rem;line-height:1;flex:0 0 auto;width:44px;height:44px;border-radius:12px;
  display:flex;align-items:center;justify-content:center;background:var(--surface-2);
}

/* ---- the built-in rich-text editor ---- */
.rte{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.rte.drag{outline:2px dashed var(--brand);outline-offset:-4px}
.rte-bar{
  display:flex;flex-wrap:wrap;gap:.15rem;align-items:center;padding:.4rem;
  background:var(--surface-2);border-bottom:1px solid var(--line-2);position:sticky;top:0;z-index:2;
}
.rte-b{
  min-width:30px;height:30px;padding:0 .45rem;border:1px solid transparent;border-radius:7px;
  background:transparent;color:var(--text);font-size:.82rem;line-height:1;cursor:pointer;
}
.rte-b:hover{background:var(--surface);border-color:var(--line)}
.rte-b.on{background:var(--brand);border-color:var(--brand);color:#fff}
.rte-sep{width:1px;height:20px;background:var(--line);margin:0 .2rem}
.rte-color{
  width:30px;height:30px;padding:2px;border:1px solid var(--line);border-radius:7px;
  background:var(--surface);cursor:pointer;
}
.rte-area{
  min-height:190px;max-height:60vh;overflow-y:auto;padding:.9rem 1rem;
  font-size:.95rem;line-height:1.7;color:var(--text);outline:none;
}
.rte-area:focus{box-shadow:inset 0 0 0 2px rgba(var(--brand-rgb),.16)}
.rte-area img{max-width:100%;height:auto;border-radius:8px}
.rte-area blockquote{
  margin:.8rem 0;padding:.5rem .9rem;border-left:3px solid var(--brand);
  background:var(--surface-2);color:var(--text-2);
}
.rte-area code{background:var(--surface-2);padding:.1rem .35rem;border-radius:5px;font-size:.88em}
.rte-area h2{font-size:1.25rem;margin:.8rem 0 .4rem}
.rte-area h3{font-size:1.05rem;margin:.7rem 0 .35rem}
.rte-area ul,.rte-area ol{margin:.5rem 0 .5rem 1.4rem}
.rte-area a{color:var(--brand);text-decoration:underline}
.rte-src{
  width:100%;min-height:190px;border:0;padding:.9rem 1rem;resize:vertical;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.82rem;line-height:1.6;
  background:var(--surface);color:var(--text);outline:none;
}
.rte-video{position:relative;padding-bottom:56.25%;height:0;margin:.8rem 0}
.rte-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0;border-radius:10px}
.rte-note{
  padding:.4rem .9rem;font-size:.78rem;color:var(--muted);
  background:var(--surface-2);border-top:1px solid var(--line-2);
}
@media (max-width:640px){
  .rte-b{min-width:34px;height:34px}
  .rte-area{min-height:150px;padding:.75rem}
}

/* ---- the credit line every script carries ---- */
.foot-credit{
  padding:1.1rem 1.2rem 1.6rem;text-align:center;font-size:.8rem;color:var(--muted);
  line-height:1.6;
}
.foot-credit a{color:var(--brand);font-weight:600}
.foot-credit img{max-width:100%;height:auto;vertical-align:middle;max-height:28px}
.foot-credit p{margin:0}
@media print{ .foot-credit{display:none} }

/* ---- a command you are meant to copy ---- */
.copy-row{
  display:flex;gap:.5rem;align-items:center;background:var(--surface-2);
  border:1px solid var(--line-2);border-radius:var(--radius);padding:.5rem .6rem;
}
.copy-row code{
  flex:1;min-width:0;overflow-x:auto;white-space:nowrap;font-size:.76rem;
  background:transparent;padding:0;
}

/* ---- nothing may push the page sideways ----
   Grid and flex items default to min-width:auto, which means a wide table or a
   long word makes the whole page scroll instead of the box that holds it. This
   is the rule that keeps every screen inside the viewport on a phone. */
.main, .content, .card, .card-b, .card-h, .card-f,
.grid > *, .g2 > *, .g-2-1 > *, .stats > *, .form-grid > *{ min-width:0 }
.table-wrap{ max-width:100%; overflow-x:auto }
.card, .content, .main{ max-width:100% }
.tbl-sub, .tbl-title{ overflow-wrap:break-word }
.notif-item p, .notif-item h5{ overflow-wrap:anywhere }
code, .small code{ overflow-wrap:anywhere }

@media (max-width:640px){
  /* Two- and three-column forms become one column; nothing is worth
     squeezing to 90px on a phone. */
  .form-grid.f2, .form-grid.f3{ grid-template-columns:1fr }
  .field.span2, .field.span3{ grid-column:auto }
  .g2, .g-2-1{ grid-template-columns:1fr }
  .stats{ grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:.7rem }
  .toolbar{ gap:.45rem }
  .toolbar form{ width:100% }
  .toolbar .grow{ flex:1 1 100%; min-width:0 }
  .btn{ padding:.5rem .8rem }
  .card-h{ flex-wrap:wrap; gap:.4rem }
  .card-h h2{ font-size:1rem }
  .inv-sheet{ padding:1rem }
  .inv-head{ gap:.8rem }
  .inv-head h1{ font-size:1.3rem }
  .dt-grid{ grid-template-columns:1fr }
}

@media (max-width:420px){
  .stats{ grid-template-columns:1fr }
  .umenu-name{ display:none }
  .btn-row{ flex-wrap:wrap }
  .btn-row .btn{ flex:1 1 auto }
}

/* ---- the top bar has to fit a phone too ---- */
.topbar > div:first-of-type, .topbar .tb-title{ min-width:0 }
.topbar h1{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;
}
.topbar .sub{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;
}
@media (max-width:760px){
  .topbar{ padding:.6rem .9rem; gap:.55rem }
  .topbar h1{ font-size:1rem }
  .topbar .sub{ display:none }
  .lic-chip{ display:none }          /* the licence state lives on its own page */
}
@media (max-width:420px){
  .topbar{ gap:.4rem; padding:.55rem .7rem }
  .umenu-btn{ padding:.25rem .3rem }
}

/* Addon chips: green when the licence grants what the script is running,
   red when it does not. The set wraps inside its cell rather than pushing
   the table sideways. */
.chip-ok{background:var(--ok-bg);color:var(--ok);border-color:transparent}
.chip-no{background:var(--danger-bg);color:var(--danger);border-color:transparent}
.chip-mod{background:var(--brand-bg,var(--surface-2));color:var(--brand);border-color:transparent}
.chip-set{display:flex;flex-wrap:wrap;gap:.28rem;max-width:280px}
.chip-set .chip{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tbl td .key-cell{word-break:break-all;display:inline-block;max-width:220px}

/* A radio in a table cell needs no visible label — the column heading is the
   label — but a screen reader still has to be told which one it is. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
.pkg-mods td .check{margin:0}
.pkg-mods th.num,.pkg-mods td.num{text-align:right}

/* A module the customer can tick at checkout: name and blurb on the left,
   price on the right, the whole row clickable. */
.pick-row{display:flex;align-items:flex-start;gap:.7rem;padding:.7rem .8rem;border:1px solid var(--line);
  border-radius:10px;margin-bottom:.5rem;cursor:pointer}
.pick-row:hover{border-color:var(--brand)}
.pick-row .grow{flex:1;min-width:0;display:block}
.pick-row .tbl-sub{display:block}
.pick-row .pick-price{text-align:right;white-space:nowrap;flex-shrink:0}
@media (max-width:520px){
  .pick-row{flex-wrap:wrap}
  .pick-row .pick-price{width:100%;text-align:left;padding-left:1.7rem}
}

/* The footer every panel shares: what this is on the left, where to go on the
   right. It stacks on a phone rather than squeezing into one line. */
/* The footer sits inside the same column as the page content — run out to
   the full window width and the two ends drift so far apart they stop
   reading as one line. */
.foot{padding:0 1.3rem 1.4rem;font-size:.78rem;color:var(--muted)}
@media (max-width:720px){ .foot{padding:0 .9rem 1.1rem} }
.foot-bar{max-width:1180px;margin:0 auto;padding:.85rem 1.1rem;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius)}
.foot-credit-line{max-width:1180px;margin:.5rem auto 0}
.foot-bar{display:flex;flex-wrap:wrap;gap:.6rem 1.2rem;align-items:center;justify-content:space-between}
.foot-left{min-width:0}
.foot-app{font-weight:700;color:var(--text)}
.foot-ver{opacity:.7}
.foot-right{display:flex;flex-wrap:wrap;gap:.3rem 1rem}
.foot-right a{color:var(--muted);text-decoration:none;border-bottom:1px dotted var(--line-2)}
.foot-right a:hover{color:var(--brand);border-bottom-color:var(--brand)}
.foot-credit-line{margin-top:.5rem;text-align:center;opacity:.85}
@media (max-width:560px){
  .foot-bar{flex-direction:column;align-items:flex-start;gap:.5rem}
  .foot-right{gap:.3rem .8rem}
}

/* The little heading above a package's module chips. */
.pkg-mod-head{font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;
  color:var(--muted);margin:.7rem 0 .35rem;display:flex;align-items:center;gap:.4rem}

/* The tier badge sits in the card's top corner, so the heading beside it has to
   stop short of that corner — otherwise a long module name wraps underneath the
   badge and the second line is hidden by it. The reserve is sized for the wider
   of the two badges ("Premium"); long names then wrap where they should. */
.mod .tier + .mh{padding-right:5.4rem}
.mod h3{overflow-wrap:anywhere}

/* The module keys pointed at one installation, listed under its main key. */
.keybox{margin-top:.5rem;padding:.5rem .6rem;background:var(--surface-2);
  border:1px solid var(--line-2);border-radius:8px}
.keybox-h{font-size:.66rem;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);
  margin-bottom:.35rem}
.keybox-row{display:flex;flex-wrap:wrap;align-items:center;gap:.3rem;margin-bottom:.3rem}
.keybox-row:last-child{margin-bottom:0}
.keybox-row code{word-break:break-all}

/* The language switch in the top bar. */
/* The pill that holds the language button.

   No overflow:hidden here, however tempting it looks for a rounded box.
   The menu inside is position:absolute and hangs *below* this element, so
   clipping the box clips the whole menu away: the button toggled, the
   class changed, display:block applied, and nothing appeared on screen.
   The rounding is put on the button instead, which is the thing that
   actually needs it. */
.langpick{display:inline-flex;border:1px solid var(--line);border-radius:999px;
  background:var(--surface);flex-shrink:0}
.langpick > button{border-radius:999px}
.langpick-b{padding:.3rem .6rem;font-size:.76rem;color:var(--muted);text-decoration:none;line-height:1.4}
.langpick-b + .langpick-b{border-left:1px solid var(--line)}
.langpick-b.on{background:var(--brand);color:#fff;font-weight:700}
.langpick-b:hover:not(.on){background:var(--surface-2);color:var(--text)}
@media (max-width:560px){ .langpick-b{padding:.28rem .45rem;font-size:.72rem} }

/* ------------------------------------------------- public front page bits */
.home-track{background:var(--brand-light);border-radius:var(--radius);padding:1.6rem;margin-top:2.6rem}
.home-track-in{display:flex;flex-wrap:wrap;gap:1rem;align-items:center;justify-content:space-between}
.home-track-form{display:flex;gap:.5rem;flex-wrap:wrap}
.home-track-form input{min-width:200px;text-transform:uppercase;
  font-family:ui-monospace,Menlo,Consolas,monospace}

.home-steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem;margin-top:1.2rem}
.home-step{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:1.2rem;position:relative}
.home-step-n{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;
  background:var(--brand);color:#fff;font-weight:800;font-size:.85rem;margin-bottom:.6rem}
.home-step h3{margin:0 0 .3rem;font-size:1rem}
.home-step p{margin:0;font-size:.86rem;color:var(--text-2);line-height:1.6}

.home-figs{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1rem;margin-top:2.6rem}
.home-fig{text-align:center;padding:1.2rem;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius)}
.home-fig strong{display:block;font-size:1.9rem;font-weight:800;color:var(--brand);letter-spacing:-.02em}
.home-fig span{display:block;font-size:.82rem;color:var(--muted);margin-top:.2rem}

.home-faq{max-width:760px;margin:1.2rem auto 0}
.home-q{background:var(--surface);border:1px solid var(--line);border-radius:10px;
  padding:.85rem 1rem;margin-bottom:.55rem}
.home-q summary{cursor:pointer;font-weight:700;font-size:.92rem;list-style:none}
.home-q summary::-webkit-details-marker{display:none}
.home-q summary::after{content:'+';float:right;color:var(--muted);font-weight:400}
.home-q[open] summary::after{content:'\2212'}
.home-q p{margin:.6rem 0 0;font-size:.88rem;color:var(--text-2);line-height:1.7}

.home-cta{text-align:center;margin-top:3rem;padding:2.4rem 1.2rem;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius)}
.home-cta h2{margin:0 0 .3rem}
.home-cta p{margin:0;color:var(--muted)}
@media (max-width:560px){
  .home-track-in{flex-direction:column;align-items:stretch}
  .home-track-form input{flex:1}
}

/* The top bar has to fit a phone. The language switch shows each language's own
   name where there is room and its code where there is not, and the sync chip
   keeps its dot and drops its words — adding the switch had pushed every panel
   page wider than the screen. */
.langpick-b .lp-code{display:none}
@media (max-width:620px){
  .langpick-b .lp-full{display:none}
  .langpick-b .lp-code{display:inline}
  .langpick-b{padding:.3rem .5rem;font-weight:700;letter-spacing:.02em}
  .sync-chip .txt{display:none}
  .sync-chip{padding-left:.5rem;padding-right:.5rem}
}

/* ------------------------------------- sidebar: where am I, at a glance */
.nav a.active{
  position:relative;
  background:linear-gradient(90deg,rgba(var(--brand-rgb),.95),rgba(var(--brand-rgb),.45));
  color:#fff;font-weight:600;
  box-shadow:0 4px 14px rgba(var(--brand-rgb),.35);
}
/* A bar on the edge reads faster than a colour change, and survives being
   half-scrolled off the top of a long list. */
.nav a.active::before{
  content:'';position:absolute;left:-.6rem;top:50%;transform:translateY(-50%);
  width:4px;height:62%;border-radius:0 4px 4px 0;background:var(--accent);
}
.nav a.active .ico{transform:scale(1.08)}
.nav-group.on{color:var(--accent)}

/* ------------------------------------------ activating a key by hand */
.lic-activate{
  border-top:1px dashed var(--line);margin-top:.6rem;padding-top:.8rem;
  display:flex;flex-direction:column;gap:.35rem;
}
.lic-activate label{font-size:.82rem;font-weight:600;color:var(--text-2)}
.lic-activate input[type=text]{
  padding:.42rem .6rem;border:1px solid var(--line);border-radius:8px;
  font:inherit;font-size:.86rem;background:var(--surface);color:var(--text);
}

/* =====================================================================
   Panels on a phone.

   The top bar carries a burger, the page title, a link to the website,
   the licence chip, the language switch, notifications and the user
   menu. On a 375px screen that is about 190px of controls, which left
   the title with 95px and turned "Visitor Analytics" into "Visitor An…".

   So below 640px the bar becomes two rows: the controls keep the first,
   the title gets the whole of the second. Nothing is dropped — every
   control a person needs on a desk is one they need on a phone too.
   ===================================================================== */
@media (max-width:640px){
  .topbar{flex-wrap:wrap;row-gap:.15rem;padding:.55rem .8rem}
  .tb-title{order:9;flex:1 1 100%;min-width:0}
  .topbar-spacer{flex:1 1 auto}
  .topbar h1{font-size:1.02rem;white-space:normal;overflow:visible;line-height:1.3}
  /* The subtitle is a sentence of explanation. On a phone it costs more
     screen than it gives, and the page itself says the same thing. */
  .topbar .sub{display:none}
  .menu-btn{flex:0 0 auto}
}

/* The sidebar drawer: keep it clear of a notch, and stop a flick inside
   it from scrolling the page underneath. */
@media (max-width:900px){
  .sidebar{
    width:min(262px,84vw);
    padding-top:env(safe-area-inset-top);
    padding-bottom:env(safe-area-inset-bottom);
    overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  }
  body.sb-open{overflow:hidden}
}

/* Buttons, tabs and toolbars that were laid out for a desk. */
@media (max-width:560px){
  /* A row of buttons should stack rather than squeeze to nothing. */
  .btn-row{flex-wrap:wrap}
  .btn-row .btn{flex:1 1 auto;justify-content:center}
  .card-h{flex-wrap:wrap;gap:.5rem;row-gap:.6rem}
  .card-h .btn-row{width:100%}
  /* Filter bars: one control per line beats six half-width ones. */
  .filters,.filter-bar{flex-direction:column;align-items:stretch}
  .filters input,.filters select,.filter-bar input,.filter-bar select{width:100%}
  /* Tables scroll inside their wrapper; make it obvious they can. */
  .table-wrap{-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
  .stats{grid-template-columns:1fr 1fr}
  .pager{flex-wrap:wrap;justify-content:center}
  /* A modal that is taller than the phone has to be able to scroll. */
  .modal-box{max-height:92vh;overflow-y:auto;width:calc(100vw - 1.4rem)}
}

/* Nothing in a panel may push the page sideways; wide things scroll in
   their own box instead. `clip` rather than `hidden`: `hidden` turns the
   body into a scroll container and the sticky sidebar and top bar stop
   sticking. */
body{overflow-x:hidden}
@supports (overflow-x:clip){ body{overflow-x:clip} }

/* ------------------------------------------------- wide tables on a phone
   A table with eight columns cannot fit a 375px screen and should not try.
   It already scrolls inside .table-wrap; two things were missing.

   One: the browser was squeezing the key column until "HCBS-ADDON-
   AUDIOLOGY-0001" broke across four lines. Codes, keys, dates, money and
   serials are single tokens — let them keep their line and let the table
   be as wide as it needs.

   Two: nothing said the table scrolled. The shadows below appear only on
   the edge that has more content, using background-attachment:local, so
   they need no JavaScript and cost nothing when the table already fits. */
table.tbl code,table.tbl .code,table.tbl .mono,
table.tbl td.num,table.tbl th.num,table.tbl td.nowrap,
table.tbl .badge,table.tbl .chip{white-space:nowrap}

.table-wrap{
  background:
    linear-gradient(to right,var(--surface) 30%,rgba(255,255,255,0)),
    linear-gradient(to right,rgba(255,255,255,0),var(--surface) 70%) 100% 0,
    radial-gradient(farthest-side at 0 50%,rgba(15,23,42,.16),rgba(15,23,42,0)),
    radial-gradient(farthest-side at 100% 50%,rgba(15,23,42,.16),rgba(15,23,42,0)) 100% 0;
  background-repeat:no-repeat;
  background-size:34px 100%,34px 100%,13px 100%,13px 100%;
  background-attachment:local,local,scroll,scroll;
}

/* The stat card's icon is decoration sitting in the top-right corner. On a
   half-width card a long label such as "Domains in use" ran underneath it.
   Reserve the corner rather than shrinking the label. */
.stat .lbl,.stat .val{padding-right:2.2rem}
@media (max-width:560px){
  .stat .ico{right:.7rem;top:.7rem;font-size:1.25rem}
  .stat .lbl{font-size:.72rem;letter-spacing:.05em}
}

/* =====================================================================
   The sidebar, in blocks.

   Once a few modules are on, the menu runs to sixty-odd entries, and a
   flat list of sixty is a list you scan three times looking for
   something you already know is there. Each category is now its own
   bordered block: the eye can reject a whole block at a glance instead
   of reading every line in it.

   The header sticks to the top of the sidebar while its own block
   scrolls past, so you always know which block you are in.
   ===================================================================== */
.nav-sec{
  border:1px solid rgba(255,255,255,.09);
  border-radius:12px;
  margin:.55rem 0;
  background:rgba(255,255,255,.025);
}
.nav-sec .nav-group{
  position:sticky;top:0;z-index:2;
  margin:0;padding:.5rem .75rem .45rem;
  background:rgba(13,21,38,.92);
  backdrop-filter:blur(6px);
  border-bottom:1px solid rgba(255,255,255,.07);
  border-radius:11px 11px 0 0;
  display:flex;align-items:center;gap:.5rem;
}
/* A short rule before the label, so the header reads as a divider even
   where the border is faint. */
.nav-sec .nav-group::before{
  content:'';width:12px;height:2px;border-radius:2px;
  background:var(--accent);opacity:.75;flex:0 0 12px;
}
.nav-sec-in{padding:.35rem}
.nav-sec-in a{margin-bottom:1px}

/* The block holding the page you are on is lifted out of the stack. */
.nav-sec:has(a.active){
  border-color:rgba(var(--brand-rgb),.55);
  background:rgba(var(--brand-rgb),.10);
}
.nav-sec:has(a.active) .nav-group{color:var(--accent)}

/* Dashboard sits above the first block with no header of its own. */
.nav > a:first-child{margin-bottom:.5rem}

/* ------------------------------------------------------- menu filter */
.nav-find{position:relative;margin:.15rem .1rem .5rem}
.nav-find input{
  width:100%;padding:.48rem .7rem .48rem 2rem;
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);
  border-radius:10px;color:#e6ecf7;font:inherit;font-size:.85rem;
}
.nav-find input::placeholder{color:#7c8aa3}
.nav-find input:focus{
  outline:0;border-color:rgba(var(--brand-rgb),.7);
  background:rgba(255,255,255,.09);
}
.nav-find::before{
  content:'\1F50D';position:absolute;left:.6rem;top:50%;
  transform:translateY(-50%);font-size:.8rem;opacity:.55;pointer-events:none;
}
/* What the filter hides. Kept as a class rather than an inline style so
   clearing the box is one class removal, not a style rebuild. */
.nav .is-hidden{display:none !important}
.nav-find-none{
  display:none;padding:.8rem .75rem;color:#7c8aa3;font-size:.84rem;text-align:center;
}
.nav-find-none.on{display:block}

/* A browser without :has still gets the boxes, just not the highlight. */
@supports not selector(:has(a)){
  .nav-sec{background:rgba(255,255,255,.03)}
}

/* =====================================================================
   The top bar, as icons.

   It used to spell everything out — "View site", "Active", "Online",
   the user's full name and role — and a page with a long title had
   nowhere left to put it, so the bar broke onto a second line.

   Every control right of the title is now a 36px square. The words are
   in the tooltip and, where there is more to say, in the control's own
   menu. The title takes whatever is left and scales with it.
   ===================================================================== */
.tb-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;flex:0 0 36px;padding:0;
  border:1px solid var(--line);border-radius:10px;
  background:var(--surface);color:var(--text-2);
  font-size:1rem;line-height:1;cursor:pointer;text-decoration:none;
  position:relative;transition:background .15s,border-color .15s,color .15s;
}
.tb-icon:hover{background:var(--surface-2);color:var(--text);text-decoration:none}
.tb-icon .lp-code{font-size:.74rem;font-weight:800;letter-spacing:.04em}

/* The licence key, coloured by state. The word is in the tooltip. */
.tb-icon.lic-chip.ok{border-color:rgba(22,163,74,.45);color:#15803d;background:rgba(22,163,74,.09)}
.tb-icon.lic-chip.warn{border-color:rgba(217,119,6,.45);color:#b45309;background:rgba(217,119,6,.1)}
.tb-icon.lic-chip.danger{border-color:rgba(220,38,38,.45);color:#b91c1c;background:rgba(220,38,38,.09)}

/* Sync: a dot, green when it is talking to the server. */
.tb-icon.sync-chip .dot{
  width:10px;height:10px;border-radius:50%;background:var(--ok);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--ok) 22%,transparent);
}
.tb-icon.sync-chip.off .dot{background:var(--muted);box-shadow:none}
.tb-icon.sync-chip.busy .dot{background:var(--warn)}
.tb-dot-count{
  position:absolute;top:-5px;right:-5px;min-width:17px;height:17px;padding:0 4px;
  border-radius:9px;background:var(--danger);color:#fff;
  font-size:.62rem;font-weight:800;line-height:17px;text-align:center;
}

/* Just the picture. */
.umenu-btn.only-avatar{
  padding:0;border:0;background:none;cursor:pointer;
  width:36px;height:36px;flex:0 0 36px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
}
.umenu-btn.only-avatar .avatar{width:36px;height:36px;font-size:.92rem}
.umenu-btn.only-avatar:hover .avatar{box-shadow:0 0 0 3px var(--brand-light)}

/* --------------------------------------------------- inside a dropdown */
.dropdown .dd-head{
  padding:.45rem .65rem .3rem;font-size:.7rem;font-weight:800;
  text-transform:uppercase;letter-spacing:.09em;color:var(--muted);
}
.dropdown .dd-note{padding:.15rem .65rem .45rem;font-size:.82rem;color:var(--text-2)}
.dropdown .dd-user{
  padding:.55rem .65rem;margin-bottom:.3rem;border-bottom:1px solid var(--line);
  display:flex;flex-direction:column;gap:.1rem;
}
.dropdown .dd-user strong{font-size:.92rem;line-height:1.3}
.dropdown .dd-user small{color:var(--muted);font-size:.78rem}
.dropdown a.on{background:var(--brand-light);font-weight:600}
.dropdown .dd-tick{margin-left:auto;color:var(--brand);font-weight:800}
.langpick .dropdown{min-width:180px}
.langpick .dropdown .lp-code{
  font-size:.68rem;font-weight:800;color:var(--muted);
  border:1px solid var(--line);border-radius:5px;padding:.05rem .3rem;
}

/* -------------------------------------------------------- the title */
/* Fluid, so a long page name shrinks to fit rather than shoving the
   controls onto a second row. */
.topbar h1{
  font-size:clamp(.98rem,1.35vw + .5rem,1.22rem);
  line-height:1.25;margin:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.topbar .sub{
  font-size:clamp(.72rem,.45vw + .58rem,.82rem);
  color:var(--muted);line-height:1.35;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.tb-title{min-width:0;flex:0 1 auto}
/* Only above the phone breakpoint: below it the bar deliberately wraps
   so the title gets a full row of its own. */
@media (min-width:641px){ .topbar{gap:.45rem;flex-wrap:nowrap} }

@supports not (color: color-mix(in srgb, red 50%, blue)){
  .tb-icon.sync-chip .dot{box-shadow:0 0 0 3px rgba(22,163,74,.22)}
}

/* =====================================================================
   table.table is the same thing as table.tbl.

   Both names were in use — 125 places said "tbl", 58 said "table", and
   the stylesheet only knew the first. Everything written with the second
   name rendered as a bare browser table: 1px cell padding, no header
   band, no row rules, columns collapsed to their text with the rest of
   the card left empty. That included includes/admin-crud.php, so every
   generated list screen looked like that.

   Aliasing rather than renaming 58 tags in 38 files: the rename can miss
   one and nobody notices until a screenshot arrives, and the next person
   to type the wrong one is served either way.
   ===================================================================== */
table.table{
  width:100%;border-collapse:collapse;font-size:.88rem;min-width:600px;
}
table.table th{
  text-align:left;padding:.68rem .85rem;background:var(--surface-2);
  border-bottom:1px solid var(--line);font-weight:700;font-size:.76rem;
  text-transform:uppercase;letter-spacing:.06em;color:var(--text-2);white-space:nowrap;
}
table.table td{padding:.68rem .85rem;border-bottom:1px solid var(--line-2);vertical-align:middle}
table.table tbody tr:last-child td{border-bottom:0}
table.table tbody tr:hover{background:var(--surface-2)}
table.table td.num,table.table th.num,table.table td.right,table.table th.right{text-align:right}
table.table td.center,table.table th.center{text-align:center}
table.table code,table.table .code,table.table .mono,
table.table td.num,table.table th.num,table.table td.nowrap,
table.table .badge,table.table .chip{white-space:nowrap}

/* A short table — a two-column summary inside a card — should not be
   forced to 600px and made to scroll for no reason. */
table.table.tight,table.tbl.tight,
table.table[style*="min-width:auto"],table.tbl[style*="min-width:auto"]{min-width:0}

/* =====================================================================
   Filter rows.

   Every list screen has a filter bar built as `<form style="display:flex;
   flex-wrap:wrap">`. The global form rule gives every input and select
   `width:100%`, so inside a wrapping flex row each control claimed a whole
   line and a four-control filter became four stacked rows the full width
   of the card — on a 1400px screen.

   A flex item should be sized by flex, not by a blanket width. Matching on
   the inline style rather than adding a class to thirty-three forms: the
   class can be forgotten on the thirty-fourth, and this cannot.
   ===================================================================== */
form[style*="display:flex"] > input,
form[style*="display:flex"] > select,
form[style*="display:flex"] > .pw-wrap,
.toolbar input, .toolbar select,
.filters input, .filters select{
  width:auto;
}
/* The search box is the one that should soak up the leftover room. */
form[style*="display:flex"] > input[type=search]{flex:1 1 220px;min-width:180px}

@media (max-width:560px){
  /* On a phone the stack is right — one control per line, each full width. */
  form[style*="display:flex"] > input,
  form[style*="display:flex"] > select,
  .toolbar input, .toolbar select,
  .filters input, .filters select{width:100%}
}

/* A class that sets display beats the browser's own [hidden] rule, so an
   element told to hide stays on screen. One line here rather than one per
   component, because the next one would be found the same slow way. */
[hidden]{display:none !important}

/* ------------------------------------------------- buying several at once
   A bar that appears only when something is ticked. It sits over the page
   rather than in the flow so it does not move the cards about as it comes
   and goes. */
.buy-tick{
  display:inline-flex;align-items:center;gap:.3rem;font-size:.8rem;
  padding:.3rem .55rem;border:1px solid var(--line);border-radius:8px;
  cursor:pointer;user-select:none;background:var(--surface);
}
.buy-tick input{margin:0}
.buy-tick:hover{border-color:var(--brand)}

.buy-bar{
  position:sticky;bottom:0;z-index:40;margin:1.2rem 0 0;
}
.buy-bar-in{
  display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;
  padding:.7rem 1rem;border:1px solid var(--line);border-radius:12px;
  background:var(--surface);box-shadow:0 -4px 18px rgba(0,0,0,.08);
}
.buy-bar-in strong{margin-right:auto;font-size:1.05rem}
@media (max-width:560px){
  .buy-bar-in{gap:.5rem}
  .buy-bar-in strong{margin-right:0;width:100%}
}
}

/* ------------------------------------------------- licence keys in prose
   A key that shares a face with the sentence around it disappears into it,
   and people copy half of one. Anywhere a key is printed inside text — a
   notification, a support reply, a licence screen — it gets a box of its own.
   The box wraps rather than clipping: on a phone a key is wider than the
   column, and a key cut off at the edge is worse than one on two lines. */
.lickey{
  display:inline-block;font-family:ui-monospace,SFMono-Regular,Consolas,"Liberation Mono",monospace;
  font-size:.94em;font-weight:700;letter-spacing:.06em;
  background:var(--surface-2);border:1px dashed var(--line);border-radius:7px;
  padding:.1em .5em;margin:.1em 0;color:var(--text);
  word-break:break-all;white-space:normal;
}
.notif-full .lickey{font-size:1.02rem;padding:.25em .7em;background:var(--brand-light);
  border-color:var(--brand);color:var(--brand-ink,var(--text))}

/* ------------------------------------------------------------ the trail
   Under the page title: Dashboard / Licenses / HCBS-…, each part but the
   last a link back to it. Small and quiet — it is a way back, not a heading. */
.crumbs{
  display:flex;align-items:center;gap:.3rem;flex-wrap:wrap;
  margin-top:.25rem;font-size:.78rem;line-height:1.5;
}
.crumbs a{color:var(--muted);text-decoration:none}
.crumbs a:hover{color:var(--brand);text-decoration:underline}
.crumbs span{color:var(--text-2);font-weight:600}
.crumbs i{color:var(--line);font-style:normal;user-select:none}

/* The brand is a link now, so it must not pick up link colours. */
a.brand{text-decoration:none;color:inherit}
a.brand:hover{text-decoration:none}

@media (max-width:640px){
  /* On a phone the middle of a long trail is the part worth losing: the way
     home and where you are standing are what somebody actually needs. */
  .crumbs{font-size:.74rem}
  .crumbs a:not(:first-child),
  .crumbs i:not(:last-of-type){display:none}
}



/* Retired addons, closed by default under the live catalogue. */
.retired-addons{border-top:1px solid var(--line);margin-top:.6rem;padding-top:.8rem}
.retired-addons > summary{
  cursor:pointer;font-size:.84rem;font-weight:600;color:var(--muted);
  list-style:none;display:flex;align-items:center;gap:.4rem;padding:.3rem 0;
}
.retired-addons > summary::-webkit-details-marker{display:none}
.retired-addons > summary::before{content:'\25B8';transition:transform .15s;display:inline-block}
.retired-addons[open] > summary::before{transform:rotate(90deg)}
.retired-addons > summary:hover{color:var(--text)}

/* ------------------------------------------- a wide table that fits instead
   The licences list carried nine columns and a four-button action bar, so on
   anything narrower than a desk monitor the actions sat off the right-hand
   edge and the table had to be dragged sideways to reach them. Three things
   fix that, and none of them hides information:

   - the action buttons wrap into a small block instead of one long line;
   - `.hide-md` columns drop below 1200px, and their `.only-md` twin appears
     inside a cell that is still there, so the figure moves rather than goes;
   - below 760px the rows stack, each cell labelled from its data-label. */
.row-acts{
  display:flex;flex-wrap:wrap;gap:.3rem;justify-content:flex-end;
  max-width:14rem;margin-left:auto;
}
/* Room for two buttons abreast, but only where there is room to give: at
   full width the column is otherwise squeezed to one button and every row
   grows four lines tall. Below that the buttons stack, which is the right
   answer for a narrow screen anyway. */
@media (min-width:1201px){
  .tbl td.actions,.tbl th.actions{min-width:10.5rem}
}
.only-md{display:none}
@media (max-width:1200px){
  .tbl .hide-md{display:none}
  .tbl .only-md{display:block}
}

@media (max-width:760px){
  /* Stacked rows. The header is gone, so every cell says what it is. */
  .tbl.stacked,
  .tbl.stacked tbody,
  .tbl.stacked tr,
  .tbl.stacked td{display:block;width:auto}
  .tbl.stacked{min-width:0}
  .tbl.stacked thead{display:none}
  .tbl.stacked tr{
    border:1px solid var(--line);border-radius:12px;padding:.6rem .8rem;
    margin-bottom:.7rem;background:var(--surface);
  }
  .tbl.stacked td{
    border:0;padding:.32rem 0;display:flex;gap:.8rem;align-items:baseline;
    justify-content:space-between;text-align:right;
  }
  .tbl.stacked td::before{
    content:attr(data-label);flex:0 0 auto;text-align:left;
    font-size:.72rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
    color:var(--muted);
  }
  /* `display:block` on every cell above is more specific than `.hide-md`,
     so the dropped columns came back the moment the rows stacked — and the
     domain count then appeared twice, once in its own row and once in the
     line that stands in for it. */
  .tbl.stacked td.hide-md,
  .tbl.stacked th.hide-md{display:none}
  .tbl.stacked td:not([data-label])::before{content:''}
  .tbl.stacked td > *{text-align:right}
  /* A licence key is 25 characters and a phone is 375px wide. Codes stay on
     one line everywhere else in the panel, on purpose — here they have to be
     allowed to wrap, because a key running off the edge of the screen is
     worse than a key on two lines. */
  .tbl.stacked td{flex-wrap:wrap}
  .tbl.stacked code,
  .tbl.stacked .nowrap,
  .tbl.stacked .tbl-sub{white-space:normal;overflow-wrap:anywhere}
  .tbl.stacked .row-acts{max-width:none;margin-left:0}
  .tbl.stacked td.actions{justify-content:flex-end;padding-top:.6rem;border-top:1px solid var(--line-2)}
}

/* =====================================================================
   Which product a row belongs to.
   One server sells several scripts whose addons share names and codes, so
   every list says which product each row is for: a chip on the row, a
   coloured head over each group, and a tab per product. --pc is set inline
   by includes/product-scope.php.
   ===================================================================== */
.pchip{
  --pc:#64748b;display:inline-flex;align-items:center;gap:.35rem;max-width:100%;vertical-align:middle;
  padding:.1rem .6rem .1rem .18rem;border-radius:999px;font-size:.74rem;font-weight:600;white-space:nowrap;
  background:var(--surface-2);border:1px solid var(--line);color:var(--text-2);line-height:1.5;
}
.pchip b{background:var(--pc);color:#fff;border-radius:999px;padding:0 .45rem;font-size:.64rem;
  letter-spacing:.05em;font-weight:800;line-height:1.6}
.pchip span{overflow:hidden;text-overflow:ellipsis}
.pchip-none{padding:.1rem .6rem;color:var(--muted)}
@supports (color: color-mix(in srgb, red 50%, blue)){
  .pchip{background:color-mix(in srgb,var(--pc) 9%,var(--surface));
    border-color:color-mix(in srgb,var(--pc) 30%,transparent);
    color:color-mix(in srgb,var(--pc) 78%,var(--text))}
}
.pchip-sm{font-size:.68rem}

.ptabs a{display:inline-flex;align-items:center;gap:.4rem}
.ptabs a .pdot{width:9px;height:9px;border-radius:50%;background:var(--pc,var(--brand));flex:0 0 9px}
.ptabs a .n{background:var(--surface-2);border:1px solid var(--line);border-radius:999px;
  font-size:.7rem;padding:0 .45rem;color:var(--muted);font-weight:700}
.ptabs a.active .n{background:var(--brand);border-color:var(--brand);color:#fff}

.pgroup-head{
  --pc:#64748b;display:flex;align-items:center;gap:.85rem;flex-wrap:wrap;
  margin:1.5rem 0 .9rem;padding:.75rem .95rem;border-radius:var(--radius);
  background:var(--surface);border:1px solid var(--line);border-left:5px solid var(--pc);box-shadow:var(--shadow);
}
.pgroup-head:first-child{margin-top:.2rem}
.pgroup-head .pg-mark{min-width:46px;height:40px;padding:0 .5rem;border-radius:11px;background:var(--pc);color:#fff;
  display:grid;place-items:center;font-weight:800;font-size:.74rem;letter-spacing:.05em}
.pgroup-head .pg-text{min-width:0;flex:1}
.pgroup-head h2,.pgroup-head h3{margin:0;font-size:1.05rem;letter-spacing:-.01em}
.pgroup-head .pg-meta{font-size:.8rem;color:var(--muted);margin-top:.1rem}
.pgroup-head .pg-act{display:flex;gap:.4rem;flex-wrap:wrap}
@supports (color: color-mix(in srgb, red 50%, blue)){
  .pgroup-head{background:linear-gradient(90deg,color-mix(in srgb,var(--pc) 9%,var(--surface)),var(--surface) 70%)}
}
table.tbl tr.pgroup-row td{background:var(--surface-2);border-left:3px solid var(--pc);padding:.55rem .8rem}
table.tbl tr.pgroup-row:hover td{background:var(--surface-2)}
table.tbl tr.pgroup-row .pg-meta{font-size:.78rem;color:var(--muted);margin-left:.4rem;font-weight:500}

/* product overview cards on the dashboard */
.pcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1rem;margin-bottom:1.2rem}
.pcard{--pc:#64748b;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);overflow:hidden;display:flex;flex-direction:column}
.pcard-top{display:flex;gap:.8rem;align-items:center;padding:.95rem 1rem;border-bottom:1px solid var(--line-2);
  background:linear-gradient(120deg,var(--pc),#0b1220);color:#fff}
.pcard-top .pg-mark{min-width:48px;height:42px;padding:0 .5rem;border-radius:11px;background:rgba(255,255,255,.16);
  display:grid;place-items:center;font-weight:800;font-size:.76rem;letter-spacing:.05em}
.pcard-top h3{margin:0;font-size:1rem;color:#fff}
.pcard-top small{color:rgba(255,255,255,.75);font-size:.76rem}
.pcard-nums{display:grid;grid-template-columns:repeat(3,1fr);gap:0}
.pcard-nums a{padding:.75rem .6rem;text-align:center;color:var(--text);text-decoration:none;
  border-right:1px solid var(--line-2);border-bottom:1px solid var(--line-2)}
.pcard-nums a:nth-child(3n){border-right:0}
.pcard-nums a:hover{background:var(--surface-2);text-decoration:none}
.pcard-nums strong{display:block;font-size:1.25rem;letter-spacing:-.02em}
.pcard-nums span{font-size:.72rem;color:var(--muted)}
.pcard-foot{display:flex;gap:.4rem;flex-wrap:wrap;padding:.7rem 1rem}

/* =====================================================================
   Light and dark mode.

   Light is the default look; html[data-theme="dark"] swaps the tokens.
   The switch sits in the top bar of both panels and in the public
   header, and the browser remembers the choice (see theme.php).
   The menu follows the look as well, which is why the sidebar has its
   own --sb-* tokens: white in light mode, the Theme sidebar colour in
   dark mode — and the logo above it changes with it.
   ===================================================================== */
:root{
  --sb-bg:#ffffff; --sb-bg-2:#fbfcfe; --sb-text:#3b4a61; --sb-strong:#0f172a; --sb-muted:#8a96ab;
  --sb-hover:rgba(15,23,42,.05); --sb-line:#e6eaf2; --sb-top:#f8fafd;
  --sb-sec:#fcfdff; --sb-sec-line:#e7ebf3; --sb-group-bg:rgba(248,250,253,.95);
  --sb-find-bg:#ffffff; --sb-find-line:#dde3ed; --sb-find-text:#0f172a; --sb-thumb:rgba(15,23,42,.16);
}
html[data-theme="dark"]{
  color-scheme:dark;
  --bg:#0a0f1c; --surface:#111827; --surface-2:#172033; --line:#253149; --line-2:#1c2639;
  --text:#e7ecf5; --text-2:#b4c0d4; --muted:#8391a9;
  --ok:#4ade80; --ok-bg:rgba(34,197,94,.14);
  --warn:#fbbf24; --warn-bg:rgba(245,158,11,.15);
  --danger:#f87171; --danger-bg:rgba(239,68,68,.15);
  --info:#60a5fa; --info-bg:rgba(59,130,246,.15);
  --brand-light:rgba(var(--brand-rgb),.2);
  --shadow:0 1px 2px rgba(0,0,0,.35), 0 8px 24px rgba(0,0,0,.3);
  --shadow-lg:0 12px 40px rgba(0,0,0,.55);

  --sb-bg:var(--sidebar); --sb-bg-2:var(--sidebar-2); --sb-text:#c1cde0; --sb-strong:#ffffff; --sb-muted:#7c8aa3;
  --sb-hover:rgba(255,255,255,.07); --sb-line:rgba(255,255,255,.08); --sb-top:rgba(0,0,0,.12);
  --sb-sec:rgba(255,255,255,.025); --sb-sec-line:rgba(255,255,255,.09); --sb-group-bg:rgba(13,21,38,.92);
  --sb-find-bg:rgba(255,255,255,.06); --sb-find-line:rgba(255,255,255,.1); --sb-find-text:#e6ecf7; --sb-thumb:rgba(255,255,255,.14);
}

/* the menu */
.sidebar{background:linear-gradient(180deg,var(--sb-bg) 0%,var(--sb-bg-2) 100%);color:var(--sb-text);border-right:1px solid var(--sb-line)}
.sidebar::-webkit-scrollbar-thumb,.nav::-webkit-scrollbar-thumb{background:var(--sb-thumb)}
.sidebar .brand{color:var(--sb-strong)}
.sb-top{background:var(--sb-top)}
.sb-top .brand{border-bottom-color:var(--sb-line)}
.nav-group{color:var(--sb-muted)}
.nav a{color:var(--sb-text)}
.nav a:hover{background:var(--sb-hover);color:var(--sb-strong)}
.nav a.active,.nav a.active:hover{color:#fff}
.sb-foot{border-top-color:var(--sb-line);color:var(--sb-muted)}
.sb-foot strong{color:var(--sb-text)}
.nav-sec{border-color:var(--sb-sec-line);background:var(--sb-sec)}
.nav-sec .nav-group{background:var(--sb-group-bg);border-bottom-color:var(--sb-sec-line)}
.nav-find input{background:var(--sb-find-bg);border-color:var(--sb-find-line);color:var(--sb-find-text)}
.nav-find input:focus{background:var(--sb-find-bg)}
.nav-find input::placeholder,.nav-find-none{color:var(--sb-muted)}
@supports not selector(:has(a)){ .nav-sec{background:var(--sb-sec)} }

/* the logo: one for each look, and the caption under it */
.brand-has-logo{flex-direction:column;align-items:flex-start;justify-content:center;gap:.3rem}
.brand-logos{display:flex;align-items:center;max-width:100%;line-height:0}
.brand .brand-logo,.brand-logo{display:block;width:auto;height:auto;max-height:40px;max-width:200px;border-radius:0;object-fit:contain}
.brand .brand-svg{height:36px;max-width:190px}
.brand-logos .logo-for-dark{display:none}
html[data-theme="dark"] .brand-logos .logo-for-light{display:none}
html[data-theme="dark"] .brand-logos .logo-for-dark{display:block}
html[data-theme="dark"] .fkbd-ink{fill:#fff}
.brand-sub{font-size:.64rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--sb-muted);line-height:1.2}

/* the switch: a moon while the page is light, a sun while it is dark */
.theme-tgl svg{display:block}
.theme-tgl .tt-sun{display:none}
html[data-theme="dark"] .theme-tgl .tt-sun{display:block}
html[data-theme="dark"] .theme-tgl .tt-moon{display:none}
.tb-icon.theme-tgl:hover{color:var(--brand)}

/* the few colours that were not tokens */
:where(html[data-theme="dark"]) a{color:color-mix(in srgb,var(--brand) 55%,#fff)}
html[data-theme="dark"] .badge-brand,
html[data-theme="dark"] .msg.staff header{color:color-mix(in srgb,var(--brand) 45%,#fff)}
html[data-theme="dark"] .badge-muted{background:var(--line-2)}
html[data-theme="dark"] .switch .sl{background:#334155}
html[data-theme="dark"] .flash-success{color:#bbf7d0;border-color:rgba(34,197,94,.32)}
html[data-theme="dark"] .flash-error{color:#fecaca;border-color:rgba(239,68,68,.32)}
html[data-theme="dark"] .flash-warning{color:#fde68a;border-color:rgba(245,158,11,.32)}
html[data-theme="dark"] .flash-info{color:#bfdbfe;border-color:rgba(59,130,246,.32)}
html[data-theme="dark"] .tb-icon.lic-chip.ok{color:#4ade80}
html[data-theme="dark"] .tb-icon.lic-chip.warn{color:#fbbf24}
html[data-theme="dark"] .tb-icon.lic-chip.danger{color:#f87171}
html[data-theme="dark"] .nav a.active .pill{background:#fff;color:#0f172a}
html[data-theme="dark"] img.thumb{background:#fff;border-radius:6px}

/* paper stays white */
@media print{
  html[data-theme="dark"]{color-scheme:light;--bg:#fff;--surface:#fff;--surface-2:#f8fafc;--line:#e4e8f0;
    --line-2:#eef1f6;--text:#0f172a;--text-2:#475569;--muted:#7b879c}
}

/* Settings -> General: logo and icon uploads */
.sb-home{display:block;color:inherit;text-decoration:none}
.sb-home:hover{text-decoration:none}
.brand-up-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1rem}
.brand-up{display:flex;flex-direction:column;gap:.45rem;border:1px solid var(--line);border-radius:12px;padding:.9rem;background:var(--surface)}
.brand-up label{font-weight:700;font-size:.86rem}
.brand-up-prev{height:92px;border-radius:10px;display:grid;place-items:center;background:#fff;border:1px dashed #d5dce7;padding:.7rem}
.brand-up.on-dark .brand-up-prev{background:#0b1220;border-color:#0b1220}
.brand-up-prev img,.brand-up-prev .brand-up-svg{max-height:64px;height:64px;max-width:100%;width:auto;object-fit:contain}

/* Settings -> Footer & branding: the credit on a light and a dark footer */
.credit-prev{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:.8rem}
.credit-prev-box{position:relative;border:1px solid #e4e8f0;border-radius:12px;background:#fff;color:#475569;padding:1.6rem 1rem 1rem}
.credit-prev-box.is-dark{background:#0b1220;border-color:#0b1220;color:#cbd5e1}
.credit-prev-box .foot-credit{background:none;border:0;color:inherit;margin:0;padding:0}
.credit-prev-tag{position:absolute;top:.45rem;left:.7rem;font-size:.66rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;opacity:.6}
.fkbd-on-dark .fkbd-ink{fill:#fff}

/* English / বাংলা on the product, addon and package forms */
.bi{border:1px solid var(--line);border-radius:12px;background:var(--surface);min-width:0}
.bi-bar{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .9rem;padding:.55rem .7rem;
  border-bottom:1px solid var(--line);background:var(--surface-2);border-radius:12px 12px 0 0}
.bi-tabs{display:inline-flex;gap:.25rem;background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:3px}
.bi-tab{border:0;background:none;padding:.4rem .85rem;border-radius:8px;font:inherit;font-weight:700;
  font-size:.86rem;color:var(--text-2);cursor:pointer;display:inline-flex;align-items:center;gap:.4rem;white-space:nowrap}
.bi-tab:hover{background:var(--surface-2)}
.bi-tab.on{background:var(--primary,#4f46e5);color:#fff}
.bi-miss{font-size:.68rem;font-weight:800;background:#fef3c7;color:#92400e;border-radius:20px;padding:.05rem .45rem;line-height:1.5}
.bi-miss.done{background:#dcfce7;color:#166534}
.bi-tab.on .bi-miss{background:rgba(255,255,255,.25);color:#fff}
.bi-note{font-size:.76rem;color:var(--muted);flex:1 1 220px;min-width:0}
.bi-pane{padding:.9rem}
.bi-lbl{font-size:.66rem;font-weight:800;color:var(--muted);border:1px solid var(--line);border-radius:6px;padding:0 .3rem;vertical-align:middle}
.bi-en{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
html[data-theme="dark"] .bi-miss{background:rgba(245,158,11,.2);color:#fcd34d}
html[data-theme="dark"] .bi-miss.done{background:rgba(34,197,94,.18);color:#86efac}
@media (max-width:640px){ .bi-pane .form-grid.f2{grid-template-columns:1fr} .bi-pane .span2{grid-column:auto} }

/* Admin -> Comments & Suggestions */
.cm-filters{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}
.cm-filters select,.cm-filters input[type=search]{flex:1 1 170px;min-width:0;max-width:260px}
.cm-bulk{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;margin:.2rem 0 .7rem}
.cm-bulk select{max-width:220px}
.cm-item{margin-bottom:.8rem}
.cm-item.cm-pending{border-left:4px solid #f59e0b}
.cm-item.cm-hidden,.cm-item.cm-spam{opacity:.72}
.cm-item.cm-focus{box-shadow:0 0 0 2px var(--primary,#4f46e5)}
.cm-top{display:flex;gap:.7rem;align-items:flex-start;flex-wrap:wrap}
.cm-top>input[type=checkbox]{margin-top:.7rem}
.cm-av{width:38px;height:38px;flex:0 0 38px}
.cm-who{flex:1 1 260px;min-width:0}
.cm-who .badge{margin-left:.25rem}
.cm-page{text-align:right;font-size:.86rem;min-width:0;max-width:100%}
.cm-parent{margin:.6rem 0 0;padding:.45rem .7rem;border-left:3px solid var(--line);background:var(--surface-2);font-size:.84rem;color:var(--text-2);border-radius:0 8px 8px 0}
.cm-body{margin:.7rem 0 .5rem;white-space:normal;line-height:1.6;overflow-wrap:anywhere}
.cm-foot{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}
.cm-forms{display:flex;flex-wrap:wrap;gap:.4rem 1.2rem;margin-top:.5rem}
.cm-forms details{flex:1 1 280px;min-width:0}
.cm-forms summary{cursor:pointer;font-size:.84rem;font-weight:600;color:var(--primary,#4f46e5)}
.cm-forms textarea{width:100%;margin-top:.4rem}
@media (max-width:640px){ .cm-page{text-align:left} }

/* Admin -> Home Page */
.hs-form[data-lang="en"] .hs-l-bn,.hs-form[data-lang="bn"] .hs-l-en{display:none}
.hs-l + .hs-l{margin-top:0}
.hs-langbar{border:1px solid var(--line);border-radius:12px}
.hs-list{margin-top:1.2rem;border-top:1px solid var(--line);padding-top:1rem}
.hs-list-h{display:flex;align-items:center;gap:.6rem;margin-bottom:.6rem}
.hs-items{display:grid;gap:.7rem;margin-bottom:.7rem}
.hs-item{border:1px solid var(--line);border-radius:12px;background:var(--surface-2);overflow:hidden}
.hs-item-bar{display:flex;align-items:center;gap:.35rem;padding:.4rem .6rem;border-bottom:1px solid var(--line);background:var(--surface)}
.hs-item-n{font-weight:800;font-size:.8rem;color:var(--muted)}
.hs-item .form-grid{padding:.8rem}
.hs-thumb{display:block;max-width:220px;max-height:120px;border-radius:8px;border:1px solid var(--line);margin:.3rem 0}
.hs-icon-in{max-width:110px;font-size:1.15rem}
.hs-tokens{margin-top:1.2rem;font-size:.86rem}
.hs-tokens summary{cursor:pointer;font-weight:600;color:var(--primary,#4f46e5)}
.hs-move{display:inline-flex;gap:.2rem}
.hs-table td{vertical-align:middle}
textarea.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.84rem}

/* English / বাংলা on the public pages and the sign-in screens */
.lang-pub{display:inline-flex;align-items:center;gap:2px;padding:3px;border:1px solid var(--line);border-radius:999px;background:var(--surface);flex:0 0 auto}
.lang-pub a{display:inline-flex;align-items:center;min-height:34px;padding:0 .72rem;border-radius:999px;font-size:.8rem;font-weight:800;
  color:var(--text-2);text-decoration:none;white-space:nowrap}
.lang-pub a.on{background:var(--primary,#4f46e5);color:#fff}
.lang-pub a:not(.on):hover{color:var(--primary,#4f46e5);text-decoration:none}
.auth-lang{display:flex;justify-content:flex-end;margin:0 0 .8rem}
.reg-main .auth-lang{margin-bottom:1rem}
html[lang="bn"] body{font-family:'Hind Siliguri','Noto Sans Bengali','Nirmala UI',var(--font,system-ui),sans-serif}

/* Languages & Translations */
.tr-stats .stat{text-decoration:none;color:inherit}
.tr-stats .stat:hover{text-decoration:none;border-color:var(--brand)}
.tr-txt{font-family:inherit;font-size:.86rem;background:none;border:0;padding:0;color:inherit;white-space:pre-wrap;word-break:break-word}
.tr-bn{font-family:'Hind Siliguri','Noto Sans Bengali','Nirmala UI',var(--font,system-ui),sans-serif;font-size:.95rem}
.tr-tbl td:nth-child(2),.tr-tbl td:nth-child(3){min-width:220px;max-width:460px}
.tr-tbl tr.tr-on td{background:rgba(var(--brand-rgb),.07)}
.tr-ph{display:inline-block;font-size:.74rem;background:var(--surface-2);border:1px solid var(--line);border-radius:5px;padding:0 .3rem}
.tr-filter{padding-bottom:.4rem}
.tr-filter select{width:auto}
.tr-foot{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center;justify-content:space-between}
.tr-foot select{width:auto}
.tr-more form{margin:0}
.tr-where{margin:0;padding-left:1.1rem;display:grid;gap:.55rem;font-size:.88rem}
@media (max-width:640px){.tr-filter .toolbar select,.tr-filter .toolbar .btn{flex:1 1 auto}}

/* ---------------------------------------------- Settings → Licensing: cron job */
.cron-card .card-h h2{margin:0}
.cron-pill{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .75rem;border-radius:999px;font-size:.76rem;font-weight:800;letter-spacing:.02em}
.cron-pill::before{content:"";width:.5rem;height:.5rem;border-radius:50%;background:currentColor}
.cron-pill.cron-ok{background:var(--ok-bg);color:var(--ok)}
.cron-pill.cron-ok::before{animation:cronBeat 1.8s ease-in-out infinite}
.cron-pill.cron-late{background:var(--warn-bg);color:var(--warn)}
.cron-pill.cron-stopped{background:var(--danger-bg);color:var(--danger)}
.cron-pill.cron-never{background:var(--surface-2);color:var(--muted)}
@keyframes cronBeat{0%,100%{box-shadow:0 0 0 0 currentColor}50%{box-shadow:0 0 0 4px transparent}}
.cron-state{display:flex;gap:.9rem;align-items:flex-start;padding:1rem 1.1rem;border-radius:14px;border:1px solid var(--line);background:var(--surface-2)}
.cron-state.cron-ok{background:var(--ok-bg);border-color:color-mix(in srgb,var(--ok) 30%,transparent)}
.cron-state.cron-late{background:var(--warn-bg);border-color:color-mix(in srgb,var(--warn) 30%,transparent)}
.cron-state.cron-stopped{background:var(--danger-bg);border-color:color-mix(in srgb,var(--danger) 30%,transparent)}
.cron-ico{flex:0 0 auto;width:2.4rem;height:2.4rem;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-weight:900;font-size:1.1rem;color:#fff;background:var(--muted)}
.cron-ok .cron-ico{background:var(--ok)}
.cron-late .cron-ico{background:var(--warn)}
.cron-stopped .cron-ico{background:var(--danger)}
.cron-state-txt{min-width:0}
.cron-state-txt strong{display:block;font-size:.98rem;color:var(--text)}
.cron-state-txt p{margin:.25rem 0 0;font-size:.85rem;color:var(--text-2);line-height:1.55}
.cron-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:.6rem;margin:.8rem 0 0}
.cron-facts>div{border:1px solid var(--line);border-radius:12px;padding:.6rem .8rem;background:var(--surface);min-width:0}
.cron-facts dt{font-size:.7rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.cron-facts dd{margin:.15rem 0 0;font-weight:700;color:var(--text);overflow-wrap:anywhere}
.cron-sub{font-size:.76rem;font-weight:500;color:var(--muted)}
dd.cron-sub{margin-top:0;font-weight:500}
.cron-alert{margin-top:.8rem;padding:.8rem 1rem;border-radius:12px;background:var(--warn-bg);border:1px solid color-mix(in srgb,var(--warn) 35%,transparent)}
.cron-alert strong{color:var(--warn)}
.cron-alert p{margin:.3rem 0;font-size:.85rem;color:var(--text-2);line-height:1.55}
.cron-out{margin-top:.8rem;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.cron-out summary{cursor:pointer;padding:.6rem .9rem;font-weight:700;font-size:.87rem}
.cron-out pre{margin:0;padding:.7rem .9rem;border-top:1px solid var(--line);font-size:.76rem;line-height:1.6;overflow-x:auto;white-space:pre-wrap;
  overflow-wrap:anywhere;font-family:ui-monospace,Consolas,monospace;color:var(--text-2)}
.cron-guide{margin-top:1.2rem;padding-top:1.1rem;border-top:1px dashed var(--line)}
.cron-guide h3{margin:0 0 .8rem;font-size:1rem}
.cron-guide h4{margin:1.2rem 0 .4rem;font-size:.9rem}
.cron-guide p{line-height:1.6}
.cron-steps{list-style:none;counter-reset:cron;margin:0;padding:0;display:flex;flex-direction:column;gap:.7rem}
.cron-steps>li{counter-increment:cron;position:relative;padding:.1rem 0 .1rem 2.6rem;min-width:0}
.cron-steps>li::before{content:counter(cron);position:absolute;left:0;top:0;width:1.9rem;height:1.9rem;border-radius:50%;
  background:var(--brand);color:#fff;font-weight:800;font-size:.85rem;display:flex;align-items:center;justify-content:center}
.cron-steps>li>strong{display:block;font-size:.92rem}
.cron-steps>li>p{margin:.15rem 0 .45rem;font-size:.85rem;color:var(--text-2)}
.cron-cmd{margin:.35rem 0}
.cron-cmd input{flex:1 1 auto;min-width:0;font-family:ui-monospace,Consolas,monospace;font-size:.78rem}
.cron-faq{margin:.3rem 0 0}
.cron-faq dt{font-weight:700;font-size:.86rem;margin-top:.6rem}
.cron-faq dd{margin:.15rem 0 0;font-size:.84rem;color:var(--text-2);line-height:1.55}
@media (max-width:560px){.cron-state{padding:.8rem}.cron-steps>li{padding-left:2.3rem}}

/* -------------------------------------------- Settings → Footer & branding: links */
.fl-list{display:flex;flex-direction:column;gap:.6rem;margin-top:.8rem}
.fl-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:.7rem;align-items:start;padding:.75rem .8rem;
  border:1px solid var(--line);border-radius:14px;background:var(--surface);transition:border-color .2s,box-shadow .2s}
.fl-row:focus-within{border-color:var(--brand);box-shadow:0 0 0 3px color-mix(in srgb,var(--brand) 15%,transparent)}
.fl-row.fl-new{animation:flIn .35s ease}
@keyframes flIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.fl-order{display:flex;flex-direction:column;gap:.25rem;padding-top:1.1rem}
.fl-mv,.fl-del{width:1.8rem;height:1.8rem;border-radius:8px;border:1px solid var(--line);background:var(--surface-2);color:var(--text-2);
  cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:.7rem;line-height:1;padding:0}
.fl-mv:hover{border-color:var(--brand);color:var(--brand)}
.fl-del{font-size:1.15rem;margin-top:1.1rem}
.fl-del:hover{border-color:var(--danger);color:var(--danger);background:var(--danger-bg)}
.fl-fields{min-width:0;display:flex;flex-direction:column;gap:.55rem}
.fl-inputs{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.7fr);gap:.55rem}
.fl-f{display:flex;flex-direction:column;gap:.2rem;min-width:0;margin:0}
.fl-f>span{font-size:.7rem;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.fl-f input{width:100%;min-width:0}
.fl-panels{display:flex;flex-wrap:wrap;gap:.35rem}
.fl-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.28rem .65rem;border:1px solid var(--line);border-radius:999px;
  font-size:.76rem;font-weight:600;cursor:pointer;background:var(--surface-2);color:var(--text-2);user-select:none;max-width:100%}
.fl-chip input{width:auto;margin:0;accent-color:var(--brand)}
.fl-chip:has(input:checked){border-color:color-mix(in srgb,var(--brand) 55%,transparent);background:color-mix(in srgb,var(--brand) 12%,transparent);color:var(--text)}
.fl-add-row{margin-top:.8rem}
.fl-bulk{margin-top:.8rem;padding:.9rem 1rem;border:1.5px dashed color-mix(in srgb,var(--brand) 40%,var(--line));border-radius:14px;
  background:color-mix(in srgb,var(--brand) 5%,var(--surface));display:flex;flex-direction:column;gap:.6rem}
.fl-bulk label{font-size:.85rem}
.fl-bulk textarea{width:100%;min-height:7rem;font-family:ui-monospace,Consolas,monospace;font-size:.8rem;line-height:1.6}
.fl-bulk-panels{display:flex;flex-wrap:wrap;gap:.35rem;align-items:center}
.fl-bulk-msg.ok{color:var(--ok);font-weight:700}
.fl-bulk-msg.err{color:var(--danger);font-weight:700}
@media (max-width:640px){
  .fl-inputs{grid-template-columns:minmax(0,1fr)}
  .fl-row{grid-template-columns:minmax(0,1fr) auto;padding:.7rem}
  .fl-order{grid-column:1/-1;grid-row:2;flex-direction:row;padding-top:0}
  .fl-del{margin-top:0}
}

/* ------------------------------------------------------------- message templates (SMS / WhatsApp) */
.tpl-group{margin:1.4rem 0 .6rem;font-size:.78rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.tpl-group:first-of-type{margin-top:.2rem}
.tpl{border:1px solid var(--line);border-radius:12px;padding:.75rem .85rem;margin-bottom:.7rem;background:var(--surface)}
.tpl-h{display:flex;align-items:center;gap:.5rem;margin-bottom:.35rem}
.tpl-h label{font-weight:700;font-size:.88rem}
.tpl textarea{width:100%;font-family:inherit}
.tpl-f{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-top:.4rem;font-size:.76rem}
.tpl-count{color:var(--muted);font-variant-numeric:tabular-nums}
.tpl-vars{display:flex;gap:.25rem;flex-wrap:wrap;margin-left:auto}
.tpl-var{border:1px solid var(--line);background:var(--surface-2);color:var(--muted);border-radius:999px;padding:.1rem .45rem;
  font:inherit;font-size:.72rem;cursor:pointer;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.tpl-var:hover{border-color:var(--brand);color:var(--brand)}

/* ------------------------------------------------------------- e-mail templates */
table.tbl.mt-tbl{min-width:640px}
.mt-tbl tr.mt-group td{background:var(--surface-2);font-size:.72rem;font-weight:800;letter-spacing:.07em;
  text-transform:uppercase;color:var(--muted);padding:.45rem .85rem}
.mt-tbl tr.mt-off td{opacity:.6}
.mt-tbl .mt-subj{max-width:280px;overflow-wrap:anywhere}
.mt-tbl td.actions,.mt-tbl th.actions{min-width:0}
.mt-state{display:flex;gap:.3rem;flex-wrap:wrap;align-items:center}
.mt-vars{display:flex;flex-wrap:wrap;gap:.3rem;align-items:center;margin-top:.7rem}
.mt-vars code{font-size:.74rem;background:var(--surface-2);border:1px solid var(--line);border-radius:6px;padding:.05rem .35rem}
.mt-layout{display:grid;gap:.9rem}
.mt-lab{display:block;font-size:.72rem;color:var(--muted);font-weight:600;margin-bottom:.45rem}
.mt-preview{width:100%;height:640px;border:1px solid var(--line);border-radius:12px;background:#f1f5f9;display:block}
@media (max-width:640px){.mt-preview{height:500px}}

/* ------------------------------------------------------------- payment method logos */
.pay-logo{display:inline-flex;align-items:center;justify-content:center;line-height:0;flex:0 0 auto}
.pay-logo svg,.pay-logo img{height:32px;width:auto;max-width:100px;display:block;border-radius:7px}
.gw .gi .pay-logo svg,.gw .gi .pay-logo img{height:40px;max-width:120px}
.pay-logo-prev{margin:.35rem 0}
.pay-logo-prev .pay-logo svg,.pay-logo-prev .pay-logo img{height:44px;max-width:132px}
.pay-strip{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.5rem}
.pay-strip .pay-logo svg,.pay-strip .pay-logo img{height:24px}

/* ------------------------------------------------------------- the invoice logo drawn in code */
.inv-logo-svg{height:56px;width:auto;max-width:240px;display:block}

/* ------------------------------------------------------------- translations: the list fits its box */
table.tbl.tr-tbl{min-width:0;table-layout:fixed}
.tr-tbl th:nth-child(1),.tr-tbl td:nth-child(1){width:42px}
.tr-tbl th:nth-child(4),.tr-tbl td:nth-child(4){width:132px}
.tr-tbl th:nth-child(5),.tr-tbl td:nth-child(5){width:84px}
.tr-tbl td.actions,.tr-tbl th.actions{min-width:0}
.tr-tbl td:nth-child(2),.tr-tbl td:nth-child(3){min-width:0;max-width:none;overflow-wrap:anywhere}
table.tbl.tr-tbl code.tr-txt,table.tbl.tr-tbl .tbl-sub code.tr-txt{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word}
@media (max-width:760px){
  .tr-tbl thead{display:none}
  table.tbl.tr-tbl,.tr-tbl tbody{display:block;width:100%}
  .tr-tbl tr{display:grid;grid-template-columns:30px minmax(0,1fr) auto;gap:.3rem .6rem;padding:.7rem .85rem;border-bottom:1px solid var(--line-2)}
  .tr-tbl td{display:block;width:auto!important;padding:0!important;border:0!important;min-width:0}
  .tr-tbl td:nth-child(1){grid-row:1 / span 3;padding-top:.15rem!important}
  .tr-tbl td:nth-child(2),.tr-tbl td:nth-child(3){grid-column:2 / span 2}
  .tr-tbl td:nth-child(4){grid-column:2;grid-row:3}
  .tr-tbl td:nth-child(5){grid-column:3;grid-row:3;text-align:right}
}

/* The first line of a message, so the template list says what each one
   actually sends rather than only what it is called. */
.tpl-peek{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.75rem;opacity:.85;
  overflow-wrap:anywhere;white-space:normal}

/* ------------------------------------------------- key prefixes per product
   The example keys are the widest thing on the row, and they used to push
   the table past the edge of its card. They wrap now, and on a phone each
   row becomes a small stack instead of a sideways scroll. */
table.tbl.kp-tbl{min-width:0;table-layout:fixed}
.kp-tbl th:nth-child(1),.kp-tbl td:nth-child(1){width:26%}
.kp-tbl th:nth-child(2),.kp-tbl td:nth-child(2),
.kp-tbl th:nth-child(3),.kp-tbl td:nth-child(3){width:17%}
.kp-tbl td input{max-width:100%}
.kp-tbl td.kp-eg{white-space:normal}
.kp-tbl td.kp-eg code{white-space:normal;overflow-wrap:anywhere;word-break:break-word;
  font-size:.76rem;line-height:1.5}
.kp-lab{display:inline-block;min-width:4.4rem;color:var(--muted);font-size:.7rem;
  text-transform:uppercase;letter-spacing:.05em;font-weight:700}
@media (max-width:760px){
  .kp-tbl,.kp-tbl tbody,.kp-tbl tr,.kp-tbl td{display:block;width:auto}
  .kp-tbl thead{display:none}
  .kp-tbl tr{border:1px solid var(--line);border-radius:12px;padding:.6rem .7rem;margin-bottom:.6rem}
  .kp-tbl td{border:0;padding:.28rem 0;width:auto}
  .kp-tbl td:nth-child(1),.kp-tbl td:nth-child(2),.kp-tbl td:nth-child(3){width:auto}
  .kp-tbl .tbl-title{display:inline}
  .kp-tbl td input{max-width:none;width:100%}
}

/* The name of the message being edited, on a line of its own so it can be
   translated like any other heading. */
.tpl-name{margin:0 0 .3rem;font-size:.98rem;font-weight:700}
