/* ---- The application shell (style guide 6.1) --------------------------------
   Sidebar, topbar and the page column they frame. Loaded on every page, but
   every rule here is under `.page-app`, which `base.html` sets only when the
   request has a tenant. The pre-login pages therefore pay one small file and
   inherit none of its layout.

   Colour discipline is the token layer's (tokens.css): blue is chrome, and the
   one status this file signals is "waiting on you", which is amber.

   The shell's own measurements are named at the top rather than written into
   the rules that use them. They are structure, not spacing: a 248px sidebar
   and a 64px rail are two numbers the guide gives, and each of them is read
   in four places (the grid track, the drawer's width, the rail's state, the
   nav row's padding). Everything else on this page comes from tokens.css.
   -------------------------------------------------------------------------- */

/* This project has no global box-sizing reset, and the shell is full of
   "100% wide, with padding" controls that silently overflow under
   `content-box` (the page column overflowed the viewport by exactly its own
   padding). Scoped to the shell's own markup rather than made global: the
   page templates below were written against `content-box` and are not this
   phase's to re-lay-out. */
.side, .side *, .topbar, .topbar *, .page-app .page {
  box-sizing: border-box;
}

body.page-app {
  --sidebar-w: 248px;  /* the docked sidebar, and the drawer below 64rem */
  --rail-w: 64px;  /* the collapsed rail */
  --topbar-h: 56px;
  --nav-row-h: 36px;  /* one sidebar item */
  --nav-bar: 3px;  /* the accent bar at the left edge of the current item */
  --jump-w: 16.25rem;  /* the "Jump to" control: 260px */
  /* The page column. Wider than `--page-max`, which the shell will take when
     the step that re-lays-out the page bodies names it: narrowing every page
     by 12rem is not a change the shell may make on its own. */
  --page-w: 84rem;

  max-width: none;
  margin: 0;
  padding: 0;
  min-height: 100vh;
  background: var(--ground);
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
}
.shell__main {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* ---- Sidebar --------------------------------------------------------------- */

.side {
  background: var(--panel);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: var(--sp-20);
  padding: var(--sp-12) var(--sp-12) var(--sp-20);
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
}

.side__brand {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  height: var(--topbar-h);
  flex: none;
}
.side__mark { display: flex; flex: none; }
/* The mark's pulse line is cut in its ground, and the sidebar's ground is the
   panel rather than the page. */
.side__brand .brand-mark { --brand-cut: var(--panel); }
.side__mark .brand-mark { display: block; width: var(--sp-32); height: var(--sp-32); }
.side__name {
  font-weight: var(--fw-semibold);
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  color: var(--ink);
}
.side__toggle {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--slate);
  cursor: pointer;
  padding: var(--sp-4);
  border-radius: var(--radius-sm);
  line-height: 0;
  transition: background var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
.side__toggle:hover { background: var(--panel-sunk); color: var(--ink); }

/* The group's ledger line (7.1). `.legend` gives it the hairline, the micro
   title and the mono clause; what the sidebar adds is that the clause may be
   a product name of any length in a 248px column, so it truncates and the
   title never does. */
.side__group { margin: 0 0 var(--sp-8); }
/* The clause gives way, not the title (7.1): the group's name holds its line
   and a long product name truncates beside it, with the whole of it in the
   row's `title` (`sidebar.html`). The clause takes whatever the title leaves,
   which in a 248px column is most of it. */
.side__group .legend__title { white-space: nowrap; flex: none; }

.side__foot { margin-top: auto; }
.side__public {
  display: block;
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  color: var(--slate);
  text-decoration: none;
  border-top: 1px solid var(--line-soft);
  padding-top: var(--sp-12);
}
.side__public:hover { color: var(--accent); }

/* The reader's own account page, drawn only in the drawer. The topbar link
   that normally leads there is dropped below 64rem for width, and a member who
   was handed an initial password still has to be able to find the form. */
.side__account {
  display: none;
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  color: var(--slate);
  text-decoration: none;
  padding-top: var(--sp-8);
}
.side__account:hover { color: var(--accent); }

/* ---- Pickers (organization, product) --------------------------------------- */

/* Every level between `.picker` and the label has to be allowed to shrink,
   or a long product name pushes the chevron out of the sidebar. */
.picker, .picker form, .picker__menu { min-width: 0; }
.picker { display: grid; gap: var(--sp-4); }
.picker__label {
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  color: var(--slate);
  font-weight: var(--fw-medium);
}
.picker__btn {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  width: 100%;
  min-width: 0;
  height: var(--control-h);
  text-align: left;
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
  background: var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0 var(--control-pad-x);
  cursor: pointer;
  list-style: none;
  transition: border-color var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}
.picker__btn::-webkit-details-marker { display: none; }
.picker__btn:hover { border-color: var(--accent); background: var(--accent-soft); }
.picker__btn--fixed { cursor: default; }
.picker__btn--fixed:hover { border-color: var(--line); background: var(--panel-sunk); }
.picker__btn--empty { color: var(--slate); font-weight: var(--fw-medium); }
.picker__name {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.picker__chev { color: var(--slate); flex: none; }
.picker__menu[open] .picker__chev { transform: rotate(180deg); }

.picker__list {
  list-style: none;
  margin: var(--sp-4) 0 0;
  padding: var(--sp-4);
  display: grid;
  gap: 1px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop);
  max-height: 17rem;
  overflow-y: auto;
}
.picker__option {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  color: var(--ink-2);
  text-decoration: none;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  padding: var(--sp-8) var(--sp-12);
  cursor: pointer;
}
.picker__option:hover { background: var(--accent-soft); color: var(--accent-deep); }
.picker__option.is-on { color: var(--accent-deep); font-weight: var(--fw-semibold); }
.picker__option--more { color: var(--slate); border-top: 1px solid var(--line-soft); }

/* ---- Nav ------------------------------------------------------------------- */

.side .nav__items { display: grid; gap: 1px; }
.nav__item {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  height: var(--nav-row-h);
  padding: 0 var(--sp-12);
  border-radius: var(--radius-md);
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  font-weight: var(--fw-medium);
  color: var(--ink-2);
  text-decoration: none;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.nav__item:hover { background: var(--panel-sunk); color: var(--ink); }
/* The current item is marked three ways: the ground, the ink, and the bar at
   the row's left edge. The bar is an inset shadow rather than a border or a
   pseudo-element, so it costs the row no width and no extra box. */
.nav__item.is-on {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset var(--nav-bar) 0 0 0 var(--accent);
}
/* A section whose route does not exist yet: present, explained, not a link. */
.nav__item--off { color: var(--neutral); cursor: not-allowed; }
.nav__item--off:hover { background: none; color: var(--neutral); }

.nav__ico { flex: none; color: var(--slate); }
.nav__item:hover .nav__ico { color: var(--ink-2); }
.nav__item.is-on .nav__ico { color: var(--accent); }
.nav__item--off .nav__ico { color: var(--neutral); }
.nav__label {
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Amber is "waiting on you" (tokens.css). Quiet counts are just counts. */
.nav__count {
  flex: none;
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  background: var(--warn-bright);
  color: var(--on-warn);
  border-radius: var(--radius-pill);
  padding: var(--sp-4) var(--sp-8);
  min-width: var(--sp-20);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.nav__count--quiet { background: var(--neutral-soft); color: var(--slate); }

/* ---- The collapsed rail (6.1) -----------------------------------------------
   64px of icons. The current item keeps its ground and its bar; everything
   that needs words goes. The labels are hidden rather than removed and every
   row also carries `title` and `aria-label` (`nav_item.html`), so the rail is
   the same nav to a screen reader as the sidebar is.

   The whole state is a desktop one, guarded by the width where the sidebar
   stops being docked. Below that the sidebar is a drawer, and a remembered
   collapse would otherwise open the drawer 64px wide with nothing in it that
   says how to widen it again. */

@media (min-width: 64.01rem) {
  body.page-app.is-collapsed { --sidebar-w: var(--rail-w); }
  .page-app.is-collapsed .side__name,
  .page-app.is-collapsed .picker,
  .page-app.is-collapsed .side__group,
  .page-app.is-collapsed .side__foot,
  .page-app.is-collapsed .nav__count { display: none; }
  .page-app.is-collapsed .nav__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .page-app.is-collapsed .nav__item { justify-content: center; padding: 0; }
  /* 64px of rail does not hold the mark, the wordmark and the toggle. The
     toggle is the one that has to stay: it is the way back out. */
  .page-app.is-collapsed .side__mark { display: none; }
  .page-app.is-collapsed .side__brand { justify-content: center; }
  .page-app.is-collapsed .side__toggle { margin-left: 0; }
}

/* ---- Topbar ---------------------------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--sp-20);
  height: var(--topbar-h);
  padding: 0 var(--sp-24);
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  margin: 0;
}

.topbar__drawer {
  display: none;
  background: var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink-2);
  padding: var(--sp-4) var(--sp-8);
  cursor: pointer;
  line-height: 0;
}

.crumbs {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  color: var(--slate);
  min-width: 0;
}
.crumbs a { color: inherit; text-decoration: none; }
.crumbs a:hover { color: var(--accent); }
.crumbs__sep { opacity: 0.45; }
.crumbs__product {
  color: var(--ink);
  font-weight: var(--fw-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.topbar__right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-12);
}

/* The right group never shrinks. Between the drawer breakpoint (64rem) and a
   comfortable desktop the sidebar is still docked, which leaves the topbar
   about 776px at 1024, and with the group allowed to shrink "New case" and
   "Log out" each wrapped onto two lines on every workspace page. What gives
   instead is "Jump to" below, which is not built yet, and then the
   breadcrumb's product name, which already ellipsises. */
.topbar__right > * { flex: none; }
.topbar__right .btn,
.topbar__right .linklike { white-space: nowrap; }

/* "Jump to" (6.1): the one control here that has no route yet. It renders as
   the control it will be, disabled, saying so in its title. */
.topbar__jump {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  width: var(--jump-w);
  height: var(--control-h);
  padding: 0 var(--control-pad-x);
  background: var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.topbar__jump-ico { color: var(--slate); flex: none; }
.topbar__jump-input {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  color: var(--ink);
  background: none;
  border: 0;
  padding: 0;
}
.topbar__jump-input::placeholder { color: var(--placeholder); }
.topbar__jump-input:disabled { cursor: not-allowed; }

/* …and below a comfortable desktop "Jump to" goes, because it is the one
   control here that does nothing yet. It has to come after the rule above,
   not before it: both are one class, so source order is what decides. */
@media (max-width: 80rem) {
  .topbar { gap: var(--sp-12); padding-inline: var(--sp-20); }
  .topbar__jump { display: none; }
  /* The breadcrumb is the other thing that gives: the organization name is
     one token and wrapped it onto a second line. */
  .crumbs { overflow: hidden; }
  .crumbs__org { white-space: nowrap; }
}

.user-menu {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  font-size: var(--fs-ui);
}
/* Two account actions now sit here, and at the menu's own gap two
   link-coloured words read as one control, so the pair is spaced wider than
   the avatar is from the first of them. */
.user-menu__actions {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-16);
}
.avatar {
  width: var(--sp-32);
  height: var(--sp-32);
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent-deep);
  display: grid;
  place-items: center;
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  font-family: var(--font-mono);
}

/* ---- Page column ----------------------------------------------------------- */

.page-app .page {
  padding: var(--sp-24) var(--sp-24) var(--sp-48);
  max-width: var(--page-w);
}
.page-app .site-messages { margin-inline: 0; }
.page-app .site-messages > .notice:first-child { margin-top: 0; }
.page-app .site-messages > .notice:last-child { margin-bottom: var(--sp-20); }
.page-app h1 { margin-top: 0; }

@media (min-width: 80rem) {
  .page-app .page { padding: var(--sp-32) var(--sp-32) var(--sp-48); }
}

/* ---- Narrow: the sidebar becomes a drawer (6.5, 9) --------------------------
   Below 64rem the sidebar leaves the grid and slides in over the page.
   `sidebar.js` traps focus inside it, returns focus to the button that opened
   it, and marks the page behind it `inert`; with the script absent the drawer
   never opens and every page is the one-column layout below. */

@media (max-width: 64rem) {
  body.page-app { grid-template-columns: 1fr; }
  .side {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--sidebar-w);
    z-index: var(--z-drawer);
    transform: translateX(-100%);
    transition: transform var(--dur-3) var(--ease);
    box-shadow: var(--shadow-drawer);
  }
  body.page-app.is-drawer-open .side { transform: translateX(0); }
  .topbar__drawer { display: inline-flex; }
  .topbar { gap: var(--sp-8); padding-inline: var(--sp-20); }
  /* A phone's topbar holds the drawer, the primary action and the account
     controls, and nothing else. The breadcrumb repeats the page's own
     heading and "Jump to" is not built yet, so those two are what go. */
  .crumbs, .topbar__jump, .avatar { display: none; }
  .page-app .page { padding: var(--sp-20) var(--sp-20) var(--sp-32); }
}

/* ---- Phone: the account link changes places ---------------------------------
   "Change password" is the fourth control in the topbar's right group, and the
   group cannot shrink (every child is `flex: none` and nowrap, above). At a
   390px viewport the row measured 420px and pushed "Log out" off the screen,
   so on a phone the link moves into the drawer instead, where `.side__foot`
   already has a column of its own. The two rules are one swap and belong to
   one breakpoint: the row needs about 420px with the link in it, and 30rem is
   the first round width comfortably above that. Above it the topbar carries
   the link and the drawer does not, so it is never offered twice. */

@media (max-width: 30rem) {
  .user-menu__pw { display: none; }
  .side__account { display: block; }
}

/* ---- The signed-in footer --------------------------------------------------
   A compact row of the same two brand links used on public pages.
   `templates/partials/app_footer.html` owns the wrapper, while base.css owns
   the shared logo layout.

   Place the footer in the last grid column: beside the sticky sidebar on
   desktop, and across the single column on mobile. Spanning both desktop
   columns lets the sidebar cover the AuCRA Shield link while scrolling. */

.app-footer {
  grid-column: -2 / -1;
  padding: var(--sp-20) var(--sp-24) var(--sp-24);
  border-top: 1px solid var(--line-soft);
  color: var(--ink-2);
}

@media (max-width: 64rem) {
  .app-footer { padding: var(--sp-20); }
}
