/* Member surface.
 *
 * The same design system as the trainer surface — same tokens, same fonts,
 * same theme behaviour — with a layout built for the only situation it is ever
 * used in: a phone held one-handed by somebody standing at a machine, possibly
 * mid-set (CLAUDE.md §3).
 *
 * This mirrors the split the Feedback app makes between admin.css and
 * form.css. It is a separate file, not a media query on admin.css, because the
 * member surface must stay small: this is the hot path, and the trainer's
 * chrome bar, account menu and table styling are dead weight on it.
 *
 * The tokens are duplicated rather than imported. An @import costs a second
 * round trip before first paint, which is exactly the wrong trade on the page
 * that has to be readable in under a second on 4G.
 */

:root{
  --ink:#1d2025; --ink-2:#3a3f47; --muted:#5b6068; --line:#e7e7e8; --line-strong:#d3d4d6;
  --bg:#f4f4f5; --surface:#ffffff; --surface-2:#fafafa;
  --accent:#f5a81d; --accent-press:#e2940c; --accent-line:#f7c164; --accent-tint:#fef8ec;
  --danger:#d64545; --danger-tint:#fdf1f1; --success:#2e9e5b; --success-tint:#eef7f1;
  --font-display:'Montserrat',-apple-system,"Segoe UI",sans-serif;
  --font-body:'Lato',-apple-system,"Segoe UI",sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --fs-caption:13px; --fs-sm:15px; --fs-base:17px; --fs-md:20px; --fs-lg:28px; --fs-xl:40px;
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:20px; --s-6:24px; --s-8:32px;
  --r-sm:4px; --r-md:6px; --r-lg:10px;
  --shadow:0 1px 2px rgba(29,32,37,.05); --ring:0 0 0 3px rgba(245,168,29,.28);
  --chrome:#1d2025; --chrome-ink:#ffffff; --chrome-muted:#9ea3aa;
  --on-accent:#1d2025; --warn-bg:#fdf6e6; --warn-ink:#7a5410;

  /* A control a standing person hits without looking. 48px is the floor. */
  --tap:52px;
}

:root[data-theme="dark"]{
  color-scheme:dark;
  --ink:#eceef0; --ink-2:#c3c7cc; --muted:#8f959d; --line:#2b3037; --line-strong:#3c424a;
  --bg:#141619; --surface:#1c1f24; --surface-2:#22262c; --accent-tint:#2a2315; --accent-line:#6a5320;
  --danger:#ef8080; --danger-tint:#301d1d; --success:#5cc287; --success-tint:#1b2b22;
  --chrome:#101215; --warn-bg:#33280f; --warn-ink:#f3d79a; --shadow:0 1px 2px rgba(0,0,0,.4);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}

body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--font-body);font-size:var(--fs-base);line-height:1.5;
  -webkit-font-smoothing:antialiased;
}

a{color:var(--accent-press);text-decoration:none}

/* --- chrome ------------------------------------------------------------- */

.mhead{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s-4);
  padding:var(--s-3) var(--s-4);
  padding-top:max(var(--s-3),env(safe-area-inset-top));
  background:var(--chrome);color:var(--chrome-ink);
  border-bottom:2px solid var(--accent);
}
.mhead__brand{
  color:var(--chrome-ink);font-family:var(--font-display);font-weight:700;
  font-size:var(--fs-sm);letter-spacing:.01em;text-decoration:none;
}
.mhead__brand:hover{color:var(--chrome-ink)}
.mhead__right{display:flex;align-items:center;gap:var(--s-3);font-size:var(--fs-caption)}
.mhead__right a,.mhead__right button{
  color:var(--chrome-muted);background:none;border:0;padding:0;
  font:inherit;cursor:pointer;text-decoration:none;
}
.mhead__right a:hover,.mhead__right button:hover{color:var(--chrome-ink)}
.mhead__form{display:inline;margin:0}

.mmain{max-width:34rem;margin:0 auto;padding:var(--s-4);padding-bottom:max(var(--s-8),env(safe-area-inset-bottom))}
.mfoot{padding:var(--s-6) var(--s-4);color:var(--muted);font-size:var(--fs-caption);text-align:center}

/* --- the card, the only container ---------------------------------------- */

.mcard{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--shadow);padding:var(--s-5);margin-bottom:var(--s-4);
}
.mcard--quiet{background:none;border:0;box-shadow:none;padding:0}

/* The machine's name is the first thing to read and the thing that confirms
   the right tag was tapped. It gets the size to match. */
.mtitle{font-family:var(--font-display);font-weight:700;font-size:var(--fs-lg);
        line-height:1.2;margin:0 0 var(--s-1);letter-spacing:-.01em}
.msub{margin:0;color:var(--muted);font-size:var(--fs-sm)}
.mh2{font-family:var(--font-display);font-weight:600;font-size:var(--fs-md);margin:0 0 var(--s-3)}

/* --- the numbers --------------------------------------------------------- */
/*
 * What the trainer prescribed, read at arm's length. Tabular figures so the
 * digits do not shift between two members' programmes.
 */
.mfigures{display:flex;gap:var(--s-3);margin:0}
.mfigure{flex:1 1 0;text-align:center;background:var(--surface-2);
         border:1px solid var(--line);border-radius:var(--r-md);padding:var(--s-3) var(--s-2)}
.mfigure__value{display:block;font-family:var(--font-display);font-weight:700;
                font-size:var(--fs-xl);line-height:1;font-variant-numeric:tabular-nums}
.mfigure__unit{font-size:var(--fs-sm);font-weight:400;color:var(--muted)}
.mfigure__label{display:block;margin-top:var(--s-1);font-size:var(--fs-caption);
                text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
.mfigure__range{display:block;font-size:var(--fs-caption);color:var(--muted);margin-top:2px}

/* --- machine settings ---------------------------------------------------- */

.msettings{display:grid;grid-template-columns:1fr auto;gap:var(--s-3) var(--s-4);margin:0}
.msettings dt{color:var(--muted)}
.msettings dd{margin:0;font-weight:700;font-variant-numeric:tabular-nums;text-align:right}

/* --- notes ---------------------------------------------------------------- */
/*
 * Styling comes from note_type and is never authored (§8). A contraindication
 * is red and at the top; a caution is amber and sits before the log control;
 * technique is neutral and inline; admin is collapsed.
 */
.mnote{border-left:4px solid var(--line-strong);background:var(--surface-2);
       border-radius:var(--r-md);padding:var(--s-3) var(--s-4);margin:0 0 var(--s-3)}
.mnote__type{display:block;font-size:var(--fs-caption);font-weight:700;
             text-transform:uppercase;letter-spacing:.06em;margin-bottom:2px;color:var(--muted)}
.mnote p{margin:0 0 var(--s-2)}
.mnote p:last-child{margin-bottom:0}
.mnote ul{margin:0;padding-left:1.2em}

.mnote--contraindication{border-left-color:var(--danger);background:var(--danger-tint);color:var(--danger)}
.mnote--contraindication .mnote__type{color:var(--danger)}
.mnote--caution{border-left-color:var(--accent);background:var(--warn-bg);color:var(--warn-ink)}
.mnote--caution .mnote__type{color:var(--warn-ink)}
.mnote--technique{border-left-color:var(--line-strong)}
.mnote--admin{border-left-color:var(--line);color:var(--muted);font-size:var(--fs-sm)}
.mnote--error{border-left-color:var(--danger);background:var(--danger-tint);color:var(--danger)}
.mnote--warn{border-left-color:var(--accent);background:var(--warn-bg);color:var(--warn-ink)}

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

/* NOTHING ON A PHONE IS ALLOWED TO BE WIDER THAN THE PHONE.
   A form control sizes itself to its content — a <select> to its longest
   option, an <input> to its `size` — and will happily be wider than the screen
   it is on. The member surface is the one that has to be right on a 375px
   phone held one-handed at a machine (§3), so it is said once here rather than
   remembered on each new field. */
select,input,textarea,button{max-width:100%}

.mbtn{
  display:flex;align-items:center;justify-content:center;width:100%;
  min-height:var(--tap);padding:0 var(--s-5);
  border:1px solid var(--accent-press);border-radius:var(--r-md);
  background:var(--accent);color:var(--on-accent);
  font-family:var(--font-display);font-weight:700;font-size:var(--fs-md);
  text-decoration:none;cursor:pointer;
}
.mbtn:hover{background:var(--accent-press);color:var(--on-accent)}
.mbtn:active{transform:translateY(1px)}
.mbtn:focus-visible{outline:0;box-shadow:var(--ring)}
.mbtn--ghost{background:var(--surface);color:var(--ink);border-color:var(--line-strong)}
.mbtn--ghost:hover{background:var(--surface-2);color:var(--ink)}

/* A GRID ITEM DOES NOT SHRINK BELOW ITS CONTENT unless it is told to.
   `min-width` defaults to `auto` on a grid item, and a <select> is as wide as
   its longest option — "Beinpresse · Beinpresse 1 (Kraftraum) — hat schon
   einen Tag" is 59 characters. On a 375px phone that made the form 499px wide
   inside a 343px card: the page scrolled sideways by 161px and the button,
   being width:100% of an overflowing parent, ran off the screen with it.

   Found by tapping a real tag on a real iPhone. It cost nothing on a laptop,
   which is exactly the shape of bug the member surface exists to avoid — this
   is the screen somebody is standing at a machine holding a sticker for. */
.mform{display:grid;gap:var(--s-4);margin-top:var(--s-4);min-width:0}
.mform>*{min-width:0}
.mfield{display:grid;gap:var(--s-1);min-width:0}
.mfield>*{min-width:0}
.mfield__label{font-weight:700;font-size:var(--fs-sm)}
.mfield__input{
  /* The width, not just the minimum: a <select> asked to be as wide as its
     longest option has to be told the answer is "the card". iOS then truncates
     the selected line itself, which is what it does everywhere else. */
  width:100%;max-width:100%;
  min-height:var(--tap);padding:0 var(--s-4);
  border:1px solid var(--line-strong);border-radius:var(--r-md);
  background:var(--surface);color:var(--ink);font-family:var(--font-body);
  /* 16px minimum, or iOS Safari zooms on focus and the member loses the
     machine they were looking at. */
  font-size:17px;
}
.mfield__input:focus-visible{outline:0;box-shadow:var(--ring);border-color:var(--accent-line)}
.mfield__hint{color:var(--muted);font-size:var(--fs-caption)}

.mcode{font-family:var(--font-mono);font-size:var(--fs-md);font-weight:700;
       letter-spacing:.12em;user-select:all}

/* The preview banner (§23).
   A practitioner reading a member's screen, never the member themselves. It
   sits above the contraindication — which nothing else is allowed to do —
   because it is not a warning about the training, it is a statement about
   whose screen this is. Loud on purpose: a page that looks like your own and
   is not is the one thing worth shouting about. */
.mpreview{
  display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;
  margin:0 0 var(--s-4);padding:var(--s-3) var(--s-4);
  background:var(--warn-bg);color:var(--warn-ink);
  border:1px solid var(--accent-line);border-radius:var(--r-lg);
  font-size:var(--fs-sm);
}
.mpreview__lbl{
  font-size:var(--fs-caption);font-weight:700;text-transform:uppercase;
  letter-spacing:.08em;
}
.mpreview__back{margin-left:auto;color:var(--warn-ink);font-weight:700;text-decoration:underline}

/* A fold (§30). <details> is native, needs no script, and is the member
   surface's one way to keep a second form out of the way of the first: the
   trainer sees "Neue Maschine anlegen" or "verschieben" as a line and opens it
   only when it is the thing they came to do. The summary is a tap target of
   its own, so it gets the same minimum height as a button. */
.mdetails{margin-top:var(--s-4);border-top:1px solid var(--line);padding-top:var(--s-2)}
.mdetails__sum{
  display:flex;align-items:center;min-height:var(--tap);
  font-family:var(--font-display);font-weight:700;font-size:var(--fs-md);
  color:var(--ink);cursor:pointer;list-style:none;
}
.mdetails__sum::-webkit-details-marker{display:none}
.mdetails__sum::before{content:"+";display:inline-block;width:1.2em;color:var(--accent-press)}
.mdetails[open]>.mdetails__sum::before{content:"–"}

/* The trainer's tools under a claimed tag (§30). Two buttons that are two
   different acts — edit the machine, take the tag off it — stacked, because
   side by side on a 375px phone each would be too narrow for its own label. */
.mtools__row{display:grid;gap:var(--s-3);margin-top:var(--s-4)}
.mtools__row form{margin:0}

/* Heute (§35): the programme as a checklist. One row per exercise, a mark on
   the left saying where it stands — done, part done, not for you — and the
   numbers the member has to set the machine to on the right. It is a list
   read top to bottom on a phone, so nothing in a row is side by side except
   the mark and the text. */
.mlist{list-style:none;margin:0;padding:0}
.mlist__item{display:grid;grid-template-columns:2.4rem 1fr;gap:var(--s-3);
  padding:var(--s-3) 0;border-top:1px solid var(--line);min-width:0}
.mlist__item:first-child{border-top:0;padding-top:0}
.mlist__item>*{min-width:0}
.mlist__mark{display:flex;align-items:center;justify-content:center;
  width:2.4rem;height:2.4rem;border-radius:50%;
  border:2px solid var(--line-strong);color:var(--muted);
  font-family:var(--font-display);font-weight:700;font-size:var(--fs-sm);
  font-variant-numeric:tabular-nums}
.mlist__item.is-done .mlist__mark{background:var(--accent);border-color:var(--accent-press);color:var(--on-accent)}
.mlist__item.is-part .mlist__mark{border-color:var(--accent-line);color:var(--ink)}
.mlist__item.is-off .mlist__mark{border-color:var(--danger);color:var(--danger)}
.mlist__item.is-off .mlist__name{color:var(--muted)}
.mlist__name{display:block;font-family:var(--font-display);font-weight:700;font-size:var(--fs-md)}
.mlist__line{display:block;font-size:var(--fs-sm);color:var(--muted);margin-top:2px;font-variant-numeric:tabular-nums}
.mlist__line strong{color:var(--ink)}
.mlist__flag{display:inline-block;margin-top:4px;padding:2px 8px;border-radius:var(--r-sm);
  font-size:var(--fs-caption);font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  background:var(--danger-tint);color:var(--danger)}
.mlist__flag--warn{background:var(--warn-bg);color:var(--warn-ink)}

/* The member's nav (§35): three links under the chrome, the current one
   underlined in the accent. Tap targets, not text links — a thumb on a phone. */
.mnav{display:flex;max-width:34rem;margin:0 auto;padding:0 var(--s-4);gap:var(--s-2)}
.mnav__a{flex:1 1 0;display:flex;align-items:center;justify-content:center;min-height:var(--tap);
  font-family:var(--font-display);font-weight:700;font-size:var(--fs-sm);
  color:var(--muted);text-decoration:none;border-bottom:3px solid transparent}
.mnav__a:hover{color:var(--ink)}
.mnav__a.is-here{color:var(--ink);border-bottom-color:var(--accent)}

.mlink{color:var(--ink);font-weight:700;text-decoration:underline;text-decoration-color:var(--accent-line)}
.mcard--off .mh2{color:var(--muted)}

/* The pager, as on the admin surface (§28 step 8) — the same partial draws
   it, so it needs the same class names here. */
.pager{display:flex;align-items:center;gap:var(--s-1);flex-wrap:wrap;margin-top:var(--s-4);
  padding-top:var(--s-3);border-top:1px solid var(--line)}
.pager__p{display:inline-flex;align-items:center;justify-content:center;min-width:2.4em;min-height:2.4em;
  padding:0 10px;border:1px solid var(--line-strong);border-radius:var(--r-md);
  font-size:var(--fs-sm);color:var(--ink);text-decoration:none}
.pager__p--here{background:var(--accent);border-color:var(--accent);color:var(--on-accent);font-weight:700}
.pager__p--off{color:var(--muted);border-color:var(--line);pointer-events:none}
.pager__gap{color:var(--muted);padding:0 2px}
.pager__of{font-size:var(--fs-caption);color:var(--muted)}
.grow{flex:1 1 auto}

/* A past visit, in the history-led Heute. */
.mvisit{padding:var(--s-3) 0;border-top:1px solid var(--line)}
.mvisit:first-child{border-top:0;padding-top:0}
.mvisit__when{font-family:var(--font-display);font-weight:700}
.mvisit__where{color:var(--muted);font-size:var(--fs-sm)}
.mvisit ul{margin:var(--s-2) 0 0;padding-left:1.1em;font-size:var(--fs-sm);font-variant-numeric:tabular-nums}
.mvisit li{margin:2px 0}

@media(max-width:380px){
  :root{--fs-xl:34px;--fs-lg:24px}
  .mfigures{gap:var(--s-2)}
}

/* Which installation is this? See admin.css — the login form is exactly where
   the local copy and the live site being identical costs an afternoon. Only
   drawn when the config says env is not prod. */
.envmark{font-family:var(--font-body);font-size:var(--fs-caption);font-weight:700;
  letter-spacing:.12em;line-height:1;color:#1d2025;background:var(--accent);
  border-radius:var(--r-sm);padding:4px 7px;flex:0 0 auto}
