/* model.css — the model view (REVAMP-DESIGN §7, §11 WP12): Progress › The
 * model and Me › Lab › Energy balance, both drawn by js/model.js.
 *
 * Every class is prefixed model-; what the kit draws (a tile, a tag, a gauge,
 * a stage, a chart, a nav row) keeps its own styling from base.css and is
 * only placed here. Greys and tokens only: the accent paints the person's own
 * estimates (the charts draw those themselves) and the legend's marks for
 * them; categories are greys; red is only a limit passed, which the kit's
 * gauge draws. Nothing is set under 13px, and nothing answers to the
 * viewport: the face column and the pane are the containers (§3.3).
 */

.model-host { display: grid; min-width: 0; }
.model-wait { font: var(--t-sub); color: var(--ink-2); padding: 8px 0; }
/* The page's shape while it reads (§6 Loading): blocks, no words. */
.model-skel { display: grid; gap: 18px; max-width: 640px; }
.model-skel-hero { height: 44px; width: 42%; }
/* The six numbers' hairline grid, each cell a label and a figure. */
.model-skel-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-top: 1px solid var(--line); }
.model-skel-cell { display: grid; gap: 8px; padding: 14px 12px 14px 0; border-bottom: 1px solid var(--line); }
.model-skel-cell:nth-child(2n) { padding-left: 12px; border-left: 1px solid var(--line); }
.model-skel-k { display: block; height: 10px; width: 48%; }
.model-skel-v { display: block; height: 20px; width: 64%; }
.model-skel-chart { height: 180px; }

.model-view {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
  min-width: 0;
}
.model-view > * { min-width: 0; }

/* ---- the head: what the reading rests on, and the ladder in words ---- */

.model-head { display: grid; gap: 8px; }
.model-stamp {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font: var(--t-sub);
  color: var(--ink-2);
  text-wrap: pretty;
}
/* Which model the page trusts, in words: an annotation with an edge rule
 * (never accent), set a size under the figures it qualifies. */
.model-ladder { display: grid; gap: 2px; padding-left: 12px; border-left: 2px solid var(--edge); }
.model-ladder-text { font: var(--t-sub); color: var(--ink); text-wrap: pretty; }
.model-ladder-rate { font: var(--t-sub); color: var(--ink-2); text-wrap: pretty; }
.model-tag { flex: none; }

/* ---- the hero: body fat on the DEXA scale ---- */

.model-hero { display: grid; gap: 6px; }
.model-hero-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.model-hero-main { margin: 0; min-width: 0; }
.model-hero-v {
  font: var(--t-display);
  font-stretch: 85%;
  letter-spacing: -.01em;
  color: var(--ink);
}
.model-hero-u {
  font: 450 var(--t-row-size)/1.2 var(--font);
  color: var(--ink-2);
  white-space: nowrap;
}
.model-hero-top .prov,
.model-hero-top .tag { margin-top: 8px; flex: none; }
.model-hero-sub { font: var(--t-sub); color: var(--ink-2); text-wrap: pretty; }

/* ---- the six numbers, a hairline grid (§7.1 item 3) ---- */

.model-kpis {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--line);
}
.model-kpi {
  display: grid;
  align-content: start;
  gap: 3px;
  min-width: 0;
  padding: 12px 12px 12px 0;
  border-bottom: 1px solid var(--line);
}
.model-kpi:nth-child(2n) { padding-left: 12px; border-left: 1px solid var(--line); }
.model-kpi-k { font: var(--t-cap); color: var(--ink-2); }
.model-kpi-v { font: 600 22px/1.1 var(--font); font-stretch: 92%; color: var(--ink); }
.model-kpi-u,
.model-pm { font: 450 var(--t-cap-size)/1.2 var(--font); font-stretch: 100%; color: var(--ink-2); }
.model-kpi-none { font: var(--t-body); color: var(--ink-2); }
.model-kpi-sub { font: var(--t-cap); color: var(--ink-2); text-wrap: pretty; }
.model-kpi .tag { justify-self: start; margin-top: 2px; }
/* A last cell alone on its row spans it: no half-width hairline hangs. */
.model-kpi.is-lone-2 { grid-column: 1 / -1; }

/* ---- sections ---- */

/* Packed from the top: in the wide pane two sections share a row, and the
 * shorter one must not spread its parts down the taller one's height. */
.model-sec { display: grid; gap: 10px; min-width: 0; align-content: start; }
/* A section's date range or unit drops under its title, whole, when the two
 * do not fit on one line (a 320 phone), rather than both wrapping ragged. */
.model-sec .sec-head { flex-wrap: wrap; row-gap: 2px; padding-top: 6px; padding-bottom: 0; }
.model-sec .sec-meta { white-space: nowrap; }
.model-sec .chart { margin: 0; }
.model-note { font: var(--t-sub); color: var(--ink-2); text-wrap: pretty; }
.model-none { display: grid; justify-items: start; gap: 8px; font: var(--t-body); color: var(--ink-2); }
.model-none p { text-wrap: pretty; }

.model-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font: var(--t-cap);
  color: var(--ink-2);
}
.model-key { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.model-key-mark { flex: none; display: inline-block; }
.model-key-mark.is-print,
.model-key-mark.is-measured { width: 8px; height: 8px; border-radius: 999px; background: var(--ink-2); }
.model-key-mark.is-estimated {
  width: 9px; height: 9px; border-radius: 999px;
  box-shadow: inset 0 0 0 1.75px var(--accent-ink);
}
.model-key-mark.is-trend { width: 16px; height: 2.5px; border-radius: 2px; background: var(--accent-ink); }
.model-key-mark.is-band { width: 16px; height: 10px; border-radius: 2px; background: var(--accent-band); }
.model-key-mark.is-fan { width: 16px; height: 10px; border-radius: 2px; background: var(--accent-fan); }
.model-key-mark.is-pace { width: 16px; height: 0; border-top: 2.5px dotted var(--accent-ink); }
.model-key-mark.is-second,
.model-key-mark.is-plan { width: 16px; height: 0; border-top: 1.75px dashed var(--ink-2); }
.model-key-mark.is-ink { width: 16px; height: 2px; border-radius: 2px; background: var(--ink-2); }
.model-key-mark.is-bar { width: 9px; height: 10px; border-radius: 2px; background: var(--ink-3); }
.model-key-mark.is-incomplete {
  width: 9px; height: 10px; border-radius: 2px;
  border: 1.25px dashed var(--ink-3);
}

/* ---- where the deficit goes ---- */

.model-deficit-top,
.model-share-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.model-deficit-k,
.model-share-k {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: 600 var(--t-row-size)/1.3 var(--font);
  color: var(--ink);
}
.model-deficit-v,
.model-share-v {
  font: 600 22px/1.1 var(--font);
  font-stretch: 92%;
  color: var(--ink);
  white-space: nowrap;
}
.model-gauge { margin-top: 2px; }
.model-share { display: grid; gap: 4px; padding-top: 6px; }

/* ---- fat and lean: the kit's tiles, a DEXA scan as a dot on the line ---- */

.model-sec-fatlean .tile-spark { height: 34px; }

/* ---- where the plan lands: three forecasts in a hairline row ---- */

.model-fcs {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line);
}
.model-fc {
  display: grid;
  align-content: start;
  gap: 3px;
  min-width: 0;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.model-fc-k { font: var(--t-cap); color: var(--ink-2); }
/* Stacked (a phone, the wide pane's side column), each forecast is a row:
 * its label and words on the left, the figure set right on the label's
 * line, like the rest of the app's rows. */
.model-fc { grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; }
.model-fc > * { grid-column: 1; }
.model-fc > .model-fc-v { grid-column: 2; grid-row: 1 / span 2; align-self: start; text-align: right; white-space: nowrap; }
.model-fc > .model-share-gauge { grid-column: 1 / -1; }
.model-fc-v { font: 600 22px/1.1 var(--font); font-stretch: 92%; color: var(--ink); }
.model-fc-sub { font: var(--t-cap); color: var(--ink-2); text-wrap: pretty; }
.model-lands-lead { color: var(--ink-2); }

/* The water's share: a grey bar against half-way (a category, never the
 * accent: §4.1). */
.model-share-gauge {
  position: relative;
  display: block;
  height: 8px;
  margin-top: 6px;
  border-radius: 4px;
  background: var(--surface-2);
}
.model-share-gauge i { position: absolute; top: 0; bottom: 0; }
.model-share-gauge .model-share-gauge-fill { left: 0; border-radius: 4px; background: var(--ink-3); }
.model-share-gauge .model-share-gauge-half {
  left: 50%;
  top: -3px;
  bottom: -3px;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--ink-2);
}

/* ---- does the model earn its keep: two grey bars when there is no ladder ---- */

.model-miss {
  display: grid;
  grid-template-columns: minmax(0, 9em) minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
}
.model-miss-k { font: var(--t-sub); color: var(--ink); }
.model-miss-track { position: relative; display: block; height: 12px; border-radius: 3px; background: var(--surface-2); }
.model-miss-track i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; background: var(--ink-3); }
.model-miss-v { font: 600 var(--t-sub-size)/1.2 var(--font); color: var(--ink); white-space: nowrap; }

/* ---- what the data says: sentences with an edge rule, never accent ---- */

.model-says { display: grid; gap: 14px; }
.model-say { display: grid; gap: 2px; padding-left: 12px; border-left: 2px solid var(--edge); }
.model-say-h { font: 600 var(--t-body-size)/1.35 var(--font); color: var(--ink); }
.model-say-p { font: var(--t-sub); color: var(--ink-2); text-wrap: pretty; }

/* ---- the error and the corner ---- */

.model-error { display: grid; justify-items: start; gap: 8px; padding: 12px 0; }
.model-error-title { font: var(--t-head); color: var(--ink); }
.model-actions { display: inline-flex; align-items: center; gap: 8px; }
.model-window { flex: none; }
/* The kit's segments share the track equally and ellipsise (base.css); in a
 * corner the track is only as wide as its words, so each segment takes its
 * own width and the chosen one, set bolder, never becomes "2…" (the A pass). */
.model-window .segmented-btn {
  flex: 1 0 auto;
  min-width: 52px;
  padding-left: 10px;
  padding-right: 10px;
  white-space: nowrap;
  text-overflow: clip;
}

/* ---- the pushed screens: tables, facts, lists ---- */

.model-sub,
.model-numbers { display: grid; gap: 12px; min-width: 0; }
.model-sub .sec-head { padding-top: 8px; padding-bottom: 0; }
.model-list { display: grid; gap: 8px; padding-left: 18px; font: var(--t-sub); color: var(--ink); }
.model-list li { text-wrap: pretty; }
.model-checks { list-style: none; padding-left: 0; }
.model-checks li { color: var(--ink-2); }
.model-checks li[data-pass="true"] { color: var(--ink); }

.model-facts { display: grid; border-top: 1px solid var(--line); }
.model-fact {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.model-fact-k { font: var(--t-body); color: var(--ink); min-width: 0; }
.model-fact-v { font: 560 var(--t-body-size)/1.3 var(--font); color: var(--ink); text-align: right; }
.model-fact-sub { grid-column: 1 / -1; font: var(--t-cap); color: var(--ink-2); text-wrap: pretty; }

.model-ests { display: grid; border-top: 1px solid var(--line); }
.model-est { display: grid; gap: 3px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.model-est-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.model-est-name { font: var(--t-body); color: var(--ink); min-width: 0; text-wrap: pretty; }
.model-est-v { font: 600 var(--t-row-size)/1.2 var(--font); color: var(--ink); white-space: nowrap; }
.model-est-range { font: var(--t-cap); color: var(--ink-2); }
.model-est-why { font: var(--t-cap); color: var(--ink-2); text-wrap: pretty; }
.model-est-why .tag { vertical-align: middle; }
/* Short of days: the words say so; the figure steps back to ink-2 (never an
 * opacity, which would take the text under AA). */
.model-est.is-short .model-est-v,
.model-est.is-short .model-est-name { color: var(--ink-2); }

.model-consts { display: grid; border-top: 1px solid var(--line); }
.model-const { display: grid; gap: 2px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.model-const-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.model-const-k { font: 560 var(--t-sub-size)/1.3 var(--font); color: var(--ink); min-width: 0; }
.model-const-v { font: var(--t-sub); color: var(--ink); text-align: right; overflow-wrap: anywhere; }
.model-const-src { font: var(--t-cap); color: var(--ink-2); text-wrap: pretty; overflow-wrap: anywhere; }

/* ---- Me › Lab › Energy balance ---- */

.model-energy { display: grid; gap: 16px; min-width: 0; }
.model-energy-head { display: grid; gap: 6px; }
.model-proc-key { display: flex; flex-wrap: wrap; gap: 4px 14px; font: var(--t-cap); color: var(--ink-2); }
.model-energy-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; min-width: 0; }
.model-energy-aside { display: grid; gap: 14px; align-content: start; min-width: 0; }
.model-energy-aside .callout { margin-top: 0; }
.model-stage-tag { display: flex; margin-top: 6px; }
.model-strip .stackbar-wrap { max-width: 100%; }
.model-parts { display: grid; gap: 2px; }
.model-degr { display: grid; gap: 8px; }
.model-degr .sec-head { padding-top: 0; padding-bottom: 0; }

.model-minis-wrap { display: grid; gap: 8px; }
/* In the wide pane's narrow aside the corner words drop under the title,
 * whole, rather than both wrapping ragged. */
.model-minis-wrap .sec-head { padding-top: 0; padding-bottom: 0; flex-wrap: wrap; row-gap: 2px; }
.model-minis-wrap .sec-meta { white-space: nowrap; }
.model-minis { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
.model-mini {
  display: grid;
  align-content: start;
  gap: 2px;
  min-width: 0;
  padding: 11px 11px 10px;
  border-radius: var(--r-tile);
  background: var(--surface);
  box-shadow: var(--lift);
}
.model-mini-k { font: 500 var(--t-cap-size)/1.2 var(--font); color: var(--ink-2); }
.model-mini-sub { font: var(--t-cap); color: var(--ink-2); text-wrap: pretty; }

/* ---- a narrow phone (320) ---- */

@container face (max-width: 340px) {
  .model-hero-v { font-size: 40px; }
  .model-kpi-v,
  .model-fc-v,
  .model-deficit-v,
  .model-share-v { font-size: 20px; }
  .model-miss { grid-template-columns: minmax(0, 1fr) auto; }
  .model-miss-track { grid-column: 1 / -1; grid-row: 2; }
}

/* ---- the three forecasts in a row, once there is room ----
 * Not on a phone: three columns of 110px set the landing's sentence and
 * the water's share five lines deep beside a lone figure. Stacked, each
 * reads as one line of label, figure and words. */

@container face (min-width: 520px) {
  /* In a row of three, each cell is a column again. */
  .model-fcs .model-fc { grid-template-columns: minmax(0, 1fr); }
  .model-fcs .model-fc > .model-fc-v { grid-column: 1; grid-row: auto; text-align: left; }
  .model-fcs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* One label that wraps ("Reaching the target") no longer drops its figure
   * below its neighbours': every label keeps two lines' room, set on the
   * lower one, so the three figures share a baseline. */
  .model-fcs:not(.model-fcs-1) > .model-fc > .model-fc-k { min-height: 2.7em; display: flex; align-items: flex-end; }
  .model-fcs-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .model-fcs-1 { grid-template-columns: minmax(0, 1fr); }
  .model-fc { padding: 12px 10px 12px 0; }
  .model-fc + .model-fc { padding-left: 10px; border-left: 1px solid var(--line); }
}

/* ---- the wide pane (§7.1 "Wide", §7.2 "Wide") ---- */

@container pane (min-width: 520px) {
  /* In a row of three, each cell is a column again. */
  .model-fcs .model-fc { grid-template-columns: minmax(0, 1fr); }
  .model-fcs .model-fc > .model-fc-v { grid-column: 1; grid-row: auto; text-align: left; }
  .model-fcs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .model-fcs:not(.model-fcs-1) > .model-fc > .model-fc-k { min-height: 2.7em; display: flex; align-items: flex-end; }
  .model-fcs-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .model-fcs-1 { grid-template-columns: minmax(0, 1fr); }
  .model-fc { padding: 12px 10px 12px 0; }
  .model-fc + .model-fc { padding-left: 10px; border-left: 1px solid var(--line); }
}

@container pane (min-width: 560px) {
  /* The hero row, the grid three across, "The scale and the tissue" full
   * width, then "What the scale is hiding" and "Where the plan lands" side by
   * side; the rest scrolls, in the dashboard's order. */
  .model-view { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 28px; }
  .model-view > * { grid-column: 1 / -1; }
  .model-view > .model-sec-hiding,
  .model-view > .model-sec-lands { grid-column: auto; order: 1; }
  .model-view:not(:has(> .model-sec-hiding)) > .model-sec-lands,
  .model-view:not(:has(> .model-sec-lands)) > .model-sec-hiding { grid-column: 1 / -1; }
  .model-view > .model-sec-energy,
  .model-view > .model-sec-deficit,
  .model-view > .model-sec-fatlean,
  .model-view > .model-sec-keep,
  .model-view > .model-sec-wave,
  .model-view > .model-sec-says { order: 2; }
  .model-view > .model-sec-lands .model-fcs { grid-template-columns: minmax(0, 1fr); }
  .model-view > .model-sec-lands .model-fc { padding: 10px 0; }
  .model-view > .model-sec-lands .model-fc + .model-fc { padding-left: 0; border-left: 0; }
  .model-view > .model-sec-lands .model-fc > .model-fc-k { min-height: 0; }
  .model-view > .model-sec-lands .model-fcs .model-fc { grid-template-columns: minmax(0, 1fr) auto; }
  .model-view > .model-sec-lands .model-fcs .model-fc > .model-fc-v { grid-column: 2; grid-row: 1 / span 2; text-align: right; }

  /* The hero as one row: the figure, its sentence, the provenance badge. */
  .model-hero { grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 18px; }
  .model-hero-top { display: contents; }
  .model-hero-main { grid-column: 1; grid-row: 1; }
  .model-hero-sub { grid-column: 2; grid-row: 1; max-width: 26em; }
  .model-hero-top .prov,
  .model-hero-top .tag { grid-column: 3; grid-row: 1; margin-top: 0; }

  .model-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .model-kpi:nth-child(2n) { padding-left: 0; border-left: 0; }
  .model-kpi:not(:nth-child(3n + 1)) { padding-left: 12px; border-left: 1px solid var(--line); }
  .model-kpi.is-lone-2 { grid-column: auto; }
  .model-kpi.is-lone-3 { grid-column: 1 / -1; }
  .model-kpi.is-pair-3 { grid-column: span 2; }

  .model-says { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; }

  /* The process view: the strip on the left, the callout and the small
   * multiples stacked on the right (§7.2 "Wide"). */
  .model-energy-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 13.5rem); column-gap: 20px; }
  .model-energy-aside .model-minis { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Me › Lab › Energy balance: what the model is missing ----
 * The server's own sentences, kept whole (they name the key to add), set as
 * one quiet tile between the strip and the rows rather than a run of bullets
 * on the ground (the A pass). */
.model-energy .model-degr {
  padding: var(--s-4);
  border-radius: var(--r-tile);
  background: var(--surface);
  box-shadow: var(--lift);
}
.model-energy .model-degr .sec-title { font: var(--t-row); font-weight: 600; }
.model-energy .model-degr .model-list { color: var(--ink-2); gap: 6px; }

/* The gaps past the first two, behind one row that says how many: a
 * tertiary row like a chart's table (base.css .chart-table), a full tap
 * target with a chevron that turns as it opens. */
.model-energy .model-degr .sec-meta { white-space: nowrap; }
.model-degr-more > summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--tap);
  margin-bottom: -8px;
  cursor: pointer;
  font: 500 var(--t-sub-size)/1.2 var(--font);
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}
.model-degr-more > summary::-webkit-details-marker { display: none; }
.model-degr-more-chev { display: inline-flex; margin-left: auto; color: var(--ink-3); transition: transform .2s var(--ease); }
.model-degr-more-chev svg { width: 18px; height: 18px; }
.model-degr-more[open] > summary .model-degr-more-chev { transform: rotate(90deg); }
.model-degr-more[open] > summary { margin-bottom: 4px; }
.model-degr-more:focus-within > summary:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 6px; }

/* A process view with nothing for the aside (no callout, too few prints for
 * the small multiples): the strip takes the whole pane rather than stopping
 * short of an empty column. */
.model-energy-aside:empty { display: none; }
@container pane (min-width: 560px) {
  .model-energy-grid:not(:has(> .model-energy-aside > *)) { grid-template-columns: minmax(0, 1fr); }
}

/* An odd panel out on the phone's two columns spans both, so the grid never
 * ends on an empty cell. */
.model-minis > .model-mini:last-child:nth-child(odd) { grid-column: 1 / -1; }
@container pane (min-width: 560px) {
  .model-energy-aside .model-minis > .model-mini:last-child:nth-child(odd) { grid-column: auto; }
}

