/* ─────────────────────────────────────────────────────────────────────────────
   BetterRoofing's side of the BPG app shell (#1461).

   BPG.Shell.Web owns the sidebar (bpg-shell.css, loaded before this file). This file owns what the
   package deliberately does not: the top bar across the main column (search + Calendar), the host
   that holds it, and the few places the shell's frame needs BetterRoofing's page conventions.

   Colour comes from /css/theme.css tokens only. Loaded after header.css, whose .search-wrapper /
   .calendar-btn / .badge-notification rules are still live for the adminBPG header, so the top
   bar's selectors are scoped under .app-topbar and out-weigh them.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── Admin Dashboard is for BPG admins ───────────────────────────────────────
   The sidebar is server-rendered for everyone, so the BPG-admin-only row ships hidden here and
   shell-chrome.ts adds data-revealed once /api/auth/me says so. Never painted for anyone else. */
.bpg-shell [data-nav-key="adminBPG"]:not([data-revealed]) {
  display: none !important;
}

/* ── Anything in the sidebar with [hidden] stays hidden ───────────────────────
   The shell's nav rows are display:flex, which beats the UA's [hidden] rule. shell-chrome.ts hides
   a gated nav item, an empty section and the BPG-admin-only Admin Dashboard with the attribute.
   Scoped to the sidebar: page content that styles its own [hidden] (Smart Lists' .smart-view-dirty
   keeps its width with visibility:hidden) must keep doing so. */
.bpg-shell-sidebar [hidden] {
  display: none !important;
}

/* ── BPG Marketplace sits just above the profile chip ────────────────────────
   ShellNavBuilder puts it in the nav's last section, and this pushes that section to the bottom of
   the nav. A nav taller than the sidebar scrolls as before, with Marketplace as its last row. */
.bpg-shell-nav {
  display: flex;
  flex-direction: column;
}

.bpg-shell-nav > .bpg-shell-nav__section:last-child {
  margin-top: auto;
  padding-top: 1rem;
}

/* ── The company's logo in the profile chip ──────────────────────────────────
   shell-chrome.ts puts the tenant's logo where the shell draws initials (BetterGather's chip). A logo
   is its own artwork, so it gets no circle or border, and it is fitted whole rather than cropped. */
.bpg-shell-user__avatar.has-logo {
  background: transparent;
  border-color: transparent;
  border-radius: 6px;
  overflow: hidden;
}

/* No logo: the icon the company picked, at a size that reads, without the initials' circle. */
.bpg-shell-user__avatar.has-company-icon {
  background: transparent;
  border-color: transparent;
  font-size: 1.125rem;
  line-height: 1;
}

.bpg-shell-user__avatar.has-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ── Notch ────────────────────────────────────────────────────────────────────
   Every page sets viewport-fit=cover, so a phone held sideways draws the page under the notch. The
   sidebar (or its rail) is what sits at the left edge on a tablet or a sideways phone: its background
   runs to the screen edge and its own content is inset, as the header did (layout-safe-area.css).
   The widths grow by the inset so the nav keeps its room. Zero, so unchanged, wherever there is no notch.
   On a phone upright the sidebar is the off-canvas drawer, which the package already pads itself. */
:root {
  --bpg-shell-width: calc(260px + env(safe-area-inset-left, 0px));
  --bpg-shell-width-collapsed: calc(64px + env(safe-area-inset-left, 0px));
}

.bpg-shell-sidebar {
  padding-left: env(safe-area-inset-left, 0px);
}

/* ── Box model of the chrome ──────────────────────────────────────────────────
   The package's CSS is written for border-box (every host resets `*`). Some BetterRoofing pages
   (the dashboard) never do, and the sidebar came out 261px wide and the top bar 67px tall. Scoped to
   the chrome: the page content inside .bpg-shell__main keeps whatever box model its page asks for. */
.bpg-shell-sidebar,
.bpg-shell-sidebar *,
.bpg-shell-sidebar *::before,
.bpg-shell-sidebar *::after,
.bpg-shell-navbar,
.bpg-shell-navbar *,
.bpg-shell-placeholder,
.app-topbar,
.app-topbar *,
.app-topbar *::before,
.app-topbar *::after {
  box-sizing: border-box;
}

/* ── The frame owns the page edge ────────────────────────────────────────────
   Pages that never load a stylesheet resetting <body> (My Day, Better Pages, the dashboard) kept the
   browser's 8px margin, which the old header sat inside. A sidebar flush to the screen edge cannot. */
body:has(> .bpg-shell) {
  margin: 0;
}

/* ── The column is a block, like the <body> the pages were written for ──────────
   The package makes .bpg-shell__main a flex column. A page wrapper written as `max-width: N; margin: 0 auto`
   (BetterRoofing's .container and most page shells) is then shrunk to its content and centred, instead of
   filling up to N as it does in a block <body>. */
.bpg-shell__main {
  display: block;
}

/* ── Stacking ────────────────────────────────────────────────────────────────
   The page keeps the z-indexes it always had (the sticky top bar at 100, the settings quick-nav at 200,
   popovers and modals at 1000 and up), and the sidebar is placed against them:
   - Desktop and the tablet rail: 20, above in-flow page content so the profile drop-up of a collapsed rail
     (15rem wide, it opens over the page) is not painted under it, and below every modal and popover, so a
     full-screen overlay still covers the sidebar.
   - A phone drawer and an expanded tablet rail: 2500, with the scrim at 2400. They float over the whole
     page, the top bar and the settings quick-nav included (the package's own 50 / 40 would sit under both). */
@media (min-width: 768px) {
  .bpg-shell-sidebar:not([data-overlay="true"]) {
    z-index: 20;
  }
}

@media (max-width: 767px) {
  .bpg-shell-sidebar {
    z-index: 2500;
  }
}

.bpg-shell-sidebar[data-overlay="true"] {
  z-index: 2500;
}

.bpg-shell-scrim {
  z-index: 2400;
}

/* While a BPG admin impersonates a tenant the banner is position:fixed over the top of the viewport
   (header.ts pads <body> by its height and publishes --banner-height): the sticky sidebar starts
   below it instead of hiding its brand row. 0px otherwise. */
@media (min-width: 768px) {
  .bpg-shell-sidebar {
    top: var(--banner-height, 0px);
    height: calc(100dvh - var(--banner-height, 0px));
  }
}

/* ── The sidebar's place before the markup arrives (static pages) ─────────────
   shell-chrome.ts builds the frame before the page's own scripts run and fetches the sidebar after,
   so this holds exactly the width the sidebar will take and the page lays out once. Same widths and
   breakpoints as bpg-shell.css: 260px, the 64px rail from 768 to 900px, nothing on a phone. */
.bpg-shell-placeholder {
  flex: 0 0 var(--bpg-shell-width);
  width: var(--bpg-shell-width);
  background: var(--bg-secondary);
  border-right: 1px solid var(--border-light);
  box-sizing: border-box;
}

.bpg-shell-placeholder.is-collapsed {
  flex-basis: var(--bpg-shell-width-collapsed);
  width: var(--bpg-shell-width-collapsed);
}

@media (min-width: 768px) and (max-width: 900px) {
  .bpg-shell-placeholder {
    flex-basis: var(--bpg-shell-width-collapsed);
    width: var(--bpg-shell-width-collapsed);
  }
}

@media (max-width: 767px) {
  .bpg-shell-placeholder {
    display: none;
  }
}

/* ── The top bar's host ───────────────────────────────────────────────────────
   #header-container is kept as the host so the three --header-height publishers (settings, marketing
   studio, prospecting map) and pending-deletion-notice keep working unchanged. Sticky, below the
   impersonation banner. Pages that pin it themselves (marketing-studio.css) say the same thing. */
.app-topbar-host {
  position: sticky;
  top: var(--banner-height, 0px);
  z-index: 100;
  flex: 0 0 auto;
}

/* ── The top bar ──────────────────────────────────────────────────────────── */
.app-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  box-sizing: border-box;
  min-height: 56px;
  padding: 8px 24px;
  /* --ios-safe-top is injected by the native shell (env() reads 0 there); env() covers a browser. */
  padding-top: max(8px, var(--ios-safe-top, env(safe-area-inset-top, 0px)));
  /* Beside the sidebar the left inset is the sidebar's to clear; the bar's own left edge is only on the
     screen's edge on a phone (below). */
  padding-left: 24px;
  padding-right: max(24px, env(safe-area-inset-right, 0px));
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-light);
}

/* BPG.Shell.Web docks its phone hamburger here (the [data-app-nav-slot] contract). Empty and invisible
   above 767px, where the button hides itself by class. */
.app-topbar__nav-slot {
  display: contents;
}

/* header.css hides .search-wrapper below 1024px (the old header's drawer carried a second box). The top
   bar's is the only one, and it shows at every width. */
.app-topbar .search-wrapper {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  max-width: 560px;
  min-width: 0;
}

.app-topbar .search-box {
  width: 100%;
  max-width: none;
  min-height: 36px;
  box-sizing: border-box;
}

.app-topbar__calendar {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  margin-left: auto;
  min-height: 36px;
  padding: 6px 12px;
  border: 1px solid var(--border-light);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.2s;
}

.app-topbar__calendar:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}

.app-topbar__calendar:focus-visible {
  outline: 2px solid var(--input-focus-border);
  outline-offset: 2px;
}

.app-topbar__calendar .lc {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
}

/* Self-contained, so the bar does not depend on header.css's copy (it is shared with the adminBPG header). */
.app-topbar .badge-notification {
  position: absolute;
  top: -8px;
  right: -8px;
  z-index: 10;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border: 2px solid var(--bg-secondary);
  border-radius: 10px;
  background: var(--btn-danger-bg);
  color: var(--btn-danger-text);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

.app-topbar .badge-notification.show {
  display: flex;
}

/* The nav is a drawer on a phone, so the bar starts at the screen's edge. */
@media (max-width: 767px) {
  .app-topbar {
    padding-left: max(12px, env(safe-area-inset-left, 0px));
  }
}

/* A phone keeps the icon and the badge; the word is the first thing to go. */
@media (max-width: 640px) {
  .app-topbar {
    gap: 8px;
    padding-right: max(12px, env(safe-area-inset-right, 0px));
  }

  .app-topbar__calendar-label {
    display: none;
  }

  .app-topbar__calendar {
    padding: 6px 10px;
  }
}

/* ── Pages fills the column (#1490) ──────────────────────────────────────────
   /pages mounts the Better Pages app (#bp-root, BPG.Pages.Web) inside the layout's <main class="container">,
   whose 24px gutter and 1400px cap left the Pages list floating 24px off the sidebar and the top bar. Here the
   Pages list sits flush against both, a second sidebar beside the first, and the app fills what is left of the
   screen without a page scroll. The column is a flex column only on this page; the package's own height
   (calc(100vh - 60px), written for an older 60px header) gives way to the space under the top bar.
   BetterGather's Pages host does the same (project-detail.css, body[data-nav-active="better-pages"]).
   The shell's own min-height (100dvh) is cut by the banner too: while the impersonation banner pads <body>, a
   100dvh shell under it would scroll the page by the banner's height. */
.bpg-shell:has(> .bpg-shell__main > main > #bp-root) {
  min-height: calc(100vh - var(--banner-height, 0px));
  min-height: calc(100dvh - var(--banner-height, 0px));
}

.bpg-shell__main:has(> main > #bp-root) {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--banner-height, 0px));
  height: calc(100dvh - var(--banner-height, 0px));
  min-height: 0;
}

.bpg-shell__main > main.container:has(> #bp-root) {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  max-width: none;
  margin: 0;
  /* The gutter goes. Beside the sidebar the left inset is the sidebar's; on a phone, where the sidebar is a
     drawer, the column clears it itself (below). The right inset is not padding here: it is on the app's
     own surfaces (next rule), so they still reach the screen edge. */
  padding: 0;
}

@media (max-width: 767px) {
  .bpg-shell__main > main.container:has(> #bp-root) {
    padding-left: env(safe-area-inset-left, 0px);
  }
}

.bpg-shell__main > main.container > #bp-root.bp-shell {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
}

/* The right notch on a sideways phone: each surface that runs to the app's right edge paints its own
   background under a transparent border of the inset (the .smart-list-panel pattern in
   layout-safe-area.css), so the background reaches the screen edge and only the content is inset. These are
   the editor's bars and body (the body is the white page on a phone) and the workspaces home. A 0px border
   at inset 0, so nothing moves on a desktop or an upright phone. */
.bpg-shell__main > main.container > #bp-root :is(.bp-home, .bp-share-status, .bp-drift-banner, .bp-editor-body) {
  border-right: env(safe-area-inset-right, 0px) solid transparent;
}

/* The phone top bar (.bp-mobile-topbar: workspace pill, search, ⋮) is the first row INSIDE the editor body, so
   the body's border above stopped the bar's 1px bottom line 47px short of the screen edge (#1496 review). The
   bar reaches back over that border by the inset and adds the inset to its own right padding (the package's
   0.5rem, better-pages.css), so the line runs to the edge and the ⋮ still clears the notch. Padding, not a
   transparent border: a 47px right border meeting the 1px line would cut it off on the diagonal. Same media
   query as the package's row; at inset 0 the margin is 0 and the padding is the package's, so nothing moves. */
@media (max-width: 860px), (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
  .bpg-shell__main > main.container > #bp-root .bp-editor-body > .bp-mobile-topbar:not(.bp-mobile-topbar--hosted) {
    margin-right: calc(-1 * env(safe-area-inset-right, 0px));
    padding-right: calc(0.5rem + env(safe-area-inset-right, 0px));
  }
}
