/* ==========================================================================
   Stelar Reality — utilities
   A deliberately closed set. Loads last, so a single-class utility beats a
   single-class component rule on source order alone — no !important needed
   anywhere in this file.

   WHAT IS NOT HERE, ON PURPOSE:
   padding utilities, colour utilities beyond muted/dim, font-size ramps,
   border/radius/shadow utilities, and responsive variants of anything except
   the one md pair at the bottom. If a view needs more than this, it needs a
   component, not another utility.
   ========================================================================== */

/* --- Spacing ---------------------------------------------------------------
   Steps map onto the token scale: 0=0 · 1=4px · 2=8px · 3=12px · 4=16px
   5=24px · 6=32px. Logical properties, so they follow writing mode. */

.u-mb-0 { margin-block-end: 0; }
.u-mb-1 { margin-block-end: var(--space-1); }
.u-mb-2 { margin-block-end: var(--space-2); }
.u-mb-3 { margin-block-end: var(--space-3); }
.u-mb-4 { margin-block-end: var(--space-4); }
.u-mb-5 { margin-block-end: var(--space-5); }
.u-mb-6 { margin-block-end: var(--space-6); }

.u-mt-0 { margin-block-start: 0; }
.u-mt-1 { margin-block-start: var(--space-1); }
.u-mt-2 { margin-block-start: var(--space-2); }
.u-mt-3 { margin-block-start: var(--space-3); }
.u-mt-4 { margin-block-start: var(--space-4); }
.u-mt-5 { margin-block-start: var(--space-5); }
.u-mt-6 { margin-block-start: var(--space-6); }

/* --- Flow ------------------------------------------------------------------- */

/* Things that sit on one line and wrap gracefully when they cannot. */
.u-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.u-stack {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap, var(--space-4));
}

.u-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.u-center {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
}

.u-end {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
}

.u-grow { flex: 1; }

/* Opts a grid/flex child out of stretching to its row. A card that holds a
   short list next to a taller aside otherwise grows to match it and ends in a
   band of empty white — see the cart. */
.u-self-start { align-self: start; }

.u-wrap { flex-wrap: wrap; }

.u-gap-1 { gap: var(--space-1); }
.u-gap-2 { gap: var(--space-2); }
.u-gap-3 { gap: var(--space-3); }
.u-gap-4 { gap: var(--space-4); }

/* --- Text -------------------------------------------------------------------- */

/* #585857 — passes AA at every size. This is the muted colour for real copy. */
.u-muted { color: var(--text-secondary); }

/* #7E7E7E — only clears AA at >=18.66px bold or >=24px regular. Use it for
   large numerals, oversized labels and decorative type. Never for body copy,
   hints, table cells or anything a user has to read to act. */
.u-dim { color: var(--text-muted); }

.u-small { font-size: 0.875rem; }

.u-bold { font-weight: 700; }

.u-nowrap { white-space: nowrap; }

.u-right { text-align: right; }

.u-text-center { text-align: center; }

.u-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Aligns figures in columns so digits stack. */
.u-tabular { font-variant-numeric: tabular-nums; }

/* --- Display ------------------------------------------------------------------ */

.u-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.u-hidden { display: none; }

.u-full { width: 100%; }

/* Caps a .form-control that sits in a table cell. A form field is width:100%,
   and inside a <td> that means the column's width — a 3-digit quantity box
   stretched across a third of the table. Wide enough for "999". */
.u-narrow { max-width: 6rem; }

/* Expands a link's hit area to its nearest positioned ancestor, so a whole
   card is clickable without nesting an <a> around block content. The ancestor
   must be position:relative (.card.is-interactive already is).

   NOT used by the clickable table/list rows — those go through app.js's
   "row:open" action. Two reasons: this overlay cannot work inside a <table>,
   and it swallows text selection across the whole row, which an admin copying
   an order id or an e-mail address needs. Reach for it on card-sized targets. */
.u-stretch::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* --- The two responsive pairs -------------------------------------------------
   48rem (phone/tablet) and 64rem (the topbar/sidebar collapse line). No other
   utility gets a breakpoint variant. */

@media (max-width: 47.98rem) {
  .u-hide-below-md { display: none; }
}

@media (min-width: 48rem) {
  .u-show-below-md { display: none; }
}

@media (max-width: 63.98rem) {
  .u-hide-below-lg { display: none; }
}

@media (min-width: 64rem) {
  .u-show-below-lg { display: none; }
}
