/* Application shell — sidebar, profile menu, screen chrome, states.
 *
 * Loaded after tokens.css and style.css. Every value here is a design
 * token: this file is outside the literal baseline, so a raw hex or an
 * off-scale length fails `designSystem.test.mjs` rather than shipping.
 *
 * The layout is a two-column grid on the desktop and a bottom tab bar
 * on a phone — the same three destinations, reachable with a thumb.
 * That is the 09-mobile rule: the navigation changes shape, never
 * content, so a seller who learned the app on a laptop already knows
 * where things are on the phone.
 */

/* The landing is a different surface entirely and hides the app; the
   shell has to hide with it or an anonymous visitor sees a sidebar
   floating over the marketing page. */
html.mg-landing .mg-app { display: none; }

.mg-app {
  display: grid;
  grid-template-columns: var(--mg-nav-width) minmax(0, 1fr);
  align-items: start;
  max-width: var(--mg-shell-max-width);
  margin: 0 auto;
}

/* `#root` still carries the pre-IA editorial cap from style.css, which was
   right when it WAS the page and is wrong now that it is one column of the
   app grid. Two nested caps meant the operational shell resolved to roughly
   half the window: the summary tiles had a whole screen of empty space to
   their right and still stacked one per row. The grid above owns the width
   now — `--mg-shell-max-width` is the wide operational measure, and the
   ledger and the tile row are what want it. */
.mg-app > .mg-app-shell {
  max-width: none;
  width: 100%;
}

/* ── sidebar ── */

/* Sticky rather than full-height: pinning the rail to the viewport
   needs a viewport-relative length, which is off the scale, and it buys
   nothing — the nav travels with the reader either way, and on a short
   screen a rule running past the last item is a line with nothing left
   to separate. */
.mg-side {
  position: sticky;
  top: var(--mg-space-0);
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-250);
  padding: var(--mg-nav-padding-y) var(--mg-nav-padding-x);
  border-right: var(--mg-border-width-hairline) solid var(--mg-nav-border);
  box-sizing: border-box;
}

.mg-side-label {
  font-family: var(--mg-type-eyebrow-family);
  font-size: var(--mg-type-eyebrow-size);
  font-weight: var(--mg-type-eyebrow-weight);
  letter-spacing: var(--mg-type-eyebrow-tracking);
  text-transform: var(--mg-type-eyebrow-transform);
  color: var(--mg-nav-group-label);
  padding: var(--mg-space-0) var(--mg-nav-item-padding-x);
}

.mg-side-nav {
  display: flex;
  flex-direction: column;
  gap: var(--mg-nav-item-gap);
}

.mg-side-item {
  display: flex;
  align-items: center;
  gap: var(--mg-space-125);
  padding: var(--mg-nav-item-padding-y) var(--mg-nav-item-padding-x);
  border-radius: var(--mg-nav-item-radius);
  color: var(--mg-nav-item-text);
  text-decoration: none;
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  font-weight: var(--mg-type-control-weight);
  transition: var(--mg-transition-control);
}

.mg-side-item:hover { color: var(--mg-nav-item-hover-text); }

.mg-side-item-active {
  color: var(--mg-nav-item-active-text);
  background: var(--mg-nav-item-active-fill);
}

.mg-side-item:focus-visible,
.mg-profile-button:focus-visible {
  outline: var(--mg-border-width-rail) solid var(--mg-state-focus);
  outline-offset: var(--mg-space-25);
}

.mg-side-icon {
  flex: none;
  display: inline-flex;
  width: var(--mg-space-250);
  height: var(--mg-space-250);
}

.mg-side-icon svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--mg-border-width-rail);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ADR-053 theme toggle icon. The sun and moon ship as inline SVG the app owns,
   so a latin-subset font can never drop them the way a Unicode glyph can. The
   button offers the mode it switches TO — the sun under a dark theme, the moon
   under light — so the icon is derived from the applied theme, using the same
   [data-theme] + prefers-color-scheme resolution the rest of the sheet uses.
   Deriving it from the root (not a JS-set attribute) keeps first paint correct
   before the deferred module runs. */
.mg-theme-toggle { display: inline-flex; align-items: center; justify-content: center; }
.mg-theme-icon {
  display: none;
  width: var(--mg-space-200);
  height: var(--mg-space-200);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--mg-border-width-rail);
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Dark active (pinned, or the unpinned default) offers light → show the sun. */
:root[data-theme="dark"] .mg-theme-icon-sun,
:root:not([data-theme]) .mg-theme-icon-sun { display: block; }
/* Light active offers dark → show the moon. */
:root[data-theme="light"] .mg-theme-icon-moon { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) .mg-theme-icon-sun { display: none; }
  :root:not([data-theme]) .mg-theme-icon-moon { display: block; }
}

/* ── profile control (the only door to the account surface) ── */

.mg-profile { position: relative; }

.mg-profile-button {
  display: inline-flex;
  align-items: center;
  gap: var(--mg-space-75);
  padding: var(--mg-space-50) var(--mg-space-100);
  border: var(--mg-border-width-hairline) solid var(--mg-control-border);
  border-radius: var(--mg-radius-pill);
  background: var(--mg-control-fill);
  /* Body ink, not control-meta: the only glyph that inherits this is the ▾
     disclosure caret (the avatar pill carries its own colour), and at meta grey
     it was nearly lost on the dark lozenge — the caret is the affordance that
     says this pill opens a menu, so it reads a step brighter. */
  color: var(--mg-text-body);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  cursor: pointer;
  transition: var(--mg-transition-control);
}

.mg-profile-button:hover { border-color: var(--mg-control-active-border); color: var(--mg-control-active-text); }

.mg-profile-initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--mg-space-250);
  height: var(--mg-space-250);
  border-radius: var(--mg-radius-pill);
  background: var(--mg-verdict-profit-soft);
  color: var(--mg-verdict-profit-text);
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-font-weight-600);
}

.mg-profile-menu {
  position: absolute;
  right: var(--mg-space-0);
  top: calc(100% + var(--mg-space-75));
  z-index: 20;
  min-width: var(--mg-size-notice-max);
  max-width: var(--mg-size-measure);
  display: flex;
  flex-direction: column;
  padding: var(--mg-space-75);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-surface-raised);
}

.mg-profile-menu[hidden] { display: none; }

.mg-profile-email {
  padding: var(--mg-space-75) var(--mg-space-100);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  overflow-wrap: anywhere;
}

.mg-profile-menu a {
  padding: var(--mg-space-100);
  border-radius: var(--mg-nav-item-radius);
  color: var(--mg-text-body);
  text-decoration: none;
  font-size: var(--mg-type-body-sm-size);
  transition: var(--mg-transition-control);
}

.mg-profile-menu a:hover { background: var(--mg-surface-card-hover); color: var(--mg-text-primary); }

.mg-profile-sep {
  margin: var(--mg-space-75) var(--mg-space-0);
  border: 0;
  border-top: var(--mg-border-width-hairline) solid var(--mg-border-hairline);
}

/* ── screen chrome (shared by every tab) ── */

.mg-screen { display: block; }

.mg-screen-head {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-100);
  padding-top: var(--mg-shell-head-padding-top);
}

.mg-screen-head h2 {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-screen-title-family);
  font-size: var(--mg-type-screen-title-size);
  font-weight: var(--mg-type-screen-title-weight);
  line-height: var(--mg-type-screen-title-leading);
  letter-spacing: var(--mg-type-screen-title-tracking);
  color: var(--mg-text-primary);
}

/* The signature green period closes every in-app screen heading, the same mark
   the landing wordmark and the mockups carry. It was only ever green on the
   landing; in the app the span rendered in the heading's own ink. */
.mg-screen-head h2 .mg-period { color: var(--mg-verdict-profit-text); }

.mg-lede {
  margin: var(--mg-space-0);
  max-width: var(--mg-size-measure);
  font-family: var(--mg-type-lede-family);
  font-size: var(--mg-type-lede-size);
  line-height: var(--mg-type-lede-leading);
  color: var(--mg-text-body);
}

.mg-basis {
  margin-top: var(--mg-basis-margin-top);
  color: var(--mg-basis-color);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  letter-spacing: var(--mg-type-basis-tracking);
}

.mg-screen-body { margin-top: var(--mg-shell-section-gap); }

/* ── window / control form ── */

.mg-window {
  display: flex;
  flex-direction: column;
  gap: var(--mg-control-gap);
  margin-top: var(--mg-shell-section-gap);
}

.mg-window-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--mg-control-gap);
}

.mg-window-row-secondary { align-items: center; }

/* ── Window pill: the timeframe control collapsed into the header, as the
   mockups lead every data screen. The popover mirrors the ledger column
   picker — a small dialog anchored under its trigger, hidden until asked for,
   closed by an outside click or Escape (see windowControl.mjs). */
.mg-window-control { position: relative; align-self: flex-start; }

.mg-window-trigger {
  display: inline-flex;
  align-items: baseline;
  gap: var(--mg-space-75);
  padding: var(--mg-control-padding-y) var(--mg-control-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-control-border);
  border-radius: var(--mg-control-radius);
  background: var(--mg-control-fill);
  color: var(--mg-control-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  cursor: pointer;
}

.mg-window-trigger:hover { background: var(--mg-button-hover-fill); }
.mg-window-trigger:focus-visible { outline: none; border-color: var(--mg-control-focus-border); }

.mg-window-cap {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}

.mg-window-label { color: var(--mg-text-body); }
.mg-window-span { font-family: var(--mg-type-control-family); color: var(--mg-text-meta); }
.mg-window-caret { color: var(--mg-text-meta); }

.mg-window-pop {
  position: absolute;
  left: var(--mg-space-0);
  top: calc(100% + var(--mg-space-75));
  z-index: 20;
  min-width: var(--mg-size-tile-min);
  padding: var(--mg-space-100);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-surface-raised);
}

.mg-window-pop[hidden] { display: none; }

.mg-window-form { display: flex; flex-direction: column; gap: var(--mg-control-gap); }
.mg-window-poplabel { margin-top: var(--mg-space-25); }
.mg-window-dates { display: flex; gap: var(--mg-space-75); }
.mg-window-dates .mg-field { flex: 1; min-width: var(--mg-space-0); }
.mg-window-dates .mg-field input { width: 100%; box-sizing: border-box; }
.mg-window-apply { width: 100%; }

.mg-field-inline { flex-direction: row; align-items: center; gap: var(--mg-space-75); }

.mg-field { display: flex; flex-direction: column; gap: var(--mg-space-50); }

.mg-field label {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}

.mg-field input {
  padding: var(--mg-control-padding-y) var(--mg-control-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-control-border);
  border-radius: var(--mg-control-radius);
  background: var(--mg-control-fill);
  color: var(--mg-control-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
}

.mg-field input:focus-visible { outline: none; border-color: var(--mg-control-focus-border); }

/* ── buttons ── */

.mg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--mg-button-padding-y) var(--mg-button-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-button-border);
  border-radius: var(--mg-button-radius);
  background: var(--mg-button-fill);
  color: var(--mg-button-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  font-weight: var(--mg-type-control-weight);
  text-decoration: none;
  cursor: pointer;
  transition: var(--mg-transition-control);
}

.mg-btn:hover { background: var(--mg-button-hover-fill); border-color: var(--mg-button-hover-border); }

.mg-btn-primary {
  background: var(--mg-button-primary-fill);
  border-color: var(--mg-button-primary-fill);
  color: var(--mg-button-primary-text);
}

.mg-btn-primary:hover { background: var(--mg-button-primary-hover-fill); border-color: var(--mg-button-primary-hover-fill); }

/* ── summary tiles ── */

.mg-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--mg-tile-min-width), 1fr));
  gap: var(--mg-tile-gap);
}

.mg-tile {
  display: flex;
  flex-direction: column;
  gap: var(--mg-tile-label-margin-bottom);
  padding: var(--mg-tile-padding-y) var(--mg-tile-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-tile-border);
  border-radius: var(--mg-tile-radius);
  background: var(--mg-tile-fill);
}

.mg-tile-label {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}

.mg-tile-value {
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-figure-number-size);
  font-weight: var(--mg-type-figure-number-weight);
  font-feature-settings: var(--mg-type-figure-number-features);
  letter-spacing: var(--mg-type-figure-number-tracking);
  color: var(--mg-text-primary);
}

.mg-tile-primary .mg-tile-value {
  font-family: var(--mg-type-headline-number-family);
  font-size: var(--mg-type-headline-number-size);
  font-weight: var(--mg-type-headline-number-weight);
  font-feature-settings: var(--mg-type-headline-number-features);
  letter-spacing: var(--mg-type-headline-number-tracking);
}

/* Colour carries state and nothing else: a positive net is green, a
   negative one red, and an unknown one stays neutral rather than
   picking a side. */
.mg-tile-value[data-state="pos"] { color: var(--mg-verdict-profit); }
.mg-tile-value[data-state="neg"] { color: var(--mg-verdict-loss); }
.mg-tile-value[data-state="unknown"] { color: var(--mg-text-meta); }

.mg-dash-currency + .mg-dash-currency { margin-top: var(--mg-space-500); }

.mg-dash-currency-head {
  margin: var(--mg-space-0) var(--mg-space-0) var(--mg-space-150);
  font-family: var(--mg-type-column-head-family);
  font-size: var(--mg-type-column-head-size);
  font-weight: var(--mg-type-column-head-weight);
  letter-spacing: var(--mg-type-column-head-tracking);
  text-transform: var(--mg-type-column-head-transform);
  color: var(--mg-text-meta);
}

.mg-dash-coverage {
  margin: var(--mg-space-150) var(--mg-space-0) var(--mg-space-0);
  max-width: var(--mg-size-measure);
  color: var(--mg-text-meta);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
}

.mg-dash-coverage[data-state="complete"] { color: var(--mg-verdict-profit); }

/* ── views + customization (the toolbar) ── */

.mg-segmented { display: inline-flex; gap: var(--mg-space-25); }

.mg-chip {
  padding: var(--mg-pill-padding-y) var(--mg-pill-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-control-border);
  border-radius: var(--mg-radius-pill);
  background: var(--mg-control-fill);
  color: var(--mg-control-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  cursor: pointer;
  transition: var(--mg-transition-control);
}

.mg-chip:hover { background: var(--mg-button-hover-fill); }

.mg-chip-active {
  border-color: var(--mg-control-active-border);
  background: var(--mg-control-active-fill);
  color: var(--mg-control-active-text);
}

.mg-field select {
  padding: var(--mg-control-padding-y) var(--mg-control-padding-x);
  /* A section-closing rule, not a group hairline: a dropdown is an input the
     reader acts on, so it earns the same strong edge the editable ledger cells
     do. On the dark ground a hairline sat a single step off the fill and read as
     static text until you found the chevron. */
  border: var(--mg-border-width-hairline) solid var(--mg-border-strong);
  border-radius: var(--mg-control-radius);
  background: var(--mg-control-fill);
  color: var(--mg-control-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
}

.mg-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--mg-space-75);
  color: var(--mg-text-body);
  font-size: var(--mg-type-body-sm-size);
  cursor: pointer;
}

/* The brand green, never the browser's default blue accent — the same rule the
   ledger column picker and settings preferences already follow. */
.mg-toggle input { accent-color: var(--mg-verdict-profit); }

.mg-customize {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-75);
  align-items: flex-start;
  max-width: var(--mg-size-notice-max);
  padding: var(--mg-panel-padding-y) var(--mg-panel-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-panel-fill);
}

.mg-customize-head {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}

.mg-customize-row {
  display: flex;
  align-items: center;
  gap: var(--mg-space-75);
  color: var(--mg-text-body);
  font-size: var(--mg-type-body-sm-size);
  cursor: pointer;
}

.mg-customize-note {
  margin: var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}

/* ── tile comparison ── */

.mg-tile-sub {
  color: var(--mg-text-meta);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
}

.mg-tile-sub a { color: var(--mg-verdict-profit); text-decoration: none; }
.mg-tile-sub a:hover { text-decoration: underline; }

/* A delta's colour says whether the movement was GOOD, not which way it
   pointed — fees going up is not a green number. */
.mg-tile-delta {
  margin-top: var(--mg-tile-delta-margin-top);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-text-meta);
}

.mg-tile-delta[data-tone="good"] { color: var(--mg-verdict-profit); }
.mg-tile-delta[data-tone="bad"] { color: var(--mg-verdict-loss); }
.mg-tile-delta-basis { color: var(--mg-text-meta); }

/* ── where the revenue goes ── */

.mg-panel {
  margin-top: var(--mg-panel-gap);
  padding: var(--mg-panel-padding-y) var(--mg-panel-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-panel-fill);
}

.mg-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--mg-space-125);
  margin-bottom: var(--mg-panel-head-margin-bottom);
}

.mg-panel-head h4 {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  font-weight: var(--mg-type-panel-title-weight);
  color: var(--mg-text-primary);
}

.mg-panel-sub, .mg-panel-foot {
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}

.mg-panel-foot { margin: var(--mg-chart-foot-padding-top) var(--mg-space-0) var(--mg-space-0); }

.mg-donut-wrap {
  position: relative;
  width: var(--mg-size-donut);
  max-width: 100%;
  margin-inline: auto;
}

.mg-donut { display: block; width: 100%; height: auto; }

.mg-donut-track { stroke: var(--mg-dataviz-donut-track); }

/* The placeholder ring in the no-data allocation panel takes a mid neutral that
   carries similar weight on both grounds, so it reads as an intentional "the
   split appears here" state rather than an absent graphic — the faint track all
   but vanished on the off-white paper and read weakly on the dark ground too. */
.mg-donut-empty .mg-donut-track { stroke: var(--mg-dataviz-donut-2); }

/* The empty allocation panel stretches to match the taller ranked chart beside
   it, so its ring + explanation are centred as a group in the space below the
   head rather than stranded at the top over a hollow lower half. */
.mg-alloc-empty { display: flex; flex-direction: column; }
.mg-alloc-empty-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--mg-space-300);
}

/* Verdict green for what the seller keeps; graded neutrals for what the
   costs took. Hue means verdict, never category. */
.mg-donut-arc[data-tone="verdict"] { stroke: var(--mg-verdict-profit); }
/* The two cost wedges take the ends of the donut ramp, not the middle share
   ramp — those two greys sit ~20 luminance levels apart in dark mode, too close
   to tell a slice (or its legend dot) from its neighbour. donut-1 (brightest,
   the largest cost) vs donut-3 (dimmest) reads clearly in both themes. */
.mg-donut-arc[data-tone="cogs"] { stroke: var(--mg-dataviz-donut-1); }
.mg-donut-arc[data-tone="fees"] { stroke: var(--mg-dataviz-donut-3); }

.mg-donut-center {
  position: absolute;
  inset: var(--mg-space-0);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.mg-donut-num {
  font-family: var(--mg-type-headline-number-family);
  font-size: var(--mg-type-headline-number-size);
  font-weight: var(--mg-type-headline-number-weight);
  font-feature-settings: var(--mg-type-headline-number-features);
  color: var(--mg-text-primary);
}

.mg-donut-sub {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}

/* Every wedge is named and numbered here, so identity never rests on
   telling two neutrals apart. */
.mg-legend { display: flex; flex-direction: column; gap: var(--mg-space-50); }

.mg-legend-row {
  display: flex;
  align-items: center;
  gap: var(--mg-space-75);
  font-size: var(--mg-type-body-sm-size);
  color: var(--mg-text-body);
}

.mg-legend-dot {
  width: var(--mg-pill-dot-size);
  height: var(--mg-pill-dot-size);
  border-radius: var(--mg-radius-pill);
  flex: none;
}

.mg-legend-dot[data-tone="verdict"] { background: var(--mg-verdict-profit); }
.mg-legend-dot[data-tone="cogs"] { background: var(--mg-dataviz-donut-1); }
.mg-legend-dot[data-tone="fees"] { background: var(--mg-dataviz-donut-3); }

.mg-legend-label { flex: 1; }

.mg-legend-share, .mg-legend-value {
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-ledger-number-size);
  font-feature-settings: var(--mg-type-ledger-number-features);
  color: var(--mg-text-primary);
}

.mg-legend-share { color: var(--mg-text-meta); }

/* ── states (08-states) ── */

.mg-notice {
  display: flex;
  flex-direction: column;
  max-width: var(--mg-notice-max-width);
  padding: var(--mg-notice-padding-y) var(--mg-notice-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-notice-border);
  border-radius: var(--mg-notice-radius);
  background: var(--mg-surface-card);
}

.mg-notice-error { border-color: var(--mg-notice-error-border); }

.mg-notice h3 {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  font-weight: var(--mg-type-panel-title-weight);
  line-height: var(--mg-type-panel-title-leading);
  color: var(--mg-text-primary);
}

/* The recovery card carries its tone in the heading, as the mockup does —
   clay-red is what names the failure, not just the border and the eyebrow.
   Placed after the base rule so it wins at equal specificity. */
.mg-notice-error h3 { color: var(--mg-verdict-loss); }

.mg-notice p {
  margin: var(--mg-space-125) var(--mg-space-0) var(--mg-space-0);
  color: var(--mg-text-body);
  font-size: var(--mg-type-body-size);
  line-height: var(--mg-type-body-leading);
}

.mg-notice-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--mg-space-125); }

.mg-notice-meta { color: var(--mg-text-meta); font-family: var(--mg-type-basis-family); font-size: var(--mg-type-basis-size); }

.mg-notice-tag {
  margin-bottom: var(--mg-space-150);
  font-family: var(--mg-type-eyebrow-family);
  font-size: var(--mg-type-eyebrow-size);
  font-weight: var(--mg-type-eyebrow-weight);
  letter-spacing: var(--mg-type-eyebrow-tracking);
  text-transform: var(--mg-type-eyebrow-transform);
  color: var(--mg-notice-tag-color);
}

.mg-notice-tag[data-tone="empty"] { color: var(--mg-verdict-profit-text); }
.mg-notice-tag[data-tone="loading"] { color: var(--mg-verdict-watch); }
.mg-notice-tag[data-tone="error"] { color: var(--mg-verdict-loss); }

.mg-notice-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mg-notice-actions-gap);
  margin-top: var(--mg-notice-actions-margin-top);
}

.mg-progress {
  margin-top: var(--mg-space-200);
  height: var(--mg-progress-height);
  border-radius: var(--mg-progress-radius);
  background: var(--mg-progress-track);
  overflow: hidden;
}

.mg-progress > span {
  display: block;
  height: 100%;
  background: var(--mg-progress-fill);
  transition: var(--mg-transition-layout);
}

/* A progress bar that carries a completeness verdict fills in the same tone as
   the figure it sits under: amber while a gap remains, green once it closes —
   so the bar and the number never disagree about whether the work is done. */
.mg-progress[data-tone="watch"] > span { background: var(--mg-verdict-watch); }

.mg-stream { display: flex; flex-direction: column; gap: var(--mg-progress-gap); margin-top: var(--mg-space-200); }

.mg-stream-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--mg-space-100);
  font-size: var(--mg-type-body-sm-size);
  color: var(--mg-text-body);
}

.mg-stream-item[data-status="done"] .mg-stream-icon { color: var(--mg-progress-done); }
.mg-stream-item[data-status="active"] .mg-stream-icon { color: var(--mg-progress-active); }
.mg-stream-item[data-status="wait"] { color: var(--mg-text-meta); }
.mg-stream-item[data-status="wait"] .mg-stream-icon { color: var(--mg-progress-waiting); }

.mg-stream-count { font-family: var(--mg-type-ledger-number-family); font-size: var(--mg-type-ledger-number-size); color: var(--mg-text-meta); }

.mg-rails { display: flex; flex-direction: column; gap: var(--mg-space-75); margin-top: var(--mg-space-175); }

.mg-rail {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--mg-rail-gap);
  padding: var(--mg-rail-padding-y) var(--mg-rail-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-rail-border);
  border-radius: var(--mg-rail-radius);
  font-size: var(--mg-type-body-sm-size);
  color: var(--mg-text-body);
}

.mg-rail[data-tone="ok"] .mg-rail-icon { color: var(--mg-rail-icon-ok); }
.mg-rail[data-tone="warn"] .mg-rail-icon { color: var(--mg-rail-icon-watch); }
.mg-rail[data-tone="blocked"] { background: var(--mg-rail-blocked-fill); border-color: var(--mg-rail-blocked-border); }
.mg-rail[data-tone="blocked"] .mg-rail-icon { color: var(--mg-rail-icon-blocked); }

.mg-rail-value { font-family: var(--mg-type-ledger-number-family); font-size: var(--mg-type-ledger-number-size); color: var(--mg-text-meta); }

/* ── onboarding / connect Amazon (mockup 02) ──
   A single-column, reading-width flow: eyebrow + serif head, then three
   numbered step cards (done / current / upcoming), a scope rail, a region
   picker + authorize action, and a subtle trust row. Only the live step
   carries the green outline. */

/* Centered in the content area — a focused single-column task, like the
   mockup's centered wrap, rather than a narrow strip pinned to the sidebar. */
.mg-onboard { max-width: var(--mg-size-notice-max); margin-inline: auto; }

.mg-onboard-nowrap { white-space: nowrap; }

.mg-onboard-eyebrow {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-eyebrow-family);
  font-size: var(--mg-type-eyebrow-size);
  font-weight: var(--mg-type-eyebrow-weight);
  letter-spacing: var(--mg-type-eyebrow-tracking);
  text-transform: var(--mg-type-eyebrow-transform);
  color: var(--mg-verdict-profit-text);
}

.mg-onboard-eyebrow[data-tone="error"] { color: var(--mg-verdict-loss); }

.mg-onboard-steps {
  list-style: none;
  margin: var(--mg-shell-section-gap) var(--mg-space-0) var(--mg-space-0);
  padding: var(--mg-space-0);
  display: grid;
  gap: var(--mg-space-175);
}

.mg-onboard-step {
  display: grid;
  grid-template-columns: var(--mg-space-400) 1fr;
  gap: var(--mg-space-250);
  align-items: start;
  padding: var(--mg-panel-padding-y) var(--mg-panel-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-panel-fill);
}

.mg-onboard-step[data-state="current"] { border-color: var(--mg-verdict-profit); }

.mg-onboard-badge {
  width: var(--mg-space-400);
  height: var(--mg-space-400);
  border-radius: var(--mg-radius-pill);
  border: var(--mg-border-width-hairline) solid var(--mg-border-strong);
  display: grid;
  place-items: center;
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-body-sm-size);
  color: var(--mg-text-meta);
}

.mg-onboard-step[data-state="done"] .mg-onboard-badge { border-color: var(--mg-verdict-profit); color: var(--mg-verdict-profit); }
.mg-onboard-step[data-state="current"] .mg-onboard-badge { border-color: var(--mg-verdict-profit); background: var(--mg-verdict-profit); color: var(--mg-button-primary-text); }

.mg-onboard-step-body h3 {
  margin: var(--mg-space-0) var(--mg-space-0) var(--mg-space-50);
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  font-weight: var(--mg-type-panel-title-weight);
  line-height: var(--mg-type-panel-title-leading);
  color: var(--mg-text-primary);
}

.mg-onboard-step-body > p {
  margin: var(--mg-space-0);
  color: var(--mg-text-body);
  font-family: var(--mg-type-lede-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-lede-leading);
}

.mg-onboard-scope {
  list-style: none;
  margin: var(--mg-space-175) var(--mg-space-0);
  padding: var(--mg-space-0);
  display: grid;
  gap: var(--mg-space-100);
}

.mg-onboard-scope > li {
  display: grid;
  grid-template-columns: var(--mg-space-200) 1fr;
  gap: var(--mg-space-100);
  align-items: start;
  color: var(--mg-text-body);
  font-family: var(--mg-type-lede-family);
  font-size: var(--mg-type-body-sm-size);
}

.mg-onboard-scope-icon { color: var(--mg-verdict-profit); font-family: var(--mg-type-ledger-number-family); }

/* The closing scope line is a muted mono footnote. Its own class (not the
   shared .mg-basis, which carries a margin-top) so it keeps the rail's even
   row rhythm instead of stranding a gap above it. */
.mg-onboard-scope-note {
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  letter-spacing: var(--mg-type-basis-tracking);
}

.mg-onboard-authorize {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--mg-space-150);
  margin-top: var(--mg-space-100);
}

/* The region picker shares a bottom edge with the Authorize button beside it, so
   it takes the button's vertical padding — otherwise the shorter default control
   height left the select looking stunted against the taller pill. */
.mg-onboard-region select { padding-block: var(--mg-button-padding-y); }

.mg-onboard-error { flex-basis: 100%; margin: var(--mg-space-0); }

/* A muted helper under the region picker; more specific than the step-body
   paragraph rule so it stays a small footnote, not body copy. */
.mg-onboard-step-body > .mg-onboard-region-note {
  margin-top: var(--mg-space-150);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  line-height: var(--mg-type-lede-leading);
}

.mg-onboard-trust {
  list-style: none;
  margin: var(--mg-space-400) var(--mg-space-0) var(--mg-space-0);
  padding: var(--mg-space-300) var(--mg-space-0) var(--mg-space-0);
  border-top: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--mg-space-150) var(--mg-space-400);
}

.mg-onboard-trust > li {
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  letter-spacing: var(--mg-type-basis-tracking);
  color: var(--mg-text-meta);
}

/* connected state — the withheld-cost note (framed) + the coming-soon card
   that replaces the form when Amazon connect is not yet enabled. */
.mg-onboard-note { margin-top: var(--mg-shell-section-gap); }
.mg-onboard-note > p {
  margin: var(--mg-space-0);
  color: var(--mg-text-body);
  font-family: var(--mg-type-lede-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-lede-leading);
}

.mg-coming-soon {
  margin-top: var(--mg-space-100);
  padding: var(--mg-panel-padding-y) var(--mg-panel-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-left: var(--mg-border-width-spine) solid var(--mg-verdict-profit);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-panel-fill);
}

.mg-coming-soon h3 {
  margin: var(--mg-space-0) var(--mg-space-0) var(--mg-space-100);
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  font-weight: var(--mg-type-panel-title-weight);
  color: var(--mg-text-primary);
}

.mg-coming-soon h3 .mg-period { color: var(--mg-verdict-profit-text); }
.mg-coming-soon p { margin: var(--mg-space-0); color: var(--mg-text-body); font-size: var(--mg-type-body-sm-size); }
.mg-coming-soon .mg-coming-soon-meta { margin-top: var(--mg-space-75); color: var(--mg-text-meta); font-family: var(--mg-type-basis-family); font-size: var(--mg-type-basis-size); }

@media (max-width: 560px) {
  .mg-onboard-region,
  .mg-onboard-region select,
  .mg-onboard-authorize-btn { width: 100%; }
  .mg-onboard-trust { grid-template-columns: 1fr; }
  /* Restrained card titles on a narrow screen so they don't compete with the
     page head or wrap awkwardly. */
  .mg-onboard-step-body h3 { font-size: var(--mg-font-size-800); }
  /* Stack the notice head on a phone so the mono meta drops UNDER the title
     instead of colliding with a title that has wrapped to two lines. */
  .mg-notice-head { flex-direction: column; align-items: flex-start; gap: var(--mg-space-50); }
}

/* ── responsive (09-mobile) ──
   Below the compact breakpoint the sidebar becomes a fixed bottom tab
   bar. The literal values in these conditions are the breakpoint tokens
   — CSS cannot read a custom property inside @media, and the guard
   allows exactly these two numbers. */

@media (max-width: 720px) {
  .mg-app { grid-template-columns: minmax(0, 1fr); }

  .mg-side {
    position: fixed;
    left: var(--mg-space-0);
    right: var(--mg-space-0);
    bottom: var(--mg-space-0);
    top: auto;
    z-index: 30;
    flex-direction: row;
    min-height: 0;
    gap: var(--mg-space-0);
    padding: var(--mg-space-75) var(--mg-space-100);
    border-right: 0;
    border-top: var(--mg-border-width-hairline) solid var(--mg-nav-border);
    background: var(--mg-shell-bar-fill);
  }

  .mg-side-label { display: none; }

  .mg-side-nav { flex: 1; flex-direction: row; justify-content: space-around; }

  .mg-side-item {
    flex: 1;
    flex-direction: column;
    gap: var(--mg-space-25);
    text-align: center;
    font-size: var(--mg-type-label-size);
  }

  /* The bar is fixed, so the last rows of every screen would sit under
     it without this. */
  .mg-app-shell { padding-bottom: var(--mg-space-1000); }

  /* The head's top pad is a desktop measure — it separates the title from the
     header rule across a wide canvas. On a phone the header already sits right
     above, and a full space-500 of it PLUS the shell's own space-300 top opened
     a dead band before the title on every screen. Trim both so the title reads
     near the top the way the native mockup does. */
  .mg-app > .mg-app-shell { padding-top: var(--mg-space-100); }
  .mg-screen-head { padding-top: var(--mg-space-150); }

  .mg-tiles { grid-template-columns: minmax(0, 1fr); }

  .mg-profile-menu { min-width: 0; left: var(--mg-space-0); right: var(--mg-space-0); }
}

@media (max-width: 560px) {
  .mg-side-item span:not(.mg-side-icon) { font-size: var(--mg-type-eyebrow-size); }
  .mg-window { gap: var(--mg-space-100); }
  .mg-field { flex: 1; }

  /* The popover spans the content column rather than overflowing the phone,
     and the two full dates stack — side by side they clip the day digits and
     collide with the calendar glyph at phone width. */
  .mg-window-pop { min-width: 0; left: var(--mg-space-0); right: var(--mg-space-0); }
  .mg-window-dates { flex-direction: column; }

  /* The head puts a serif title and its qualifier on one baseline. At phone
     width the qualifier claims half the row and the title wraps mid-phrase —
     "Cost / coverage", "Start with / these" — which reads as a broken layout
     rather than a heading. They stack instead. */
  .mg-panel-head {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--mg-space-25);
  }

  /* The header nav is sized for a laptop. A `<select>` will not shrink below
     its own content, so in a session that carries the developer switch-context
     picker the nav out-measured the viewport and pushed the DOCUMENT sideways
     — on every screen, not just the one showing the picker. The nav wraps to a
     second line and the picker yields its width first. Only an operator sees
     that control, but a header that scrolls the page sideways is a defect
     whoever is reading it. */
  body > header { flex-wrap: wrap; row-gap: var(--mg-space-75); }
  body > header nav { flex-wrap: wrap; min-width: 0; }
  .mg-developer-switch-picker { min-width: 0; max-width: 100%; }
}

.mg-window-error {
  flex-basis: 100%;
  margin: var(--mg-space-0);
  color: var(--mg-verdict-loss);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}

/* ── Tab 2 · SKU Calculator ───────────────────────────────────────── */

.mg-crumb {
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-text-meta);
  margin-bottom: var(--mg-space-75);
}

.mg-crumb a { color: var(--mg-text-meta); text-decoration: none; }
.mg-crumb a:hover { color: var(--mg-text-primary); text-decoration: underline; }

.mg-sku-block + .mg-sku-block { margin-top: var(--mg-space-500); }

/* The ledger is instrument density: a seller scans it, so the rules are
   hairlines and the numbers are monospaced to keep the columns aligned
   digit for digit. */
/* `position: relative` is load-bearing, not decoration. `overflow-x: auto`
   clips a normal-flow child, but NOT an absolutely positioned descendant
   whose containing block is further up — and a `.mg-visually-hidden` label
   is absolutely positioned. On a phone the head cell of the cost task list
   escaped this box and pushed the DOCUMENT to nearly twice the viewport,
   so every screen scrolled sideways into empty space. Making the scroller a
   containing block puts such a descendant back inside the thing that clips
   it. */
.mg-ledger-scroll { overflow-x: auto; position: relative; }

.mg-ledger {
  width: 100%;
  border-collapse: collapse;
  min-width: var(--mg-ledger-min-width);
}

.mg-ledger th {
  text-align: left;
  padding-bottom: var(--mg-ledger-head-padding-bottom);
  padding-right: var(--mg-ledger-cell-padding-x);
  border-bottom: var(--mg-border-width-hairline) solid var(--mg-ledger-rule);
  font-family: var(--mg-type-column-head-family);
  font-size: var(--mg-type-column-head-size);
  font-weight: var(--mg-type-column-head-weight);
  letter-spacing: var(--mg-type-column-head-tracking);
  text-transform: uppercase;
  color: var(--mg-text-meta);
}

.mg-ledger td {
  padding: var(--mg-ledger-row-padding-y) var(--mg-ledger-cell-padding-x) var(--mg-ledger-row-padding-y) var(--mg-space-0);
  border-bottom: var(--mg-border-width-hairline) solid var(--mg-ledger-rule);
  color: var(--mg-ledger-cell);
  font-size: var(--mg-type-body-sm-size);
}

.mg-ledger-row:hover td { background: var(--mg-ledger-row-hover); }

.mg-ledger-num {
  text-align: right;
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-ledger-number-size);
}

.mg-ledger th.mg-ledger-num { text-align: right; }

.mg-ledger-identity { display: flex; flex-direction: column; gap: var(--mg-space-25); }

.mg-ledger-identity a {
  color: var(--mg-ledger-identity);
  text-decoration: none;
  font-weight: var(--mg-font-weight-500);
}

.mg-ledger-identity a:hover { color: var(--mg-verdict-profit); text-decoration: underline; }

.mg-ledger-identity-sub {
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-ledger-identity-sub);
}

/* On the wide layout the head row labels every column, so the in-cell label
   is redundant — and `display: none` keeps it out of the accessibility tree
   too, leaving the `<th>` association as the single answer. It comes back
   below the dense breakpoint, where the card list has no head row. */
.mg-ledger-cell-label { display: none; }

.mg-ledger-verdict { color: var(--mg-ledger-verdict-cell); }
.mg-ledger-verdict[data-state="pos"] { color: var(--mg-verdict-profit); }
.mg-ledger-verdict[data-state="neg"] { color: var(--mg-verdict-loss); }
.mg-ledger-verdict[data-state="unknown"] { color: var(--mg-text-meta); }

/* A figure the reader changed is never allowed to look like Amazon's.
   The dot is redundant with the banner on purpose — colour alone would
   not carry it. */
.mg-modelled-dot { color: var(--mg-editable-unsaved-marker); margin-left: var(--mg-space-50); }

/* ── the ledger as a card list (09-mobile) ──
   "The wide desktop ledger becomes a native card list" is the approved
   mobile spec, and it is a correctness rule as much as a style one. At
   phone width a seven-column table showed SKU, units and price and put
   cost, fees, NET and margin past the right edge — the one figure the SKU
   Calculator exists to give was reachable only by finding a sideways swipe
   inside a panel, with nothing on screen suggesting one. The cost task
   list was worse: its Save control sat in the same hidden region, so a
   seller on a phone could not record a cost at all.
   Below the dense breakpoint each row becomes a card and each cell states
   its own column name, so nothing is off-screen and no number is read off
   a position the reader cannot see. */
@media (max-width: 560px) {
  .mg-ledger-scroll { overflow-x: visible; }
  .mg-ledger { display: block; min-width: 0; }
  .mg-ledger thead { display: none; }
  .mg-ledger tbody,
  .mg-ledger tr,
  .mg-ledger td { display: block; }

  .mg-ledger-row {
    padding: var(--mg-space-100) var(--mg-space-0);
    border-bottom: var(--mg-border-width-hairline) solid var(--mg-ledger-rule);
  }

  .mg-ledger td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--mg-space-100);
    padding: var(--mg-space-25) var(--mg-space-0);
    border-bottom: 0;
    text-align: right;
  }

  .mg-ledger-cell-label {
    display: block;
    flex: 0 0 auto;
    text-align: left;
    font-family: var(--mg-type-column-head-family);
    font-size: var(--mg-type-column-head-size);
    font-weight: var(--mg-type-column-head-weight);
    letter-spacing: var(--mg-type-column-head-tracking);
    text-transform: uppercase;
    color: var(--mg-text-meta);
  }

  /* The identity is the card's title, not one of its labelled fields. */
  .mg-ledger td.mg-ledger-identity {
    flex-direction: column;
    align-items: stretch;
    text-align: left;
    padding-bottom: var(--mg-space-75);
  }

  .mg-ledger td.mg-ledger-action { justify-content: flex-end; }
}

/* ── the ledger's working controls (group · filter · search · columns) ──
   A seller reads this list to find one product among many, so it carries the
   controls that make a long list tractable. Each is a pure view over data
   already loaded — none re-reads the window, so the list answers instantly. */

/* The ledger sits in one framed surface — toolbar as its header band, table
   and count line within — so the instrument reads as a defined object on the
   page rather than columns floating on the ground. Rows stay hairline-ruled
   inside it; the frame is a container, not per-row boxing. */
.mg-ledger-region {
  display: flex;
  flex-direction: column;
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-radius-card);
  background: var(--mg-surface-raised);
}

.mg-ledger-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--mg-space-150);
  padding: var(--mg-space-150) var(--mg-space-200);
  border-bottom: var(--mg-border-width-hairline) solid var(--mg-ledger-rule);
}

.mg-ledger-tables { padding: var(--mg-space-150) var(--mg-space-200) var(--mg-space-200); }

.mg-ledger-toolbar-l,
.mg-ledger-toolbar-r {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--mg-space-150);
}

.mg-ledger-tb-title {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-font-weight-600);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-primary);
}

.mg-ledger-segwrap { display: inline-flex; align-items: center; gap: var(--mg-space-75); }

.mg-ledger-seg-cap {
  font-family: var(--mg-type-eyebrow-family);
  font-size: var(--mg-type-eyebrow-size);
  letter-spacing: var(--mg-type-eyebrow-tracking);
  text-transform: var(--mg-type-eyebrow-transform);
  color: var(--mg-text-meta);
}

/* The result-filter chips carry a verdict dot, so the filter reads in the
   same colour language as the margins it filters. */
.mg-chip .mg-margin-dot { margin-right: var(--mg-space-50); }

.mg-ledger-search {
  display: inline-flex;
  align-items: center;
  gap: var(--mg-space-50);
  padding: var(--mg-space-50) var(--mg-space-100);
  border: var(--mg-border-width-hairline) solid var(--mg-control-border);
  border-radius: var(--mg-radius-control);
  background: var(--mg-control-fill);
}

.mg-ledger-search:focus-within { border-color: var(--mg-control-active-border); }

.mg-ledger-search-icon { color: var(--mg-text-meta); font-size: var(--mg-type-body-sm-size); }

.mg-ledger-search-input {
  border: 0;
  background: transparent;
  color: var(--mg-text-primary);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  outline: none;
}

.mg-ledger-search-input::placeholder { color: var(--mg-text-faint); }

.mg-ledger-cols { position: relative; }

.mg-ledger-cols-btn { display: inline-flex; align-items: center; gap: var(--mg-space-50); }

/* Mirrors the profile menu: a small dialog anchored under its trigger, hidden
   until asked for, closed by an outside click or Escape. */
.mg-ledger-cols-pop {
  position: absolute;
  right: var(--mg-space-0);
  top: calc(100% + var(--mg-space-75));
  z-index: 20;
  min-width: var(--mg-size-tile-min);
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-75);
  padding: var(--mg-space-100);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-surface-raised);
}

.mg-ledger-cols-pop[hidden] { display: none; }

.mg-ledger-cols-title {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}

.mg-ledger-cols-list { display: flex; flex-direction: column; gap: var(--mg-space-25); }

.mg-ledger-cols-item {
  display: flex;
  align-items: center;
  gap: var(--mg-space-75);
  padding: var(--mg-space-50) var(--mg-space-75);
  border-radius: var(--mg-radius-control);
  color: var(--mg-text-body);
  font-size: var(--mg-type-body-sm-size);
  cursor: pointer;
}

.mg-ledger-cols-item:hover { background: var(--mg-surface-card-hover); }

/* The native checkbox is themed to the brand green — nowhere in the app is
   the browser's default blue accent, and the picker must not be the exception. */
.mg-ledger-cols-item input { accent-color: var(--mg-verdict-profit); }

.mg-ledger-cols-lock {
  margin-left: auto;
  font-family: var(--mg-type-eyebrow-family);
  font-size: var(--mg-type-eyebrow-size);
  letter-spacing: var(--mg-type-eyebrow-tracking);
  text-transform: var(--mg-type-eyebrow-transform);
  color: var(--mg-text-faint);
}

.mg-ledger-cols-foot { display: flex; justify-content: flex-end; }

.mg-link {
  border: 0;
  background: none;
  padding: var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-body-sm-size);
  text-decoration: underline;
  cursor: pointer;
}

.mg-link:hover { color: var(--mg-text-primary); }

/* ── sortable heads + resizable columns ── */

.mg-ledger th.mg-ledger-sortable { position: relative; white-space: nowrap; }

/* The interactive sort is a real button inside the header cell, so the <th>
   keeps its column-header semantics. The button reads as the header text — it
   inherits the head's type and only adds a pointer and a focus ring. */
.mg-ledger-sort-btn {
  display: inline-flex;
  align-items: center;
  border: 0;
  background: none;
  padding: var(--mg-space-0);
  margin: var(--mg-space-0);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
}

.mg-ledger-sort-btn:hover .mg-ledger-head-label { color: var(--mg-text-primary); }

.mg-ledger-sort-btn:focus-visible {
  outline: var(--mg-border-width-rail) solid var(--mg-state-focus);
  outline-offset: var(--mg-space-25);
}

/* Every sortable head carries a caret so the whole row reads as sortable. The
   inactive carets are invisible until the head is hovered; the active one shows
   its direction in the verdict colour and always. */
.mg-ledger-sortmark { margin-left: var(--mg-space-50); }
.mg-ledger-sortmark[data-active="true"] { color: var(--mg-verdict-profit); }
.mg-ledger-sortmark[data-active="false"] { color: var(--mg-text-faint); opacity: 0; }
.mg-ledger-sort-btn:hover .mg-ledger-sortmark[data-active="false"] { opacity: 1; }

/* A grab strip over the column's right edge. Its centre straddles the border
   so the cursor lands on it without hunting. */
.mg-ledger-resizer {
  position: absolute;
  top: var(--mg-space-0);
  right: calc(var(--mg-space-50) * -1);
  width: var(--mg-space-100);
  height: 100%;
  cursor: col-resize;
  touch-action: none;
}

.mg-ledger-resizer:hover { background: var(--mg-border-strong); }

body.mg-ledger-resizing { user-select: none; cursor: col-resize; }

/* ── grouped rows ── */

.mg-ledger-group-row td {
  background: var(--mg-surface-raised);
  border-bottom-color: var(--mg-border-strong);
}

.mg-ledger-group-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--mg-space-50);
  border: 0;
  background: none;
  padding: var(--mg-space-0);
  color: var(--mg-text-primary);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  font-weight: var(--mg-font-weight-600);
  cursor: pointer;
}

.mg-ledger-caret { color: var(--mg-text-meta); }

/* A child under an ASIN group is indented behind a faint tree guide, so the
   parent→child relationship registers on a fast scan. */
.mg-ledger td.mg-ledger-child {
  padding-left: var(--mg-space-300);
  border-left: var(--mg-border-width-rail) solid var(--mg-ledger-rule);
}

/* The row is the click target for opening the SKU, so it reads as openable. */
.mg-ledger-row:not(.mg-ledger-group-row) { cursor: pointer; }

/* ── the margin verdict, in its most compact form ── */

/* The verdict pill is restrained: a neutral chip carrying a coloured dot and a
   coloured number, not a coloured fill. Colour states the judgment; it does not
   flood the cell. */
.mg-margin-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--mg-space-50);
  padding: var(--mg-pill-padding-y) var(--mg-pill-padding-x);
  border-radius: var(--mg-radius-pill);
  background: var(--mg-surface-card);
  color: var(--mg-text-primary);
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-basis-size);
  font-feature-settings: var(--mg-type-ledger-number-features);
}

.mg-margin-pill[data-tone="pos"] { color: var(--mg-verdict-profit-text); }
.mg-margin-pill[data-tone="watch"] { color: var(--mg-verdict-watch); }
.mg-margin-pill[data-tone="neg"] { color: var(--mg-verdict-loss); }
.mg-margin-pill[data-tone="unknown"] { background: transparent; color: var(--mg-text-meta); }

.mg-margin-dot {
  width: var(--mg-pill-dot-size);
  height: var(--mg-pill-dot-size);
  border-radius: var(--mg-radius-pill);
  flex: none;
  background: currentColor;
}

.mg-margin-dot[data-tone="pos"] { background: var(--mg-verdict-profit); }
.mg-margin-dot[data-tone="neg"] { background: var(--mg-verdict-loss); }
.mg-margin-dot[data-tone="watch"] { background: var(--mg-verdict-watch); }
.mg-margin-dot[data-tone="unknown"] { background: var(--mg-text-meta); }

/* ── the count line under the table ── */

.mg-ledger-foot {
  margin: var(--mg-space-150) var(--mg-space-0) var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  letter-spacing: var(--mg-type-basis-tracking);
}

.mg-ledger-foot b { color: var(--mg-text-primary); font-weight: var(--mg-font-weight-600); }
.mg-ledger-foot .mg-foot-pos { color: var(--mg-verdict-profit); }
.mg-ledger-foot .mg-foot-neg { color: var(--mg-verdict-loss); }

.mg-ledger-empty-row td {
  padding: var(--mg-space-300) var(--mg-space-0);
  color: var(--mg-text-meta);
  text-align: center;
  font-size: var(--mg-type-body-sm-size);
}

@media (max-width: 720px) {
  .mg-ledger-toolbar { align-items: stretch; }
  .mg-ledger-search { flex: 1; }
}

.mg-modelled-banner {
  margin: var(--mg-space-0) var(--mg-space-0) var(--mg-space-200);
  padding: var(--mg-space-100) var(--mg-space-150);
  border-left: var(--mg-border-width-spine) solid var(--mg-editable-unsaved-marker);
  background: var(--mg-verdict-watch-soft);
  color: var(--mg-text-body);
  font-size: var(--mg-type-body-sm-size);
}

/* ── the three editable fields ── */

.mg-editable-panel { margin-top: var(--mg-space-300); }

.mg-editable-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--mg-space-250);
}

.mg-editable-field { display: flex; flex-direction: column; gap: var(--mg-space-75); }

.mg-editable-field label {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: uppercase;
  color: var(--mg-text-meta);
}

.mg-editable {
  width: 100%;
  padding: var(--mg-editable-padding-y) var(--mg-editable-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-editable-border);
  border-radius: var(--mg-editable-radius);
  background: var(--mg-editable-fill);
  color: var(--mg-editable-text);
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-figure-number-size);
  transition: border-color var(--mg-transition-control);
}

.mg-editable:focus-visible { outline: none; border-color: var(--mg-editable-focus-border); }

.mg-editable-hint {
  margin: var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  line-height: var(--mg-font-leading-body);
}

.mg-editable-error {
  margin: var(--mg-space-0);
  color: var(--mg-verdict-loss);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}

.mg-editable-error[hidden] { display: none; }

.mg-editable-foot {
  display: flex;
  align-items: center;
  gap: var(--mg-space-200);
  flex-wrap: wrap;
  margin-top: var(--mg-space-250);
}

/* ── the per-unit cost stack ── */

.mg-stack { display: flex; flex-direction: column; gap: var(--mg-evidence-stack-gap); }

.mg-stack-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--mg-space-200);
  padding: var(--mg-space-125) var(--mg-space-0);
  border-bottom: var(--mg-border-width-hairline) solid var(--mg-ledger-rule);
  font-size: var(--mg-type-body-sm-size);
  color: var(--mg-text-body);
}

.mg-stack-row[data-kind="unset"] .mg-stack-amount,
.mg-stack-row[data-kind="unknown"] .mg-stack-amount { color: var(--mg-text-meta); }

.mg-stack-amount {
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-ledger-number-size);
  color: var(--mg-editable-derived-color);
}

.mg-stack-total {
  border-bottom: 0;
  border-top: var(--mg-border-width-hairline) solid var(--mg-evidence-total-rule);
  margin-top: var(--mg-space-50);
  padding-top: var(--mg-space-150);
}

.mg-stack-total .mg-stack-label {
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  color: var(--mg-text-primary);
}

.mg-stack-total .mg-stack-amount { font-size: var(--mg-type-figure-number-size); }
.mg-stack-total .mg-stack-amount[data-state="pos"] { color: var(--mg-verdict-profit); }
.mg-stack-total .mg-stack-amount[data-state="neg"] { color: var(--mg-verdict-loss); }
.mg-stack-total .mg-stack-amount[data-state="unknown"] { color: var(--mg-text-meta); }

/* Each cost-stack line carries a magnitude bar under it — the deduction
   or the net drawn as its share of the revenue it comes from, so the
   relative sizes read at a glance. The row is a block (label + amount on
   one line, bar beneath) rather than the flat flex row it is without a
   bar; the deductions keep the neutral cost palette and only the net line
   takes a verdict colour, because colour is a judgment and a cost is not
   one. */
.mg-stack-row-bar { display: block; border-bottom: 0; }
.mg-stack-line { display: flex; justify-content: space-between; align-items: baseline; gap: var(--mg-space-200); }
.mg-stack-bar {
  display: block;
  margin-top: var(--mg-space-100);
  height: var(--mg-size-bar-chart);
  background: var(--mg-dataviz-donut-track);
  border-radius: var(--mg-radius-bar);
  overflow: hidden;
}
.mg-stack-bar-fill { display: block; height: 100%; border-radius: var(--mg-radius-bar); }
/* Revenue is the darkest neutral; every deduction shares one mid neutral,
   told apart by its label and its width rather than its shade — the lighter
   cost token washed out on the light theme's near-white track. Only the net
   line takes a verdict colour. */
.mg-stack-bar-fill[data-bar="price"] { background: var(--mg-dataviz-cost-revenue); }
.mg-stack-bar-fill[data-bar="fees"] { background: var(--mg-dataviz-cost-deduction-1); }
.mg-stack-bar-fill[data-bar="cogs"] { background: var(--mg-dataviz-cost-deduction-1); }
.mg-stack-bar-fill[data-bar="ad"] { background: var(--mg-dataviz-cost-deduction-1); }
.mg-stack-bar-fill[data-bar="credit"] { background: var(--mg-verdict-profit); }
.mg-stack-bar-fill[data-bar="pos"] { background: var(--mg-verdict-profit); }
.mg-stack-bar-fill[data-bar="neg"] { background: var(--mg-verdict-loss); }
.mg-stack-bar-fill[data-bar="watch"] { background: var(--mg-verdict-watch); }
.mg-stack-bar-fill[data-bar="unknown"] { background: var(--mg-dataviz-donut-track); }
/* An unmeasured line keeps a faint baseline for rhythm, not a filled track. */
.mg-stack-bar-empty { background: transparent; border-bottom: var(--mg-border-width-hairline) dashed var(--mg-ledger-rule); border-radius: var(--mg-radius-none); }

/* ── the detail head row: currency eyebrow + verdict pill ── */
.mg-detail-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mg-space-200);
  margin-bottom: var(--mg-space-200);
}
.mg-detail-eyebrow {
  font-family: var(--mg-type-column-head-family);
  font-size: var(--mg-type-column-head-size);
  font-weight: var(--mg-type-column-head-weight);
  letter-spacing: var(--mg-type-column-head-tracking);
  text-transform: var(--mg-type-column-head-transform);
  color: var(--mg-text-meta);
}
.mg-verdict-pill {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-body-sm-size);
  font-weight: var(--mg-font-weight-600);
  border: var(--mg-border-width-hairline) solid var(--mg-border-hairline);
}

/* ── the two-panel analysis: cost stack beside allocation (or narrative) ──
   Top-aligned, not stretched: the cost stack's five rows make it the taller
   panel, and a shorter neighbour that ends at its own content reads as a
   tight card with room beside it — where stretching it to match would strand
   a void INSIDE a bordered card, which reads as unfinished. The full-width
   narrative band beneath carries the width the two panels leave. */
.mg-detail-analysis { align-items: start; }
.mg-detail-col { display: flex; flex-direction: column; gap: var(--mg-panel-gap); }
.mg-detail-col > .mg-panel { margin-top: var(--mg-space-0); }

/* ── where each dollar of revenue goes: a stacked share bar + legend ── */
.mg-alloc-bar {
  display: flex;
  height: var(--mg-evidence-bar-height);
  margin-bottom: var(--mg-space-200);
  border-radius: var(--mg-radius-bar);
  overflow: hidden;
  background: var(--mg-dataviz-donut-track);
}
.mg-alloc-seg { height: 100%; }
/* A hairline in the panel's own fill separates the neutral cost greys, which
   sit close in tone on purpose; box-sizing is border-box, so it eats a pixel
   of the segment rather than pushing the bar past 100%. */
.mg-alloc-seg + .mg-alloc-seg { border-left: var(--mg-border-width-hairline) solid var(--mg-surface-card); }
.mg-alloc-seg[data-seg="cogs"] { background: var(--mg-dataviz-share-cogs); }
.mg-alloc-seg[data-seg="fees"] { background: var(--mg-dataviz-share-fees); }
.mg-alloc-seg[data-seg="ad"] { background: var(--mg-dataviz-share-ad); }
.mg-alloc-seg[data-seg="net"] { background: var(--mg-verdict-profit); }
/* Square swatches for the allocation legend so each marker carries its
   segment's exact shade — a round dot reads the neutral greys as one. */
.mg-legend-dot[data-seg] { border-radius: var(--mg-radius-none); }
.mg-legend-dot[data-seg="cogs"] { background: var(--mg-dataviz-share-cogs); }
.mg-legend-dot[data-seg="fees"] { background: var(--mg-dataviz-share-fees); }
.mg-legend-dot[data-seg="ad"] { background: var(--mg-dataviz-share-ad); }
.mg-legend-dot[data-seg="net"] { background: var(--mg-verdict-profit); }

/* ── "what the number says": a lead sentence beside tinted signal chips ──
   When the allocation bar is drawn this panel runs full width beneath the
   grid, so the lead and the chips sit side by side and fill it rather than
   leaving a short paragraph stranded across the width. In a loss or a fee
   credit it takes the allocation's column instead, and the same flex wraps
   the two halves into a stack without a second rule. */
.mg-narrative-body { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--mg-panel-gap); }
.mg-narrative-lead {
  flex: 1 1 55%;
  min-width: min(100%, var(--mg-size-measure));
  margin: var(--mg-space-0);
  font-family: var(--mg-type-lede-family);
  font-size: var(--mg-type-body-size);
  line-height: var(--mg-type-body-leading);
  color: var(--mg-text-body);
}
.mg-narrative-aside { flex: 1 1 34%; display: flex; flex-direction: column; gap: var(--mg-space-100); }
.mg-signals { display: flex; flex-direction: column; gap: var(--mg-space-75); }
.mg-signal {
  display: flex;
  align-items: center;
  gap: var(--mg-space-100);
  padding: var(--mg-space-75) var(--mg-space-125);
  border: var(--mg-border-width-hairline) solid var(--mg-border-hairline);
  border-radius: var(--mg-radius-control);
  background: var(--mg-surface-card);
  font-size: var(--mg-type-body-sm-size);
  color: var(--mg-text-body);
}
.mg-signal[data-tone="pos"] { border-color: var(--mg-verdict-profit); background: var(--mg-verdict-profit-soft); }
.mg-signal[data-tone="watch"] { border-color: var(--mg-verdict-watch); background: var(--mg-verdict-watch-soft); }
.mg-signal[data-tone="neg"] { border-color: var(--mg-verdict-loss); background: var(--mg-verdict-loss-soft); }
.mg-signal-dot { width: var(--mg-pill-dot-size); height: var(--mg-pill-dot-size); border-radius: var(--mg-radius-pill); flex: none; background: var(--mg-text-meta); }
.mg-signal[data-tone="pos"] .mg-signal-dot { background: var(--mg-verdict-profit); }
.mg-signal[data-tone="watch"] .mg-signal-dot { background: var(--mg-verdict-watch); }
.mg-signal[data-tone="neg"] .mg-signal-dot { background: var(--mg-verdict-loss); }
.mg-signal[data-tone="muted"] .mg-signal-dot { background: var(--mg-text-faint); }
.mg-signal-label { flex: 1; }
.mg-signal-val {
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-basis-size);
  font-feature-settings: var(--mg-type-ledger-number-features);
  color: var(--mg-text-primary);
}
.mg-signal[data-tone="muted"] .mg-signal-val { color: var(--mg-text-meta); }
.mg-narrative-cta { align-self: flex-start; }

@media (max-width: 720px) {
  .mg-editable-grid { grid-template-columns: minmax(0, 1fr); }
}

/* On a phone the four figure tiles pack two-up rather than one long column,
   the density the mockup carries; the primary Net tile keeps its subline. */
@media (max-width: 560px) {
  .mg-sku-block .mg-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Profit Projects · the real-price-test gate (ADR-065) ─────────────
   Loud on purpose. This is the one surface in the product where the
   reader may be acting on a business that is not theirs, so it is
   sized and coloured to interrupt rather than to sit politely in the
   flow. Every value is a token; nothing here is hand-picked. */

.danger-gate {
  display: grid;
  gap: var(--mg-space-150);
  max-width: var(--mg-size-notice-max);
  padding: var(--mg-danger-banner-padding-y) var(--mg-danger-banner-padding-x);
  border: var(--mg-danger-banner-border-width) solid var(--mg-verdict-loss);
  border-radius: var(--mg-danger-banner-radius);
  background: var(--mg-danger-banner-fill);
  color: var(--mg-danger-banner-text);
}

.danger-gate-eyebrow {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-eyebrow-family);
  font-size: var(--mg-type-eyebrow-size);
  font-weight: var(--mg-type-eyebrow-weight);
  line-height: var(--mg-type-eyebrow-leading);
  letter-spacing: var(--mg-type-eyebrow-tracking);
  text-transform: var(--mg-type-eyebrow-transform);
  color: var(--mg-danger-banner-text);
}

.danger-gate-headline {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  font-weight: var(--mg-type-panel-title-weight);
  line-height: var(--mg-type-panel-title-leading);
  color: var(--mg-danger-banner-text);
}

.danger-gate-detail,
.danger-gate-label {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
  color: var(--mg-danger-banner-text);
}

.danger-gate-input {
  width: 100%;
  padding: var(--mg-editable-padding-y) var(--mg-editable-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-editable-border);
  border-radius: var(--mg-editable-radius);
  background: var(--mg-editable-fill);
  color: var(--mg-editable-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
}

.danger-gate-input:focus-visible {
  outline: none;
  border-color: var(--mg-editable-focus-border);
}

.danger-gate-mismatch {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
  line-height: var(--mg-type-basis-leading);
  color: var(--mg-danger-banner-text);
}

.danger-gate-button {
  justify-self: start;
  padding: var(--mg-control-padding-y) var(--mg-control-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-verdict-loss);
  border-radius: var(--mg-control-radius);
  background: var(--mg-verdict-loss);
  color: var(--mg-danger-banner-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  font-weight: var(--mg-type-control-weight);
}

/* The dimming comes from the global `button[disabled]` rule. Only the
   cursor is overridden: the global `progress` cursor reads as "working
   on it", and this button is not working on anything — it is waiting
   for the reader to type the confirmation. */
.danger-gate-button[disabled] { cursor: not-allowed; }

/* The quieter sibling: a write to someone else's account that does
   not start a price test. */
.use-as-notice {
  max-width: var(--mg-size-notice-max);
  margin: var(--mg-space-0) var(--mg-space-0) var(--mg-space-150);
  padding: var(--mg-notice-padding-y) var(--mg-notice-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-notice-error-border);
  border-radius: var(--mg-notice-radius);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
  color: var(--mg-text-primary);
}

/* ── Profit Projects (Tab 3) ──
   This screen had NO stylesheet at all: it rendered in browser defaults
   beside two screens built from the design system, and its guardrail form
   put each label inline with the next field's input, so a reader could not
   tell which label belonged to which number. Tokens only, like everything
   else here. */

.experiments {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-300);
}

.experiments h2 {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-screen-title-family);
  font-size: var(--mg-type-screen-title-size);
  font-weight: var(--mg-type-screen-title-weight);
  letter-spacing: var(--mg-type-screen-title-tracking);
  color: var(--mg-text-primary);
}

.experiments h3 {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-section-title-family);
  font-size: var(--mg-type-section-title-size);
  font-weight: var(--mg-type-section-title-weight);
  color: var(--mg-text-primary);
}

.experiments > .placeholder {
  margin: var(--mg-space-0);
  max-width: var(--mg-size-measure);
  color: var(--mg-text-body);
}

.experiment-group {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-150);
}

.experiment-list {
  margin: var(--mg-space-0);
  padding: var(--mg-space-0);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-100);
}

.experiment-list li {
  padding: var(--mg-space-150) var(--mg-space-0);
  border-bottom: var(--mg-border-width-hairline) solid var(--mg-ledger-rule);
}

/* A form is an actionable region, so it is enclosed — the same rule the
   Dashboard's Customize panel follows. */
.experiment-new,
.kill-switch-panel {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-200);
  padding: var(--mg-panel-padding-y) var(--mg-panel-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-panel-fill);
}

.experiments fieldset {
  margin: var(--mg-space-0);
  padding: var(--mg-space-200);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
}

/* Guardrails are independent numbers and read well side by side. Variants
   are a repeating ROW plus an "add" control, so the grid must stop at the
   fieldset boundary — applied to both, "+ variant" became a grid cell beside
   the first SKU field instead of an action under the list. */
.guardrails {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--mg-tile-min-width), 1fr));
  gap: var(--mg-space-200);
}

.variants,
.variant-rows {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-150);
  align-items: stretch;
}

.experiments legend {
  padding: var(--mg-space-0) var(--mg-space-100);
  font-family: var(--mg-type-column-head-family);
  font-size: var(--mg-type-column-head-size);
  letter-spacing: var(--mg-type-column-head-tracking);
  text-transform: var(--mg-type-column-head-transform);
  color: var(--mg-text-meta);
}

/* The fix that matters: a label owns the line above its own control. */
.experiments label,
.draft-row {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-75);
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  color: var(--mg-text-meta);
}

.experiments input,
.experiments select {
  padding: var(--mg-editable-padding-y) var(--mg-editable-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-editable-border);
  border-radius: var(--mg-editable-radius);
  background: var(--mg-editable-fill);
  color: var(--mg-editable-text);
  font-family: var(--mg-type-figure-sm-family);
  font-size: var(--mg-type-figure-sm-size);
}

.experiments input:focus-visible,
.experiments select:focus-visible {
  outline: none;
  border-color: var(--mg-editable-focus-border);
}

.experiments button {
  align-self: flex-start;
  padding: var(--mg-control-padding-y) var(--mg-control-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-control-border);
  border-radius: var(--mg-control-radius);
  background: var(--mg-control-fill);
  color: var(--mg-control-text);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  cursor: pointer;
}

.experiments #new-draft-submit {
  background: var(--mg-button-primary-fill);
  border-color: var(--mg-button-primary-fill);
  color: var(--mg-button-primary-text);
}

.variant-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mg-space-150);
  align-items: center;
}

.variant-row input { flex: 1 1 var(--mg-tile-min-width); }
.variant-row .variant-remove { flex: none; }

/* Engaged is an ALARM state and reads like one; armed is an ordinary
   control that happens to be destructive, so it stays quiet until used. */
.kill-switch-engaged {
  border-color: var(--mg-danger-banner-fill);
}

.kill-switch-form {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-150);
  align-items: flex-start;
  max-width: var(--mg-size-notice-max);
}

.kill-switch-form input {
  width: 100%;
}

.kill-switch-banner {
  margin: var(--mg-space-0);
  padding: var(--mg-danger-banner-padding-y) var(--mg-danger-banner-padding-x);
  border-radius: var(--mg-danger-banner-radius);
  background: var(--mg-danger-banner-fill);
  color: var(--mg-danger-banner-text);
}

/* ── Profit Projects, design-language pass (ADR-065) ──
   The list used to be underlined links grouped under plain headings, and the
   editor printed raw cents, a bare guardrail <dl> and ISO timestamps. This
   brings both to the mockup bar: a status-grouped card list, and an editor
   built from the before → after / guardrail-rail / breach panels. Tokens
   only, like the rest of the file. */

/* Group label — the "Audit trail" eyebrow in the editor's history section. */
.mg-exp-history .mg-group-label {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-column-head-family);
  font-size: var(--mg-type-column-head-size);
  font-weight: var(--mg-type-column-head-weight);
  letter-spacing: var(--mg-type-column-head-tracking);
  text-transform: var(--mg-type-column-head-transform);
  color: var(--mg-text-meta);
}

/* A project card: the name and a coloured status pill on one line, the real
   price move on a second line — so the row has no mid-width void and the
   status reads at a glance. The whole card is the link (the ledger's
   row-click affordance). */
/* A project is a thing you open, so it wears the same frame as the form below
   it — a bare underlined row read as static text lighter than the panels it sat
   above, hiding the two most important click targets on the screen. */
.mg-project-card {
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-panel-fill);
}
.mg-project-card:hover { border-color: var(--mg-verdict-profit); }
.mg-project-link {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-75);
  padding: var(--mg-space-175) var(--mg-panel-padding-x);
  text-decoration: none;
  color: inherit;
}
.mg-project-card-top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--mg-space-150);
}
.mg-project-link:hover .mg-project-name { color: var(--mg-verdict-profit); }
.mg-project-name {
  font-family: var(--mg-type-section-title-family);
  font-size: var(--mg-type-section-title-size);
  font-weight: var(--mg-type-section-title-weight);
  color: var(--mg-text-primary);
}
.mg-project-pill {
  padding: var(--mg-pill-padding-y) var(--mg-pill-padding-x);
  border-radius: var(--mg-radius-pill);
  font-family: var(--mg-type-column-head-family);
  font-size: var(--mg-type-column-head-size);
  font-weight: var(--mg-type-column-head-weight);
  letter-spacing: var(--mg-type-column-head-tracking);
  text-transform: var(--mg-type-column-head-transform);
  white-space: nowrap;
  background: var(--mg-surface-raised);
  color: var(--mg-text-meta);
}
.mg-project-pill[data-tone="watch"] { background: var(--mg-verdict-watch-soft); color: var(--mg-verdict-watch); }
.mg-project-pill[data-tone="pos"] { background: var(--mg-verdict-profit-soft); color: var(--mg-verdict-profit-text); }
.mg-project-pill[data-tone="neg"] { background: var(--mg-verdict-loss-soft); color: var(--mg-verdict-loss); }
.mg-project-summary {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--mg-space-150);
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-text-meta);
}
.mg-project-move { color: var(--mg-text-body); }
.mg-project-now { color: var(--mg-text-meta); }
.mg-project-arrow { color: var(--mg-text-meta); }
.mg-project-new { color: var(--mg-text-primary); }
.mg-project-delta[data-dir="increase"] { color: var(--mg-verdict-profit-text); }
.mg-project-delta[data-dir="decrease"] { color: var(--mg-verdict-loss); }

/* First-run: the required first step is connecting Amazon, so it leads as a
   framed CTA with a real button — not a text link buried in a paragraph above
   a large form the seller cannot use yet. The new-project form still renders
   (nothing is hidden), but muted so the CTA is unmistakably the primary path. */
.mg-connect-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--mg-space-150);
  padding: var(--mg-panel-padding-y) var(--mg-panel-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-panel-fill);
}
.mg-connect-cta-title {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-section-title-family);
  font-size: var(--mg-type-section-title-size);
  font-weight: var(--mg-type-section-title-weight);
  color: var(--mg-text-primary);
}
.mg-connect-cta-body {
  margin: var(--mg-space-0);
  max-width: var(--mg-size-measure);
  color: var(--mg-text-body);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
}
.mg-connect-cta-action { margin-top: var(--mg-space-50); }

/* Editor — the two-panel before → after / guardrails layout, matching the
   mockup's 1.25fr / 1fr split, with the breach panel full-width beneath. */
.experiment-editor { display: block; }
.mg-exp-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: var(--mg-space-200);
  margin-top: var(--mg-shell-section-gap);
  align-items: start;
}
.mg-exp-grid > .mg-panel { margin-top: var(--mg-space-0); }
.mg-exp-panel { display: flex; flex-direction: column; }
/* The price change (price move + honest note) and the four guardrail rails
   are of similar height, so each panel takes its natural size rather than
   stretching — which would strand an internal void in whichever is shorter. */
.mg-exp-change .mg-panel-foot { margin-top: var(--mg-space-250); }

/* Before → after: the price move reads as the hero of the screen. */
.mg-exp-move {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--mg-space-150);
  margin-bottom: var(--mg-space-100);
}
.mg-exp-price-now,
.mg-exp-price-new {
  font-family: var(--mg-type-headline-number-family);
  font-size: var(--mg-type-headline-number-size);
  font-weight: var(--mg-type-headline-number-weight);
  font-feature-settings: var(--mg-type-headline-number-features);
  letter-spacing: var(--mg-type-headline-number-tracking);
  line-height: var(--mg-type-headline-number-leading);
}
.mg-exp-price-now { color: var(--mg-text-meta); }
.mg-exp-price-new { color: var(--mg-text-primary); }
.mg-exp-move-arrow {
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-figure-number-size);
  color: var(--mg-text-meta);
}
.mg-exp-move-basis { margin-top: var(--mg-space-0); }
.mg-exp-move-delta[data-dir="increase"] { color: var(--mg-verdict-profit-text); }
.mg-exp-move-delta[data-dir="decrease"] { color: var(--mg-verdict-loss); }
.mg-mono { font-family: var(--mg-type-figure-number-family); }

/* Multi-variant projects fall back to a compact change table. */
.mg-exp-vtable { width: 100%; border-collapse: collapse; }
.mg-exp-vtable th,
.mg-exp-vtable td {
  padding: var(--mg-space-100) var(--mg-space-125);
  text-align: right;
  border-bottom: var(--mg-border-width-hairline) solid var(--mg-ledger-rule);
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-text-body);
}
.mg-exp-vtable th {
  font-family: var(--mg-type-column-head-family);
  font-size: var(--mg-type-column-head-size);
  letter-spacing: var(--mg-type-column-head-tracking);
  text-transform: var(--mg-type-column-head-transform);
  color: var(--mg-text-meta);
  font-weight: var(--mg-type-column-head-weight);
}
.mg-exp-vtable th.mg-exp-vsku,
.mg-exp-vtable td.mg-exp-vsku { text-align: left; }
.mg-exp-vtable tr:last-child td { border-bottom: 0; }
.mg-exp-vdelta[data-dir="increase"] { color: var(--mg-verdict-profit-text); }
.mg-exp-vdelta[data-dir="decrease"] { color: var(--mg-verdict-loss); }

/* Guardrail rails — the checklist. Each rail is icon · label · value, toned
   by whether Marginly could evaluate it (ok / blocked) or is stating a floor
   it checks server-side at go-live (info). */
.mg-rails { display: grid; gap: var(--mg-space-100); }
.mg-rail {
  display: grid;
  grid-template-columns: var(--mg-space-250) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--mg-space-125);
  padding: var(--mg-space-150) var(--mg-space-175);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-radius-control);
}
.mg-rail-icon {
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-body-sm-size);
  text-align: center;
  color: var(--mg-text-meta);
}
.mg-rail[data-kind="ok"] .mg-rail-icon { color: var(--mg-verdict-profit); }
.mg-rail[data-kind="blocked"] { border-color: var(--mg-verdict-loss); background: var(--mg-verdict-loss-soft); }
.mg-rail[data-kind="blocked"] .mg-rail-icon { color: var(--mg-verdict-loss); }
.mg-rail-label {
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
  color: var(--mg-text-body);
}
.mg-rail-label strong { color: var(--mg-text-primary); font-weight: var(--mg-font-weight-600); }
.mg-rail-value {
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-text-meta);
  white-space: nowrap;
  text-align: right;
}
.mg-rail[data-kind="ok"] .mg-rail-value { color: var(--mg-verdict-profit-text); }
.mg-rail[data-kind="blocked"] .mg-rail-value { color: var(--mg-verdict-loss); }

/* The lifecycle actions (Submit / Confirm / the ADR-065 gate / etc.) are the
   body of their own full-width panel below the two-column row. The editor
   container is `.experiment-editor`, so the generic `.experiments` form rules
   do not reach here — these actions style themselves. */
.mg-exp-actions-panel { margin-top: var(--mg-panel-gap); }
.mg-exp-actions .lifecycle-actions {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-200);
  align-items: stretch;
}
/* Every button here EXCEPT the ADR-065 typed gate takes the neutral control
   look. The gate's confirm button keeps its own loud danger styling
   (.danger-gate-button) — this generic rule is later and more specific, so
   without the :not() it would repaint the load-bearing warning's action in
   ordinary control tokens. gateButtonKeepsDangerStyling in the design guard
   fails the build if this exclusion is ever dropped. */
.mg-exp-actions button:not(.danger-gate-button) {
  align-self: flex-start;
  padding: var(--mg-control-padding-y) var(--mg-control-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-control-border);
  border-radius: var(--mg-control-radius);
  background: var(--mg-control-fill);
  color: var(--mg-control-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
  font-weight: var(--mg-type-control-weight);
  cursor: pointer;
}
/* The primary lifecycle action for a state is filled green — Submit (draft),
   Confirm (the account holder's own pending). The ADR-065 typed gate keeps
   its own danger styling (.danger-gate-button) and is untouched here. */
.mg-exp-actions #submit-experiment,
.mg-exp-actions .confirmation button {
  background: var(--mg-button-primary-fill);
  border-color: var(--mg-button-primary-fill);
  color: var(--mg-button-primary-text);
}
/* The reason field for a destructive action (cancel / rollback / complete) is
   secondary — capped narrow so it does not out-weigh the primary green action
   (Submit / Confirm) that anchors this panel. */
.mg-exp-actions .reason-action {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-75);
  align-items: flex-start;
  max-width: var(--mg-size-input-max);
}
.mg-exp-actions .reason-action .reason-input { width: 100%; }
.mg-exp-actions .reason-action label {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}
.mg-exp-actions .reason-input {
  padding: var(--mg-editable-padding-y) var(--mg-editable-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-editable-border);
  border-radius: var(--mg-editable-radius);
  background: var(--mg-editable-fill);
  color: var(--mg-editable-text);
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
}
.mg-exp-actions .reason-input:focus-visible {
  outline: none;
  border-color: var(--mg-editable-focus-border);
}
.mg-exp-actions .confirmation {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-125);
}
.mg-exp-actions .confirmation h4 {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  font-weight: var(--mg-type-panel-title-weight);
  color: var(--mg-text-primary);
}
.mg-exp-actions .confirm-ack {
  display: flex;
  gap: var(--mg-space-100);
  align-items: baseline;
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
  color: var(--mg-text-body);
}
.mg-exp-actions .confirm-ack input { accent-color: var(--mg-verdict-profit); }
.mg-exp-actions .use-as-notice { margin: var(--mg-space-0); }
.mg-exp-actions .muted {
  margin: var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
}

/* If a guardrail fails — the breach panel: an example blocked rail beside the
   numbered consequence steps. */
.mg-breach-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: var(--mg-space-400);
  align-items: center;
}
.mg-breach-note { margin-top: var(--mg-space-150); }
.mg-breach-steps {
  margin: var(--mg-space-0);
  padding: var(--mg-space-0);
  list-style: none;
  display: grid;
  gap: var(--mg-space-150);
  border-left: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  padding-left: var(--mg-space-300);
}
.mg-breach-step {
  display: grid;
  grid-template-columns: var(--mg-space-250) minmax(0, 1fr);
  gap: var(--mg-space-125);
  align-items: baseline;
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-type-body-sm-leading);
  color: var(--mg-text-body);
}
.mg-breach-num {
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-basis-size);
  text-align: center;
  color: var(--mg-text-meta);
  border: var(--mg-border-width-hairline) solid var(--mg-panel-border);
  border-radius: var(--mg-radius-control);
}

/* Audit trail — a clean two-column readout, no longer raw ISO strings. */
.mg-exp-history { margin-top: var(--mg-shell-section-gap); }
.mg-exp-history .audit-trail {
  margin: var(--mg-space-150) var(--mg-space-0) var(--mg-space-0);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--mg-tile-min-width), 1fr));
  gap: var(--mg-space-150);
}
.mg-history-row {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-25);
}
.mg-history-row dt {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}
.mg-history-row dd {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-figure-number-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-text-body);
}

.mg-exp-back { margin-top: var(--mg-shell-section-gap); }
.mg-exp-back a { color: var(--mg-verdict-profit); text-decoration: none; }
.mg-exp-back a:hover { text-decoration: underline; }

@media (max-width: 720px) {
  .mg-exp-grid { grid-template-columns: minmax(0, 1fr); }
  .mg-breach-grid { grid-template-columns: minmax(0, 1fr); gap: var(--mg-space-250); }
  .mg-breach-steps { border-left: 0; padding-left: var(--mg-space-0); }
}

/* ─── Cost of goods (ADR-069) ─────────────────────────────────────────── */

/* The progress signal. A seller reads this before anything else on the screen,
   so it leads with a hero figure — the share of products that sold and now have
   a unit cost — the way every other screen leads with its KPI figure. The figure
   sits left with its caption; the raw counts sit right as labelled facts, so the
   panel fills its width instead of stranding an empty right half. All three are
   COUNTS, never a summed money total, which keeps the panel currency-safe. */
.mg-cost-cover {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--mg-space-400);
  align-items: start;
  margin-bottom: var(--mg-space-250);
}

.mg-cost-figure { display: flex; flex-direction: column; gap: var(--mg-space-75); }

.mg-cost-facts {
  display: grid;
  gap: var(--mg-space-100);
  margin: var(--mg-space-0);
  text-align: right;
}
.mg-cost-fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--mg-space-300);
}
.mg-cost-fact dt {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
  white-space: nowrap;
}
.mg-cost-fact dd {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-ledger-number-size);
  color: var(--mg-text-body);
  white-space: nowrap;
}

/* The coverage meter is this screen's headline signal, so it carries real
   weight — a substantial track under the hero figure — rather than the hairline
   the inline progress bars elsewhere use. Costs-scoped, so the shared
   `.mg-progress` (the states screen's loader) keeps its slim default. */
.mg-cost-bar { height: var(--mg-space-100); }

.mg-cost-figure-value {
  font-family: var(--mg-type-headline-number-family);
  font-size: var(--mg-type-headline-number-size);
  font-weight: var(--mg-type-headline-number-weight);
  font-feature-settings: var(--mg-type-headline-number-features);
  letter-spacing: var(--mg-type-headline-number-tracking);
  line-height: var(--mg-type-headline-number-leading);
  color: var(--mg-text-primary);
}

/* Amber is attention, not alarm: an uncosted majority of revenue is a gap to
   close, so the figure wears the watch tone. A fully-costed window turns it
   green. Colour is never the only signal — the caption states it in words. */
.mg-cost-figure[data-tone="watch"] .mg-cost-figure-value { color: var(--mg-verdict-watch); }
.mg-cost-figure[data-tone="ok"] .mg-cost-figure-value { color: var(--mg-verdict-profit-text); }

.mg-cost-figure-label {
  max-width: var(--mg-size-measure);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-font-leading-body);
}

/* Explanatory sentences ride in the reading face, not the figure face —
   monospace on this screen is kept to figures, column heads, and one-line
   metadata. A multi-line note set in mono reads like a terminal, not the calm
   editorial the language asks for. */
.mg-cost-progress-sub {
  margin: var(--mg-space-100) var(--mg-space-0) var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-font-leading-body);
}

/* The result of a save. It is a status line rather than a toast because it
   carries a fact the reader needs to keep — that the account figures follow
   shortly — and a message that disappears on its own would take that with
   it. */
.mg-cost-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--mg-space-150);
  margin-bottom: var(--mg-space-200);
  padding: var(--mg-notice-padding-y) var(--mg-notice-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-notice-border);
  border-radius: var(--mg-notice-radius);
  background: var(--mg-surface-raised);
  color: var(--mg-text-body);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
}

.mg-cost-notice[data-tone="ok"] {
  border-color: var(--mg-verdict-profit);
  background: var(--mg-verdict-profit-soft);
}

.mg-cost-notice[data-tone="error"] {
  border-color: var(--mg-notice-error-border);
  background: var(--mg-verdict-loss-soft);
}

/* A secondary, correctly-defaulting control — the label sits inline with the
   input so it reads as one compact control rather than a stacked block adrift
   between two full-width panels, sized like the window inputs it sits near, not
   at the hero figure scale the shared editable field carries on the SKU detail
   where the number IS the subject. It hugs the task panel below it — the saves
   it dates — and keeps its distance from the coverage panel above, so it reads
   as the header of the saves rather than orphaned between two frames. It stays
   screen-level, not folded into the task panel, because it also defaults the
   dates of the bulk paste, which renders even when the task list is empty. */
.mg-cost-effective {
  max-width: var(--mg-size-notice-max);
  margin-top: var(--mg-space-250);
  margin-bottom: var(--mg-space-100);
}
.mg-cost-effective-row {
  display: flex;
  align-items: center;
  gap: var(--mg-space-150);
  margin-bottom: var(--mg-space-75);
}
.mg-cost-effective-row label {
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
  white-space: nowrap;
}
.mg-cost-effective .mg-editable-wrap { max-width: var(--mg-size-input-max); }
.mg-cost-effective .mg-editable {
  font-family: var(--mg-type-control-family);
  font-size: var(--mg-type-control-size);
}

/* Multi-line helper prose on this screen reads in the body face; monospace is
   held to the figures and one-line metadata. */
.mg-cost-effective .mg-editable-hint,
[data-testid="mg-costs-bulk"] .mg-editable-hint {
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
}

/* The cost field is bounded and pulled to the right of its column, so it sits
   beside the Save button it feeds instead of stretching the full column into a
   dead band. A currency symbol prefixes it — the same affix every other figure
   on the screen carries — set as a positioned mark, never in the value, so the
   number the seller types stays exactly what parseCostCell accepts. */
.mg-cost-inputwrap {
  position: relative;
  max-width: var(--mg-size-input-max);
  margin-left: auto;
}
.mg-cost-inputcur {
  position: absolute;
  left: var(--mg-editable-padding-x);
  top: 50%;
  transform: translateY(-50%);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-ledger-number-size);
  pointer-events: none;
}
.mg-cost-input {
  width: 100%;
  padding-left: var(--mg-space-400);
  text-align: right;
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-ledger-number-size);
}

/* Revenue at risk, drawn as a magnitude bar under its figure so the panel's
   ranking ("most unexplained revenue first") reads without comparing numbers.
   The fill wears the watch tone — the same amber as the coverage figure while a
   gap remains — because this is the unfinished cost work, an attention state,
   not a loss: amber says "close this", where clay-red would say "money lost".
   Magnitude is carried by width; the tone is uniform, so no row reads as worse
   than another. */
.mg-risk { display: flex; flex-direction: column; align-items: flex-end; gap: var(--mg-space-75); }
.mg-risk-amount {
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-ledger-number-size);
  color: var(--mg-text-primary);
}
.mg-risk-bar {
  display: block;
  width: 100%;
  height: var(--mg-space-100);
  background: var(--mg-dataviz-donut-track);
  border-radius: var(--mg-radius-bar);
  overflow: hidden;
}
/* The fill hugs the RIGHT of the track, so its end sits directly under the
   right-aligned figure above it — magnitude reads as the bar extending left
   from the number, and every row's bar shares the figure's edge instead of
   ending in a floating gap. */
.mg-risk-bar-fill {
  display: block;
  height: 100%;
  margin-left: auto;
  background: var(--mg-verdict-watch);
  border-radius: var(--mg-radius-bar);
}

/* "Costs on file" is a narrow reference — three columns, often only a row or
   two. Left it at the ledger's full width, two short rows read as a sparse band
   with wide gaps between the columns; sized to its content it packs to the left
   like the compact table it is. */
.mg-cost-onfile-table {
  width: auto;
  min-width: 0;
  max-width: var(--mg-size-notice-max);
}
.mg-cost-onfile-table .mg-ledger-num { padding-left: var(--mg-space-500); }

.mg-cost-paste {
  width: 100%;
  margin-bottom: var(--mg-space-150);
  font-family: var(--mg-font-family-mono);
  font-size: var(--mg-type-body-sm-size);
  line-height: var(--mg-font-leading-body);
  resize: vertical;
}

.mg-cost-save {
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-75);
  margin-top: var(--mg-space-200);
  padding-top: var(--mg-space-200);
  border-top: var(--mg-border-width-hairline) solid var(--mg-panel-border);
}

/* A save that succeeded speaks in the same place a save that failed does,
   so the reader looks in one spot for the answer either way. */
.mg-editable-error[data-tone="ok"] { color: var(--mg-verdict-profit); }

/* The preview's verdict per row. Colour is a second signal here, never the
   only one: every row also carries its status in words. */
[data-testid="mg-costs-preview"] tr[data-state="error"] .mg-ledger-identity,
[data-testid="mg-costs-preview"] tr[data-state="error"] td {
  color: var(--mg-verdict-loss);
}

[data-testid="mg-costs-preview"] tr[data-state="warn"] td {
  color: var(--mg-verdict-watch);
}

/* A scannable severity mark ahead of each preview verdict, so warn (amber, a
   row a seller may still save) and error (red, a row that blocks the batch)
   are told apart at a glance and not only on close reading. */
.mg-preview-glyph { margin-right: var(--mg-space-75); font-family: var(--mg-font-family-mono); }
.mg-preview-glyph[data-state="ok"] { color: var(--mg-verdict-profit-text); }
.mg-preview-glyph[data-state="warn"] { color: var(--mg-verdict-watch); }
.mg-preview-glyph[data-state="error"] { color: var(--mg-verdict-loss); }

/* A commit with nothing ready to save is inactive, not loading: it reads as a
   quiet neutral control rather than the global disabled treatment's dimmed
   green with a progress cursor, which looked broken next to "Save costs". */
[data-testid="mg-costs-commit"]:disabled,
/* Same reasoning for "Save as this SKU's cost": the global opacity:.5 dims the
   forest green enough to read disabled on the light ground, but the vivid dark-mode
   green stayed saturated at half-opacity and looked like an armed primary. The
   neutral control fill reads inactive in BOTH themes. */
[data-testid="mg-sku-save-cost"]:disabled {
  opacity: 1;
  cursor: not-allowed;
  background: var(--mg-control-fill);
  border-color: var(--mg-control-border);
  color: var(--mg-text-meta);
}

.mg-visually-hidden {
  position: absolute;
  width: var(--mg-border-width-hairline);
  height: var(--mg-border-width-hairline);
  margin: calc(var(--mg-border-width-hairline) * -1);
  padding: var(--mg-space-0);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: var(--mg-radius-none);
}

/* ══════════════════════════════════════════════════════════════════════════
   Dashboard: headline accent · KPI density · two-up panels (Margin-per-SKU
   ranked chart + revenue donut). Account-grain summary; the per-SKU ledger is
   the SKU Calculator's. Every value below is a design token (ADR-061, ADR-062).
   ══════════════════════════════════════════════════════════════════════════ */

/* The green italic serif accent inside a display heading ("per SKU"). */
.mg-accent { font-style: italic; color: var(--mg-verdict-profit-text); }

/* KPI band: content-hugging cards, top-aligned like the mockup — label, value
   and the period comparison stay one tight group at the top. A card that
   stretches to match a taller neighbour lets the slack fall to its foot as
   padding, never a void opened between the value and its delta (the old
   space-between stranded the value over dead space). Zeroing the tile's own
   flex gap leaves the delta's margin-top as the single value→delta rhythm, so
   the whole group reads at one spacing step. Scoped to the Dashboard so the
   SKU detail's tiles keep their own layout. */
.mg-dash-currency .mg-tile { justify-content: flex-start; gap: var(--mg-space-0); }
/* Cards size to their content instead of stretching to the tallest in the row,
   so a card that says more (the withheld net's note, the losing tile's recovery
   line) is simply a little taller — never a short card padded out with a hollow
   band to match it. Matches the mockup's dense, content-hugging KPI band. */
.mg-dash-currency .mg-tiles { align-items: start; }
.mg-tile-top { display: flex; flex-direction: column; gap: var(--mg-tile-label-margin-bottom); }

/* Two panels abreast on the desktop — the ranked chart gets the wider column —
   stacked below the compact width. Equal height, and the chart's bars flex to
   fill it so a sparse catalogue never leaves a stretched-empty void. */
.mg-grid-2 {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: var(--mg-panel-gap);
  margin-top: var(--mg-panel-gap);
}
.mg-grid-2 > .mg-panel { margin-top: var(--mg-space-0); }
@media (max-width: 720px) {
  .mg-grid-2 { grid-template-columns: minmax(0, 1fr); }
  /* The coverage counts drop below the figure rather than beside it once the
     panel is too narrow to hold two columns without cramping. */
  .mg-cost-cover { grid-template-columns: minmax(0, 1fr); gap: var(--mg-space-200); }
  .mg-cost-facts { text-align: left; }
  .mg-cost-fact { justify-content: flex-start; gap: var(--mg-space-150); }
}

/* In the card list a numeric cell is a `label … value` row, which would pin the
   revenue-at-risk bar to the width of its own figure — an unreadable stub. The
   risk cell instead stacks: label, then the figure, then a full-card-width bar,
   so magnitude still reads on a phone. */
@media (max-width: 560px) {
  .mg-ledger td.mg-cost-risk-cell {
    flex-direction: column;
    align-items: stretch;
  }
  .mg-cost-risk-cell .mg-risk { align-items: stretch; width: 100%; }
}

/* ── Margin per SKU (ranked diverging bars) ── */
.mg-mchart-panel { display: flex; flex-direction: column; }
.mg-mchart { display: flex; flex-direction: column; flex: 1; }
.mg-mbar {
  display: grid;
  grid-template-columns: calc(var(--mg-space-1200) + var(--mg-space-500)) minmax(0, 1fr) var(--mg-space-600);
  align-items: center;
  gap: var(--mg-space-125);
  flex: 1;
}
.mg-mbar-name {
  font-family: var(--mg-type-ledger-number-family);
  font-size: var(--mg-type-basis-size);
  color: var(--mg-text-body);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The track fills its row's full height so the zero tick spans it edge to edge;
   with rows adjacent (no gap) the ticks join into one continuous break-even
   line, and the fill bar floats vertically centred at the mockup's bar height. */
.mg-mbar-track { position: relative; align-self: stretch; }
.mg-mbar-zero {
  position: absolute;
  top: var(--mg-space-0);
  bottom: var(--mg-space-0);
  width: var(--mg-border-width-hairline);
  background: var(--mg-chart-zero-line);
}
.mg-mbar-fill {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  height: var(--mg-chart-bar-height);
  border-radius: var(--mg-chart-bar-radius);
}
.mg-mbar-fill[data-tone="pos"] { background: var(--mg-chart-positive); }
.mg-mbar-fill[data-tone="watch"] { background: var(--mg-chart-watch); }
.mg-mbar-fill[data-tone="neg"] { background: var(--mg-chart-negative); }
.mg-mbar-val { font-family: var(--mg-type-ledger-number-family); font-size: var(--mg-type-basis-size); text-align: right; }
.mg-mbar-val[data-tone="pos"] { color: var(--mg-verdict-profit-text); }
.mg-mbar-val[data-tone="watch"] { color: var(--mg-verdict-watch); }
.mg-mbar-val[data-tone="neg"] { color: var(--mg-verdict-loss); }
.mg-mchart-foot { display: flex; justify-content: space-between; gap: var(--mg-space-150); }
.mg-mchart-foot b { font-family: var(--mg-type-ledger-number-family); font-weight: var(--mg-font-weight-500); }

/* ── workspace column: pin the slim footer to the viewport bottom ──
   On a short signed-in page (a not-connected dashboard, an error state) the
   footer is a normal-flow body sibling and sits just under the content, leaving
   a dead band beneath it to the viewport edge. The fix is the classic
   sticky-footer column: the signed-in body is a flex column (banner · header ·
   app grid · footer) and the app grid takes the vertical slack, so the footer
   rests on the viewport bottom when content is short and flows naturally when it
   is tall. Scoped `:not(.mg-landing)` so the marketing body is untouched.
   Pinned via the percentage-height chain (`html` height:100% → `body`
   min-height:100%), NOT a viewport unit: `%` is a proportion of the container,
   which ADR-061 excludes from the token scanner as layout rather than an
   off-scale value, so this keeps the shell's "no off-scale viewport length"
   principle intact (ADR-070). The app grid never shrinks (`flex: 1 0 auto`); its
   own `align-items: start` keeps the sidebar and #root top-aligned in the slack. */
html:not(.mg-landing) { height: 100%; }
html:not(.mg-landing) body { display: flex; flex-direction: column; min-height: 100%; }
/* `width: 100%` is load-bearing: a flex item with horizontal `margin: 0 auto`
   (both .mg-app and .mg-appfooter centre that way) otherwise resolves its cross
   size to max-content and shrinks the whole workspace to the width of its text.
   Restoring an explicit 100% makes them fill the body and centre at their
   max-width exactly as they did in the prior block layout. */
html:not(.mg-landing) .mg-app { flex: 1 0 auto; width: 100%; }

/* ── slim in-app footer ──
   The signed-in workspace carries a slim footer, not the full marketing footer
   (~40% of a phone screen). `:not(.mg-landing)` shows it on every SPA route
   (including localhost, which never carries the landing class) and hides the
   marketing footer there; the landing keeps the marketing footer above. */
.mg-appfooter { display: none; }
html:not(.mg-landing) .mg-footer { display: none; }
html:not(.mg-landing) .mg-appfooter {
  display: block;
  /* Frame the same box as the workspace content: the footer inherited the
     narrower marketing reading measure (--mg-size-shell-max) from when it was
     the landing footer, which left it centred on the body and misaligned with
     the sidebar-offset content column. --mg-shell-max-width is the operational
     width .mg-app uses, so the footer now shares the content's outer frame and
     right edge — like the full-width header does at the top. `width: 100%` is
     needed for the same flex auto-margin reason as .mg-app above. */
  width: 100%;
  max-width: var(--mg-shell-max-width);
  margin-inline: auto;
  padding: var(--mg-space-250) var(--mg-space-400) var(--mg-space-300);
  border-top: var(--mg-border-width-hairline) solid var(--mg-border-hairline);
}
.mg-appfooter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--mg-space-75) var(--mg-space-200);
}
.mg-appfooter-wordmark {
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  color: var(--mg-text-primary);
  text-decoration: none;
}
.mg-appfooter-wordmark .mg-period { color: var(--mg-verdict-profit-text); }
.mg-appfooter-links {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--mg-space-75) var(--mg-space-0);
}
.mg-appfooter-link {
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-body-sm-size);
  color: var(--mg-text-body);
  text-decoration: none;
}
.mg-appfooter-link:hover { color: var(--mg-text-primary); }
/* Bind the links into one nav cluster with middot separators so the row does
   not read as four loosely-spaced words. */
.mg-appfooter-link + .mg-appfooter-link { margin-left: var(--mg-space-150); }
.mg-appfooter-link + .mg-appfooter-link::before {
  content: "·";
  margin-right: var(--mg-space-150);
  color: var(--mg-text-faint);
}
.mg-appfooter-copy {
  margin-left: auto;
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  letter-spacing: var(--mg-type-label-tracking);
  color: var(--mg-text-meta);
}
/* The trademark disclaimer is a legal PARAGRAPH, so it reads in the body font
   (the marketing footer's disclaimer does the same) — mono is reserved for the
   single-line meta stamp above it. */
.mg-appfooter-disclaimer {
  margin: var(--mg-space-150) var(--mg-space-0) var(--mg-space-0);
  max-width: var(--mg-size-measure);
  font-family: var(--mg-type-body-sm-family);
  font-size: var(--mg-type-basis-size);
  line-height: var(--mg-type-basis-leading);
  color: var(--mg-text-faint);
}
/* At the compact breakpoint the sidebar becomes a fixed bottom tab bar. This
   footer sits OUTSIDE .mg-app-shell (which gets its own clearance above), so
   without matching clearance its last (disclaimer) lines sit under the opaque
   bar at maximum scroll — hiding the legal chrome this footer exists to keep
   reachable. Match the shell's `--mg-space-1000` clearance. The selector mirrors
   the base rule's specificity and comes later, so this padding-bottom wins. */
@media (max-width: 720px) {
  html:not(.mg-landing) .mg-appfooter { padding-bottom: var(--mg-space-1000); }
}
/* On a phone the bar wraps: keep © with the fine print (left-aligned) instead
   of stranding it right-floated on its own line, and let the disclaimer use the
   full width. */
@media (max-width: 560px) {
  .mg-appfooter-copy { margin-left: var(--mg-space-0); width: 100%; }
  .mg-appfooter-disclaimer { max-width: none; }
}

/* ── Settings (#/settings) ──────────────────────────────────────────────
   Account & settings: connection · subscription · notification preferences ·
   beta program. Token-only; replaces the pre-kernel .settings-* rules removed
   from style.css. The panels use the shared .mg-panel frame; only the modal
   scrim (no kernel token yet) still lives in style.css. The screen is a focused
   reading column, not a full-bleed grid, so panels fill their width. */
.mg-settings { max-width: var(--mg-size-notice-max); }

.mg-settings-eyebrow {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-eyebrow-family);
  font-size: var(--mg-type-eyebrow-size);
  font-weight: var(--mg-type-eyebrow-weight);
  letter-spacing: var(--mg-type-eyebrow-tracking);
  text-transform: var(--mg-type-eyebrow-transform);
  color: var(--mg-verdict-profit-text);
}

.mg-settings-copy {
  margin: var(--mg-space-0) var(--mg-space-0) var(--mg-space-150);
  max-width: var(--mg-size-measure);
  color: var(--mg-text-body);
  line-height: var(--mg-type-lede-leading);
}
.mg-settings-copy:last-child { margin-bottom: var(--mg-space-0); }
.mg-settings-copy-muted { color: var(--mg-text-meta); }

.mg-settings-note {
  margin: var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}
.mg-settings-note[data-tone="error"] { color: var(--mg-verdict-loss); }

/* Access is a verdict: granted reads green, revoked reads clay-red — a pill,
   not loose coloured text, so the account's standing is legible at a glance. */
.mg-settings-access {
  display: inline-flex;
  align-items: center;
  padding: var(--mg-pill-padding-y) var(--mg-pill-padding-x);
  border: var(--mg-border-width-hairline) solid transparent;
  border-radius: var(--mg-radius-pill);
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
}
.mg-settings-access[data-state="granted"] {
  color: var(--mg-verdict-profit-text);
  background: var(--mg-verdict-profit-soft);
  border-color: var(--mg-verdict-profit);
}
.mg-settings-access[data-state="revoked"] {
  color: var(--mg-verdict-loss);
  background: var(--mg-verdict-loss-soft);
  border-color: var(--mg-verdict-loss);
}

.mg-settings-kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--mg-space-75) var(--mg-space-200);
  margin: var(--mg-space-150) var(--mg-space-0);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}
.mg-settings-kv dt {
  color: var(--mg-text-meta);
  text-transform: var(--mg-type-label-transform);
  letter-spacing: var(--mg-type-label-tracking);
}
.mg-settings-kv dd { margin: var(--mg-space-0); color: var(--mg-text-body); }

.mg-settings-subhead {
  margin: var(--mg-space-150) var(--mg-space-0) var(--mg-space-75);
  font-family: var(--mg-type-label-family);
  font-size: var(--mg-type-label-size);
  font-weight: var(--mg-type-label-weight);
  letter-spacing: var(--mg-type-label-tracking);
  text-transform: var(--mg-type-label-transform);
  color: var(--mg-text-meta);
}
.mg-settings-features {
  list-style: none;
  margin: var(--mg-space-0);
  padding: var(--mg-space-0);
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-75);
}
.mg-settings-feature {
  display: flex;
  align-items: baseline;
  gap: var(--mg-space-100);
  color: var(--mg-text-body);
}
.mg-settings-feature-check { flex: none; color: var(--mg-verdict-profit-text); }
.mg-settings-feature-empty { color: var(--mg-text-meta); font-style: italic; }

/* Notification preferences: whole-row label, checkbox themed to the brand
   green (the OS blue is off the palette). */
.mg-settings-prefs { display: flex; flex-direction: column; }
.mg-settings-pref {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--mg-space-125);
  align-items: start;
  padding: var(--mg-space-150) var(--mg-space-0);
  border-top: var(--mg-border-width-hairline) solid var(--mg-border-hairline);
  cursor: pointer;
}
.mg-settings-pref:first-child { border-top: 0; }
.mg-settings-pref input {
  margin-top: var(--mg-space-25);
  accent-color: var(--mg-verdict-profit);
}
.mg-settings-pref-text { display: flex; flex-direction: column; gap: var(--mg-space-25); }
.mg-settings-pref-label { color: var(--mg-text-primary); font-weight: var(--mg-font-weight-500); }
.mg-settings-pref-desc { color: var(--mg-text-meta); font-size: var(--mg-type-body-sm-size); }
.mg-settings-pref-status {
  margin: var(--mg-space-125) var(--mg-space-0) var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}
.mg-settings-pref-status[data-tone="ok"] { color: var(--mg-verdict-profit-text); }

/* Beta program rows. */
.mg-settings-beta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--mg-space-125);
  padding: var(--mg-space-150) var(--mg-space-0);
  border-top: var(--mg-border-width-hairline) solid var(--mg-border-hairline);
}
.mg-settings-beta-row:first-of-type { border-top: 0; }
.mg-settings-beta-row p { margin: var(--mg-space-0); color: var(--mg-text-body); flex: 1 1 var(--mg-space-0); }
.mg-settings-beta-row-stale { flex-direction: column; align-items: stretch; }
.mg-settings-beta-row-stale p { flex: none; }
.mg-settings-beta-actions { display: flex; flex-wrap: wrap; gap: var(--mg-space-100); }

/* Beta consent modal — a scrim and the card that floats over it. The scrim is
   the one deliberately translucent surface: every `surface` role is an opaque
   fill, so it takes the overlay-scrim role, not a canvas colour. The card floats
   over the scrim, so it is a CARD, not a panel: a panel fill is the page canvas
   (panels are told apart by a hairline, not a fill), which on a dark ground left
   the dialog the same near-black as the scrimmed page behind it — no elevation.
   The visual grammar reserves an enclosed, movable surface for exactly this, so
   the modal takes the raised card fill and a section-closing rule, and reads as
   lifted in both themes. */
.mg-settings-modal-backdrop {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--mg-space-300);
  background: var(--mg-overlay-scrim);
  z-index: 200;
}
.mg-settings-modal {
  width: calc(100% - var(--mg-space-400));
  max-width: var(--mg-size-evidence-max);
  display: flex;
  flex-direction: column;
  gap: var(--mg-space-150);
  padding: var(--mg-panel-padding-y) var(--mg-panel-padding-x);
  border: var(--mg-border-width-hairline) solid var(--mg-border-strong);
  border-radius: var(--mg-panel-radius);
  background: var(--mg-surface-card);
}
.mg-settings-modal h4 {
  margin: var(--mg-space-0);
  font-family: var(--mg-type-panel-title-family);
  font-size: var(--mg-type-panel-title-size);
  font-weight: var(--mg-type-panel-title-weight);
  color: var(--mg-text-primary);
}
.mg-settings-modal-version {
  margin: var(--mg-space-0);
  color: var(--mg-text-meta);
  font-family: var(--mg-type-basis-family);
  font-size: var(--mg-type-basis-size);
}
.mg-settings-modal-body {
  margin: var(--mg-space-0);
  color: var(--mg-text-body);
  line-height: var(--mg-type-lede-leading);
}
.mg-settings-modal-actions { display: flex; gap: var(--mg-space-100); justify-content: flex-end; }
