/* app/set-data.css — page-local styles for Data Model + Features.
   ============================================================================================
   Prefix every selector `.e8-set-data-`. Shared grammar lives in app/set-core.css and must not
   be duplicated here; if a page needs a new shared primitive, that is a core change, not a
   local override. Tokens only — no hex, no raw font sizes.

   WHAT IS ACTUALLY IN HERE, and why each piece could not just come from core.

   1. THE DEPENDENT WRAPPER (`.e8-set-data-dep`). Features is the master/dependent page, so its
      dependent rows have to be dimmed and made inert AS A GROUP — the reference calls out
      per-child dimming as a signature failure. One wrapper element carrying one class is the
      only way to do that, and a wrapper is exactly what core's row-divider rule does not expect:
      `.e8-set-card > * + *::before` reaches the wrapper but not the rows inside it. So this file
      re-states that ONE rule scoped to the wrapper's children. It is the same declaration with
      the same variables, not a second opinion about what a divider looks like — the day
      `--set-card-pad-x` or `--set-line` moves in core, both follow.

   2. THE MASTER ROW'S FILL (`.e8-set-data-master`). Core's `--set-tint` is what a card HEADER is
      painted with — a static strip that names the card. The Features master row is the opposite:
      the one control on the card that governs everything under it. Both wearing the identical
      fill meant the same tint carried two meanings across the surface (a critic measured them
      byte-identical: `color(srgb 0.94902 0.94902 0.960784 / 0.8)` on the master row and on the
      card headers of Stages, Labels, Import and Templates). `--set-tint` stays the card-header
      register; an operable tinted row gets a faint accent wash instead. This is the only
      declaration in this file that deliberately DISAGREES with a core value rather than
      re-stating it, and the specificity note is on the rule itself.

   3. THE MASTER ROW'S BOTTOM HAIRLINE — worth knowing, but NOT a rule in this file. Core draws it
      as the dependent wrapper's own `::before`. Opacity applies to a whole subtree including its
      pseudo-elements, so fading the WRAPPER when the master is off would fade that boundary too
      and the same card would show a crisp line in one toggle state and a nearly invisible one in
      the other. The fix is where the fade is applied, not a replacement hairline: `.is-locked > *`
      fades the rows and leaves the wrapper — and therefore its `::before` — at full strength. See
      the comment on that rule. (An earlier version of this header claimed the line was redrawn
      from the row above and core's pseudo-element suppressed. No such rule was ever in the file.)

   4. THE COVERAGE METER. Data Model reports how many records actually carry each attribute. The
      percentage is DATA, so it arrives as a custom property on the element and this file only
      says how wide a percentage is drawn. Nothing in core is a meter.
   ============================================================================================ */

/* ---------- Data Model · detail view ----------------------------------------------------------
   The drill-down's way back out. Pulled left by the button's own 13px padding so its glyph lines
   up with the page title's optical left edge rather than sitting one control-inset in from it. */
.e8-set-data-back { margin: var(--ui-space-4) 0 0 -13px; }
/* Core gives every section 30px of clearance from whatever precedes it, which is the right gap
   under a page title and too much under a 34px button. Stated, not fudged with a negative margin. */
.e8-set-data-back + .e8-set-section { margin-top: var(--ui-space-3); }

/* ---------- Data Model · coverage meter -------------------------------------------------------
   Sits in the row's control slot, so it sizes to its content like every other control there. */
.e8-set-data-cov {
  display: inline-flex;
  align-items: center;
  gap: var(--ui-space-2);
}
.e8-set-data-cov-track {
  flex: none;
  width: 56px;
  height: 4px;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-fill);
  overflow: hidden;
}
.e8-set-data-cov-fill {
  display: block;
  height: 100%;
  /* The measured value, handed in as a custom property by the JSX. The fallback is 0% so a field
     with no measurement draws an empty track rather than a full one. */
  width: var(--e8-set-data-pct, 0%);
  border-radius: inherit;
  background: color-mix(in srgb, var(--ui-accent) 72%, transparent);
}
.e8-set-data-cov-n {
  /* Tabular numerals and a reserved width: without both, six rows of percentages ripple as the
     digit count changes and the column stops reading as a column. */
  min-width: 30px;
  text-align: right;
  font-size: var(--ui-text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ui-text-secondary);
}
/* A thinly-populated attribute is the only thing this meter is for. Warning-tinted rather than
   red: it is an observation about the data, not an error the user has made. */
.e8-set-data-cov.is-thin .e8-set-data-cov-fill {
  background: color-mix(in srgb, var(--ui-warning) 78%, transparent);
}

/* ---------- Features · master row --------------------------------------------------------------
   Core marks the row tinted (`is-tinted`) and draws the hairline under it, as the dependent
   wrapper's `::before`. Two things are added on top.

   The 600 weight, because the master row heads its card exactly as `.e8-set-cardhead-t` heads
   one that has a header strip. That part IS the same job, so it reads the same.

   The fill, because the rest of the job is not the same. A card header is a static label; this row
   is the switch that locks and unlocks everything beneath it, and painting the two with the same
   `--set-tint` made one tint mean both things across the whole surface. So the operable row gets a
   faint accent wash and the card-header register is left to core, untouched.

   SPECIFICITY, deliberately: `.e8-set-data-master.is-tinted` is two classes, matching core's
   `.e8-set-row.is-tinted` exactly rather than out-weighing it, and wins only because
   app/set-data.css is linked after app/set-core.css in "ELEV8 ATS.html". A single-class
   `.e8-set-data-master` would LOSE and this rule would silently do nothing. The selector still
   opens with the file's `.e8-set-data-` prefix, so it does not reach outside these two pages.

   8% is measured, not picked: over the white card it composites to rgb(241,236,255) — plainly
   violet next to `--set-tint`'s rgb(245,245,247), and still quieter than any control on the row.
   Dark mode inverts for free because `--ui-accent` is itself lightened there. */
.e8-set-data-master .e8-set-row-label { font-weight: 600; }
.e8-set-data-master.is-tinted { background: color-mix(in srgb, var(--ui-accent) 8%, transparent); }

/* ---------- Features · dependent block ----------------------------------------------------------
   Core sets `position: relative` on direct card children only, and these rows are one level deeper
   inside the wrapper. Both halves of core's divider mechanism therefore have to be restated for the
   nested case — same variables, same declaration, so the day `--set-card-pad-x` or `--set-line`
   moves in core these follow rather than disagreeing. */
.e8-set-data-dep > * {
  position: relative;
  transition: opacity 160ms ease;
}
.e8-set-data-dep > * + *::before {
  content: '';
  position: absolute;
  top: 0;
  left: var(--set-card-pad-x);
  right: var(--set-card-pad-x);
  height: 1px;
  background: var(--set-line);
}

/* THE dependent state — one class, on the group, exactly once. Glyph, label, description and
   control fade together as a unit; the named failure mode is a page that greys the control and
   leaves the label black, and `> *` cannot produce that because it never reaches inside a row.

   Why the fade is on the ROWS and not on the wrapper, which would be the obvious place: opacity
   applies to a whole rendered subtree INCLUDING pseudo-elements, and the hairline separating the
   tinted master row from this block is the wrapper's own `::before`. Fading the wrapper fades that
   boundary too, so the same card would show a crisp line with the master on and a nearly invisible
   one with it off. Fading the children instead leaves the block bracketed by two full-strength
   rules — its top from the wrapper, its bottom from the always-live history row below — with only
   the interior dimmed. That is what makes it read as one inert slab rather than a rendering fault.

   `pointer-events` stops the mouse and nothing else. The `disabled` attribute each dependent
   control carries, bound to the same master state in the JSX, is what keeps it out of the tab
   order — CSS cannot enforce that and must not be trusted to. */
.e8-set-data-dep.is-locked { pointer-events: none; }
.e8-set-data-dep.is-locked > * { opacity: 0.42; }
/* A control that is disabled INSIDE a locked block must not dim twice. Core fades a disabled
   select to 0.45 on its own; multiplied by the block's 0.42 that lands near 0.19 — a control so
   faint it reads as a rendering fault, and the exact uneven half-state the group dim exists to
   avoid. Inside the wrapper the group opacity is the only one that applies. */
.e8-set-data-dep.is-locked .e8-set-select.is-disabled,
.e8-set-data-dep.is-locked .e8-set-input.is-disabled { opacity: 1; }

/* ---------- narrow -----------------------------------------------------------------------------
   After every rule above, deliberately: a conditional at-rule adds no specificity, so one written
   before the rule it overrides never applies in any state. */

/* At 640 core turns the control slot full-width and stacks it under the label. The meter has to
   follow, or it strands a 56px track against the left edge of a full-width row. */
@media (max-width: 640px) {
  .e8-set-data-cov { width: 100%; }
  .e8-set-data-cov-track { flex: 1 1 auto; width: auto; }
}

/* Matches the transition declared on `.e8-set-data-dep > *` above — the same subject, not the
   wrapper, or this would silently guard nothing. */
@media (prefers-reduced-motion: reduce) {
  .e8-set-data-dep > * { transition: none; }
}
