/* ==========================================================
   THE BODY — measurements, and what was lifted.
   ==========================================================

   NOTHING ON THIS PAGE IS COLOURED BY WHETHER A NUMBER IS GOOD. There is no
   green band, no red ring, no target line — six hours of sleep is a fact,
   and an app that starts marking somebody's resting heart rate has quietly
   become a doctor. The arrow beside a number says which way it moved and
   stops there, which is the whole opinion get-body.js offers and the whole
   opinion this draws.

   The one thing here that IS coloured is the banner, and only in the state
   where something has stopped working — amber, once, at the top, because
   the alternative is a person losing a year to a shortcut that quietly
   died in March. */
.body-banner{ font-size:var(--type-body); color:var(--text-dim); padding:0 0 var(--space-3); line-height:1.55;
  max-width:var(--prose-measure); }
.body-banner.is-setup{
  border:1px solid var(--glass-border); border-radius:var(--radius-card); padding:var(--space-3) var(--space-4); margin-bottom:var(--space-4);
  background:var(--glass-bg); }
.body-banner.is-quiet{
  border:1px solid var(--amber, #C08A2E); border-radius:var(--radius-card); padding:var(--space-3) var(--space-4); margin-bottom:var(--space-4);
  background:var(--glass-bg); }
.body-banner b{ color:var(--text); font-weight:650; }
.body-banner div + div{ margin-top:var(--space-2); }
.body-banner .btn-row{ margin-bottom:0; }

.body-next{ border:1px solid var(--glass-border); border-radius:var(--radius-card); background:var(--glass-bg);
  padding:var(--space-4); max-width:var(--prose-measure); }
.body-next-when{ font-size:var(--type-lead); color:var(--text-dim); }
.body-next-when b{ color:var(--text); font-weight:650; }
.body-next-plan{ font-size:var(--type-body); color:var(--text-dim); margin-top:var(--space-1); }
.body-ex{ display:flex; align-items:baseline; gap:var(--space-3); flex-wrap:wrap; padding:var(--space-2) 0;
  border-bottom:1px solid var(--glass-border); }
.body-ex:first-of-type{ margin-top:var(--space-2); }
.body-ex-name{ font-size:var(--type-body); font-weight:600; color:var(--text); flex:1.4; min-width:120px; }
.body-ex-ss{ font-size:var(--type-label); font-weight:500; color:var(--text-faint); }
.body-ex-target{ font-size:var(--type-body); color:var(--text); flex:1; min-width:80px; }
/* THE ONE NUMBER THIS FEATURE EXISTS FOR, beside today's target rather than
   on a history screen. Never styled as a warning however long ago it was:
   coming back after three weeks is the normal path, not the error path. */
.body-ex-last{ font-size:var(--type-body); color:var(--text-dim); flex:1.6; min-width:150px; }
.body-ex-last.is-new{ color:var(--text-faint); font-style:italic; }

/* The tile grid is the house's own (see the .box-grid ladder in app.css): as many
   columns as fit at --tile-min, never wider than --tile-span. It used to be
   declared here as three, two and one columns and then overridden by that
   ladder, which is the grid that was always on screen. */
.body-metrics{ display:grid; grid-template-columns:repeat(auto-fill, minmax(min(100%, var(--tile-min)), 1fr));
  gap:var(--tile-gap); align-items:start; max-width:var(--tile-span); }
.body-metric{ border:1px solid var(--glass-border); border-radius:var(--radius-card); background:var(--glass-bg);
  padding:var(--space-3) var(--space-4); }
.body-metric-name{ font-size:var(--type-body); font-weight:600; color:var(--text-dim);
  text-transform:uppercase; letter-spacing:.04em; }
.body-metric-now{ font-size:var(--type-title); font-weight:600; color:var(--text); margin-top:var(--space-1); }
/* Grey, in both directions, on purpose. Down is not red and up is not green:
   for resting heart rate those would be exactly the wrong way round, and
   deciding which metrics want which is the doctoring this page refuses. */
.body-metric-arrow{ font-size:var(--type-lead); color:var(--text-dim); margin-left:var(--space-1); }
.body-metric-when{ font-size:var(--type-label); color:var(--text-faint); }
.body-spark{ width:100%; height:40px; display:block; margin:var(--space-2) 0 var(--space-2); color:var(--text-dim); }
.body-metric-trend{ font-size:var(--type-label); color:var(--text-dim); line-height:1.5; }

/* THREE KINDS OF NOTHING, AND THEY MUST NEVER LOOK ALIKE.
   See bodyMetricState() in rooms/body.js — the shapes are the whole point.

   A reading that DID NOT ARRIVE is amber and says so in a sentence, with the
   last value it had underneath in grey. It is the same amber the banner uses
   because it is the same fact: something stopped.

   A reading that was NEVER SENT is a dashed outline and grey. Nothing is
   wrong with it and nothing wants doing about it, so it must not borrow the
   amber — that is exactly the confusion this page is built to prevent.

   Neither of them is ever a number, a zero or a dash, and neither gets the
   line or the trend: those belong to a reading that is true. */
.body-metric.is-stale{ border-color:var(--amber, #C08A2E); }
.body-metric.is-empty{ border-style:dashed; background:transparent; }
.body-metric-said{ font-size:var(--type-body); line-height:1.5; margin-top:var(--space-1); }
/* THE SENTENCE IS --orange AND NOT --amber, and the reason is measured.
   --amber is defined nowhere in this stylesheet, so every rule reaching for
   it runs on one hardcoded fallback and is the same colour on all sixteen
   grounds — the note on .pal-foot-warn says so already. On the light ground
   that fallback measures 2.87:1 against the card behind it, under the 4.5
   floor, so the one warning on this page would be the hardest thing on it to
   read. --orange is declared once per ground: 8.45:1 on the default dark,
   4.83:1 on light. The BORDER stays on --amber because that is what the
   banner's border uses and the two are one fact — a border is not text and
   is not held to a contrast floor. */
.body-metric.is-stale .body-metric-said{ color:var(--orange); font-weight:600; }
.body-metric.is-empty .body-metric-said{ color:var(--text-dim); }
/* --text-dim rather than --text-faint: this line carries a NUMBER, and the
   note on .pal-wait measured --text-faint on glass under the 4.5 floor. It is
   still plainly quieter than the sentence above it, which is the job. */
.body-metric-was{ font-size:var(--type-label); color:var(--text-dim); margin-top:var(--space-1); }

/* What the two quiet shapes mean, under the tiles, and only when at least one
   of them is actually on the page. */
.body-states{ display:grid; gap:var(--space-2); margin-top:var(--space-3);
  max-width:var(--prose-measure); font-size:var(--type-label); color:var(--text-dim);
  line-height:1.55; }
.body-states b{ color:var(--text); font-weight:650; }
.body-states-key{ display:inline-block; width:22px; height:10px; border-radius:3px;
  vertical-align:middle; margin-right:6px; border:1px solid var(--glass-border); }
.body-states-key.is-stale{ border-color:var(--amber, #C08A2E); }
.body-states-key.is-empty{ border-style:dashed; }

.body-log{ display:flex; align-items:center; gap:var(--space-3); padding:var(--space-2) 0;
  border-bottom:1px solid var(--glass-border); flex-wrap:wrap; }
.body-log-title{ font-size:var(--type-body); color:var(--text); font-weight:600; }
.body-log-when{ font-size:var(--type-body); color:var(--text-dim); flex:1; min-width:0; }
.body-log .btn{ font-size:var(--type-body); padding:var(--space-1) var(--space-3); }

.body-sets{ display:flex; flex-direction:column; gap:var(--space-2); margin:var(--space-2) 0; }
.body-set{ display:flex; gap:var(--space-2); align-items:center; }
.body-plan{ border:1px solid var(--glass-border); border-radius:var(--radius-card); background:var(--glass-bg);
  padding:var(--space-3) var(--space-4); margin-bottom:var(--space-3); }
.body-plan-name{ font-size:var(--type-lead); font-weight:650; color:var(--text); }
.body-session{ border-top:1px solid var(--glass-border); padding:var(--space-2) 0 var(--space-hair); margin-top:var(--space-2); }
.body-session-head{ display:flex; align-items:baseline; gap:var(--space-3); }
.body-session-name{ font-size:var(--type-body); font-weight:600; color:var(--text); cursor:pointer; }
.body-session-name:hover{ text-decoration:underline; }
.body-session-n{ font-size:var(--type-body); color:var(--text-dim); }

/* THE KEY, THE ONE TIME IT IS READABLE. Only its sha256 is stored, so there
   is no request anybody can make — him included — that shows it again. It is
   large and selectable for that reason, with the seven taps that use it
   underneath rather than in a help page somewhere. */
.body-key{ border:1px solid var(--glass-border-hi); border-radius:var(--radius-card); padding:var(--space-3) var(--space-4);
  margin-bottom:var(--space-4); background:rgba(120,120,140,.08); }
.body-key-head{ font-size:var(--type-body); font-weight:650; color:var(--text); }
.body-key-value{ font-family:var(--font-mono); font-size:var(--type-body);
  color:var(--text); word-break:break-all; user-select:all; cursor:pointer;
  border:1px solid var(--glass-border); border-radius:var(--radius-card); padding:var(--space-2) var(--space-3); margin:var(--space-2) 0; }
.body-key-note{ font-size:var(--type-body); color:var(--text-dim); line-height:1.6; }
.body-steps{ font-size:var(--type-body); color:var(--text-dim); line-height:1.65;
  padding-left:var(--space-5); margin:0; }
.body-steps li{ margin-bottom:var(--space-2); }
/* ITEM 155 — the setup steps, always available and folded shut.
   Folded, because somebody arriving at this panel to unpair a phone should
   not have to scroll past nine numbered paragraphs to reach the button; and
   <details> because it needs no state on the JavaScript side and remembers
   nothing between visits, which is right for a thing read once a year. */
.body-howto{ margin-top:var(--space-4); border-top:1px solid var(--glass-border); padding-top:var(--space-3); }
.body-howto > summary{ cursor:pointer; font-size:var(--type-body); font-weight:600; color:var(--text-dim);
  list-style:none; display:flex; align-items:center; gap:var(--space-2); }
.body-howto > summary::-webkit-details-marker{ display:none; }
/* The triangle is drawn rather than inherited, because Safari's default
   marker sits on a different baseline from Chrome's and this row has one
   line of text in it. */
.body-howto > summary::before{ content:'▸'; font-size:var(--type-label); color:var(--text-faint);
  transition:transform var(--dur-fast) var(--ease-out); display:inline-block; }
.body-howto[open] > summary::before{ transform:rotate(90deg); }
.body-howto > summary:hover{ color:var(--text); }
.body-howto .body-steps{ margin-top:var(--space-3); }

/* =========================================================================
   BODY A — "why the week was hard" — and BODY B — "what today has room for".
   -------------------------------------------------------------------------
   Two rules carried over from the amber sentence on this same page, and both
   were learned the expensive way:

   · EVERY COLOUR HERE IS A DECLARED ONE. --violet, --green, --blue and
     --orange are declared once per background, so the pips and the warning
     ink follow the theme instead of being one fixed value on all sixteen.
     The gold the banner's border uses is declared nowhere, which is why the
     stale SENTENCE was moved off it and only the border kept it.

   · THE PIP IS DECORATION AND THE WORDS ARE NOT. Nothing on either card
     depends on telling the pips apart — each bullet already names its own
     source in words underneath it, so the card reads identically to somebody
     who cannot see the four colours at all.
   ========================================================================= */
.bw-card{ border:1px solid var(--glass-border); border-radius:var(--radius-card);
  background:var(--glass-bg); padding:var(--space-4) var(--space-5); margin:0 0 var(--space-4); }
.bw-lede{ font-family:var(--font-display); font-size:clamp(20px, 2.4vw, 28px);
  line-height:1.18; color:var(--text); margin:0 0 var(--space-4); }
.bw-facts{ list-style:none; margin:0 0 var(--space-4); padding:0; }
.bw-facts li{ display:flex; gap:var(--space-3); align-items:flex-start;
  padding:var(--space-2) 0; border-top:1px solid var(--glass-border); }
.bw-facts li:first-child{ border-top:0; padding-top:0; }
.bw-pip{ width:9px; height:9px; border-radius:50%; flex:none; margin-top:7px; }
.bw-g{ flex:1; min-width:0; }
.bw-t{ font-size:var(--type-body); color:var(--text); line-height:1.5; }
.bw-t b{ font-weight:700; }
.bw-from{ display:block; font-family:var(--mono, ui-monospace, monospace); font-size:10px; letter-spacing:.06em;
  color:var(--text-faint); margin-top:3px; }   /* NO text-transform. It lowercased United into united in the trip line — the source is written in the case it should be read in. Found in a picture; no number on this page could see it. */
.bw-tail{ font-family:var(--font-display); font-style:normal; font-weight:500;
  font-size:var(--type-lead); color:var(--text); margin:0 0 var(--space-3);
  padding-top:var(--space-3); border-top:1px solid var(--glass-border); }
/* The line that says which sources answered. --text-dim, not --text-faint:
   it is the sentence that tells a missing bullet from a clear day, and the
   faint ink on this page is for units under a number. */
.bw-src{ font-size:var(--type-label); color:var(--text-dim); margin:0; line-height:1.5; }

.br-card{ border:1px solid var(--glass-border); border-radius:var(--radius-card);
  background:var(--glass-bg); padding:var(--space-4) var(--space-5); margin:0 0 var(--space-3); }
.br-gap{ font-family:var(--font-display); font-size:clamp(20px, 2.6vw, 30px);
  line-height:1.12; color:var(--text); margin:0 0 var(--space-3); }
.br-say{ font-size:var(--type-body); color:var(--text-dim); margin:0 0 var(--space-2); line-height:1.55; }
.br-say b{ color:var(--text); font-weight:700; }
.br-acts{ display:flex; gap:var(--space-2); flex-wrap:wrap; margin:var(--space-4) 0 var(--space-3); }
.br-back{ font-size:var(--type-label); color:var(--text-dim); margin:0 0 var(--space-3); }

.br-panel{ border:1px solid var(--glass-border); border-radius:var(--radius-card);
  background:var(--glass-bg); padding:var(--space-4) var(--space-5); margin:0 0 var(--space-3); }
.br-panel h4{ font-family:var(--mono, ui-monospace, monospace); font-size:10px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--text-faint); margin:0 0 10px; font-weight:600; }
.br-refuse{ margin:0; color:var(--text-dim); font-size:var(--type-body); line-height:1.55; }
.br-week{ display:flex; gap:var(--space-2); flex-wrap:wrap; }
.br-wd{ flex:1 1 92px; border:1px solid var(--glass-border); border-radius:var(--radius-control);
  padding:var(--space-2) var(--space-3); min-width:0; }
.br-wd.is-now{ border-color:color-mix(in srgb, var(--accent, #C08A2E) 50%, transparent); }
.br-d{ font-family:var(--mono, ui-monospace, monospace); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--text-faint); margin-bottom:3px; }
.br-gp{ font-family:var(--font-display); font-size:var(--type-lead); font-weight:600;
  color:var(--text); }
.br-mt{ font-size:var(--type-label); color:var(--text-faint); display:block; margin-top:2px; }

/* At phone width the week strip stops being six columns and becomes six
   rows. Six 92px cells inside a 430px screen is what "nothing spills off the
   side" fails on, and it fails by four pixels rather than by forty, which is
   the kind that only a picture finds. */
@media(max-width:560px){
  .bw-card, .br-card, .br-panel{ padding:var(--space-3) var(--space-4); }
  .br-wd{ flex:1 1 100%; display:flex; align-items:baseline; gap:var(--space-2); }
  .br-d{ margin-bottom:0; flex:1 1 auto; }
  .br-mt{ display:inline; margin-top:0; }
}
