:root{--pshadow:0 8px 24px rgba(16,27,45,.09);--pshadow-lg:0 18px 46px rgba(16,27,45,.14)}
*{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
.card{box-shadow:var(--pshadow)!important;border-radius:16px!important;transition:box-shadow .2s ease,transform .2s ease}
.card.kpi{border-radius:16px!important}
.card.kpi:hover{box-shadow:var(--pshadow-lg)!important;transform:translateY(-3px)}
.kpi .ico{border-radius:13px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.35),0 4px 10px rgba(16,27,45,.10)}
.kpi .n{letter-spacing:-.5px}
.btn{border-radius:10px;transition:transform .12s ease,box-shadow .2s ease,filter .2s ease}
.btn:hover{transform:translateY(-1px)}
.btn.orange{box-shadow:0 8px 18px rgba(242,103,34,.30);background-image:linear-gradient(180deg,#f7813a,#f26722)}
.btn.orange:hover{filter:brightness(1.04)}
.nitem{border-radius:11px;transition:background .15s ease,color .15s ease}
.nitem.on{position:relative;font-weight:700}
.nitem.on::before{content:'';position:absolute;left:-2px;top:9px;bottom:9px;width:3px;border-radius:0 3px 3px 0;background:linear-gradient(#f7813a,#f26722)}
.pill{border-radius:999px;font-weight:700}
.tab{border-radius:10px;transition:background .15s ease}
.in{border-radius:10px;transition:border-color .15s ease,box-shadow .15s ease}
.in:focus{border-color:#f26722;box-shadow:0 0 0 3px rgba(242,103,34,.14);outline:none}
table{border-radius:12px;overflow:hidden}
thead th{background:#fbfbfc;letter-spacing:.2px}
tbody tr{transition:background .12s ease}
tbody tr:hover{background:#fbf7f3}
.phead h1{letter-spacing:-.6px}
.sec-h b{letter-spacing:-.2px}
.gc-card{background:linear-gradient(180deg,#ffffff, #fcfbfa)}
@media(max-width:768px){.card{border-radius:14px!important}.btn{min-height:42px}.nitem{min-height:44px}.in{min-height:42px}.kpi .n{font-size:26px}}

:root{
  --navy:#0f1b2d; --navy2:#16273c; --navy3:#1d3350; --side:#0f1b2d; --side-hi:#18293f;
  --brand:#f26722; --brand-d:#d9541a;
  --blue:#2563eb; --blue-d:#1d4ed8; --green:#16a34a; --sky:#0ea5e9; --amber:#f59e0b; --red:#ef4444; --violet:#7c3aed;
  --bg:#eef1f5; --card:#ffffff; --ink:#1b2735; --ink2:#33475b; --muted:#69788c; --line:#e5e9ef;
  --ok-bg:#e6f5ec; --ok:#127a3e; --warn-bg:#fdf1df; --warn:#a6641b; --err-bg:#fdeceb; --err:#c23127; --info-bg:#e8f0fe; --info:#1e56c9;
  --r:14px; --sh:0 1px 2px rgba(16,28,45,.06),0 2px 8px rgba(16,28,45,.05);
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
/* 19 Aug — Jay: "make the entire UI adjustable as per the screen size, it should accommodate the
   look fluid." The layout already had 3 hard breakpoints (1100/860/480px) that jump between fixed
   states; between those jumps nothing scaled, so a laptop at 1250px or a tablet at 950px got
   whatever the nearest breakpoint happened to look like, not something tuned to its own width.
   Added continuous, no-breakpoint-needed scaling in three ways: (1) clamp()-based fluid type/
   spacing on the page header, KPI numbers, #main padding, sidebar width and the topbar search box
   — these now shrink/grow smoothly with viewport width instead of snapping; (2) KPI/quick-action
   grids switched from a fixed column count to repeat(auto-fit,minmax(...)) so they reflow to
   however many columns actually fit at any width, no media query needed; (3) .formgrid switched
   the same way so its 3/2/1-column jump becomes a smooth reflow. Existing breakpoints (1100/860/
   480) are kept for the pieces that genuinely need a hard state change (sidebar off-canvas vs
   docked, .split's sticky side panel) — fluid scaling and breakpoints aren't mutually exclusive,
   this just removes the "nothing happens between breakpoints" gaps. */
body{overflow-x:hidden}
img,svg{max-width:100%;height:auto}
.hidden{display:none!important}
/* login */
#login{position:fixed;inset:0;z-index:200;display:none;align-items:center;justify-content:center;background:linear-gradient(140deg,#0f1b2d,#1a1206 130%)}
.lcard{background:#fff;width:380px;max-width:92vw;border-radius:18px;box-shadow:0 30px 80px rgba(0,0,0,.45);padding:30px 30px 24px}
.llogo{display:flex;align-items:center;gap:12px;margin-bottom:4px}
.lcube{width:44px;height:44px;border-radius:12px;background:var(--brand);display:flex;align-items:center;justify-content:center;color:#fff;font-size:22px}
.llogo b{font-size:19px;letter-spacing:.5px;display:block;line-height:1}
.llogo span{font-size:9.5px;letter-spacing:2.5px;color:var(--muted)}
.ltenant{color:var(--muted);font-size:12px;margin:14px 0 18px;padding-bottom:14px;border-bottom:1px solid var(--line)}
#login label{display:block;font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.4px;margin:12px 0 5px}
.lin{width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:10px;outline:none}
.lin:focus{border-color:var(--brand)}
.lbtn{width:100%;margin-top:18px;padding:12px;border-radius:10px;background:var(--blue);color:#fff;font-weight:700;font-size:14.5px}
.lbtn:hover{background:var(--blue-d)}
.llink{background:none;border:none;color:var(--blue);font-weight:600;font-size:12.5px;cursor:pointer}
.lmsg{margin-top:12px;font-size:12.5px;padding:9px 11px;border-radius:8px;display:none}
.lmsg.err{display:block;background:var(--err-bg);color:var(--err)}
.lmsg.ok{display:block;background:var(--ok-bg);color:var(--ok)}
.lsec{margin-top:16px;text-align:center;color:var(--muted);font-size:11px}
.lspin{width:15px;height:15px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;display:inline-block;animation:lsp .7s linear infinite;vertical-align:-2px}@keyframes lsp{to{transform:rotate(360deg)}}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Arial,sans-serif;background:var(--bg);color:var(--ink);font-size:13.5px;line-height:1.5;-webkit-font-smoothing:antialiased}
button{font-family:inherit;cursor:pointer;border:none;background:none}
input,select{font-family:inherit;font-size:13.5px}
.mono{font-variant-numeric:tabular-nums}
.hidden{display:none!important}

#app{display:grid;grid-template-columns:clamp(200px,18vw,236px) 1fr;grid-template-rows:64px 1fr;height:100vh;transition:grid-template-columns .18s ease}

/* ---------- Sidebar ---------- */
#side{grid-row:1/3;background:var(--side);display:flex;flex-direction:column;color:#c4d0de;overflow:hidden}
.logo{display:flex;align-items:center;gap:11px;padding:16px 18px 14px}
.logo .cube{width:38px;height:38px;border-radius:10px;background:var(--brand);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
.logo .cube svg{width:22px;height:22px}
.logo .t b{font-size:16px;letter-spacing:.5px;color:#fff;display:block;line-height:1.1}
.logo .t span{font-size:9.5px;letter-spacing:2px;color:#6b7d92}
.nav{flex:1;overflow:auto;padding:8px 10px}
.nav::-webkit-scrollbar{width:0}
.nitem{display:flex;align-items:center;gap:11px;width:100%;text-align:left;color:#aab8c8;padding:9px 11px;border-radius:9px;font-weight:600;font-size:13px;margin-bottom:1px;border-left:3px solid transparent;position:relative}
.nitem:hover{background:var(--side-hi);color:#fff}
.nitem.on{background:var(--side-hi);color:#fff;border-left-color:var(--brand)}
.nitem .ic{width:18px;text-align:center;font-size:15px;opacity:.9;flex:0 0 auto}
.nitem .badge{margin-left:auto;background:var(--brand);color:#fff;font-size:10px;font-weight:800;padding:1px 7px;border-radius:20px}
.tenant{margin:10px;padding:12px 13px;border-radius:11px;background:#0b1524;border:1px solid #1c2c40}
.tenant .k{font-size:9px;letter-spacing:1.5px;color:#5f7086;font-weight:700}
.tenant b{color:#fff;font-size:13px;display:block;margin-top:3px}
.tenant .sub{color:#6b7d92;font-size:11px;margin-top:2px}
.tenant .live{display:inline-flex;align-items:center;gap:5px;font-size:10px;font-weight:800;color:#3ddc84;background:#0d2a1c;padding:2px 8px;border-radius:20px;margin-top:8px}
.tenant .live::before{content:"";width:6px;height:6px;border-radius:50%;background:#3ddc84}
.tenant .ver{color:#4a5a6e;font-size:10px;margin-top:8px}

/* ---------- Sidebar collapse (icons-only) — Jay: "I want side panel to be collapsible and when
   collapsed put there icons only visible." A small ‹ toggle sits just under the logo; clicking it
   adds/removes #app.navcollapsed. Collapsed width is just enough for the icon column; every text
   label (logo wordmark, nav item/group labels, chevrons, sub-item lists, the tenant footer card)
   is hidden via display:none rather than clipped, so nothing truncates awkwardly. Sub-menus
   collapse to nothing while narrow (their parent group icon still shows and, per the click
   handler in renderNav(), clicking it while collapsed re-expands the sidebar and opens that
   group) — the underlying open/closed state per group is untouched so it's exactly as you left
   it once expanded again. Every icon-only button keeps a title="" tooltip with its full label. */
.navtoggle{align-self:flex-end;width:26px;height:26px;margin:0 12px 8px;border:1px solid #1c2c40;border-radius:8px;background:#0b1524;color:#8fa2b8;font-size:13px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;flex:0 0 auto;transition:transform .18s ease}
.navtoggle:hover{background:#132238;color:#fff}
/* min-width guard: the collapse is a desktop-only affordance — on narrow screens the sidebar is
   already off-canvas via #app.navopen (see the max-width:860px block below), and this rule's
   higher specificity (#app.navcollapsed vs plain #app) would otherwise fight that layout if the
   class were ever set at a narrow width. */
@media(min-width:861px){
  #app.navcollapsed{grid-template-columns:64px 1fr}
  #app.navcollapsed #side{overflow:visible}
  #app.navcollapsed .logo{justify-content:center;padding:16px 0 6px}
  #app.navcollapsed .logo .t{display:none}
  #app.navcollapsed .navtoggle{align-self:center;transform:rotate(180deg)}
  #app.navcollapsed .tenant{display:none}
  #app.navcollapsed .nsub{display:none}
  #app.navcollapsed .nav{padding:8px 6px}
  #app.navcollapsed .nitem,#app.navcollapsed .ngroup{justify-content:center;padding:9px 0;gap:0}
  #app.navcollapsed .nitem .lbl,#app.navcollapsed .ngroup .gt,#app.navcollapsed .ngroup .chev,#app.navcollapsed .nitem .badge{display:none}
}

/* ---------- Topbar ---------- */
#top{grid-column:2;background:var(--card);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:16px;padding:0 22px}
#top .title b{font-size:17px;letter-spacing:-.3px}
#top .title .sub{color:var(--muted);font-size:11.5px;margin-top:-1px}
#top .spacer{flex:1}
.search{display:flex;align-items:center;gap:8px;background:#f3f5f8;border:1px solid var(--line);border-radius:10px;padding:8px 12px;width:clamp(160px,20vw,330px);color:var(--muted)}
.search input{border:none;background:none;outline:none;width:100%;color:var(--ink)}
.plant{display:flex;align-items:center;gap:7px;border:1px solid var(--line);border-radius:10px;padding:8px 12px;font-weight:600;background:#fff}
.notif{position:relative;width:38px;height:38px;border-radius:10px;border:1px solid var(--line);display:flex;align-items:center;justify-content:center;font-size:15px}
.notif::after{content:"";position:absolute;top:9px;right:10px;width:7px;height:7px;background:var(--red);border-radius:50%;border:2px solid #fff}
.uchip{display:flex;align-items:center;gap:9px;border:1px solid var(--line);border-radius:12px;padding:5px 10px 5px 6px}
.uchip .av{width:32px;height:32px;border-radius:8px;background:linear-gradient(135deg,#2563eb,#7c3aed);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12px}
.uchip .nm b{font-size:12.5px;display:block;line-height:1.1}
.uchip .nm span{font-size:10.5px;color:var(--muted)}

/* ---------- Main ---------- */
#main{grid-column:2;overflow:auto;padding:clamp(14px,2.5vw,22px) clamp(14px,3vw,26px) clamp(24px,4vw,40px)}
.phead{display:flex;align-items:flex-end;gap:14px;margin-bottom:20px;flex-wrap:wrap}
.phead h1{font-size:clamp(19px,2.2vw,25px);margin:0;letter-spacing:-.6px}
.phead .d{color:var(--muted);font-size:13.5px;margin-top:3px}
.phead .spacer{flex:1}
.btn{display:inline-flex;align-items:center;gap:8px;background:var(--blue);color:#fff;font-weight:700;padding:11px 18px;border-radius:11px;font-size:13.5px;box-shadow:0 2px 6px rgba(37,99,235,.3)}
.btn:hover{background:var(--blue-d)}
.btn.orange{background:var(--brand);box-shadow:0 2px 6px rgba(242,103,34,.3)}
.btn.orange:hover{background:var(--brand-d)}
.btn.ghost{background:#fff;color:var(--ink);border:1px solid var(--line);box-shadow:none}
.btn.sm{padding:8px 13px;font-size:12.5px}

.cards{display:grid;gap:16px}
/* 19 Aug — fluid reflow: auto-fit lets these size themselves to however many columns actually
   fit at the current width, so a KPI row smoothly goes 5→4→3→2→1 columns as the window narrows
   instead of jumping straight from 5 to 2 at the old 1100px breakpoint. minmax() floor keeps
   cards from ever getting too cramped to read. */
.k5{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
.k4{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.k3{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.k2{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh)}
.card.p{padding:18px}
.kpi{padding:17px 18px}
.kpi .top{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.kpi .ico{width:42px;height:42px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:19px;color:#fff}
.kpi .lab{color:var(--ink2);font-weight:600;font-size:13px}
.kpi .n{font-size:clamp(22px,2.6vw,29px);font-weight:800;letter-spacing:-.8px}
.kpi .sub{font-size:11.5px;color:var(--muted);margin-top:3px;font-weight:600}
.kpi .sub.up{color:var(--green)}
.chip-act{font-size:10px;font-weight:800;background:var(--warn-bg);color:var(--warn);padding:2px 9px;border-radius:20px}
.ic-blue{background:var(--blue)}.ic-green{background:var(--green)}.ic-sky{background:var(--sky)}.ic-orange{background:var(--brand)}.ic-dark{background:#334155}.ic-violet{background:var(--violet)}.ic-red{background:var(--red)}.ic-amber{background:var(--amber)}

.sec-h{display:flex;align-items:center;margin-bottom:3px}
.sec-h b{font-size:16px;letter-spacing:-.2px}
.sec-h .s{color:var(--muted);font-size:12px}
.sec-h .r{margin-left:auto}
.grid-2{display:grid;grid-template-columns:1.6fr 1fr;gap:16px;margin-top:16px}
.grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;margin-top:16px}

/* production flow */
.flowcols{display:grid;grid-template-columns:120px repeat(4,1fr);gap:0 8px;color:var(--muted);font-size:11.5px;font-weight:700;padding:14px 4px 8px;border-bottom:1px solid var(--line)}
.flowrow{display:grid;grid-template-columns:120px 1fr;gap:10px;align-items:center;padding:11px 4px;border-bottom:1px solid #f1f3f6}
.flowrow:last-child{border-bottom:none}
.flowrow .job b{font-size:12.5px}.flowrow .job span{font-size:10.5px;color:var(--muted);display:block}
.track{position:relative;height:26px;background:#f1f3f6;border-radius:7px;overflow:hidden}
.bar{position:absolute;top:0;left:0;height:100%;border-radius:7px;display:flex;align-items:center;padding:0 10px;color:#fff;font-size:11px;font-weight:700;white-space:nowrap}
.pct{position:absolute;right:9px;top:50%;transform:translateY(-50%);font-size:11px;font-weight:700;color:var(--ink2)}

/* machine status list */
.mrow{display:flex;align-items:center;gap:10px;padding:11px 2px;border-bottom:1px solid #f1f3f6}
.mrow:last-child{border-bottom:none}
.dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto}
.dot.g{background:var(--green)}.dot.a{background:var(--amber)}.dot.r{background:var(--red)}
.mrow .nm b{font-size:12.5px}.mrow .nm span{font-size:10.5px;color:var(--muted);display:block}
.mrow .st{margin-left:auto}
.pill{display:inline-block;padding:3px 10px;border-radius:20px;font-size:10.5px;font-weight:700}
.pill.run{background:var(--ok-bg);color:var(--ok)}.pill.chg{background:var(--warn-bg);color:var(--warn)}.pill.mnt{background:var(--err-bg);color:var(--err)}
.pill.hi{background:var(--err-bg);color:var(--err)}.pill.md{background:var(--warn-bg);color:var(--warn)}.pill.lo{background:var(--info-bg);color:var(--info)}
.pill.done{background:var(--ok-bg);color:var(--ok)}.pill.prog{background:var(--info-bg);color:var(--info)}.pill.plan{background:#eef1f5;color:#55606e}.pill.hold{background:var(--err-bg);color:var(--err)}.pill.pause{background:var(--warn-bg);color:var(--warn)}
.pill.g{background:var(--ok-bg);color:var(--ok)}.pill.a{background:var(--warn-bg);color:var(--warn)}.pill.r{background:var(--err-bg);color:var(--err)}

/* alerts */
.alert{display:flex;gap:10px;padding:10px 2px;border-bottom:1px solid #f1f3f6}
.alert:last-child{border-bottom:none}
.alert .adot{width:8px;height:8px;border-radius:50%;margin-top:5px;flex:0 0 auto}
.alert b{font-size:12.5px}.alert span{font-size:11px;color:var(--muted);display:block}

/* profitability bars */
.pf{display:flex;align-items:center;gap:12px;padding:9px 0}
.pf .lab{width:66px;font-size:12px;font-weight:700}
.pf .bwrap{flex:1;height:12px;background:#f1f3f6;border-radius:8px;overflow:hidden}
.pf .b{height:100%;border-radius:8px}
.pf .v{width:42px;text-align:right;font-weight:800;font-size:12.5px}

/* numbered exceptions */
.exc{display:flex;align-items:center;gap:13px;padding:10px 0}
.exc .num{width:34px;height:34px;border-radius:9px;background:#f3f5f8;color:var(--ink);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:15px}
.exc b{font-size:12.5px}.exc span{font-size:11px;color:var(--muted);display:block}

/* quick actions */
.qa{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
.qacard{display:flex;align-items:center;gap:11px;border:1px solid var(--line);border-radius:11px;padding:12px}
.qacard:hover{border-color:#cdd5df;background:#fafbfc}
.qacard .qi{width:38px;height:38px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:#fff;font-size:16px}
.qacard b{font-size:12.5px}.qacard span{font-size:10.5px;color:var(--muted);display:block}

/* tables */
table{width:100%;border-collapse:collapse}
th{text-align:left;font-size:10.5px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);font-weight:700;padding:11px 12px;border-bottom:1px solid var(--line)}
td{padding:12px;border-bottom:1px solid #f1f3f6;font-size:12.8px}
tr:last-child td{border-bottom:none}
tbody tr:hover{background:#fafbfc}
.r{text-align:right}
.subtle{color:var(--muted);font-size:11.5px}
.tag{display:inline-block;background:#f3f5f8;color:var(--ink2);border-radius:6px;padding:2px 7px;font-size:11px;font-weight:600}
.progress{height:8px;background:#f1f3f6;border-radius:6px;overflow:hidden;min-width:70px}
.progress > i{display:block;height:100%;background:var(--blue);border-radius:6px}

.split{display:grid;grid-template-columns:1.5fr 1fr;gap:16px}
/* 18 Aug — Jay: "i always need this breakup in the side panel" — #eng-res (the Cost breakdown
   card) already sits in the right-hand column of .split; pinning it with sticky positioning
   keeps it in view while the left-hand Quotation form scrolls, instead of scrolling away with it.
   Falls back to normal flow under the 1100px breakpoint where .split collapses to one column
   (see the media queries below) — sticky would just pin it awkwardly above the form there. */
/* 19 Aug fix — max-height was calc(100vh - 32px), calculated against the full viewport. But #eng-res
   lives inside #main, which is its own scroll container (#app gives #main a 64px header row above it,
   then #main itself adds 22px top-padding), so #main's actual visible area is only (100vh - 64px), not
   100vh. The old value let the sticky panel claim ~94px more height than #main could show, so the
   bottom of the panel (and content after it) rendered past the visible area — "everything seems coming
   under the screen." Recalculated against #main's real box: 64px header + 16px sticky top offset + 24px
   bottom breathing room. */
@media(min-width:1101px){#eng-res{position:sticky;top:16px;align-self:start;max-height:calc(100vh - 104px);overflow-y:auto}}
.mini{padding:16px 18px}
.mini .l{color:var(--muted);font-size:11.5px;font-weight:600}
.mini .n{font-size:22px;font-weight:800;letter-spacing:-.5px;margin-top:3px}
.divide{height:1px;background:var(--line);margin:2px 0}
.leg{display:flex;gap:16px;flex-wrap:wrap;font-size:11.5px;color:var(--muted);margin-top:10px}
.leg i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:5px;vertical-align:-1px}

.crumb{color:var(--muted);font-size:12px;margin-bottom:2px}
.formgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:16px}
.f label{display:block;font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.4px;margin-bottom:6px}
.f .in,.f select{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:9px;background:#fff}
/* Jay (17 Aug): "make the entire sheet simple and beautiful" — same NQ Main colours/layout,
   just tidier spacing and typography (his pick from the options offered). Costlines/costtot
   get a solid hairline + clearer total divider instead of a dashed rule; everything below gets
   a bit more breathing room. */
.costline{display:flex;justify-content:space-between;align-items:baseline;padding:9px 2px;border-bottom:1px solid #f0f2f5;font-size:13px}
.costline span{color:var(--ink2)}
.costline b{font-variant-numeric:tabular-nums;font-weight:600}
.costtot{display:flex;justify-content:space-between;padding:14px 2px 4px;margin-top:2px;border-top:1px solid #e5e9ef;font-weight:800;font-size:15px}

.subtabs{display:flex;gap:8px;margin:16px 0 0;flex-wrap:wrap}
.subtab{padding:8px 15px;border-radius:9px;font-weight:700;font-size:12.5px;border:1px solid var(--line);background:#fff;color:var(--muted)}
.subtab.on{background:var(--navy);color:#fff;border-color:var(--navy)}
.rmcat{font-size:10.5px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:var(--brand);padding:20px 2px 8px;margin-top:2px}
.sheetgrid{border:1px solid var(--line);border-radius:12px;overflow:hidden;margin-top:6px;background:#fff}
.sheetrow{display:flex;flex-wrap:wrap;align-items:stretch;border-bottom:1px solid var(--line)}
.sheetrow:last-child{border-bottom:none}
.sheetrow-label{flex:0 0 130px;padding:12px 10px;font-weight:800;font-size:12px;background:#f4f6f9;color:var(--ink);border-right:1px solid var(--line);display:flex;align-items:center;line-height:1.25}
.sheetrow.sr-y .sheetrow-label{background:#fdf1cf;color:#7a5b00}
.sheetrow.sr-g .sheetrow-label{background:#eef1f5;color:var(--muted)}
.sheetrow-body{flex:1 1 320px;display:flex;flex-wrap:wrap;gap:10px;padding:10px 12px;align-items:flex-start}
.sheetrow-body .f{margin:0;flex:1 1 130px;min-width:110px}
.sheetrow-body .f label{font-size:9.5px;margin-bottom:3px}
.sheetrow-body .f .in,.sheetrow-body .f select{padding:7px 9px;font-size:12.5px}
@media(max-width:860px){.sheetrow-label{flex:1 1 100%;border-right:none;border-bottom:1px solid var(--line)}}
/* Literal spreadsheet-grid look — matches NQ Main Quotation tab (thin cell borders,
   compact rows, small text, colour-banded label column) instead of padded form cards. */
/* Base "box pattern" for the Quotation grid — every cell now gets its real NQ Main colour via
   an inline style (rowStyle()/rowBg()/rowFg() in JS, sourced from the live Google Sheet's actual
   cell formatting). These base rules are just the fallback for the rare cell with no inline
   colour and the shared border/spacing every row uses, so the "box" no longer relies on the old
   generic amber .nq-y/.nq-g theme. */
.nqwrap{overflow-x:auto;border:1px solid #4a5568;border-radius:10px;margin-top:8px;background:#fff}
.nqsheet{border-collapse:collapse;width:100%;font-size:11.5px;min-width:760px;font-family:inherit}
.nqsheet td{border:1px solid #dde1e7;padding:7px 10px;vertical-align:top;background:#fff}
.nqsheet tr.nqhead td{font-weight:700;font-size:10.5px;text-transform:uppercase;letter-spacing:.3px;text-align:left;padding:8px 10px;border-color:#4a5568}
/* 19 Aug — root cause of "boxes coming over each other": this rule used to be white-space:nowrap.
   Header cells with a label + input + a SECOND inline element stacked after it (Custom Price ₹'s
   input+select) are both inline-level and width:100% — with nowrap forcing them onto one "line"
   (nowrap disables the whitespace wrap point between them), the second element had nowhere to go
   but overflow sideways past the cell's border into the next column, which the next column's own
   opaque background then visually clipped — exactly the overlapping-boxes look Jay saw. Dropped
   nowrap (the short header labels never needed it to avoid wrapping in these column widths anyway)
   and made every input/select inside a stacked header cell explicitly block-level, so they always
   stack on their own line regardless of white-space, however this row's markup evolves later. -->
.nqsheet tr.nqhead .nqin,.nqsheet tr.nqhead input,.nqsheet tr.nqhead select{display:block}
.nqsheet td.nqlabel{font-weight:700;font-size:12px;white-space:nowrap;vertical-align:middle}
.nqch{font-size:8px;font-weight:700;color:#666;text-transform:uppercase;letter-spacing:.2px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 18 Aug — Jay: "arrange complete raw heights" — this blanket td{overflow:hidden} could clip a
   cell's content vertically if it ever wraps taller than its neighbours in the same row (cells
   that need horizontal clipping, like .nqch above, already set their own overflow:hidden). Removed
   so every row always grows to fully fit whatever's inside it, nothing gets cropped. */
.nqin{border:1px solid #c9b287;border-radius:5px;background:#fff;width:100%;min-width:56px;font-size:12.5px;padding:5px 7px;font-family:inherit;color:#111;box-shadow:none;transition:border-color .15s ease,box-shadow .15s ease}
select.nqin{cursor:pointer}
.nqin:hover{border-color:#8a6d3b}
.nqin:focus{outline:none;box-shadow:0 0 0 3px rgba(76,141,255,.18);border-color:#4c8dff;background:#fff}
.nqcell{min-width:70px;width:1%}
.nqcell.wide{min-width:120px}
.nqnote{font-size:9px;color:#9aa0a6;white-space:normal;line-height:1.3;max-width:150px}
.nqsheet{table-layout:fixed}
.nqsheet col.nqcol-label{width:112px}
.nqsheet col.nqcol-desc{width:170px}
.nqsheet col.nqcol-d{width:100px}
.nqsheet col.nqcol-price{width:120px}
.nqsheet col.nqcol-amt{width:115px}
.nqitemwrap{position:relative}
.nqitem-res{position:absolute;top:100%;left:0;z-index:40;min-width:280px;max-width:360px;max-height:360px;overflow-y:auto;background:#fff;border:1px solid #e5e9ef;border-radius:10px;box-shadow:0 10px 28px rgba(16,28,45,.14);margin-top:6px}
.nqitem-res:empty{display:none;border:none;box-shadow:none}
@media(max-width:860px){.nqwrap{border-radius:0}}
/* 19 Aug — the .k5/.k4/.formgrid column-count overrides that used to live in these breakpoints
   are gone: repeat(auto-fit,minmax(...)) above already reflows them to however many columns fit
   at ANY width (including phone widths — auto-fit never lets a track overflow its container, so
   it collapses to 1 column on its own once 2 genuinely won't fit, no !important tug-of-war
   needed). .grid-2/.grid-3/.split keep their hard collapse-to-1-column here since those are
   fixed-RATIO layouts (e.g. 1.6fr/1fr), not uniform card grids — auto-fit doesn't apply to them. */
@media(max-width:1100px){.grid-2,.grid-3,.split{grid-template-columns:1fr}}
.hamb{display:none}
@media(max-width:860px){
  #app{grid-template-columns:1fr;grid-template-rows:56px 1fr}
  #side{position:fixed;top:0;bottom:0;left:-248px;width:236px;z-index:130;transition:left .25s ease;box-shadow:2px 0 40px rgba(0,0,0,.35)}
  #app.navopen #side{left:0}
  #app.navopen::after{content:"";position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:120}
  #top{grid-column:1;grid-row:1;padding:0 12px}
  #main{grid-column:1;grid-row:2}
  .hamb{display:inline-flex;align-items:center;background:none;border:none;font-size:23px;color:var(--ink);cursor:pointer;padding:0 12px 0 0}
  #top .search,#top .plant,#top .notif{display:none}
  #top .title b{font-size:15px}#top .title .sub{font-size:10.5px}
  #top .uchip .nm{display:none}
  .navtoggle{display:none} /* the icons-only collapse is a desktop concept — the sidebar is already off-canvas (hamburger) below this width */
  .grid-2,.grid-3,.split{grid-template-columns:1fr!important}
  #main .card{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .subtabs{flex-wrap:wrap}
}
/* 19 Aug (later) — Jay: "what is this box, coming in the quotation print" — a screenshot of the
   raw internal Costing Engine grid showing up in a printed page. Every real "print" action in the
   app (Print/PDF on a quotation, job card, etc.) already opens an isolated popup document via
   printDoc() that only ever contains the clean client-facing HTML — this main stylesheet had NO
   print rules at all, so if the browser's own Ctrl+P/Print is used directly on an app screen
   instead, it printed the whole page verbatim: sidebar, buttons, and any internal tool visible on
   screen (like the "Add item" Costing Engine below an open quotation, marked .no-print below).
   This is a safety net for that path, not a replacement for the dedicated Print/PDF buttons. */
@media print{
  #side,#top,.no-print,.btn,button{display:none!important}
  #app{display:block!important;height:auto!important}
  #main{padding:0!important;overflow:visible!important}
}

/* ===== BOXOX navy + gold theme ===== */
:root{--brand:#c9a24b;--brand-d:#b08d3e;--gold:#c9a24b;--gold-2:#d9b866;--gold-d:#a9822f;--navy:#0f1b2d;--navy-2:#16273c;--bg:#eef1f4}
body{background:radial-gradient(1100px 500px at 100% -5%,#e9edf3,transparent),var(--bg)}
#side{background:linear-gradient(180deg,#122034,#0b1524);box-shadow:2px 0 24px rgba(6,12,22,.28)}
.logo .cube{background:linear-gradient(145deg,#1a2c44,#0f1b2d)!important;box-shadow:inset 0 0 0 1px rgba(201,162,75,.55),0 4px 12px rgba(0,0,0,.3)}
.logo .cube svg path{stroke:var(--gold-2)}
.logo .t b{color:#fff}.logo .t span{color:var(--gold);opacity:.85}
.nitem{color:#b6c2d2}
.nitem:hover{background:#17293f;color:#fff}
.nitem.on{background:linear-gradient(90deg,rgba(201,162,75,.18),rgba(201,162,75,.02));color:#fff;border-left-color:var(--gold)}
.nitem.on::before{background:linear-gradient(#d9b866,#c9a24b)!important}
.nitem .badge{background:var(--gold);color:#12203a}
.tenant{background:#0b1626;border-color:#1e2c40}
.tenant .live{color:var(--gold-2);background:#241b09}
.tenant .live::before{background:var(--gold-2)}
#top{box-shadow:0 1px 0 var(--line),0 8px 22px rgba(16,27,45,.05)}
.uchip .av{background:linear-gradient(145deg,#1a2c44,#0f1b2d);box-shadow:inset 0 0 0 1px rgba(201,162,75,.5)}
.btn{background:linear-gradient(180deg,#22374f,#14273e);color:#fff;box-shadow:0 6px 15px rgba(15,27,45,.26);border-radius:11px}
.btn:hover{background:linear-gradient(180deg,#28405f,#182f49);transform:translateY(-1px)}
.btn.orange{background:linear-gradient(180deg,#dcbb6a,#c29a3f)!important;color:#14273e!important;box-shadow:0 8px 18px rgba(201,162,75,.42)!important;font-weight:800}
.btn.orange:hover{filter:brightness(1.05)}
.btn.ghost{background:#fff;color:var(--navy);border:1px solid var(--line);box-shadow:var(--pshadow)}
.btn.ghost:hover{background:#fbfaf7;border-color:#e3d9c2}
.in:focus,.lin:focus{border-color:var(--gold)!important;box-shadow:0 0 0 3px rgba(201,162,75,.18)!important}
.kpi .ico{box-shadow:inset 0 0 0 1px rgba(255,255,255,.28),0 6px 14px rgba(16,27,45,.14)}
.ic-orange{background:linear-gradient(145deg,#d9b866,#c29a3f)!important;color:#14273e!important}
.card{border-color:#e9ecf1}
.sec-h b{color:var(--navy)}
thead th{background:#0f1b2d;color:#cfd8e4;font-weight:700;border-color:#0f1b2d}
tbody tr:hover{background:#faf7ef}
.pill.g{background:#eef7f0;color:#1a7f45}.pill.a{background:#fbf2df;color:#9a6a15}.pill.r{background:#fdecec;color:#c23127}
#login{background:radial-gradient(1000px 520px at 18% -12%,#1e3350,transparent),linear-gradient(140deg,#0f1b2d,#080f1a)}
.lcard{border-radius:20px;box-shadow:0 40px 110px rgba(0,0,0,.55);border-top:4px solid var(--gold)}
.lcube{background:linear-gradient(145deg,#1a2c44,#0f1b2d)!important;box-shadow:inset 0 0 0 1px rgba(201,162,75,.6)}
.lbtn{background:linear-gradient(180deg,#dcbb6a,#c29a3f);color:#14273e;font-weight:800}
.lbtn:hover{background:linear-gradient(180deg,#e2c477,#c9a24b);filter:brightness(1.02)}
.llink{color:var(--gold-d)}
#gbFab{background:linear-gradient(145deg,#1a2c44,#0f1b2d)!important;box-shadow:0 12px 28px rgba(10,18,32,.5),inset 0 0 0 1px rgba(201,162,75,.55)!important}
#main::-webkit-scrollbar{width:10px}#main::-webkit-scrollbar-thumb{background:#d5dbe4;border-radius:8px;border:3px solid var(--bg)}
.ngroup{display:flex;align-items:center;gap:11px;width:100%;text-align:left;color:#aab8c8;padding:9px 11px;border-radius:9px;font-weight:700;font-size:13px;margin-bottom:1px}
.ngroup .ic{width:18px;text-align:center;font-size:15px}
.ngroup .gt{flex:1}.ngroup .chev{opacity:.55;font-size:11px}
.ngroup:hover{background:#17293f;color:#fff}
.ngroup.active{color:#fff}.ngroup.active .gt{color:var(--gold-2)}
.nsub{margin:0 0 5px 0}
.nitem.sub{padding:7px 11px 7px 32px;font-size:12.5px;font-weight:600;border-left:none}
.nitem.sub .dotm{width:5px;height:5px;border-radius:50%;background:#5f7086;display:inline-block;margin-right:10px;flex:0 0 auto}
.nitem.sub.on{background:linear-gradient(90deg,rgba(201,162,75,.18),transparent)}
.nitem.sub.on .dotm{background:var(--gold-2)}
.nitem.sub.on::before{display:none}
/* Box Costing (vBoxCost) — 28 Aug fresh rebuild. Jay: "lite magenta cells are the one where i put
   the numbers" — every manual-entry field in this module gets that same light-magenta treatment,
   applied uniformly per his own blanket rule (not per-cell-guessed fill colors this round). */
.bc-in{background:#fbeef4!important;border-color:#e3b8cd!important}
.bc-in:focus{background:#fdf5f9!important}
