/* =============================================================================
   SHELL — header, collapsible side nav, profile menu, table row actions.
   Additive only: every value still derives from tokens.css. This file extends
   the existing "modern ledger" system to the app-shell pieces introduced by
   FRONTEND-DIRECTION.md (header + collapsible left nav); it does not touch
   components.css or forms.css.
============================================================================= */

:root {
  --sidebar-w-collapsed: 60px;
  --header-h: 60px;
}

.icon {
  width: 1.15em;
  height: 1.15em;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* ------------------------------------------------------------------ header */
/* Full-width bar above the sidebar/content grid. Same white ground and
   hairline device as the sidebar, so header and rail read as one instrument
   rather than two competing surfaces. */
.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  height: var(--header-h);
  padding: 0 var(--sp-5);
  background: var(--c-surface);
  border-bottom: var(--rule-hair);
}

.app-header__brand {
  display: flex;
  align-items: center;
  color: inherit;
  text-decoration: none;
}
.app-header__brand img {
  display: block;
  height: 26px;
  width: auto;
}

/* --------------------------------------------------------------- profile */
.profile {
  position: relative;
}

/* The trigger is a <summary> inside <details>: native disclosure, keyboard-
   operable, zero JavaScript. Suppress the default marker so it reads as the
   same button shape .profile__trigger was designed for. */
.profile summary.profile__trigger { list-style: none; cursor: pointer; }
.profile summary.profile__trigger::-webkit-details-marker,
.profile summary.profile__trigger::marker { display: none; }

.profile__trigger {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  height: var(--control-h);
  padding: 0 var(--sp-2) 0 0;
  border: none;
  background: transparent;
  color: var(--c-ink);
  font: inherit;
  cursor: pointer;
  border-radius: var(--r-sm);
}
.profile__trigger:hover { background: var(--c-surface-alt); }
.profile__trigger:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-sm); }
.profile__trigger .icon { color: var(--c-ink-muted); width: 1em; height: 1em; }

.profile__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--c-ink);
  color: var(--c-on-primary);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.02em;
}

.profile__menu {
  position: absolute;
  top: calc(100% + var(--sp-2));
  right: 0;
  z-index: 110;
  width: 260px;
  background: var(--c-surface);
  border: var(--rule-hair);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-pop);
  padding: var(--sp-2) 0;
}
.profile__menu[hidden] { display: none; }

.profile__identity {
  padding: var(--sp-2) var(--sp-4) var(--sp-3);
  border-bottom: var(--rule-hair);
  margin-bottom: var(--sp-2);
}
.profile__name { font-weight: var(--fw-semibold); color: var(--c-ink); }
.profile__email {
  display: block;
  font-size: var(--fs-sm);
  color: var(--c-ink-muted);
  margin-top: 2px;
  word-break: break-all;
}
.profile__org {
  display: block;
  font-size: var(--fs-xs);
  color: var(--c-ink-muted);
  margin-top: var(--sp-2);
}

.profile__item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-2) var(--sp-4);
  border: none;
  background: transparent;
  color: var(--c-ink);
  font: inherit;
  font-size: var(--fs-base);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.profile__item:hover { background: var(--c-primary-tint); }
.profile__item:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-sm); }
.profile__item .icon { color: var(--c-ink-muted); }

/* ------------------------------------------------------------- side nav */
/* Header owns the brand now, so the rail holds navigation only. Width is
   driven by a CSS var so collapsing is one property change, not a layout
   rewrite. --nav-w lives on .shell (the grid container); it can only be
   toggled by adding/removing .is-collapsed on the .shell__nav child, so the
   :has() below reads that state back up rather than declaring --nav-w twice
   in two places that could drift. */
.shell {
  --nav-w: var(--sidebar-w);
  grid-template-columns: var(--nav-w) 1fr;
  min-height: calc(100vh - var(--header-h));
  transition: grid-template-columns 0.15s ease;
}
.shell:has(.shell__nav.is-collapsed) {
  --nav-w: var(--sidebar-w-collapsed);
}
.shell__nav {
  display: flex;
  flex-direction: column;
  padding: var(--sp-4) var(--sp-3);
  transition: padding 0.15s ease;
}
.shell__nav-items { display: flex; flex-direction: column; gap: var(--sp-1); flex: 1; }

.shell__nav a.nav-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  white-space: nowrap;
  overflow: hidden;
}
.shell__nav a.nav-item .icon { color: var(--c-ink-muted); }
.shell__nav a.nav-item[aria-current="page"] .icon { color: var(--c-primary); }

.shell__nav-label {
  overflow: hidden;
  text-overflow: ellipsis;
}
.shell__nav.is-collapsed .shell__nav-label { display: none; }
.shell__nav.is-collapsed a.nav-item { justify-content: center; padding-left: var(--sp-2); padding-right: var(--sp-2); }

/* ------------------------------------------------------------- nav group */
/* Grouped navigation items under a collapsible header. Uses native <details>/
   <summary> so the open state is already exposed to assistive technology. */
.nav-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.nav-group-header {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  color: var(--c-ink-muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.05em;
  border: none;
  background: transparent;
  text-align: left;
  list-style: none;
}

.nav-group-header::-webkit-details-marker,
.nav-group-header::marker { display: none; }

.nav-group-header:hover {
  background: var(--c-surface-alt);
  color: var(--c-ink);
}
.nav-group-header:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-sm); }

.nav-group-header .group-icon {
  color: currentColor;
  opacity: 0.7;
  transition: all 0.15s ease;
}

.nav-group[open] .nav-group-header .group-icon {
  color: var(--c-primary);
  opacity: 1;
}

.nav-group-header .chevron {
  margin-left: auto;
  color: currentColor;
  opacity: 0.5;
  transition: transform 0.15s ease;
}

.nav-group[open] .nav-group-header .chevron {
  transform: rotate(90deg);
  opacity: 0.8;
}

.nav-group-items {
  display: none;
  flex-direction: column;
  gap: var(--sp-1);
  padding-left: var(--sp-4);
}

.nav-group[open] .nav-group-items {
  display: flex;
}

.nav-group .nav-item {
  font-size: var(--fs-sm);
}

/* Collapsed sidebar: group header is hidden, items show as centered icons */
.shell__nav.is-collapsed .nav-group-header {
  display: none;
}

.shell__nav.is-collapsed .nav-group[open] .nav-group-items {
  display: flex;
  padding-left: 0;
}

.shell__nav.is-collapsed .nav-group .nav-item {
  justify-content: center;
  padding-left: var(--sp-2);
  padding-right: var(--sp-2);
}

/* Collapsed rail: active item gets the primary fill with icon knocked out */
.shell__nav.is-collapsed .nav-group .nav-item[aria-current="page"] {
  background: var(--c-primary);
  border-radius: var(--r-sm);
}

.shell__nav.is-collapsed .nav-group .nav-item[aria-current="page"] .icon {
  color: var(--c-on-primary);
}

/* Mobile: show group header and items inline */
@media (max-width: 900px) {
  .shell__nav .nav-group-header {
    display: flex !important;
    padding: var(--sp-2);
  }

  .shell__nav .nav-group-items {
    display: none !important;
    position: absolute;
    top: 100%;
    left: 0;
    background: var(--c-surface);
    border: var(--rule-hair);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-pop);
    padding: var(--sp-2);
    z-index: 100;
    min-width: 200px;
  }

  .shell__nav .nav-group[open] .nav-group-items {
    display: flex !important;
  }

  .shell__nav .nav-group .nav-item {
    padding: var(--sp-2) var(--sp-3);
    white-space: nowrap;
  }
}

/* Collapse toggle: a quiet hairline-topped row, matching the ledger rule's
   habit of marking structure with a line rather than a box. */
.shell__nav-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  width: 100%;
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border: none;
  border-top: var(--rule-hair);
  background: transparent;
  color: var(--c-ink-muted);
  font: inherit;
  font-size: var(--fs-sm);
  cursor: pointer;
  border-radius: 0;
}
.shell__nav-toggle:hover { color: var(--c-ink); }
.shell__nav-toggle:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-sm); }
.shell__nav-toggle .icon { transition: transform 0.15s ease; }
.shell__nav.is-collapsed .shell__nav-toggle .icon { transform: rotate(180deg); }
.shell__nav.is-collapsed .shell__nav-toggle-label { display: none; }

/* The rail is a stretched grid item, so on a long list it grows to the height of
   the table beside it and the toggle lands at the bottom of the *document* —
   several screens below the fold. Sticking the toggle's form to the bottom of the
   scrollport keeps the control in reach at any scroll position. The rail's own
   white ground travels with it, so nav items pass underneath rather than through,
   and the bottom breathing room sits inside the sticky box so the button never
   touches the viewport edge. */
.shell__nav > form {
  position: sticky;
  bottom: 0;
  background: var(--c-surface);
  padding-bottom: var(--sp-4);
}

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .shell__nav { flex-direction: row; align-items: center; padding: var(--sp-2) var(--sp-4); }
  .shell__nav-items { flex-direction: row; flex-wrap: wrap; }
  .shell__nav-toggle { display: none; }
  /* The rail is a horizontal strip here and the toggle is hidden, so the sticky
     footer would only contribute a stray white box to the row. */
  .shell__nav > form { display: none; }
}

/* --------------------------------------------------------- table row actions */
/* The icon buttons are taller than a line of text: the negative margin centres them on the cell's first line, in the
   cell's padding, so they neither push the row's text down nor shrink when the table is tight. */
.actions-cell { display: flex; gap: var(--sp-1); justify-content: flex-end; margin-block: calc(-1 * var(--sp-2)); }
.actions-cell .icon-btn { flex-shrink: 0; }
table.ledger th.actions, table.ledger td.actions { text-align: right; }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-sm);
  border: none;
  background: transparent;
  color: var(--c-ink-muted);
  text-decoration: none;
  cursor: pointer;
}
.icon-btn:hover { background: var(--c-primary-tint); color: var(--c-primary); }
.icon-btn--neg:hover { background: var(--c-neg-tint); color: var(--c-neg); }

/* ------------------------------------------------------------------ badges */
/* Status is state, not a financial outcome, so it borrows the brand ink
   rather than the pos/neg pair reserved for budget meaning. */
.badge--active { background: var(--c-primary-tint); color: var(--c-primary); }
.badge--inactive { background: var(--c-surface-alt); color: var(--c-ink-muted); }

/* ------------------------------------------------------------------- misc */
/* A second, muted line in a ledger cell, cut to one line: a scenario's description under its name. */
.ledger__sub {
  display: block;
  max-width: 32rem;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--fs-sm);
  color: var(--c-ink-muted);
}

/* A muted lock after a row's name: the row opens its item for viewing only (an entity a policy action owns). The
   row link's accessible name says so ("Bekijk …"), so the icon stays decorative. */
.row-lock { color: var(--c-ink-muted); margin-left: var(--sp-1); vertical-align: text-bottom; }

/* An empty-state cell with a call to action under its sentence. */
.empty-state .btn { margin-top: var(--sp-3); }

.count-cell { font-feature-settings: var(--num-features); font-variant-numeric: tabular-nums lining-nums; }

.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--c-ink-muted);
  margin-bottom: var(--sp-2);
}
.breadcrumb a { color: var(--c-ink-muted); }
.breadcrumb a:hover { color: var(--c-primary); }

/* --------------------------------------------------------- remember-me row */
.field--checkbox {
  flex-direction: row;
  align-items: center;
  gap: var(--sp-2);
}
.field--checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--c-primary);
}
.field--checkbox label { font-size: var(--fs-base); color: var(--c-ink); font-weight: var(--fw-regular); }

.form-hint {
  font-size: var(--fs-xs);
  color: var(--c-ink-muted);
  margin-top: calc(-1 * var(--sp-2));
}

/* Inside a .field the field's gap already spaces it; the negative margin is for a hint below a form. */
.field > .form-hint {
  margin-top: 0;
}

@media (prefers-reduced-motion: reduce) {
  .shell, .shell__nav, .shell__nav-toggle .icon { transition: none; }
}

/* ---------------------------------------------------------------- island */
/* The page that hosts the frontend app (ADR 0011): no left menu, and the app
   fills exactly the height below the header, so the page itself never scrolls.
   The app element is a flex column with a definite height its children can fill. */
.island {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--header-h));
}
.island__app {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
