/* Trek model administration, styles
 *
 * Consumes tokens.css. No colour, radius, spacing or font literal appears below;
 * everything routes through a --trek- token so a brand change is one file.
 *
 * Class names are unchanged from the previous revision, so app.js needs no edits.
 */

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--trek-font-family-body);
  font-size: var(--trek-font-size-body);
  line-height: var(--trek-font-leading-body);
  color: var(--trek-color-semantic-text);
  background: var(--trek-color-semantic-surface-sunken);
}

h1, h2, h3 {
  font-family: var(--trek-font-family-heading);
  color: var(--trek-color-semantic-heading);
}

/* ---- top bar ---- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--trek-space-4);
  padding: var(--trek-space-3) var(--trek-space-5);
  background: var(--trek-color-brand-navy);
  color: var(--trek-color-semantic-text-on-dark);
}
.brand { display: flex; align-items: center; gap: var(--trek-space-3); }
/* The derived white bug. Kept a little under the 42px lockup minimum because this is the bug
   alone rather than a full lockup, and the wordmark beside it carries the name. */
.brand img { height: 34px; width: auto; display: block; }
.brand .mark {
  font-family: var(--trek-font-family-heading);
  font-size: var(--trek-font-size-h3);
  font-weight: var(--trek-font-weight-semibold);
}
.brand .sub { font-size: var(--trek-font-size-small); opacity: 0.78; }
.who {
  display: flex;
  align-items: center;
  gap: var(--trek-space-3);
  font-size: var(--trek-font-size-small);
}
.who .link { color: inherit; opacity: 0.85; text-decoration: none; }
.who .link:hover { opacity: 1; text-decoration: underline; }
.pill {
  background: rgba(255, 255, 255, 0.16);
  padding: 2px 10px;
  border-radius: var(--trek-radius-pill);
  font-size: 12px;
  font-weight: var(--trek-font-weight-semibold);
}

/* ---- tabs ---- */

.tabs {
  display: flex;
  gap: 2px;
  padding: 0 var(--trek-space-5);
  background: var(--trek-color-brand-navy-dark);
  border-bottom: 3px solid var(--trek-color-brand-orange);
}
.tab {
  appearance: none;
  border: 0;
  background: transparent;
  color: rgba(255, 255, 255, 0.72);
  font-family: var(--trek-font-family-body);
  font-size: var(--trek-font-size-small);
  font-weight: var(--trek-font-weight-medium);
  padding: var(--trek-space-3) var(--trek-space-4);
  min-height: 44px;
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -3px;
}
.tab:hover { color: var(--trek-color-semantic-text-on-dark); }
.tab.is-active {
  color: var(--trek-color-semantic-text-on-dark);
  border-bottom-color: var(--trek-color-brand-orange);
}

/* ---- layout ---- */

main { max-width: 1180px; margin: 0 auto; padding: var(--trek-space-5); }
.view { display: none; }
.view.is-active { display: block; }

.view-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--trek-space-4);
  margin-bottom: var(--trek-space-4);
  flex-wrap: wrap;
}
h1 { font-size: var(--trek-font-size-h2); font-weight: var(--trek-font-weight-semibold); margin: 0 0 3px; }
h2 { font-size: var(--trek-font-size-h3); font-weight: var(--trek-font-weight-semibold); margin: 0 0 var(--trek-space-2); }
.muted { color: var(--trek-color-semantic-text-muted); font-size: var(--trek-font-size-small); margin: 0; }
.small { font-size: var(--trek-font-size-small); }
.hint { font-size: 12px; color: var(--trek-color-semantic-text-muted); }
.spinner { color: var(--trek-color-semantic-text-muted); font-size: var(--trek-font-size-small); padding: var(--trek-space-5) 0; }

/* ---- buttons ---- */

.btn {
  appearance: none;
  font-family: var(--trek-font-family-body);
  font-size: var(--trek-font-size-small);
  font-weight: var(--trek-font-weight-semibold);
  padding: 10px 20px;
  min-height: 40px;
  /* A visible border, not a transparent one.
     The surface colour is white and cards are also white, so a transparent border made every
     secondary button invisible until hover: Add row, Rebalance, Close and Enrich all all read
     as plain text. A control nobody can see is a control nobody presses. */
  border: 2px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-md);
  background: var(--trek-color-semantic-surface);
  color: var(--trek-color-brand-navy);
  cursor: pointer;
}
.btn:hover:not(:disabled) {
  border-color: var(--trek-color-brand-navy);
  background: var(--trek-color-neutral-panel);
}
.btn:disabled {
  background: var(--trek-color-neutral-light-gray);
  color: var(--trek-color-neutral-mid-gray);
  cursor: not-allowed;
  border-color: transparent;
}
.btn-primary {
  background: var(--trek-color-brand-navy);
  border-color: var(--trek-color-brand-navy);
  color: var(--trek-color-semantic-text-on-dark);
}
.btn-primary:hover:not(:disabled) {
  background: var(--trek-color-brand-navy-dark);
  border-color: var(--trek-color-brand-navy-dark);
}
.btn-accent {
  background: var(--trek-color-brand-orange);
  border-color: var(--trek-color-brand-orange);
  color: var(--trek-color-semantic-text-on-dark);
}
.btn-danger {
  color: var(--trek-color-state-danger);
  border-color: var(--trek-color-semantic-border);
}
.btn-danger:hover:not(:disabled) { border-color: var(--trek-color-state-danger); }
.btn-sm { padding: 5px 11px; min-height: 32px; font-size: 12px; }
:root[data-theme='dark'] .btn-primary {
  background: var(--trek-color-brand-orange-light);
  border-color: var(--trek-color-brand-orange-light);
  color: var(--trek-color-brand-navy-dark);
}

/* ---- filters ---- */

.filters {
  display: flex;
  gap: var(--trek-space-2);
  align-items: center;
  margin-bottom: var(--trek-space-4);
  flex-wrap: wrap;
}
.chip {
  appearance: none;
  font-family: var(--trek-font-family-body);
  font-size: var(--trek-font-size-small);
  background: var(--trek-color-semantic-surface);
  border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-pill);
  padding: 6px 14px;
  min-height: 34px;
  cursor: pointer;
  color: var(--trek-color-semantic-text);
}
.chip.is-active {
  background: var(--trek-color-brand-navy);
  border-color: var(--trek-color-brand-navy);
  color: var(--trek-color-semantic-text-on-dark);
}

/* ---- form controls ---- */

input, select, textarea {
  font-family: var(--trek-font-family-body);
  font-size: var(--trek-font-size-small);
  padding: 9px 12px;
  border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-md);
  background: var(--trek-color-semantic-surface);
  color: var(--trek-color-semantic-text);
}
/* One visible focus state everywhere, using the orange ring the brand guide
   specifies. Required for accessibility, and never removed. */
input:focus, select:focus, textarea:focus, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--trek-color-semantic-focus);
  outline-offset: 1px;
  border-color: var(--trek-color-semantic-focus);
}
label { font-size: var(--trek-font-size-small); color: var(--trek-color-semantic-text-muted); display: inline-flex; gap: var(--trek-space-2); align-items: center; }

/* ---- cards and tables ---- */

.card {
  background: var(--trek-color-semantic-surface);
  border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-lg);
  padding: 18px;
  margin-bottom: var(--trek-space-4);
  box-shadow: var(--trek-shadow-card);
}

table { width: 100%; border-collapse: collapse; background: var(--trek-color-semantic-surface); }
.card table, #register-table table, #holdings-grid table {
  border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-lg);
  overflow: hidden;
}
th {
  text-align: left;
  font-family: var(--trek-font-family-body);
  font-size: var(--trek-font-size-label);
  font-weight: var(--trek-font-weight-semibold);
  color: var(--trek-color-semantic-text-muted);
  padding: 10px;
  border-bottom: 1px solid var(--trek-color-semantic-border);
  background: var(--trek-color-semantic-surface-sunken);
  white-space: nowrap;
}
td { padding: 10px; border-bottom: 1px solid var(--trek-color-semantic-border); font-size: var(--trek-font-size-small); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--trek-color-semantic-surface-sunken); }
.num { text-align: right; font-family: var(--trek-font-family-mono); font-size: var(--trek-font-size-label); }
.code { font-family: var(--trek-font-family-mono); font-size: var(--trek-font-size-label); }

/* ---- status badges ----
   Colour never carries the meaning alone: the status word is always present. */

.status {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--trek-radius-pill);
  font-size: 12px;
  font-weight: var(--trek-font-weight-semibold);
}
.status-Active { background: var(--trek-color-state-success-bg); color: var(--trek-color-state-success); }
.status-Review { background: var(--trek-color-state-warning-bg); color: var(--trek-color-state-warning); }
.status-Proposed { background: var(--trek-color-neutral-light-blue); color: var(--trek-color-brand-navy); }
.status-Archived { background: var(--trek-color-neutral-panel); color: var(--trek-color-semantic-text-muted); }

/* Signed figures always carry their sign, so the colour is reinforcement. */
.pos { color: var(--trek-color-state-success); }
.neg { color: var(--trek-color-state-danger); }

/* ---- metrics ---- */

.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--trek-space-3); }
.field label { display: block; margin-bottom: var(--trek-space-1); }
.field input, .field select, .field textarea { width: 100%; }

.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--trek-space-3); margin-bottom: var(--trek-space-4); }
.metric {
  background: var(--trek-color-semantic-surface);
  border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-lg);
  padding: var(--trek-space-3) var(--trek-space-4);
}
.metric .k { font-size: var(--trek-font-size-label); color: var(--trek-color-semantic-text-muted); }
.metric .v {
  font-family: var(--trek-font-family-heading);
  font-size: 21px;
  font-weight: var(--trek-font-weight-semibold);
  color: var(--trek-color-semantic-heading);
  margin-top: 2px;
}

/* ---- holdings editor ---- */

.editor-bar {
  display: flex;
  align-items: center;
  gap: var(--trek-space-4);
  flex-wrap: wrap;
  background: var(--trek-color-semantic-surface);
  border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-lg);
  padding: var(--trek-space-3) var(--trek-space-4);
  margin-bottom: var(--trek-space-3);
  box-shadow: var(--trek-shadow-card);
}
.readout {
  font-family: var(--trek-font-family-mono);
  font-size: var(--trek-font-size-small);
  font-weight: var(--trek-font-weight-semibold);
  padding: 5px 12px;
  border-radius: var(--trek-radius-md);
}
.readout.ok { background: var(--trek-color-state-success-bg); color: var(--trek-color-state-success); }
.readout.off { background: var(--trek-color-state-danger-bg); color: var(--trek-color-state-danger); }

.errors:not(:empty) {
  background: var(--trek-color-state-danger-bg);
  border-left: 6px solid var(--trek-color-state-danger);
  border-radius: 0 var(--trek-radius-md) var(--trek-radius-md) 0;
  color: var(--trek-color-state-danger);
  padding: 15px 20px;
  margin-bottom: var(--trek-space-3);
  font-size: var(--trek-font-size-small);
}
.errors ul { margin: var(--trek-space-1) 0 0; padding-left: 20px; }

.dropzone {
  border: 2px dashed var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-lg);
  background: var(--trek-color-semantic-surface);
  padding: var(--trek-space-6);
  text-align: center;
  margin-bottom: var(--trek-space-4);
}
.dropzone.is-over {
  border-color: var(--trek-color-brand-orange);
  background: var(--trek-color-state-warning-bg);
}
.dropzone p { margin: 0 0 var(--trek-space-3); }

.wbar {
  /* Removed from the flow. The bar sat beside the input and pushed the numbers out of
     alignment, so a column of weights no longer read as a column. Weight is a four-decimal
     figure people compare digit by digit; a rough visual length adds nothing and cost the
     alignment that does. */
  display: none;
}

/* ---- toast ---- */

.toast {
  position: fixed;
  bottom: var(--trek-space-5);
  left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: var(--trek-color-brand-navy);
  color: var(--trek-color-semantic-text-on-dark);
  padding: var(--trek-space-3) var(--trek-space-5);
  border-radius: var(--trek-radius-md);
  font-size: var(--trek-font-size-small);
  box-shadow: var(--trek-shadow-lg);
  opacity: 0;
  transition: transform 0.2s, opacity 0.2s;
  pointer-events: none;
}
.toast.show { transform: translateX(-50%) translateY(0); opacity: 1; }
.toast.bad { background: var(--trek-color-state-danger); }

@media (prefers-reduced-motion: reduce) {
  .toast { transition: none; }
}


/* ------------------------------------------------------------- returns editor */
.ret-in { font-family: var(--trek-font-family-mono); text-align: right; }
/* A value beyond 50% is a percentage typed where a fraction was expected, flagged as you type
   rather than on save. */
.ret-in.is-bad {
  border-color: var(--trek-color-state-danger);
  background: var(--trek-color-state-danger-bg);
  color: var(--trek-color-state-danger);
}
.pill-warn {
  background: var(--trek-color-state-warning-bg); color: var(--trek-color-state-warning);
  font-size: 11px; padding: 2px 8px; border-radius: var(--trek-radius-pill);
}

/* ------------------------------------------------------------ inline guidance
   A details block rather than a paragraph, so the explanation is one click away for someone
   who needs it and invisible to someone who does not. */
.tmh-help { margin: 8px 0 4px; }
.tmh-help summary {
  cursor: pointer; font-size: 13px; font-weight: var(--trek-font-weight-semibold);
  color: var(--trek-color-brand-navy); padding: 6px 0;
}
.tmh-help dl { margin: 8px 0 0; font-size: 13px; }
.tmh-help dt {
  font-weight: var(--trek-font-weight-semibold); color: var(--trek-color-brand-navy);
  margin-top: 10px;
}
.tmh-help dd { margin: 3px 0 0; color: var(--trek-color-semantic-text); line-height: 1.55; }
.tmh-help code {
  font-family: var(--trek-font-family-mono); font-size: 12px;
  background: var(--trek-color-semantic-surface-sunken); padding: 1px 5px; border-radius: 4px;
}


/* ------------------------------------------------- holdings edit mode switch
   Two segments rather than a checkbox, because the choice is between two actions rather than
   on and off, and a mislabelled toggle here overwrites a month of composition history. */
.mode-switch { display: inline-flex; border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-pill); overflow: hidden; }
.mode {
  border: 0; cursor: pointer; padding: 7px 15px; font-size: 12.5px;
  font-family: var(--trek-font-family-body); font-weight: var(--trek-font-weight-semibold);
  background: var(--trek-color-semantic-surface); color: var(--trek-color-brand-navy);
}
.mode.is-on { background: var(--trek-color-brand-navy); color: var(--trek-color-semantic-text-on-dark); }
.mode:not(.is-on):hover { background: var(--trek-color-neutral-panel); }

/* Rebalance history. Each snapshot is in force until the next, which the row makes visible. */
.snap-row { display: flex; flex-wrap: wrap; gap: 6px; }
.snap {
  cursor: pointer; border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-md); padding: 5px 10px;
  background: var(--trek-color-semantic-surface);
  font-family: var(--trek-font-family-mono); font-size: 12px;
  color: var(--trek-color-brand-navy); display: inline-flex; align-items: center; gap: 7px;
}
.snap.is-on { border-color: var(--trek-color-brand-navy); background: var(--trek-color-neutral-panel);
  font-weight: var(--trek-font-weight-semibold); }
.snap-n { font-size: 10px; color: var(--trek-color-semantic-text-muted);
  background: var(--trek-color-semantic-surface-sunken); border-radius: 8px; padding: 1px 6px; }


/* Grid footer. Add row sits where a new row appears rather than in the toolbar above, and the
   note beside it answers the question the controls raise: what has actually been saved. */
.grid-foot {
  /* One action bar under the grid, where the editing happens. These controls previously sat in
     the toolbar above and wrapped onto a second line on a narrower screen, which put Save
     somewhere unpredictable. */
  display: flex; align-items: center; gap: var(--trek-space-3); flex-wrap: wrap;
  padding: var(--trek-space-3) 0 0;
  border-top: 1px solid var(--trek-color-semantic-border);
  margin-top: var(--trek-space-2);
}
/* Push Save to the right, so the destructive-ish action is not adjacent to Add row. */
.grid-foot .hint { max-width: 46ch; margin-left: auto; text-align: right; }
.grid-foot .btn-primary { margin-left: 0; }


/* A flagged count is a review item, not a failure, so it is amber rather than red. Rendering
   both conditions in red made a balanced 100.0000% look like the problem. */
.warn, td.warn { color: var(--trek-color-state-warning); }


/* ------------------------------------------------------------ weight total
   Restated under the grid. It lived only in the toolbar, which is off screen by the time
   anyone has scrolled to the row they are editing, and a total of 110% is worth knowing while
   typing rather than after scrolling back up. */
.weight-bar {
  display: flex; align-items: baseline; gap: var(--trek-space-3); flex-wrap: wrap;
  padding: 10px 14px; border-radius: var(--trek-radius-md);
  background: var(--trek-color-semantic-surface-sunken);
  border: 1px solid var(--trek-color-semantic-border);
  margin-top: var(--trek-space-3);
}
.wb-label { font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--trek-color-semantic-text-muted); font-weight: var(--trek-font-weight-semibold); }
.wb-value { font-family: var(--trek-font-family-mono); font-size: 17px;
  font-weight: var(--trek-font-weight-semibold); color: var(--trek-color-semantic-heading); }
.wb-note { font-size: 12px; color: var(--trek-color-semantic-text-muted); }

.weight-bar.is-ok  { border-color: #BFDCC9; background: #F2F8F4; }
.weight-bar.is-ok  .wb-value { color: var(--trek-color-state-success); }
/* Off is a block on saving, not a caution, so it reads as one. */
.weight-bar.is-off { border-color: #E8B9B5; background: var(--trek-color-state-danger-bg); }
.weight-bar.is-off .wb-value,
.weight-bar.is-off .wb-note { color: var(--trek-color-state-danger); }


/* ------------------------------------------------------------ grid weight total
   The same number as the readout beside the model picker, repeated where the work happens. A
   figure in the top right is easy to miss while editing row forty, which is how a model reaches
   110% without anyone noticing. */
.grid-total {
  display: flex; align-items: baseline; gap: var(--trek-space-3);
  padding: var(--trek-space-3) var(--trek-space-4);
  border-top: 2px solid var(--trek-color-semantic-border);
  background: var(--trek-color-semantic-surface-sunken);
  border-radius: 0 0 var(--trek-radius-md) var(--trek-radius-md);
}
.grid-total:empty { display: none; }
.gt-ok, .gt-bad {
  font-family: var(--trek-font-family-heading); font-size: 16px;
  font-weight: var(--trek-font-weight-semibold);
}
.gt-ok { color: var(--trek-color-state-success); }
.gt-bad { color: var(--trek-color-state-danger); }
.gt-note { font-size: 12.5px; color: var(--trek-color-semantic-text-muted); }
.gt-note-bad { color: var(--trek-color-state-danger); font-weight: var(--trek-font-weight-medium); }


/* ------------------------------------------------------------------ page help
   Closed by default. Someone using this console daily does not need the explanation on screen
   every time, and someone using it twice a year needs it without having to ask. A details
   element serves both; a permanent panel serves neither. */
.page-help {
  margin: 0 0 var(--trek-space-4);
  border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-md);
  background: var(--trek-color-semantic-surface);
}
.page-help summary {
  cursor: pointer; padding: 10px 16px;
  font-size: 13px; font-weight: var(--trek-font-weight-semibold);
  color: var(--trek-color-brand-navy);
}
.page-help[open] summary { border-bottom: 1px solid var(--trek-color-semantic-border); }
.page-help dl { margin: 0; padding: 4px 16px 14px; font-size: 13px; }
.page-help dt {
  font-weight: var(--trek-font-weight-semibold); color: var(--trek-color-brand-navy);
  margin-top: 12px;
}
.page-help dd {
  margin: 3px 0 0; color: var(--trek-color-semantic-text); line-height: 1.55; max-width: 82ch;
}


/* A locked date field. readOnly rather than disabled, so the value is still submitted and still
   readable by a screen reader; disabled would remove it from the form and the accessibility
   tree both. */
input.is-locked {
  background: var(--trek-color-semantic-surface-sunken);
  color: var(--trek-color-semantic-text-muted);
  cursor: not-allowed;
}


/* A file that cannot be imported. Tinted rather than only red text, so a bad row in a list of
   twenty is found by scanning rather than by reading each one. */
tr.row-bad > td { background: var(--trek-color-state-danger-bg); }
tr.row-bad .errors { border: 0; padding: 6px 10px; margin: 0; background: none; }


/* Headings inside the page help, now that it covers two modes rather than one flow. */
.page-help h3 {
  font-family: var(--trek-font-family-heading); font-size: 14px;
  color: var(--trek-color-brand-navy); margin: 16px 0 4px;
  padding-bottom: 4px; border-bottom: 2px solid var(--trek-color-brand-orange);
}
.page-help h3:first-of-type { margin-top: 8px; }
.page-help dd code {
  font-family: var(--trek-font-family-mono); font-size: 12px;
  background: var(--trek-color-semantic-surface-sunken); padding: 1px 5px; border-radius: 4px;
}


/* Labelled inputs in a bar. The label stacks above its control so a row of them reads as a form
   rather than as a sentence with boxes in it. */
.bar label { display: flex; flex-direction: column; gap: 4px; font-size: 12px;
  color: var(--trek-color-semantic-text-muted); font-weight: var(--trek-font-weight-semibold); }


/* An inline checkbox with its label, for options that qualify an action rather than being one. */
label.check {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: var(--trek-font-weight-semibold);
  color: var(--trek-color-brand-navy); cursor: pointer;
}
label.check input { margin: 0; }


/* -------------------------------------------------- per-row import review
   A scrolling region rather than a page that grows to two thousand rows: the reviewer works through
   a group, and the commit button has to stay reachable while they do. */
.scroll-y { max-height: 340px; overflow-y: auto; border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-md); }
.scroll-y table { margin: 0; }
/* Sticky header, because scrolling past it in a table of paired numbers means losing which column
   is stored and which is incoming. */
.scroll-y thead th { position: sticky; top: 0; z-index: 1; }
.rowgroup { margin-top: 8px; }
.rowgroup td input[type='checkbox'] { margin: 0; }


/* Status pills for the batch list. Three states that need distinguishing at a glance: needs
   attention, needs review, done. */
.pill-ok  { background: var(--trek-color-state-success-bg); color: var(--trek-color-state-success);
  font-size: 11px; padding: 2px 8px; border-radius: var(--trek-radius-pill); }
.pill-bad { background: var(--trek-color-state-danger-bg); color: var(--trek-color-state-danger);
  font-size: 11px; padding: 2px 8px; border-radius: var(--trek-radius-pill); }


/* The console build, in the header. Quiet, but present: the question "is what I deployed what I am
   looking at" should not require opening developer tools. */
.buildstamp {
  font-family: var(--trek-font-family-mono); font-size: 10.5px;
  color: var(--trek-color-semantic-text-muted); opacity: .8;
  padding: 2px 8px; border: 1px solid var(--trek-color-semantic-border);
  border-radius: var(--trek-radius-pill);
}


/* ---------------------------------------------------------------- field units and help

   Two related additions, both about making a number's UNIT impossible to miss.

   The model form carries three numeric conventions at once and always did: a model fee as a
   decimal fraction, allocations as percentages, minimums as dollars. They used to be explained in
   a paragraph under each field, which was accurate, unmissable and unread -- five stacked
   paragraphs is a wall. So the unit moved onto the control, where it cannot be skipped, and the
   prose moved into a bubble for whoever wants it.

   The specific error being guarded is quiet: 27 typed where 0.0027 was meant, or 0.02 typed into a
   field that now expects 2. Neither looks wrong on screen, and both reach a client-facing fee
   breakdown. A $ or a % rendered against the box is the cheapest possible defence. */

.unit { display: flex; align-items: stretch; width: 100%; }
.unit input { flex: 1 1 auto; min-width: 0; }

/* The tag is visually part of the input, so the border is drawn once around the pair rather than
   twice with a seam down the middle. */
.unit-tag {
  display: flex;
  align-items: center;
  padding: 0 var(--trek-space-2, 8px);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--trek-color-semantic-text-muted);
  background: var(--trek-color-semantic-surface-sunken, rgba(0, 0, 0, 0.04));
  border: 1px solid var(--line);
  white-space: nowrap;
}
.unit-prefix .unit-tag { border-right: 0; border-radius: 6px 0 0 6px; }
.unit-prefix input { border-radius: 0 6px 6px 0; }
.unit-suffix .unit-tag { border-left: 0; border-radius: 0 6px 6px 0; }
.unit-suffix input { border-radius: 6px 0 0 6px; }

/* Dollars and percentages line up under each other when they are tabular, which is what makes a
   column of them scannable. */
.unit input, input[data-kind='fee'] { font-variant-numeric: tabular-nums; }

/* The live basis-point echo under a fee input. Empty until there is a figure, so it does not
   reserve a blank line on every form. */
.bps-echo:empty { display: none; }

/* The help bubble. No JavaScript and no icon library: this console has no runtime dependencies and
   the brand guide rules out a CDN, so it is a styled span and CSS. */
.bub { position: relative; display: inline-block; margin-left: 5px; vertical-align: middle; }
.bub-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  cursor: help;
  color: var(--trek-color-semantic-text-on-dark, #fff);
  background: var(--trek-color-semantic-text-muted, #8d9092);
}
.bub:hover .bub-mark, .bub:focus-visible .bub-mark {
  background: var(--trek-color-brand-navy, #18344b);
}

.bub-tip {
  position: absolute;
  bottom: 125%;
  left: -6px;
  z-index: 40;
  display: none;
  width: 290px;
  padding: 9px 11px;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.45;
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  color: var(--trek-color-semantic-text-on-dark, #fff);
  background: var(--trek-color-brand-navy, #18344b);
  border-radius: 7px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
}
/* Shown on hover AND on keyboard focus. Without the focus rule the help is unreachable for anyone
   not using a mouse, which would make the move to bubbles a regression for them. */
.bub:hover .bub-tip, .bub:focus-visible .bub-tip, .bub:focus-within .bub-tip { display: block; }

/* Fields in the right-hand column would push their tooltip off the edge of the viewport. Flipping
   it is one rule and costs nothing when it is not needed. */
.grid-2 > .field:nth-child(even) .bub-tip,
.grid-4 > .field:nth-child(4n) .bub-tip { left: auto; right: -6px; }

/* ---------------------------------------------------------------- reference rows

   The columns are declared here rather than inline so every row in a table shares one grid and the
   inputs line up down the page. They were inline per row, which is fine until a cell's content
   changes width and the whole column steps sideways.

   A row being added carries .is-new: tinted, so an unsaved form is visibly not a record. The
   earlier version left a permanently empty row at the bottom of each table with placeholder text
   in it, which read as a saved row that had somehow lost its values -- the risk band table looked
   like it listed Moderate Aggressive twice. */

.ref-row { padding: 10px 0; border-top: 1px solid var(--line); }
.ref-row:first-child { border-top: 0; }

.ref-grid { display: grid; gap: 10px; align-items: end; }
/* level | shown as | prefix | fee | charged on | actions */
.ref-grid-level { grid-template-columns: 1.1fr 1.4fr 0.7fr 0.9fr 1.1fr auto; }
/* classification | from | to | order | active | actions */
.ref-grid-band { grid-template-columns: 1.7fr 0.7fr 0.7fr 0.7fr 0.6fr auto; }

/* Buttons sit on the input baseline, not the label's. */
.ref-actions { display: flex; gap: 6px; align-items: center; padding-bottom: 1px; }

.ref-row textarea { width: 100%; font: inherit; font-size: 13px; padding: 6px 8px;
  border: 1px solid var(--line); border-radius: 6px; }
.ref-desc { margin-top: 8px; }
.ref-usage { margin-top: 6px; }

/* An unsaved row. Tinted rather than outlined, so it reads as a draft rather than an error. */
.ref-row.is-new {
  margin: 4px -10px 0;
  padding: 10px;
  border: 1px dashed var(--trek-color-semantic-text-muted, #8d9092);
  border-radius: 8px;
  background: var(--trek-color-semantic-surface-sunken, rgba(0, 0, 0, 0.03));
}

/* One column below the point where six of them stop being readable. */
@media (max-width: 1000px) {
  .ref-grid-level, .ref-grid-band { grid-template-columns: 1fr; }
  .ref-actions { justify-content: flex-start; padding-top: 4px; }
}

/* ---------------------------------------------------------------- health page fixes

   Inline controls on a health row, so a reported problem can be resolved where it is reported.
   Sending someone to another tab holding a model code in their head is how a list of eleven
   problems becomes the same list next month. */

.yield-set { display: flex; gap: 6px; align-items: center; }
.yield-set input[type='date'] { font-size: 12px; }

/* A small explanatory table inside a health card: what each state means and what to do about it.
   Quieter than the data table below it, because it is reference rather than findings. */
table.mini { font-size: 12px; }
table.mini th, table.mini td {
  padding: 5px 8px;
  vertical-align: top;
  color: var(--trek-color-semantic-text-muted);
}
table.mini td:first-child { white-space: nowrap; color: inherit; }
table.mini td:last-child { color: inherit; }

/* An edit history, collapsed. A details element rather than a panel: it answers a question rather
   than forming part of the form, and it should cost nothing to have on every model. */
.edit-history { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 8px; }
.edit-history > summary {
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: var(--trek-color-semantic-text-muted);
  list-style: none;
}
.edit-history > summary::-webkit-details-marker { display: none; }
.edit-history > summary::before { content: '\25b8  '; }
.edit-history[open] > summary::before { content: '\25be  '; }
.edit-history > summary:hover { color: var(--trek-color-brand-navy, #18344b); }

/* ---------------------------------------------------------------- health progress

   Shown while the health page runs its twenty-one checks. A bare spinner for four seconds reads as
   a page that might be broken; this shows what is being run and how far through it is.

   Everything here is CSS. No library, no sprite, no remote asset -- the brand guide rules out a CDN
   dependency and this console has no build step, so an animation that needs neither is the only kind
   that survives. */

.hp {
  max-width: 620px;
  margin: 28px auto;
  padding: 22px 24px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--trek-color-semantic-surface-raised, #fff);
  box-shadow: 0 6px 24px rgba(24, 52, 75, 0.07);
}

.hp-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.hp-title { font-size: 15px; font-weight: 600; color: var(--trek-color-brand-navy, #18344b); }
.hp-sub { font-size: 12px; color: var(--trek-color-semantic-text-muted); margin-top: 2px; }
.hp-head > div:nth-child(2) { flex: 1 1 auto; }
.hp-clock {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--trek-color-semantic-text-muted);
}

/* The orb. Two counter-rotating arcs rather than a single spinner, so it reads as work being done
   on something rather than a page waiting on a network call. */
.hp-orb {
  position: relative;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
}
.hp-orb::before, .hp-orb::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid transparent;
}
.hp-orb::before {
  border-top-color: var(--trek-color-brand-navy, #18344b);
  border-right-color: var(--trek-color-brand-navy, #18344b);
  animation: hp-spin 1.1s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}
.hp-orb::after {
  inset: 6px;
  border-bottom-color: var(--trek-color-brand-orange, #f7941e);
  border-left-color: var(--trek-color-brand-orange, #f7941e);
  animation: hp-spin 1.6s cubic-bezier(0.5, 0, 0.5, 1) infinite reverse;
}
@keyframes hp-spin { to { transform: rotate(360deg); } }

.hp-bar {
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--trek-color-semantic-surface-sunken, rgba(24, 52, 75, 0.08));
}
.hp-fill {
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg,
    var(--trek-color-brand-navy, #18344b),
    var(--trek-color-brand-orange, #f7941e));
  transition: width 140ms linear;
  /* A slow sheen, so a bar that is holding short of full still looks alive rather than stuck. */
  background-size: 200% 100%;
  animation: hp-sheen 2.4s ease-in-out infinite;
}
@keyframes hp-sheen {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

.hp-list {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 18px;
  font-size: 12px;
}
.hp-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
  color: var(--trek-color-semantic-text-muted);
  opacity: 0.45;
  transition: opacity 200ms ease, color 200ms ease;
}
.hp-list li.is-running { opacity: 1; color: var(--trek-color-brand-navy, #18344b); }
.hp-list li.is-done { opacity: 1; }

/* The tick: an empty ring that fills and gains a check. */
.hp-tick {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  position: relative;
}
.hp-list li.is-running .hp-tick { animation: hp-pulse 0.9s ease-in-out infinite; }
.hp-list li.is-done .hp-tick {
  border-color: var(--trek-color-state-good, #2e7d32);
  background: var(--trek-color-state-good, #2e7d32);
  animation: none;
}
.hp-list li.is-done .hp-tick::after {
  content: '';
  position: absolute;
  left: 3px;
  top: 1px;
  width: 4px;
  height: 7px;
  border: solid #fff;
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(40deg);
}
@keyframes hp-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.28); opacity: 0.6; }
}

.hp-note {
  margin: 14px 0 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--trek-color-semantic-text-muted);
}

@media (max-width: 700px) { .hp-list { grid-template-columns: 1fr; } }

/* Respect a stated preference for less motion. The panel still informs; it just stops moving. */
@media (prefers-reduced-motion: reduce) {
  .hp-orb::before, .hp-orb::after, .hp-fill, .hp-list li.is-running .hp-tick { animation: none; }
}
