/* =============================================================================
   Blugital — merchant backend shell (v2.8)
   Paired with blugital-shell.js. Loaded by every page that uses the sidebar.

   Two rules run through all of this, both learned the hard way:

   * Grid tracks are minmax(0,1fr), never a bare 1fr. A plain 1fr is
     minmax(auto,1fr) and that `auto` floor is min-content — which is what
     pushed the cashier screen to 872px on a 375px phone.
   * flex shorthand is `0 0 auto`, never `0`. `flex:0` sets flex-basis:0%,
     which in a column container is the HEIGHT, and collapsed a button label
     to nothing.
   ============================================================================= */

:root{
  --ink:#0B1B33; --soft:#5A6A82; --line:#E2E8F2; --line2:#EDF1F8; --bg:#F6F8FC;
  --blue:#1B5AF3; --blue-d:#0B39C4; --sky:#EAF1FF; --green:#1B8F5A; --green-bg:#E9F6EF;
  --rose:#C0453E; --rose-bg:#FBECEB; --gold:#B8842A; --gold-bg:#FFF6E6; --card:#fff;
  --nav-w:236px;
}
html,body{margin:0;overflow-x:hidden;}
body.bg-shell{
  background:var(--bg); color:var(--ink);
  font-family:Inter,'Noto Sans Khmer',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  font-size:14px; line-height:1.55;
}
/* Khmer stacks diacritics above and below; the English leading collides. */
html[lang="km"] body.bg-shell{line-height:1.75;}
body.bg-shell h1,body.bg-shell h2,body.bg-shell h3,
body.bg-shell .val,body.bg-shell .num{
  font-family:'Space Grotesk','Noto Sans Khmer',system-ui,sans-serif;
}
html[lang="km"] body.bg-shell .val{line-height:1.35;}
body.bg-shell button,body.bg-shell input,body.bg-shell select,body.bg-shell textarea{
  font-family:inherit;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}

/* scrollbars are never visible anywhere in the shell */
.noscroll{scrollbar-width:none;-ms-overflow-style:none;}
.noscroll::-webkit-scrollbar{width:0;height:0;display:none;}

/* ---------- layout ---------- */
body.bg-shell{display:grid;grid-template-columns:var(--nav-w) minmax(0,1fr);
  grid-template-rows:minmax(0,1fr);min-height:100vh;}
/* position:FIXED, not sticky. `html,body{overflow-x:hidden}` above makes body a
   scroll container, and a sticky child of a scroll container that never scrolls
   internally has no range to stick within — so the sidebar scrolled away with
   the page. Measured on the live v2.8 build at 1280px: at scrollY 600 the
   sidebar's top was at -600. Fixed positioning is immune to that, and it is
   what the mobile drawer already uses, so both breakpoints now behave alike.
   The 236px grid column stays as the spacer that .bg-main sits beside. */
.bg-side{grid-column:1;background:#0B1B33;color:#C8D6EE;padding:14px 11px;
  display:flex;flex-direction:column;gap:2px;
  position:fixed;top:0;left:0;width:var(--nav-w);height:100vh;overflow-y:auto;}
.bg-main{grid-column:2;min-width:0;padding:20px 24px 60px;}
.bg-top{display:none;}
.bg-scrim{display:none;}

.bg-brand{display:flex;align-items:center;gap:9px;padding:6px 10px 14px;text-decoration:none;}
.bg-bars{display:flex;gap:3px;flex:0 0 auto;}
.bg-bars i{width:4px;height:18px;background:#4C8DFF;border-radius:2px;display:block;}
.bg-bars i:nth-child(2){height:12px;opacity:.75;}
.bg-bars i:nth-child(3){height:22px;opacity:.55;}
.bg-brand b{color:#fff;font-size:15px;}
.bg-sec{font-size:10.5px;text-transform:uppercase;letter-spacing:.08em;color:#6D82A8;
  padding:13px 10px 5px;}
.bg-side a{display:flex;align-items:center;gap:10px;padding:10px;border-radius:9px;
  color:#C8D6EE;text-decoration:none;font-size:13.5px;font-weight:500;cursor:pointer;min-width:0;}
.bg-side a .ic{width:20px;flex:0 0 auto;text-align:center;}
.bg-side a .tx{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bg-side a:hover{background:rgba(255,255,255,.06);}
.bg-side a.on{background:var(--blue);color:#fff;font-weight:600;}
.bg-side a .pill{flex:0 0 auto;background:var(--gold);color:#2A1E00;font-size:10.5px;
  font-weight:800;border-radius:99px;padding:1px 6px;}
.bg-foot{margin-top:auto;padding-top:12px;border-top:1px solid rgba(255,255,255,.09);}
.bg-lang{display:flex;gap:4px;padding:10px 8px 4px;}
.bg-lang button{flex:1 1 auto;border:1px solid #2A4E82;background:transparent;color:#8FB4EC;
  border-radius:8px;padding:6px;font-size:11.5px;font-weight:700;cursor:pointer;}
.bg-lang button.on{background:var(--blue);color:#fff;border-color:var(--blue);}

/* ---------- ‹ › scroller ----------
   The arrows sit IN the flex row, not absolutely positioned over it. Overlaid,
   an arrow covered the first and last item — on the Settings sub-nav the ‹ sat
   on top of the storefront icon. As real flex items they occupy their own
   space and can never cover a control. Both appear together (the inactive one
   is only made invisible) so the track keeps a steady width while you scroll. */
.hs{display:flex;align-items:center;gap:4px;min-width:0;}
.hs-track{flex:1 1 auto;min-width:0;display:flex;gap:6px;overflow-x:auto;
  scroll-behavior:smooth;scrollbar-width:none;-ms-overflow-style:none;padding:2px;}
/* Flex items shrink by default. Without this the buttons squeezed themselves
   to fit instead of overflowing, so scrollWidth never exceeded clientWidth,
   the ‹ › arrows never appeared, and the Khmer labels were cramped. Measured
   at 320px: five buttons compressed 306px of content into 298px. */
.hs-track > *{flex:0 0 auto;}
.hs-track::-webkit-scrollbar{width:0;height:0;display:none;}
.hs-arrow{flex:0 0 auto;width:28px;height:28px;border-radius:50%;
  border:1px solid var(--line);background:#fff;color:var(--ink);
  font-size:15px;line-height:1;cursor:pointer;padding:0;display:none;
  align-items:center;justify-content:center;box-shadow:0 2px 8px rgba(11,27,51,.13);}
.hs.hs-on > .hs-arrow{display:flex;}
.hs-arrow:disabled{visibility:hidden;cursor:default;}

/* ---------- page furniture ---------- */
.page-h{display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap;margin-bottom:8px;}
.page-h h1{font-size:21px;margin:0;}
.page-h .sub{color:var(--soft);font-size:13px;margin:2px 0 0;}
.page-h .act{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap;}
.btn{border:none;border-radius:10px;padding:9px 14px;font-size:13px;font-weight:600;
  background:linear-gradient(180deg,var(--blue),var(--blue-d));color:#fff;cursor:pointer;}
.btn.ghost{background:#fff;border:1px solid var(--line);color:var(--ink);}
.btn.sm{padding:6px 11px;font-size:12.5px;}
.btn.danger{color:var(--rose);border-color:#F0C9C6;}
.btn:disabled{opacity:.5;cursor:default;}

.card{background:var(--card);border:1px solid var(--line);border-radius:14px;
  padding:15px 17px;margin-bottom:12px;min-width:0;}
.card h3{margin:0 0 3px;font-size:15px;}
.card .hint{color:var(--soft);font-size:12.5px;margin:0 0 12px;}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,270px),1fr));gap:12px;}
.grid3{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,180px),1fr));gap:12px;}
.grid4{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,166px),1fr));gap:12px;}
.grid2>*,.grid3>*,.grid4>*{min-width:0;}

.tasks{background:var(--gold-bg);border:1px solid #EBD9A8;border-radius:14px;
  padding:12px 15px;margin-bottom:14px;}
.tasks h3{margin:0 0 6px;font-size:14px;color:#6B5320;}
.task{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 0;
  border-top:1px solid #EBD9A8;font-size:13px;color:#6B5320;}
.task:first-of-type{border-top:none;}
.task .n{flex:1 1 190px;min-width:0;}
.task .bs{display:flex;gap:6px;flex:0 0 auto;}

.kpi{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:13px 15px;min-width:0;}
.kpi .lab{font-size:11.5px;color:var(--soft);text-transform:uppercase;letter-spacing:.04em;}
.kpi .val{font-size:25px;font-weight:700;margin-top:4px;line-height:1.15;overflow-wrap:anywhere;}
.kpi .dl{font-size:12px;margin-top:5px;font-weight:600;}
.up{color:var(--green);} .down{color:var(--rose);} .flat{color:var(--soft);}
.kpi.hero{background:linear-gradient(150deg,#12294A,#0B1B33);border-color:#12294A;color:#fff;}
.kpi.hero .lab{color:#8FB4EC;} .kpi.hero .val{color:#fff;}

.bars-h{display:flex;flex-direction:column;gap:9px;}
.bar-row{display:flex;align-items:center;gap:9px;font-size:12.5px;min-width:0;}
.bar-row .nm{flex:0 1 120px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bar-row .tr{flex:1 1 auto;min-width:30px;background:var(--line2);border-radius:99px;height:9px;overflow:hidden;}
.bar-row .fl{height:100%;background:var(--blue);border-radius:99px;display:block;}
.bar-row .fl.g{background:var(--green);} .bar-row .fl.r{background:var(--rose);}
.bar-row .vv{flex:0 0 auto;text-align:right;font-weight:700;white-space:nowrap;}
.spark{display:flex;align-items:flex-end;gap:3px;height:72px;min-width:0;}
.spark div{flex:1 1 0;min-width:0;background:var(--sky);border-radius:4px 4px 0 0;position:relative;}
.spark div i{position:absolute;inset:auto 0 0 0;background:var(--blue);border-radius:4px 4px 0 0;display:block;}
.hours{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:3px;}
.hours span{aspect-ratio:1;border-radius:3px;background:var(--line2);}
.hlab{display:flex;justify-content:space-between;font-size:10.5px;color:var(--soft);margin-top:5px;}

/* ---------- tables that become cards ---------- */
.tbl{width:100%;border-collapse:collapse;font-size:13px;}
.tbl th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--soft);padding:7px 8px;border-bottom:1px solid var(--line);font-weight:700;}
.tbl td{padding:9px 8px;border-bottom:1px solid var(--line2);}
.tbl tr:last-child td{border-bottom:none;}
.tbl td.r,.tbl th.r{text-align:right;}
.tag{display:inline-block;font-size:11px;font-weight:700;border-radius:99px;padding:2px 8px;white-space:nowrap;}
.tag.ok{background:var(--green-bg);color:var(--green);}
.tag.low{background:var(--gold-bg);color:var(--gold);}
.tag.out{background:var(--rose-bg);color:var(--rose);}

.row{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:11px 0;border-top:1px solid var(--line2);}
.row:first-of-type{border-top:none;}
.row .rl{flex:1 1 190px;min-width:0;}
.row .rl b{display:block;font-size:13.5px;}
.row .rl span{font-size:12px;color:var(--soft);}
.sw{width:42px;height:24px;border-radius:99px;background:var(--line);position:relative;
  flex:0 0 auto;cursor:pointer;border:none;padding:0;}
.sw i{position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;
  transition:.15s;box-shadow:0 1px 3px rgba(0,0,0,.2);}
.sw.on{background:var(--green);} .sw.on i{left:21px;}
.fld label{display:block;font-size:12px;color:var(--soft);margin-bottom:4px;}
.inp{border:1px solid var(--line);border-radius:9px;padding:9px 10px;font-size:13px;width:100%;}
.mono{font-family:ui-monospace,Menlo,monospace;font-size:12.5px;overflow-wrap:anywhere;}
/* Namespaced. As plain ".soon" this pill badge collided with mystore.html's
   own ".card.soon" card modifier — and because this shared sheet loaded after
   that page's <style>, the badge's border-radius:99px, inline-block and 2px
   padding won, turning three feature cards into grey pills. A shared
   stylesheet must not claim a word as common as "soon". */
.bg-soon{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:.04em;
  text-transform:uppercase;background:var(--line2);color:var(--soft);border-radius:99px;
  padding:2px 8px;margin-left:6px;vertical-align:middle;}
.empty{color:var(--soft);font-size:13px;padding:18px 2px;}

/* ---------- settings sub-nav ---------- */
.set-wrap{display:grid;grid-template-columns:206px minmax(0,1fr);gap:16px;align-items:start;}
.set-nav{position:sticky;top:14px;background:var(--card);border:1px solid var(--line);
  border-radius:14px;padding:6px;min-width:0;}
.set-nav button{display:flex;align-items:center;gap:9px;width:100%;text-align:left;border:none;
  background:none;padding:9px 10px;border-radius:9px;font-size:13px;color:var(--soft);
  cursor:pointer;font-weight:500;min-width:0;}
.set-nav button .tx{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.set-nav button.on{background:var(--sky);color:var(--blue);font-weight:700;}
.set-nav .grp{font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;color:#93A2BA;
  padding:10px 10px 4px;}
/* On desktop this is a vertical list in a 206px column, so the shared .hs
   scroller must NOT apply — .hs-track{display:flex} was laying the sections
   out in a row 986px wide inside that column, which is why Settings showed one
   clipped button with an arrow over it. Below 900px the row form is correct
   and the media query further down restores it. */
.set-nav .hs{display:block;}
.set-nav .hs-track{display:block;overflow:visible;padding:0;}
.set-nav .hs-arrow{display:none !important;}

/* ================= RESPONSIVE ================= */
@media (max-width:1080px){ :root{--nav-w:210px;} }

@media (max-width:900px){
  body.bg-shell{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);}
  .bg-top{display:flex;grid-column:1;grid-row:1;position:sticky;top:0;z-index:20;
    background:#0B1B33;color:#fff;align-items:center;gap:10px;padding:9px 12px;}
  .bg-burger{background:rgba(255,255,255,.1);border:none;color:#fff;border-radius:9px;
    width:38px;height:38px;font-size:17px;cursor:pointer;flex:0 0 auto;}
  .bg-ttl{flex:1 1 auto;min-width:0;font-size:15px;font-weight:700;
    font-family:'Space Grotesk','Noto Sans Khmer';overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .bg-lang-top{padding:0;flex:0 0 auto;}
  .bg-lang-top button{padding:6px 9px;}
  .bg-side{position:fixed;top:0;left:0;bottom:0;width:250px;z-index:30;height:100vh;
    transform:translateX(-102%);transition:transform .22s cubic-bezier(.4,0,.2,1);}
  body.bg-drawer .bg-side{transform:none;}
  .bg-scrim{position:fixed;inset:0;background:rgba(4,10,22,.5);z-index:29;}
  body.bg-drawer .bg-scrim{display:block;}
  .bg-main{grid-column:1;grid-row:2;padding:16px 14px 56px;}
  .set-wrap{grid-template-columns:minmax(0,1fr);gap:12px;}
  .set-nav{position:static;padding:4px;}
  .set-nav .grp{display:none;}
  .set-nav button{width:auto;flex:0 0 auto;white-space:nowrap;}
  .set-nav button .tx{overflow:visible;}
  /* back to the horizontal ‹ › strip, which is the right shape on a phone */
  .set-nav .hs{display:flex;}
  .set-nav .hs-track{display:flex;overflow-x:auto;padding:2px;}
  .set-nav .hs.hs-on > .hs-arrow{display:flex !important;}
}

/* Phone: a six-column table cannot be read however it scrolls, so each row
   becomes a small stacked card with its column name beside each value. Every
   <td> must carry data-l for this to work. */
@media (max-width:760px){
  .tbl,.tbl tbody,.tbl tr,.tbl td{display:block;width:100%;}
  .tbl thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);}
  .tbl tr{border:1px solid var(--line);border-radius:11px;padding:6px 10px;margin-bottom:8px;background:#fff;}
  .tbl td{border:none;padding:5px 0;display:flex;gap:12px;align-items:center;}
  .tbl td::before{content:attr(data-l);flex:0 0 42%;font-size:11.5px;color:var(--soft);
    text-transform:uppercase;letter-spacing:.04em;font-weight:700;}
  .tbl td.r{text-align:left;}
  .tbl td:first-child{font-weight:700;font-size:14px;padding-bottom:7px;
    border-bottom:1px solid var(--line2);margin-bottom:4px;}
  .tbl td:first-child::before{display:none;}
  .page-h h1{font-size:19px;}
  .kpi .val{font-size:22px;}
  .bar-row .nm{flex-basis:90px;}
}
@media (max-width:420px){
  .bg-main{padding:12px 11px 52px;}
  .card{padding:13px 14px;}
  .kpi{padding:11px 13px;}
}
@media print{ .bg-side,.bg-top,.bg-scrim{display:none !important;}
  body.bg-shell{display:block;} .bg-main{padding:0;} }

/* ---------- retiring the old per-page chrome ----------
   Each page used to carry its own <header> with a logo, the store name, a
   language toggle and a sign-out link. The shell provides all of that once, so
   the old header is hidden rather than deleted — the pages still reference
   elements inside it (the account email, the language pills), and removing the
   markup would break that JS for no gain. The shell reads the same i18n, so
   the hidden pills stay in step. */
body.bg-shell .bg-main > header{display:none;}
body.bg-shell .bg-main > main{max-width:none;margin:0;padding:0;width:auto;}
body.bg-shell .bg-main > main > .wrap,
body.bg-shell .bg-main > main > .container{max-width:none;padding:0;margin:0;}
/* A page's own sticky save bar must sit above the drawer scrim, not under it. */
body.bg-shell .savebar{z-index:28;}

/* Store switcher relocated out of the retired page header (see shell.js). */
.bg-store{padding:2px 10px 6px;}
.bg-store select{width:100%;max-width:100%;box-sizing:border-box;
  background:#12294A;color:#E6EEFB;border:1px solid #2A4E82;border-radius:9px;
  padding:8px 9px;font-size:12.5px;font-family:inherit;cursor:pointer;
  appearance:none;-webkit-appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,#8FB4EC 50%),
                   linear-gradient(135deg,#8FB4EC 50%,transparent 50%);
  background-position:calc(100% - 15px) 50%,calc(100% - 10px) 50%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;}
.bg-store select option{background:#0B1B33;color:#E6EEFB;}
