/* layout.css -- how things are arranged. Layer 3 of 4.
 *
 * Four primitives -- container, stack, cluster, grid -- plus the page shells.
 * They compose: a .stack inside a .container inside a <section>. Nothing here
 * paints a colour or sets a font; that is components.css.
 *
 * The point of separating this out is that a layout primitive has no opinion
 * about what it holds. The Bootstrap theme it replaces mixed the two -- .col-md-4
 * carried padding that a card then had to cancel, and .box-simple was
 * simultaneously a grid cell, a card and a hover effect. Splitting them is why
 * this file and components.css can each stay short.
 */

/* ── Container ─────────────────────────────────────────────────────────
 * Horizontal padding lives on the container, never on a section, so nested
 * containers never double up their gutters. */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.container-narrow {
  max-width: var(--container-narrow);
}

/* Long-form prose from the database. Capping the measure is the single
 * highest-value typographic rule on the site -- privacy_policy_html at full
 * 1140px width is unreadable. */
.prose {
  max-width: var(--measure);
}

/* ── Stack -- vertical rhythm ──────────────────────────────────────────
 * The owl selector: margin goes on every child except the first, so a stack
 * never adds space above itself or below its last child, and the spacing
 * survives an element being added, removed or reordered. --gap is per-instance,
 * which is why this one class covers everything from a form to a page. */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--gap, var(--space-4));
}

.stack-sm { --gap: var(--space-2); }
.stack-lg { --gap: var(--space-6); }
.stack-xl { --gap: var(--space-7); }

/* ── Cluster -- horizontal groups that wrap ────────────────────────────
 * Button rows, nav items, badge lists, table row actions. Wraps rather than
 * overflows, so it needs no breakpoint. */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap, var(--space-3));
}

.cluster-between {
  justify-content: space-between;
}

.cluster-end {
  justify-content: flex-end;
}

.cluster-sm { --gap: var(--space-2); }

/* ── Grid ──────────────────────────────────────────────────────────────
 * auto-fit + minmax means the column count is derived from available width
 * rather than declared per breakpoint. --col is the minimum comfortable card
 * width; below it the grid drops a column on its own.
 *
 * The min() guard matters on narrow phones: a bare minmax(280px, 1fr) forces
 * a 280px track inside a 320px viewport minus gutters and the row overflows.
 * min(100%, --col) lets the track collapse instead. */
.grid {
  display: grid;
  gap: var(--gap, var(--space-5));
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--col, 280px)), 1fr));
}

.grid-2 { --col: 420px; }
.grid-4 { --col: 220px; }

/* A fixed two-column split that collapses at one breakpoint -- used where
 * auto-fit is wrong because the two columns are not peers (form + aside). */
.split {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    align-items: start;
  }
  .split-even {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* ── Section rhythm ────────────────────────────────────────────────────
 * Vertical padding is a layout concern, so it lives here rather than being
 * respecified by every section component. */
.section {
  padding-block: var(--space-8);
}

.section-lg {
  padding-block: var(--space-9);
}

.section-tint {
  background: var(--surface-2);
}

.section-dark {
  background: var(--surface-inverse);
  color: color-mix(in srgb, white 80%, var(--surface-inverse));
}

.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4,
.section-dark strong {
  color: #fff;
}

.section-dark a {
  color: #fff;
  text-decoration-color: var(--brand-accent);
}

/* ── Page shell ────────────────────────────────────────────────────────
 * Sticky footer without a fixed height: the main region grows to fill, so a
 * short page (a 404, an empty leads table) still pins its footer to the
 * bottom of the viewport. */
.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.page > main {
  flex: 1 0 auto;
}

/* Skip link. Off-screen until focused, then pinned top-left over the header --
 * the first Tab stop on every page. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(-1 * var(--space-9));
  z-index: calc(var(--z-header) + 1);
  padding: var(--space-2) var(--space-4);
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius);
  text-decoration: none;
  transition: top var(--dur) var(--ease);
}

.skip-link:focus {
  top: var(--space-3);
  color: #fff;
}

/* ── Admin shell ───────────────────────────────────────────────────────
 * Sidebar + content. Below 900px the sidebar becomes a horizontally
 * scrollable strip above the content rather than a drawer -- no JS, no focus
 * trap, and no way to end up with an invisible nav if a script fails to load. */
.admin-shell {
  display: grid;
  min-height: 100vh;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  background: var(--surface-2);
}

.admin-main {
  min-width: 0; /* lets wide tables scroll inside instead of stretching the grid */
  padding: var(--space-5) var(--space-5) var(--space-8);
}

.admin-content {
  width: 100%;
  max-width: 1280px;
  margin-inline: auto;
}

@media (min-width: 900px) {
  .admin-shell {
    grid-template-columns: var(--sidebar) minmax(0, 1fr);
    grid-template-rows: 1fr;
  }
  .admin-main {
    padding: var(--space-6) var(--space-7) var(--space-9);
  }
}

/* ── Print ─────────────────────────────────────────────────────────────
 * One realistic case: an admin printing a lead. Drop the chrome, keep the
 * content, and expose link targets since a printed link is otherwise dead. */
@media print {
  .site-header,
  .site-footer,
  .admin-nav,
  .toast,
  .btn,
  .skip-link {
    display: none !important;
  }
  .admin-shell {
    display: block;
  }
  body {
    background: #fff;
  }
  a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: var(--text-xs);
    color: var(--ink-3);
  }
}
