:root{
  /* Sampled from the Designphic logo mark: its teal, steel blue, indigo and
     purple. --grad is the mark's own gradient; --grad-strong is the same
     sweep one step deeper so white text on it stays readable (4.5:1+). */
  --brand-teal:#02a8a2; --brand-blue:#2478a0; --brand-indigo:#553b9c; --brand-purple:#86189b;
  --teal:var(--brand-teal); --blue:var(--brand-blue); --purple:var(--brand-purple);
  --grad:linear-gradient(135deg,#02a8a2 0%,#2478a0 45%,#553b9c 78%,#86189b 100%);
  --grad-strong:linear-gradient(110deg,#02837e 0%,#1f6a8f 60%,#4a3590 100%);
  /* Logo teal, deepened only as far as white text on it needs (4.6:1). */
  --primary:#02837e; --primary-d:#016d69; --primary-soft:#e2f5f3;
  --bg:#f5f7fb; --surface:#ffffff; --surface-2:#f8fafc;
  --border:#e4e8f0; --border-2:#eef1f6; --border-input:#8596ae;
  /* Text: deep navy, then two greys that both pass 4.5:1 on white. */
  --ink:#121629; --muted:#4f5a6e; --faint:#667085;
  --green:#15803d; --green-bg:#eaf7ee;
  --red:#be123c; --red-bg:#fdeaef;
  --amber:#b45309; --amber-bg:#fef4e6;
  --topbar-bg:rgba(255,255,255,.86); --tabbar-bg:rgba(255,255,255,.94); --hover:#cfd6e2;
  --radius:12px;
  --shadow:0 1px 2px rgba(18,22,41,.04),0 1px 3px rgba(18,22,41,.06);
  --shadow-md:0 6px 16px -4px rgba(18,22,41,.10),0 2px 4px -2px rgba(18,22,41,.06);
  --shadow-lg:0 24px 48px -12px rgba(18,22,41,.22);
  --sidebar-w:248px;
  --gold:var(--primary); --gold-soft:var(--primary-soft);
  --text:var(--ink); --yellow:var(--amber);
  --glass:var(--surface); --glass-2:var(--surface-2);
  --stroke:var(--border); --stroke-soft:var(--border-2);
}
/* Dark: the logo's navy-indigo instead of neutral grey, so the dark theme
   still reads as Designphic. Every text colour is at least 5:1. */
body[data-theme="dark"]{
  --bg:#0b0e1c; --surface:#12162a; --surface-2:#191e36;
  --border:#262c47; --border-2:#1f2440; --border-input:#5f6a90;
  --ink:#e9ecf5; --muted:#a3abc2; --faint:#8790a8;
  --primary-soft:#0f2e33;
  --green:#4ade80; --green-bg:#10261c;
  --red:#fb7185; --red-bg:#2c1220;
  --amber:#fbbf24; --amber-bg:#2a200c;
  --topbar-bg:rgba(18,22,42,.82); --tabbar-bg:rgba(18,22,42,.94); --hover:#323a5c;
  --shadow:0 1px 2px rgba(0,0,0,.45),0 1px 3px rgba(0,0,0,.3);
  --shadow-md:0 8px 20px -6px rgba(0,0,0,.55);
  --shadow-lg:0 24px 48px -12px rgba(0,0,0,.7);
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
/* A label a screen reader can find without changing how the field looks:
   the auth screen's inputs rely on a placeholder alone today, which reads
   fine visually but disappears as an association the moment there's text
   in the field, and was never announced as a label to begin with. */
.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}
html,body{height:100%}
body{font-family:'Inter',system-ui,-apple-system,sans-serif;color:var(--ink);background:var(--bg);min-height:100vh;font-size:14px;-webkit-font-smoothing:antialiased;transition:background .25s,color .25s}
body[data-lang="bn"]{font-family:'Hind Siliguri','Inter',system-ui,sans-serif}
h1,h2,h3{font-family:'Inter',system-ui,-apple-system,sans-serif;letter-spacing:-.01em}
.bn-brand{font-family:'Poppins',sans-serif}
body[data-lang="bn"] h1,body[data-lang="bn"] h2,body[data-lang="bn"] h3{font-family:'Hind Siliguri','Inter',sans-serif}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:inherit;font-size:14px;color:var(--ink)}
a{color:inherit;text-decoration:none}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:var(--border);border-radius:8px;border:2px solid var(--bg)}
::-webkit-scrollbar-track{background:transparent}
.glass{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow)}

.logo-badge{background:transparent;border-radius:14px;display:flex;align-items:center;justify-content:center;overflow:visible;flex-shrink:0;position:relative}
.logo-badge img{display:block;width:100%;height:100%;object-fit:contain}
.logo-badge.sm{width:38px;height:38px}
.logo-badge.lg{width:64px;height:64px}
.logo-badge.xl{width:104px;height:104px}

#auth{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;padding:24px;background:var(--bg)}
.auth-card{width:100%;max-width:392px;padding:38px 32px;text-align:center;box-shadow:var(--shadow-lg)}
.auth-card .logo-badge{margin:0 auto 18px}
.auth-logo{font-size:24px;font-weight:800;letter-spacing:-.6px}
.auth-logo b{color:var(--primary)}
.auth-sub{color:var(--muted);font-size:12.5px;margin-bottom:26px}
.auth-card input{width:100%;padding:13px 15px;border-radius:11px;background:var(--surface-2);border:1px solid var(--border);margin-bottom:14px;outline:none;transition:.18s}
.auth-card input:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft);background:var(--surface)}
.auth-err{color:var(--red);font-size:12.5px;min-height:18px;margin-bottom:6px;text-align:left;font-weight:500}
.auth-toggles{display:flex;gap:8px;justify-content:center;margin-bottom:20px}

.btn{display:inline-flex;align-items:center;gap:8px;justify-content:center;padding:10px 16px;border-radius:10px;font-weight:600;font-size:13.5px;background:var(--surface);border:1px solid var(--border);color:var(--ink);transition:.16s}
.btn:hover{background:var(--surface-2);border-color:var(--hover)}
.btn:active{transform:translateY(1px)}
.btn-gold{background:var(--primary);color:#fff;border-color:transparent}
.btn-gold:hover{background:var(--primary-d)}
.btn-grad{background:var(--grad-strong);color:#fff;border-color:transparent;width:100%}
.btn-grad:hover{filter:brightness(.94)}
.btn-sm{padding:7px 12px;font-size:12.5px;border-radius:9px}
.btn-danger{color:var(--red);border-color:#f6c6d2}
body[data-theme="dark"] .btn-danger{border-color:#5b2230}
.btn-danger:hover{background:var(--red-bg)}
.btn-ghost{background:transparent}
.btn-ok{color:var(--green);border-color:#bfe6cd}
body[data-theme="dark"] .btn-ok{border-color:#22503a}
.btn-ok:hover{background:var(--green-bg)}
/* WhatsApp reminder: an icon button on desktop, icon plus label on phones.
   The icon carries its own size (an un-sized svg collapses in a flex button). */
.btn-wa{color:var(--green);border-color:#bfe6cd;padding-left:6px;padding-right:6px;gap:6px}
.btn-wa:hover{background:var(--green-bg)}
.btn-wa .wa-ic{width:16px;height:16px;flex-shrink:0;display:block;stroke-width:2}
.btn-wa .wa-lbl{display:none}
body[data-theme="dark"] .btn-wa{border-color:#22503a}
@media(max-width:640px){.btn-wa{padding-left:11px;padding-right:12px}.btn-wa .wa-lbl{display:inline}}
/* Service badges: a sale or a client can carry several services. */
.svc-badges{display:flex;flex-wrap:wrap;gap:4px}
.svc-badge{background:var(--primary-soft);color:var(--primary-d)}
.svc-more{background:var(--surface-2);color:var(--muted);border:1px solid var(--border)}
@media(max-width:640px){.table-wrap tbody td .svc-badges{justify-content:flex-end}}
/* Sale form: one row per service, each with its own amount. */
.svc-lines{display:flex;flex-direction:column;gap:8px}
.svc-line{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) 38px;gap:8px;align-items:center}
.svc-line .svc-del{width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center}
.svc-line .svc-del svg{width:15px;height:15px}
.svc-line .svc-del:disabled{opacity:.35;cursor:not-allowed}
.svc-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:10px;flex-wrap:wrap}
.svc-foot .btn svg{width:14px;height:14px}
.svc-total{font-size:13px;color:var(--muted)}
.svc-total b{font-size:15px;color:var(--ink);margin-left:6px;font-variant-numeric:tabular-nums}
.fld.err .svc-amt{border-color:var(--red)}

/* segmented + icon controls */
.seg{display:inline-flex;background:var(--surface-2);border:1px solid var(--border);border-radius:10px;overflow:hidden;padding:2px}
.seg button{padding:7px 11px;font-weight:600;font-size:12.5px;color:var(--muted);transition:.15s;border-radius:8px;white-space:nowrap}
.seg button.active{background:var(--primary);color:#fff}
.icon-btn{width:38px;height:38px;border-radius:10px;background:var(--surface-2);border:1px solid var(--border);color:var(--muted);display:flex;align-items:center;justify-content:center;transition:.15s}
.icon-btn:hover{color:var(--ink);border-color:var(--hover)}
.icon-btn svg{width:18px;height:18px}

#app{display:none}
.shell{display:flex;min-height:100vh}
.sidebar{width:var(--sidebar-w);flex-shrink:0;position:sticky;top:0;height:100vh;padding:20px 14px;display:flex;flex-direction:column;gap:4px;background:var(--surface);border-right:1px solid var(--border)}
.side-brand{display:flex;align-items:center;gap:11px;padding:6px 8px 18px;border-bottom:1px solid var(--border-2);margin-bottom:14px}
.side-brand .bn{font-size:16.5px;font-weight:800;letter-spacing:-.4px;line-height:1.1;font-family:'Poppins'}
.side-brand .bn b{color:var(--primary)}
.side-brand .bt{font-size:12px;color:var(--faint);font-weight:600;letter-spacing:1.2px;text-transform:uppercase;margin-top:3px}
.nav-label{font-size:12px;font-weight:700;color:var(--faint);letter-spacing:.8px;text-transform:uppercase;padding:8px 12px 4px}
.nav-item{display:flex;align-items:center;gap:11px;padding:10px 14px;border-radius:10px;color:var(--muted);font-weight:500;font-size:14.5px;transition:background .15s ease,color .15s ease,transform .15s ease,box-shadow .15s ease;cursor:pointer}
.nav-item svg{width:18px;height:18px;flex-shrink:0;stroke-width:2;opacity:.85;transition:opacity .15s ease}
.nav-item:hover{background:var(--surface-2);color:var(--ink)}
.nav-item:hover svg{opacity:1}
.nav-item.active{background:var(--grad-strong);color:#fff;font-weight:600;box-shadow:0 1px 2px rgba(16,24,40,.14)}
.nav-item.active svg{stroke:#fff;opacity:1}
.side-foot{margin-top:auto;font-size:12px;color:var(--faint);padding:12px;border-top:1px solid var(--border-2)}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{position:sticky;top:0;z-index:50;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 24px;background:var(--topbar-bg);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border-bottom:1px solid var(--border)}
.page-title{font-size:19px;font-weight:700;letter-spacing:-.3px}
.topbar-actions{display:flex;align-items:center;gap:9px}
.mode-pill{font-size:12px;padding:5px 11px;border-radius:20px;border:1px solid var(--border);color:var(--muted);font-weight:600;background:var(--surface)}
.mode-pill.local{color:var(--amber);border-color:#f3dcb4;background:var(--amber-bg)}
.mode-pill.live{color:var(--green);border-color:#bfe6cd;background:var(--green-bg)}
body[data-theme="dark"] .mode-pill.local{border-color:#4a3a18}
body[data-theme="dark"] .mode-pill.live{border-color:#1f4a33}
.content{padding:24px;flex:1;width:100%;max-width:100%;min-width:0}
@media(min-width:1100px){.content{padding:26px 32px}}
@media(min-width:1600px){.content{padding:30px 44px}}
@media(min-width:2000px){.content{padding:34px 64px}}
.tabbar{display:none}

.welcome{display:flex;align-items:center;gap:18px;padding:20px 22px;margin-bottom:20px;position:relative;overflow:hidden}
.welcome::before{content:'';position:absolute;left:0;top:0;bottom:0;width:5px;background:var(--grad)}
.welcome h2{font-size:18px;font-weight:700;letter-spacing:-.3px}
.welcome p{color:var(--muted);font-size:13px;line-height:1.6;margin-top:5px;max-width:700px}
.welcome .tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:11px}
.welcome .tag{font-size:12px;font-weight:600;padding:4px 10px;border-radius:20px;background:var(--primary-soft);color:var(--primary-d)}
body[data-theme="dark"] .welcome .tag{color:#2fd1c6}

.grid{display:grid;gap:16px}
.stat-grid{grid-template-columns:repeat(auto-fit,minmax(200px,1fr));margin-bottom:18px}
.stat{padding:20px;position:relative;overflow:hidden}
.stat .label{font-size:12px;color:var(--muted);font-weight:600;display:flex;align-items:center;gap:8px}
.stat .ic-box svg{width:16px;height:16px}
.stat .value{font-size:27px;font-weight:700;margin-top:12px;letter-spacing:-.6px;font-family:'Inter',system-ui,sans-serif}
.stat .sub{font-size:12px;color:var(--faint);margin-top:5px;font-weight:500}
.stat.profit-pos .value{color:var(--green)}
.stat.profit-neg .value{color:var(--red)}
.stat .value.gold{color:var(--primary)}
body[data-theme="dark"] .stat .value.gold{color:#2fd1c6}

@media(min-width:900px){.dash-lists{grid-template-columns:1fr 1fr}}
.card{padding:20px}
.card h3{font-size:14.5px;font-weight:700;margin-bottom:16px;display:flex;align-items:center;justify-content:space-between;gap:8px}
.card h3 .hint{font-size:12px;color:var(--faint);font-weight:500}
.chart-wrap{position:relative;height:290px}
.chart-wrap.sm{height:250px}
.mini-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 0;border-bottom:1px solid var(--border-2)}
.mini-row:last-child{border-bottom:none}
.mini-row .ttl{font-weight:600;font-size:13.5px}
.mini-row .meta{font-size:12px;color:var(--muted);margin-top:2px}
.mini-amt{font-weight:700;font-family:'Inter',system-ui,sans-serif;white-space:nowrap}

.toolbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:18px}
.input,.select{padding:10px 13px;border-radius:10px;background:var(--surface);border:1px solid var(--border-input);outline:none;transition:.16s;min-width:0;color:var(--ink)}
.input:focus,.select:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
.input::placeholder{color:var(--faint)}
.select{appearance:none;padding-right:34px;cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2364748b' stroke-width='2'%3E%3Cpath d='M2 4l4 4 4-4'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 13px center}
.field{position:relative}
.search{flex:1;min-width:200px}
.search .input{width:100%;padding-left:38px}
.search svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--faint)}
.spacer{flex:1}
.total-pill{font-size:13px;color:var(--muted);font-weight:500}
.total-pill b{color:var(--ink);font-size:17px;font-family:'Inter',system-ui,sans-serif;margin-left:6px}
.chips{display:flex;gap:8px;flex-wrap:wrap}
.chip{padding:7px 13px;border-radius:9px;background:var(--surface);border:1px solid var(--border);font-size:12.5px;font-weight:600;color:var(--muted);transition:.15s}
.chip:hover{color:var(--ink);border-color:var(--hover)}
.chip.active{background:var(--primary-soft);color:var(--primary-d);border-color:#b9e7e0}
body[data-theme="dark"] .chip.active{color:#2fd1c6;border-color:#1f4a46}

.table-wrap{overflow-x:auto;border-radius:var(--radius);border:1px solid var(--border-2)}
table{width:100%;border-collapse:collapse;font-size:13.5px}
th{text-align:left;padding:12px 14px;font-weight:700;font-size:12px;color:var(--muted);background:var(--surface-2);border-bottom:1px solid var(--border);white-space:nowrap;cursor:pointer;user-select:none;text-transform:uppercase;letter-spacing:.3px}
th:hover{color:var(--ink)}
th .arrow{color:var(--primary);font-size:12px;margin-left:3px}
td{padding:12px 14px;border-bottom:1px solid var(--border-2);vertical-align:middle}
tbody tr:last-child td{border-bottom:none}
tbody tr{transition:.1s}
tbody tr:hover{background:var(--surface-2)}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
.row-actions{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap}
.badge{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:20px;font-size:12px;font-weight:600}
.badge::before{content:'';width:6px;height:6px;border-radius:50%;background:currentColor}
.b-active{background:var(--green-bg);color:var(--green)}
.b-inactive{background:var(--surface-2);color:var(--muted)}
.b-paid{background:var(--green-bg);color:var(--green)}
.b-unpaid{background:var(--red-bg);color:var(--red)}
.b-partial{background:var(--amber-bg);color:var(--amber)}
.b-overdue{background:var(--red-bg);color:var(--red)}
/* Leave and due-soon status pills, in the same .badge.b-* family as the
   ones above, so every status pill in the app comes from one place. */
.b-pending{background:var(--amber-bg);color:var(--amber)}
.b-duesoon{background:var(--amber-bg);color:var(--amber)}
.b-approved{background:var(--green-bg);color:var(--green)}
.b-rejected{background:var(--red-bg);color:var(--red)}

.client-grid{grid-template-columns:repeat(auto-fill,minmax(255px,1fr))}
.client-card{padding:18px;cursor:pointer;transition:.16s}
.client-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);border-color:var(--hover)}
.client-card .cc-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
.client-card .cc-name{font-weight:700;font-size:15.5px;font-family:'Inter',system-ui,sans-serif}
.client-card .cc-row{display:flex;align-items:center;gap:7px;color:var(--muted);font-size:12.5px;margin-top:10px}
.client-card .cc-row svg{width:14px;height:14px;flex-shrink:0;color:var(--faint)}
.client-card .cc-svc{margin-top:13px;font-size:12px;font-weight:700;letter-spacing:.3px;color:var(--primary-d);background:var(--primary-soft);display:inline-block;padding:4px 10px;border-radius:7px}
body[data-theme="dark"] .client-card .cc-svc{color:#2fd1c6}

#toasts{position:fixed;top:18px;right:18px;z-index:300;display:flex;flex-direction:column;gap:10px;pointer-events:none}
.toast{display:flex;align-items:center;gap:11px;padding:13px 16px;border-radius:12px;min-width:250px;max-width:350px;background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-lg);animation:slideIn .3s cubic-bezier(.2,.9,.3,1);pointer-events:auto;font-size:13.5px;font-weight:500}
.toast.out{animation:slideOut .3s forwards}
.toast .ic{width:22px;height:22px;flex-shrink:0;border-radius:50%;display:flex;align-items:center;justify-content:center}
.toast .ic svg{width:13px;height:13px;color:#fff}
.toast.ok{border-left:3px solid var(--green)}.toast.ok .ic{background:var(--green)}
.toast.err{border-left:3px solid var(--red)}.toast.err .ic{background:var(--red)}
.toast.info{border-left:3px solid var(--primary)}.toast.info .ic{background:var(--primary)}
.toast-act{flex-shrink:0;background:var(--primary-soft);color:var(--primary-d);border-radius:8px;padding:6px 12px;font-weight:700;font-size:12px;transition:.15s}
.toast-act:hover{background:var(--primary);color:#fff}
body[data-theme="dark"] .toast-act{color:#2fd1c6}
@keyframes slideIn{from{transform:translateX(120%);opacity:0}to{transform:translateX(0);opacity:1}}
@keyframes slideUp{from{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}
@keyframes slideOut{to{transform:translateX(120%);opacity:0}}

.overlay{position:fixed;inset:0;z-index:150;display:none;align-items:center;justify-content:center;padding:20px;background:rgba(15,27,45,.5);backdrop-filter:blur(3px);animation:fade .2s}
.overlay.show{display:flex}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{width:100%;max-width:520px;max-height:90vh;overflow-y:auto;padding:26px;box-shadow:var(--shadow-lg);animation:pop .25s cubic-bezier(.2,.9,.3,1)}
.modal.wide{max-width:660px}
@keyframes pop{from{transform:scale(.96) translateY(8px);opacity:0}to{transform:scale(1) translateY(0);opacity:1}}
.modal-head{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:20px}
.modal-head h2{font-size:18px;font-weight:700}
.modal-head .x{width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:var(--muted);background:var(--surface-2);transition:.15s}
.modal-head .x:hover{color:var(--ink);background:var(--border-2)}
.modal-head .x svg{width:16px;height:16px}
.form-grid{display:grid;gap:14px}
@media(min-width:520px){.form-grid.two{grid-template-columns:1fr 1fr}}
.fld label{display:block;font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:6px}
.fld .input,.fld .select,.fld textarea{width:100%}
.fld textarea{padding:11px 13px;border-radius:10px;background:var(--surface);border:1px solid var(--border);outline:none;resize:vertical;min-height:74px;transition:.16s;color:var(--ink)}
.fld textarea:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
.fld.err .input,.fld.err .select,.fld.err textarea{border-color:var(--red);box-shadow:0 0 0 3px var(--red-bg)}
.fld .err-msg{color:var(--red);font-size:12px;margin-top:5px;display:none;font-weight:500}
.fld.err .err-msg{display:block}
.modal-foot{display:flex;gap:10px;margin-top:24px}
.modal-foot .btn{flex:1}
.confirm{max-width:410px;text-align:center;padding:30px 26px}
.confirm .ic{width:50px;height:50px;border-radius:50%;background:var(--red-bg);color:var(--red);display:flex;align-items:center;justify-content:center;margin:0 auto 16px}
.confirm h2{font-size:17px;margin-bottom:8px}
.confirm p{color:var(--muted);font-size:13.5px;line-height:1.5;margin-bottom:22px}
.empty{text-align:center;padding:48px 20px;color:var(--muted)}
.empty .ic{width:56px;height:56px;border-radius:50%;background:var(--surface-2);display:flex;align-items:center;justify-content:center;margin:0 auto 16px;color:var(--faint)}
.empty .ic svg{width:24px;height:24px}
.empty h3{font-size:15px;color:var(--ink);margin-bottom:6px}
.empty p{font-size:13px;max-width:320px;margin:0 auto;line-height:1.5}
.loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:54px;color:var(--muted);gap:14px}
.spinner{width:34px;height:34px;border:3px solid var(--border);border-top-color:var(--primary);border-radius:50%;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.detail-meta{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px}
.detail-meta .dm{padding:12px 14px;background:var(--surface-2);border-radius:10px;border:1px solid var(--border-2)}
.detail-meta .dm .k{font-size:12px;color:var(--faint);margin-bottom:4px;font-weight:600}
.detail-meta .dm .v{font-weight:600;font-size:13.5px;word-break:break-word}
.sub-head{font-size:12.5px;font-weight:700;color:var(--primary-d);margin:18px 0 10px;text-transform:uppercase;letter-spacing:.4px}
body[data-theme="dark"] .sub-head{color:#2fd1c6}
.kv-row{display:flex;justify-content:space-between;padding:9px 0;border-bottom:1px solid var(--border-2);font-size:13px}
.kv-row:last-child{border-bottom:none}
.kv-row .k{color:var(--muted)}.kv-row .v{font-weight:600}

@media(max-width:860px){
  /* The sidebar becomes the phone's full nav drawer, the exact same markup
     and buildNav() output the desktop rail uses (Settings included, which
     the bottom tab bar below has no room for), just slid off-canvas by
     default instead of removed from layout, and brought on screen with a
     transform instead of a rebuilt second menu. */
  .sidebar{
    display:flex;position:fixed;top:0;left:0;z-index:210;height:100vh;
    width:min(300px,82vw);transform:translateX(-100%);
    transition:transform .3s cubic-bezier(.4,0,.2,1);
    box-shadow:16px 0 40px rgba(0,0,0,.28);
  }
  body.mobile-drawer-open .sidebar{transform:translateX(0)}
  /* Collapsing the rail to icon-only makes no sense on a drawer that
     already covers the screen edge-to-edge when open, so that control sits
     out entirely on phones. The rest of the "what does collapsed look
     like" override lives further down, AFTER the desktop collapsed-rail
     rules in the stylesheet, on purpose: same selectors, same specificity,
     so source order is what decides the winner, and it has to win here. */
  .sidebar .sidebar-toggle{display:none}

  /* display:flex/block here is overridden by later, higher-priority !important
     rules near the bottom of this file (search "Bug fix" there); every other
     property below is real and in effect, only the visibility toggle moved. */
  .mobile-menu-btn{display:flex}
  .mobile-drawer-close{
    display:flex;position:absolute;top:18px;right:14px;width:32px;height:32px;
    align-items:center;justify-content:center;border-radius:9px;color:var(--muted);
    background:var(--surface-2);border:1px solid var(--border);
  }
  .mobile-drawer-close svg{width:16px;height:16px}
  .mobile-drawer-backdrop{
    display:block;position:fixed;inset:0;z-index:205;background:rgba(15,27,45,.5);
    backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
    opacity:0;pointer-events:none;transition:opacity .25s ease;
  }
  body.mobile-drawer-open .mobile-drawer-backdrop{opacity:1;pointer-events:auto}
  body.mobile-drawer-open{overflow:hidden}

  .content{padding:18px 14px 92px}
  .topbar{padding:13px 16px}
  .page-title{font-size:17px}
  .welcome{flex-direction:column;align-items:flex-start;gap:12px}
  /* Five equal slots. The active one gets a soft pill behind its icon; every
     icon sits in the same 52x28 box, so nothing shifts when the tab changes. */
  .tabbar{display:grid;grid-template-columns:repeat(5,1fr);position:fixed;bottom:0;left:0;right:0;z-index:90;background:var(--tabbar-bg);border-top:1px solid var(--border);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);padding:6px 6px calc(6px + env(safe-area-inset-bottom))}
  .tab{display:flex;flex-direction:column;align-items:center;gap:3px;padding:4px 2px;min-width:0;color:var(--muted);font-size:12px;font-weight:600;letter-spacing:.01em;transition:color .15s ease}
  .tab svg{width:52px;height:28px;padding:4px 16px;box-sizing:border-box;border-radius:999px;stroke-width:1.9;transition:background .15s ease}
  .tab span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tab:active svg{background:var(--surface-2)}
  .tab.active{color:var(--primary-d)}
  .tab.active svg{background:var(--primary-soft);color:var(--primary)}
  body[data-theme="dark"] .tab.active{color:#2fd1c6}
  body[data-theme="dark"] .tab.active svg{color:#2fd1c6}
  .modal{padding:22px 18px}
  .detail-meta{grid-template-columns:1fr}
  .stat .value{font-size:24px}
  .topbar-actions .mode-pill{display:none}
}
@media(max-width:430px){.seg button{padding:7px 9px;font-size:12px}.topbar-actions{gap:6px}}

/* ===== premium animations & components ===== */
@media (prefers-reduced-motion: reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important}}
.btn-gold:active,.btn-grad:active{transform:scale(.98)}
.trend{display:inline-block;font-size:12px;font-weight:700;padding:2px 7px;border-radius:20px;margin-right:7px}
.trend.up{background:var(--green-bg);color:var(--green)}.trend.down{background:var(--red-bg);color:var(--red)}
.act{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--border-2)}
.act:last-child{border-bottom:none}
.act .ttl{font-weight:600;font-size:13.5px}
.act .meta{font-size:12px;color:var(--muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:210px}
.act-ic{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.act-ic svg{width:16px;height:16px}
.act-ic.sale{background:var(--green-bg);color:var(--green)}
.act-ic.cost{background:var(--red-bg);color:var(--red)}
.act-ic.payment{background:var(--primary-soft);color:var(--primary)}
body[data-theme="dark"] .act-ic.payment{color:#2fd1c6}
.tc{display:flex;align-items:center;gap:12px;padding:9px 0}
.tc .tc-name{width:130px;font-weight:600;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex-shrink:0}
.tc .bar{flex:1;height:8px;border-radius:6px;background:var(--surface-2);overflow:hidden}
.tc .fill{height:100%;border-radius:6px;background:var(--grad);width:0}
.tc .tc-amt{font-weight:700;font-size:12.5px;white-space:nowrap;font-family:'Inter',system-ui,sans-serif;flex-shrink:0}
@media(max-width:520px){.tc .tc-name{width:88px}}
.skel{background:linear-gradient(90deg,var(--surface-2) 25%,var(--border-2) 37%,var(--surface-2) 63%);background-size:400% 100%;animation:shimmer 1.4s ease infinite;border-radius:10px}
@keyframes shimmer{0%{background-position:100% 0}100%{background-position:-100% 0}}
.linkbox{background:var(--surface-2);border:1px dashed var(--border);border-radius:11px;padding:14px}
/* premium toggle switch (overrides .fld label rule) */
.fld label.switch,label.switch{display:inline-flex!important;align-items:center;gap:12px;cursor:pointer;font-size:13.5px;font-weight:600;user-select:none;margin-bottom:0!important;color:var(--ink);line-height:1.3}
.switch input[type="checkbox"]{position:absolute;opacity:0;width:0;height:0;pointer-events:none;margin:0}
.switch .track{position:relative;width:44px;height:24px;border-radius:24px;background:var(--border);transition:background .25s ease;flex-shrink:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.08)}
.switch .track::after{content:'';position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:#fff;transition:transform .18s ease,box-shadow .18s ease;box-shadow:0 1px 3px rgba(0,0,0,.25),0 0 0 1px rgba(0,0,0,.04)}
.switch input:checked + .track{background:var(--primary);box-shadow:inset 0 1px 2px rgba(16,24,40,.15)}
.switch input:checked + .track::after{transform:translateX(20px);box-shadow:0 1px 3px rgba(16,24,40,.3)}
.switch input:focus-visible + .track{box-shadow:0 0 0 3px var(--primary-soft),inset 0 1px 2px rgba(0,0,0,.08)}
.switch .label-txt{flex:1;min-width:0}
/* A toggle with an explanation under it. The switch itself carries
   margin-bottom:0!important (it has to, so it sits flush inside a .fld), which
   means neither the switch nor the paragraph could be spaced apart from the
   outside. Both were sitting on top of each other. The gap belongs to this
   wrapper instead, where no !important is fighting it. */
.switch-row{margin-bottom:16px}
.switch-row .fx-note{margin-top:8px;margin-bottom:0}
.link-hint{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--primary-d);margin-top:12px;font-weight:500}
.link-hint svg{width:14px;height:14px}
body[data-theme="dark"] .link-hint{color:#2fd1c6}
#auth{overflow:hidden}
/* Sign-in: a plain card on a plain ground, the way business software opens. */
.auth-orbs{display:none}
.auth-card{position:relative;animation:fade .25s ease both}
.auth-card .logo-badge.xl{position:relative}
.auth-input-wrap{position:relative;margin-bottom:14px}
.auth-input-wrap input{margin-bottom:0!important;padding-right:44px}
.auth-input-wrap .eye{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:34px;height:34px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:var(--faint)}
.auth-input-wrap .eye:hover{color:var(--muted)}
.auth-input-wrap .eye svg{width:18px;height:18px}

/* premium polish */
.glass{transition:box-shadow .25s ease, border-color .25s ease, transform .25s ease}
.btn{transition:background .18s ease, border-color .18s ease, transform .12s ease, box-shadow .18s ease}
.icon-btn{transition:background .18s ease, color .18s ease, transform .18s ease}
.icon-btn:active{transform:scale(.96)}
.seg button{transition:background .2s ease, color .2s ease}
tr{transition:background .15s ease}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
#view{animation:fadeIn .25s ease both}
.act{transition:background .15s ease;border-radius:8px;padding:11px 8px;margin:0 -8px}
.act:hover{background:var(--surface-2)}
.toast{animation:slideIn .22s ease-out both}
.chip{transition:background .18s ease, color .18s ease, border-color .18s ease, transform .12s ease}
.chip:active{transform:scale(.96)}
/* page-title smooth replace */
.page-title{transition:opacity .2s ease}

/* ===== RBAC / chips / perms / devices ===== */
.user-chip{display:flex;align-items:center;gap:8px;padding:4px 11px 4px 4px;border-radius:30px;background:var(--surface-2);border:1px solid var(--border);cursor:pointer;transition:.18s}
.user-chip:hover{border-color:var(--hover)}
.uc-avatar{width:30px;height:30px;border-radius:50%;background:var(--grad-strong);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;flex-shrink:0}
.uc-meta{display:flex;flex-direction:column;line-height:1.18}
.uc-name{font-weight:600;font-size:13px}
.uc-role{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.05em}
.uc-role.superadmin{color:var(--brand-indigo)}
body[data-theme="dark"] .uc-role.superadmin{color:#b7a6f0}
.uc-role.employee{color:var(--muted)}
@media(max-width:640px){.uc-meta{display:none}}
.glass.stat[onclick]{cursor:pointer;position:relative}
.glass.stat[onclick]:hover{transform:translateY(-1px);box-shadow:var(--shadow-md);border-color:var(--hover)}
.glass.stat[onclick]:active{transform:none}
.glass.stat[onclick]::after{content:'→';position:absolute;top:14px;right:16px;font-size:17px;font-weight:700;color:var(--faint);opacity:0;transform:translateX(-5px);transition:.22s cubic-bezier(.2,.9,.3,1)}
.glass.stat[onclick]:hover::after{opacity:.75;transform:translateX(0)}
.perm-grid{border:1px solid var(--border);border-radius:13px;overflow:hidden;margin-top:6px}
.perm-head,.perm-row{display:grid;grid-template-columns:1.7fr 1fr 1fr 1fr 1fr;align-items:center}
.perm-head{background:var(--surface-2);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--muted)}
.perm-head span{padding:11px 12px;text-align:center}
.perm-head span:first-child{text-align:left}
.perm-row{border-top:1px solid var(--border)}
.perm-row .perm-sec{padding:11px 12px;font-weight:600;font-size:13px}
.ck{display:flex;align-items:center;justify-content:center;padding:9px;cursor:pointer}
.ck input{width:18px;height:18px;accent-color:var(--primary);cursor:pointer}
.emp-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 13px;border:1px solid var(--border);border-radius:13px;margin-bottom:10px;flex-wrap:wrap;transition:.16s}
.emp-row:hover{border-color:var(--primary);box-shadow:var(--shadow)}
.emp-info{display:flex;align-items:center;gap:11px}
.emp-acts{display:flex;gap:8px;flex-wrap:wrap}
.dev-log{display:flex;flex-direction:column;gap:9px}
.dev-item{display:flex;align-items:center;gap:13px;padding:11px 13px;border:1px solid var(--border);border-radius:13px;background:var(--surface-2)}
.dev-ic{width:36px;height:36px;border-radius:10px;background:var(--surface);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--primary);flex-shrink:0}
.dev-ic svg{width:18px;height:18px}
.dev-meta{flex:1;min-width:0}
.dev-time{font-size:12px;color:var(--muted);white-space:nowrap}

.audit-list{display:flex;flex-direction:column;gap:9px;max-height:520px;overflow-y:auto}
.audit-row{display:flex;align-items:flex-start;gap:13px;padding:11px 13px;border:1px solid var(--border);border-radius:13px;background:var(--surface-2)}
.audit-badge{flex-shrink:0;padding:4px 10px;border-radius:20px;font-size:12px;font-weight:700;white-space:nowrap;background:var(--surface);border:1px solid var(--border);color:var(--muted)}
.audit-badge.is-created{color:var(--green);border-color:#bfe6cd}
.audit-badge.is-updated{color:var(--amber);border-color:#f2dba8}
.audit-badge.is-deleted{color:var(--red);border-color:#f6c6d2}
body[data-theme="dark"] .audit-badge.is-created{border-color:#22503a}
body[data-theme="dark"] .audit-badge.is-updated{border-color:#5c4419}
body[data-theme="dark"] .audit-badge.is-deleted{border-color:#5b2230}
.audit-body{flex:1;min-width:0}
.audit-head{font-size:13px;color:var(--ink)}
.audit-diff{font-size:12px;color:var(--muted);margin-top:4px;line-height:1.7;word-break:break-word}
.audit-time{font-size:12px;color:var(--muted);white-space:nowrap;flex-shrink:0}

/* Generic icon-size utilities: pass as svg()'s second argument for any
   icon that isn't already sized by a specific ancestor selector (.btn
   itself sets none, so a bare icon in a plain button renders at the
   browser's un-sized-SVG default, hugely oversized, unless given one of
   these). */
.ic-13{width:13px;height:13px;flex-shrink:0}
.ic-16{width:16px;height:16px;flex-shrink:0}

.payroll-table{display:flex;flex-direction:column;gap:8px}
.payroll-row{display:flex;align-items:center;gap:14px;padding:12px 14px;border:1px solid var(--border);border-radius:13px;background:var(--surface-2);flex-wrap:wrap}
.payroll-row.is-paid{opacity:.7}
.payroll-row-head{background:none;border:none;border-bottom:1px solid var(--border-2);border-radius:0;padding:0 14px 8px;font-size:12px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.04em}
.payroll-row-head .payroll-who,.payroll-row-head .payroll-amt,.payroll-row-head .payroll-method,.payroll-row-head .payroll-status{font:inherit;color:inherit;text-transform:inherit;letter-spacing:inherit}
.payroll-check input{width:18px;height:18px;accent-color:var(--primary);cursor:pointer}
.payroll-check input:disabled{cursor:not-allowed}
.payroll-who{flex:1;min-width:140px}
.payroll-name{font-weight:600;font-size:13.5px}
.payroll-desig{font-size:12px;color:var(--muted);margin-top:2px}
.payroll-amt{font-weight:700;font-family:'Inter',system-ui,sans-serif;white-space:nowrap;min-width:88px;text-align:right}
.payroll-method{font-size:12px;color:var(--muted);min-width:88px;text-align:right}
.payroll-status{min-width:96px;display:flex;justify-content:flex-end}
.payroll-review-list{display:flex;flex-direction:column;gap:8px;max-height:360px;overflow-y:auto;margin-top:4px}
.payroll-review-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--border-2);flex-wrap:wrap}
.payroll-review-amt{max-width:110px}
.payroll-review-method{max-width:130px}

/* password show toggle */
.pw-wrap{position:relative}
.pw-wrap input{padding-right:42px;width:100%}
.pw-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--muted);cursor:pointer;padding:6px;display:flex;align-items:center;border-radius:8px;transition:.15s}
.pw-eye:hover{color:var(--primary);background:var(--surface-2)}
.pw-eye svg{width:18px;height:18px}

/* quotation builder + perm view-only */
.perm-row .pf{color:var(--faint);text-align:center}
.qitem{display:grid;grid-template-columns:1fr 70px 104px 92px 34px;gap:8px;align-items:center;margin-bottom:8px}
.qitem .qline{font-weight:700;font-size:13px;text-align:right;color:var(--ink)}
.qtotals{margin-top:16px;max-width:300px;margin-left:auto}
.qtot-row{display:flex;justify-content:space-between;padding:5px 2px;font-size:13px;color:var(--muted)}
.qtot-row b{color:var(--ink)}
.qtot-row.total{border-top:2px solid var(--primary);margin-top:5px;padding-top:9px}
.qtot-row.total span{font-weight:700;color:var(--ink)}
.qtot-row.total b{color:var(--primary);font-size:17px}
@media(max-width:560px){.qitem{grid-template-columns:1fr 1fr 1fr;}.qitem .qline{grid-column:1/2;text-align:left}}

/* ===== ANIMATION + UI POLISH v1.5 ===== */

/* Page-level enter animation */
@keyframes pageEnter{from{opacity:0}to{opacity:1}}
#view{animation:pageEnter .18s ease-out}


/* Button micro-interactions */
.btn{transition:background .18s,color .18s,border-color .18s,transform .12s,box-shadow .18s,opacity .15s}
.btn:hover:not(:disabled){transform:none;box-shadow:none}
.btn:active:not(:disabled){transform:scale(.98)}

/* Input focus ring */
.input,.select,textarea{transition:border-color .18s,box-shadow .18s,background .15s}
.input:focus,.select:focus,textarea:focus{box-shadow:0 0 0 3px color-mix(in srgb,var(--primary) 18%,transparent)}



/* Table row hover */
tbody tr{transition:background .14s}
tbody tr:hover{background:var(--surface-2) !important}


/* Switch toggle */
.track{transition:background .22s}
input[type=checkbox]:focus+.track{box-shadow:0 0 0 3px color-mix(in srgb,var(--primary) 25%,transparent)}

/* Modal scale-in */
@keyframes popIn{from{transform:translateY(6px);opacity:0}to{transform:none;opacity:1}}
.modal{animation:popIn .18s ease-out}

/* Sidebar bottom version chip */
.sidebar-footer{transition:opacity .2s}
.sidebar-footer:hover{opacity:.8}

/* Topbar */
.topbar{transition:box-shadow .2s}

/* Bottom tabbar (mobile) */
.bottom-nav a{transition:color .15s,background .15s}
.bottom-nav a:active{background:color-mix(in srgb,var(--primary) 10%,transparent);border-radius:10px}

/* Scroll smooth */
*{scroll-behavior:smooth}

/* Quotation item row enter */
@keyframes itemSlideIn{from{opacity:0;transform:translateX(-8px)}to{opacity:1;transform:translateX(0)}}
.qitem{animation:itemSlideIn .2s ease both}

/* Reminder card rows */
.mini-row{transition:background .15s,transform .15s}
.mini-row:hover{background:var(--surface-2);border-radius:10px;transform:translateX(2px)}


/* Skeleton shimmer (already exists, tweak speed) */
@media(max-width:640px){
  .form-grid.two{grid-template-columns:1fr !important}
  .toolbar{flex-wrap:wrap;gap:8px}
  .toolbar .spacer{display:none}
  .topbar{padding:10px 14px}
  .modal{padding:18px}
  .qitem{grid-template-columns:1fr 1fr 1fr !important}
}

/* Reduced motion */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
}

/* ===== Cost sub-tabs (Salary / Software / Office Cost) ===== */
.cost-subtabs{display:none;gap:9px;margin-bottom:16px;flex-wrap:wrap}
@media(max-width:860px){.cost-subtabs{display:flex}}
.cost-subtab{display:flex;align-items:center;gap:7px;padding:9px 16px;border-radius:12px;border:1px solid var(--border);background:var(--surface);color:var(--muted);font-weight:600;font-size:13px;cursor:pointer;transition:background .22s,color .22s,border-color .22s,transform .15s,box-shadow .22s}
.cost-subtab svg{width:16px;height:16px;transition:transform .25s}
.cost-subtab:hover{border-color:var(--hover);color:var(--ink)}
.cost-subtab.active{background:var(--primary);color:#fff;border-color:transparent}
.cost-subtab:active{transform:translateY(0) scale(.97)}
#costSubContent{animation:fade .15s ease-out}
@media(max-width:640px){.cost-subtabs{gap:7px}.cost-subtab{padding:8px 12px;font-size:12.5px;flex:1;justify-content:center}}

/* ===== Sidebar nested Costs/Employees group ===== =====================
   Rebuilt on the technique modern dashboards (Hostinger's sidebar included)
   actually use for a submenu that opens smoothly regardless of how many
   rows are inside it: animating CSS Grid's own track size (0fr -> 1fr)
   instead of max-height. A max-height transition times itself against a
   guessed ceiling (220px, 300px, whatever was picked), so it either snaps
   open early or drags on with nothing left to reveal; a grid track sized in
   fr units tracks the content's real height every frame, so the motion is
   exactly as long as the content actually is, every time. */
/* The sub-list opens as ONE solid block, not as items that fade in one by
   one. The staggered version that was here before ran the children's opacity
   over .16s against a container that took .34s, so on the way out the labels
   blinked away and then an empty gap kept shrinking, which is what made it
   feel cheap. Sliding the whole block on a single .35s ease curve (the same
   timing the reference software's Reports menu uses) reads as one physical
   movement in both directions. */
.nav-group{display:flex;flex-direction:column}
.nav-item:active,.nav-item:hover:active{transform:scale(.985)}
.nav-item .chev{margin-left:auto;width:14px;height:14px;flex-shrink:0;color:var(--faint);opacity:.85;transition:transform .35s ease,color .15s ease,opacity .15s ease}
.nav-item.active .chev{color:#fff;opacity:1}
.nav-group.expanded>.nav-item .chev{transform:rotate(180deg)}
.nav-subwrap{display:grid;grid-template-rows:0fr;transition:grid-template-rows .35s ease}
.nav-group.expanded .nav-subwrap{grid-template-rows:1fr}
.nav-subwrap-in{overflow:hidden;display:flex;flex-direction:column;gap:4px;min-height:0;padding-top:4px}
.nav-subitem{display:flex;align-items:center;gap:9px;padding:7px 13px 7px 28px;border-radius:10px;font-size:14px;font-weight:500;color:var(--muted);cursor:pointer;transition:background .15s ease,color .15s ease,transform .15s ease;position:relative}
.nav-subitem:active,.nav-subitem:hover:active{transform:scale(.985)}
.nav-subitem svg{width:15px;height:15px;flex-shrink:0;opacity:.85;transition:opacity .15s ease}
.nav-subitem::before{content:'';position:absolute;left:13px;top:-2px;bottom:-2px;width:1px;background:var(--border)}
.nav-subitem:hover{background:var(--surface-2);color:var(--ink);transform:translateX(2px)}
.nav-subitem:hover svg{opacity:1}
.nav-subitem.active{background:color-mix(in srgb,var(--primary) 14%,transparent);color:var(--primary-d);font-weight:600}
.nav-subitem.active svg{opacity:1}
body[data-theme="dark"] .nav-subitem.active{color:#2fd1c6}
/* ============================================================
   v2.8  Exchange rate card, wide-screen settings, premium polish
   ============================================================ */

/* --- Live exchange rate card (Settings) --- */
.fx-live{display:flex;flex-direction:column;gap:4px;padding:14px 16px;border-radius:12px;background:var(--surface-2);border:1px solid var(--border-2)}
.fx-rate{font-size:20px;font-weight:700;letter-spacing:-.3px;color:var(--muted);font-family:'Inter',system-ui,sans-serif}
.fx-rate b{font-size:24px;font-weight:700;color:var(--primary-d)}
body[data-theme="dark"] .fx-rate b{color:#2fd1c6}
.fx-meta{font-size:12px;color:var(--faint);font-weight:500}
.fx-note{font-size:12px;color:var(--faint);line-height:1.6;margin-top:10px;max-width:420px}

/* --- Settings page: use the full width instead of a 680px column --- */

/* --- Wide screens: let the dashboard breathe instead of stretching --- */
@media(min-width:1600px){
  .stat-grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:18px}
  .grid{gap:18px}
  .chart-wrap{height:330px}
}

/* --- Cards: soft lift on hover --- */
.card,.stat,.welcome{transition:box-shadow .22s ease,transform .22s ease,border-color .22s ease}
.stat{position:relative}

/* --- Sidebar: the active row is a filled pill, so it needs no extra edge
   marker. The 2px nudge on hover is the whole hover reward. --- */
.nav-item{position:relative}
.nav-item:hover{transform:translateX(2px)}

/* --- Buttons: crisper press feedback --- */
.btn{transition:transform .12s ease,box-shadow .18s ease,background .18s ease,border-color .18s ease}
.btn:active{transform:translateY(1px)}
.btn-grad:hover,.btn-gold:hover{box-shadow:none}
.btn:disabled{opacity:.55;cursor:not-allowed;transform:none;box-shadow:none}

/* --- Tables: readable row hover --- */
tbody tr{transition:background .15s ease}
tbody tr:hover{background:var(--surface-2)}

/* --- Keyboard focus ring (accessibility) --- */
:where(button,a,input,select,textarea,[tabindex]):focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:8px}

/* --- Slimmer scrollbars --- */
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--muted) 32%,transparent);border-radius:8px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--muted) 52%,transparent);background-clip:content-box}

/* --- Respect the visitor's motion preference --- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  .nav-item:hover,.stat:hover,.card:hover{transform:none}
}

/* ============================================================
   v2.9  Settings two-pane layout and form-state fixes
   ============================================================ */

.settings-layout{display:grid;grid-template-columns:212px minmax(0,1fr);gap:26px;align-items:start}
.settings-nav{display:flex;flex-direction:column;gap:2px;position:sticky;top:84px}
.settings-nav-item{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border-radius:10px;color:var(--muted);font-weight:600;font-size:13.5px;text-align:left;transition:background .15s,color .15s,transform .15s}
.settings-nav-item svg{width:17px;height:17px;flex-shrink:0;stroke-width:2}
.settings-nav-item:hover{background:var(--surface-2);color:var(--ink);transform:translateX(2px)}
.settings-nav-item.active{background:var(--primary-soft);color:var(--primary-d);transform:none}
.settings-nav-item.active svg{stroke:var(--primary)}
body[data-theme="dark"] .settings-nav-item.active{color:#2fd1c6}
body[data-theme="dark"] .settings-nav-item.active svg{stroke:#2fd1c6}
.settings-pane{display:grid;gap:16px;max-width:760px;min-width:0}

/* Phones and small tablets: the sub-nav becomes a scrollable tab strip. */
@media(max-width:860px){
  .settings-layout{grid-template-columns:minmax(0,1fr);gap:16px}
  .settings-nav{flex-direction:row;position:static;gap:8px;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}
  .settings-nav-item{width:auto;flex-shrink:0;padding:9px 14px;border-radius:12px;border:1px solid var(--border);background:var(--surface)}
  .settings-nav-item:hover{transform:none}
  .settings-nav-item.active{background:var(--primary);color:#fff;border-color:transparent}
  .settings-nav-item.active svg{stroke:#fff}
  body[data-theme="dark"] .settings-nav-item.active,
  body[data-theme="dark"] .settings-nav-item.active svg{color:#fff;stroke:#fff}
  .settings-pane{max-width:100%}
}

/* S3: the tags block reuses .welcome, so suppress its gradient edge bar. */
.welcome.is-plain::before{display:none}

/* S5: read-only fields must not look editable. */
.input:disabled,.select:disabled,textarea:disabled{background:var(--surface-2);color:var(--faint);cursor:not-allowed;opacity:1;border-color:var(--border)}
.input:disabled:focus,.select:disabled:focus{border-color:var(--border);box-shadow:none}

/* ============================================================
   v3.0  Employees: roster, access presets, permission toggles
   ============================================================ */

/* --- page header --- */
.emp-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:20px}
.emp-head-id{display:flex;align-items:center;gap:14px;min-width:0}
.emp-head-acts{display:flex;gap:8px;flex-shrink:0}
.emp-title{font-size:21px;font-weight:700;letter-spacing:-.4px;line-height:1.15}
.emp-sub{color:var(--muted);font-size:12.5px;margin-top:4px}

/* --- avatar --- */
.emp-avatar{width:38px;height:38px;border-radius:12px;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:15px;font-family:'Inter',system-ui,sans-serif;flex-shrink:0;box-shadow:0 2px 8px rgba(16,24,40,.16);letter-spacing:.2px}
.emp-avatar.is-lg{width:46px;height:46px;border-radius:14px;font-size:18px}

/* --- roster --- */
.emp-list{display:flex;flex-direction:column;gap:10px}
.emp-card{display:flex;align-items:center;gap:14px;padding:14px 16px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}
.emp-card:hover{border-color:var(--hover);box-shadow:var(--shadow-md)}
.emp-card:active{transform:translateY(0)}
.emp-main{flex:1;min-width:0}
.emp-name{font-weight:700;font-size:14.5px;letter-spacing:-.2px}
.emp-chips{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.emp-chip{font-size:12px;font-weight:600;padding:3px 9px;border-radius:20px;background:var(--primary-soft);color:var(--primary-d);white-space:nowrap}
body[data-theme="dark"] .emp-chip{color:#2fd1c6}
.emp-chip.is-more{background:var(--surface-2);color:var(--muted)}
.emp-chip.is-none{background:var(--red-bg);color:var(--red)}
.emp-seen{font-size:12px;color:var(--faint);white-space:nowrap;flex-shrink:0}
.emp-acts{display:flex;gap:4px;flex-shrink:0;opacity:0;transition:opacity .18s ease}
.emp-card:hover .emp-acts,.emp-card:focus-within .emp-acts{opacity:1}
.emp-acts .icon-btn.is-danger:hover{color:var(--red);border-color:var(--red)}
.emp-chev{color:var(--faint);display:flex;flex-shrink:0;transition:transform .2s ease}
.emp-chev svg{width:17px;height:17px}
.emp-card:hover .emp-chev{transform:translateX(2px);color:var(--ink)}
@media(max-width:720px){
  .emp-seen{display:none}
  .emp-acts{opacity:1}
}

/* --- access presets --- */
.preset-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.preset-row.is-compact{grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px}
.preset-chip{display:flex;flex-direction:column;align-items:flex-start;gap:3px;padding:12px 14px;border-radius:12px;border:1.5px solid var(--border);background:var(--surface);text-align:left;transition:border-color .2s ease,background .2s ease,box-shadow .2s ease,transform .16s ease}
button.preset-chip{cursor:pointer}
button.preset-chip:hover{border-color:var(--hover)}
.preset-chip.active{border-color:var(--primary);background:var(--primary-soft)}
.preset-name{font-weight:700;font-size:13.5px;color:var(--ink)}
.preset-chip.active .preset-name{color:var(--primary-d)}
body[data-theme="dark"] .preset-chip.active .preset-name{color:#2fd1c6}
.preset-desc{font-size:12px;color:var(--muted);line-height:1.4}
/* Custom is a state, never a button: it lights up when the toggles stop
   matching any preset. */
.preset-chip.is-custom{border-style:dashed;opacity:.75}
.preset-chip.is-custom.active{opacity:1;border-style:solid}

/* --- fixed rows for access every employee always has --- */
.perm-base{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 14px;border-radius:10px;background:var(--surface-2);margin-bottom:8px}
.perm-base .perm-sec{font-weight:600;font-size:13px}
.perm-always{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;color:var(--green)}
.perm-always svg{width:14px;height:14px;stroke-width:2.6}

/* --- permission rows --- */
.perm-list{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.perm-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:12px 14px;border:1px solid var(--border);border-radius:12px;background:var(--surface);transition:border-color .2s ease,background .2s ease}
.perm-row:hover{border-color:var(--hover)}
.perm-master{display:flex;align-items:center;gap:11px;cursor:pointer;min-width:190px;flex-shrink:0;user-select:none}
.perm-master .perm-sec{font-weight:700;font-size:13.5px}
.perm-togs{display:flex;gap:8px;flex-wrap:wrap;flex:1;justify-content:flex-end}
@media(max-width:760px){
  .perm-row{gap:10px}
  .perm-master{min-width:100%}
  .perm-togs{justify-content:flex-start;width:100%}
}

/* ------------------------------------------------------------
   The toggle. One visual language, two sizes: the master switch
   on the left of a row, and the four action switches.
   ------------------------------------------------------------ */
.perm-master input,.ptog input{position:absolute;opacity:0;width:0;height:0;pointer-events:none;margin:0}

.ptrack{
  position:relative;flex-shrink:0;border-radius:999px;
  background:var(--border);
  transition:background .28s cubic-bezier(.4,0,.2,1),box-shadow .28s ease;
  box-shadow:inset 0 1px 3px rgba(16,24,40,.12);
}
.pknob{
  position:absolute;top:2px;left:2px;border-radius:50%;background:#fff;
  transition:transform .18s ease,box-shadow .18s ease,width .18s ease;
  box-shadow:0 1px 3px rgba(16,24,40,.28),0 0 0 .5px rgba(16,24,40,.06);
}

/* master switch: 42 x 24 */
.perm-master .ptrack{width:42px;height:24px}
.perm-master .pknob{width:20px;height:20px}
.perm-master input:checked + .ptrack{
  background:var(--primary);
  box-shadow:inset 0 1px 3px rgba(16,24,40,.15);
}
.perm-master input:checked + .ptrack .pknob{transform:translateX(18px)}

/* action switches: 34 x 20, with the label beside them */
.ptog{display:inline-flex;align-items:center;gap:8px;padding:6px 12px 6px 8px;border-radius:999px;border:1px solid transparent;background:var(--surface-2);cursor:pointer;user-select:none;transition:background .2s ease,border-color .2s ease,transform .14s ease}
.ptog:hover{border-color:var(--border);transform:translateY(-1px)}
.ptog:active{transform:translateY(0)}
.ptog .ptrack{width:34px;height:20px}
.ptog .pknob{width:16px;height:16px}
.ptxt{font-size:12px;font-weight:700;color:var(--muted);letter-spacing:.02em;transition:color .2s ease}
.ptog input:checked ~ .ptxt{color:var(--ink)}
.ptog input:checked + .ptrack .pknob{transform:translateX(14px)}

/* One colour for every action switch: on is brand teal, off is grey.
   The label next to each switch already says which action it is. */
.ptog input:checked + .ptrack{background:var(--primary);box-shadow:inset 0 1px 3px rgba(16,24,40,.15)}

/* Locked: View cannot be switched off while a write permission is granted. */
.ptog.is-locked{cursor:not-allowed;opacity:.72}
.ptog.is-locked:hover{transform:none;border-color:transparent}
.ptog.is-locked .ptrack{filter:saturate(.55)}
.ptog.is-locked .pknob{width:12px;height:12px;top:4px;left:4px}
.ptog.is-locked input:checked + .ptrack .pknob{transform:translateX(18px)}

/* keyboard focus */
.perm-master input:focus-visible + .ptrack,
.ptog input:focus-visible + .ptrack{box-shadow:0 0 0 3px var(--primary-soft),inset 0 1px 3px rgba(16,24,40,.12)}

/* --- unsaved changes bar --- */
.save-bar{position:sticky;bottom:16px;z-index:60;display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:18px;padding:12px 16px;border-radius:14px;background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;transform:translateY(12px);transition:opacity .24s ease,transform .28s cubic-bezier(.2,.9,.3,1),visibility .24s}
.save-bar.show{opacity:1;visibility:visible;transform:translateY(0)}
.save-msg{font-size:13px;font-weight:600;color:var(--amber);display:flex;align-items:center;gap:8px}
.save-msg::before{content:'';width:8px;height:8px;border-radius:50%;background:var(--amber);flex-shrink:0}
.save-acts{display:flex;gap:8px;flex-shrink:0}
@media(max-width:520px){
  .save-bar{flex-direction:column;align-items:stretch;gap:10px}
  .save-acts .btn{flex:1}
}

@media(prefers-reduced-motion:reduce){
  .emp-card:hover,.ptog:hover,button.preset-chip:hover{transform:none}
  .save-msg::before{animation:none}
}

/* ============================================================
   KPI tiles
   ============================================================ */

/* Neutral tiles. The number is the point, so it gets the ink colour and the
   weight; the icon sits in a quiet grey chip, and the only colour on a tile
   is the thin teal trend line, plus green or red on the profit figure. */
.stat{
  position:relative;overflow:hidden;
  padding:17px 18px 52px;
  background:var(--surface);
  cursor:pointer;
  transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease;
}
.stat:hover{box-shadow:var(--shadow-md);border-color:var(--hover)}
.stat:active{transform:none}

.stat-top{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.stat .ic-box{
  width:32px;height:32px;border-radius:9px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  background:var(--surface-2);color:var(--muted);border:1px solid var(--border-2);
}
.stat .ic-box svg{width:16px;height:16px;stroke-width:2}
.stat .label{font-size:12px;color:var(--muted);font-weight:600;line-height:1.35;min-width:0}

/* The hero number stays in ink so it is the most readable thing on the card.
   Colour identity is carried by the chip, the bar and the sparkline instead.
   Proportional figures on purpose: tabular-nums makes display sizes look loose. */
.stat .value{
  font-size:28px;font-weight:700;letter-spacing:-.7px;font-family:'Inter',system-ui,sans-serif;
  font-variant-numeric:proportional-nums;line-height:1.1;
}
.stat.profit-pos .value{color:var(--green)}
.stat.profit-neg .value{color:var(--red)}

.stat-foot{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:9px;position:relative;z-index:1}
.stat-foot .sub{font-size:12px;color:var(--faint);font-weight:500}

/* sparkline bleeds to the card edges, under the text */
.stat .spark{position:absolute;left:0;right:0;bottom:0;width:100%;height:46px;display:block;pointer-events:none;opacity:.7}
body[data-theme="dark"] .stat .spark{opacity:.5}

@media(min-width:1600px){.stat{padding:20px 20px 56px}.stat .value{font-size:31px}}
@media(max-width:520px){.stat{padding:15px 15px 44px}.stat .value{font-size:25px}.stat .spark{height:40px}}
@media(prefers-reduced-motion:reduce){.stat:hover{transform:none}}

/* Spacing overrides for older .stat rules that still cascade into these tiles. */
.stat .label{display:block}
.stat .value{margin-top:0}
.stat-foot .sub{margin-top:0}

/* --- employee profile tabs and roster detail (v3.2) --- */
.emp-tabs{display:flex;gap:6px;margin-bottom:16px;border-bottom:1px solid var(--border)}
.emp-tab{padding:10px 16px;font-weight:700;font-size:13.5px;color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .18s ease,border-color .18s ease}
.emp-tab:hover{color:var(--ink)}
.emp-tab.active{color:var(--primary-d);border-bottom-color:var(--primary)}
body[data-theme="dark"] .emp-tab.active{color:#2fd1c6}

.emp-role{font-size:12px;color:var(--muted);margin-top:3px}
.emp-role .is-unset{color:var(--faint);font-style:italic}

.emp-state{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:700;padding:2px 8px;border-radius:20px;vertical-align:middle;margin-left:6px;letter-spacing:.02em}
.emp-state::before{content:'';width:5px;height:5px;border-radius:50%;background:currentColor}
.emp-state.is-active{background:var(--green-bg);color:var(--green)}
.emp-state.is-on_leave{background:var(--amber-bg);color:var(--amber)}
.emp-state.is-left{background:var(--surface-2);color:var(--faint)}

.emp-card:has(.emp-state.is-left){opacity:.66}
.emp-card:has(.emp-state.is-left):hover{opacity:1}

textarea.input{resize:vertical;min-height:60px;line-height:1.5;padding:10px 13px;width:100%}

/* ============================================================
   v3.3  Navigation, date range, alert strip, user menu
   ============================================================ */

/* --- sidebar groups --- */
.nav-label{margin-top:14px}
.nav-label:first-child{margin-top:0}

.nav-item{position:relative}

/* --- one date control --- */
.range-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:18px}
.range-bar .spacer{flex:1;min-width:0}
.range-month{min-width:172px;animation:rangeIn .22s cubic-bezier(.2,.9,.3,1)}
@keyframes rangeIn{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}

/* --- what needs attention today --- */
.alert-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:10px;margin-bottom:20px}
.al-item{display:flex;align-items:center;gap:11px;width:100%;padding:13px 15px;border-radius:var(--radius);border:1px solid var(--border);background:var(--surface);text-align:left;cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease,transform .18s ease}
.al-item:hover{transform:translateY(-1px);box-shadow:var(--shadow-md)}
.al-ic{width:32px;height:32px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.al-ic svg{width:16px;height:16px;stroke-width:2.2}
.al-item.is-danger .al-ic{background:var(--red-bg);color:var(--red)}
.al-item.is-warn   .al-ic{background:var(--amber-bg);color:var(--amber)}
.al-item.is-info   .al-ic{background:var(--primary-soft);color:var(--primary-d)}
body[data-theme="dark"] .al-item.is-info .al-ic{color:#2fd1c6}
.al-item.is-danger{border-color:color-mix(in srgb,var(--red) 30%,var(--border))}
.al-item.is-danger:hover{border-color:var(--red)}
.al-item.is-warn:hover{border-color:var(--amber)}
.al-item.is-info:hover{border-color:var(--hover)}
.al-txt{flex:1;min-width:0;font-size:13px;font-weight:600;color:var(--ink);line-height:1.35}
.al-amt{font-weight:700;font-family:'Inter',system-ui,sans-serif;font-size:14px;white-space:nowrap;color:var(--ink)}
.al-go{color:var(--faint);display:flex;flex-shrink:0;transition:transform .18s ease}
.al-go svg{width:16px;height:16px}
.al-item:hover .al-go{transform:translateX(3px)}

/* --- account menu --- */
.user-menu{position:relative}
.user-drop{position:absolute;top:calc(100% + 10px);right:0;z-index:120;width:268px;padding:6px;border-radius:14px;background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;transform:translateY(-6px) scale(.98);transform-origin:top right;transition:opacity .18s ease,transform .2s cubic-bezier(.2,.9,.3,1),visibility .18s}
.user-drop.open{opacity:1;visibility:visible;transform:none}
.ud-head{padding:10px 12px 12px}
.ud-name{font-weight:700;font-size:14px;letter-spacing:-.2px}
.ud-role{font-size:12px;color:var(--faint);font-weight:600;text-transform:uppercase;letter-spacing:.06em;margin-top:2px}
.ud-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:7px 12px}
.ud-lbl{font-size:12.5px;color:var(--muted);font-weight:600}
.ud-sep{height:1px;background:var(--border-2);margin:7px 4px}
.ud-item{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border-radius:9px;font-size:13.5px;font-weight:600;color:var(--ink);text-align:left;transition:background .15s ease,color .15s ease}
.ud-item svg{width:16px;height:16px;color:var(--muted);flex-shrink:0}
.ud-item:hover{background:var(--surface-2)}
.ud-item.is-danger{color:var(--red)}
.ud-item.is-danger svg{color:var(--red)}
.ud-item.is-danger:hover{background:var(--red-bg)}

/* --- all costs: where the month went --- */
.cost-split{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:14px;margin-bottom:20px}
.cs-item{min-width:0}
.cs-name{font-size:12px;color:var(--muted);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cs-amt{font-size:16px;font-weight:700;font-family:'Inter',system-ui,sans-serif;margin-top:3px}
.cs-bar{height:5px;border-radius:5px;background:var(--surface-2);overflow:hidden;margin-top:7px}
.cs-bar .fill{display:block;height:100%;width:0;border-radius:5px;background:var(--grad)}

/* D5. Columns of numbers line up; the big KPI values keep proportional
   figures, where tabular digits read loose. */
.mini-amt,.cs-amt,.al-amt{font-variant-numeric:tabular-nums}

@media(max-width:640px){
  .alert-strip{grid-template-columns:1fr}
  .user-drop{width:min(268px,calc(100vw - 28px))}
}
@media(prefers-reduced-motion:reduce){
  .al-item:hover{transform:none}
  .range-month{animation:none}
}

/* ============================================================
   v3.4  Phase 10: search, add menu, no-login employees, cost UX
   ============================================================ */

/* --- search box, the app's first. The other tables should copy this. --- */
.field.isearch{position:relative;flex:1;min-width:180px;max-width:320px}
.field.isearch .input{width:100%;padding-left:36px}
.search-ic{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--faint);display:flex;pointer-events:none}
.search-ic svg{width:15px;height:15px}
.field.isearch .input:focus + .search-ic,.field.isearch .input:focus ~ .search-ic{color:var(--primary)}
.field.isearch .input::-webkit-search-cancel-button{cursor:pointer}

/* --- add menu on All Costs, so the primary action exists on the landing view --- */
.add-menu{position:relative}
.add-drop{position:absolute;top:calc(100% + 8px);right:0;z-index:90;min-width:190px;padding:6px;border-radius:12px;background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;transform:translateY(-6px);transition:opacity .18s ease,transform .2s cubic-bezier(.2,.9,.3,1),visibility .18s}
.add-drop.open{opacity:1;visibility:visible;transform:none}
.ad-item{display:flex;align-items:center;gap:10px;width:100%;padding:9px 11px;border-radius:9px;font-size:13px;font-weight:600;color:var(--ink);text-align:left;transition:background .15s ease}
.ad-item svg{width:16px;height:16px;color:var(--muted);flex-shrink:0}
.ad-item:hover{background:var(--surface-2)}

/* --- the cost breakdown is a control now, not just a picture --- */
.cs-item.is-clickable{cursor:pointer;padding:8px;margin:-8px;border-radius:10px;transition:background .16s ease}
.cs-item.is-clickable:hover{background:var(--surface-2)}
.cs-item.is-clickable:hover .cs-name{color:var(--ink)}

/* --- "you cannot see this" should not look like "this month was quiet" --- */
.empty.is-locked .ic{background:var(--surface-2);color:var(--faint)}
.empty.is-locked h3{color:var(--muted);font-weight:600}

/* --- tab switching used to reflow the whole table because Salary carries two
   extra columns. Pinning the trailing columns keeps amounts and actions in
   place, so only the middle of the table changes. --- */
.table-wrap table{table-layout:auto}
.table-wrap th.num,.table-wrap td.num{width:1%;white-space:nowrap}
.table-wrap thead th:last-child,.table-wrap tbody td:last-child{width:1%;white-space:nowrap}
.table-wrap thead th:first-child{min-width:min(38vw,220px)}

/* --- employees with no sign-in --- */
.emp-nologin{display:inline-flex;align-items:center;font-size:12px;font-weight:700;padding:2px 8px;border-radius:20px;margin-left:6px;vertical-align:middle;background:var(--surface-2);color:var(--faint);letter-spacing:.02em}
.access-state{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-top:16px;padding:13px 15px;border-radius:12px;background:var(--surface-2);border:1px solid var(--border-2)}
.as-title{font-weight:700;font-size:13.5px}
.as-sub{font-size:12px;color:var(--muted);margin-top:3px;line-height:1.5}
.access-toggle{margin-top:4px}
.access-hint{display:block;font-size:12px;color:var(--faint);font-weight:500;margin-top:2px;line-height:1.45}

@media(max-width:640px){
  .field.isearch{max-width:100%;flex:1 1 100%}
  .access-state{flex-direction:column;align-items:stretch}
  .access-state .btn{width:100%}
}

/* --- B7 receivables aging: how long money has been stuck --- */
.aging-card{margin-bottom:18px}
.aging-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:14px}
.ag-item{min-width:0}
.ag-label{font-size:12px;color:var(--muted);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ag-amt{font-size:16px;font-weight:700;font-family:'Inter',system-ui,sans-serif;margin-top:3px;font-variant-numeric:tabular-nums}
.ag-bar{height:5px;border-radius:5px;background:var(--surface-2);overflow:hidden;margin-top:7px}
.ag-bar .fill{display:block;height:100%;width:0;border-radius:5px}
/* Three steps, not five: current, getting late, overdue. */
.ag-item.is-ok    .ag-bar .fill{background:var(--green)}
.ag-item.is-warn  .ag-bar .fill,
.ag-item.is-warn2 .ag-bar .fill{background:var(--amber)}
.ag-item.is-bad   .ag-bar .fill,
.ag-item.is-worst .ag-bar .fill{background:var(--red)}
.ag-item.is-worst .ag-amt{color:var(--red)}

/* --- A3: the erase button stays locked until a backup exists --- */
.danger-guard{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;color:var(--amber);background:var(--amber-bg);padding:9px 12px;border-radius:10px;margin-bottom:12px;line-height:1.45}
.danger-guard svg{width:15px;height:15px;flex-shrink:0}

/* --- BUG-1: choosing which sale a payment belongs to --- */
.mp-list{display:flex;flex-direction:column;gap:8px;max-height:320px;overflow-y:auto;margin-bottom:4px}
.mp-opt{display:flex;align-items:center;gap:12px;padding:12px 14px;border:1.5px solid var(--border);border-radius:12px;cursor:pointer;transition:border-color .18s ease,background .18s ease}
.mp-opt:hover{border-color:var(--hover)}
.mp-opt input{width:17px;height:17px;accent-color:var(--primary);flex-shrink:0;cursor:pointer}
.mp-opt:has(input:checked){border-color:var(--primary);background:var(--primary-soft)}
.mp-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.mp-title{font-weight:700;font-size:13.5px}
.mp-meta{font-size:12px;color:var(--muted)}
.mp-amt{font-weight:700;font-family:'Inter',system-ui,sans-serif;font-size:14px;white-space:nowrap;font-variant-numeric:tabular-nums}
.mp-opt.is-new{border-style:dashed}
.mp-opt.is-new:has(input:checked){border-style:solid}

/* --- This Month / All Time toggle, shared by Sales and Costs --- */
.month-toggle{flex-shrink:0}

/* ===== SIDEBAR: premium redesign + collapse/expand rail =====
   Modelled on the collapse pattern in VS Code / Notion / Linear: the toggle
   lives INSIDE the sidebar's own top row (never floating over the border,
   which is what caused it to overlap the topbar), and a second small button
   appears in the topbar itself, only while collapsed, to bring it back,
   the same "it reappears where you'd look for it" pattern those apps use. */
:root{ --sidebar-w-collapsed:76px; }

.sidebar{
  transition:width .26s cubic-bezier(.4,0,.2,1);
  background:linear-gradient(180deg,var(--surface) 0%,var(--surface-2) 100%);
  box-shadow:8px 0 28px -20px rgba(16,24,40,.14);
}
body[data-theme="dark"] .sidebar{
  background:linear-gradient(180deg,#12162a 0%,#0d1022 100%);
  box-shadow:8px 0 32px -16px rgba(0,0,0,.6);
}

.side-brand{
  cursor:pointer;border-radius:12px;transition:background .18s,transform .12s;
  -webkit-tap-highlight-color:transparent;user-select:none;outline:none;
}
.side-brand:hover{background:var(--surface-2)}
.side-brand:focus-visible{box-shadow:0 0 0 2px var(--primary-soft)}
.side-brand:active{transform:scale(.98)}

/* In-sidebar collapse button: a normal flex child at the end of the brand
   row, not an absolutely positioned element, so it can never overlap
   anything outside the sidebar. */
.sidebar-toggle{
  margin-left:auto;flex-shrink:0;width:28px;height:28px;border-radius:8px;
  background:transparent;border:1px solid transparent;color:var(--faint);
  display:flex;align-items:center;justify-content:center;
  transition:color .15s,background .15s,border-color .15s;
}
.sidebar-toggle svg{width:16px;height:16px}
.sidebar-toggle:hover{color:var(--primary);background:var(--surface);border-color:var(--border)}

/* Re-expand button: lives in the topbar's own flow, shown only once the
   sidebar is collapsed, styled like the app's other icon buttons. */
.page-title-group{display:flex;align-items:center;gap:12px;min-width:0}
.sidebar-expand-btn{
  display:none;width:36px;height:36px;border-radius:10px;flex-shrink:0;
  background:var(--surface-2);border:1px solid var(--border);color:var(--muted);
  align-items:center;justify-content:center;transition:.15s;
}
.sidebar-expand-btn svg{width:17px;height:17px}
.sidebar-expand-btn:hover{color:var(--primary);border-color:var(--hover)}
body.sidebar-collapsed .sidebar-expand-btn{display:flex}

/* Phone nav: hidden entirely above the mobile breakpoint (below, in
   @media(max-width:860px), the real drawer/backdrop/hamburger treatment
   takes over). Declared here, disabled here, so desktop never sees them. */
.mobile-menu-btn{
  display:none;width:38px;height:38px;border-radius:10px;flex-shrink:0;
  background:var(--surface-2);border:1px solid var(--border);color:var(--muted);
  align-items:center;justify-content:center;transition:.15s;
}
.mobile-menu-btn svg{width:19px;height:19px}
.mobile-menu-btn:active{transform:scale(.93)}
.mobile-drawer-backdrop{display:none}
.mobile-drawer-close{display:none}

/* Collapsed rail: icons only, centred, with a hover tooltip standing in for
   the hidden label. */
body.sidebar-collapsed .sidebar{width:var(--sidebar-w-collapsed);padding-left:10px;padding-right:10px}
body.sidebar-collapsed .side-brand{justify-content:center;padding:8px 0 16px}
body.sidebar-collapsed .side-brand .bn,
body.sidebar-collapsed .side-brand .bt,
body.sidebar-collapsed .side-brand .sidebar-toggle,
body.sidebar-collapsed .nav-label,
body.sidebar-collapsed .nav-item span,
body.sidebar-collapsed .nav-item .chev,
body.sidebar-collapsed .nav-subwrap,
body.sidebar-collapsed .side-foot{display:none}
body.sidebar-collapsed .nav-item{justify-content:center;padding:12px 0}

body.sidebar-collapsed .nav-item{position:relative}
body.sidebar-collapsed .nav-item:hover::after{
  content:attr(data-tip);position:absolute;left:calc(100% + 14px);top:50%;
  transform:translateY(-50%);background:var(--ink);color:var(--surface);
  padding:6px 11px;border-radius:8px;font-size:12px;font-weight:600;white-space:nowrap;
  box-shadow:var(--shadow-lg);pointer-events:none;z-index:120;animation:tipFade .14s ease;
}
body[data-theme="dark"].sidebar-collapsed .nav-item:hover::after{background:#e9ecf5;color:#0b0e1c}
/* The rail is position:sticky, which makes it its own stacking layer, so the
   label's z-index only counts inside the rail and the page content painted
   over it (the label showed as a clipped "Quot"). Lifting the collapsed rail
   above the content (below the top bar's menus, dialogs and toasts) fixes it.
   Desktop only: the phone drawer has its own layer (210). */
@media(min-width:861px){ body.sidebar-collapsed .sidebar{z-index:60} }
@keyframes tipFade{from{opacity:0;transform:translateY(-50%) translateX(-4px)}to{opacity:1;transform:translateY(-50%) translateX(0)}}

@media(max-width:860px){
  .sidebar-expand-btn{display:none !important}
  /* Undoes the desktop collapsed-rail hiding above for the phone drawer:
     same selectors, same specificity as those rules, placed after them here
     so source order decides the winner in the drawer's favour. Someone who
     collapsed the sidebar on their laptop must still see a full, labelled
     drawer on their phone, not a squeezed 76px icon rail with nothing to
     expand it back from (the only control for that is hidden on phones). */
  body.sidebar-collapsed .sidebar{width:min(300px,82vw) !important;padding-left:14px;padding-right:14px}
  body.sidebar-collapsed .side-brand{justify-content:flex-start;padding:6px 8px 18px}
  body.sidebar-collapsed .side-brand .bn,
  body.sidebar-collapsed .side-brand .bt,
  body.sidebar-collapsed .nav-label,
  body.sidebar-collapsed .nav-item span,
  body.sidebar-collapsed .nav-item .chev,
  body.sidebar-collapsed .side-foot{display:block}
  body.sidebar-collapsed .nav-subwrap{display:grid}
  body.sidebar-collapsed .nav-item{justify-content:flex-start;padding:10px 14px}

  /* Bug fix: the "display:none" base rules for these three live further up
     the file (declared near .sidebar-expand-btn) but AFTER the block that
     first tried to turn them on (the one at the top of this file, the very
     first @media(max-width:860px)). Same selector, same specificity, later
     wins, so that first attempt never actually took effect, the hamburger
     button, its drawer close button, and the backdrop stayed display:none
     on every screen size including phones. This is the same class of
     ordering mistake already caught once for .sidebar-collapsed above;
     missed here because it's a different element. Fixed the only way that
     is guaranteed to win regardless of where either declaration sits:
     turning them on again here, after the rule that turns them off. */
  .mobile-menu-btn{display:flex !important}
  .mobile-drawer-close{display:flex !important}
  .mobile-drawer-backdrop{display:block !important}
}
@media(max-width:640px){
  /* Payroll and Audit Trail rows: fixed min-widths on every column made
     sense at desktop card widths, but on a phone they add up to more than
     the screen, forcing the row to wrap awkwardly mid-line. Below this
     width both switch to two stacked lines instead: identity on top,
     figures/status on their own row underneath. */
  .payroll-row{align-items:flex-start}
  .payroll-who{min-width:0;flex-basis:100%;order:1}
  .payroll-check{order:0}
  .payroll-amt,.payroll-method,.payroll-status{min-width:0;text-align:left;order:2}
  .payroll-status{margin-left:auto}
  .audit-row{flex-wrap:wrap}
  .audit-time{flex-basis:100%;text-align:right}
}

/* ===== DARK MODE =====
   Depth comes from a faint top edge on cards, not from a coloured wash over
   the page or glows around controls. */
body[data-theme="dark"]{
  --primary-soft:#0f2e33;
}
body[data-theme="dark"] .glass{
  background:linear-gradient(180deg,color-mix(in srgb,var(--surface) 100%,#fff 3%),var(--surface));
  box-shadow:var(--shadow),inset 0 1px 0 rgba(255,255,255,.04);
}
/* The dark theme used to swap the active row for a faint 24% tint here. That
   rule outranked the base one and sat later in the file, so it would have won
   and left white label text sitting on an almost transparent background. The
   filled pill is legible on both themes, so both themes now use it. */

/* ===== Waiting on the server =====
   A 2px line across the top while a page waits for data it does not have
   yet. Shown only after 250ms (see syncStart in app.js), so quick answers
   never flash it, and it replaces the full-page skeleton on every click. */
body.is-syncing::after{
  content:'';position:fixed;top:0;left:0;right:0;height:2px;z-index:400;pointer-events:none;
  background:linear-gradient(90deg,transparent 0,var(--primary) 50%,transparent 100%);
  background-size:40% 100%;background-repeat:no-repeat;
  animation:syncSlide 1.1s linear infinite;
}
@keyframes syncSlide{from{background-position:-40% 0}to{background-position:140% 0}}

/* ============================================================
   v4.0  Premium pass: logo palette, depth, phones, Motion hooks
   ============================================================ */
::selection{background:color-mix(in srgb,var(--brand-teal) 24%,transparent)}
h1,h2,h3,.page-title,.emp-title{letter-spacing:-.02em}
.glass{border-color:var(--border)}
body[data-theme="dark"] .glass{border-color:var(--border)}

/* header: flat at the top, a hairline once content scrolls beneath it */
.topbar{transition:box-shadow .2s ease}
.topbar.is-scrolled{box-shadow:0 1px 0 var(--border),0 10px 24px -18px rgba(18,22,41,.35)}
body[data-theme="dark"] .topbar.is-scrolled{box-shadow:0 1px 0 var(--border),0 10px 24px -14px rgba(0,0,0,.7)}
.theme-btn svg{width:18px;height:18px}

/* toolbar buttons keep their label on one line */
.toolbar .btn{white-space:nowrap}

@media(max-width:860px){
  /* long rows of choices scroll sideways instead of spilling off screen */
  #dashRangeSeg{max-width:100%;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  #dashRangeSeg::-webkit-scrollbar{display:none}
  #dashRangeSeg button{flex-shrink:0}
  .cost-subtabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px}
  .cost-subtabs::-webkit-scrollbar{display:none}
}
@media(max-width:640px){
  .cost-subtab{flex:0 0 auto;white-space:nowrap}
  .topbar-actions{gap:6px}
  .theme-btn{width:36px;height:36px}

  /* tables become cards: one card per row, each value with its label */
  .table-wrap{border:none;border-radius:0;overflow:visible;background:none}
  .table-wrap table,.table-wrap tbody,.table-wrap tr,.table-wrap td{display:block;width:100%}
  .table-wrap thead{display:none}
  .table-wrap tbody tr{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:4px 14px;margin-bottom:10px;box-shadow:var(--shadow)}
  .table-wrap tbody td{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:9px 0;border-bottom:1px solid var(--border-2);text-align:right;white-space:normal;width:auto!important;min-width:0;overflow-wrap:anywhere}
  .table-wrap tbody td:last-child{border-bottom:none}
  .table-wrap tbody td::before{content:attr(data-label);flex-shrink:0;max-width:45%;text-align:left;font-size:12px;font-weight:600;color:var(--muted)}
  .table-wrap tbody td[data-label=""]::before{content:none}
  .table-wrap tbody td[data-label=""]{justify-content:flex-end}
  .table-wrap tbody tr:hover{background:var(--surface)!important}
  .table-wrap .row-actions{justify-content:flex-end}
}

/* Motion present: it animates dialogs, toasts and the tab pill itself, so
   the CSS versions of those animations step aside. */
html.has-motion .modal,html.has-motion .overlay,html.has-motion .toast{animation:none}
.tab-ind{display:none}
@media(max-width:860px){
  html.has-motion .tab-ind{display:block;position:absolute;left:0;top:0;width:52px;height:28px;border-radius:999px;background:var(--primary-soft);pointer-events:none;will-change:transform}
  html.has-motion .tab.active svg{background:none}
  .tab svg{position:relative;z-index:1}
}

/* theme switch crossfade (browsers with view transitions) */
::view-transition-old(root),::view-transition-new(root){animation-duration:.28s;animation-timing-function:ease-out}


/* ===== Notifications: unread badges and the bell (package 27) =====
   Counts sit at the end of a sidebar row, on the icon's corner when the
   sidebar is collapsed or on the phone tab bar. Red is reserved for this
   and for errors, so a count is noticed without the rest of the page shouting. */
.nav-badge{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--red);color:#fff;font-size:10.5px;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;box-shadow:0 0 0 2px var(--surface);animation:nb-in .25s cubic-bezier(.2,.9,.3,1)}
@keyframes nb-in{from{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}
@media (prefers-reduced-motion: reduce){.nav-badge{animation:none}}
.nav-item .nav-badge{margin-left:auto}
.nav-item .nav-badge+.chev{margin-left:6px}
.nav-subitem .nav-badge{margin-left:auto;min-width:16px;height:16px;font-size:10px}
body.sidebar-collapsed .nav-item{position:relative}
body.sidebar-collapsed .nav-item .nav-badge{position:absolute;top:4px;right:6px;margin:0;min-width:16px;height:16px;font-size:10px;padding:0 4px}
.tabbar .tab{position:relative}
.tabbar .tab .nav-badge{position:absolute;top:2px;left:calc(50% + 6px);min-width:16px;height:16px;font-size:10px;padding:0 4px}
.bell-wrap{position:relative}
.bell-btn{position:relative}
.bell-btn[hidden]{display:none}
.bell-btn .nav-badge{position:absolute;top:-4px;right:-4px;min-width:17px;height:17px;font-size:10px;padding:0 4px}
.bell-drop{position:absolute;right:0;top:calc(100% + 10px);z-index:1100;display:none;border-radius:var(--radius);box-shadow:var(--shadow-lg)}
.bell-drop.open{display:block;animation:bell-in .2s cubic-bezier(.2,.9,.3,1)}
@keyframes bell-in{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){.bell-drop.open{animation:none}}
@media (max-width:600px){.bell-wrap{position:static}.bell-drop{left:12px;right:12px;top:64px;position:fixed}}

/* Small phones: the header keeps title, bell, currency and the user; light or
   dark is still one tap away in the user menu. */
@media (max-width:480px){#themeBtn{display:none}}
