/* =========================================================================
   LockedIN
   World: wall planner x training ledger. Brass on club-room navy.
   Structure is built from hairlines, never from cards.

   Three colours, three jobs, no overlap:
     gold    interface state - current, done, primary action
     purple  content - this day held weight training
     wine    content - this day held cardio
   A fourth meaning for any of them takes the force out of the first three.

   Nothing in this file measures elapsed time.
   ========================================================================= */

:root {
  /* ---- Ground: club-room navy ------------------------------------------ */
  --navy-1000: #040b16;
  --navy-950:  #071224;   /* page ground */
  --navy-900:  #0b1a30;   /* bars, sheets */
  --navy-850:  #0e2039;
  --navy-800:  #12273f;   /* row hover */
  --navy-700:  #1a3555;

  /* ---- Brass ----------------------------------------------------------- */
  --gold-200: #f0dcaa;
  --gold-300: #e6cc90;
  --gold-400: #d4ac63;    /* the accent */
  --gold-500: #bd9245;
  --gold-600: #96702f;

  /* ---- Royal purple: weight training ----------------------------------- */
  --purple:      #7c4dda;
  --purple-lift: #9a74e6;
  --purple-deep: #4b2a93;
  --purple-soft: rgba(124, 77, 218, .17);

  /* ---- Wine red: cardio ------------------------------------------------ */
  --wine:      #c0485c;
  --wine-lift: #d4697b;
  --wine-deep: #6e2231;
  --wine-soft: rgba(192, 72, 92, .15);

  /* ---- Paper ----------------------------------------------------------- */
  --ink-1: #f2efe7;
  --ink-2: #9fb0c8;
  --ink-3: #6f8199;
  --ink-4: #3f5271;       /* decoration and disabled only, never body text */

  /* ---- Rules ----------------------------------------------------------- */
  --rule:      #172b46;
  --rule-soft: #0f2136;
  --rule-gold: rgba(212, 172, 99, .32);

  /* ---- States ---------------------------------------------------------- */
  --danger:     #e2796a;
  --danger-dim: rgba(226, 121, 106, .16);
  --focus:      var(--gold-400);

  /* ---- Curves ---------------------------------------------------------- */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);

  /* ---- Type ------------------------------------------------------------ */
  /* One family, two voices. Archivo is variable on width as well as weight,
     so the display voice is the same face run wide and tracked tight - which
     is how sports and Swiss typography has always shouted. A product people
     open every day does not need a second family to carry its headings. */
  --f-ui: "Archivo", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --f-display: var(--f-ui);
  --display-wide: 118%;

  --t-xs:   0.6875rem;
  --t-sm:   0.8125rem;
  --t-base: 0.9375rem;
  --t-md:   1.0625rem;
  --t-lg:   1.375rem;
  --t-xl:   1.75rem;
  --t-2xl:  2.375rem;

  /* ---- Measure --------------------------------------------------------- */
  --r-1: 2px;
  --r-2: 4px;
  --r-3: 8px;
  --r-sheet: 16px;

  --view-pad: 1.15rem;
  --column: 44rem;
  --rail-w: 15rem;
  --topbar-h: 3.25rem;
  --tabbar-h: calc(3.5rem + env(safe-area-inset-bottom, 0px));

  --shadow-leaf: 0 18px 44px -18px rgba(2, 6, 14, .85), 0 2px 8px -4px rgba(2, 6, 14, .6);
  --shadow-board: 0 -22px 56px -20px rgba(2, 6, 14, .9);
}

/* =========================================================================
   Foundations
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

/* Without this, [hidden] loses to any display from a class rule - the reason
   hidden panels stay visible. */
[hidden] { display: none !important; }

html {
  background: var(--navy-950);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;
  background:
    radial-gradient(120% 70% at 50% -10%, #0d1e36 0%, rgba(13, 30, 54, 0) 62%),
    var(--navy-950);
  color: var(--ink-1);
  font-family: var(--f-ui);
  font-size: var(--t-base);
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, p, figure, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; padding: 0; }

svg.ico { width: 1.25rem; height: 1.25rem; flex: none; display: block; }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-1); }
::selection { background: var(--gold-600); color: var(--navy-1000); }
::placeholder { color: var(--ink-3); opacity: 1; }

.sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.noscript {
  max-width: 32rem;
  margin: 4rem auto;
  padding: 1.25rem 1.5rem;
  border-top: 1px solid var(--gold-400);
  background: var(--navy-900);
  color: var(--ink-2);
}
.noscript b { display: block; color: var(--ink-1); margin-bottom: .35rem; }

/* =========================================================================
   Type roles
   ========================================================================= */

.figure {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: -0.01em;
}

.label {
  font-size: var(--t-xs);
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}

.prose { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.65; white-space: pre-wrap; }

/* =========================================================================
   Boot
   ========================================================================= */

.boot {
  position: fixed; inset: 0;
  display: grid; place-content: center; justify-items: center;
  gap: 1.1rem;
  background: var(--navy-950);
  z-index: 90;
  transition: opacity 260ms var(--ease-out);
}
.boot.is-gone { opacity: 0; pointer-events: none; }

.boot-mark {
  color: var(--gold-400);
  border: 1px solid var(--rule-gold);
  width: 4.25rem; height: 4.25rem;
  display: grid; place-content: center;
}
.boot-mark svg { width: 2rem; height: 2rem; }
.boot-text { color: var(--ink-3); font-size: var(--t-sm); }

/* =========================================================================
   Sign in
   ========================================================================= */

.auth {
  min-height: 100dvh;
  display: grid;
  align-content: center;
  gap: 2.25rem;
  padding: 3rem 1.5rem calc(3rem + env(safe-area-inset-bottom, 0px));
  max-width: 25rem;
  margin-inline: auto;
}

.auth-plate { text-align: center; }

.plate-mark {
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: clamp(2.4rem, 10.5vw, 3.1rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--ink-1);
}
.plate-in { color: var(--gold-400); }

.plate-sub {
  margin-top: .9rem;
  color: var(--ink-3);
  font-size: var(--t-sm);
}

.demo-flag {
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--ink-2);
  border-top: 1px solid var(--gold-500);
  background: rgba(212, 172, 99, .07);
  padding: .8rem .9rem;
  border-radius: 0 0 var(--r-2) var(--r-2);
}
.demo-flag b { color: var(--gold-300); }

/* Louder than the demo notice on purpose. This one means something is wrong
   that the person running the site has to go and fix. */
.config-alarm {
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--danger);
  border-top: 2px solid var(--danger);
  background: var(--danger-dim);
  padding: .9rem 1rem;
  border-radius: 0 0 var(--r-2) var(--r-2);
}

.auth-panel { display: grid; gap: 1rem; }

.auth-lead {
  font-size: var(--t-xs);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--gold-500);
  font-weight: 600;
  text-align: center;
}

.auth-hint {
  font-size: var(--t-sm);
  color: var(--ink-3);
  line-height: 1.6;
  text-align: center;
}

/* ---- The four digit code --------------------------------------------- */

.code-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .6rem;
  max-width: 17rem;
  margin-inline: auto;
  width: 100%;
}

.code-box {
  aspect-ratio: 1 / 1.15;
  width: 100%;
  text-align: center;
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: 1.9rem;
  font-weight: 600;
  color: var(--gold-200);
  background: var(--navy-900);
  border: 1px solid var(--rule);
  border-radius: var(--r-2);
  padding: 0;
  transition: border-color 140ms ease, background-color 140ms ease, transform 140ms var(--ease-out);
  caret-color: var(--gold-400);
}
.code-box:hover { border-color: var(--navy-700); }
.code-box:focus {
  outline: none;
  border-color: var(--gold-400);
  background: var(--navy-850);
}
.code-box:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.code-box.is-filled { border-color: var(--rule-gold); }

.code-row.is-wrong .code-box {
  border-color: var(--danger);
  animation: shake 260ms var(--ease-out);
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-4px); }
  75%      { transform: translateX(4px); }
}

.field-label {
  font-size: var(--t-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  text-align: center;
}

/* ---- The recovery key ------------------------------------------------- */

/* Something to be copied off a screen onto paper: wide tracking, a size that
   survives a phone photo, and the alphabet already excludes I, L, O, 0 and 1. */
.recovery-key {
  font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: clamp(1.05rem, 5.2vw, 1.4rem);
  font-weight: 600;
  letter-spacing: .1em;
  color: var(--gold-200);
  text-align: center;
  padding: 1.05rem .5rem;
  border-top: 1px solid var(--gold-500);
  border-bottom: 1px solid var(--rule-gold);
  background: rgba(212, 172, 99, .06);
  overflow-wrap: anywhere;
  user-select: all;
}

.key-input {
  font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.link-quiet {
  display: block;
  margin-inline: auto;
  font-size: var(--t-sm);
  color: var(--ink-3);
  padding: .5rem .25rem;
  transition: color 140ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .link-quiet:hover { color: var(--gold-300); }
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: var(--t-sm);
  color: var(--ink-3);
  justify-self: start;
  transition: color 140ms ease;
}
.back-link .ico { width: 1rem; height: 1rem; }
@media (hover: hover) and (pointer: fine) {
  .back-link:hover { color: var(--gold-300); }
}

.hr-label {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: .9rem;
  margin: .6rem 0 .2rem;
}
.hr-label::before, .hr-label::after { content: ""; height: 1px; background: var(--rule); }
.hr-label span {
  font-size: var(--t-xs);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* =========================================================================
   Fields
   ========================================================================= */

.field { display: grid; gap: .4rem; }
.field > label {
  font-size: var(--t-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  background: var(--navy-900);
  border: 1px solid var(--rule);
  border-radius: var(--r-2);
  padding: .68rem .75rem;
  color: var(--ink-1);
  font-size: var(--t-base);
  transition: border-color 160ms ease, background-color 160ms ease;
}
.field textarea { resize: vertical; min-height: 5rem; line-height: 1.55; }
.field input:hover, .field textarea:hover { border-color: var(--navy-700); }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--gold-500);
  background: var(--navy-850);
}
.field input:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--focus); outline-offset: 1px;
}
.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: right 1rem center, right .7rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 2rem;
}

.field-hint { font-size: var(--t-xs); color: var(--ink-3); line-height: 1.55; }
.field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }

.form-error {
  font-size: var(--t-sm);
  color: var(--danger);
  background: var(--danger-dim);
  border-top: 1px solid var(--danger);
  padding: .6rem .75rem;
  border-radius: 0 0 var(--r-2) var(--r-2);
  line-height: 1.5;
}

/* =========================================================================
   Buttons
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  padding: .62rem 1.05rem;
  border-radius: var(--r-2);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: .01em;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: transform 160ms var(--ease-out),
              background-color 160ms ease,
              border-color 160ms ease,
              color 160ms ease,
              opacity 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:active { transform: scale(0.97); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .42; cursor: not-allowed; transform: none; }
.btn .ico { width: 1.05rem; height: 1.05rem; }

.btn-gold {
  background: var(--gold-400);
  color: var(--navy-1000);
  box-shadow: 0 1px 0 rgba(255, 244, 214, .35) inset;
}
.btn-ghost { border-color: var(--rule-gold); color: var(--gold-300); }
.btn-quiet { border-color: var(--rule); color: var(--ink-2); }
.btn-danger { color: var(--danger); border-color: rgba(226, 121, 106, .38); }

.btn-purple { background: var(--purple-deep); color: #fff; border-color: var(--purple); }
.btn-wine   { background: var(--wine-deep);   color: #fff; border-color: var(--wine); }

@media (hover: hover) and (pointer: fine) {
  .btn-gold:hover:not(:disabled)   { background: var(--gold-300); }
  .btn-ghost:hover:not(:disabled)  { border-color: var(--gold-500); background: rgba(212, 172, 99, .07); }
  .btn-quiet:hover:not(:disabled)  { border-color: var(--navy-700); color: var(--ink-1); background: var(--navy-900); }
  .btn-danger:hover:not(:disabled) { background: var(--danger-dim); border-color: var(--danger); }
  .btn-purple:hover:not(:disabled) { background: #5a34ac; }
  .btn-wine:hover:not(:disabled)   { background: #85293b; }
}

.btn-block { width: 100%; padding-block: .8rem; }

.btn-inline {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-3);
  padding: .3rem .15rem;
  transition: color 140ms ease, transform 140ms var(--ease-out);
}
.btn-inline:active { transform: scale(0.97); }
.btn-inline .ico { width: .95rem; height: .95rem; }
@media (hover: hover) and (pointer: fine) {
  .btn-inline:hover { color: var(--gold-300); }
}

.btn-icon {
  width: 2.1rem; height: 2.1rem;
  display: grid; place-content: center;
  border-radius: var(--r-2);
  color: var(--ink-3);
  transition: color 140ms ease, background-color 140ms ease, transform 140ms var(--ease-out);
}
.btn-icon:active { transform: scale(0.94); }
.btn-icon:disabled { opacity: .3; cursor: not-allowed; }
@media (hover: hover) and (pointer: fine) {
  .btn-icon:hover:not(:disabled) { color: var(--ink-1); background: var(--navy-800); }
  .btn-icon.is-danger:hover:not(:disabled) { color: var(--danger); background: var(--danger-dim); }
  .btn-icon.has-note:hover { color: var(--gold-300); }
}
.btn-icon.has-note { color: var(--gold-500); }

/* =========================================================================
   Shell
   ========================================================================= */

.app {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "topbar" "view" "tabbar";
}

.topbar {
  grid-area: topbar;
  position: sticky; top: 0; z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 1.15rem;
  padding-top: env(safe-area-inset-top, 0px);
  height: calc(var(--topbar-h) + env(safe-area-inset-top, 0px));
  /* Opaque rather than backdrop-filter: a sticky bar with a blur over a long
     scrolling list costs a frame on every scroll on a phone. */
  background: var(--navy-950);
  border-bottom: 1px solid var(--rule);
}

.topbar-mark {
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink-1);
}

.topbar-right { display: flex; align-items: center; gap: .7rem; }

.topbar-user {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-2);
  transition: color 140ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .topbar-user:hover { color: var(--gold-300); }
}

.chip-demo {
  font-size: var(--t-xs);
  letter-spacing: .06em;
  color: var(--gold-500);
  border: 1px solid var(--rule-gold);
  border-radius: var(--r-1);
  padding: .12rem .4rem;
}

.rail { display: none; }

.tabbar {
  grid-area: tabbar;
  position: sticky; bottom: 0; z-index: 40;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  height: var(--tabbar-h);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--navy-950);
  border-top: 1px solid var(--rule);
}

.tab {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: .18rem;
  color: var(--ink-3);
  font-size: 0.625rem;
  letter-spacing: .02em;
  position: relative;
  transition: color 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.tab .ico { width: 1.3rem; height: 1.3rem; }
.tab.is-on { color: var(--gold-300); }
.tab.is-on::before {
  content: "";
  position: absolute; top: -1px; left: 22%; right: 22%;
  height: 1px; background: var(--gold-400);
}

.view {
  grid-area: view;
  width: 100%;
  max-width: var(--column);
  margin-inline: auto;
  padding: 1.5rem var(--view-pad) 3rem;
  outline: none;
}

.view.is-switching > * { animation: page-in 180ms var(--ease-out) both; }
@keyframes page-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* =========================================================================
   Page head
   ========================================================================= */

.head { margin-bottom: 1.5rem; }

.head-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
}
@media (max-width: 27rem) {
  .head-row { flex-direction: column; align-items: stretch; gap: 1.1rem; }
  .head-row .btn { align-self: flex-start; }
}

.head-title {
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: 2.1rem;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.032em;
  color: var(--ink-1);
}
.head-sub { color: var(--ink-3); font-size: var(--t-sm); margin-top: .45rem; }

/* =========================================================================
   The calendar
   ========================================================================= */

.cal-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: 1.1rem;
}

.cal-month {
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -0.028em;
  color: var(--ink-1);
  line-height: 1.1;
}

.cal-nav-right { display: flex; align-items: center; gap: .25rem; }

.cal-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border-bottom: 1px solid var(--rule);
  padding-bottom: .4rem;
  margin-bottom: -1px;
}
.cal-dow span {
  text-align: center;
  font-size: var(--t-xs);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-4);
  font-weight: 600;
}

/* A true planner grid: hairlines, not tiles. */
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
}

.cal-day {
  position: relative;
  aspect-ratio: 1 / 0.94;
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  padding: .3rem .35rem;
  color: var(--ink-2);
  text-align: left;
  transition: background-color 140ms ease;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
}
.cal-day:active { background: var(--navy-800); }
@media (hover: hover) and (pointer: fine) {
  .cal-day:hover { background: var(--navy-800); }
  .cal-day.is-strength:hover { background: #58309f; }
  .cal-day.is-cardio:hover   { background: #7d2739; }
}

.cal-num {
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1;
}

.cal-day.is-outside { color: var(--ink-4); }
.cal-day.is-outside .cal-num { font-weight: 400; }

/* Logged: the whole square carries the colour. */
.cal-day.is-strength { background: var(--purple-deep); color: #fff; }
.cal-day.is-cardio   { background: var(--wine-deep);   color: #fff; }

/* Both kinds on one day: split the square. */
.cal-day.is-both {
  color: #fff;
  background: linear-gradient(135deg,
              var(--purple-deep) 0%, var(--purple-deep) 49.6%,
              var(--wine-deep) 50.4%, var(--wine-deep) 100%);
}

/* Planned but not yet written up: outline only. */
.cal-day.is-planned::after {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px dashed var(--purple);
  border-radius: var(--r-1);
  pointer-events: none;
}
.cal-day.is-planned-cardio::after { border-color: var(--wine); }

/* Today: a brass ring. Gold means current, and here it does. */
.cal-day.is-today .cal-num {
  color: var(--gold-300);
}
.cal-day.is-today::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid var(--gold-400);
  pointer-events: none;
  z-index: 1;
}
.cal-day.is-strength.is-today .cal-num,
.cal-day.is-cardio.is-today .cal-num,
.cal-day.is-both.is-today .cal-num { color: var(--gold-200); }

/* The selected square. */
.cal-day.is-picked { box-shadow: inset 0 0 0 2px var(--gold-400); z-index: 2; }

.cal-note {
  font-size: 0.5625rem;
  line-height: 1.15;
  letter-spacing: .01em;
  opacity: .82;
  width: 100%;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  padding-top: .9rem;
  font-size: var(--t-xs);
  color: var(--ink-3);
}
.cal-legend span { display: inline-flex; align-items: center; gap: .4rem; }
.cal-legend i {
  width: .7rem; height: .7rem;
  border-radius: var(--r-1);
  display: block;
}
.cal-legend i.k-strength { background: var(--purple-deep); border: 1px solid var(--purple); }
.cal-legend i.k-cardio   { background: var(--wine-deep);   border: 1px solid var(--wine); }
.cal-legend i.k-planned  { border: 1px dashed var(--purple); }

/* =========================================================================
   The opened day
   ========================================================================= */

.day-panel { margin-top: 2rem; }

.day-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: .7rem;
  border-bottom: 1px solid var(--rule);
}

.day-title {
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.024em;
  color: var(--ink-1);
  line-height: 1.15;
}
.day-sub { font-size: var(--t-sm); color: var(--ink-3); margin-top: .2rem; }

.kind-tag {
  font-size: var(--t-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 600;
  padding: .15rem .45rem;
  border-radius: var(--r-1);
  flex: none;
}
.kind-tag.k-strength { color: var(--purple-lift); border: 1px solid var(--purple); background: var(--purple-soft); }
.kind-tag.k-cardio   { color: var(--wine-lift);   border: 1px solid var(--wine);   background: var(--wine-soft); }

/* The swatch in a list row: same two colours as the calendar squares, so a
   plan day announces the colour it will carry there. */
.kind-dot {
  display: inline-block;
  width: .55rem; height: .55rem;
  border-radius: var(--r-1);
  margin-right: .5rem;
  vertical-align: baseline;
  flex: none;
}
.kind-dot.k-strength { background: var(--purple-deep); border: 1px solid var(--purple); }
.kind-dot.k-cardio   { background: var(--wine-deep);   border: 1px solid var(--wine); }

.session-block { padding-top: .3rem; }
.session-block + .session-block { margin-top: 2rem; }

/* =========================================================================
   Ledger rows
   ========================================================================= */

.ledger { border-top: 1px solid var(--rule); }

.ledger-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.6rem 0 .55rem;
  border-bottom: 1px solid var(--rule);
}
.ledger-head:first-child { padding-top: .3rem; }
.ledger-head h2 {
  font-size: var(--t-xs);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--gold-500);
  font-weight: 600;
}

.row {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .85rem 0;
  border-bottom: 1px solid var(--rule);
  position: relative;
  transition: background-color 140ms ease;
}
.row-link { width: 100%; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.row-link::before {
  content: "";
  position: absolute;
  inset: 0 -1.15rem;
  background: inherit;
  z-index: -1;
}
.row-link:active { background: var(--navy-850); }
@media (hover: hover) and (pointer: fine) {
  .row-link:hover { background: var(--navy-900); }
  .row-link:hover .row-arrow { color: var(--gold-400); transform: translateX(2px); }
}

.row-main { flex: 1; min-width: 0; }
.row-title { font-size: var(--t-md); font-weight: 500; color: var(--ink-1); line-height: 1.3; }
.row-sub { font-size: var(--t-sm); color: var(--ink-3); margin-top: .18rem; }
.row-right { display: flex; align-items: center; gap: .6rem; flex: none; color: var(--ink-2); font-size: var(--t-sm); }
.row-value { font-weight: 600; color: var(--gold-300); letter-spacing: -0.01em; }
.row-arrow { color: var(--ink-4); transition: color 140ms ease, transform 160ms var(--ease-out); }
.row-arrow .ico { width: 1rem; height: 1rem; }

.row-mark {
  flex: none;
  width: 3rem;
  text-align: right;
  font-size: var(--t-xs);
  color: var(--ink-3);
  line-height: 1.25;
}
.row-mark b { display: block; color: var(--ink-2); font-size: var(--t-sm); font-weight: 600; }

/* =========================================================================
   Exercise and sets
   ========================================================================= */

.exercise { border-bottom: 1px solid var(--rule); padding: 1.1rem 0 .9rem; }
.exercise:first-of-type { border-top: 1px solid var(--rule); }

.ex-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: .7rem;
}
.ex-name { font-size: var(--t-md); font-weight: 600; color: var(--ink-1); line-height: 1.3; }
.ex-target { font-size: var(--t-xs); letter-spacing: .06em; color: var(--ink-3); margin-top: .15rem; }
.ex-tools { display: flex; gap: .1rem; flex: none; }

/* The note itself, once written, sits under the name in the exercise's own voice. */
.ex-note {
  font-size: var(--t-sm);
  color: var(--ink-2);
  line-height: 1.6;
  margin: .55rem 0 .9rem;
  padding-left: .7rem;
  border-left: 1px solid var(--gold-500);
  white-space: pre-wrap;
}

/* Superset: exactly 1px of gold. More would be decoration. */
.superset { position: relative; padding-left: 1.05rem; margin-left: .1rem; }
.superset::before {
  content: "";
  position: absolute;
  left: 0; top: .35rem; bottom: .35rem;
  width: 1px; background: var(--gold-500);
}
.superset-tag {
  position: absolute;
  left: -.05rem; top: -.65rem;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .1em;
  color: var(--gold-400);
  background: var(--navy-950);
  padding: 0 .3rem 0 0;
}

.set-head {
  display: grid;
  grid-template-columns: 2.2rem 1fr 1fr;
  gap: .5rem;
  align-items: center;
  padding-bottom: .3rem;
  border-bottom: 1px solid var(--rule-soft);
}
.set-head span {
  font-size: var(--t-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
  font-weight: 600;
}
.set-head span:nth-child(2), .set-head span:nth-child(3) { text-align: right; padding-right: .55rem; }

.set {
  display: grid;
  grid-template-columns: 2.2rem 1fr 1fr;
  gap: .5rem;
  align-items: center;
  padding: .3rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.set:last-child { border-bottom: 0; }


.set-field {
  /* The column runs to the edge, the rule under the number does not: a 200px
     line under "82.5" reads like an empty form. */
  width: 100%;
  max-width: 7.5rem;
  margin-left: auto;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  padding: .42rem .55rem .42rem 0;
  text-align: right;
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--ink-1);
  letter-spacing: -0.01em;
  transition: border-color 140ms ease, color 140ms ease;
}
.set-field:hover { border-bottom-color: var(--navy-700); }
.set-field:focus {
  outline: none;
  border-bottom-color: var(--gold-400);
  color: var(--gold-200);
}
.set-field:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.set-field::placeholder { color: var(--ink-4); font-weight: 400; }
.set-field[readonly] { border-bottom-color: transparent; }

.set-tools { display: flex; gap: 1.1rem; padding-top: .6rem; flex-wrap: wrap; }

/* ---- Cardio ----------------------------------------------------------- */

.cardio-lines { border-top: 1px solid var(--rule); }
.cardio-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: .8rem 0;
  border-bottom: 1px solid var(--rule);
}
.cardio-line dt { font-size: var(--t-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; }
.cardio-line dd { font-size: var(--t-md); color: var(--ink-1); text-align: right; }

/* =========================================================================
   Empty states - they teach the surface rather than saying nothing is here
   ========================================================================= */

.empty { border-top: 1px solid var(--rule); padding: 2.4rem 0 2rem; max-width: 32rem; }
.empty-title {
  font-family: var(--f-display); font-stretch: var(--display-wide);
  font-size: 1.3rem; font-weight: 600; letter-spacing: -0.024em;
  color: var(--ink-1); margin-bottom: .5rem;
}
.empty-text { color: var(--ink-2); font-size: var(--t-sm); line-height: 1.7; margin-bottom: 1.3rem; }
.empty-acts { display: flex; gap: .6rem; flex-wrap: wrap; }

/* =========================================================================
   Loading - ruled placeholders, no spinner in the middle of content
   ========================================================================= */

.skeleton { border-top: 1px solid var(--rule); }
.skeleton-row {
  height: 1.05rem;
  margin: 1.1rem 0;
  background: linear-gradient(90deg, var(--navy-900) 0%, var(--navy-850) 50%, var(--navy-900) 100%);
  background-size: 240% 100%;
  border-radius: var(--r-1);
  animation: shimmer 1400ms linear infinite;
}
.skeleton-row + .skeleton-row { border-top: 1px solid var(--rule); padding-top: 1.1rem; }
.skeleton-row:nth-child(2) { width: 72%; }
.skeleton-row:nth-child(3) { width: 88%; }
.skeleton-row:nth-child(4) { width: 64%; }
@keyframes shimmer {
  from { background-position: 120% 0; }
  to   { background-position: -120% 0; }
}

/* =========================================================================
   Board
   ========================================================================= */

.filters { display: flex; gap: .4rem; margin-bottom: 1.3rem; overflow-x: auto; scrollbar-width: none; padding-bottom: .2rem; }
.filters::-webkit-scrollbar { display: none; }

.filter-btn {
  flex: none;
  padding: .35rem .8rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: var(--t-sm);
  color: var(--ink-3);
  transition: color 140ms ease, border-color 140ms ease, background-color 140ms ease, transform 140ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.filter-btn:active { transform: scale(0.97); }
.filter-btn.is-on { color: var(--gold-200); border-color: var(--gold-500); background: rgba(212, 172, 99, .09); }
@media (hover: hover) and (pointer: fine) {
  .filter-btn:hover:not(.is-on) { color: var(--ink-1); border-color: var(--navy-700); }
}

.entry { border-bottom: 1px solid var(--rule); padding: 1.05rem 0; }
.entry:first-child { border-top: 1px solid var(--rule); }

.entry-head { display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap; margin-bottom: .35rem; }
.entry-who { font-weight: 600; color: var(--ink-1); font-size: var(--t-base); transition: color 140ms ease; }
@media (hover: hover) and (pointer: fine) { a.entry-who:hover { color: var(--gold-300); } }
.entry-when { font-size: var(--t-xs); color: var(--ink-4); margin-left: auto; }
.entry-title {
  font-family: var(--f-display); font-stretch: var(--display-wide);
  font-size: 1.25rem; font-weight: 600; letter-spacing: -0.024em;
  color: var(--ink-1); line-height: 1.2; margin-bottom: .35rem;
}
.entry-text { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.6; white-space: pre-wrap; }
.entry-nums { display: flex; gap: 1.15rem; margin-top: .5rem; font-size: var(--t-sm); color: var(--ink-3); flex-wrap: wrap; }
.entry-nums b { color: var(--gold-300); font-weight: 600; }
.entry-list { margin-top: .55rem; font-size: var(--t-sm); color: var(--ink-2); columns: 2; column-gap: 1.5rem; }
.entry-list li { break-inside: avoid; padding: .1rem 0; }
.entry-list .figure { color: var(--ink-3); }
@media (max-width: 30rem) { .entry-list { columns: 1; } }

/* =========================================================================
   Weight curve - real content, not a decorative squiggle
   ========================================================================= */

.chart { border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 1.4rem 0 1rem; margin-bottom: .4rem; }
.chart svg { display: block; width: 100%; height: auto; overflow: visible; }
.chart-grid { stroke: var(--rule); stroke-width: 1; }
.chart-line { stroke: var(--gold-400); stroke-width: 1.75; fill: none; stroke-linejoin: round; stroke-linecap: round; }
.chart-dot { fill: var(--gold-300); }
.chart-label { fill: var(--ink-4); font-size: 10px; letter-spacing: .06em; font-family: var(--f-ui); }

.chart-nums { display: flex; gap: 1.8rem; padding-top: 1rem; flex-wrap: wrap; }
.chart-num { font-size: var(--t-sm); color: var(--ink-3); }
/* Deltas stay white. Gaining is not worse than losing, and gold keeps
   meaning current, done, best. */
.chart-num b {
  display: block;
  font-size: var(--t-lg);
  color: var(--ink-1);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

/* =========================================================================
   Sheet
   ========================================================================= */

.veil {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(3, 8, 18, .62);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 260ms var(--ease-out);
}
.veil.is-open { opacity: 1; }

.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 61;
  max-height: min(88dvh, 46rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--navy-900);
  border-top: 1px solid var(--gold-500);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  box-shadow: var(--shadow-board);
  transform: translateY(100%);
  transition: transform 280ms var(--ease-drawer);
  padding: 0 1.15rem calc(1.5rem + env(safe-area-inset-bottom, 0px));
}
.sheet.is-open { transform: translateY(0); }
.sheet.is-closing { transition-duration: 200ms; }

.sheet-grip { width: 2.4rem; height: 3px; background: var(--navy-700); border-radius: 999px; margin: .7rem auto .2rem; }

.sheet-head {
  position: sticky; top: 0;
  background: var(--navy-900);
  padding: .5rem 0 .9rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1.15rem;
  z-index: 1;
}
.sheet-title {
  font-family: var(--f-display); font-stretch: var(--display-wide);
  font-size: 1.25rem; font-weight: 600; letter-spacing: -0.024em;
  color: var(--ink-1); line-height: 1.2;
}
.sheet-body { display: grid; gap: 1rem; }
.sheet-foot {
  display: flex; gap: .7rem;
  padding-top: 1.35rem; margin-top: .3rem;
  border-top: 1px solid var(--rule);
}
.sheet-foot .btn { flex: 1; }

/* Choice rows instead of reinvented radio buttons */
.choice { border-top: 1px solid var(--rule); }
.choice-row {
  display: flex; align-items: center; gap: .8rem;
  width: 100%; text-align: left;
  padding: .75rem .1rem;
  border-bottom: 1px solid var(--rule);
  transition: background-color 140ms ease;
  -webkit-tap-highlight-color: transparent;
}
.choice-row:active { background: var(--navy-850); }
@media (hover: hover) and (pointer: fine) { .choice-row:hover { background: var(--navy-850); } }
.choice-dot {
  flex: none; width: 1.05rem; height: 1.05rem;
  border: 1px solid var(--navy-700); border-radius: 999px;
  position: relative; transition: border-color 140ms ease;
}
.choice-dot::after {
  content: ""; position: absolute; inset: 3px; border-radius: 999px;
  background: var(--gold-400);
  transform: scale(0.4); opacity: 0;
  transition: transform 140ms var(--ease-out), opacity 140ms ease;
}
.choice-row.is-on .choice-dot { border-color: var(--gold-400); }
.choice-row.is-on .choice-dot::after { transform: scale(1); opacity: 1; }
.choice-text { flex: 1; min-width: 0; }
.choice-text b { display: block; font-weight: 500; color: var(--ink-1); }
.choice-text span { font-size: var(--t-sm); color: var(--ink-3); }

/* =========================================================================
   Toast
   ========================================================================= */

.toast-root {
  position: fixed;
  left: 50%; bottom: calc(var(--tabbar-h) + .9rem);
  transform: translateX(-50%);
  z-index: 80;
  display: grid; gap: .5rem;
  width: min(24rem, calc(100vw - 2rem));
  pointer-events: none;
}

.toast {
  background: var(--navy-850);
  border: 1px solid var(--rule);
  border-top-color: var(--gold-500);
  border-radius: var(--r-2);
  padding: .7rem .9rem;
  font-size: var(--t-sm);
  color: var(--ink-1);
  box-shadow: var(--shadow-leaf);
  display: flex; align-items: center; gap: .6rem;
  opacity: 1; transform: translateY(0);
  transition: opacity 240ms ease, transform 240ms var(--ease-out);
  pointer-events: auto;
}
.toast[data-in] { opacity: 0; transform: translateY(10px); }
.toast[data-out] { opacity: 0; transform: translateY(6px); transition-duration: 180ms; }
.toast.is-bad { border-top-color: var(--danger); color: var(--danger); }
.toast .ico { color: var(--gold-400); width: 1rem; height: 1rem; flex: none; }

/* =========================================================================
   Odds and ends
   ========================================================================= */

.tools { display: flex; gap: .8rem; align-items: center; padding-top: 1.2rem; flex-wrap: wrap; }

.day-divider {
  font-size: var(--t-xs);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--gold-500);
  font-weight: 600;
  padding: 1.5rem 0 .5rem;
  border-bottom: 1px solid var(--rule);
}
.day-divider:first-child { padding-top: .2rem; }

.danger-zone { margin-top: 2.5rem; padding-top: 1.4rem; border-top: 1px solid var(--rule); }

.stagger > * { animation: row-in 220ms var(--ease-out) both; }
.stagger > *:nth-child(1) { animation-delay: 0ms; }
.stagger > *:nth-child(2) { animation-delay: 32ms; }
.stagger > *:nth-child(3) { animation-delay: 64ms; }
.stagger > *:nth-child(4) { animation-delay: 96ms; }
.stagger > *:nth-child(5) { animation-delay: 128ms; }
.stagger > *:nth-child(n+6) { animation-delay: 150ms; }
@keyframes row-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* =========================================================================
   From tablet up: the rail replaces the tab bar
   ========================================================================= */

@media (min-width: 56rem) {
  .app {
    grid-template-columns: var(--rail-w) 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas: "topbar topbar" "rail view";
  }

  .tabbar { display: none; }
  .topbar { padding-inline: 1.75rem; }

  .rail {
    grid-area: rail;
    display: block;
    position: sticky;
    top: calc(var(--topbar-h) + env(safe-area-inset-top, 0px));
    align-self: start;
    height: calc(100dvh - var(--topbar-h) - env(safe-area-inset-top, 0px));
    padding: 1.5rem .9rem;
    border-right: 1px solid var(--rule);
  }

  .rail-item {
    display: flex; align-items: center; gap: .75rem;
    padding: .6rem .7rem;
    border-radius: var(--r-2);
    color: var(--ink-3);
    font-size: var(--t-sm);
    font-weight: 500;
    position: relative;
    transition: color 160ms ease, background-color 160ms ease;
  }
  .rail-item + .rail-item { margin-top: .1rem; }
  .rail-item:hover { color: var(--ink-1); background: var(--navy-900); }
  .rail-item.is-on { color: var(--gold-200); background: var(--navy-900); }
  .rail-item.is-on::before {
    content: "";
    position: absolute; left: 0; top: .55rem; bottom: .55rem;
    width: 1px; background: var(--gold-400);
  }

  .view { --view-pad: 2.25rem; padding: 2.5rem var(--view-pad) 5rem; margin-inline: 0; max-width: 50rem; }

  .toast-root { bottom: 1.5rem; left: auto; right: 1.75rem; transform: none; }

  .cal-day { aspect-ratio: 1 / 0.7; padding: .45rem .5rem; }
  .cal-num { font-size: var(--t-base); }
  .cal-note { font-size: 0.625rem; }

  .sheet {
    left: 50%; right: auto; bottom: auto; top: 50%;
    width: min(32rem, calc(100vw - 4rem));
    border-radius: var(--r-3);
    border: 1px solid var(--rule);
    border-top-color: var(--gold-500);
    transform: translate(-50%, -50%) scale(0.97);
    opacity: 0;
    transition: transform 240ms var(--ease-out), opacity 200ms ease;
    padding-bottom: 1.5rem;
    box-shadow: var(--shadow-leaf);
  }
  .sheet.is-open { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  .sheet.is-closing { transition-duration: 180ms; }
  .sheet-grip { display: none; }
  .sheet-head { padding-top: 1.15rem; }
}

/* =========================================================================
   The month, deepened
   -------------------------------------------------------------------------
   Two additions carry most of the weight here. The grid runs edge to edge on
   a phone, the way a planner pinned to a wall does. And every logged square
   grows a bar at its foot showing how heavy that day was against the heaviest
   in view - which turns a wall of marks into something with a shape.
   ========================================================================= */

.cal-tally {
  font-size: var(--t-sm);
  color: var(--ink-3);
  margin-top: .3rem;
}

/* Full bleed on a phone, back inside the column once there is room. */
.cal-bleed {
  margin-inline: calc(var(--view-pad) * -1);
  border-block: 1px solid var(--rule);
}
.cal-bleed .cal-grid { border-top: 0; border-left: 0; }
.cal-bleed .cal-day:nth-child(7n) { border-right: 0; }
.cal-bleed .cal-grid > .cal-day:nth-last-child(-n+7) { border-bottom: 0; }

.cal-dow { padding-inline: 0; margin-bottom: .5rem; border-bottom: 0; }

/* A plate edge on the filled squares: one hairline of light along the top,
   the way an engraved panel catches it. Not a glow, not glass. */
.cal-day.is-strength,
.cal-day.is-cardio,
.cal-day.is-both {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .09);
}

/* How heavy the day was, as a fill level along the foot of the square. Sat
   hard against the bottom edge rather than under the label, where it read as
   an underline instead of a measurement. */
.cal-load {
  position: absolute;
  left: 0; bottom: 0;
  height: 3px;
  max-width: 100%;
  background: rgba(255, 255, 255, .55);
  pointer-events: none;
}
.cal-day.is-today .cal-load { background: var(--gold-300); }
.cal-day .cal-note { margin-bottom: .22rem; }

.cal-day.is-picked { box-shadow: inset 0 0 0 2px var(--gold-400); z-index: 2; }
.cal-day.is-strength.is-picked,
.cal-day.is-cardio.is-picked,
.cal-day.is-both.is-picked {
  box-shadow: inset 0 0 0 2px var(--gold-400), inset 0 1px 0 rgba(255, 255, 255, .09);
}

@media (min-width: 56rem) {
  .cal-bleed { margin-inline: 0; border-block: 0; }
  .cal-bleed .cal-grid { border-top: 1px solid var(--rule); border-left: 1px solid var(--rule); }
  .cal-bleed .cal-day:nth-child(7n) { border-right: 1px solid var(--rule); }
  .cal-bleed .cal-grid > .cal-day:nth-last-child(-n+7) { border-bottom: 1px solid var(--rule); }
  .cal-dow { padding-bottom: .4rem; }
}

/* =========================================================================
   The plate - what a day of eating came to
   -------------------------------------------------------------------------
   Ledger grammar, not dashboard grammar: one headline figure, ruled tracks,
   and the three macros side by side. No rings, no dials.
   ========================================================================= */

.head-acts { display: flex; gap: .5rem; flex: none; }

.plate {
  border-top: 1px solid var(--gold-500);
  border-bottom: 1px solid var(--rule);
  padding: 1rem 0 1.35rem;
  margin-bottom: .4rem;
}

.plate-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
}
.plate-when { text-align: center; min-width: 0; }
.plate-when h2 {
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.024em;
  color: var(--ink-1);
  line-height: 1.15;
}
.plate-when span {
  display: block;
  font-size: var(--t-xs);
  letter-spacing: .04em;
  color: var(--ink-3);
  margin-top: .1rem;
}

.plate-cal { text-align: center; padding: 1.1rem 0 0; }

.plate-kcal {
  font-family: var(--f-display);
  font-stretch: var(--display-wide);
  font-size: clamp(2.9rem, 14vw, 3.8rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.042em;
  color: var(--ink-1);
}

.plate-cal-sub {
  font-size: var(--t-sm);
  color: var(--ink-3);
  margin: .5rem 0 .85rem;
}

.plate-hint {
  margin-top: 1.2rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--rule);
  font-size: var(--t-sm);
  color: var(--ink-3);
  line-height: 1.6;
}
.plate-hint p { margin-bottom: .4rem; }

.plate-note {
  margin-top: 1rem;
  font-size: var(--t-xs);
  color: var(--ink-4);
  text-align: center;
}

/* ---- The track --------------------------------------------------------- */

.track {
  height: 4px;
  background: var(--rule);
  border-radius: 2px;
  overflow: hidden;
}
.track i {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: var(--gold-400);
  border-radius: 2px;
}
.track.is-thin { height: 3px; }

.rest { color: var(--ink-3); }
/* Over the target is a fact, not a failure - it stays in the same ink. */
.rest.is-over { color: var(--ink-2); }

/* ---- The three macros -------------------------------------------------- */

.macro-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.1rem;
  margin-top: 1.4rem;
}

.macro-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .3rem;
  margin-bottom: .4rem;
  flex-wrap: wrap;
}
.macro-name {
  font-size: var(--t-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}
.macro-num { font-size: var(--t-sm); color: var(--ink-1); font-weight: 600; }
.macro-goal { color: var(--ink-3); font-weight: 400; }
.macro-rest { font-size: var(--t-xs); color: var(--ink-4); margin-top: .35rem; }

@media (max-width: 26rem) {
  .macro-row { gap: .7rem; }
  .macro-top { flex-direction: column; gap: 0; align-items: flex-start; }
  .macro-num { font-size: var(--t-xs); }
}

/* Three number fields in a sheet, side by side. */
.macro-fields { display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem; }
.macro-fields .field input { padding-inline: .5rem; text-align: center; }

/* =========================================================================
   Dragging an exercise into place
   ========================================================================= */

.drag-handle {
  display: none;
  color: var(--ink-4);
  cursor: grab;
  touch-action: none;
  padding: .35rem .1rem;
  transition: color 140ms ease;
}
.drag-handle .ico { width: 1.1rem; height: 1.1rem; }
@media (hover: hover) and (pointer: fine) {
  .drag-handle:hover { color: var(--ink-2); }
}
/* Pointer devices with a coarse pointer get the handle too - it is a bigger
   target than the arrows and reads as grabbable. */
.ledger .row .drag-handle { display: block; }

.row.is-dragging {
  position: relative;
  z-index: 3;
  cursor: grabbing;
  background: var(--navy-850);
  box-shadow: var(--shadow-leaf);
  border-bottom-color: var(--gold-500);
}
.row.is-dragging .drag-handle { color: var(--gold-400); cursor: grabbing; }

body.is-sorting { cursor: grabbing; user-select: none; }
body.is-sorting .row-link { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .row.is-dragging { box-shadow: none; }
}

/* =========================================================================
   Three kinds of set
   -------------------------------------------------------------------------
   Working sets carry a number, warm-ups a W, drop sets an arrow. The marker
   is a button: on a phone, tapping the number you are already looking at
   beats a fourth control under every exercise.
   ========================================================================= */

.set-n {
  font-size: var(--t-sm);
  color: var(--ink-3);
  font-weight: 600;
  text-align: left;
  padding: .45rem .2rem;
  margin: -.45rem -.2rem;
  border-radius: var(--r-2);
  line-height: 1.1;
  transition: color 140ms ease, background-color 140ms ease, transform 140ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.set-n:active { transform: scale(0.92); }
@media (hover: hover) and (pointer: fine) {
  .set-n:hover { color: var(--ink-1); background: var(--navy-800); }
}

/* Warm-ups are quieter than the work, and their numbers do not count. */
.set.is-warm .set-n { color: var(--ink-4); font-size: var(--t-xs); }
.set.is-warm .set-field { color: var(--ink-3); font-weight: 500; }
.set.is-warm .set-field:focus { color: var(--gold-200); }

.set.is-drop { margin-left: .9rem; }
.set.is-drop .set-n { color: var(--gold-600); font-size: var(--t-xs); }

/* The best you have ever done. Gold, because that is what gold means here. */
.set.is-record .set-field { color: var(--gold-200); }
.set.is-record .set-n { color: var(--gold-400); }
.set-n i {
  display: block;
  font-style: normal;
  font-size: 0.5625rem;
  letter-spacing: .1em;
  font-weight: 700;
  color: var(--gold-400);
  margin-top: .05rem;
}

.set-tools { gap: .9rem; }

/* =========================================================================
   One exercise, over time
   ========================================================================= */

.chart-caption {
  font-size: var(--t-xs);
  color: var(--ink-4);
  padding-top: .5rem;
  margin-bottom: 1.4rem;
}

.ex-day { border-bottom: 1px solid var(--rule); padding: .9rem 0; }
.ex-day:first-child { border-top: 1px solid var(--rule); }

.ex-day-head {
  display: flex;
  align-items: baseline;
  gap: .8rem;
  padding: .1rem 0 .5rem;
  transition: color 140ms ease;
}
.ex-day-when {
  flex: none;
  width: 3.4rem;
  font-size: var(--t-xs);
  color: var(--ink-3);
  line-height: 1.2;
}
.ex-day-when b { display: block; color: var(--ink-2); font-size: var(--t-sm); font-weight: 600; }
.ex-day-title { flex: 1; min-width: 0; font-size: var(--t-base); color: var(--ink-1); font-weight: 500; }
.ex-day-head .row-arrow { align-self: center; }
@media (hover: hover) and (pointer: fine) {
  .ex-day-head:hover .ex-day-title { color: var(--gold-300); }
  .ex-day-head:hover .row-arrow { color: var(--gold-400); transform: translateX(2px); }
}

/* The sets of one day, wrapped so a long session stays a few lines on a
   phone rather than a column you have to scroll past. */
.ex-day-sets {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem .5rem;
  padding-left: 4.2rem;
}
.ex-day-sets li {
  display: inline-flex;
  align-items: baseline;
  gap: .25rem;
  font-size: var(--t-sm);
  color: var(--ink-2);
  border: 1px solid var(--rule);
  border-radius: var(--r-2);
  padding: .12rem .45rem;
}
.ex-day-sets li i {
  font-style: normal;
  font-size: var(--t-xs);
  color: var(--ink-4);
}
.ex-day-sets li.is-warm { color: var(--ink-4); border-style: dashed; }
.ex-day-sets li.is-record {
  color: var(--gold-200);
  border-color: var(--gold-500);
  background: rgba(212, 172, 99, .08);
}
.ex-day-sets li b {
  font-size: 0.5625rem;
  letter-spacing: .1em;
  color: var(--gold-400);
  font-weight: 700;
}

@media (max-width: 26rem) {
  .ex-day-sets { padding-left: 0; margin-top: .2rem; }
}

.ex-name a { color: inherit; }
@media (hover: hover) and (pointer: fine) {
  .ex-name a:hover { color: var(--gold-300); }
}
.row-title a { color: inherit; }
@media (hover: hover) and (pointer: fine) {
  .row-title a:hover { color: var(--gold-300); }
}

/* =========================================================================
   Swiping between months
   -------------------------------------------------------------------------
   pan-y hands vertical scrolling to the browser and keeps the horizontal
   axis for the gesture, so a swipe never fights a scroll.
   ========================================================================= */

.cal-bleed {
  touch-action: pan-y;
  will-change: transform;
}
.cal-bleed.is-swiping {
  cursor: grabbing;
  user-select: none;
}
.cal-bleed.is-swiping .cal-day { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .cal-bleed { will-change: auto; }
}

/* =========================================================================
   Less motion: fewer and gentler, not none
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  .view.is-switching > *, .stagger > * { animation: none; }
  .code-row.is-wrong .code-box { animation: none; }

  .btn:active, .btn-icon:active, .btn-inline:active, .filter-btn:active { transform: none; }

  .sheet { transition: opacity 160ms ease; transform: translateY(0); opacity: 0; }
  .sheet.is-open { opacity: 1; transform: translateY(0); }
  @media (min-width: 56rem) {
    .sheet { transform: translate(-50%, -50%); }
    .sheet.is-open { transform: translate(-50%, -50%); }
  }

  .toast { transition: opacity 160ms ease; }
  .toast[data-in], .toast[data-out] { transform: none; }

  .skeleton-row { animation: none; background: var(--navy-900); }
  .row-link:hover .row-arrow { transform: none; }
}
