/* Back-office chrome: sidebar, top bar, search, account menu, mobile shell.
   Extracted from POS static/pultrack.css @ origin/main. Needs tokens.css + fonts/plex.css. */
/* ============================================================ BACK OFFICE
   The two chrome modes (brief Revision 1 §7):
   back office = left sidebar; POS = chrome-free top strip. */
.bo{ display:flex; min-height:100vh; min-height:100dvh; }

/* --------------------------------------------------------------- sidebar */
.sidebar{
  width:var(--sidebar-w); flex:none;
  background:var(--green-2); color:#cfdcd2;
  display:flex; flex-direction:column;
  position:sticky; top:0; height:100vh; height:100dvh;
  transition:width .15s ease;
  z-index:1030;
}
.sidebar .sb-head{
  display:flex; align-items:center; gap:9px;
  padding:11px 12px 11px 14px; flex:none;
  border-bottom:1px solid rgba(255,255,255,.08);
}
.sidebar .sb-head .tile{ width:30px; height:30px; border-radius:8px; flex:none; }
.sidebar .sb-head .wm{ font-weight:600; font-size:var(--text-xl); color:var(--paper); letter-spacing:-.01em; white-space:nowrap; }
.sidebar .sb-toggle{
  margin-left:auto; background:none; border:0; color:#9fb3a6;
  width:26px; height:26px; border-radius:6px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
}
.sidebar .sb-toggle:hover{ background:rgba(255,255,255,.08); color:#fff; }
.sidebar .sb-toggle svg{ width:15px; height:15px; }

.sidebar .sb-scroll{ flex:1; overflow-y:auto; overflow-x:hidden; padding:8px 8px 10px; }
.sidebar .sb-scroll::-webkit-scrollbar{ width:5px; }
.sidebar .sb-scroll::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.15); border-radius:3px; }

.sidebar .sb-glabel{
  font-family:'IBM Plex Mono',monospace; font-size:var(--text-2xs); letter-spacing:.14em;
  text-transform:uppercase; color:#94ab95; padding:12px 8px 4px; white-space:normal; overflow-wrap:anywhere;
}
.sidebar .sb-item{
  display:flex; align-items:center; gap:10px;
  padding:7px 9px; margin:1px 0;
  border-radius:8px; border-left:3px solid transparent;
  color:#cfdcd2; text-decoration:none; font-size:var(--text-base); font-weight:500;
  white-space:nowrap; overflow:hidden;
}
/* Nav polish (matches Pultrack F&B). Deliberately fast (.16s) and eased-out: a
   sidebar is passed through constantly, so anything slower than ~200ms starts
   to feel like lag rather than finish. No bounce, no stagger — those read as
   playful, not premium, and they fight rapid navigation. */
.sidebar .sb-item{
  transition:background .16s ease-out, color .16s ease-out,
             border-left-color .16s ease-out, transform .16s ease-out;
}
.sidebar .sb-item:hover{
  background:rgba(255,255,255,.07); color:#fff;
  transform:translateX(2px);            /* a nudge, not a slide */
}
.sidebar .sb-item:active{ transform:translateX(1px) scale(.995); }  /* press feedback on click */
.sidebar .sb-item.active{
  background:rgba(255,255,255,.10); color:#fff;
  border-left-color:var(--gold);
}
/* The gold rule grows in on hover, so the accent feels attached to the item
   rather than switched on. The ACTIVE item keeps its full bar. */
.sidebar .sb-item:not(.active):hover{ border-left-color:rgba(194,138,44,.45); }
.sidebar.rail .sb-item:hover{ transform:none; }   /* no room to nudge in a rail */
.sidebar .sb-item .ic{ width:17px; height:17px; flex:none; display:flex; }
.sidebar .sb-item .ic i{ font-size:var(--text-lg); line-height:1; }
.sidebar .sb-item .lbl{ min-width:0; white-space:normal; overflow-wrap:anywhere; }

.sidebar .sb-foot{
  flex:none; border-top:1px solid rgba(255,255,255,.08); padding:10px 12px;
}
.sidebar .sb-user{ display:flex; align-items:center; gap:9px; }
.sidebar .sb-user .av{
  width:30px; height:30px; border-radius:50%; flex:none;
  background:rgba(255,255,255,.12); color:var(--paper);
  display:flex; align-items:center; justify-content:center;
  font-size:var(--text-sm); font-weight:600;
}
.sidebar .sb-user .uw{ display:flex; flex-direction:column; min-width:0; }
.sidebar .sb-user .un{ font-size:var(--text-sm); font-weight:600; color:var(--paper);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.sidebar .sb-user .ur{ font-size:var(--text-2xs); color:#8aa18e; white-space:nowrap; }
.sidebar .sb-user .out{
  margin-left:auto; background:none; border:0; color:#9fb3a6; cursor:pointer;
  width:26px; height:26px; border-radius:6px;
  display:flex; align-items:center; justify-content:center;
}
.sidebar .sb-user .out:hover{ background:rgba(255,255,255,.1); color:#fff; }

/* Collapsed icon rail */
.sidebar.rail{ width:var(--sidebar-rail); }
.sidebar.rail .wm, .sidebar.rail .sb-glabel, .sidebar.rail .sb-item .lbl,
.sidebar.rail .sb-user .uw{ display:none; }
.sidebar.rail .sb-head{ padding-left:12px; }
.sidebar.rail .sb-item{ justify-content:center; padding:9px 0; }
.sidebar.rail .sb-toggle{ margin-left:0; }
.sidebar.rail .sb-head{ flex-direction:column; gap:7px; }
.sidebar.rail .sb-user{ justify-content:center; }
.sidebar.rail .sb-user .out{ margin-left:0; }

/* Collapsible nav group (e.g. Administration) — folds away the least-used
   section so the list doesn't force a scroll. */
.sidebar .sb-ghead{
  width:100%; display:flex; align-items:center; gap:6px;
  background:none; border:0; cursor:pointer; text-align:left;
}
.sidebar .sb-ghead:hover{ color:#cfdcd2; }
.sidebar .sb-ghead .chev{ margin-left:auto; transition:transform .22s cubic-bezier(.34,1.56,.64,1); line-height:1; }
.sidebar .sb-ghead .chev i{ font-size:var(--text-xs); }
.sidebar .sb-group.collapsible.open .sb-ghead .chev{ transform:rotate(180deg); }

/* Animated group expand/collapse. `display:none` can't be transitioned, so a
   closed group is clipped to max-height:0 instead. The transition is gated
   behind .nav-anim (added by JS one frame after the initial open) so the group
   auto-opened for the current page doesn't slide on every page load. Rail state
   keeps its own icon layout, so it's excluded. */
.sidebar:not(.rail) .sb-group.collapsible .sb-gitems{
  overflow:hidden; max-height:0; opacity:0;
  visibility:hidden;   /* keep collapsed links out of the tab order (as display:none did) */
}
.sidebar:not(.rail) .sb-group.collapsible.open .sb-gitems{
  max-height:600px; opacity:1; visibility:visible;
}
.sidebar.nav-anim:not(.rail) .sb-group.collapsible .sb-gitems{
  /* visibility flips to hidden only AFTER the collapse finishes, so content
     stays on-screen for the whole slide-up. */
  transition: max-height .22s ease, opacity .16s ease, visibility 0s linear .22s;
}
.sidebar.nav-anim:not(.rail) .sb-group.collapsible.open .sb-gitems{
  transition: max-height .28s ease, opacity .22s ease .04s, visibility 0s linear 0s;
}
/* Items settle in with a subtle downward slide when the group opens. */
.sidebar:not(.rail) .sb-group.collapsible .sb-gitems > *{ transform:translateY(-5px); }
.sidebar:not(.rail) .sb-group.collapsible.open .sb-gitems > *{ transform:translateY(0); }
.sidebar.nav-anim:not(.rail) .sb-group.collapsible .sb-gitems > *{ transition:transform .26s ease; }
@media (prefers-reduced-motion: reduce){
  .sidebar .sb-ghead .chev,
  .sidebar .sb-group.collapsible .sb-gitems,
  .sidebar .sb-group.collapsible .sb-gitems > *{ transition:none !important; }
  .sidebar .sb-item{ transition:none !important; }
  .sidebar .sb-item:hover, .sidebar .sb-item:active{ transform:none; }
}
.sidebar.rail .sb-ghead{ pointer-events:none; }   /* rail: items always show as icons */

/* --------------------------------------------------------------- main col */
.bo-main{ flex:1; min-width:0; display:flex; flex-direction:column; }
.botop{
  height:var(--topbar-h); flex:none;
  background:var(--app-card); border-bottom:1px solid var(--app-line);
  display:flex; align-items:center; gap:10px; padding:0 16px;
  position:sticky; top:0; z-index:1020;
}
.botop .crumb{ font-size:var(--text-base); color:var(--muted); font-weight:500;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Named "‹ Parent" breadcrumb at the top of a detail page — always returns to
   the parent list (restoring its last filter), the way QuickBooks does. */
.backlink{ display:inline-flex; align-items:center; gap:5px; font-size:var(--text-base);
  font-weight:600; color:var(--brand,#1B5739); text-decoration:none; margin:0 0 12px; }
.backlink:hover{ text-decoration:underline; }
.backlink .bi{ font-size:var(--text-sm); }
@media print { .backlink{ display:none !important; } }
.botop .right{ margin-left:auto; display:flex; align-items:center; gap:9px; }
.bo-main > main{ padding:1rem; }

/* ---------------- top bar: global search + account menu ---------------- */
.botop{ gap:14px; }
.topsearch{ position:relative; flex:1; max-width:520px; display:flex; align-items:center; }
.topsearch > .bi{ position:absolute; left:12px; color:var(--muted); font-size:var(--text-base); pointer-events:none; }
.topsearch input{ width:100%; padding:8px 12px 8px 34px; border:1px solid var(--app-line); border-radius:10px; background:#fff; font-size:var(--text-base); color:var(--app-ink); }
.topsearch input:focus{ outline:none; border-color:var(--green); box-shadow:0 0 0 3px rgba(27,87,57,.12); }
.ts-pop{ position:absolute; top:calc(100% + 6px); left:0; right:0; background:#fff; border:1px solid var(--app-line); border-radius:12px; box-shadow:var(--shadow); z-index:1100; max-height:60vh; overflow:hidden auto; }
.ts-item{ display:flex; flex-direction:column; gap:1px; padding:9px 13px; text-decoration:none; color:var(--app-ink); border-bottom:1px solid var(--app-line-soft); }
.ts-item:last-child{ border-bottom:0; }
.ts-item:hover{ background:var(--app-hover); }
.ts-nm{ font-weight:600; font-size:var(--text-base); }
.ts-meta{ font-size:var(--text-xs); color:var(--muted); font-family:'IBM Plex Mono',monospace; }
.ts-empty{ padding:12px 13px; color:var(--muted); font-size:var(--text-base); font-style:italic; }
.ts-newsale .bi{ font-size:var(--text-base); }
.acct{ position:relative; }
.acct-btn{ display:flex; align-items:center; gap:8px; background:none; border:1px solid transparent; border-radius:10px; padding:5px 9px; cursor:pointer; color:var(--app-ink); }
.acct-btn:hover{ background:var(--app-hover); }
.acct-btn .av{ width:28px; height:28px; border-radius:50%; background:var(--green); color:#fff; display:flex; align-items:center; justify-content:center; font-size:var(--text-sm); font-weight:600; flex:none; }
.acct-nm{ font-size:var(--text-base); font-weight:500; }
.acct-store{ font-size:var(--text-sm); font-weight:600; color:var(--green); background:var(--app-hover); border-radius:999px; padding:2px 9px; display:inline-flex; align-items:center; gap:4px; }
.acct-store .bi{ font-size:var(--text-xs); }
.acct-btn > .bi{ font-size:var(--text-xs); color:var(--muted); }
.acct-pop{ position:absolute; top:calc(100% + 6px); right:0; min-width:222px; background:#fff; border:1px solid var(--app-line); border-radius:12px; box-shadow:var(--shadow); z-index:1100; padding:6px; }
.acct-hdr{ padding:9px 11px 10px; border-bottom:1px solid var(--app-line-soft); margin-bottom:5px; }
.acct-shop{ font-weight:600; font-size:var(--text-base); color:var(--app-ink); }
.acct-u{ font-size:var(--text-xs); color:var(--muted); }
.acct-pop a, .acct-pop button{ display:flex; align-items:center; gap:9px; width:100%; text-align:left; padding:9px 11px; border-radius:8px; border:0; background:none; color:var(--app-ink); font-size:var(--text-base); text-decoration:none; cursor:pointer; }
.acct-pop a:hover, .acct-pop button:hover{ background:var(--app-hover); }
.acct-pop .bi{ font-size:var(--text-base); color:var(--muted); width:16px; text-align:center; }
/* Phone-only currency row (d-md-none in base.html): the bar's toggle moves
   here below 768px. Undo the full-width menu-row styling that
   ".acct-pop button" would otherwise give the two segment buttons. */
.acct-ccy{ display:flex; align-items:center; justify-content:space-between; gap:9px;
  padding:6px 11px; font-size:var(--text-base); color:var(--app-ink); }
.acct-ccy > span{ display:flex; align-items:center; gap:9px; }
.acct-ccy .ts-seg button{ display:block; width:auto; padding:7px 12px; border-radius:0;
  font-size:var(--text-sm); color:var(--muted); }
.acct-ccy .ts-seg button.on{ background:var(--green); color:#fff; }

/* ======================================================= MOBILE SHELL
   Phone breakpoint (≤767.98px = Bootstrap md boundary): the sidebar
   becomes an off-canvas drawer behind a hamburger in the top bar.
   Everything in this section is inert at ≥768px — desktop unchanged. */
.bo-hamburger{
  display:none; align-items:center; justify-content:center;
  width:38px; height:38px; flex:none;
  background:none; border:0; border-radius:9px;
  color:var(--app-ink); font-size:22px; cursor:pointer;
}
.bo-hamburger:hover{ background:var(--app-hover); }
.bo-backdrop{ position:fixed; inset:0; background:rgba(19,33,27,.45); z-index:1045; }
@media (min-width: 768px){ .bo-backdrop{ display:none !important; } }

@media (max-width: 767.98px){
  .bo-hamburger{ display:flex; }
  .sidebar{
    position:fixed; left:0; top:0; bottom:0; height:100dvh;
    width:min(84vw, 300px);
    transform:translateX(-100%);
    transition:transform .18s ease;
    z-index:1050;
  }
  .sidebar.open{ transform:translateX(0); box-shadow:0 0 40px rgba(0,0,0,.35); }
  /* The desktop icon-rail state is meaningless in a drawer: neutralize it
     (JS also strips .rail on phones — this is the CSS backstop). */
  .sidebar.rail{ width:min(84vw, 300px); }
  .sidebar.rail .wm, .sidebar.rail .sb-glabel, .sidebar.rail .sb-item .lbl,
  .sidebar.rail .sb-user .uw{ display:revert; }
  .sidebar.rail .sb-item{ justify-content:flex-start; padding:7px 9px; }
  .sidebar.rail .sb-head{ flex-direction:row; padding-left:14px; }
  .sidebar.rail .sb-ghead{ pointer-events:auto; }
  .sidebar .sb-toggle{ display:none; }   /* rail toggle is desktop-only */
  .botop{ padding:0 10px; gap:8px; }
  .botop .crumb{ display:none; }         /* hamburger + search need the room */
  /* The right cluster ran 38px past a 375px screen (right edge 413px) and
     sat the search on its 48px padding floor. The name and store pill were
     already d-md-none; the chevron goes too (the avatar alone opens the
     menu), and the currency toggle moves into that menu (.acct-ccy). */
  .botop .right{ gap:6px; }
  .acct-btn{ padding:4px; gap:0; }
  .acct-btn > .bi-chevron-down{ display:none; }
  /* The search, not the page, absorbs any shortfall: a flex item's default
     min-width:auto floor is what pushed the cluster off-screen. */
  .topsearch{ min-width:0; }
}

/* ---------------------------------------------- MOBILE CONTENT (≤767.98px) */
@media (max-width: 767.98px){
  .bo-main > main{ padding:12px !important; }
  /* iOS zooms any focused input under 16px — hold the line at 16. */
  .form-control, .form-select{ font-size:var(--text-xl); }
  .topsearch input{ font-size:var(--text-xl); }
  /* Cards flush to the edge feel roomier on a 375px screen. */
  .card{ border-radius:10px; }
}
/* Touch targets on any coarse-pointer device (phone AND tablet). */
@media (pointer: coarse){
  .btn-sm{ padding:.45rem .7rem; }
  .sidebar .sb-item{ padding:10px 9px; }
  .acct-pop a, .acct-pop button{ padding:11px 11px; }
}

/* Sidebar logo is now a link home (click Pultrack → dashboard). */
.sb-head .sb-brand{ display:flex; align-items:center; gap:8px; text-decoration:none; color:inherit; flex:1; min-width:0; }
.sb-head .sb-brand .wm{ white-space:nowrap; overflow:hidden; }

