/* ============================================================================
   primitives.css — tuppu.net
   Every Layout primitives — https://every-layout.dev (Pickering & Rennie)

   Rules:
   · No color, no typography, no component concerns here.
   · Primitives are composable — nest them freely.
   · Intrinsic layout only — no breakpoints, no media queries.
   · Custom properties are the API for each primitive.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   Center
   Horizontally centres content up to --measure, with fluid inline padding.
   Custom property: --measure (default 80rem)
   Usage: <div class="center">
   ---------------------------------------------------------------------------- */

.center {
  box-sizing: content-box;
  max-inline-size: var(--measure, 80rem);
  margin-inline: auto;
  padding-inline: var(--space-s-l);
  padding-block-start: var(--space-s-l);
}

/* ----------------------------------------------------------------------------
   Stack
   Vertical rhythm via margin-block-start on adjacent siblings.
   Custom property: --stack-space (default --space-s)
   Variants: .stack--2xs  → --space-2xs
             .stack--xs   → --space-xs
             .stack--tight → --space-3xs
             .stack--m    → --space-m
             .stack--loose → --space-l
   Usage: <div class="stack">
   ---------------------------------------------------------------------------- */

.stack {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.stack > * + * {
  margin-block-start: var(--stack-space, var(--space-s));
}

.stack--2xs   > * + * { --stack-space: var(--space-2xs); }
.stack--xs    > * + * { --stack-space: var(--space-xs); }
.stack--tight > * + * { --stack-space: var(--space-3xs); }
.stack--m     > * + * { --stack-space: var(--space-m); }
.stack--loose > * + * { --stack-space: var(--space-l); }

/* ----------------------------------------------------------------------------
   Box
   A generic padded container. Colour and border added by component layer.
   Custom property: --box-padding (default --space-s)
   Usage: <div class="box">
   ---------------------------------------------------------------------------- */

.box {
  padding: var(--box-padding, var(--space-s));
}

/* ----------------------------------------------------------------------------
   Cluster
   Horizontal group of items that wraps. Items are vertically centred.
   Custom property: --cluster-gap (default --space-2xs)
   Variants: .cluster--tight → --space-3xs
             .cluster--xs    → --space-xs
             .cluster--s     → --space-s
             .cluster--m     → --space-m
   Usage: <div class="cluster">
   ---------------------------------------------------------------------------- */

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cluster-gap, var(--space-2xs));
  align-items: center;
}

.cluster--tight { --cluster-gap: var(--space-3xs); }
.cluster--xs    { --cluster-gap: var(--space-xs); }
.cluster--s     { --cluster-gap: var(--space-s); }
.cluster--m     { --cluster-gap: var(--space-m); }

/* ----------------------------------------------------------------------------
   Spread
   A row where items are pushed to opposite ends (space-between).
   Wraps gracefully. Use when two groups need to occupy opposite sides.
   Custom property: --spread-gap (default --space-s)
   Variants: .spread--end → aligns items to flex-end (e.g. preview header)
   Usage: <div class="spread">
   ---------------------------------------------------------------------------- */

.spread {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--spread-gap, var(--space-s));
}

.spread--baseline { align-items: baseline; }
.spread--end { align-items: flex-end; }

/* ----------------------------------------------------------------------------
   Switcher
   A row that collapses into a column below --switcher-threshold.
   Children grow equally. No breakpoint needed.
   Custom property: --switcher-threshold (default 30rem)
                    --switcher-gap       (default --space-s)
   Variants: .switcher--stat → tight threshold for stat groups
   Usage: <div class="switcher">
   ---------------------------------------------------------------------------- */

.switcher {
  display: flex;
  flex-wrap: wrap;
  gap: var(--switcher-gap, var(--space-s));
}

.switcher > * {
  flex-grow: 1;
  flex-basis: calc((var(--switcher-threshold, 30rem) - 100%) * 999);
}

.switcher--stat {
  --switcher-threshold: 10rem;
  --switcher-gap: var(--space-xs);
}

/* ----------------------------------------------------------------------------
   Sidebar (Every Layout sidebar pattern)
   A two-column layout that collapses when the side can't hold --sidebar-basis.
   Uses row-reverse so the sidebar is second in DOM but first visually.
   Custom property: --sidebar-basis (default 300px)
   Usage:
     <div class="sidebar-layout">
       <main class="sidebar-layout__main">…</main>
       <aside class="sidebar-layout__side">…</aside>
     </div>
   ---------------------------------------------------------------------------- */

.sidebar-layout {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row-reverse;
  gap: var(--space-s);
  align-items: start;
}

.sidebar-layout__main {
  flex-basis: 0;
  flex-grow: 999;
  min-inline-size: min(60%, 100%);
}

.sidebar-layout__side {
  flex-basis: var(--sidebar-basis, 300px);
  flex-grow: 1;
}

.sidebar-layout__main,
.sidebar-layout__side {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* ----------------------------------------------------------------------------
   Cover
   Vertically centres a principal child, with optional header/footer.
   Custom property: --cover-min-height (default 100dvh)
   Usage:
     <div class="cover">
       <header>…</header>
       <main class="cover__principal">…</main>
     </div>
   ---------------------------------------------------------------------------- */

.cover {
  display: flex;
  flex-direction: column;
  min-block-size: var(--cover-min-height, 100dvh);
  padding-block: var(--space-s);
}

.cover__principal {
  margin-block: auto;
}

/* ----------------------------------------------------------------------------
   Grid (auto-fit intrinsic grid)
   Items fill the row; when they can't fit --grid-min-size, they wrap.
   Custom property: --grid-min-size (default 16rem)
                    --grid-gap      (default --space-s)
   Usage: <ul class="grid">
   ---------------------------------------------------------------------------- */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--grid-min-size, 16rem), 100%), 1fr));
  gap: var(--grid-gap, var(--space-s));
}

/* ----------------------------------------------------------------------------
   Reel
   Horizontal scroll container.
   Usage: <div class="reel">
   ---------------------------------------------------------------------------- */

.reel {
  display: flex;
  gap: var(--space-s);
  overflow-x: auto;
  scrollbar-width: thin;
}

.reel > * {
  flex-shrink: 0;
}

