/* The client dashboard shell - the LEFT sidebar and the two-column layout
 * that wrap every signed-in ("app") page. Rendered by js/app-shell.js,
 * which is included AFTER js/nav-component.js on a page carrying
 * <body data-app-page="1">.
 *
 * Why this exists (owner's decision, 7 Sep 2026): the public landing site
 * stays exactly as it is; after login the experience is a dashboard with a
 * sidebar on the left and the page on the right, same typography. The
 * signed-in links (My Deals, Owner) used to be revealed INSIDE the centred
 * top bar after /api/auth/me resolved, which shoved every other link
 * sideways on every page load. They live here now, and the top bar is
 * the slim variant nav-component.js renders on app pages.
 *
 * Design rules:
 *  - The shell adds ONLY the sidebar and the layout. The top bar is still
 *    the one shared component - nothing here is a second nav bar.
 *  - The sidebar is position:fixed and the body gets a matching
 *    padding-left. A CSS grid on <body> was rejected: every page has a
 *    different set of direct body children (gates, modals, footers,
 *    scripts), and a grid would have made each of them a grid item with
 *    its own placement rules. Padding leaves the page's own flow untouched
 *    and the sticky top bar keeps working inside the remaining width.
 *  - The design tokens are copied from the :root block the pages share
 *    (plot-plan.html) but SCOPED to the shell's own elements rather than
 *    declared on :root. This stylesheet loads after each page's inline
 *    style, so a :root block here would win the cascade and silently
 *    recolour pages whose palette differs slightly (admin.html). Scoping
 *    gives the shell identical typography without touching the host page.
 */
.app-sidebar{
  --navy-950:#070B14; --navy-900:#0D1526; --navy-850:#111B30; --navy-800:#15203A;
  --navy-line:#1E2A45; --navy-600:#2A3A5E;
  --gold-300:#F0DBA8; --gold-500:#D4AF6A;
  --ivory-100:#F2F5FA; --slate-400:#8A96AC; --slate-500:#5E6B84;
  --emerald-400:#3ECF8E; --rose-400:#F0647E;
  --font-display:'Space Grotesk', system-ui, sans-serif;
  --font-body:'Inter', system-ui, -apple-system, sans-serif;
  --app-sidebar-w:250px;
  box-sizing:border-box;
  font-family:var(--font-body);
  color:var(--ivory-100);
  font-size:14px;
  line-height:1.4;
}
.app-sidebar *, .app-sidebar *::before, .app-sidebar *::after{box-sizing:border-box;}
.app-sidebar .app-hidden{display:none !important;}

/* Two columns: the fixed sidebar on the left, the page in the rest. The
 * width is repeated on body because custom properties set on the sidebar
 * are not visible to its parent.
 *
 * TWO selectors, on purpose. body.app-shell is set by js/app-shell.js
 * when it mounts the sidebar. But that script is a separate blocking
 * fetch that runs AFTER nav-component.js has already inserted the top
 * bar, and the parser can yield (and paint) between the two - measured
 * on /app at 1280px: the Dashboard chip painted at x=188 and then jumped
 * to x=438 when the padding arrived. The :has() rule closes that gap
 * without a script: the slim bar (nav.topnav-slim) is rendered under
 * exactly the same condition as the sidebar (app page + cached session),
 * so the moment it exists the column is reserved, in the same style
 * pass, before anything is painted. The ::before box paints the column
 * itself for the instant before the sidebar element arrives, so the
 * column does not flash from page background to sidebar background. */
body.app-shell,
body[data-app-page="1"]:has(nav.topnav-slim){padding-left:250px;}
body[data-app-page="1"]:has(nav.topnav-slim)::before{
  content:""; position:fixed; top:0; left:0; bottom:0; width:250px; z-index:39;
  background:#0D1526; border-right:1px solid #1E2A45; /* --navy-900 / --navy-line, pinned: body has no shell tokens */
}
.app-sidebar{
  position:fixed; top:0; left:0; bottom:0; width:var(--app-sidebar-w);
  background:var(--navy-900); border-right:1px solid var(--navy-line);
  display:flex; flex-direction:column; overflow-y:auto;
  /* Below the sticky top bar (50) is deliberate: the bar is the shared
     component and must never sit under anything. Modals are 1000+. */
  z-index:40;
}

/* Head: where you are, and who you are. The brand stays in the top bar. */
.app-sidebar .app-head{padding:18px 18px 12px; border-bottom:1px solid var(--navy-line);}
.app-sidebar .app-home{
  display:flex; align-items:center; gap:10px; text-decoration:none; color:var(--ivory-100);
  font-family:var(--font-display); font-weight:700; font-size:16px; padding:8px 10px; border-radius:10px;
}
.app-sidebar .app-home:hover{background:var(--navy-850);}
.app-sidebar .app-home[aria-current="page"]{background:var(--navy-850); color:var(--gold-300);}
.app-sidebar .app-home svg{width:18px; height:18px; flex:none;}
.app-sidebar .app-user{padding:8px 10px 0; font-size:12px; color:var(--slate-400); line-height:1.45;}
.app-sidebar .app-user b{display:block; color:var(--ivory-100); font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.app-sidebar .app-user span{display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}

/* Sections */
.app-sidebar .app-sections{flex:1; padding:10px 12px 16px;}
.app-sidebar .app-group{margin:0 0 14px;}
.app-sidebar .app-group h2{
  font-family:var(--font-body); font-size:10.5px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--slate-500); margin:0; padding:8px 10px 4px;
}
.app-sidebar .app-group a{
  display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:9px;
  color:var(--slate-400); text-decoration:none; font-size:13.5px; white-space:nowrap;
  border-left:2px solid transparent; transition:color .15s, background .15s;
}
.app-sidebar .app-group a:hover{color:var(--ivory-100); background:var(--navy-850);}
.app-sidebar .app-group a[aria-current="page"]{
  color:var(--gold-300); font-weight:600; background:var(--navy-850); border-left-color:var(--gold-500);
}
.app-sidebar .app-group a:focus-visible, .app-sidebar .app-home:focus-visible, .app-sidebar .app-strip-toggle:focus-visible{
  outline:2px solid var(--gold-500); outline-offset:2px;
}
/* The owner section is the one part that waits for the server: the
   sidebar is drawn from the cached session, but the Owner section is
   shown only once /api/auth/me confirms the permission. */
.app-sidebar .app-group.app-owner h2{color:var(--gold-500);}

.app-sidebar .app-foot{padding:12px 18px 18px; border-top:1px solid var(--navy-line); font-size:12px; color:var(--slate-500);}
.app-sidebar .app-foot a{color:var(--slate-400); text-decoration:none;}
.app-sidebar .app-foot a:hover{color:var(--ivory-100);}

/* The collapsed strip. Hidden on desktop; below the breakpoint it is the
   whole visible sidebar until the toggle opens the sections. */
.app-sidebar .app-strip{display:none;}

/* ONE breakpoint for the shell (1000px). Below it the sidebar becomes a
 * strip across the top of the page with a toggle - not a second nav bar:
 * it holds the dashboard title and one button, and the sections open
 * underneath it in the page flow (no overlay to fight the top bar's
 * hamburger). */
@media (max-width:1000px){
  body.app-shell,
  body[data-app-page="1"]:has(nav.topnav-slim){padding-left:0;}
  body[data-app-page="1"]:has(nav.topnav-slim)::before{display:none;}
  .app-sidebar{
    position:static; width:auto; height:auto; overflow:visible;
    border-right:none; border-bottom:1px solid var(--navy-line);
  }
  .app-sidebar .app-head{display:none;}
  .app-sidebar .app-strip{
    display:flex; align-items:center; gap:12px; padding:8px 16px; min-height:44px;
  }
  .app-sidebar .app-strip-title{
    font-family:var(--font-display); font-weight:700; font-size:14px; color:var(--ivory-100); text-decoration:none;
  }
  .app-sidebar .app-strip-title[aria-current="page"]{color:var(--gold-300);}
  .app-sidebar .app-strip-current{
    flex:1; min-width:0; font-size:12.5px; color:var(--slate-400); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .app-sidebar .app-strip-current::before{content:"\00B7"; margin-right:8px; color:var(--slate-500);}
  .app-sidebar .app-strip-toggle{
    flex:none; background:none; border:1px solid var(--navy-600); border-radius:9px; color:var(--ivory-100);
    font:inherit; font-size:12.5px; font-weight:600; padding:6px 12px; cursor:pointer;
  }
  .app-sidebar .app-strip-toggle[aria-expanded="true"]{border-color:var(--gold-500); color:var(--gold-300);}
  .app-sidebar .app-sections{display:none; padding:6px 10px 12px; border-top:1px solid var(--navy-line);}
  .app-sidebar.app-open .app-sections{display:grid; grid-template-columns:repeat(auto-fill, minmax(220px, 1fr)); gap:0 16px;}
  .app-sidebar .app-group{margin:0 0 8px;}
  .app-sidebar .app-foot{display:none;}
}
