/* ==========================================================================
   Settings — the shell every settings section page shares.

   One page per section: a left Configuration nav card beside the active
   panel, `.cols-1-2` doing the split. These rules govern that shell only;
   the panels themselves are plain design-system components.
   ========================================================================== */

.settings-shell { --settings-nav-w: 288px; }

/* The Configuration nav is the same 14 links on every settings page, so its
   column must not resize with whatever the active panel happens to hold.
   `.cols-1-2` is `1fr 2fr`, and an `fr` track floors at its content's
   min-content width — so a panel carrying a wide table (Client Groups' is
   min-width 1265px, the API page's 898px) steals width from the nav, and the
   nav jumps sideways every time you switch section. Pin the nav; let the panel
   take the remainder. */
@media (min-width: 1101px) {
  .settings-shell { grid-template-columns: var(--settings-nav-w) minmax(0, 1fr); }
}

/* `minmax(0, …)` frees the TRACK to go below min-content; the card is still a
   grid item with `min-width: auto`, which would push straight back out. Both
   halves are needed, or the pin above does nothing on the wide-table pages.
   Under-width panels scroll inside their own `.table-wrap` — which is what it
   is for — instead of forcing horizontal overflow on the page. */
.settings-shell > .card { min-width: 0; }

/* --------------------------------------------------------------------------
   One surface, not two cards.

   Sections are tabs of a single Settings page, so the nav and the active panel
   are joined into one bordered block rather than floating as two separate
   cards with a gap between them: shared top edge, one seam, outer corners
   rounded only on the outside.
   -------------------------------------------------------------------------- */
@media (min-width: 1101px) {
  .settings-shell { gap: 0; }

  .settings-shell__nav {
    border-radius: var(--radius-md) 0 0 var(--radius-md);
    box-shadow: none;
  }
  /* Pulled onto the nav's right border so the two 1px edges collapse into one
     seam. The panel keeps its own left border, which is what continues the
     block's left edge below where the shorter nav ends. */
  .settings-shell__panel {
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    margin-left: -1px;
  }
}

/* The nav sits at its natural height (`align-self: start`) so a tall panel does
   not stretch it into a mostly-empty column; the panel keeps the grid's default
   stretch, so a short panel still fills the block down to the nav's full height
   and every section reads as the same size.

   That stretch is why the panel is a flex column: a section shorter than the nav
   would otherwise leave its footer floating in the middle of the card with dead
   space beneath it (139px on Terminology, 212px on Locations). The body absorbs
   the slack; the footer stays on the card's bottom edge. */
.settings-shell__panel { display: flex; flex-direction: column; }
.settings-shell__panel > .card-body { flex: 1 1 auto; }

/* Six sections edit nothing inline — roles, locations and client groups commit from
   their dialogs, and attributes, selling constraints and stock statuses are read-only
   lists — so their footer holds the metadata line alone, with no Save beside it. The
   footer's height came from that button (10px padding + a 31px btn-sm = 51px); without
   it the bar would collapse to ~39px on exactly those six and the whole block would
   change height as you tab between sections. That is the drift change 0077 measured and
   fixed, so the height is pinned here instead of being an accident of the content. */
.settings-shell__panel > .card-footer { min-height: 51px; }

/* A selected item is a tab, not a visited link: the primary rail is the part
   that says "you are here" at a glance, before colour or weight register.

   Fill / colour / weight moved here from a `style` attribute repeated on all 14
   pages (change 0085) — one rule now, and the `.is-wip` muting below cannot be
   beaten by an inline declaration when the active section is a muted one. */
#settings-config-nav [aria-current="page"] {
  position: relative;
  background: var(--color-primary-50);
  color: var(--color-primary-700);
  font-weight: 600;
}
#settings-config-nav [aria-current="page"]::before {
  content: "";
  position: absolute;
  left: 0; top: 6px; bottom: 6px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--color-primary);
}

/* The header must not change height between sections — a section whose actions
   differ would shift the whole shell down the page as you navigate. */
.page-header .page-actions { min-height: 36px; align-items: center; }

/* ==========================================================================
   Client Groups — the member roster inside Add / Edit (change 0085)

   A group is location-scoped, so the picker is a roster of the clients at that
   location rather than a free-text field. Checkbox left, label right — the same
   shape every Y/N row in the portal uses.
   ========================================================================== */

.cg-search { max-width: none; }

.cg-roster {
  display: flex;
  flex-direction: column;
  max-height: 244px;                 /* ~5 rows, then it scrolls inside the dialog */
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.cg-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 12px;
  cursor: pointer;
  border-top: 1px solid var(--color-border);
}
.cg-row:first-child { border-top: 0; }
.cg-row:hover { background: var(--color-surface-alt); }
.cg-row[hidden] { display: none; }
/* The row is a <label>, so the whole strip toggles the box; the box still needs a
   focus ring of its own for anyone arriving by keyboard. */
.cg-row:focus-within { background: var(--color-primary-50); }

.cg-check { margin-top: 2px; flex: none; accent-color: var(--color-primary); }

.cg-row__text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
/* Non-bold: this is a value being chosen, not a heading (memory.md rule 5). */
.cg-row__name { font-size: 13px; color: var(--color-text); font-weight: 400; }
.cg-row__sub  { font-size: 11px; color: var(--color-text-subtle); }

.cg-tally {
  margin: 0;
  font-size: 12px;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* A location with no clients is a real state, not an error — say what it means for
   the group rather than showing an empty box. */
.cg-empty {
  margin: 0;
  padding: 14px 12px;
  font-size: 13px;
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   Sections still in development (change 0085)

   The nav is ordered finished-first; everything below the divider is shipped but
   unfinished. Muted rather than disabled — a section you cannot open is a section
   nobody can review, and these are exactly the ones under review.
   -------------------------------------------------------------------------- */
.settings-nav__wip-head {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--color-border);
}

/* `--color-text-muted`, not `--color-text-subtle`: subtle sits near 3:1 on the
   card and these are still links people have to read. Muted clears 4.5:1. */
#settings-config-nav .dropdown-item.is-wip { color: var(--color-text-muted); }
#settings-config-nav .dropdown-item.is-wip i { opacity: 0.65; }
/* Hover and the active state come back to full strength — the item is reachable,
   so it must not look inert once you are pointing at it or standing on it. */
#settings-config-nav .dropdown-item.is-wip:hover { color: var(--color-text); }
#settings-config-nav .dropdown-item.is-wip:hover i { opacity: 1; }
#settings-config-nav .dropdown-item.is-wip[aria-current="page"] { color: var(--color-primary-700); }
#settings-config-nav .dropdown-item.is-wip[aria-current="page"] i { opacity: 1; }

/* Tablet: when .cols-1-2 stacks, the Configuration nav would become a sparse
   full-width single column with a large empty band on its right. Flow the
   section links into space-filling columns instead. */
@media (max-width: 1100px) {
  #settings-config-nav {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 2px 8px;
  }
  /* A divider is a divider at every width: as a plain grid item it would sit in
     the first cell with links beside it, reading as a heading for that one link. */
  .settings-nav__wip-head { grid-column: 1 / -1; }
}

/* ==========================================================================
   Terminology — the name picker (change 0085)

   One card per concept. The candidate names are laid out as tiles rather than
   folded into a <select>, because the whole point of the section is that the
   trade has several words for one thing — a dropdown hides exactly that, and
   closes the list to a supplier whose word is not on it. A text field above the
   tiles both narrows the list and accepts a new name.
   ========================================================================== */

.pick-lead {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--color-text-muted);
  max-width: 72ch;
}

.pick-list { display: flex; flex-direction: column; gap: 12px; }

/* Ten concepts in one flat list read as one long form. The three groups are real
   divisions — your own records, the storage chain, the words for stock — so the
   heading earns its place rather than decorating the scroll. */
.pick-group {
  margin: 8px 0 0;
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
}
.pick-group:first-child { margin-top: 0; }

.pick-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  min-width: 0;
}

/* The concept and the frozen system name are the row's two fixed facts, so they
   hold the two ends of the head; everything the supplier can change sits below. */
.pick-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.pick-card__where {
  margin: -4px 0 0;
  font-size: 12px;
  color: var(--color-text-subtle);
}
/* A label, not data, so it takes the same treatment a column header does —
   `.data-table thead th`'s family / case / tracking (app.css:1124). The names
   beside it stay in the body face; the label is the only structural word here. */
.pick-card__where-label {
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-subtle);
  margin-right: 4px;
}

.pick-body { display: flex; flex-direction: column; gap: 8px; }

/* Singular and plural are one answer, so they sit on one line joined by the same
   slash the tiles use, rather than as two unrelated fields stacked apart. */
.pick-entry {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
/* Sized to content, not to the card: the longest name these hold is
   "Production Lot"/"Production Lots". A full-width box would say the opposite. */
.pick-entry__sg { max-width: 168px; }
.pick-entry__pl { max-width: 168px; }
.pick-entry__slash {
  color: var(--color-text-subtle);
  font-size: 14px;
  line-height: 1;
  user-select: none;
}

/* Wrapping flex, not a fixed grid: a track sized to the longest option stretches every
   tile to it, so "Meters (m)" reserved as much room as "Square Centimeters (sqcm)" and
   five short units spread across a whole row of half-empty boxes. Sized to content, the
   same five fit on one line — memory.md rule 9, and the reason it exists. */
.pick-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* Units of Measure has no rename button, so the tile drops the lane reserved for it. */
.pick-grid--plain .pick-opt { padding-right: 11px; }

/* The Regional Profile picker sits above the list and drives every axis below it. */
.uom-profile {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.pick-opt {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 38px;
  padding: 8px 30px 8px 11px;   /* right pad reserves the rename button's lane */
  font-size: 13px;
  color: var(--color-text);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 120ms, background-color 120ms;
}
.pick-opt:hover { border-color: var(--color-primary); }
.pick-opt:focus-visible {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.pick-opt[hidden] { display: none; }

.pick-opt__name { min-width: 0; overflow-wrap: anywhere; }

/* The pair reads as one answer with the singular leading: the plural is the same
   word inflected, so it takes a lighter colour rather than a second line. */
.pick-opt__sep { color: var(--color-text-subtle); margin: 0 3px; }
.pick-opt__pl  { color: var(--color-text-muted); }

/* The chosen name has to read as chosen from across the card, so it takes the
   primary fill — the tick is confirmation, not the signal by itself. */
.pick-opt.is-on {
  background: var(--color-primary-50);
  border-color: var(--color-primary);
  color: var(--color-primary-700);
  font-weight: 500;
}
.pick-opt.is-on::before {
  content: "✓";
  font-size: 12px;
  line-height: 1;
  color: var(--color-primary);
}

/* Revealed on hover or keyboard focus. Kept out of the flow so showing it never
   reflows the tile — a name that shifts sideways as the pointer arrives is
   harder to click than one that does not. */
.pick-opt__edit {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--color-text-subtle);
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms, color 120ms;
}
.pick-opt:hover .pick-opt__edit,
.pick-opt:focus-within .pick-opt__edit,
.pick-opt__edit:focus-visible { opacity: 1; }
.pick-opt__edit:hover { color: var(--color-primary); }
.pick-opt__edit i { width: 13px; height: 13px; }

/* Renaming happens in the tile, on both forms. The fields inherit the tile's type
   so the words do not jump size the moment they become editable. Stacked, because
   two fields side by side inside a 176px tile leave neither one readable. */
.pick-opt.is-editing { cursor: default; }
.pick-opt__edit-box {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  min-width: 0;
}
.pick-opt__field {
  width: 100%;
  min-width: 0;
  padding: 0;
  font: inherit;
  color: var(--color-text);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--color-border-strong);
  outline: none;
}
.pick-opt__field:focus { border-bottom-color: var(--color-primary); }
/* Matches how the plural reads at rest, so the editor looks like the tile it replaces. */
.pick-opt__field--pl { color: var(--color-text-muted); }

.pick-empty {
  margin: 0;
  font-size: 12px;
  color: var(--color-text-subtle);
}
.pick-empty b { color: var(--color-text); font-weight: 500; }

/* Catalog and Stock are never counted — the app writes "the Catalog", never
   "3 Catalogs". Those cards carry one field, and say why, instead of showing an
   empty plural box the operator would try to fill. */
.pick-note {
  margin: 0;
  font-size: 12px;
  color: var(--color-text-subtle);
}

/* Narrow: a tile whose label is longer than the panel must not force the page to
   scroll sideways, so it wraps its text instead. The two entry fields split the row. */
@media (max-width: 560px) {
  .pick-opt { max-width: 100%; }
  .pick-entry__sg,
  .pick-entry__pl { flex: 1 1 0; max-width: none; min-width: 0; }
}

/* ---------- Client Types: what the mapping costs ---------------------------
   Method, Base and Effective do not hold anything — they restate the mapped
   price list in money, against one sample base, so seven tiers can be compared
   down a column instead of worked out one at a time. Fixed and narrow: figures
   are read down their right edge, and the mapping column keeps the room its
   region, badge and rate need.

   Base is muted because it is the same figure on every row — the constant the
   comparison is made against, not a result. Effective is the result. */
#client-types th.col-ct-method,
#client-types td.col-ct-method { width: 140px; }
#client-types th.col-ct-base,
#client-types td.col-ct-base   { width: 90px; }
#client-types th.col-ct-eff,
#client-types td.col-ct-eff    { width: 104px; }
#client-types td.col-ct-eff    { font-weight: 500; }
/* ---------- Product Types: the Variants column -----------------------------
   Two of seven rows carry content and five carry an em dash, so the column is
   pinned rather than shared: left to size itself it would collapse to the width
   of "—" and drop `Thickness · Finish` onto two lines on the only rows that say
   anything. Sized to that string plus the usual ~20% slack. */
#product-types th.col-variants,
#product-types td.col-variants { width: 158px; }
