/*
 * Structural arrangement: the page shell every app can start from. Visual
 * skin (color, border, radius) for individual pieces lives in
 * components.css - same separation apps/inventory-web/src/styles/layout.css
 * already established.
 *
 * This is the genuinely generic subset of that file - a page shell, brand
 * lockup, and a shared spacing rhythm. Anything domain-specific (a kanban
 * board's columns, a character strip, a tenant grid) stays local to the
 * app that needs it, not here - see ADR 0098 and docs/guides/adding-a-
 * package.md's "don't generalize before a second consumer needs it" rule.
 */

/* Page shell: body is a full-height flex column so a short page's footer
   still sits at the bottom of the viewport rather than immediately under
   the content - header and footer keep their own natural height, main
   grows to fill whatever space is left between them. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}

/* A text wordmark (no logo asset shipped in this package) sized to sit
   correctly in a compact header, rather than at its unconstrained
   context-dependent default (identity.md §5.3's .display is deliberately
   size-agnostic everywhere else). */
.site-header .display {
  font-size: 20px;
}

/* Header nav - a bare <a> in a bare <nav> would otherwise render as
   default underlined link-blue text crammed against the wordmark, with no
   visual weight or way to show which page is current. Same treatment as
   .sidebar below, so the two page shells read as one system. */
.site-header nav {
  display: flex;
  align-items: center;
  gap: 2px;
}

.site-header nav a {
  font-size: 14px;
  color: var(--text-secondary);
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-control);
}

.site-header nav a:hover {
  background: var(--fill-soft);
  color: var(--text-primary);
}

.site-header nav a[aria-current="page"] {
  background: var(--fill-soft);
  color: var(--text-primary);
  font-weight: 600;
}

.brand {
  display: inline-flex;
  align-items: center;
}

.brand-mark {
  display: block;
  /* identity.md §4.7: horizontal lockup minimum width is 220px. */
  width: 220px;
  height: auto;
}

.brand-mark--dark {
  display: none;
}

/* Keyed off the applied theme, not prefers-color-scheme - the same
   switch tokens.css uses - so the lockup always matches the surface it
   sits on, even where a page lets the theme differ from the browser's
   preference. */
[data-theme="dark"] .brand-mark--light {
  display: none;
}

[data-theme="dark"] .brand-mark--dark {
  display: block;
}

main {
  flex: 1 0 auto;
  padding: var(--space-4);
}

/* A bare <section> gets a sensible default rhythm with no class needed -
   .section/.section-lg below stay available for wherever a different
   rhythm is deliberately wanted instead. */
section {
  margin-bottom: var(--space-6);
}

/* A bare <footer> gets a sensible default treatment - a quiet divider
   above secondary, muted page-level information. A sibling of <main>,
   not nested inside .wrap, so its own border/background span the full
   page width the same way .site-header's do - put its actual text in a
   nested .wrap (see preview/*.html) so it still lines up with the
   content column above it. */
footer {
  margin-top: var(--space-4);
  padding-block: var(--space-4);
  border-top: 1px solid var(--border-subtle);
  color: var(--text-tertiary);
  font-size: 13px;
}

/* Shared section-spacing utility - for wherever a section needs a
   different rhythm than the bare-element default above. */
.section {
  margin-top: var(--space-5);
}

.section-lg {
  margin-top: var(--space-6);
}

/* A centered, reading-width content wrapper - the default outermost
   container for any page's content. */
.wrap {
  max-width: 880px;
  margin-inline: auto;
  padding-inline: var(--space-4);
}

/* Breaks a block out of .wrap (or any centered column) to span the whole
   page width - for content wider than a reading column, like a board or a
   catalog. 100vw includes a visible vertical scrollbar's width, so it
   overshoots the page by that much - the overflow-x: clip on body cuts
   that off, rather than letting it become a horizontal scrollbar. */
body:has(.full-width) {
  overflow-x: clip;
}

.full-width {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  padding-inline: var(--space-4);
}

/* A horizontal row of items with consistent gap - the single most common
   "put some things next to each other" layout need. .row-tight is the
   same idea at a smaller gap, for a tightly-paired icon+label. */
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.row-tight {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* Takes the free space left in a flex .row. */
.grow {
  flex: 1;
}

/* A .row whose items align to the top instead of centering - for when one
   of them (an opened panel, say) grows taller than the rest. */
.row.sticky-top {
  align-items: start;
}

/* A vertical stack of elements with consistent spacing between them - the
   vertical counterpart to .row, so stacked pieces never need their own
   one-off margin. */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* .stack at a tighter rhythm - the fields of one form, a list of options. */
.stack-tight {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* A simple responsive grid - override the card width via
   style="--grid-min: 200px" where the 160px default doesn't fit. */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--grid-min, 160px), 1fr));
  gap: var(--space-3);
}

.h-scroll {
  overflow-x: auto;
}

.grid.h-scroll {
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: minmax(var(--grid-min, 160px), 1fr);
}

/* A narrow sidebar (nav, filters) beside a wider main content area - the
   other common page shell, alongside .wrap's single centered column.
   Stacks to one column below 720px rather than crushing the sidebar. */
.with-sidebar {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: var(--space-5);
}

@media (max-width: 720px) {
  .with-sidebar {
    /* Not a bare 1fr, which is minmax(auto, 1fr): the column would not shrink below the
       widest thing in it (a form control's own width), and the page scrolled sideways on a
       phone. */
    grid-template-columns: minmax(0, 1fr);
  }
}

.sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.sidebar a {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-control);
  color: var(--text-secondary);
  text-decoration: none;
}

.sidebar a:hover {
  background: var(--fill-soft);
  color: var(--text-primary);
}

.sidebar a[aria-current="page"] {
  background: var(--fill-soft);
  color: var(--text-primary);
  font-weight: 600;
}

/* A list or column that scrolls inside the page instead of growing it.
   Pair with .vertical-mask (components.css) to fade the cut-off edges. */
.vertical-window {
  max-height: 70vh;
  overflow-y: auto;
}

/* Phone widths (identity.md §8.5). One breakpoint, the same 720px as
   .with-sidebar, because a second one would mean two kinds of "narrow" to
   keep in step. A custom property cannot be used in a media query, so the
   number is written here and in the .with-sidebar rule above.

   What changes is only what stops working at that width: the double gutter
   (main's padding plus .wrap's), a header that cannot fit on one row, and
   side-by-side columns. Type does not shrink (§15.5) and nothing is hidden
   to make room. */
@media (max-width: 720px) {
  main {
    padding: var(--space-3);
  }

  /* main already gives the gutter; the footer's .wrap, which has no main
     around it, keeps its own. */
  main .wrap {
    padding-inline: 0;
  }

  .site-header {
    flex-wrap: wrap;
    padding: var(--space-2) var(--space-3);
  }

  .site-header nav {
    flex-wrap: wrap;
  }

  /* Wider than the viewport minus the gutters at 320px, so it gives way
     rather than overflowing; §4.7's 220px minimum is for the lockup at
     rest, and the spark alone is the compact form (§12.2). */
  .brand-mark {
    max-width: 100%;
  }
}
