/* fitcoach — a training log, not a dashboard.
   Two ideas carry the design:
   1. The readiness band tints the page. A green day and a red day look
      different from the doorway, before you read a word. Discipline colours
      stay independent so swim/run/lift never blur into the band.
   2. Every number is set in mono. Paces, splits and scores are the vernacular
      of a training log; prose is not. */
:root{
  color-scheme: light;
  --surface-0:#f5f4f1; --surface-1:#fcfcfb; --surface-2:#efeeea;
  --border:#dcdad4; --border-strong:#c3c1b8;
  --text-primary:#0b0b0b; --text-secondary:#52514e; --text-muted:#7a7873;
  --series-1:#2a78d6; --series-2:#eb6834; --series-3:#1baf7a;
  --good:#008300; --warn:#eda100; --crit:#e34948;
  --grid:#e6e4df; --accent-soft:#eaf2fd;
  --accent:var(--series-1);      /* interactive chrome: one colour, always */
  --band:var(--series-1);        /* the day's readiness: the verdict only */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: ui-sans-serif, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
@media (prefers-color-scheme: dark){
  :root:where(:not([data-theme="light"])){
    color-scheme: dark;
    --surface-0:#131312; --surface-1:#1a1a19; --surface-2:#242422;
    --border:#35352f; --border-strong:#4a4a43;
    --text-primary:#fff; --text-secondary:#c3c2b7; --text-muted:#93918a;
    --series-1:#3987e5; --series-2:#d95926; --series-3:#199e70;
    --good:#4faf4f; --warn:#c98500; --crit:#e66767;
    --grid:#2e2e2a; --accent-soft:#16233a;
  }
}
:root[data-theme="dark"]{
  color-scheme: dark;
  --surface-0:#131312; --surface-1:#1a1a19; --surface-2:#242422;
  --border:#35352f; --border-strong:#4a4a43;
  --text-primary:#fff; --text-secondary:#c3c2b7; --text-muted:#93918a;
  --series-1:#3987e5; --series-2:#d95926; --series-3:#199e70;
  --good:#4faf4f; --warn:#c98500; --crit:#e66767;
  --grid:#2e2e2a; --accent-soft:#16233a;
}
/* The band colours the score and its chip, and nothing else. Tinting every
   button and link with it made an amber day look like a warning about the
   interface rather than a fact about recovery — and amber on white is the worst
   of the four for contrast. Buttons stay one colour so they always read as
   buttons. */
body[data-band="green"] { --band:var(--good) }
body[data-band="amber"] { --band:#b07600 }     /* darkened: amber fails on light */
body[data-band="yellow"]{ --band:var(--series-2) }
body[data-band="red"]   { --band:var(--crit) }

*{box-sizing:border-box}
body{margin:0;background:var(--surface-0);color:var(--text-primary);
  font:16px/1.55 var(--sans);-webkit-font-smoothing:antialiased}
.wrap{max-width:1040px;margin:0 auto;padding:16px 16px 120px}
@media(min-width:720px){ .wrap{padding:22px 22px 70px} }
a{color:var(--accent)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
@media (prefers-reduced-motion: reduce){ *{transition:none!important;animation:none!important} }

/* --- navigation. Thumb-reachable bar on a phone, inline row on a desktop. --- */
nav{display:flex;gap:2px;align-items:stretch;
  position:fixed;left:0;right:0;bottom:0;z-index:20;
  background:var(--surface-1);border-top:1px solid var(--border);
  /* the home indicator lives in the bottom inset, and a tab sitting in it is a
     tab you fight the system gesture to press. 10px more keeps them apart. */
  padding:4px 4px calc(10px + env(safe-area-inset-bottom))}
nav .brand,nav .race,nav .sp{display:none}
nav a{flex:1;display:flex;align-items:center;justify-content:center;
  min-height:46px;padding:6px 2px;border-radius:9px;text-decoration:none;
  color:var(--text-secondary);font:600 11px/1.2 var(--mono);letter-spacing:.04em;
  text-transform:uppercase}
nav a.on{color:var(--accent);background:var(--accent-soft)}
@media(min-width:720px){
  nav{position:static;flex-wrap:wrap;gap:6px;margin-bottom:24px;padding:0 0 14px;
    border-top:none;border-bottom:1px solid var(--border);background:none}
  nav .brand{display:inline;font:650 17px/1 var(--sans);letter-spacing:-.02em;
    margin-right:14px;color:var(--text-primary)}
  nav .race{display:inline;font:12px/1 var(--mono);color:var(--text-muted)}
  nav .sp{display:block;flex:1}
  nav a{flex:0 0 auto;padding:6px 11px;font-size:11px}
  nav a:hover{background:var(--surface-2);color:var(--text-primary)}
}

/* --- type --- */
h1{font-size:26px;margin:0 0 2px;letter-spacing:-.03em;line-height:1.15}
h2{font:600 11px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-muted);margin:32px 0 10px;
  padding-bottom:7px;border-bottom:1px solid var(--border)}
h3{font-size:16px;margin:0 0 5px;letter-spacing:-.01em}
p.note,.note{color:var(--text-secondary);font-size:14px;max-width:74ch}
.eyebrow{font:600 11px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-muted)}
.card{background:var(--surface-1);border:1px solid var(--border);border-radius:12px;padding:16px}

/* --- the hero: today's decision, with the score attached to it --- */
.verdict{border:1px solid var(--border);border-radius:14px;background:var(--surface-1);
  overflow:hidden;margin-top:14px}
.verdict .head{display:flex;align-items:center;gap:14px;padding:14px 16px;
  border-bottom:1px solid var(--border);
  background:color-mix(in srgb,var(--band) 7%,var(--surface-1))}
.verdict .score{font:700 34px/1 var(--mono);letter-spacing:-.04em;color:var(--band);
  font-variant-numeric:tabular-nums}
.verdict .band{font:650 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--band);display:block;margin-top:5px}
.verdict .headmeta{font:12px/1.5 var(--mono);color:var(--text-secondary)}
.verdict .body{padding:6px 16px 16px}

/* sessions */
.sess{border-left:3px solid var(--d,var(--accent));padding:13px 0 13px 14px;
  border-bottom:1px solid var(--border)}
.sess:last-of-type{border-bottom:none}
.sess.d-swim{--d:var(--series-1)} .sess.d-run{--d:var(--series-3)}
.sess.d-lift{--d:var(--series-2)} .sess.d-rest{--d:var(--border-strong)}
.sess .top{display:flex;justify-content:space-between;gap:12px;align-items:baseline}
.sess .mins{font:600 13px/1 var(--mono);color:var(--text-muted);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.sess .disc{font:600 10px/1 var(--mono);letter-spacing:.11em;text-transform:uppercase;
  color:var(--d,var(--accent));display:block;margin-bottom:5px}
.sess .det{font-size:14px;color:var(--text-secondary);margin-top:6px}
.sess .nt{font-size:13px;color:var(--text-muted);margin-top:7px;font-style:italic}

/* --- actions. Big targets: this is used at 6am with cold hands. --- */
.acts{display:flex;flex-wrap:wrap;gap:8px;padding:14px 16px;
  border-top:1px solid var(--border);background:var(--surface-2)}
.acts form{margin:0;display:flex;gap:6px;align-items:center}
.btn{background:var(--surface-1);border:1px solid var(--border-strong);
  color:var(--text-primary);border-radius:9px;padding:10px 14px;
  font:600 13px/1 var(--sans);cursor:pointer;text-decoration:none;
  display:inline-block;min-height:40px}
.btn:hover{border-color:var(--accent);color:var(--accent)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.primary:hover{filter:brightness(1.08);color:#fff}
.btn.quiet{border-color:var(--border);color:var(--text-secondary);font-weight:500}
select,.fld{background:var(--surface-1);border:1px solid var(--border-strong);
  color:var(--text-primary);border-radius:9px;padding:10px 8px;font:13px var(--sans);
  min-height:40px}
.fld{width:92px;font-family:var(--mono)}
.fld.wide{flex:1 1 160px;width:auto;font-family:var(--sans)}
.fld::placeholder{color:var(--text-muted)}
.applied{padding:10px 16px;font:12px/1.5 var(--mono);color:var(--band);
  background:color-mix(in srgb,var(--band) 8%,transparent);
  border-top:1px solid var(--border)}

/* --- readiness components --- */
.comp{display:grid;grid-template-columns:1fr 42px;gap:10px;align-items:start;
  padding:11px 0;border-bottom:1px solid var(--border)}
.comp:last-child{border-bottom:none}
.comp .cn{font:600 13px/1.2 var(--sans)}
.comp .cr{font-size:13px;color:var(--text-secondary);margin-top:3px}
.comp .cv{text-align:right;font:650 15px/1 var(--mono);font-variant-numeric:tabular-nums}
.bar{height:4px;border-radius:2px;background:var(--surface-2);overflow:hidden;margin-top:7px}
.bar i{display:block;height:100%;border-radius:2px;background:var(--accent)}

/* --- tiles --- */
.tiles{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
@media(min-width:600px){.tiles{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}}
.tile{background:var(--surface-1);border:1px solid var(--border);border-radius:11px;padding:12px}
.tile .k{font:600 10px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-muted);margin-bottom:6px}
.tile .v{font:650 22px/1.05 var(--mono);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.tile .d{font-size:12px;color:var(--text-secondary);margin-top:4px;font-family:var(--mono)}

.flags{display:grid;gap:7px}
.flag{background:var(--surface-1);border:1px solid var(--border);
  border-left:3px solid var(--warn);border-radius:9px;padding:11px 13px;
  font-size:14px;color:var(--text-secondary)}

/* --- tables --- */
.tblwrap{overflow-x:auto;border:1px solid var(--border);border-radius:11px;background:var(--surface-1)}
table{border-collapse:collapse;width:100%;font-size:13.5px;min-width:560px}
th,td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--border)}
thead th{font:600 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-muted);background:var(--surface-2);white-space:nowrap}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover{background:var(--surface-2)}
td.m{font-weight:560} td.t{font-weight:620;color:var(--accent);font-family:var(--mono)}

/* --- week grid --- */
.week-grid{display:grid;grid-template-columns:1fr;gap:7px}
@media(min-width:560px){.week-grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:900px){.week-grid{grid-template-columns:repeat(7,1fr)}}
.day{background:var(--surface-1);border:1px solid var(--border);border-radius:10px;padding:11px}
.day .dn{font:600 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-muted);margin-bottom:8px}
.slot{font-size:13px;padding:7px 9px;border-radius:7px;margin-bottom:5px;line-height:1.35}
.slot .st{font:620 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  display:block;margin-bottom:3px}
.s-lift{background:color-mix(in srgb,var(--series-2) 14%,transparent)}
.s-lift .st{color:var(--series-2)}
.s-swim{background:color-mix(in srgb,var(--series-1) 14%,transparent)}
.s-swim .st{color:var(--series-1)}
.s-run{background:color-mix(in srgb,var(--series-3) 16%,transparent)}
.s-run .st{color:var(--series-3)}
.s-rest{background:var(--surface-2);color:var(--text-secondary)}
.s-rest .st{color:var(--text-muted)}

pre.md{white-space:pre-wrap;font:14px/1.65 var(--sans);color:var(--text-secondary);margin:0}
pre.mono{white-space:pre-wrap;font:12px/1.6 var(--mono);color:var(--text-secondary);margin:0;
  overflow-x:auto}
.chart{background:var(--surface-1);border:1px solid var(--border);border-radius:12px;
  padding:16px 16px 10px;margin-bottom:12px}
.legend{display:flex;flex-wrap:wrap;gap:14px;margin:8px 0 4px;
  font:12px var(--mono);color:var(--text-secondary)}
.legend span{display:inline-flex;align-items:center;gap:6px}
.swatch{width:11px;height:11px;border-radius:3px}
svg{display:block;width:100%;height:auto;overflow:visible}
.gridline{stroke:var(--grid);stroke-width:1}
.axis{fill:var(--text-muted);font-size:10.5px;font-family:var(--mono)}
.foot{margin-top:36px;padding-top:16px;border-top:1px solid var(--border);
  color:var(--text-muted);font:12px/1.6 var(--mono)}
.sync-ok{color:var(--good)} .sync-bad{color:var(--crit)}

/* legacy hooks kept so the other pages keep rendering */
.hero{display:grid;gap:14px}
.gauge{display:none}

/* --- chat --- */
.chat{display:flex;flex-direction:column;gap:10px;margin:16px 0}
.msg{max-width:88%;border:1px solid var(--border);border-radius:12px;padding:11px 13px;
  background:var(--surface-1)}
.msg.me{align-self:flex-end;background:color-mix(in srgb,var(--accent) 10%,var(--surface-1));
  border-color:color-mix(in srgb,var(--accent) 35%,var(--border))}
.msg .who{font:600 10px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-muted);margin-bottom:6px;display:flex;gap:8px}
.msg .when{color:var(--text-muted);font-weight:400;letter-spacing:.04em}
.msg .body{font-size:14.5px;white-space:pre-wrap}
.composer{display:flex;gap:8px;position:sticky;bottom:64px;
  background:var(--surface-0);padding:8px 0}
@media(min-width:720px){ .composer{bottom:0} }

/* --- installed to the home screen: no Safari chrome, so the page owns the
   safe areas itself. Without this the header sits under the clock and the
   bottom bar under the home indicator. --- */
.wrap{padding-top:calc(16px + env(safe-area-inset-top))}
nav{padding-bottom:calc(8px + env(safe-area-inset-bottom))}
@media(min-width:720px){
  .wrap{padding-top:22px}
  nav{padding-bottom:14px}
}

/* A header on every page, pinned on a phone so you always know where you are.
   Fixed only on mobile: on a wide screen the nav lives at the top, and a fixed
   bar there covers the links — which made the desktop site impossible to
   navigate. */
.pagehead{position:fixed;top:0;left:0;right:0;z-index:10;
  background:var(--surface-0);border-bottom:1px solid var(--border);
  padding:calc(env(safe-area-inset-top) + 11px) 16px 10px;
  display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.ph-title{font:650 15px/1 var(--sans);letter-spacing:-.01em}
.ph-sub{font:11px/1 var(--mono);color:var(--text-muted)}
.pagehead-space{height:calc(env(safe-area-inset-top) + 44px)}
@media(min-width:720px){
  .pagehead{position:static;padding:0 0 14px;border-bottom:none}
  .ph-title{display:none}          /* the nav already says which page this is */
  .pagehead-space{display:none}
}

/* --- folds -----------------------------------------------------------------
   Everything below today's decision starts closed. The page had eleven sections
   competing with the one thing it exists to say; now the rest is one tap away
   and the summary line carries enough to decide whether to open it. <details>
   because it needs no JavaScript and keeps working offline. */
.fold{border-bottom:1px solid var(--border);margin:0}
.fold > summary{list-style:none;cursor:pointer;padding:16px 2px;
  display:flex;align-items:baseline;gap:10px;min-height:44px}
.fold > summary::-webkit-details-marker{display:none}
.fold > summary > span:first-child{font:600 11px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-primary);white-space:nowrap}
.fold > summary .sub{font:12px/1.3 var(--mono);color:var(--text-muted);
  margin-left:auto;text-align:right;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;min-width:0}
.fold > summary::after{content:"+";font:400 18px/1 var(--mono);
  color:var(--text-muted);margin-left:8px}
.fold[open] > summary::after{content:"–"}
.fold > *:not(summary){margin-bottom:16px}

/* the coach is thinking — a model reply takes 30-60 s on this Pi, and silence
   for a minute reads as a hang */
.msg.typing .body{display:flex;gap:5px;align-items:center;min-height:20px}
.msg.typing i{width:7px;height:7px;border-radius:50%;background:var(--text-muted);
  display:block;animation:blink 1.2s infinite ease-in-out}
.msg.typing i:nth-child(2){animation-delay:.2s}
.msg.typing i:nth-child(3){animation-delay:.4s}
@keyframes blink{0%,80%,100%{opacity:.25} 40%{opacity:1}}
@media (prefers-reduced-motion: reduce){
  .msg.typing i{animation:none;opacity:.5}
}

/* Pull to refresh. The strip lives above the page and grows out of the top
   edge as you drag, so the affordance is the movement itself — no spinner
   sitting there permanently, nothing to see when you are not pulling. */
#ptr{height:0;overflow:hidden;display:flex;align-items:flex-end;
     justify-content:center;transition:height .18s ease}
#ptr span{display:block;width:26px;height:3px;border-radius:2px;
          margin-bottom:10px;background:var(--border-strong);
          transition:background .15s ease,width .15s ease}
#ptr.ready span{background:var(--accent);width:40px}
#ptr.go span{background:var(--accent);width:40px;animation:ptr-go .7s linear infinite}
@keyframes ptr-go{0%{opacity:.35}50%{opacity:1}100%{opacity:.35}}
@media (prefers-reduced-motion:reduce){
  #ptr{transition:none}
  #ptr.go span{animation:none}
}

/* The week has to agree with Today, so the day you are standing in is marked
   and anything that bent it says why. A plan that quietly differs from the one
   on the front page is worse than no week view at all. */
.day.is-today{border-color:var(--accent)}
.dn-now{color:var(--accent);letter-spacing:.06em}
.day-adj{margin:7px 0 0;font-size:12px;line-height:1.45;color:var(--text-secondary)}
.day-adj::before{content:"→ ";color:var(--accent)}

/* A finished session. The plan is what you were asked to do; this is the part
   that already happened, so it recedes rather than shouts — the eye should go
   to what is still ahead. */
.sess.is-done,.slot.is-done{opacity:.72}
.slot.is-unplanned{border-style:dashed}
.sess.is-done .det,.slot.is-done{text-decoration:none}
.donetag{font:600 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
         color:var(--ok,var(--series-3));border:1px solid currentColor;
         border-radius:99px;padding:4px 8px;white-space:nowrap}
.did{display:block;margin-top:6px;font:600 10px/1.4 var(--mono);
     letter-spacing:.06em;text-transform:uppercase;color:var(--ok,var(--series-3))}

/* How good the prescribed loads turned out. Three verdicts, three colours, and
   the direction of a miss is the useful part. */
.scorecard{margin-top:12px}
table.mini{width:100%;border-collapse:collapse;margin-top:10px;font-size:13px}
table.mini td{padding:7px 8px;border-top:1px solid var(--border);
              vertical-align:top}
table.mini td:first-child{font-weight:600}
table.mini td:last-child{text-align:right;font:600 11px/1 var(--mono);
                         text-transform:uppercase;letter-spacing:.05em}
tr.v-right   td:last-child{color:var(--ok,var(--series-3))}
tr.v-light   td:last-child{color:var(--series-1)}
tr.v-heavy   td:last-child{color:var(--crit)}

/* Planned against done. Adherence is the number that decides a year of
   training, so it gets a colour — but only at the ends, because a middling
   week is just a week. */
.tile .s{font-size:11px;line-height:1.4;color:var(--text-secondary);margin-top:5px;
         font-family:var(--mono)}
.tile .of{font-size:14px;color:var(--text-secondary)}
.tile.t-good{border-color:var(--ok,var(--series-3))}
.tile.t-good .v{color:var(--ok,var(--series-3))}
.tile.t-bad{border-color:var(--crit)}
.tile.t-bad .v{color:var(--crit)}

/* The draggable week. Lanes are the openings in a day — a session lives in one
   of them, and where it lives is the thing being edited. */
.day.is-free{background:var(--surface-2,var(--surface-1))}
.dn-hol{color:var(--accent);letter-spacing:.04em;text-transform:none}
.dn-free{color:var(--text-secondary)}
.lane{border-top:1px dashed var(--border);margin-top:8px;padding-top:6px;
      min-height:34px;border-radius:6px;transition:background .12s ease}
.lane:first-of-type{border-top:0}
.lane-k{display:block;font:600 9px/1 var(--mono);letter-spacing:.09em;
        text-transform:uppercase;color:var(--text-muted,var(--text-secondary));
        margin-bottom:5px}
.lane.over{background:color-mix(in srgb,var(--accent) 14%,transparent)}
.dragweek .slot[draggable=true]{cursor:grab}
.dragweek .slot.held{outline:2px solid var(--accent);opacity:.85;cursor:grabbing}
.dragweek .slot.moving{opacity:.45}
body.placing .lane{background:color-mix(in srgb,var(--accent) 7%,transparent)}
.warn{margin:8px 0;padding:9px 12px;border-radius:9px;font-size:13px;
      line-height:1.45;border:1px solid var(--crit);
      background:color-mix(in srgb,var(--crit) 8%,transparent)}
@media (min-width:760px){.week-grid{grid-template-columns:repeat(7,1fr)}}

/* Where the card will land. A real gap that opens in the target lane, not just
   a border colour — the question a drag asks is "where does this go", and the
   answer should be the shape of the thing arriving. */
.dropghost{margin-top:6px;padding:8px 10px;border-radius:8px;
           border:1px dashed var(--accent);
           background:color-mix(in srgb,var(--accent) 10%,transparent);
           color:var(--accent);font:600 11px/1.3 var(--mono);
           letter-spacing:.04em;text-transform:uppercase;
           animation:ghost-in .14s ease-out}
@keyframes ghost-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
.lane.over{background:color-mix(in srgb,var(--accent) 14%,transparent);
           box-shadow:inset 0 0 0 1px var(--accent)}
@media (prefers-reduced-motion:reduce){.dropghost{animation:none}}

/* Take a session off the week. Quiet until the card is hovered or focused —
   a delete control that shouts is a delete control that gets pressed. */
.slot .st{display:flex;align-items:center;gap:6px;justify-content:space-between}
.drop{margin-left:auto;border:0;background:none;cursor:pointer;padding:0 2px;
      font:600 15px/1 var(--mono);color:var(--text-muted,var(--text-secondary));
      opacity:0;transition:opacity .12s ease,color .12s ease}
.slot:hover .drop,.drop:focus-visible{opacity:1}
.drop:hover{color:var(--crit)}
@media (hover:none){.drop{opacity:.55}}   /* no hover on a phone */

/* The typed answer to a calendar question. The three buttons above it cover
   the common cases; this is for the answers that name particular days. */
.calsay{display:flex;gap:8px;margin-top:10px}
.calsay .fld{flex:1;min-width:0}

/* One busy bar for the whole app, pinned above everything. A form submit over
   the tailnet takes a second or two, and without this the app looked frozen
   for all of it. */
#busy{position:fixed;top:0;left:0;right:0;height:2px;z-index:99;
      background:var(--accent);transform:scaleX(0);transform-origin:0 50%;
      opacity:0;pointer-events:none}
#busy.on{opacity:1;animation:busy-run 1.1s ease-in-out infinite}
@keyframes busy-run{
  0%{transform:scaleX(0);transform-origin:0 50%}
  50%{transform:scaleX(1);transform-origin:0 50%}
  51%{transform:scaleX(1);transform-origin:100% 50%}
  100%{transform:scaleX(0);transform-origin:100% 50%}
}
@media (prefers-reduced-motion:reduce){
  #busy.on{animation:none;transform:scaleX(1);opacity:.5}
}

/* Say something from anywhere. Sits below the page content and above the
   footer — the chat log is still its own page, this is just the mouth. */
.saybar{display:flex;gap:8px;margin:22px 0 0;align-items:center}
.saybar .fld{flex:1;min-width:0}
.saybar .btn{white-space:nowrap}
@media (max-width:520px){
  .saybar{flex-wrap:wrap}
  .saybar .fld{flex:1 1 100%}
}

/* Where he is now, against where he started. Colour only at the ends: a figure
   that has moved the right way, and one that has not. */
td.now{font-weight:600;font-variant-numeric:tabular-nums}
td.now.up{color:var(--ok,var(--series-3))}
td.now.down{color:var(--crit)}

/* What he actually lifted, when it was not what was planted. Quieter than the
   plan above it: this is a record, not an instruction. */
.didcard{margin-top:12px;border-left:3px solid var(--series-2)}
