/* ============================================================================
   Manifest Tier 1 — Design System: utilities.css
   ----------------------------------------------------------------------------
   Layout + alignment + spacing + a11y utilities ONLY.
   Tight whitelist (~55 classes). Banner-comment sections below.

   ============================================================================
   THE RULE (printed at top of components.css too)
   ----------------------------------------------------------------------------
   If you reach for a color, border, radius, shadow, font, or typography
   utility — you actually need a NEW COMPONENT class (or a modifier on an
   existing one). Color / typography / border / radius / shadow utilities
   are BANNED BY POLICY. Add them here and the next dev faces 1000-class
   Tailwind soup, which is exactly what we just left.

   Allowed in this file:
     - layout primitives  (.container, .stack, .cluster, .row, .grid[-N])
     - flex/grid helpers  (alignment, gap, flex-1, shrink-0)
     - SEMANTIC spacing   (.gap-xs..2xl, .p-sm..xl, .px/py/pt/pb, .mx-auto)
     - text alignment     (.text-center/left/right, .truncate, .text-balance)
     - width helpers      (.w-full, .max-w-prose, .max-w-container)
     - display / a11y     (.hidden, .block, .inline-block, .sr-only, .skip-link)
     - state              (.is-loading, .no-scroll)
     - responsive layout  (.md:flex, .md:hidden, .md:grid-cols-N, .lg:*)
       — LAYOUT ONLY, not colors/typography/spacing.

   BANNED (do not commit):
     .bg-* / .text-primary / .text-2xl / .border / .rounded-md / .shadow-md
     .md:bg-primary / .md:text-2xl / .md:p-xl
     .gap-1 / .gap-2 / .p-4 (numeric scale — use semantic xs/sm/md/lg/xl/2xl)
     arbitrary value syntax like .text-[14px]

   Spacing values come from base.css tokens (--space-xs..2xl), so a per-page
   inline `style="--density: 0.85"` reflows every utility automatically.

   Breakpoints (mobile-first, Tailwind-compatible):
     md  >= 768px
     lg  >= 1024px
   No sm: prefix — anything smaller than md is the unprefixed default.
   ========================================================================== */


/* ----------------------------------------------------------------------------
   1. LAYOUT PRIMITIVES
   ---------------------------------------------------------------------------- */

/* Centered max-width wrapper. Wrap <main>, page sections, footer-inner. */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-padding);
}

/* Vertical stack — children laid out top→bottom with consistent gap.
   Combine with .gap-* for rhythm. Default gap = --space-md if no .gap-*. */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* Horizontal cluster — flex-wrap row with consistent gap.
   Use for tag rows, button rows, breadcrumbs that may wrap mid-line. */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

/* Plain row alias — explicit display:flex (clarity in form rows etc). */
.row {
  display: flex;
}

/* Grid base — no template-columns by default; use .grid-N below. */
.grid {
  display: grid;
}

/* Responsive grids — auto-collapse to 1 column on mobile. CSS-only, no JS.
   Pattern: 1col mobile → Ncol at md (768px) or lg (1024px).
   Uses repeat()+minmax fallback so children don't get squished. */
.grid-2 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}
.grid-3 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}
.grid-4 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}

@media (min-width: 640px) {
  .grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .grid-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 768px) {
  .grid-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .grid-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .grid-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}


/* ----------------------------------------------------------------------------
   2. FLEXBOX HELPERS
   ---------------------------------------------------------------------------- */

.flex          { display: flex; }
.inline-flex   { display: inline-flex; }
.flex-col      { flex-direction: column; }
.flex-wrap     { flex-wrap: wrap; }
.flex-nowrap   { flex-wrap: nowrap; }

.items-start    { align-items: flex-start; }
.items-center   { align-items: center; }
.items-end      { align-items: flex-end; }
.items-baseline { align-items: baseline; }

.justify-start   { justify-content: flex-start; }
.justify-center  { justify-content: center; }
.justify-end     { justify-content: flex-end; }
.justify-between { justify-content: space-between; }
.justify-around  { justify-content: space-around; }

.flex-1   { flex: 1 1 0%; min-width: 0; }   /* min-width:0 prevents text overflow blow-up */
.shrink-0 { flex-shrink: 0; }


/* ----------------------------------------------------------------------------
   3. GAP + SPACING (semantic xs/sm/md/lg/xl/2xl — token-backed, density-aware)
   ---------------------------------------------------------------------------- */

/* Gap (flex + grid both) */
.gap-xs  { gap: var(--space-xs); }
.gap-sm  { gap: var(--space-sm); }
.gap-md  { gap: var(--space-md); }
.gap-lg  { gap: var(--space-lg); }
.gap-xl  { gap: var(--space-xl); }
.gap-2xl { gap: var(--space-2xl); }

/* Padding — all-sides */
.p-sm { padding: var(--space-sm); }
.p-md { padding: var(--space-md); }
.p-lg { padding: var(--space-lg); }
.p-xl { padding: var(--space-xl); }

/* Padding — axis */
.px-sm { padding-inline: var(--space-sm); }
.px-md { padding-inline: var(--space-md); }
.px-lg { padding-inline: var(--space-lg); }
.py-sm { padding-block: var(--space-sm); }
.py-md { padding-block: var(--space-md); }
.py-lg { padding-block: var(--space-lg); }
.py-xl { padding-block: var(--space-xl); }

/* Padding — single side (common needs only) */
.pt-md { padding-top: var(--space-md); }
.pt-lg { padding-top: var(--space-lg); }
.pt-xl { padding-top: var(--space-xl); }
.pb-md { padding-bottom: var(--space-md); }
.pb-lg { padding-bottom: var(--space-lg); }
.pb-xl { padding-bottom: var(--space-xl); }

/* Margin auto — only auto values exposed. Numeric margins go on components. */
.mt-auto { margin-top: auto; }
.mb-auto { margin-bottom: auto; }
.mx-auto { margin-inline: auto; }


/* ----------------------------------------------------------------------------
   4. TEXT ALIGNMENT + TRUNCATE
   ---------------------------------------------------------------------------- */

.text-center { text-align: center; }
.text-left   { text-align: left; }
.text-right  { text-align: right; }

/* Single-line ellipsis. Pair with display:block / flex parent. */
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Progressive enhancement — better-balanced hero headlines on supporting
   browsers (Chrome 114+, Safari 17.5+, Firefox 121+). Older browsers
   gracefully ignore. */
.text-balance { text-wrap: balance; }


/* ----------------------------------------------------------------------------
   5. WIDTH + SIZING
   ---------------------------------------------------------------------------- */

.w-full           { width: 100%; }
.h-full           { height: 100%; }
.min-h-screen     { min-height: 100vh; }
.max-w-prose      { max-width: 65ch; }                 /* legal pages, article body */
.max-w-container  { max-width: var(--container-max); }


/* ----------------------------------------------------------------------------
   6. DISPLAY + VISIBILITY
   ---------------------------------------------------------------------------- */

.hidden        { display: none; }
.block         { display: block; }
.inline-block  { display: inline-block; }
.inline        { display: inline; }


/* ----------------------------------------------------------------------------
   7. ACCESSIBILITY
   ---------------------------------------------------------------------------- */

/* Visually-hidden but kept in DOM for screen readers + keyboard focus.
   Standard pattern — never use display:none for sr-only content. */
.sr-only,
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Skip link — first focusable element on every page, jumps to #main.
   Visually hidden until focused, then visible top-left with brand color. */
.skip-link {
  position: fixed;
  top: var(--space-sm);
  left: var(--space-sm);
  z-index: 1000;
  padding: var(--space-sm) var(--space-md);
  background: var(--color-primary);
  color: #fff;
  border-radius: var(--radius-sm);
  font-weight: 500;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--transition-fast) var(--ease-out);
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* Body-scroll lock helper — applied when a modal/drawer opens. */
.no-scroll {
  overflow: hidden;
  /* compensate for scrollbar removal so layout doesn't jump */
  scrollbar-gutter: stable;
}


/* ----------------------------------------------------------------------------
   8. STATE
   ---------------------------------------------------------------------------- */

/* Generic loading state — components opt in with their own shimmer/spinner.
   Pair with [aria-busy="true"] for assistive tech. */
.is-loading {
  cursor: wait;
  pointer-events: none;
  user-select: none;
}


/* ============================================================================
   9. RESPONSIVE LAYOUT VARIANTS  (md: 768px+, lg: 1024px+)

   POLICY: Layout-only. NO color/typography/spacing variants.
   If you need a different padding on desktop, that's a component CSS rule.
   ========================================================================== */

@media (min-width: 768px) {
  .md\:flex          { display: flex; }
  .md\:inline-flex   { display: inline-flex; }
  .md\:block         { display: block; }
  .md\:inline-block  { display: inline-block; }
  .md\:grid          { display: grid; }
  .md\:hidden        { display: none; }

  .md\:flex-row      { flex-direction: row; }
  .md\:flex-col      { flex-direction: column; }

  .md\:items-start    { align-items: flex-start; }
  .md\:items-center   { align-items: center; }
  .md\:justify-start  { justify-content: flex-start; }
  .md\:justify-center { justify-content: center; }
  .md\:justify-between { justify-content: space-between; }

  .md\:grid-cols-2   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .md\:grid-cols-3   { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .md\:grid-cols-4   { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  .md\:text-center   { text-align: center; }
  .md\:text-left     { text-align: left; }
}

@media (min-width: 1024px) {
  .lg\:flex          { display: flex; }
  .lg\:inline-flex   { display: inline-flex; }
  .lg\:block         { display: block; }
  .lg\:grid          { display: grid; }
  .lg\:hidden        { display: none; }

  .lg\:flex-row      { flex-direction: row; }
  .lg\:flex-col      { flex-direction: column; }

  .lg\:grid-cols-2   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lg\:grid-cols-3   { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lg\:grid-cols-4   { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* End utilities.css */
