/* ──────────────────────────────────────────────────────────────────────────
   Layout — the shell: sidebar, topbar, environment banner, page container.
   ────────────────────────────────────────────────────────────────────────── */

.shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  min-height: 100vh;
}

/* ── Sidebar ─────────────────────────────────────────────────────────────── */

.sidebar {
  background: var(--bg-surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  /* visible, not hidden: the collapse button hangs 14px past the right edge.
     The nav inside does its own scrolling, so nothing here needs clipping. */
  overflow: visible;
  /* `position: sticky` makes this a stacking context whatever its children
     ask for, so the button's own z-index is scoped INSIDE the sidebar and
     cannot lift it over .main — which, being a later sibling with a
     background, painted over the half of the circle that overhangs. The
     sidebar as a whole has to win, not the button. */
  z-index: 40;
}

.sidebar__brand {
  padding: var(--s-5) var(--s-4) var(--s-4);
  border-bottom: 1px solid var(--border);
}
/* Images, not text. The brand used to be the word SEALUTION. set in the body
   font, which meant that collapsing the sidebar to 64px left a 17px word in a
   64px box: it rendered as "SEALU" spilling out over the topbar. Sized by
   height with width:auto so neither mark can ever be wider than its box. */
.sidebar__wordmark {
  display: block;
  height: 20px;
  width: auto;
}
.sidebar__mark {
  display: none;
  height: 24px;
  width: auto;
  margin-inline: auto;
}
.sidebar__sub {
  margin-top: var(--s-2);
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--text-muted);
}

/* The bottom padding is 16 and not 24 on purpose. The brand block above
   resolves to a fractional height (83.5px at the default type size), so with
   24 the nav's content came out ONE pixel taller than its box — enough to
   draw a full-height scrollbar track down the sidebar, right beside the
   collapse button, on a screen with room to spare. Scroll when there is
   genuinely no room; not for a rounding error.

   `scrollbar-width: thin` is for the screens where it IS needed: a short
   laptop window scrolls this nav legitimately, and the default track is a
   heavy grey slab against a white sidebar. */
.sidebar__nav {
  flex: 1;
  overflow-y: auto;
  padding: var(--s-2) 0 var(--s-4);
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

.nav__group { padding: var(--s-2) var(--s-2) var(--s-3); }
.nav__group + .nav__group { border-top: 1px solid var(--border); }

.nav__grouplabel {
  padding: var(--s-2) var(--s-3) var(--s-1);
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted);
}

.nav__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  height: 40px;
  padding: 0 var(--s-3);
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-secondary);
  position: relative;
  transition: background var(--t-fast), color var(--t-fast);
}
.nav__item:hover { background: var(--bg-subtle); color: var(--text-primary);
                   text-decoration: none; }
.nav__item--active {
  background: var(--bg-active-nav);
  color: var(--text-primary);
  font-weight: 600;
}
/* The bar sits on the SIDEBAR'S left edge, not the item's: the group has 8px
   of padding, so the pseudo-element is pulled back by exactly that. Drawn as
   a pseudo-element rather than a border so the label's x never moves between
   the active item and the rest. */
.nav__item--active::before {
  content: "";
  position: absolute;
  left: calc(var(--s-2) * -1);
  top: var(--s-2);
  bottom: var(--s-2);
  width: 2px;
  background: var(--text-primary);
  border-radius: 0 2px 2px 0;
}
.nav__item .icon { color: inherit; }

/* ── Main column ─────────────────────────────────────────────────────────── */

.main { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  height: var(--topbar-h);
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: 0 var(--s-6);
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
}
/* A breadcrumb, not a second copy of the heading two inches below it. */
.topbar__crumb      { display: flex; align-items: center; gap: var(--s-2);
                      font-size: 14px; font-weight: 500; }
.topbar__crumb-up   { color: var(--text-muted); }
.topbar__crumb-sep  { color: var(--text-muted); }
.topbar__crumb-here { color: var(--text-primary); font-weight: 600; }
.topbar__actions { display: flex; align-items: center; gap: var(--s-2); }

/* ── Environment banner ──────────────────────────────────────────────────── */

.banner {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-6);
  background: var(--warning-bg);
  color: var(--warning-text);
  border-bottom: 1px solid var(--warning-border);
  font-size: 12px;
  font-weight: 600;
}
.banner .icon { font-size: 18px; }

/* ── Page ────────────────────────────────────────────────────────────────── */

/* FULL WIDTH, deliberately.
   A 1280px cap is right for a page of prose; this panel is tables of fifteen
   columns with an editable input in most of them. Capped, the Unit column was
   sixty pixels wide and showed "per m" — the content was there and unreadable,
   which is the worst of both. The lede under each heading keeps its own
   measure, so the reading line stays sane while the tables get the room. */
/* One container for the heading, the cards and the footer note, so they share
   a left edge and a measure. */
.page {
  flex: 1;
  width: 100%;
  max-width: 1280px;
  margin-inline: auto;
  padding: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.page__head { display: flex; align-items: flex-start; justify-content: space-between;
              gap: var(--s-4); flex-wrap: wrap; }
/* A page heading needed no class: there were three ways to size one and all
   three had the same values — `.page h1` in the bridge (25 screens), this
   class (1 screen), and `.t-page` in the type scale (0 screens). A page has
   exactly one h1, so the element is the selector. `.t-page` stays as the scale
   entry for the rare heading that is not an h1; `.page__title` is kept only so
   markup that still says it does not break, and goes with legacy.css. */
.page h1,
.page__title { font-size: 24px; font-weight: 600; letter-spacing: -0.01em; }
.page__sub   { margin-top: var(--s-1); font-size: 13px; font-weight: 400;
               color: var(--text-secondary); max-width: 70ch; }

/* A heading on the left, actions on the right, wrapping on a narrow screen. */
.page__header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap;
}

/* Main column plus a narrower aside; one column once there is no room. */
.page__split {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: var(--s-4); align-items: start;
}
@media (max-width: 1024px) { .page__split { grid-template-columns: 1fr; } }

.page__note  { padding-top: var(--s-5); font-size: 12px; font-weight: 400;
               color: var(--text-muted); max-width: 720px; line-height: 1.6; }

/* ── Responsive ──────────────────────────────────────────────────────────── */

/* ── Sidebar collapse ────────────────────────────────────────────────────── */

/* The button straddles the sidebar's right edge near the top, so it reads as
   belonging to the boundary it moves rather than to the nav above or the page
   beside it. It sits on .sidebar (not inside the scrolling nav) so it cannot
   scroll away from the edge it controls. */
.sidebar__toggle[hidden] { display: none; }
.sidebar__toggle {
  position: absolute;
  top: 18px;
  right: -14px;
  width: 28px;
  height: 28px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast);
}
.sidebar__toggle:hover {
  background: var(--bg-subtle);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.sidebar__toggle .icon { font-size: 18px; transition: transform var(--t-fast); }

/* Collapsed: icons only, same shape the narrow-viewport rules produce below.
   CSS cannot say "either this attribute or that media query", so the two
   conditions each carry the list. If you change one, change both. */
:root[data-sidebar="collapsed"] .shell {
  grid-template-columns: var(--sidebar-w-collapsed) minmax(0, 1fr);
}
:root[data-sidebar="collapsed"] .sidebar__sub,
:root[data-sidebar="collapsed"] .nav__grouplabel,
:root[data-sidebar="collapsed"] .nav__item span:not(.icon) { display: none; }
:root[data-sidebar="collapsed"] .sidebar__brand {
  padding: var(--s-4) var(--s-2); text-align: center;
}
:root[data-sidebar="collapsed"] .sidebar__wordmark { display: none; }
:root[data-sidebar="collapsed"] .sidebar__mark     { display: block; }
:root[data-sidebar="collapsed"] .nav__item {
  justify-content: center; padding: 0; gap: 0;
}
/* One glyph, turned around, rather than a second one in the font subset. */
:root[data-sidebar="collapsed"] .sidebar__toggle .icon {
  transform: rotate(180deg);
}

/* Below 1024 the sidebar keeps its icons and drops its words. It is still
   there and still usable — collapsing it to nothing would mean no way back
   without JavaScript, and this panel runs none. */
@media (max-width: 1024px) {
  .shell { grid-template-columns: var(--sidebar-w-collapsed) minmax(0, 1fr); }
  .sidebar__sub,
  .nav__grouplabel,
  .nav__item span:not(.icon) { display: none; }
  .sidebar__brand    { padding: var(--s-4) var(--s-2); text-align: center; }
  .sidebar__wordmark { display: none; }
  .sidebar__mark     { display: block; }
  .nav__item      { justify-content: center; padding: 0; gap: 0; }
  .topbar, .banner, .page { padding-left: var(--s-4); padding-right: var(--s-4); }
}

@media (max-width: 768px) {
  .page { padding: var(--s-4); gap: var(--s-4); }
  .topbar { height: auto; padding-top: var(--s-3); padding-bottom: var(--s-3);
            flex-wrap: wrap; }
}
