/* ============================================================================
   THE MARATHONS — Brand Stylesheet
   v1.0 · Route-mark identity

   HOW TO USE
   1. Drop this file into your project and link it in <head>:
        <link rel="stylesheet" href="the-marathons.css">
      (Fonts are pulled via @import below. For best performance you can instead
       move the Google Fonts <link> into your <head> and delete the @import.)
   2. Apply classes to your markup. Everything is namespaced with `tm-` and all
      tokens are `--tm-*`, so this layers cleanly over an existing site.
   3. The page defaults to the dark charcoal theme. Wrap any block in
      `.tm-on-lime`, `.tm-on-light`, or `.tm-on-trail` to flip the local theme.

   THE LOGO is an inline SVG (so it inherits color). Paste this where needed:

     <a class="tm-logo" href="/">
       <svg class="tm-logo__mark" viewBox="0 0 120 66" fill="none" aria-hidden="true">
         <polyline points="4,54 22,47 34,51 50,30 64,38 80,17 96,25 110,9"
           fill="none" stroke="currentColor" stroke-width="5.5"
           stroke-linecap="round" stroke-linejoin="round"/>
         <circle cx="110" cy="9" r="6" fill="currentColor"/>
       </svg>
       <span class="tm-wordmark"><span class="the">The</span>Marathons</span>
     </a>
   ============================================================================ */

/* Fonts are loaded via <link> tags in the layout head (see layouts/onboarding.html.erb)
   instead of an @import here, per the performance note above. */

/* ============================================================================
   1. DESIGN TOKENS
   ============================================================================ */
:root {
  /* --- Brand color primitives --- */
  --tm-charcoal:    #111317;   /* primary background, ink on light       */
  --tm-surface:     #171a20;   /* raised panels on charcoal              */
  --tm-surface-2:   #21262e;   /* higher panels, inputs                  */
  --tm-hairline:    #23272f;   /* dividers, structure                    */
  --tm-hairline-2:  #262a31;   /* card borders                           */
  --tm-lime:        #d4ff3f;   /* THE signature accent                   */
  --tm-lime-press:  #c2ef2c;   /* pressed/active accent                  */
  --tm-trail:       #79b45f;   /* supporting nature green                */
  --tm-trail-2:     #8ec873;   /* lighter trail green                    */
  --tm-cream:       #fffdf9;   /* light-surface background               */
  --tm-off-white:   #f4f3ef;   /* primary text on dark                   */
  --tm-muted:       #aeb4bc;   /* secondary text                         */
  --tm-dim:         #7c828b;   /* tertiary text, captions                */
  --tm-faint:       #5a616b;   /* labels, the quietest text              */
  --tm-online:      #3f9b5f;   /* "online" status dot                    */
  --tm-danger:      #ff7a7a;   /* errors                                 */

  /* --- Semantic tokens (components read THESE; themes override them) --- */
  --tm-bg:            var(--tm-charcoal);
  --tm-fg:            var(--tm-off-white);
  --tm-fg-muted:      var(--tm-muted);
  --tm-fg-dim:        var(--tm-dim);
  --tm-fg-faint:      var(--tm-faint);
  --tm-panel:         var(--tm-surface);
  --tm-panel-2:       var(--tm-surface-2);
  --tm-border:        var(--tm-hairline-2);
  --tm-border-soft:   var(--tm-hairline);
  --tm-accent:        var(--tm-lime);
  --tm-accent-press:  var(--tm-lime-press);
  --tm-accent-ink:    var(--tm-charcoal);   /* text sitting ON the accent */
  --tm-accent-soft:   rgba(212, 255, 63, 0.14);

  /* --- Typography --- */
  --tm-font-display: 'Archivo', system-ui, -apple-system, sans-serif;
  --tm-font-body:    'Hanken Grotesk', system-ui, -apple-system, sans-serif;

  --tm-text-xs:   0.75rem;    /* 12 */
  --tm-text-sm:   0.875rem;   /* 14 */
  --tm-text-base: 1rem;       /* 16 */
  --tm-text-lg:   1.125rem;   /* 18 */
  --tm-text-xl:   1.375rem;   /* 22 */
  --tm-text-2xl:  1.625rem;   /* 26 */
  --tm-text-3xl:  2rem;       /* 32 */
  --tm-text-4xl:  clamp(2.25rem, 4vw, 3rem);     /* 36–48 */
  --tm-text-5xl:  clamp(2.75rem, 6vw, 4.5rem);   /* 44–72 */

  --tm-tracking-display: -0.03em;
  --tm-tracking-eyebrow:  0.16em;
  --tm-leading-display:   0.94;
  --tm-leading-body:      1.6;

  /* --- Spacing scale --- */
  --tm-space-1: 0.25rem;  --tm-space-2: 0.5rem;   --tm-space-3: 0.75rem;
  --tm-space-4: 1rem;     --tm-space-5: 1.5rem;   --tm-space-6: 2rem;
  --tm-space-7: 3rem;     --tm-space-8: 4rem;     --tm-space-9: 6rem;

  /* --- Radius --- */
  --tm-radius-sm:   6px;    /* buttons, pills, chips        */
  --tm-radius-md:   12px;   /* inputs, small cards          */
  --tm-radius-lg:   16px;   /* cards, panels                */
  --tm-radius-xl:   22px;   /* app-icon / hero media        */
  --tm-radius-pill: 999px;

  /* --- Elevation --- */
  --tm-shadow-sm: 0 4px 14px rgba(0,0,0,0.35);
  --tm-shadow-md: 0 10px 26px rgba(0,0,0,0.45);
  --tm-shadow-lg: 0 18px 50px rgba(0,0,0,0.55);

  /* --- Motion --- */
  --tm-transition: 180ms cubic-bezier(.4,0,.2,1);

  /* --- Layout --- */
  --tm-container: 1200px;
  --tm-gutter: 48px;
}

@media (max-width: 760px){ :root{ --tm-gutter: 22px; } }

/* ============================================================================
   2. BASE / RESET
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body{
  margin: 0;
  background: var(--tm-bg);
  color: var(--tm-fg);
  font-family: var(--tm-font-body);
  font-size: var(--tm-text-base);
  line-height: var(--tm-leading-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

::selection { background: var(--tm-lime); color: var(--tm-charcoal); }

:focus-visible{
  outline: 2px solid var(--tm-accent);
  outline-offset: 2px;
  border-radius: 3px;
}

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ============================================================================
   3. TYPOGRAPHY
   ============================================================================ */
.tm-display, .tm-h1, .tm-h2, .tm-h3, .tm-h4,
h1.tm, h2.tm, h3.tm, h4.tm{
  font-family: var(--tm-font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: var(--tm-tracking-display);
  line-height: var(--tm-leading-display);
  color: var(--tm-fg);
  margin: 0;
}
.tm-display{ font-size: var(--tm-text-5xl); letter-spacing: -0.035em; }
.tm-h1{ font-size: var(--tm-text-4xl); }
.tm-h2{ font-size: var(--tm-text-3xl); }
.tm-h3{ font-size: var(--tm-text-2xl); }
.tm-h4{ font-size: var(--tm-text-xl); }

.tm-lead{ font-size: var(--tm-text-lg); color: var(--tm-fg-muted); font-weight: 500; line-height: 1.55; }
.tm-body{ color: var(--tm-fg-muted); font-weight: 400; }
.tm-small{ font-size: var(--tm-text-sm); color: var(--tm-fg-dim); }

/* Eyebrow / kicker label */
.tm-eyebrow{
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--tm-font-display);
  font-size: var(--tm-text-xs); font-weight: 800;
  letter-spacing: var(--tm-tracking-eyebrow); text-transform: uppercase;
  color: var(--tm-accent); margin: 0;
}
.tm-eyebrow::before{
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--tm-accent);
  box-shadow: 0 0 0 4px var(--tm-accent-soft);
}
.tm-eyebrow.tm-eyebrow--plain::before{ display: none; }

/* Links */
.tm-link, .tm-prose a{
  color: var(--tm-accent);
  text-decoration: none;
  text-underline-offset: 3px;
  transition: color var(--tm-transition);
}
.tm-link:hover, .tm-prose a:hover{ text-decoration: underline; }

/* ============================================================================
   4. WORDMARK & LOGO LOCKUP
   ============================================================================ */
.tm-wordmark{
  font-family: var(--tm-font-display);
  font-weight: 900; text-transform: uppercase;
  letter-spacing: -0.03em; line-height: 0.86;
  white-space: nowrap; color: var(--tm-fg);
}
.tm-wordmark .the{
  display: block; font-size: 0.32em; font-weight: 800;
  letter-spacing: 0.34em; line-height: 1; margin-bottom: 0.32em;
  color: var(--tm-accent);
}

.tm-logo{
  display: inline-flex; align-items: center; gap: 16px;
  text-decoration: none; color: var(--tm-fg);
}
.tm-logo__mark{ color: var(--tm-accent); width: 48px; height: auto; flex: none; }
.tm-logo .tm-wordmark{ font-size: 1.5rem; }
.tm-logo--lg .tm-logo__mark{ width: 120px; }
.tm-logo--lg .tm-wordmark{ font-size: 3.5rem; }
.tm-logo--sm .tm-logo__mark{ width: 30px; }
.tm-logo--sm .tm-wordmark{ font-size: 1.05rem; }
/* Stacked / vertical lockup */
.tm-logo--stacked{ flex-direction: column; gap: 14px; text-align: center; }
.tm-logo--stacked .tm-wordmark .the{ letter-spacing: 0.4em; }

/* Author styles like .tm-btn { display: inline-flex } otherwise override the
   UA [hidden] rule and leave "hidden" controls visible. */
[hidden]{ display: none !important; }

/* ============================================================================
   5. LAYOUT
   ============================================================================ */
.tm-container{ max-width: var(--tm-container); margin-inline: auto; padding-inline: var(--tm-gutter); }
.tm-section{ padding-block: var(--tm-space-9); }
.tm-section--tight{ padding-block: var(--tm-space-7); }
.tm-divider{ height: 1px; background: var(--tm-border-soft); border: 0; margin: 0; }

.tm-grid{ display: grid; gap: 18px; }
.tm-grid--2{ grid-template-columns: repeat(2, 1fr); }
.tm-grid--3{ grid-template-columns: repeat(3, 1fr); }
.tm-grid--4{ grid-template-columns: repeat(4, 1fr); }
@media (max-width: 880px){ .tm-grid--3, .tm-grid--4{ grid-template-columns: repeat(2,1fr); } }
@media (max-width: 560px){ .tm-grid--2, .tm-grid--3, .tm-grid--4{ grid-template-columns: 1fr; } }

/* ============================================================================
   6. BUTTONS
   ============================================================================ */
.tm-btn{
  --_btn-bg: var(--tm-accent);
  --_btn-fg: var(--tm-accent-ink);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--tm-font-display); font-weight: 800;
  font-size: var(--tm-text-sm); letter-spacing: 0.02em; text-transform: uppercase;
  line-height: 1; text-decoration: none; cursor: pointer;
  padding: 14px 22px; border: 1.5px solid transparent; border-radius: var(--tm-radius-sm);
  background: var(--_btn-bg); color: var(--_btn-fg);
  transition: transform var(--tm-transition), background var(--tm-transition),
              color var(--tm-transition), border-color var(--tm-transition);
}
.tm-btn:hover{ transform: translateY(-2px); }
.tm-btn:active{ transform: translateY(0); }

.tm-btn--primary{ --_btn-bg: var(--tm-accent); --_btn-fg: var(--tm-accent-ink); }
.tm-btn--primary:hover{ background: var(--tm-accent-press); }

.tm-btn--secondary{
  --_btn-bg: transparent; --_btn-fg: var(--tm-fg);
  border-color: var(--tm-fg);
}
.tm-btn--secondary:hover{ background: var(--tm-fg); color: var(--tm-bg); }

.tm-btn--ghost{
  --_btn-bg: transparent; --_btn-fg: var(--tm-fg-muted);
  padding-inline: 12px;
}
.tm-btn--ghost:hover{ color: var(--tm-fg); transform: none; }

/* Nothing targeted :disabled before, so a button disabled while its POST was in
   flight looked and read exactly like a live one — the click had registered but
   said nothing, so people clicked again into a dead control. The guard existed;
   this is what makes it visible.
   Every submit style in the app is listed: composers disable their button while
   posting, and the blanket handler in application.js disables every other form's
   on submit, so any of these can be the one a person is staring at. */
.tm-btn:disabled, .tm-btn[disabled],
.btn:disabled, .btn[disabled],
.tm-chat__send:disabled, .tm-chat__send[disabled],
.tm-icon-btn:disabled, .tm-icon-btn[disabled]{
  opacity: 0.45; cursor: not-allowed; transform: none;
}
/* Hover must not paint over the dimming — these families each restyle it. */
.tm-btn:disabled:hover,
.tm-btn[disabled]:hover{
  transform: none; background: var(--_btn-bg); color: var(--_btn-fg);
  border-color: transparent;
}
.btn:disabled:hover, .btn[disabled]:hover,
.tm-chat__send:disabled:hover, .tm-chat__send[disabled]:hover,
.tm-icon-btn:disabled:hover, .tm-icon-btn[disabled]:hover{
  transform: none; border-color: inherit; color: inherit;
}
.tm-btn--sm{ padding: 9px 14px; font-size: var(--tm-text-xs); }
.tm-btn--lg{ padding: 18px 30px; font-size: var(--tm-text-base); }
.tm-btn--block{ display: flex; width: 100%; }

/* ============================================================================
   7. CARDS / PANELS / CALLOUTS
   ============================================================================ */
.tm-card{
  background: var(--tm-panel);
  border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-lg);
  padding: var(--tm-space-6);
}
.tm-card--raised{ box-shadow: var(--tm-shadow-md); }
.tm-card__title{
  font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase;
  letter-spacing: -0.02em; font-size: var(--tm-text-xl); margin: 0 0 var(--tm-space-3);
}
.tm-card__text{ color: var(--tm-fg-muted); margin: 0; }

/* Callout with a lime accent bar — great for mission/quote/CTA blocks */
.tm-callout{
  background: var(--tm-accent-soft);
  border-left: 4px solid var(--tm-accent);
  border-radius: 0 var(--tm-radius-md) var(--tm-radius-md) 0;
  padding: var(--tm-space-5) var(--tm-space-6);
  color: var(--tm-fg);
}
.tm-callout strong{ color: var(--tm-fg); }

/* ============================================================================
   8. CHIPS / BADGES / PILLS / STATS
   ============================================================================ */
.tm-chip{
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--tm-font-body); font-weight: 600; font-size: var(--tm-text-sm);
  color: var(--tm-fg-muted);
  background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-pill); padding: 8px 14px;
}
.tm-badge{
  display: inline-flex; align-items: center;
  font-family: var(--tm-font-display); font-weight: 800; font-size: 10px;
  letter-spacing: 0.12em; text-transform: uppercase;
  background: var(--tm-accent); color: var(--tm-accent-ink);
  border-radius: 5px; padding: 5px 9px;
}
.tm-badge--outline{ background: transparent; color: var(--tm-accent); border: 1px solid currentColor; }

.tm-stat{ display: flex; flex-direction: column; gap: 4px; }
.tm-stat__num{
  font-family: var(--tm-font-display); font-weight: 900; letter-spacing: -0.03em;
  font-size: var(--tm-text-4xl); color: var(--tm-accent); line-height: 1;
}
.tm-stat__label{ font-size: var(--tm-text-sm); color: var(--tm-fg-dim); font-weight: 500; }

/* ============================================================================
   9. NAVIGATION & FOOTER
   ============================================================================ */
.tm-nav{
  display: flex; align-items: center; justify-content: space-between;
  padding-block: var(--tm-space-4);
  border-bottom: 1px solid var(--tm-border-soft);
}
.tm-nav__links{
  display: flex; align-items: center; gap: var(--tm-space-5);
  list-style: none; margin: 0; padding: 0;
}
@media (max-width: 480px){
  .tm-nav__links{ flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
}
.tm-nav__links a{
  font-family: var(--tm-font-display); font-weight: 700; font-size: var(--tm-text-xs);
  letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--tm-fg-muted); text-decoration: none; transition: color var(--tm-transition);
}
.tm-nav__links a.tm-btn{ color: var(--_btn-fg); }
.tm-nav__links a:hover{ color: var(--tm-fg); }
.tm-nav__links a.tm-btn:hover{ color: var(--_btn-fg); }
@media (max-width: 640px){
  .tm-nav__links{ gap: var(--tm-space-4); }
  .tm-nav__links .tm-nav__hide{ display:none; }
  /* Wordmark alone in the top nav on mobile — the route mark eats width the
     nav links need. Scoped to .tm-nav so hero/footer logos keep their mark. */
  .tm-nav .tm-logo__mark{ display: none; }
}

.tm-footer{
  border-top: 1px solid var(--tm-border-soft);
  padding-block: var(--tm-space-7);
  color: var(--tm-fg-dim); font-size: var(--tm-text-sm);
}

/* ============================================================================
   10. FORMS
   ============================================================================ */
.tm-label{
  display: block; font-family: var(--tm-font-display); font-weight: 700;
  font-size: var(--tm-text-xs); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--tm-fg-dim); margin-bottom: var(--tm-space-2);
}
.tm-input, .tm-textarea, .tm-select{
  width: 100%; font-family: var(--tm-font-body); font-size: var(--tm-text-base);
  color: var(--tm-fg); background: var(--tm-panel-2);
  border: 1px solid var(--tm-border); border-radius: var(--tm-radius-md);
  padding: 13px 15px; transition: border-color var(--tm-transition), box-shadow var(--tm-transition);
}
.tm-input::placeholder, .tm-textarea::placeholder{ color: var(--tm-fg-faint); }
.tm-input:focus, .tm-textarea:focus, .tm-select:focus{
  outline: none; border-color: var(--tm-accent);
  box-shadow: 0 0 0 3px var(--tm-accent-soft);
}
/* Inline waitlist/email field + button */
.tm-field-row{ display: flex; gap: var(--tm-space-3); flex-wrap: wrap; }
.tm-field-row .tm-input{ flex: 1 1 240px; }

/* ============================================================================
   11. CHAT BUBBLES  (coach ↔ athlete — the product's signature UI)
   ============================================================================ */
.tm-chat{
  background: var(--tm-cream);
  border: 1px solid #efe6da;
  border-radius: var(--tm-radius-lg); overflow: hidden;
}
.tm-chat__head{
  display: flex; align-items: center; gap: 11px;
  padding: 15px 16px; border-bottom: 1px solid #f0e8dc; background: var(--tm-cream);
}
.tm-chat__avatar{
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--tm-font-display); font-weight: 900; font-size: 17px;
  background: var(--tm-lime); color: var(--tm-charcoal);
}
.tm-chat__name{ font-family: var(--tm-font-body); font-weight: 700; font-size: 15px; color: #231f1a; }
.tm-chat__status{ display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--tm-online); margin-top: 1px; }
.tm-chat__status::before{ content:""; width: 6px; height: 6px; border-radius: 50%; background: var(--tm-online); }
.tm-chat__body{ display: flex; flex-direction: column; gap: 9px; padding: 16px 14px; background: #fbf7f0; }
.tm-bubble{ max-width: 82%; padding: 10px 13px; font-size: 14px; line-height: 1.42; font-family: var(--tm-font-body); }
.tm-bubble--in{ align-self: flex-start; background: #fff; border: 1px solid #efe6da; border-radius: 15px 15px 15px 5px; color: #231f1a; }
.tm-bubble--out{ align-self: flex-end; background: var(--tm-charcoal); color: var(--tm-lime); border-radius: 15px 15px 5px 15px; }
.tm-bubble__meta{
  display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 6px;
  margin-top: 6px; font-size: 11px; opacity: 0.7;
}
.tm-bubble--in .tm-bubble__meta{ justify-content: flex-start; }
.tm-bubble__time{ opacity: 0.95; }
/* Outbound SMS delivery chip (coach chat) */
.tm-bubble__status{
  display: inline-flex; align-items: center;
  font-family: var(--tm-font-display); font-weight: 800; font-size: 9px;
  letter-spacing: 0.08em; text-transform: uppercase;
  border-radius: 4px; padding: 2px 6px; line-height: 1.2;
  opacity: 1;
}
.tm-bubble--out .tm-bubble__status--success{
  background: rgba(212, 255, 63, 0.18); color: var(--tm-lime);
}
.tm-bubble--out .tm-bubble__status--pending{
  background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.75);
}
.tm-bubble--out .tm-bubble__status--danger{
  background: rgba(255, 122, 122, 0.22); color: #ff9b9b;
}
.tm-bubble--out .tm-bubble__status--muted{
  background: rgba(255, 255, 255, 0.08); color: rgba(255, 255, 255, 0.65);
}
.tm-bubble--in .tm-bubble__status--success{ background: rgba(63, 122, 31, 0.12); color: #3f7a1f; }
.tm-bubble--in .tm-bubble__status--pending{ background: #f0ebe3; color: #8a8e96; }
.tm-bubble--in .tm-bubble__status--danger{ background: rgba(255, 122, 122, 0.15); color: #c44; }
.tm-bubble--in .tm-bubble__status--muted{ background: #f0ebe3; color: #8a8e96; }

/* ============================================================================
   12. MARQUEE  (scrolling brand strip)
   ============================================================================ */
.tm-marquee{ overflow: hidden; border-block: 1px solid var(--tm-border-soft); padding-block: 16px; }
.tm-marquee__track{ display: inline-flex; gap: 40px; white-space: nowrap; animation: tm-scroll 28s linear infinite; }
.tm-marquee__track span{
  font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase;
  letter-spacing: -0.02em; font-size: var(--tm-text-2xl); color: var(--tm-fg);
}
.tm-marquee__track span::after{ content: "•"; color: var(--tm-accent); margin-left: 40px; }
@keyframes tm-scroll{ from{ transform: translateX(0);} to{ transform: translateX(-50%);} }

/* ============================================================================
   13. CONTEXT THEMES  (flip the local theme for a block)
   ============================================================================ */
.tm-on-dark{
  background: var(--tm-charcoal); color: var(--tm-off-white);
}
.tm-on-lime{
  background: var(--tm-lime);
  --tm-bg: var(--tm-lime);
  --tm-fg: var(--tm-charcoal);
  --tm-fg-muted: #41571a;
  --tm-fg-dim: #5c7327;
  --tm-panel: rgba(0,0,0,0.06);
  --tm-panel-2: rgba(0,0,0,0.06);
  --tm-border: rgba(0,0,0,0.18);
  --tm-border-soft: rgba(0,0,0,0.12);
  --tm-accent: var(--tm-charcoal);
  --tm-accent-ink: var(--tm-lime);
  --tm-accent-soft: rgba(0,0,0,0.08);
  color: var(--tm-charcoal);
}
.tm-on-light{
  background: var(--tm-cream);
  --tm-bg: var(--tm-cream);
  --tm-fg: #1a1c20;
  --tm-fg-muted: #595d66;
  /* Was #8a8e96, which is only 3.2:1 on this cream surface — under the 4.5:1
     WCAG AA needs for small text, and .tm-small is exactly what reads this
     token. #6e737c is 4.7:1 and still sits a clear step below --tm-fg-muted
     (6.5:1), so the three-level text hierarchy is preserved. */
  --tm-fg-dim: #6e737c;
  --tm-panel: #fff;
  --tm-panel-2: #f6f1e9;
  --tm-border: #e9e0d2;
  --tm-border-soft: #efe7da;
  /* Darker than --tm-trail (#79b45f). .tm-link paints link text with
     --tm-accent, and the raw trail green is 2.4:1 on cream — the phone-number
     link in the SMS callout is the main call to action and was near-invisible.
     #4e7c35 is 4.9:1 as link text and 4.9:1 behind white --tm-accent-ink. */
  --tm-accent: #4e7c35;
  --tm-accent-ink: #fff;
  --tm-accent-soft: rgba(121,180,95,0.16);
  color: #1a1c20;
}
.tm-on-trail{
  background: linear-gradient(150deg, #2c5641, #15291f);
  --tm-bg: #1d3a2c;
  --tm-fg: #ffffff;
  --tm-fg-muted: #bcd3c4;
  --tm-fg-dim: #91ab9b;
  --tm-panel: rgba(255,255,255,0.06);
  --tm-panel-2: rgba(255,255,255,0.08);
  --tm-border: rgba(255,255,255,0.14);
  --tm-border-soft: rgba(255,255,255,0.10);
  --tm-accent: var(--tm-lime);
  --tm-accent-ink: var(--tm-charcoal);
  --tm-accent-soft: rgba(212,255,63,0.16);
  color: #fff;
}

/* ============================================================================
   14. UTILITIES
   ============================================================================ */
.tm-text-accent{ color: var(--tm-accent) !important; }
.tm-text-muted{ color: var(--tm-fg-muted) !important; }
.tm-text-dim{ color: var(--tm-fg-dim) !important; }
.tm-uppercase{ text-transform: uppercase; letter-spacing: 0.04em; }
.tm-center{ text-align: center; }
.tm-mx-auto{ margin-inline: auto; }
.tm-measure{ max-width: 60ch; }
.tm-stack > * + *{ margin-top: var(--tm-space-4); }
/* Spacing utilities. Kept as a complete 1-6 scale on purpose: the steps that
   were missing (mt-3/5, mb-1/2/3/5/6) were still being used in views, where a
   class that matches no rule fails silently — the "Still calibrating" callout
   on Fitness and Trends ended up flush against the block above and below it
   because both its own tm-mb-5 and the stats row's tm-mb-6 did nothing. */
.tm-mt-0{ margin-top: 0 !important; }
.tm-mt-1{ margin-top: var(--tm-space-1) !important; }
.tm-mt-2{ margin-top: var(--tm-space-2) !important; }
.tm-mt-3{ margin-top: var(--tm-space-3) !important; }
.tm-mt-4{ margin-top: var(--tm-space-4) !important; }
.tm-mt-5{ margin-top: var(--tm-space-5) !important; }
.tm-mt-6{ margin-top: var(--tm-space-6) !important; }
.tm-mb-0{ margin-bottom: 0 !important; }
.tm-mb-1{ margin-bottom: var(--tm-space-1) !important; }
.tm-mb-2{ margin-bottom: var(--tm-space-2) !important; }
.tm-mb-3{ margin-bottom: var(--tm-space-3) !important; }
.tm-mb-4{ margin-bottom: var(--tm-space-4) !important; }
.tm-mb-5{ margin-bottom: var(--tm-space-5) !important; }
.tm-mb-6{ margin-bottom: var(--tm-space-6) !important; }
.tm-flex{ display: flex; }
.tm-items-center{ align-items: center; }
.tm-justify-between{ justify-content: space-between; }
.tm-gap-1{ gap: var(--tm-space-1); }
.tm-gap-2{ gap: var(--tm-space-2); }
.tm-gap-3{ gap: var(--tm-space-3); }
.tm-gap-4{ gap: var(--tm-space-4); }
.tm-wrap{ flex-wrap: wrap; }

/* ============================================================================
   15. WORKOUT TYPE TAGS  (shared by widgets, week strip, calendar)
   ============================================================================ */
.tm-tag{
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--tm-font-display); font-weight: 800; font-size: 10px;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 5px 9px; border-radius: 5px;
  background: var(--tm-surface-2); color: var(--tm-fg-muted);
}
.tm-tag::before{ content:""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.tm-tag--easy{     color: var(--tm-trail-2); }
.tm-tag--workout{  color: var(--tm-lime); }
.tm-tag--long{     color: #e0a64e; }
.tm-tag--rest{     color: var(--tm-fg-faint); }
.tm-tag--race{     color: var(--tm-danger); }
.tm-tag--primary{  color: var(--tm-accent); }
.tm-tag--done{     color: var(--tm-online); }
.tm-tag--today{    color: var(--tm-lime); }
.tm-tag--tomorrow{ color: var(--tm-trail-2); }

/* ============================================================================
   16. WORKOUT WIDGETS  (scheduled + completed)
   ============================================================================ */
.tm-workout{
  background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-lg); padding: var(--tm-space-5);
  display: flex; flex-direction: column; gap: var(--tm-space-4);
}
/* Activity-type glyph leading the title. Sized in em so it tracks the title,
   and kept dim so the workout name still carries the line. Hover darkens it —
   that's where the type-name tooltip is. */
.tm-workout__type{
  font-size: 0.62em; line-height: 1; vertical-align: 0.18em;
  margin-right: 0.5em; color: var(--tm-fg-faint);
  transition: color var(--tm-transition);
}
.tm-workout__date .tm-workout__type{
    font-size: 1.2em;
}
.tm-workout__type:hover{ color: var(--tm-fg-dim); }
.tm-workout--done{ border-color: rgba(63,155,95,0.4); }
/* Much lighter than .tm-callout's --tm-accent-soft (0.14) so today's card
   doesn't read as a second lime block when stacked under "This week's focus". */
.tm-workout--today{
  border-color: rgba(212, 255, 63, 0.4);
  background: linear-gradient(rgba(212, 255, 63, 0.05), rgba(212, 255, 63, 0.05)), var(--tm-panel);
}
.tm-workout__top{ display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.tm-workout__date{
  font-family: var(--tm-font-display); font-weight: 800; text-transform: uppercase;
  letter-spacing: 0.08em; font-size: var(--tm-text-xs); color: var(--tm-fg-dim);
}
.tm-workout__title{
  font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase;
  letter-spacing: -0.02em; font-size: var(--tm-text-xl); color: var(--tm-fg); margin: 3px 0 0;
}
.tm-workout__check{
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  background: var(--tm-online); color: #06210f;
  display: flex; align-items: center; justify-content: center; font-weight: 900; font-size: 15px;
}
/* The check doubles as the undo for a hand-recorded session. Reset the button
   chrome so it is pixel-identical to the span, and grey it on hover so it reads
   as something you can click rather than a badge. */
.tm-workout__check--undo{ border: 0; padding: 0; font: inherit; font-weight: 900; font-size: 15px; cursor: pointer; }
.tm-workout__check--undo:hover,
.tm-workout__check--undo:focus-visible{ background: var(--tm-fg-faint); color: var(--tm-fg); }
.tm-workout__metrics{ display: flex; gap: var(--tm-space-6); flex-wrap: wrap; }
.tm-metric{ display: flex; flex-direction: column; gap: 2px; }
.tm-metric b{ font-family: var(--tm-font-display); font-weight: 900; font-size: var(--tm-text-lg); color: var(--tm-fg); }
.tm-metric span{ font-size: 10px; color: var(--tm-fg-dim); text-transform: uppercase; letter-spacing: 0.07em; }
.tm-workout__desc{ color: var(--tm-fg-muted); font-size: var(--tm-text-sm); line-height: 1.55; margin: 0; }
.tm-workout__actions{ display: flex; gap: var(--tm-space-3); flex-wrap: wrap; }
.tm-workout__note{
  display: flex; gap: 9px; align-items: flex-start;
  background: var(--tm-accent-soft); border-radius: var(--tm-radius-sm);
  padding: 11px 13px; font-size: var(--tm-text-sm); color: var(--tm-fg); line-height: 1.45;
}
.tm-workout__note b{ color: var(--tm-accent); }
.tm-note__time{ font-size: 10px; color: var(--tm-fg-dim); font-weight: 400; margin-top: 3px; }

/* "How did it feel?" 1–10 scale.
   Fixed label column so the first dots of Feeling / Effort line up vertically
   (labels differ in length: "How you felt:" vs "How hard you pushed:"). */
.tm-feel{ display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* Groups the feeling + effort rows as one .tm-workout flex child so they sit
   close together, instead of each inheriting the card's full 16px gap. */
.tm-feel-group{ display: flex; flex-direction: column; gap: 6px; }
.tm-feel__label{
  flex: 0 0 11.5rem;
  width: 11.5rem;
  font-size: var(--tm-text-xs);
  color: var(--tm-fg-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.tm-feel__scale{ display: flex; gap: 4px; flex-shrink: 0; }
/* The unselected dot is an empty slot, so its ring is the only thing that shows
   it exists. --tm-border (#262a31) was 1.2:1 against the card and 1.1:1 against
   the dot's own fill — invisible, so a partly-filled scale read as "nothing
   here" instead of "3 of 10". --tm-fg-dim is 4.5:1 on the card, clearing the
   3:1 WCAG minimum for non-text UI, and being a semantic token it re-maps
   correctly if this ever sits on a light surface. */
.tm-feel__dot{ width: 15px; height: 15px; border-radius: 50%; background: var(--tm-surface-2); border: 1px solid var(--tm-fg-dim); }
.tm-feel__dot--on{ background: var(--tm-accent); border-color: var(--tm-accent); }
.tm-feel__num{ font-family: var(--tm-font-display); font-weight: 900; color: var(--tm-accent); font-size: var(--tm-text-lg); min-width: 2.5rem; }

/* ============================================================================
   17. TRAINING WEEK STRIP
   ============================================================================ */
.tm-week-scroll{ overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tm-week{ display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; min-width: 520px; }
.tm-week__day{
  position: relative;
  background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-md);
  padding: 12px 8px; display: flex; flex-direction: column; align-items: center; gap: 8px;
  text-align: center; min-height: 112px; min-width: 0;
}
/* New comments / completed workouts on this day. Selecting the day clears it. */
.tm-week__count{
  position: absolute; top: 4px; right: 4px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px; background: var(--tm-accent); color: var(--tm-accent-ink);
  font-family: var(--tm-font-display); font-size: 10px; font-weight: 700;
  line-height: 16px; text-align: center;
}
.tm-week__count[hidden]{ display: none; }
/* Previewing a proposal: which days it would touch. Dashed, so a pending day
   never reads as part of the real plan. */
.tm-week__day--pending{ border-style: dashed; border-color: var(--tm-accent); }
.tm-week__pending{
  position: absolute; top: 4px; left: 4px;
  width: 16px; height: 16px; border-radius: 999px;
  background: var(--tm-accent-soft); color: var(--tm-accent);
  font-family: var(--tm-font-display); font-size: 10px; font-weight: 700;
  line-height: 16px; text-align: center;
}
.tm-week__day--today{ border-color: var(--tm-accent); box-shadow: 0 0 0 1px var(--tm-accent); }
.tm-week__dow{ font-family: var(--tm-font-display); font-weight: 800; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--tm-fg-dim); }
.tm-week__dot{ width: 9px; height: 9px; border-radius: 50%; flex: none; }
/* One row carrying which sports the day holds — an icon per distinct type, so
   a run day and a ride day tell themselves apart before the label is read —
   and, on a finished day, the check.
   The check shares this row rather than taking one of its own. As its own flex
   child in the cell's column it cost a row gap plus a line, and because the
   grid rows are equal that height landed on all seven cells the moment a
   single day was done. It stays centred rather than tucked in a corner:
   bottom-right collides with a wrapped kind label on a narrow cell, and the
   two top corners belong to the count and pending badges.
   Everything here is sized to hold ONE line in the ~49px cell the strip's
   520px minimum gives on mobile — wrapping puts that height straight back. */
.tm-week__meta{ display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px; }
.tm-week__icons{ display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; line-height: 1; }
.tm-week__icon{ font-size: 13px; line-height: 1; color: var(--tm-fg-dim); }
.tm-week__check{ color: var(--tm-online); font-weight: 900; font-size: 11px; line-height: 1; }
.tm-week__day--done .tm-week__icon{ color: var(--tm-online); }
/* Three or more sports: at full size the third icon no longer fits. */
.tm-week__icon:first-child:nth-last-child(n+3),
.tm-week__icon:first-child:nth-last-child(n+3) ~ .tm-week__icon{ font-size: 11px; }
.tm-week__icons:has(> :nth-child(3)){ gap: 4px; }
/* A check on the row costs another ~12px, so the icons beside it step down. */
.tm-week__meta:has(.tm-week__check){ gap: 3px; }
.tm-week__meta:has(.tm-week__check) .tm-week__icons{ gap: 4px; }
.tm-week__meta:has(.tm-week__check) .tm-week__icon{ font-size: 11px; }
.tm-week__meta:has(.tm-week__check) .tm-week__icon:first-child:nth-last-child(n+3),
.tm-week__meta:has(.tm-week__check) .tm-week__icon:first-child:nth-last-child(n+3) ~ .tm-week__icon{ font-size: 9px; }
.tm-week__meta:has(.tm-week__check) .tm-week__icons:has(> :nth-child(3)){ gap: 2px; }
/* Activity-type switch in the weekly volume widget. Single-select, and
   aria-pressed carries the whole state — nothing per-type, because the type list
   is admin-editable and a colour-per-key table like .tm-trend-toggle's could
   never cover it. */
.tm-chart__types{ margin: 0 0 var(--tm-space-3); }
.tm-chart__type{
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0;
  background: none; border: 0; border-radius: var(--tm-radius-sm);
  cursor: pointer;
  transition: background var(--tm-transition), color var(--tm-transition);
}
.tm-chart__type:hover .tm-week__icon{ color: var(--tm-fg); }
.tm-chart__type[aria-pressed="true"]{ background: var(--tm-accent-soft); }
.tm-chart__type[aria-pressed="true"] .tm-week__icon{ color: var(--tm-accent); }
.tm-chart__type:focus-visible{ outline: 2px solid var(--tm-accent); outline-offset: 1px; }
/* .tm-week__icon's own shrink rule counts siblings, and wrapping each icon in a
   button makes every icon an only child — so re-express it on the buttons. */
.tm-chart__type:first-child:nth-last-child(n+5),
.tm-chart__type:first-child:nth-last-child(n+5) ~ .tm-chart__type{ width: 20px; height: 20px; }
.tm-chart__type:first-child:nth-last-child(n+5) .tm-week__icon,
.tm-chart__type:first-child:nth-last-child(n+5) ~ .tm-chart__type .tm-week__icon{ font-size: 11px; }
.tm-week__dist{ font-family: var(--tm-font-display); font-weight: 900; font-size: var(--tm-text-base); color: var(--tm-fg); line-height: 1; white-space: nowrap; }
/* "mi" / "min" next to the number. Small and dim so the figure still carries
   the cell — a full-size unit at weight 900 competes with it, and "14.0 min"
   at that size does not fit a 51px cell at the strip's 520px minimum. */
.tm-week__unit{ font-size: 8px; font-weight: 700; color: var(--tm-fg-dim); margin-left: 1px; }
.tm-week__kind{
  font-size: 10px; color: var(--tm-fg-dim); letter-spacing: 0.02em; line-height: 1.3;
  width: 100%; overflow-wrap: anywhere; word-break: break-word;
  text-transform: none; font-weight: 600;
}
/* Strip cells as buttons (week planner + athlete week view) */
button.tm-week__day{
  font: inherit; cursor: pointer;
  transition: border-color var(--tm-transition), background var(--tm-transition);
}
button.tm-week__day:hover:not(:disabled){ border-color: var(--tm-fg-faint); }
button.tm-week__day:disabled{ cursor: default; opacity: 0.55; }
.tm-week__day--done{ border-color: rgba(63,155,95,0.35); }
.tm-week__day--active{ background: var(--tm-panel-2); border-color: var(--tm-fg-muted); }

/* ============================================================================
   18. TRAINING CALENDAR  (month grid)
   ============================================================================ */
.tm-cal{ background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-lg); padding: var(--tm-space-5); }
.tm-cal__head{ display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--tm-space-4); }
.tm-cal__month{ font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase; letter-spacing: -0.02em; font-size: var(--tm-text-lg); }
.tm-cal__nav{ display: flex; gap: 6px; }
.tm-cal__nav button{
  width: 32px; height: 32px; border-radius: var(--tm-radius-sm); cursor: pointer;
  background: var(--tm-surface-2); border: 1px solid var(--tm-border); color: var(--tm-fg-muted);
  font-size: 15px; line-height: 1; transition: var(--tm-transition);
}
.tm-cal__nav button:hover{ color: var(--tm-fg); border-color: var(--tm-fg-faint); }
.tm-cal__grid{ display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.tm-cal__dow{ font-family: var(--tm-font-display); font-weight: 800; font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--tm-fg-faint); text-align: center; padding-bottom: 4px; }
.tm-cal__cell{
  aspect-ratio: 1; border: 1px solid var(--tm-border); border-radius: 8px; padding: 6px;
  display: flex; flex-direction: column; gap: 3px; font-size: 11px; background: var(--tm-bg); position: relative;
}
.tm-cal__cell--muted{ opacity: 0.4; }
.tm-cal__cell--today{ border-color: var(--tm-accent); box-shadow: inset 0 0 0 1px var(--tm-accent); }
.tm-cal__num{ font-family: var(--tm-font-display); font-weight: 700; color: var(--tm-fg); font-size: 11px; }
.tm-cal__dots{ display: flex; gap: 3px; margin-top: auto; flex-wrap: wrap; }
.tm-cal__dots i{ width: 6px; height: 6px; border-radius: 50%; display: block; background: var(--tm-fg-faint); }
.tm-cal__dots i.is-easy{ background: var(--tm-trail-2); }
.tm-cal__dots i.is-workout{ background: var(--tm-lime); }
.tm-cal__dots i.is-long{ background: #e0a64e; }
.tm-cal__dots i.is-race{ background: var(--tm-danger); }

/* ============================================================================
   19. WEEKLY PROGRESS CHART  (CSS bar chart)
   ============================================================================ */
.tm-chart{ background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-lg); padding: var(--tm-space-6); }
.tm-chart__head{ display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: var(--tm-space-5); }
.tm-chart__title{ font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase; letter-spacing: -0.02em; font-size: var(--tm-text-lg); margin: 0; }
.tm-chart__sub{ font-size: var(--tm-text-xs); color: var(--tm-fg-dim); margin-top: 3px; }
.tm-chart__total{ font-family: var(--tm-font-display); font-weight: 900; color: var(--tm-accent); font-size: var(--tm-text-2xl); line-height: 1; text-align: right; }
/* The number is <strong>, the caption under it is <span>. The span rule came
   first and the old weekly-volume markup put the number inside it, which is why
   that headline rendered as a dim 10px caption instead of the accent number. */
.tm-chart__total strong{ font-weight: inherit; }
.tm-chart__total span{ display: block; font-size: 10px; color: var(--tm-fg-dim); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; margin-top: 4px; }
.tm-chart__empty{ font-size: var(--tm-text-xs); color: var(--tm-fg-dim); margin: 0; }
.tm-chart__bars{ display: flex; align-items: flex-end; gap: 12px; }
.tm-bar{ flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.tm-bar__track{ width: 100%; height: 140px; display: flex; align-items: flex-end; justify-content: center; }
.tm-bar__fill{
  width: 100%; max-width: 38px; min-height: 4px; border-radius: 6px 6px 0 0;
  background: linear-gradient(180deg, #2a323c, #222932); /* default = past weeks */
}
.tm-bar--now .tm-bar__fill{ background: linear-gradient(180deg, var(--tm-lime), #a9d62f); }
/* Planned weeks: outline-only bar sized to planned mileage; the fill inside
   grows from the bottom up to the mileage completed so far. */
.tm-bar__outline{
  width: 100%; max-width: 38px; min-height: 4px;
  display: flex; align-items: flex-end; justify-content: center;
  border: 1.5px solid var(--tm-border); border-radius: 6px 6px 0 0;
}
.tm-bar__fill--actual{
  min-height: 0; /* an untouched planned week stays empty (no 4px sliver) */
  border-radius: 5px 5px 0 0;
  background: linear-gradient(180deg, var(--tm-lime), #a9d62f);
}
.tm-bar__label{ font-family: var(--tm-font-display); font-weight: 800; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--tm-fg-dim); }
.tm-bar__val{ font-size: 10px; color: var(--tm-fg-muted); font-weight: 600; }
.tm-bar--now .tm-bar__val{ color: var(--tm-accent); }

/* ============================================================================
   19b. FITNESS CHART  (CTL / ATL / TSB — the PMC line chart)
   ============================================================================ */
:root{ --tm-fatigue: #e0566f; }   /* fatigue/ATL line + headline number */

.tm-fitness-stats{
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--tm-space-4);
}
@media (max-width: 560px){ .tm-fitness-stats{ grid-template-columns: 1fr; } }

.tm-fitness-stat{ display: flex; flex-direction: column; gap: 4px; }
.tm-fitness-stat__num{
  font-family: var(--tm-font-display); font-weight: 900; line-height: 1;
  font-size: var(--tm-text-4xl); color: var(--tm-fg);
}
.tm-fitness-stat__num--fatigue{ color: var(--tm-fatigue); }
.tm-fitness-stat__label{ font-size: var(--tm-text-sm); color: var(--tm-fg-dim); }

.tm-fchart{ width: 100%; position: relative; }
.tm-fchart__svg{ width: 100%; height: auto; display: block; overflow: visible; touch-action: pan-y; }

.tm-fchart__grid{ stroke: var(--tm-border-soft); stroke-width: 1; stroke-dasharray: 2 5; }

.tm-fchart__line{ fill: none; stroke-width: 2.5; vector-effect: non-scaling-stroke;
  stroke-linejoin: round; stroke-linecap: round; }
.tm-fchart__line--ctl{ stroke: var(--tm-fg); }
.tm-fchart__line--atl{ stroke: var(--tm-fatigue); }
.tm-fchart__line--pred{ stroke-dasharray: 3 4; opacity: 0.9; }

/* "Today" divider where solid history meets the dashed projection */
.tm-fchart__today{ stroke: var(--tm-fg-faint); stroke-width: 1; stroke-dasharray: 2 3; vector-effect: non-scaling-stroke; }
.tm-fchart__today-label{ fill: var(--tm-fg-faint); font-size: 9px; font-weight: 800; letter-spacing: 0.1em;
  font-family: var(--tm-font-display); }

.tm-fchart__ylabel{ fill: var(--tm-fg-dim); font-size: 12px; font-family: var(--tm-font-body); }
.tm-fchart__xlabel{ fill: var(--tm-fg-dim); font-size: 12px; font-family: var(--tm-font-body); }

/* Hover/tap crosshair + point markers */
.tm-fchart__cursor-line{ stroke: var(--tm-fg-faint); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tm-fchart__dot{ vector-effect: non-scaling-stroke; stroke: var(--tm-panel); stroke-width: 2; }
.tm-fchart__dot--ctl{ fill: var(--tm-fg); }
.tm-fchart__dot--atl{ fill: var(--tm-fatigue); }

/* Floating value readout */
.tm-fchart-tip{
  position: absolute; z-index: 5; pointer-events: none;
  min-width: 118px; padding: 8px 10px;
  background: var(--tm-panel-2); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md); box-shadow: var(--tm-shadow-md);
  font-size: var(--tm-text-xs); color: var(--tm-fg);
}
.tm-fchart-tip__date{ font-family: var(--tm-font-display); font-weight: 800; font-size: 11px;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--tm-fg-dim); margin-bottom: 5px;
  display: flex; align-items: center; gap: 6px; }
.tm-fchart-tip__tag{ font-size: 9px; font-weight: 800; letter-spacing: 0.06em; color: var(--tm-accent-ink);
  background: var(--tm-accent); border-radius: var(--tm-radius-pill); padding: 1px 6px; }
.tm-fchart-tip__row{ display: flex; align-items: center; gap: 7px; line-height: 1.7; }
.tm-fchart-tip__row b{ margin-left: auto; font-variant-numeric: tabular-nums; }
.tm-fchart-tip__row--form{ margin-top: 3px; padding-top: 4px; border-top: 1px solid var(--tm-border-soft); color: var(--tm-fg-muted); }
.tm-fchart-tip__dot{ width: 9px; height: 3px; border-radius: 2px; flex: none; }
.tm-fchart-tip__dot--ctl{ background: var(--tm-fg); }
.tm-fchart-tip__dot--atl{ background: var(--tm-fatigue); }

.tm-fchart-legend{ display: flex; gap: var(--tm-space-4); flex-wrap: wrap; }
.tm-fchart-legend__item{ display: inline-flex; align-items: center; gap: 7px;
  font-size: var(--tm-text-sm); color: var(--tm-fg-muted); }
.tm-fchart-legend__swatch{ width: 16px; height: 3px; border-radius: 2px; flex: none; }
.tm-fchart-legend__swatch--ctl{ background: var(--tm-fg); }
.tm-fchart-legend__swatch--atl{ background: var(--tm-fatigue); }
.tm-fchart-legend__swatch--pred{
  background: repeating-linear-gradient(90deg, var(--tm-fg-muted) 0 3px, transparent 3px 6px);
}

/* ============================================================================
   19c. TRENDS CHART  (rolling averages — pace/distance/elevation/effort/feeling)
   Reuses the .tm-fchart* shell above; only the five line colors, the metric
   toggles and the value chips are new.
   ============================================================================ */
:root{
  --tm-trend-pace:      #d4ff3f;   /* lime — the signature accent            */
  --tm-trend-distance:  #5fb0e8;   /* blue                                   */
  --tm-trend-elevation: #f0a44a;   /* amber                                  */
  --tm-trend-effort:    #e0566f;   /* shares the fatigue red — "how hard"    */
  /* Violet, deliberately NOT the trail green — Pace and Feeling are the two
     default-on lines, and green-on-lime is unreadable side by side. */
  --tm-trend-feeling:   #b18bf5;
}

/* The 100% line is the baseline every metric is measured against, so it reads
   solid while the other gridlines stay dashed. */
.tm-fchart__grid--base{ stroke: var(--tm-fg-faint); stroke-dasharray: none; opacity: 0.55; }

.tm-fchart__empty{
  display: flex; align-items: center; justify-content: center;
  min-height: 220px; margin: 0; color: var(--tm-fg-dim); font-size: var(--tm-text-sm);
}

.tm-tline--pace{ stroke: var(--tm-trend-pace); }
.tm-tline--distance{ stroke: var(--tm-trend-distance); }
.tm-tline--elevation{ stroke: var(--tm-trend-elevation); }
.tm-tline--effort{ stroke: var(--tm-trend-effort); }
.tm-tline--feeling{ stroke: var(--tm-trend-feeling); }

.tm-tdot--pace{ fill: var(--tm-trend-pace); }
.tm-tdot--distance{ fill: var(--tm-trend-distance); }
.tm-tdot--elevation{ fill: var(--tm-trend-elevation); }
.tm-tdot--effort{ fill: var(--tm-trend-effort); }
.tm-tdot--feeling{ fill: var(--tm-trend-feeling); }

.tm-tdot-key--pace{ background: var(--tm-trend-pace); }
.tm-tdot-key--distance{ background: var(--tm-trend-distance); }
.tm-tdot-key--elevation{ background: var(--tm-trend-elevation); }
.tm-tdot-key--effort{ background: var(--tm-trend-effort); }
.tm-tdot-key--feeling{ background: var(--tm-trend-feeling); }

/* Metric toggles carry their OWN line color rather than the generic lime active
   state — with five lines, "which button drives which line" has to be readable
   at a glance, and a lime active state would collide with Pace's own lime. An
   active toggle lights its swatch and border in the metric color; an inactive
   one greys the swatch and dims down. */
.tm-trend-toggle{
  display: inline-flex; align-items: center; gap: 7px;
  border-color: var(--tm-border); color: var(--tm-fg-dim);
}
.tm-trend-toggle:hover{ background: transparent; color: var(--tm-fg); }
.tm-trend-toggle__swatch{
  width: 12px; height: 3px; border-radius: 2px; flex: none;
  background: var(--tm-fg-faint); transition: background var(--tm-transition);
}
.tm-trend-toggle[aria-pressed="true"]{ color: var(--tm-fg); }

.tm-trend-toggle--pace[aria-pressed="true"]{ border-color: var(--tm-trend-pace); }
.tm-trend-toggle--pace[aria-pressed="true"] .tm-trend-toggle__swatch{ background: var(--tm-trend-pace); }
.tm-trend-toggle--distance[aria-pressed="true"]{ border-color: var(--tm-trend-distance); }
.tm-trend-toggle--distance[aria-pressed="true"] .tm-trend-toggle__swatch{ background: var(--tm-trend-distance); }
.tm-trend-toggle--elevation[aria-pressed="true"]{ border-color: var(--tm-trend-elevation); }
.tm-trend-toggle--elevation[aria-pressed="true"] .tm-trend-toggle__swatch{ background: var(--tm-trend-elevation); }
.tm-trend-toggle--effort[aria-pressed="true"]{ border-color: var(--tm-trend-effort); }
.tm-trend-toggle--effort[aria-pressed="true"] .tm-trend-toggle__swatch{ background: var(--tm-trend-effort); }
.tm-trend-toggle--feeling[aria-pressed="true"]{ border-color: var(--tm-trend-feeling); }
.tm-trend-toggle--feeling[aria-pressed="true"] .tm-trend-toggle__swatch{ background: var(--tm-trend-feeling); }

.tm-trend-toggle[disabled]{ opacity: 0.35; cursor: not-allowed; }
.tm-trend-toggle[disabled]:hover{ transform: none; color: var(--tm-fg-dim); }

/* Latest real value per metric — the chart itself is all percentages. */
.tm-trend-chips{ display: flex; flex-wrap: wrap; gap: var(--tm-space-3); }
.tm-trend-chip{
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 5px 10px; border-radius: var(--tm-radius-pill);
  background: var(--tm-panel-2); border: 1px solid var(--tm-border);
  font-size: var(--tm-text-xs);
}
.tm-trend-chip__label{ color: var(--tm-fg-dim); }
.tm-trend-chip__val{ font-weight: 700; font-variant-numeric: tabular-nums; color: var(--tm-fg); }
.tm-trend-chip--pace .tm-trend-chip__val{ color: var(--tm-trend-pace); }
.tm-trend-chip--distance .tm-trend-chip__val{ color: var(--tm-trend-distance); }
.tm-trend-chip--elevation .tm-trend-chip__val{ color: var(--tm-trend-elevation); }
.tm-trend-chip--effort .tm-trend-chip__val{ color: var(--tm-trend-effort); }
.tm-trend-chip--feeling .tm-trend-chip__val{ color: var(--tm-trend-feeling); }

/* Info "?" popover (Fitness/Fatigue/Form explainer) */
.tm-info{ position: relative; display: inline-flex; }
.tm-info__btn{
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; flex: none; padding: 0; cursor: pointer;
  border: 1.5px solid var(--tm-fg-faint); border-radius: 50%;
  background: none; color: var(--tm-fg-muted);
  font-family: var(--tm-font-display); font-weight: 800; font-size: 12px; line-height: 1;
  transition: border-color var(--tm-transition), color var(--tm-transition);
}
.tm-info__btn:hover{ border-color: var(--tm-accent); color: var(--tm-fg); }
.tm-info__pop{
  display: none; position: absolute; top: calc(100% + 8px); left: 0; z-index: 40;
  width: min(340px, 78vw); padding: var(--tm-space-4);
  background: var(--tm-panel-2); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-lg); box-shadow: var(--tm-shadow-lg);
}
.tm-info:hover .tm-info__pop,
.tm-info.is-open .tm-info__pop{ display: block; }
.tm-info__row{ margin: 0 0 var(--tm-space-3); font-size: var(--tm-text-sm); color: var(--tm-fg-muted); line-height: 1.5; }
.tm-info__row strong{ color: var(--tm-fg); }
.tm-info__note{ margin: 0; padding-top: var(--tm-space-3); border-top: 1px solid var(--tm-border-soft);
  font-size: var(--tm-text-sm); color: var(--tm-fg-muted); line-height: 1.5; }
.tm-info__note strong{ color: var(--tm-fg); }

/* ============================================================================
   20. PRICING CARDS
   ============================================================================ */
.tm-price-grid{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: stretch; }
@media (max-width: 880px){ .tm-price-grid{ grid-template-columns: 1fr; } }
.tm-price{
  position: relative; background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-lg); padding: var(--tm-space-6);
  display: flex; flex-direction: column; gap: var(--tm-space-4);
}
.tm-price--featured{ border-color: var(--tm-accent); box-shadow: 0 0 0 1px var(--tm-accent), var(--tm-shadow-md); }
.tm-price__badge{ position: absolute; top: -11px; left: var(--tm-space-6); }
.tm-price__name{ font-family: var(--tm-font-display); font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; font-size: var(--tm-text-sm); color: var(--tm-fg-dim); }
.tm-price__amount{ font-family: var(--tm-font-display); font-weight: 900; letter-spacing: -0.03em; line-height: 1; font-size: var(--tm-text-4xl); color: var(--tm-fg); }
.tm-price__amount small{ font-size: var(--tm-text-base); color: var(--tm-fg-dim); font-weight: 600; letter-spacing: 0; }
.tm-price__desc{ color: var(--tm-fg-muted); font-size: var(--tm-text-sm); margin: 0; }
.tm-price__features{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.tm-price__features li{ display: flex; gap: 10px; font-size: var(--tm-text-sm); color: var(--tm-fg-muted); line-height: 1.4; }
.tm-price__features li::before{ content: "✓"; color: var(--tm-accent); font-weight: 900; flex: none; }
.tm-price .tm-btn{ margin-top: auto; }

/* ============================================================================
   21. FAQ / ACCORDION  (native <details>, no JS required)
   ============================================================================ */
.tm-accordion{ display: flex; flex-direction: column; gap: 10px; }
.tm-faq{ background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-md); overflow: hidden; }
.tm-faq > summary{
  list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 17px 20px; font-family: var(--tm-font-display); font-weight: 700;
  text-transform: uppercase; letter-spacing: -0.01em; font-size: var(--tm-text-base); color: var(--tm-fg);
}
.tm-faq > summary::-webkit-details-marker{ display: none; }
.tm-faq > summary::after{ content: "+"; font-family: var(--tm-font-display); font-weight: 900; font-size: 22px; line-height: 1; color: var(--tm-accent); transition: transform var(--tm-transition); }
.tm-faq[open] > summary::after{ transform: rotate(45deg); }
.tm-faq__body{ padding: 0 20px 18px; color: var(--tm-fg-muted); font-size: var(--tm-text-sm); line-height: 1.6; }

/* ============================================================================
   22. TESTIMONIALS
   ============================================================================ */
.tm-quote{
  background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-lg);
  padding: var(--tm-space-6); display: flex; flex-direction: column; gap: var(--tm-space-5); height: 100%;
}
.tm-quote__stars{ color: var(--tm-accent); font-size: 14px; letter-spacing: 2px; }
.tm-quote__text{ font-size: var(--tm-text-lg); line-height: 1.5; color: var(--tm-fg); font-weight: 500; margin: 0; }
.tm-quote__person{ display: flex; align-items: center; gap: 12px; margin-top: auto; }
.tm-quote__avatar{
  width: 42px; height: 42px; border-radius: 50%; flex: none; overflow: hidden;
  background: var(--tm-surface-2); display: flex; align-items: center; justify-content: center;
  font-family: var(--tm-font-display); font-weight: 900; color: var(--tm-accent); font-size: 16px;
}
.tm-quote__name{ font-weight: 700; color: var(--tm-fg); font-size: var(--tm-text-sm); }
.tm-quote__role{ font-size: var(--tm-text-xs); color: var(--tm-fg-dim); }

/* ============================================================================
   23. COACH BIO
   ============================================================================ */
.tm-coach{
  background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-lg);
  padding: var(--tm-space-6); display: flex; flex-direction: column; gap: var(--tm-space-4);
}
.tm-coach__head{ display: flex; align-items: center; gap: 16px; }
.tm-coach__avatar{
  width: 64px; height: 64px; border-radius: 50%; flex: none; position: relative; overflow: visible;
  background: linear-gradient(150deg, var(--tm-trail), #2c5641);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--tm-font-display); font-weight: 900; font-size: 24px; color: #fff;
}
.tm-coach__avatar img{ width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.tm-coach__avatar .tm-online{ position: absolute; bottom: 1px; right: 1px; width: 14px; height: 14px; border-radius: 50%; background: var(--tm-online); border: 2px solid var(--tm-panel); }
.tm-coach__name{ font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase; letter-spacing: -0.02em; font-size: var(--tm-text-xl); color: var(--tm-fg); }
.tm-coach__title{ font-size: var(--tm-text-sm); color: var(--tm-accent); font-weight: 600; }
.tm-coach__bio{ color: var(--tm-fg-muted); font-size: var(--tm-text-sm); line-height: 1.6; margin: 0; }
.tm-coach__stats{ display: flex; gap: var(--tm-space-6); padding: var(--tm-space-4) 0; border-top: 1px solid var(--tm-border); border-bottom: 1px solid var(--tm-border); }
.tm-coach__stat{ display: flex; flex-direction: column; gap: 2px; }
.tm-coach__stat b{ font-family: var(--tm-font-display); font-weight: 900; color: var(--tm-fg); font-size: var(--tm-text-lg); line-height: 1; }
.tm-coach__stat span{ font-size: 10px; color: var(--tm-fg-dim); text-transform: uppercase; letter-spacing: 0.06em; }
.tm-coach__tags{ display: flex; flex-wrap: wrap; gap: 8px; }

/* ============================================================================
   24. MOBILE NAV  (CSS-only disclosure via checkbox; no JS required)
   ============================================================================ */
.tm-mobilenav{ position: relative; }
.tm-mobilenav__toggle{ position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.tm-mobilenav__bar{ position: relative; display: flex; align-items: center; justify-content: space-between; padding-block: var(--tm-space-4); border-bottom: 1px solid var(--tm-border-soft); }
.tm-mobilenav__menu{ display: flex; align-items: center; gap: var(--tm-space-5); }
.tm-mobilenav__menu a{
  font-family: var(--tm-font-display); font-weight: 700; font-size: var(--tm-text-xs);
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--tm-fg-muted); text-decoration: none;
  transition: color var(--tm-transition);
}
.tm-mobilenav__menu a:hover{ color: var(--tm-fg); }
.tm-burger{
  display: none; width: 44px; height: 44px; border: 1px solid var(--tm-border); border-radius: var(--tm-radius-sm);
  background: var(--tm-panel); cursor: pointer; align-items: center; justify-content: center; flex-direction: column; gap: 5px;
}
.tm-burger span{ display: block; width: 18px; height: 2px; background: var(--tm-fg); border-radius: 2px; transition: var(--tm-transition); }

@media (max-width: 760px){
  .tm-burger{ display: inline-flex; }
  .tm-mobilenav__menu{
    position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 50;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-md);
    padding: 0 8px; max-height: 0; overflow: hidden; opacity: 0;
    transition: max-height var(--tm-transition), opacity var(--tm-transition), padding var(--tm-transition);
  }
  .tm-mobilenav__menu a{ padding: 13px 14px; border-radius: 8px; font-size: var(--tm-text-sm); }
  .tm-mobilenav__menu a:hover{ background: var(--tm-surface-2); }
  .tm-mobilenav__toggle:checked ~ .tm-mobilenav__bar .tm-mobilenav__menu{ max-height: 360px; opacity: 1; padding: 8px; }
  .tm-mobilenav__toggle:checked ~ .tm-mobilenav__bar .tm-burger span:nth-child(1){ transform: translateY(7px) rotate(45deg); }
  .tm-mobilenav__toggle:checked ~ .tm-mobilenav__bar .tm-burger span:nth-child(2){ opacity: 0; }
  .tm-mobilenav__toggle:checked ~ .tm-mobilenav__bar .tm-burger span:nth-child(3){ transform: translateY(-7px) rotate(-45deg); }
}

/* ============================================================================
   25. PRIMITIVES — linear progress + radial ring (reused by many widgets)
   ============================================================================ */
.tm-progress{ height: 8px; border-radius: 999px; background: var(--tm-surface-2); overflow: hidden; }
.tm-progress--sm{ height: 5px; }
.tm-progress--lg{ height: 12px; }
.tm-progress__fill{ height: 100%; width: 0; border-radius: 999px; background: var(--tm-accent); transition: width .6s cubic-bezier(.4,0,.2,1); }
.tm-progress__fill--warn{ background: #e0a64e; }
.tm-progress__fill--over{ background: var(--tm-danger); }
.tm-progress__fill--trail{ background: var(--tm-trail); }

.tm-ring{
  position: relative; flex: none;
  width: var(--tm-ring-size, 120px); aspect-ratio: 1; border-radius: 50%;
  background: conic-gradient(var(--tm-ring-color, var(--tm-accent)) calc(var(--tm-ring-pct, 0) * 1%), var(--tm-surface-2) 0);
}
.tm-ring::after{ content: ""; position: absolute; inset: var(--tm-ring-tw, 11px); border-radius: 50%; background: var(--tm-panel); }
.tm-ring__inner{ position: absolute; inset: 0; display: grid; place-items: center; text-align: center; line-height: 1; z-index: 1; }
.tm-ring__val{ font-family: var(--tm-font-display); font-weight: 900; font-size: var(--tm-text-2xl); color: var(--tm-fg); }
.tm-ring__sub{ font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--tm-fg-dim); margin-top: 4px; }
.tm-ring--amber{ --tm-ring-color: #e0a64e; }
.tm-ring--red{ --tm-ring-color: var(--tm-danger); }
.tm-ring--trail{ --tm-ring-color: var(--tm-trail); }

/* ============================================================================
   26. WIDGET WRAPPER  (uniform titled panel for dashboard tiles)
   ============================================================================ */
.tm-widget{
  background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-lg);
  padding: var(--tm-space-5); display: flex; flex-direction: column; gap: var(--tm-space-4); height: 100%;
}
.tm-widget__head{ display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.tm-widget__title{ font-family: var(--tm-font-display); font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; font-size: var(--tm-text-sm); color: var(--tm-fg-dim); margin: 0; }
.tm-widget__action{ font-family: var(--tm-font-display); font-weight: 700; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--tm-accent); text-decoration: none; }
.tm-widget__action:hover{ text-decoration: underline; }

/* ============================================================================
   27. STREAK / CONSISTENCY HEATMAP
   ============================================================================ */
.tm-streak__big{ display: flex; align-items: baseline; gap: 10px; }
.tm-streak__big b{ font-family: var(--tm-font-display); font-weight: 900; font-size: var(--tm-text-4xl); color: var(--tm-accent); line-height: 1; }
.tm-streak__big span{ color: var(--tm-fg-muted); font-size: var(--tm-text-sm); }
.tm-streak__flame{ font-size: 22px; line-height: 1; }
.tm-heatmap-scroll{ overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
.tm-heatmap{ display: grid; grid-auto-flow: column; grid-template-rows: repeat(7, 1fr); gap: 4px; }
.tm-heatmap__cell{ width: 14px; height: 14px; border-radius: 3px; background: var(--tm-surface-2); }
.tm-heatmap__cell.is-l1{ background: rgba(212,255,63,.28); }
.tm-heatmap__cell.is-l2{ background: rgba(212,255,63,.50); }
.tm-heatmap__cell.is-l3{ background: rgba(212,255,63,.75); }
.tm-heatmap__cell.is-l4{ background: var(--tm-lime); }
.tm-heatmap-legend{ display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--tm-fg-dim); }
.tm-heatmap-legend i{ width: 11px; height: 11px; border-radius: 3px; display: inline-block; background: var(--tm-surface-2); }

/* ============================================================================
   28. RACE COUNTDOWN
   ============================================================================ */
.tm-countdown{ display: flex; align-items: center; gap: var(--tm-space-5); }
.tm-countdown__info{ display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.tm-countdown__race{ font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase; letter-spacing: -0.02em; font-size: var(--tm-text-lg); color: var(--tm-fg); }
.tm-countdown__date{ font-size: var(--tm-text-sm); color: var(--tm-fg-dim); }
.tm-countdown__week{ margin-top: 6px; }
.tm-ring__val--days{ font-size: var(--tm-text-4xl); color: var(--tm-accent); }

/* ============================================================================
   29. SHOE MILEAGE TRACKER
   ============================================================================ */
.tm-shoe + .tm-shoe{ margin-top: 16px; }
.tm-shoe__top{ display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.tm-shoe__name{ font-weight: 600; color: var(--tm-fg); font-size: var(--tm-text-sm); }
.tm-shoe__mi{ font-family: var(--tm-font-display); font-weight: 800; font-size: var(--tm-text-xs); color: var(--tm-fg-dim); white-space: nowrap; }

/* ============================================================================
   30. PERSONAL BESTS
   ============================================================================ */
.tm-pr-grid{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
@media (max-width: 680px){ .tm-pr-grid{ grid-template-columns: repeat(2, 1fr); } }
.tm-pr{ background: var(--tm-bg); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-md); padding: 14px; display: flex; flex-direction: column; gap: 4px; }
.tm-pr__dist{ font-family: var(--tm-font-display); font-weight: 800; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--tm-fg-dim); }
.tm-pr__time{ font-family: var(--tm-font-display); font-weight: 900; font-size: var(--tm-text-xl); color: var(--tm-fg); line-height: 1; }
.tm-pr__date{ font-size: 11px; color: var(--tm-fg-faint); }

/* ============================================================================
   31. DASHBOARD LAYOUT  (12-col grid + greeting)
   ============================================================================ */
.tm-dash{ display: grid; grid-template-columns: repeat(12, 1fr); gap: 18px; }
.tm-col-3{ grid-column: span 3; } .tm-col-4{ grid-column: span 4; } .tm-col-5{ grid-column: span 5; }
.tm-col-6{ grid-column: span 6; } .tm-col-7{ grid-column: span 7; } .tm-col-8{ grid-column: span 8; }
.tm-col-9{ grid-column: span 9; } .tm-col-12{ grid-column: span 12; }
@media (max-width: 900px){
  .tm-col-3,.tm-col-4,.tm-col-5,.tm-col-6,.tm-col-7,.tm-col-8,.tm-col-9{ grid-column: span 6; }
}
@media (max-width: 560px){
  .tm-col-3,.tm-col-4,.tm-col-5,.tm-col-6,.tm-col-7,.tm-col-8,.tm-col-9{ grid-column: span 12; }
}
.tm-dash__greeting{ display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.tm-dash__hello{ font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase; letter-spacing: -0.025em; font-size: var(--tm-text-3xl); margin: 0; }
.tm-dash__meta{ color: var(--tm-fg-dim); font-size: var(--tm-text-sm); }

/* ============================================================================
   32. ONBOARDING ADDENDUM  (app-specific: questionnaire wizard + checkout)
   ============================================================================ */

/* Wizard steps: fieldsets hidden until active */
.tm-wizard-step[hidden]{ display: none; }
.tm-wizard-step{ border: 0; padding: 0; margin: 0; min-width: 0; }

/* Question block spacing */
.tm-question{ margin-top: var(--tm-space-6); }
.tm-question:first-of-type{ margin-top: var(--tm-space-5); }
.tm-question > .tm-label{ font-size: var(--tm-text-sm); letter-spacing: 0.05em; color: var(--tm-fg); margin-bottom: var(--tm-space-3); }
.tm-question .tm-hint{ font-size: var(--tm-text-sm); color: var(--tm-fg-dim); margin: -6px 0 var(--tm-space-3); }

/* Choice cards: checkbox/radio options styled as selectable chips */
.tm-choices{ display: flex; flex-wrap: wrap; gap: 10px; }
.tm-choice{ position: relative; }
.tm-choice input{ position: absolute; opacity: 0; width: 1px; height: 1px; }
.tm-choice span{
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--tm-font-body); font-weight: 600; font-size: var(--tm-text-sm);
  color: var(--tm-fg-muted); background: var(--tm-panel);
  border: 1px solid var(--tm-border); border-radius: var(--tm-radius-pill);
  padding: 10px 16px; transition: border-color var(--tm-transition), color var(--tm-transition), background var(--tm-transition);
}
.tm-choice span:hover{ border-color: var(--tm-fg-faint); color: var(--tm-fg); }
.tm-choice input:checked + span{
  border-color: var(--tm-accent); color: var(--tm-fg);
  background: var(--tm-accent-soft);
  box-shadow: 0 0 0 1px var(--tm-accent);
}
.tm-choice input:focus-visible + span{ outline: 2px solid var(--tm-accent); outline-offset: 2px; }

/* 0–10 scale as a row of round choices */
.tm-scale{ display: flex; flex-wrap: wrap; gap: 8px; }
.tm-scale .tm-choice span{
  width: 42px; height: 42px; justify-content: center; padding: 0;
  border-radius: 50%; font-family: var(--tm-font-display); font-weight: 800;
}

/* "Other:" inline text input next to a choice */
.tm-choice-other{ display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tm-choice-other .tm-input{ flex: 1 1 220px; padding: 10px 14px; }

/* Wizard footer: back/next buttons + progress */
.tm-wizard-nav{ display: flex; align-items: center; justify-content: space-between; gap: var(--tm-space-4); margin-top: var(--tm-space-7); }
.tm-wizard-count{
  font-family: var(--tm-font-display); font-weight: 800; font-size: var(--tm-text-xs);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--tm-fg-dim);
}

/* Narrow content column for the funnel pages */
.tm-narrow{ max-width: 720px; margin-inline: auto; }
/* Same measure, anchored left. For a working list rather than a page of prose:
   a coach scanning names reads from the left edge, and the centred column left
   them hanging in the middle of the content area. */
.tm-narrow--start{ margin-inline: 0; }

/* Checkout: Stripe Payment Element container */
.tm-payment-element{ margin-top: var(--tm-space-5); min-height: 220px; }
.tm-payment-error{ color: var(--tm-danger); font-size: var(--tm-text-sm); margin-top: var(--tm-space-3); min-height: 1.4em; }

/* Admin hookup form: fields | start preview | checkout preview */
.tm-hookup-form{
  display: grid;
  grid-template-columns: minmax(280px, 1.15fr) minmax(240px, 1fr) minmax(240px, 1fr);
  gap: var(--tm-space-5);
  align-items: start;
}
.tm-hookup-form__preview-pane{
  position: sticky;
  top: var(--tm-space-4);
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  min-width: 0;
}
.tm-hookup-form__note{
  grid-column: 1 / -1;
}
/* Form on top, two previews side-by-side below */
@media (max-width: 1200px){
  .tm-hookup-form{
    grid-template-columns: 1fr 1fr;
  }
  .tm-hookup-form__fields{
    grid-column: 1 / -1;
  }
}
@media (max-width: 720px){
  .tm-hookup-form{
    grid-template-columns: 1fr;
  }
  .tm-hookup-form__fields,
  .tm-hookup-form__preview-pane{
    grid-column: auto;
    position: static;
    max-height: none;
  }
}

/* Admin hookup show: details | two preview panes */
.tm-hookup-show{
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(0, 1.4fr);
  gap: var(--tm-space-6);
  align-items: start;
}
.tm-hookup-show__previews{
  position: sticky;
  top: var(--tm-space-4);
  min-width: 0;
}
.tm-hookup-previews{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--tm-space-5);
  align-items: start;
}
.tm-hookup-show__previews .tm-hookup-form__preview-pane{
  position: static;
  max-height: none;
  overflow: visible;
}
@media (max-width: 1100px){
  .tm-hookup-show{
    grid-template-columns: 1fr;
  }
  .tm-hookup-show__previews{
    position: static;
  }
}
@media (max-width: 720px){
  .tm-hookup-previews{
    grid-template-columns: 1fr;
  }
}
.tm-hookup-preview{
  border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-lg);
  background: var(--tm-panel);
  overflow: hidden;
}
.tm-hookup-preview__chrome{
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 12px;
  background: var(--tm-panel-2);
  border-bottom: 1px solid var(--tm-border);
}
.tm-hookup-preview__dot{
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--tm-fg-faint);
}
.tm-hookup-preview__url{
  margin-left: 8px;
  font-size: var(--tm-text-xs);
  color: var(--tm-fg-dim);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.tm-hookup-preview__frame{
  padding: var(--tm-space-5);
  background: var(--tm-bg, var(--tm-panel));
}
.tm-hookup-preview__stripe{
  border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--tm-panel-2);
}
.tm-hookup-preview__stripe-row{
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: var(--tm-text-sm);
  color: var(--tm-fg-dim);
}
.tm-hookup-preview__fake{
  color: var(--tm-fg-faint);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

/* Flash message variant */
.tm-callout--danger{ background: rgba(255,122,122,0.12); border-left-color: var(--tm-danger); }

/* Terms checkboxes (plain row, not chips) */
.tm-check-row{ display: flex; align-items: flex-start; gap: 10px; margin-top: var(--tm-space-3); font-size: var(--tm-text-sm); color: var(--tm-fg-muted); }
.tm-check-row input{ width: 18px; height: 18px; margin-top: 2px; accent-color: var(--tm-lime); flex: none; }
.tm-check-row--consent{
  margin-top: var(--tm-space-4); padding: var(--tm-space-4);
  background: var(--tm-panel); border: 2px solid var(--tm-accent);
  border-radius: var(--tm-radius-md);
}
.tm-check-row--consent span{ color: var(--tm-fg-muted); line-height: 1.55; font-size: var(--tm-text-sm); }
.tm-sms-consent .tm-hint{ max-width: 40rem; }
.tm-sms-consent__box{
  max-width: 40rem; padding: var(--tm-space-4);
  background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md);
}
.tm-sms-consent__lead{
  margin: 0 0 var(--tm-space-3); font-size: var(--tm-text-sm);
  color: var(--tm-fg-muted); line-height: 1.55;
}
.tm-sms-consent__list{
  margin: 0; padding-left: 1.2rem; font-size: var(--tm-text-sm);
  color: var(--tm-fg-muted); line-height: 1.55;
}
.tm-sms-consent__list li{ margin: 0.4em 0; }

/* ============================================================================
   33. HOMEPAGE — hero grid, phone mockup, slash marquee, feature cards
   (ported from the Cadence site mock, adapted to tm- tokens)
   ============================================================================ */

/* Two-column hero: copy left, phone right */
.tm-hero-grid{ display: grid; grid-template-columns: 1.08fr .92fr; gap: 48px; align-items: center; }
@media (max-width: 940px){ .tm-hero-grid{ grid-template-columns: 1fr; gap: 44px; } }

/* Floating phone mockup with coach chat */
.tm-phone{ width: 308px; background: #000; border-radius: 44px; padding: 11px;
  box-shadow: 0 30px 70px rgba(0,0,0,.5); animation: tm-floaty 6s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce){ .tm-phone{ animation: none; } }
.tm-phone__screen{ background: var(--tm-cream); border-radius: 34px; overflow: hidden; height: 600px; display: flex; flex-direction: column; }
.tm-phone__top{ display: flex; align-items: center; gap: 11px; padding: 18px 18px 14px; border-bottom: 1px solid #f0e8dc; }
.tm-phone__av{ width: 40px; height: 40px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--tm-font-display); font-weight: 900; font-size: 17px;
  background: var(--tm-lime); color: var(--tm-charcoal); }
.tm-phone__name{ font-weight: 700; font-size: 15px; color: #231f1a; font-family: var(--tm-font-body); }
.tm-phone__status{ font-size: 12px; color: var(--tm-online); display: flex; align-items: center; gap: 5px; }
.tm-phone__status .d{ width: 6px; height: 6px; border-radius: 50%; background: var(--tm-online); }
.tm-phone__body{ flex: 1; padding: 18px 16px; display: flex; flex-direction: column; gap: 11px;
  background: #fbf7f0; overflow: hidden; font-family: var(--tm-font-body); }
.tm-phone .tm-bubble{ font-size: 13.5px; max-width: 84%; }
.tm-typing{ align-self: flex-start; background: #fff; border: 1px solid #efe6da; padding: 13px 15px; border-radius: 16px; display: flex; gap: 5px; }
.tm-typing span{ width: 7px; height: 7px; border-radius: 50%; background: #c8bfb2; animation: tm-blink 1.3s infinite; }
.tm-typing span:nth-child(2){ animation-delay: .2s; } .tm-typing span:nth-child(3){ animation-delay: .4s; }
.tm-phone__input{ padding: 13px 16px; border-top: 1px solid #f0e8dc; display: flex; align-items: center; gap: 10px; }
.tm-phone__input .field{ flex: 1; background: #f2ebe0; border-radius: 999px; height: 34px; }
.tm-phone__input .send{ width: 34px; height: 34px; border-radius: 50%; background: var(--tm-charcoal); }

/* Slash-separated marquee variant (dimmed text, lime slashes) */
.tm-marquee--slash .tm-marquee__track{ animation-duration: 22s; gap: 0; }
.tm-marquee--slash .tm-marquee__track span{ font-weight: 800; font-size: 30px; letter-spacing: -0.01em; color: #2b3038; }
.tm-marquee--slash .tm-marquee__track span::after{ content: none; }
.tm-marquee--slash .sl{ color: var(--tm-accent); }

/* Feature cards: icon tile + title + blurb, 4-up */
.tm-feat{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
@media (max-width: 880px){ .tm-feat{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px){ .tm-feat{ grid-template-columns: 1fr; } }
.tm-fcard{ background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: 14px; padding: 26px 24px; }
.tm-fcard .tm-fi{ width: 42px; height: 42px; border-radius: 11px; background: var(--tm-accent-soft); color: var(--tm-accent);
  display: flex; align-items: center; justify-content: center; }
.tm-fcard h4{ font-family: var(--tm-font-display); font-weight: 800; font-size: 17px; margin: 16px 0 7px; color: var(--tm-fg); }
.tm-fcard p{ margin: 0; color: var(--tm-fg-muted); font-size: 14px; line-height: 1.55; font-weight: 500; }

@keyframes tm-blink{ 0%, 60%, 100%{ opacity: .25; } 30%{ opacity: 1; } }
@keyframes tm-floaty{ 0%, 100%{ transform: translateY(0); } 50%{ transform: translateY(-10px); } }

/* ============================================================================
   34. ATHLETE DASHBOARD ADDENDUM  (training page, shared move/chat partials)
   ============================================================================ */

/* Nav avatar (athlete/coach layouts) */
.tm-nav__avatar{ width: 34px; height: 34px; border-radius: 50%; object-fit: cover; display: block; }

/* Force the 2-col dashboard grid to a single column on small screens —
   the existing 900px breakpoint only halves span-8/span-4 to span-6. */
@media (max-width: 640px){ .tm-col-8, .tm-col-4{ grid-column: span 12; } }

/* Chat composer (real input, not the phone-mockup's decorative .field/.send) */
/* align-items keeps Send the height of the button rather than stretching it to
   the composer's full height — the input is several rows tall now. */
.tm-chat__composer{ display: flex; align-items: flex-end; gap: 8px; padding: 12px; border-top: 1px solid #f0e8dc; background: var(--tm-cream); }
.tm-chat__input{
  flex: 1; min-width: 0; font-family: var(--tm-font-body); font-size: 14px; color: #231f1a;
  background: #fff; border: 1px solid #e7ddce; border-radius: var(--tm-radius-md); padding: 11px 13px;
  /* Starts at one row and grows with what is typed (lib/autosize). An explicit
     line-height is what makes that measurable — a textarea's UA styles leave it
     `normal`, which has no numeric value to compute a row from. overflow starts
     hidden so a single-row box has no scrollbar; autosize turns it back on once
     the content passes the cap. */
  line-height: 1.45;
  overflow-y: hidden;
}
.tm-chat__input::placeholder{ color: #b8ad9c; }
.tm-chat__input:focus{ outline: none; border-color: var(--tm-trail); box-shadow: 0 0 0 3px rgba(121,180,95,.18); }
.tm-chat__send{
  flex: none; border: 0; cursor: pointer; border-radius: var(--tm-radius-md); padding: 0 16px;
  min-height: 42px;
  background: var(--tm-charcoal); color: var(--tm-lime); font-family: var(--tm-font-display);
  font-weight: 800; font-size: 13px; text-transform: uppercase;
}
.tm-chat--fill{ display: flex; flex-direction: column; max-height: 520px; }
.tm-chat--fill .tm-chat__body{ flex: 1 1 auto; overflow-y: auto; min-height: 0; }
/* .list-group.messages is a legacy class pair some AJAX responses select by
   name (messages/create.js.erb) — kept as the actual flex container so new
   messages can be prepended without any JS changes. */
.tm-chat__body .list-group.messages, .moves-comments .messages{ display: flex; flex-direction: column; gap: 9px; }

/* Small ghost icon-button used for the "past activity" chevron toggle and
   the coach-only edit-move pencil (kept minimal — icon supplied inline as SVG) */
.tm-icon-btn{
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: none; border: 1px solid var(--tm-border); border-radius: var(--tm-radius-pill);
  color: var(--tm-fg-muted); font-family: var(--tm-font-display); font-weight: 700;
  font-size: var(--tm-text-xs); letter-spacing: 0.05em; text-transform: uppercase;
  text-decoration: none;
  padding: 8px 16px; cursor: pointer; transition: border-color var(--tm-transition), color var(--tm-transition);
}
.tm-icon-btn:hover{ border-color: var(--tm-fg-faint); color: var(--tm-fg); }
.tm-icon-btn svg{ width: 14px; height: 14px; }
.tm-icon-btn--plain{ border: 0; padding: 4px; color: var(--tm-fg-dim); }
.tm-icon-btn--unread{ border-color: var(--tm-accent); color: var(--tm-fg); background: var(--tm-accent-soft); }

/* ---- Week planner header --------------------------------------------------
   The dates and the week controls share one row. On a phone "This week" used to
   grow until it sat on top of the arrows, so here the arrows are fixed at a real
   tap target and the label is the piece that gives way. */
.tm-weeknav{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--tm-space-3);
}
.tm-weeknav__title{ margin: 0; min-width: 0; }
/* "· This Week" is context, not the heading — smaller, and first to wrap. */
.tm-weeknav__desc{
  color: var(--tm-fg-dim); font-size: var(--tm-text-sm);
  font-weight: 600; letter-spacing: 0;
}
.tm-weeknav__desc::before{ content: " · "; }
.tm-weeknav__controls{ display: flex; align-items: center; gap: var(--tm-space-2); flex: none; }
/* 44px: the smallest target a thumb hits reliably. The old arrows were 22px. */
.tm-weeknav__arrow{
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: none;
  border: 1px solid var(--tm-border); border-radius: var(--tm-radius-pill);
  color: var(--tm-fg); text-decoration: none;
  /* Button chrome reset, same as .tm-icon-btn. The coach's arrows are <a>, the
     athlete's are <button> — without this the browser paints its own ButtonFace
     background and the chevron disappears into a white disc. */
  background: none; padding: 0; font: inherit; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  transition: border-color var(--tm-transition), color var(--tm-transition),
              background var(--tm-transition);
}
.tm-weeknav__arrow svg{ width: 22px; height: 22px; }
.tm-weeknav__arrow:hover{ border-color: var(--tm-accent); color: var(--tm-accent); }
.tm-weeknav__arrow:active{ background: var(--tm-accent-soft); }
/* Only the athlete's view can run out of weeks — its arrows page through a
   fixed set already on the page, where the coach's are links to any week. */
.tm-weeknav__arrow:disabled{ opacity: 0.3; cursor: default; }
.tm-weeknav__arrow:disabled:hover{ border-color: var(--tm-border); color: var(--tm-fg); }

@media (max-width: 600px){
  /* The date range is the heading; the week's position is a subtitle under it. */
  .tm-weeknav__desc{ display: block; font-size: var(--tm-text-xs); }
  .tm-weeknav__desc::before{ content: none; }
  .tm-weeknav__today{ padding-left: var(--tm-space-3); padding-right: var(--tm-space-3); }
}

/* Where window.showAlert renders. Fixed, so a failure is seen wherever the page
   happens to be scrolled — the old helper wrote into a container that usually
   was not on the page at all. The server's inline flash is separate. */
.tm-toast-region{
  position: fixed; top: 16px; left: 50%; transform: translateX(-50%);
  z-index: 1080; width: max-content; max-width: min(520px, calc(100vw - 32px));
}
.tm-toast{
  display: flex; align-items: flex-start; gap: var(--tm-space-3);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}
.tm-toast__close{
  background: none; border: 0; padding: 0; margin-left: auto;
  color: inherit; font-size: 18px; line-height: 1; cursor: pointer; opacity: 0.7;
}
.tm-toast__close:hover{ opacity: 1; }

/* Unread notification badge (chip with a dot, used on move cards) */
/* ---- Bootstrap-JS-driven modal shell, restyled (JS/markup untouched) ----
   Bootstrap toggles .modal.in and injects a sibling .modal-backdrop.in — we
   only restyle the visual layer, the show/hide behavior stays as-is. */
.modal-backdrop{
  position: fixed; inset: 0; z-index: 1040; background: var(--tm-charcoal); opacity: 0;
  transition: opacity var(--tm-transition);
}
.modal-backdrop.in{ opacity: 0.6; }
.modal{ position: fixed; inset: 0; z-index: 1050; display: none; overflow-y: auto; }
.modal.in{ display: block; }
.modal-dialog{ max-width: 520px; margin: 8vh auto; padding: 0 var(--tm-space-4); }
.modal-dialog.modal-sm{ max-width: 400px; }
.modal-content{
  background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-lg);
  box-shadow: 0 30px 70px rgba(0,0,0,.35); overflow: hidden;
}
.modal-header{ display: flex; align-items: center; justify-content: space-between; padding: var(--tm-space-5) var(--tm-space-5) var(--tm-space-4); border-bottom: 1px solid var(--tm-border-soft); }
.modal-title{ font-family: var(--tm-font-display); font-weight: 800; font-size: var(--tm-text-lg); color: var(--tm-fg); margin: 0; }
.modal-body{ padding: var(--tm-space-5); }
.modal-footer{ display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: var(--tm-space-4) var(--tm-space-5) var(--tm-space-5); }
.modal-footer .pull-left{ margin-right: auto; }
.close{ background: none; border: 0; color: var(--tm-fg-dim); font-size: 22px; line-height: 1; cursor: pointer; padding: 0; }
.close:hover{ color: var(--tm-fg); }

/* Form controls used inside the modals above (move edit, note edit, dismiss dialog) */
.form-group{ margin-bottom: var(--tm-space-4); }
.control-label{ display: block; font-size: var(--tm-text-sm); color: var(--tm-fg-muted); margin-bottom: var(--tm-space-2); font-weight: 600; }
.form-control{
  width: 100%; font-family: var(--tm-font-body); font-size: 14px; color: var(--tm-fg);
  background: var(--tm-panel-2); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-md);
  padding: 10px 13px; transition: border-color var(--tm-transition);
}
.form-control:focus{ outline: none; border-color: var(--tm-accent); }
#error_explanation{ background: rgba(255,122,122,0.12); border-left: 3px solid var(--tm-danger); border-radius: var(--tm-radius-sm); padding: var(--tm-space-3) var(--tm-space-4); margin-bottom: var(--tm-space-4); color: var(--tm-fg); }
#error_explanation h2{ font-size: var(--tm-text-sm); font-weight: 700; margin: 0 0 6px; }
#error_explanation ul{ margin: 0; padding-left: 18px; }

/* Clickable .tm-feel__dot (move feedback: feeling / effort). Dots are plain
   <button> elements so the browser default needs resetting; fill state is
   still driven by the .tm-feel__dot--on modifier defined above.

   Scoped to button. Coach view renders the same dots as static <span>s, and
   unscoped these rules gave those a pointer cursor and a grow-on-hover — an
   affordance for something that does nothing when clicked. */
button.tm-feel__dot{
  padding: 0; cursor: pointer;
  transition: background var(--tm-transition), border-color var(--tm-transition),
              transform var(--tm-transition), opacity var(--tm-transition);
}
button.tm-feel__dot:hover{ transform: scale(1.15); }
button.tm-feel__dot:focus-visible{ outline: 2px solid var(--tm-accent); outline-offset: 2px; }

/* Hover preview. Until you actually click one, a row of empty rings looks like
   a readout rather than something you can set — this is what tells you it is a
   control. Hovering the 7th slot paints 1-7 in a translucent accent, so the
   result of the click is visible before committing to it.

   While previewing, the whole scale is neutralised first so that hovering
   *below* the saved value reads as a downgrade (saved 7, hover 3 -> slots 4-7
   go empty) instead of leaving stale lime dots above the cursor. */
.tm-feel__scale.is-previewing .tm-feel__dot{
  background: var(--tm-surface-2); border-color: var(--tm-fg-dim);
}
.tm-feel__scale.is-previewing .tm-feel__dot--preview{
  background: var(--tm-accent); border-color: var(--tm-accent); opacity: 0.55;
}

/* Buttons used inside those same modals (kept as Bootstrap class names) */
.btn{
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-family: var(--tm-font-display); font-weight: 700; font-size: var(--tm-text-sm);
  border-radius: var(--tm-radius-sm); border: 1.5px solid transparent; padding: 10px 18px;
  cursor: pointer; text-transform: uppercase; letter-spacing: 0.02em; transition: all var(--tm-transition);
}
.btn-default{ background: var(--tm-panel-2); color: var(--tm-fg); border-color: var(--tm-border); }
.btn-default:hover{ border-color: var(--tm-fg-faint); }
.btn-success{ background: var(--tm-accent); color: var(--tm-accent-ink); }
.btn-success:hover{ background: var(--tm-accent-press); }
.btn-primary{ background: var(--tm-charcoal); color: var(--tm-lime); }
.btn-link{ background: none; border: 0; color: var(--tm-accent); text-transform: none; letter-spacing: normal; padding: 0; }

/* Training dashboard: .tm-dash is a grid, so its default align-items:stretch
   makes the right column match the ever-growing (infinite-scroll) left
   column's height — which in turn stretches any height:100% widget inside it
   to match. align-self:start lets it size to its own content instead, and
   position:sticky keeps the chat/chart in view while only the left column
   scrolls past. */
.tm-dash__side--sticky{ align-self: start; position: sticky; top: var(--tm-space-5); }
.tm-widget--auto{ height: auto; }

/* ============================================================================
   35. COACH PLANNING ADDENDUM  (athlete list, athlete show, weeks editor)
   ============================================================================ */

/* Responsive pair for views that render two variants of the same block
   (desktop via layout, mobile inline) instead of one CSS-only responsive one. */
@media (max-width: 760px){ .tm-hide-mobile{ display: none !important; } }
@media (min-width: 761px){ .tm-show-mobile-only{ display: none !important; } }

/* Coach's athlete list sidebar */
.tm-athlete-list{ display: flex; flex-direction: column; gap: 4px; }
.tm-athlete-list__item{
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: var(--tm-radius-md);
  color: var(--tm-fg-muted); text-decoration: none; font-size: var(--tm-text-sm);
  transition: background var(--tm-transition), color var(--tm-transition);
}
.tm-athlete-list__item:hover{ background: var(--tm-panel-2); color: var(--tm-fg); text-decoration: none; }
.tm-athlete-list__item--active{ background: var(--tm-accent-soft); color: var(--tm-fg); font-weight: 700; }
.tm-athlete-list__avatar{ width: 36px; height: 36px; border-radius: 50%; object-fit: cover; flex: none; }
.tm-athlete-list__name{ flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tm-athlete-list__avatar-wrap{ position: relative; flex: none; display: inline-flex; }
/* Over the top-left corner of the photo, where it reads as belonging to that
   athlete. At the end of the row it was stranded halfway across the page. */
.tm-athlete-list__badge{
  position: absolute; top: -4px; left: -6px;
  min-width: 18px; padding: 1px 5px; line-height: 1.4;
  /* A ring in the page colour lifts it off the photo underneath. */
  box-shadow: 0 0 0 2px var(--tm-bg);
}
/* The badge is hidden by attribute when the count is zero, and `position` alone
   wouldn't stop an empty pill rendering — this keeps `hidden` winning. */
.tm-athlete-list__badge[hidden]{ display: none; }

/* Bootstrap modal size variant (AI coach modal) */
.modal-dialog.modal-lg{ max-width: 720px; }

/* Day-of-week tab switcher (weeks/_form.html.erb). Bootstrap's tab.js drives
   show/hide via these exact class names — only the visual layer is new here,
   styled like the onboarding questionnaire's pill choices. Since this layout
   no longer loads Bootstrap's CSS, the base show/hide behavior (normally
   bundled with it) is redefined explicitly below. */
.training-days .nav-tabs{
  display: flex; flex-wrap: wrap; gap: 8px; list-style: none;
  padding: 0; margin: 0 0 var(--tm-space-4); border: 0;
}
.training-days .nav-tabs li{ display: block; }
.training-days .nav-tabs li a{
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--tm-font-display); font-weight: 700; font-size: var(--tm-text-sm);
  color: var(--tm-fg-muted); background: var(--tm-panel);
  border: 1px solid var(--tm-border); border-radius: var(--tm-radius-pill);
  padding: 8px 16px; text-decoration: none; cursor: pointer;
  transition: border-color var(--tm-transition), color var(--tm-transition), background var(--tm-transition);
}
.training-days .nav-tabs li a:hover{ border-color: var(--tm-fg-faint); color: var(--tm-fg); text-decoration: none; }
.training-days .nav-tabs li.active a{
  border-color: var(--tm-accent); color: var(--tm-fg); background: var(--tm-accent-soft);
  box-shadow: 0 0 0 1px var(--tm-accent);
}
.training-days .tab-content{ position: relative; }
.training-days .tab-pane{ display: none; }
.training-days .tab-pane.active{ display: block; }

/* Template-select modal's clickable list (weeks/_form.html.erb) */
.list-group.templates{ display: flex; flex-direction: column; gap: 6px; list-style: none; padding: 0; margin: 0; }
.list-group.templates .list-group-item{
  display: block; padding: 10px 14px; border-radius: var(--tm-radius-md);
  border: 1px solid var(--tm-border); color: var(--tm-fg); text-decoration: none;
  transition: border-color var(--tm-transition), background var(--tm-transition);
}
.list-group.templates .list-group-item:hover{ border-color: var(--tm-accent); background: var(--tm-accent-soft); text-decoration: none; }

/* ---- Coach-to-coach thread (fourth column) ------------------------------- */
/* Sits between the sidebar and the main panel. The sidebar is force-collapsed
   while this is open (NavHelper#sidebar_collapsed?), which is where its width
   comes from. */
.tm-dm{
  position: sticky; top: 0;
  height: 100dvh;
  display: flex; flex-direction: column; min-width: 0;
  background: var(--tm-panel);
  border-right: 1px solid var(--tm-border-soft);
}
.tm-dm__avatar{ width: 34px; height: 34px; border-radius: 50%; object-fit: cover; flex: none; }
.tm-dm__intro{
  margin: 0 0 var(--tm-space-4);
  padding: 10px 12px; border-radius: var(--tm-radius-md);
  background: var(--tm-surface-2); color: var(--tm-fg-dim);
  font-size: var(--tm-text-xs); line-height: 1.5;
}
.tm-dm__typing{
  margin: 0; padding: 4px 14px 8px;
  font-size: var(--tm-text-xs); color: var(--tm-fg-dim); font-style: italic;
}
/* Trouble belongs to the conversation, not to a page-level flash — the coach
   pages have no .flash container, so window.showAlert would say it to nobody. */
.tm-dm__error{
  margin: 0; padding: 4px 14px 8px;
  font-size: var(--tm-text-xs); color: var(--tm-danger);
}
/* Mini tag for the PRIMARY marker in the sidebar list — the full .tm-tag is
   too heavy next to a nav label. */
.tm-tag--mini{
  padding: 2px 6px; font-size: 9px; letter-spacing: 0.06em; margin-left: auto;
}
.tm-tag--mini::before{ display: none; }
.tm-shell[data-collapsed] .tm-tag--mini{ display: none; }
.tm-sidebar__group--sub{ padding-top: var(--tm-space-2); }

/* Composer replacement for coaches who may read a thread but not write to it. */
.tm-chat__readonly{
  margin: 0; padding: 12px 14px;
  border-top: 1px solid var(--tm-border-soft);
  font-size: var(--tm-text-xs); color: var(--tm-fg-dim); text-align: center;
}
/* Coach assignment list (admin/athletes/_coaches). Row actions stay hidden
   until hover or keyboard focus so the list reads as names, not buttons. */
.tm-assign{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.tm-assign__row{
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--tm-radius-md);
  transition: background var(--tm-transition);
}
.tm-assign__row:hover{ background: var(--tm-panel-2); }
.tm-assign__avatar{ width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex: none; }
.tm-assign__name{ font-size: var(--tm-text-sm); color: var(--tm-fg); }
.tm-assign__actions{
  margin-left: auto; display: flex; gap: 6px; align-items: center;
  opacity: 0; transition: opacity var(--tm-transition);
}
.tm-assign__row:hover .tm-assign__actions,
.tm-assign__actions:focus-within{ opacity: 1; }
/* Touch and reduced-motion users never get a hover, so don't hide anything. */
@media (hover: none){ .tm-assign__actions{ opacity: 1; } }

/* "My athletes" nav dropdown (coach nav). Bootstrap's dropdown.js toggles
   .open on the .dropdown wrapper — only the visual layer is new here. */
.dropdown{ position: relative; }
.dropdown-toggle{ display: inline-flex; align-items: center; gap: 4px; cursor: pointer; white-space: nowrap; }
.tm-caret{ width: 12px; height: 12px; transition: transform var(--tm-transition); }
.dropdown.open .tm-caret{ transform: rotate(180deg); }
.dropdown-menu{
  display: none; position: absolute; top: 100%; right: 0; margin-top: 10px; z-index: 1000;
  min-width: 320px; max-height: 420px; overflow-y: auto;
  background: var(--tm-panel); border: 1px solid var(--tm-border); border-radius: var(--tm-radius-lg);
  padding: var(--tm-space-3); box-shadow: 0 20px 40px rgba(0,0,0,.35);
}
.dropdown.open .dropdown-menu{ display: block; }

/* Plain menu items inside a .dropdown-menu (e.g. the "AI Assist" actions) */
.tm-menu-item{
  display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: 8px 10px; border-radius: var(--tm-radius-sm);
  color: var(--tm-fg-muted); font-size: var(--tm-text-sm); cursor: pointer;
  transition: background var(--tm-transition), color var(--tm-transition);
}
.tm-menu-item:hover{ background: var(--tm-panel-2); color: var(--tm-fg); }

/* Move activity-type picker (shared/_move_type_picker): icon-only toggle that
   opens the type list. Sized to line up with the summary field beside it. */
.tm-type-picker__btn{
  width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--tm-surface-2); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md); color: var(--tm-fg-muted);
  font-size: 16px; cursor: pointer;
  transition: border-color var(--tm-transition), color var(--tm-transition);
}
.tm-type-picker__btn:hover{ border-color: var(--tm-accent); color: var(--tm-fg); }
.tm-type-menu{ min-width: 200px; left: 0; right: auto; }
.tm-type-menu__item{ display: flex; align-items: center; gap: 10px; }
.tm-type-menu__item i{ width: 18px; text-align: center; color: var(--tm-fg-dim); }
.tm-type-menu__item--on{ background: var(--tm-accent-soft); color: var(--tm-fg); }
.tm-type-menu__item--on i{ color: var(--tm-accent); }

/* "Common prompts" in a coach -> AI coach thread. Two things have to be undone
   from .dropdown-menu above: it opens at top:100%, but this toggle sits at the
   bottom of a 100dvh sticky column (.tm-dm) so the menu would open off the
   bottom of the viewport; and its 320px min-width is the entire --tm-dm-w
   column. */
.tm-dm__prompts{
  /* .tm-dm .tm-chat is a flex column and every sibling that must keep its height
     says so — without this the control squashes on a long thread. */
  flex: none;
  padding: 0 12px 8px;
}
.tm-prompt-menu{
  top: auto; bottom: 100%; margin-top: 0; margin-bottom: 8px;
  left: 0; right: 0; min-width: 0;
  max-height: min(420px, 50dvh);
  /* .dropdown-menu casts its shadow downward, which reads wrong opening up. */
  box-shadow: 0 -12px 32px rgba(0,0,0,.35);
}
/* Prompt text is prose, and wraps rather than being clipped to one line. */
.tm-prompt-menu__item{ white-space: normal; line-height: 1.35; }
/* The caret points up when the menu is shut, so the open flip is inverted. */
.tm-dm__prompts .tm-caret{ transform: rotate(180deg); }
.tm-dm__prompts.dropdown.open .tm-caret{ transform: rotate(0deg); }

/* Admin icon chooser (admin/move_types/_form) */
.tm-icon-grid{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px;
}
.tm-icon-grid__item{
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 6px; cursor: pointer;
  background: var(--tm-surface-2); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md); color: var(--tm-fg-muted); font-size: 16px;
  transition: border-color var(--tm-transition), color var(--tm-transition), background var(--tm-transition);
}
.tm-icon-grid__item span{ font-size: 10px; color: var(--tm-fg-dim); overflow-wrap: anywhere; line-height: 1.2; }
.tm-icon-grid__item:hover{ border-color: var(--tm-fg-faint); color: var(--tm-fg); }
.tm-icon-grid__item--on{ border-color: var(--tm-accent); background: var(--tm-accent-soft); color: var(--tm-accent); }
.tm-icon-grid__item--on span{ color: var(--tm-fg); }

/* Admin "Send test to me" template picker */
.tm-email-test-menu{
  min-width: 280px;
  max-width: 340px;
  right: 0;
  left: auto;
}
.tm-email-test-menu__hint{
  padding: 4px 10px 10px;
  font-size: var(--tm-text-xs);
  color: var(--tm-fg-faint);
  border-bottom: 1px solid var(--tm-border-soft);
  margin-bottom: 6px;
}
.tm-email-test-menu__label{
  padding: 8px 10px 4px;
  font-family: var(--tm-font-display);
  font-weight: 800;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tm-fg-dim);
}
.tm-email-test-menu__form{ margin: 0; }
.tm-email-test-menu__form .tm-menu-item{ font-family: var(--tm-font-body); text-transform: none; letter-spacing: 0; font-weight: 500; }

/* ============================================================================
   36. ADMIN & TEMPLATES ADDENDUM
   ============================================================================ */

/* Bootstrap tables (admin index/questionnaires/waitlist, kept as class names) */
.table{ width: 100%; border-collapse: collapse; font-size: var(--tm-text-sm); color: var(--tm-fg); }
.table th{
  text-align: left; font-family: var(--tm-font-display); font-weight: 800; font-size: var(--tm-text-xs);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--tm-fg-dim);
  padding: 10px 12px; border-bottom: 1px solid var(--tm-border);
}
.table td{ padding: 10px 12px; border-bottom: 1px solid var(--tm-border-soft); vertical-align: middle; }
.table-striped tbody tr:nth-child(odd){ background: var(--tm-panel); }
.table-condensed th, .table-condensed td{ padding: 6px 10px; }
.table-hover tbody tr:hover{ background: var(--tm-panel-2); }

/* Status color variants on the existing .tm-badge component */
.tm-badge--success{ background: var(--tm-trail); color: #fff; }
.tm-badge--warn{ background: #e0a64e; color: var(--tm-charcoal); }
.tm-badge--muted{ background: var(--tm-panel-2); color: var(--tm-fg-dim); }

/* Admin compose-email recipient picker */
.tm-email-recipients{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--tm-space-4);
}
@media (min-width: 900px){
  .tm-email-recipients{ grid-template-columns: 1fr 1fr 1fr; }
}
.tm-email-recipients__col{
  background: var(--tm-panel);
  border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md);
  padding: var(--tm-space-4);
}
.tm-email-recipients__list{
  max-height: 280px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.tm-email-recipients__row{
  margin-top: 0;
  padding: 8px 10px;
  border-radius: var(--tm-radius-sm);
}
.tm-email-recipients__row:hover{ background: var(--tm-panel-2); }
.tm-email-recipients__row strong{ color: var(--tm-fg); font-weight: 600; }

/* Compose editor + live branded preview */
.tm-email-compose{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--tm-space-5);
  align-items: start;
}
@media (min-width: 960px){
  .tm-email-compose{ grid-template-columns: 1fr 1fr; }
}
.tm-email-compose__textarea{ min-height: 280px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: var(--tm-text-sm); line-height: 1.5; }
.tm-email-compose__preview-wrap{ position: sticky; top: var(--tm-space-4); }
.tm-email-preview{
  border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md);
  overflow: hidden;
  background: var(--tm-panel);
}
.tm-email-preview__subject{
  padding: 12px 16px;
  border-bottom: 1px solid var(--tm-border);
  font-family: var(--tm-font-body);
  font-weight: 700;
  font-size: var(--tm-text-sm);
  color: var(--tm-fg);
  background: var(--tm-panel-2);
}
.tm-email-preview__subject.is-placeholder{ color: var(--tm-fg-faint); font-weight: 500; }
/* Matches app/views/layouts/mailer.html.erb chrome. */
.tm-email-preview__page{
  background: #f0ebe3;
  padding: 16px 12px 18px;
}
.tm-email-preview__card{
  background: #fffdf9;
  border: 1px solid #e6ddd0;
  border-radius: 12px;
  overflow: hidden;
  color: #1a1c20;
}
.tm-email-preview__accent{
  height: 4px;
  background: #d4ff3f;
}
.tm-email-preview__chrome{
  padding: 24px 22px 28px;
}
.tm-email-preview__brand-block{ margin: 0 0 18px; }
.tm-email-preview__brand{
  font-family: Arial Black, Arial, sans-serif;
  font-weight: 900;
  font-size: 20px;
  letter-spacing: -0.5px;
  text-transform: uppercase;
  color: #111317;
  line-height: 1.05;
}
.tm-email-preview__brand .the{
  color: #79b45f;
  font-size: 11px;
  letter-spacing: 4px;
  display: block;
  margin-bottom: 2px;
}
.tm-email-preview__rule{
  margin: 14px 0 0;
  border: 0;
  border-top: 1px solid #efe7da;
}
.tm-email-preview__content{
  font-family: Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  color: #1a1c20;
  min-height: 120px;
}
.tm-email-preview__content a{ color: #3f7a1f; }
.tm-email-preview__content p{ margin: 0 0 1em; }
.tm-email-preview__content p:last-child{ margin-bottom: 0; }
.tm-email-preview__content h1,
.tm-email-preview__content h2,
.tm-email-preview__content h3{
  font-family: Arial, Helvetica, sans-serif;
  color: #111317;
  line-height: 1.25;
  margin: 1.25em 0 0.5em;
}
.tm-email-preview__content h1{ font-size: 1.45em; }
.tm-email-preview__content h2{ font-size: 1.22em; }
.tm-email-preview__content h3{ font-size: 1.08em; }
.tm-email-preview__content ul,
.tm-email-preview__content ol{ margin: 0 0 1em; padding-left: 1.4em; }
.tm-email-preview__content li{ margin: 0.3em 0; }
.tm-email-preview__content blockquote{
  margin: 0 0 1em;
  padding: 0.35em 0 0.35em 1em;
  border-left: 3px solid #d4ff3f;
  color: #5a616b;
}
.tm-email-preview__content code{
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.9em;
  background: #f4f3ef;
  padding: 0.1em 0.35em;
  border-radius: 4px;
}
.tm-email-preview__content pre{
  background: #f4f3ef;
  padding: 12px 14px;
  border-radius: 8px;
  overflow-x: auto;
  margin: 0 0 1em;
  border: 1px solid #efe7da;
}
.tm-email-preview__content pre code{ background: transparent; padding: 0; }
.tm-email-preview__content table{ border-collapse: collapse; width: 100%; margin: 0 0 1em; font-size: 0.95em; }
.tm-email-preview__content th,
.tm-email-preview__content td{ border: 1px solid #efe7da; padding: 8px 10px; text-align: left; }
.tm-email-preview__content th{ background: #faf7f1; font-weight: 700; }
.tm-email-preview__placeholder{ color: #8a8e96; font-style: italic; margin: 0; }
.tm-email-preview__footer{
  font-family: Helvetica, Arial, sans-serif;
  font-size: 12px;
  line-height: 1.55;
  color: #8a8e96;
  margin-top: 28px;
  border-top: 1px solid #efe7da;
  padding-top: 16px;
}
.tm-email-preview__footer a{ color: #3f7a1f; text-decoration: none; }
.tm-email-preview__footer a:hover{ text-decoration: underline; }
.tm-email-preview__footer-brand{
  font-weight: 700;
  color: #5a616b;
  margin: 0 0 4px;
}
.tm-email-preview__footer-tagline{
  margin: 0 0 10px;
  font-style: italic;
  color: #8a8e96;
}
.tm-email-preview__footer-links{ margin: 0; }
.tm-email-preview__footer-sep{ color: #c8c2b8; padding: 0 6px; }

/* Markdown help modal (admin compose) */
.tm-markdown-help-table td{ vertical-align: top; }
.tm-markdown-help-table code{
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.85em;
  color: var(--tm-accent);
  white-space: pre-wrap;
}

/* Admin email send-log detail */
.tm-email-log-detail{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--tm-space-5);
  align-items: start;
}
@media (min-width: 960px){
  .tm-email-log-detail{ grid-template-columns: minmax(240px, 0.9fr) 1.2fr; }
}
.tm-email-log-source{
  margin: 0;
  padding: var(--tm-space-4);
  background: var(--tm-panel);
  border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md);
  color: var(--tm-fg);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: var(--tm-text-sm);
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 320px;
  overflow: auto;
}

/* ============================================================================
   APP SHELL — full-width sidebar layout for the coach & admin workspaces
   ----------------------------------------------------------------------------
   Two columns: a sticky sidebar and a scrolling main area. Collapse is driven
   entirely by one custom property, so the toggle only has to flip an attribute:

     .tm-shell                      -> sidebar at full width (264px)
     .tm-shell[data-collapsed]      -> sidebar at icon width (68px)
     .tm-shell[data-drawer]         -> mobile only: sidebar slid in over content

   The initial collapsed state is rendered server-side from the tm_sidebar
   cookie (see shared/_shell_head), so there is no flash on load.
   ============================================================================ */
.tm-shell{
  --tm-sidebar-w:           264px;
  --tm-sidebar-w-collapsed:  68px;
  --tm-shell-gutter:         28px;
  --tm-topbar-h:             60px;
  --tm-content-max:        1600px;

  display: grid;
  grid-template-columns: var(--_tm-sidebar-w, var(--tm-sidebar-w)) minmax(0, 1fr);
  min-height: 100dvh;
}
.tm-shell[data-collapsed]{ --_tm-sidebar-w: var(--tm-sidebar-w-collapsed); }

/* ---- Sidebar ------------------------------------------------------------ */
.tm-sidebar{
  position: sticky; top: 0;
  height: 100dvh;
  display: flex; flex-direction: column;
  background: var(--tm-panel);
  border-right: 1px solid var(--tm-border-soft);
  overflow: hidden;
}

.tm-sidebar__head{
  display: flex; align-items: center; gap: var(--tm-space-2);
  height: var(--tm-topbar-h); flex: none;
  padding-inline: 14px;
  border-bottom: 1px solid var(--tm-border-soft);
}
.tm-sidebar__head .tm-logo{ gap: 8px; min-width: 0; overflow: hidden; }
.tm-sidebar__head .tm-logo__mark{ width: 30px; }
.tm-sidebar__head .tm-wordmark{ font-size: 1.05rem; white-space: nowrap; }

/* Collapse / drawer toggle — no margin-left:auto here; that was pushing the
   mobile topbar hamburger (also .tm-shell-toggle) toward center. Sidebar head
   pins its collapse control to the right explicitly. */
.tm-shell-toggle{
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: none; margin: 0; padding: 0;
  background: none; border: 0; border-radius: var(--tm-radius-sm);
  color: var(--tm-fg-dim); cursor: pointer;
  transition: background var(--tm-transition), color var(--tm-transition);
}
.tm-shell-toggle:hover{ background: var(--tm-panel-2); color: var(--tm-fg); }
.tm-shell-toggle svg{ width: 18px; height: 18px; }
.tm-sidebar__head .tm-shell-toggle{ margin-left: auto; }
.tm-shell[data-collapsed] .tm-shell-toggle svg{ transform: scaleX(-1); }

/* Scrolling nav body */
.tm-sidebar__scroll{
  position: relative;
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--tm-space-4) 10px;
  display: flex; flex-direction: column; gap: var(--tm-space-5);
}
.tm-sidebar__scroll::-webkit-scrollbar{ width: 8px; }
.tm-sidebar__scroll::-webkit-scrollbar-thumb{ background: var(--tm-border); border-radius: 4px; }

.tm-sidebar__group{ display: flex; flex-direction: column; gap: 2px; }

/* Nested AI Assist accordion under the selected athlete */
.tm-sidebar__accordion{ display: flex; flex-direction: column; gap: 2px; }
.tm-sidebar__chevron{
  width: 14px; height: 14px; flex: none; margin-left: auto;
  color: var(--tm-fg-faint);
  transition: transform var(--tm-transition);
}
.tm-sidebar__chevron--open{ transform: rotate(180deg); }
.tm-sidebar__sub{
  display: flex; flex-direction: column; gap: 2px;
  padding-left: 10px; margin-left: 18px;
  border-left: 1px solid var(--tm-border-soft);
}
.tm-sidebar__link--sub{
  font-size: var(--tm-text-sm);
  padding-block: 8px;
  font-weight: 600;
}
.tm-shell[data-collapsed] .tm-sidebar__sub,
.tm-shell[data-collapsed] .tm-sidebar__chevron{ display: none; }

/* Middle panel for Questionnaire / AI Assist (coach athlete pages) */
.tm-coach-tool{ margin-bottom: var(--tm-space-6); }
.tm-coach-tool__card{
  padding: var(--tm-space-5);
  max-width: 920px;
}
.tm-coach-tool__ai-body{ min-height: 120px; }
.tm-coach-tool__pre{
  margin: 0;
  white-space: pre-wrap;
  font-family: inherit;
  font-size: var(--tm-text-sm);
  line-height: 1.55;
  color: var(--tm-fg);
}
.tm-sidebar__label{
  font-family: var(--tm-font-display); font-size: 10px; font-weight: 800;
  letter-spacing: var(--tm-tracking-eyebrow); text-transform: uppercase;
  color: var(--tm-fg-faint);
  padding: 0 10px var(--tm-space-2);
  white-space: nowrap;
}

/* ---- Nav items ---------------------------------------------------------- */
.tm-sidebar__link{
  position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 9px 10px; border-radius: var(--tm-radius-sm);
  color: var(--tm-fg-muted); text-decoration: none;
  font-size: var(--tm-text-sm); line-height: 1.2;
  transition: background var(--tm-transition), color var(--tm-transition);
}
/* Some rows are button_to forms (e.g. "Send test SMS"); strip the UA button look. */
button.tm-sidebar__link{
  width: 100%; text-align: left; cursor: pointer;
  background: none; border: 0;
  font-family: var(--tm-font-body); font-size: var(--tm-text-sm);
}
.tm-sidebar__link:hover{ background: var(--tm-panel-2); color: var(--tm-fg); text-decoration: none; }
.tm-sidebar__link--active{ background: var(--tm-accent-soft); color: var(--tm-fg); font-weight: 700; }
.tm-sidebar__link--active::before{
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 18px; border-radius: 0 3px 3px 0; background: var(--tm-accent);
}
.tm-sidebar__link--active .tm-sidebar__icon{ color: var(--tm-accent); }

.tm-sidebar__icon{ width: 18px; height: 18px; flex: none; color: currentColor; }
.tm-sidebar__text{ flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tm-sidebar__avatar{ width: 22px; height: 22px; border-radius: 50%; object-fit: cover; flex: none; }

/* Count badge. Collapsed, it shrinks to a dot pinned to the icon. */
.tm-sidebar__badge{
  flex: none; min-width: 20px; padding: 2px 6px; border-radius: var(--tm-radius-pill);
  background: var(--tm-accent); color: var(--tm-accent-ink);
  font-family: var(--tm-font-display); font-size: 10px; font-weight: 800;
  text-align: center; line-height: 1.5;
}
.tm-sidebar__badge--quiet{ background: var(--tm-panel-2); color: var(--tm-fg-muted); }

/* Roster filter */
.tm-sidebar__filter{
  width: 100%; margin-bottom: var(--tm-space-2);
  background: var(--tm-panel-2); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-sm); color: var(--tm-fg);
  font-family: var(--tm-font-body); font-size: var(--tm-text-sm);
  padding: 7px 10px;
}
.tm-sidebar__filter::placeholder{ color: var(--tm-fg-faint); }
.tm-sidebar__filter:focus{ outline: none; border-color: var(--tm-accent); }
.tm-sidebar__empty{
  padding: 6px 10px; margin: 0;
  font-size: var(--tm-text-sm); color: var(--tm-fg-faint);
}

/* ---- Sidebar footer ----------------------------------------------------- */
.tm-sidebar__foot{
  flex: none; border-top: 1px solid var(--tm-border-soft);
  padding: 10px; display: flex; flex-direction: column; gap: 2px;
}
.tm-sidebar__user{
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--tm-radius-sm);
  color: var(--tm-fg); text-decoration: none; font-size: var(--tm-text-sm);
}
.tm-sidebar__user:hover{ background: var(--tm-panel-2); text-decoration: none; }
.tm-sidebar__user-name{ min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600; }

/* ---- Collapsed state ---------------------------------------------------- */
.tm-shell[data-collapsed] .tm-sidebar__text,
.tm-shell[data-collapsed] .tm-sidebar__label,
.tm-shell[data-collapsed] .tm-sidebar__user-name,
.tm-shell[data-collapsed] .tm-sidebar__filter,
.tm-shell[data-collapsed] .tm-sidebar__empty,
.tm-shell[data-collapsed] .tm-sidebar__head .tm-wordmark{ display: none; }

.tm-shell[data-collapsed] .tm-sidebar__head{ padding-inline: 10px; justify-content: center; }
.tm-shell[data-collapsed] .tm-sidebar__head .tm-logo{ display: none; }
.tm-shell[data-collapsed] .tm-shell-toggle{ margin-inline: auto; }
.tm-shell[data-collapsed] .tm-sidebar__scroll{ padding-inline: 8px; gap: var(--tm-space-4); }
.tm-shell[data-collapsed] .tm-sidebar__group{ gap: 4px; }
.tm-shell[data-collapsed] .tm-sidebar__link,
.tm-shell[data-collapsed] .tm-sidebar__user{ justify-content: center; padding-inline: 0; gap: 0; }
.tm-shell[data-collapsed] .tm-sidebar__badge{
  position: absolute; top: 3px; right: 6px;
  min-width: 8px; width: 8px; height: 8px; padding: 0;
  font-size: 0; overflow: hidden;
}
/* A hairline between groups replaces the hidden section labels */
.tm-shell[data-collapsed] .tm-sidebar__group + .tm-sidebar__group{
  border-top: 1px solid var(--tm-border-soft); padding-top: var(--tm-space-4);
}

/* ---- Main column -------------------------------------------------------- */
.tm-main{ display: flex; flex-direction: column; min-width: 0; }

.tm-topbar{
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: flex-start;
  gap: var(--tm-space-3);
  min-height: var(--tm-topbar-h); flex: none;
  padding-inline: var(--tm-shell-gutter);
  background: var(--tm-bg);
  border-bottom: 1px solid var(--tm-border-soft);
}
.tm-topbar__title{
  font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase;
  letter-spacing: var(--tm-tracking-display); font-size: var(--tm-text-lg);
  margin: 0; min-width: 0; flex: 1 1 auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-align: left;
}
.tm-topbar__actions{
  margin-left: auto; flex: none;
  display: flex; align-items: center; gap: var(--tm-space-3);
}
.tm-topbar__drawer{ display: none; }   /* hamburger — mobile only */
.tm-topbar__chat{ display: none; }     /* chat-rail button — mobile only */

/* A message whose reply carried plan changes.
   Solid fills with dark ink: these sit inside chat bubbles that are white one
   side and charcoal the other, so a tinted pill disappears on one of them. */
.tm-plan-chip{ margin-top: 10px; }
.tm-plan-chip__link{
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--tm-accent); color: var(--tm-accent-ink);
  font-family: var(--tm-font-display); font-weight: 700;
  font-size: var(--tm-text-xs); letter-spacing: 0.01em;
  text-decoration: none; line-height: 1.25;
}
.tm-plan-chip__link::before{
  content: "◈"; font-size: 11px; opacity: 0.8; flex: none;
}
a.tm-plan-chip__link::after{ content: "›"; font-size: 14px; margin-left: 1px; flex: none; }
a.tm-plan-chip__link:hover{ background: var(--tm-accent-press); }

/* Already in the plan — green rather than "needs you". */
.tm-plan-chip--applied .tm-plan-chip__link{
  background: var(--tm-trail-2); color: var(--tm-charcoal);
}
.tm-plan-chip--applied a.tm-plan-chip__link:hover{ background: var(--tm-trail); }

/* Put back: quiet, but still legible on either bubble. */
.tm-plan-chip--undone .tm-plan-chip__link{
  background: var(--tm-surface-2); color: var(--tm-off-white); font-weight: 500;
}
.tm-plan-chip--undone a.tm-plan-chip__link:hover{ background: var(--tm-hairline); }

/* --- Plan proposal review (split diff) ------------------------------------
   The primary coach deciding a proposal day by day: Current beside Proposed,
   changed values marked in place. Desktop-first; the columns stack on a phone. */
.tm-proposal-banner{ border-left: 3px solid var(--tm-accent); border-radius: 0; }
.tm-diff__head{ display: flex; align-items: center; gap: var(--tm-space-3); flex-wrap: wrap; }
.tm-diff__progress{ display: flex; align-items: center; gap: var(--tm-space-3); flex-wrap: wrap; }
.tm-diff__bar{
  flex: 1; min-width: 160px; height: 6px; border-radius: 999px;
  background: var(--tm-panel-2); overflow: hidden;
}
.tm-diff__bar span{ display: block; height: 100%; background: var(--tm-accent); transition: width var(--tm-transition); }

.tm-diff__week{ margin-bottom: var(--tm-space-4); }
.tm-diff__week-head{
  padding: 6px 10px; color: var(--tm-fg-dim); font-size: var(--tm-text-xs);
  background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md) var(--tm-radius-md) 0 0;
}
/* Fully resolved weeks fold away — a 20-week proposal stays navigable. */
.tm-diff__week--done .tm-diff__day{ display: none; }
.tm-diff__week--done .tm-diff__week-head::after{ content: " · all resolved"; color: var(--tm-accent); }

.tm-diff__day{
  border: 1px solid var(--tm-border); border-top: none;
  background: var(--tm-panel); padding: 10px;
}
.tm-diff__day--decided{ opacity: 0.55; }
.tm-diff__day--decided .tm-diff__cols{ display: none; }
.tm-diff__day-head{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tm-diff__date{ color: var(--tm-fg); font-size: var(--tm-text-sm); }
.tm-diff__badge{
  background: var(--tm-accent-soft); color: var(--tm-accent);
  font-size: 11px; padding: 2px 7px; border-radius: 999px;
}
.tm-diff__badge--warn{ background: rgba(255,122,122,0.14); color: var(--tm-danger); }
.tm-diff__actions{ margin-left: auto; display: flex; gap: 6px; align-items: center; }
.tm-diff__verdict{ color: var(--tm-accent); font-size: var(--tm-text-xs); }
.tm-diff__verdict[hidden]{ display: none; }
.tm-diff__decline{ color: var(--tm-danger); }

.tm-diff__cols{ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 8px; }
.tm-diff__col{ border: 1px solid var(--tm-border); border-radius: var(--tm-radius-md); padding: 8px; }
.tm-diff__col--proposed{ border-color: rgba(212,255,63,0.35); background: rgba(212,255,63,0.05); }
.tm-diff__col-label{ color: var(--tm-fg-faint); font-size: 11px; margin-bottom: 6px; }
.tm-diff__item + .tm-diff__item{ margin-top: 8px; border-top: 1px solid var(--tm-border-soft); padding-top: 8px; }
.tm-diff__item--empty{ color: var(--tm-fg-faint); font-style: italic; font-size: var(--tm-text-sm); }
.tm-diff__item--added{ border-left: 2px solid var(--tm-accent); padding-left: 7px; }
.tm-diff__item--removed{ color: var(--tm-danger); font-size: var(--tm-text-sm); }
.tm-diff__item--gone .tm-diff__title{ text-decoration: line-through; }
.tm-diff__title{ color: var(--tm-fg); font-size: var(--tm-text-sm); }
.tm-diff__details{ margin-top: 4px; line-height: 1.5; }

.tm-diff__fields{ display: grid; grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: 6px; }
.tm-diff__field{ display: block; }
.tm-diff__field > span{ display: block; color: var(--tm-fg-faint); font-size: 11px; margin-bottom: 2px; }
/* A field the proposer actually changed, so the eye lands on it first. */
.tm-diff__field.is-changed > span{ color: var(--tm-accent); }
.tm-diff__field.is-changed input,
.tm-diff__field.is-changed textarea{ border-color: var(--tm-accent); }
.tm-input--sm{ padding: 5px 8px; font-size: var(--tm-text-sm); width: 100%; }

@media (max-width: 900px){
  .tm-diff__cols{ grid-template-columns: minmax(0, 1fr); }
}

/* --- Notification bell ----------------------------------------------------
   The inbox. Its count is unread, the same rows the nav badges and week strip
   count, so it always equals their sum. */
.tm-bell{ position: relative; flex: none; }
.tm-bell__button{ position: relative; }
.tm-bell__count{
  position: absolute; top: -4px; right: -4px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px; background: var(--tm-accent); color: var(--tm-accent-ink);
  font-family: var(--tm-font-display); font-size: 10px; font-weight: 700;
  line-height: 17px; text-align: center;
}
.tm-bell__count[hidden]{ display: none; }
.tm-bell__panel{
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
  width: min(380px, calc(100vw - 32px));
  background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-lg, 12px);
  box-shadow: 0 18px 40px rgba(0,0,0,0.45);
  overflow: hidden;
}
.tm-bell__panel[hidden]{ display: none; }
.tm-bell__head{
  padding: var(--tm-space-3) var(--tm-space-4);
  border-bottom: 1px solid var(--tm-border-soft);
  display: flex; align-items: center; justify-content: space-between; gap: var(--tm-space-3);
}
/* Quiet by default: clearing the lot is a deliberate act, not the thing the
   panel is for, so it reads as a link rather than competing with the rows. */
.tm-bell__mark-all{
  flex: none; background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--tm-font-body); font-size: var(--tm-text-xs); font-weight: 600;
  color: var(--tm-fg-dim); transition: color var(--tm-transition);
}
.tm-bell__mark-all:hover{ color: var(--tm-accent); }
.tm-bell__mark-all:focus-visible{ outline: 2px solid var(--tm-accent); outline-offset: 2px; border-radius: var(--tm-radius-sm); }
.tm-bell__mark-all[hidden]{ display: none; }
.tm-bell__title{
  font-family: var(--tm-font-display); font-size: var(--tm-text-sm);
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--tm-fg-dim);
}
.tm-bell__list{ max-height: min(60vh, 460px); overflow-y: auto; }
.tm-bell__item{
  display: flex; gap: var(--tm-space-3); align-items: flex-start;
  padding: var(--tm-space-3) var(--tm-space-4);
  border-bottom: 1px solid var(--tm-border-soft);
  color: var(--tm-fg-muted); text-decoration: none;
}
.tm-bell__item:hover{ background: var(--tm-panel-2); color: var(--tm-fg); }
.tm-bell__item--unread{ background: var(--tm-accent-soft); color: var(--tm-fg); }
.tm-bell__item--unread .tm-bell__item-title{ font-weight: 600; }
.tm-bell__avatar{ width: 32px; height: 32px; border-radius: 50%; object-fit: cover; flex: none; }
.tm-bell__body{ display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tm-bell__item-title{ font-size: var(--tm-text-sm); }
.tm-bell__item-preview{
  font-size: var(--tm-text-xs); color: var(--tm-fg-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tm-bell__item-time{ font-size: var(--tm-text-xs); color: var(--tm-fg-faint); }
.tm-bell__empty{
  margin: 0; padding: var(--tm-space-5) var(--tm-space-4);
  font-size: var(--tm-text-sm); color: var(--tm-fg-dim); text-align: center;
}
.tm-bell__empty[hidden]{ display: none; }

/* --- Weekly focus: collapse away, re-open from the topbar ----------------- */

/* grid-rows 0fr→1fr animates the callout's real height, margin included,
   without measuring anything in JS. The inner wrapper does the clipping. */
.week-focus-wrap{
  display: grid; grid-template-rows: 1fr;
  transition: grid-template-rows 0.3s ease, opacity 0.22s ease;
}
.week-focus-wrap__inner{ overflow: hidden; min-height: 0; }
.week-focus-wrap--collapsed{ grid-template-rows: 0fr; opacity: 0; }

/* Coach accordion header — the whole label toggles, so it's a wide target. */
.week-focus__summary{
  display: inline-flex; align-items: center; gap: 8px;
  padding: 0; margin: 0; border: 0; background: none; cursor: pointer;
  color: inherit; font: inherit; text-align: left;
}
.week-focus__summary strong{ color: var(--tm-fg); }
.week-focus__summary:hover strong{ color: var(--tm-accent); }
.week-focus__chev{
  width: 15px; height: 15px; flex: none; color: var(--tm-fg-dim);
  transition: transform 0.25s ease;
}
.week-focus--open .week-focus__chev{ transform: rotate(90deg); color: var(--tm-accent); }

/* Anchors the hint bubble to the button. */
.tm-topbar__focus{ position: relative; display: inline-flex; flex: none; }
.tm-topbar__focus-btn--on{ color: var(--tm-accent); }

/* Fires once, on the athlete's first dismissal — three pulses is enough to
   catch the eye without turning into a distraction. */
.tm-topbar__focus-btn--pulse{ animation: tm-focus-pulse 1.3s ease-out 3; }
@keyframes tm-focus-pulse{
  0%   { box-shadow: 0 0 0 0 rgba(212, 255, 63, 0.5); }
  70%  { box-shadow: 0 0 0 11px rgba(212, 255, 63, 0); }
  100% { box-shadow: 0 0 0 0 rgba(212, 255, 63, 0); }
}

/* AI insights. Reuses tm-focus-pulse deliberately — the athlete's week-focus
   icon already solved "draw the eye once without nagging", and three pulses is
   the answer that was tuned there. --on is the standing state (an answer is
   waiting); --pulse fires only on arrival. */
.tm-topbar__insights{ position: relative; }
.tm-topbar__insights--on{ color: var(--tm-accent); }
.tm-topbar__insights--pulse{ animation: tm-focus-pulse 1.3s ease-out 3; }
/* Every other .tm-shell-toggle is a <button>; this one is a link. */
a.tm-shell-toggle{ text-decoration: none; }

.tm-focus-hint{
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
  width: max-content; max-width: 15rem;
  padding: 9px 12px;
  background: var(--tm-accent); color: var(--tm-accent-ink);
  border-radius: var(--tm-radius-md); box-shadow: var(--tm-shadow-md);
  font-size: var(--tm-text-xs); font-weight: 600; line-height: 1.45;
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.tm-focus-hint.is-visible{ opacity: 1; transform: translateY(0); }
.tm-focus-hint::before{
  content: ""; position: absolute; bottom: 100%; right: 15px;
  border: 6px solid transparent; border-bottom-color: var(--tm-accent);
}

@media (prefers-reduced-motion: reduce){
  .week-focus-wrap{ transition: none; }
  .week-focus__chev{ transition: none; }
  .tm-topbar__focus-btn--pulse{ animation: none; }
  .tm-topbar__insights--pulse{ animation: none; }
  .tm-focus-hint{ transition: none; }
}

.tm-content{
  flex: 1;
  width: 100%; max-width: var(--tm-content-max); margin-inline: auto;
  padding: var(--tm-space-6) var(--tm-shell-gutter) var(--tm-space-8);
}
/* For prose-ish pages (compose email, forms) that shouldn't run full-bleed */
.tm-content--narrow{ --tm-content-max: 900px; }

.tm-shell .tm-flash{ margin-bottom: var(--tm-space-5); }

/* ---- Right chat rail ----------------------------------------------------
   A third shell column holding the athlete chat, present on every coach page
   that has an athlete in scope. Collapsed it becomes a 52px tab strip so
   there's always a way back; the state persists in the tm_chat cookie.
   -------------------------------------------------------------------------- */
.tm-shell--rail{
  --tm-rail-w: 360px;
  grid-template-columns:
    var(--_tm-sidebar-w, var(--tm-sidebar-w))
    minmax(0, 1fr)
    var(--_tm-rail-w, var(--tm-rail-w));
}
.tm-shell--rail[data-rail-collapsed]{ --_tm-rail-w: 52px; }

/* Coach thread inserts a column after the sidebar. With the athlete rail also
   open that's four columns, which is why the sidebar is collapsed to 68px for
   the duration. */
.tm-shell--dm{
  --tm-dm-w: 320px;
  grid-template-columns:
    var(--_tm-sidebar-w, var(--tm-sidebar-w))
    var(--tm-dm-w)
    minmax(0, 1fr);
}
.tm-shell--dm.tm-shell--rail{
  grid-template-columns:
    var(--_tm-sidebar-w, var(--tm-sidebar-w))
    var(--tm-dm-w)
    minmax(0, 1fr)
    var(--_tm-rail-w, var(--tm-rail-w));
}
/* Four columns need room. Below this the athlete rail collapses to its tab
   strip first, since the coach opened the thread deliberately and the rail
   is one click from returning. */
@media (max-width: 1400px){
  .tm-shell--dm.tm-shell--rail{ --_tm-rail-w: 52px; }
  .tm-shell--dm.tm-shell--rail .tm-rail__panel{ display: none; }
  .tm-shell--dm.tm-shell--rail .tm-rail__tab{ display: flex; }
}
/* Narrow: the thread takes over as the only panel beside the collapsed nav.
   Closing it (the X, or the sidebar link again) brings the page straight back. */
@media (max-width: 1100px){
  .tm-shell--dm,
  .tm-shell--dm.tm-shell--rail{
    grid-template-columns: var(--_tm-sidebar-w, var(--tm-sidebar-w)) minmax(0, 1fr);
  }
  .tm-shell--dm .tm-main,
  .tm-shell--dm .tm-rail{ display: none; }
}

.tm-rail{
  position: sticky; top: 0;
  height: 100dvh;
  display: flex; flex-direction: column; min-width: 0;
  background: var(--tm-panel);
  border-left: 1px solid var(--tm-border-soft);
}

/* Collapsed tab: vertical strip, label rotated to read bottom-up. */
.tm-rail__tab{
  display: none;
  flex: 1; width: 100%;
  flex-direction: column; align-items: center; gap: 12px;
  padding: 18px 0; cursor: pointer;
  background: none; border: 0; color: var(--tm-fg-muted);
  transition: background var(--tm-transition), color var(--tm-transition);
}
.tm-rail__tab:hover{ background: var(--tm-panel-2); color: var(--tm-fg); }
.tm-rail__tab svg{ width: 20px; height: 20px; flex: none; }
.tm-rail__tab-label{
  writing-mode: vertical-rl;
  font-family: var(--tm-font-display); font-size: 11px; font-weight: 800;
  letter-spacing: var(--tm-tracking-eyebrow); text-transform: uppercase;
}
.tm-rail__panel{ display: flex; flex-direction: column; min-height: 0; flex: 1; }

.tm-shell--rail[data-rail-collapsed] .tm-rail__panel{ display: none; }
.tm-shell--rail[data-rail-collapsed] .tm-rail__tab{ display: flex; }

/* The chat fills its column rather than the 520px card cap .tm-chat--fill uses.
   Shared with the coach-to-coach thread (.tm-dm) so both chats look the same. */
.tm-rail .tm-chat,
.tm-dm .tm-chat{
  display: flex; flex-direction: column; flex: 1; min-height: 0;
  border: 0; border-radius: 0; max-height: none;
}
.tm-rail .tm-chat__body,
.tm-dm .tm-chat__body{ flex: 1 1 auto; overflow-y: auto; min-height: 0; }
.tm-rail .tm-chat__head,
.tm-dm .tm-chat__head{ flex: none; }
.tm-rail .tm-chat__composer,
.tm-dm .tm-chat__composer{ flex: none; }

/* Weekly mileage under Athlete Chat in the left coach sidebar */
.tm-sidebar__widget{
  margin-top: var(--tm-space-3);
  background: var(--tm-panel);
  border-top: 1px solid var(--tm-border-soft);
  padding-top: var(--tm-space-3);
}
.tm-sidebar__widget .tm-widget{
  margin: 0;
  border: 0;
  background: transparent;
  padding: 0;
  height: auto;
}
.tm-sidebar__widget .tm-chart{ min-height: 110px; }
.tm-sidebar__widget .tm-chart__title{
  font-size: 10px;
  letter-spacing: 0.08em;
}
.tm-sidebar__widget .tm-chart__total{ font-size: var(--tm-text-sm); }
/* Compact bars so the chart fits the narrow sidebar */
.tm-sidebar__widget .tm-bar__label{ font-size: 8px; }
.tm-sidebar__widget .tm-bar__val{ font-size: 8px; }
/* The type strip costs ~28px, so take it back off the track — 140px was sized
   for a full-width card and is the one thing the rail never compacted. */
.tm-sidebar__widget .tm-chart__types{ margin-bottom: var(--tm-space-2); }
.tm-sidebar__widget .tm-chart__type{ width: 22px; height: 22px; }
.tm-sidebar__widget .tm-bar__track{ height: 96px; }
.tm-sidebar__widget .tm-chart__bars{ gap: 6px; }
.tm-shell[data-collapsed] .tm-sidebar__widget{ display: none; }

.tm-rail__close{
  margin-left: auto; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
  background: none; border: 0; border-radius: var(--tm-radius-sm);
  color: #8a7f70; cursor: pointer;
}
.tm-rail__close:hover{ background: #f0e8dc; color: #231f1a; }
.tm-rail__close svg{ width: 16px; height: 16px; }

/* ---- Mobile: sidebar becomes an off-canvas drawer ------------------------ */
@media (max-width: 900px){
  .tm-shell,
  .tm-shell--dm,
  .tm-shell--dm.tm-shell--rail{ grid-template-columns: minmax(0, 1fr); --tm-shell-gutter: 18px; }

  .tm-sidebar{
    position: fixed; inset: 0 auto 0 0; z-index: 1060;
    width: var(--tm-sidebar-w);
    transform: translateX(-100%);
    transition: transform var(--tm-transition);
    box-shadow: var(--tm-shadow-lg);
  }
  .tm-shell[data-drawer] .tm-sidebar{ transform: translateX(0); }

  /* Collapsed is a desktop-only affordance; the drawer is always full width. */
  .tm-shell[data-collapsed] .tm-sidebar__text,
  .tm-shell[data-collapsed] .tm-sidebar__label,
  .tm-shell[data-collapsed] .tm-sidebar__user-name,
  .tm-shell[data-collapsed] .tm-sidebar__filter,
  .tm-shell[data-collapsed] .tm-sidebar__empty,
  .tm-shell[data-collapsed] .tm-sidebar__head .tm-logo,
  .tm-shell[data-collapsed] .tm-sidebar__head .tm-wordmark{ display: revert; }
  .tm-shell[data-collapsed] .tm-sidebar__head{ justify-content: flex-start; }
  .tm-shell[data-collapsed] .tm-sidebar__link,
  .tm-shell[data-collapsed] .tm-sidebar__user{ justify-content: flex-start; padding-inline: 10px; gap: 12px; }
  .tm-shell[data-collapsed] .tm-sidebar__badge{
    position: static; width: auto; height: auto; min-width: 20px;
    padding: 2px 6px; font-size: 10px;
  }
  .tm-shell[data-collapsed] .tm-sidebar__group + .tm-sidebar__group{ border-top: 0; padding-top: 0; }

  .tm-shell__scrim{
    position: fixed; inset: 0; z-index: 1050;
    background: var(--tm-charcoal); opacity: 0;
    pointer-events: none; transition: opacity var(--tm-transition);
  }
  .tm-shell[data-drawer] .tm-shell__scrim{ opacity: 0.6; pointer-events: auto; }

  /* Hamburger + title stay left; actions (chat, avatar) stay right. */
  .tm-topbar__drawer{
    display: inline-flex;
    margin: 0;
    order: 0;
  }
  .tm-topbar__title{ order: 1; }
  .tm-topbar__actions{ order: 2; margin-left: auto; }

  /* The chat rail becomes a right-hand drawer; the 52px tab strip would eat
     too much width, so the topbar button is the affordance instead. */
  .tm-shell--rail{ grid-template-columns: minmax(0, 1fr); }
  .tm-rail{
    position: fixed; inset: 0 0 0 auto; z-index: 1060;
    width: min(360px, 92vw);
    transform: translateX(100%);
    transition: transform var(--tm-transition);
    box-shadow: var(--tm-shadow-lg);
  }
  .tm-shell--rail:not([data-rail-collapsed]) .tm-rail{ transform: translateX(0); }
  .tm-shell--rail[data-rail-collapsed] .tm-rail__tab{ display: none; }
  .tm-shell--rail[data-rail-collapsed] .tm-rail__panel{ display: flex; }
  .tm-shell--rail:not([data-rail-collapsed]) .tm-shell__scrim{ opacity: 0.6; pointer-events: auto; }

  .tm-topbar__chat{ display: inline-flex; }

  /* The panel is right-anchored to the bell, but the bell is not at the screen
     edge — the avatar sits to its right — so `width: calc(100vw - 32px)` was
     wider than the space left of the bell and ran off-screen (measured -32px at
     375px wide). Pin it to the viewport instead. The topbar is sticky at top 0,
     so a fixed panel sits under it and stays put, and the shell gutter keeps it
     clear of both edges. */
  .tm-bell__panel{
    position: fixed;
    top: calc(var(--tm-topbar-h) + 8px);
    right: var(--tm-shell-gutter);
    left: auto;
    width: min(380px, calc(100vw - 2 * var(--tm-shell-gutter)));
  }
}

@media (min-width: 901px){
  .tm-shell__scrim{ display: none; }
  .tm-topbar__chat{ display: none; }
}

/* ============================================================================
   PROGRESS REPORTS
   ============================================================================ */

/* The page is chaptered with the theme scopes (.tm-on-lime / -light / -trail),
   which remap the whole palette — so a report reads as a different kind of
   object from the rest of the app rather than another dark card. */
.tm-report{ max-width: 820px; margin: 0 auto; display: flex; flex-direction: column; gap: var(--tm-space-5); }
.tm-report__cover{
  border-radius: var(--tm-radius-lg);
  padding: var(--tm-space-8) var(--tm-space-6);
}
.tm-report__section{
  background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-lg); padding: var(--tm-space-6);
}
.tm-report__section.tm-on-light,
.tm-report__section.tm-on-trail,
.tm-report__section.tm-on-lime{ border-color: transparent; }
/* Left-aligned like the opening note it mirrors — a centred paragraph beside a
   left-aligned one reads as a different kind of thing. */
.tm-report__signoff{ text-align: left; }
/* The coach's name under their closing words. Their signature, so it carries
   weight rather than sitting in the same grey as a caption. */
.tm-report__signature{
  margin: 0; font-family: var(--tm-font-display); font-weight: 800;
  letter-spacing: 0.04em; color: var(--tm-fg);
}
.tm-report__footer{ padding: 0 var(--tm-space-2) var(--tm-space-6); }

.tm-report-stats{
  display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--tm-space-5);
}
.tm-report__types{ display: flex; flex-wrap: wrap; gap: var(--tm-space-6); }
.tm-report__unit{ font-size: 10px; font-weight: 700; color: var(--tm-fg-dim); margin-left: 2px; }
.tm-report__fitness{ display: flex; align-items: center; gap: var(--tm-space-6); flex-wrap: wrap; }
.tm-report__arrow{ font-size: var(--tm-text-2xl); color: var(--tm-fg-dim); }
.tm-report__deltas{ display: flex; flex-wrap: wrap; gap: var(--tm-space-3); }

/* The new-report form's live stat preview while it refetches. Dimmed rather
   than emptied: the previous range's numbers are the better placeholder, and a
   panel that collapses to nothing makes the form jump under the coach's hands. */
.tm-range-preview{ transition: opacity 120ms ease-out; }
.tm-range-preview.is-loading{ opacity: .45; }
@media (prefers-reduced-motion: reduce){
  .tm-range-preview{ transition: none; }
}

/* Placeholder while the prose is being written. The stat blocks above are
   already real, so this only stands in for the words. */
/* A button that should read as a link. .tm-link is an anchor style, so on a
   <button> the browser's own chrome shows through underneath it. */
.tm-linkbtn{
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--tm-accent);
}
.tm-linkbtn:hover{ text-decoration: underline; }

/* A figure in the prose the report's own numbers don't support. Amber rather
   than red — it is a "look at this", not an error. */
.tm-flag{ color: #f0a44a; }

.tm-report-skeleton{
  height: 96px; border-radius: var(--tm-radius-md);
  background: linear-gradient(90deg, var(--tm-panel-2) 25%, var(--tm-surface-2) 37%, var(--tm-panel-2) 63%);
  background-size: 400% 100%;
  animation: tm-shimmer 1.4s ease-in-out infinite;
}
.tm-report-skeleton + .tm-report-skeleton{ margin-top: var(--tm-space-4); }
@keyframes tm-shimmer{ from{ background-position: 100% 0; } to{ background-position: 0 0; } }
@media (prefers-reduced-motion: reduce){ .tm-report-skeleton{ animation: none; } }

/* Something is happening. Sized in em so it matches whatever text it sits in,
   and drawn in currentColor so it works on every button variant and inside the
   themed report sections without a second rule. */
.tm-spinner{
  display: inline-block; width: 1em; height: 1em; vertical-align: -0.125em;
  /* It is a flex item inside the callout, and a shrunk circle is an oval. */
  flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: tm-spin .6s linear infinite;
}
@keyframes tm-spin{ to{ transform: rotate(360deg); } }
/* Slowed rather than stopped — a spinner that doesn't move says nothing at all,
   which defeats the point of showing one. */
@media (prefers-reduced-motion: reduce){ .tm-spinner{ animation-duration: 2.4s; } }

.tm-btn.is-busy{ pointer-events: none; opacity: .75; }

/* The rewrite brief. The summary IS the button, so the marker has to go — and
   Safari needs the ::-webkit- pseudo-element as well as list-style. */
.tm-rewrite{ display: inline-block; }
.tm-rewrite > summary{ list-style: none; cursor: pointer; }
.tm-rewrite > summary::-webkit-details-marker{ display: none; }
/* An absolutely-positioned child escapes the way a closed <details> hides its
   content, so it floats on the page permanently unless this says otherwise. */
.tm-rewrite:not([open]) .tm-rewrite__panel{ display: none; }
.tm-rewrite__panel{
  position: absolute; z-index: 20; width: min(420px, calc(100vw - var(--tm-space-8)));
  background: var(--tm-panel); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md); padding: var(--tm-space-5);
  box-shadow: 0 12px 32px rgba(0,0,0,.35);
}

/* A section the coach has dropped. Dimmed rather than hidden — it is still
   theirs to switch back on, and the prose is still in the box. */
.tm-toggle{ display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.tm-report-field.is-off > *:not(:first-child){ opacity: .4; }
.tm-report-field.is-off textarea{ text-decoration: line-through; }

/* The prompt picker. Tiles rather than a list: these are questions to choose
   between at a glance, not a menu to read through. */
.tm-insight-grid{ display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--tm-space-3); }
.tm-insight-tile{
  width: 100%; text-align: left; cursor: pointer;
  padding: var(--tm-space-4); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md); background: var(--tm-panel-2);
  color: var(--tm-fg); font: inherit; font-weight: 600;
  transition: border-color var(--tm-transition), background var(--tm-transition);
}
.tm-insight-tile:hover{ border-color: var(--tm-accent); background: var(--tm-panel); }
.tm-insight-tile.is-busy{ pointer-events: none; opacity: .75; }

.tm-report-row{
  display: flex; align-items: center; gap: var(--tm-space-4);
  padding: var(--tm-space-4); border: 1px solid var(--tm-border);
  border-radius: var(--tm-radius-md); text-decoration: none; color: inherit;
  transition: border-color var(--tm-transition);
}
.tm-report-row:hover{ border-color: var(--tm-accent); }
.tm-report-row__title{ font-family: var(--tm-font-display); font-weight: 900; font-size: var(--tm-text-lg); }

/* ---- The Week Ribbon ----------------------------------------------------- */
/* One column per day, height by TRAINING LOAD — the only axis on which a lift
   and a long run can honestly share a chart. */
.tm-ribbon{ display: flex; align-items: flex-end; gap: 8px; min-height: 150px; }
.tm-ribbon__empty{ margin: 0; }
.tm-ribbon__day{ flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0; }
.tm-ribbon__track{ width: 100%; height: 130px; display: flex; align-items: flex-end; justify-content: center; }
.tm-ribbon__stack{
  width: 100%; max-width: 40px; display: flex; flex-direction: column-reverse;
  border-radius: 6px 6px 0 0; overflow: hidden; gap: 1px;
}
.tm-ribbon__seg{
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, var(--tm-lime), #a9d62f);
  color: var(--tm-charcoal); font-size: 11px; min-height: 10px;
}
/* A day that was planned and not done reads as an outline, not a filled bar. */
.tm-ribbon__day--missed .tm-ribbon__seg{ background: transparent; }
.tm-ribbon__day--missed .tm-ribbon__stack{ border: 1.5px dashed var(--tm-border); }
.tm-ribbon__day--extra .tm-ribbon__seg{ background: linear-gradient(180deg, var(--tm-trail-2), var(--tm-trail)); }
/* Rest is a baseline tick — visibly "nothing planned, nothing done", which is
   different from a gap in the week. */
.tm-ribbon__rest{ width: 100%; height: 3px; background: var(--tm-fg-faint); border-radius: 2px; }
.tm-ribbon__dow{
  font-family: var(--tm-font-display); font-weight: 800; font-size: 10px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--tm-fg-dim);
}

/* ---- The Fitness Arc ----------------------------------------------------- */
/* One curve, two dots. No axes, no gridlines, no second line — the Fitness page
   is the coach's instrument; this is the sentence. */
.tm-arc__svg{ width: 100%; height: auto; display: block; overflow: visible; }
.tm-arc__line{ fill: none; stroke: var(--tm-accent); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
/* Dashed while the model is warming up, so the shape never reads as a claim the
   numbers can't yet support. */
.tm-arc__line--calibrating{ stroke-dasharray: 5 5; opacity: 0.75; }
/* Everything before the reported period is context. */
.tm-arc__prior{ fill: none; stroke: var(--tm-fg-faint); stroke-width: 2; opacity: 0.35; }
.tm-arc__dot{ fill: var(--tm-bg); stroke: var(--tm-accent); stroke-width: 2.5; }
.tm-arc__dot--now{ fill: var(--tm-accent); }
.tm-arc__empty{ margin: 0; }

/* ---- Next Week's Shape --------------------------------------------------- */
.tm-nextweek{ display: flex; flex-direction: column; gap: 6px; }
.tm-nextweek__day{ display: flex; align-items: center; gap: 10px; }
.tm-nextweek__dow{
  flex: none; width: 34px;
  font-family: var(--tm-font-display); font-weight: 800; font-size: 10px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--tm-fg-dim);
}
.tm-nextweek__track{ flex: 1; display: flex; gap: 4px; min-width: 0; }
/* Sized by planned volume, shaded by target effort — the ramp runs from the
   quietest surface to full accent as --tm-pill-shade goes 0 to 1. */
.tm-nextweek__pill{
  display: flex; align-items: center; gap: 6px; min-width: 0;
  padding: 6px 10px; border-radius: var(--tm-radius-pill);
  background: color-mix(in srgb, var(--tm-accent) calc(var(--tm-pill-shade, 0) * 100%), var(--tm-surface-2));
  color: var(--tm-fg); font-size: var(--tm-text-xs); font-weight: 600;
  white-space: nowrap; overflow: hidden;
}
.tm-nextweek__label{ overflow: hidden; text-overflow: ellipsis; }
.tm-nextweek__rest{ font-size: var(--tm-text-xs); color: var(--tm-fg-faint); }
.tm-nextweek__empty{ margin: 0; }

/* ---- Prose --------------------------------------------------------------- */
/* Only .tm-prose a existed before this — the anchor styling was reserved for a
   block that was never written. Everything is in --tm-* variables so the same
   markup reads correctly on lime, on trail and on dark. */
.tm-prose{ color: var(--tm-fg-muted); font-size: var(--tm-text-base); line-height: 1.65; }
.tm-prose > * + *{ margin-top: var(--tm-space-4); }
.tm-prose > :first-child{ margin-top: 0; }
.tm-prose p{ margin: 0; }
.tm-prose strong{ color: var(--tm-fg); font-weight: 700; }
.tm-prose h2, .tm-prose h3{
  font-family: var(--tm-font-display); font-weight: 900; text-transform: uppercase;
  letter-spacing: -0.02em; color: var(--tm-fg); margin: 0;
}
.tm-prose h2{ font-size: var(--tm-text-xl); }
.tm-prose h3{ font-size: var(--tm-text-lg); }
/* A heading opens a new section, so it needs more air above it than the even
   rhythm `> * + *` gives every sibling — otherwise it sits on the paragraph
   above and reads as part of the same block. Must come AFTER the rule that
   zeroes heading margins: same specificity, so source order decides. */
.tm-prose > * + h2{ margin-top: var(--tm-space-6); }
.tm-prose > * + h3{ margin-top: var(--tm-space-5); }
.tm-prose ul, .tm-prose ol{ margin: 0; padding-left: 1.25em; }
.tm-prose li + li{ margin-top: var(--tm-space-2); }
.tm-prose li::marker{ color: var(--tm-accent); }
.tm-prose blockquote{
  margin: 0; padding-left: var(--tm-space-4);
  border-left: 3px solid var(--tm-accent); color: var(--tm-fg);
}
.tm-prose table{ width: 100%; border-collapse: collapse; font-size: var(--tm-text-sm); }
.tm-prose th, .tm-prose td{ text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--tm-border); }
.tm-prose--lead{ font-size: var(--tm-text-lg); color: var(--tm-fg); line-height: 1.55; }

/* ---- Print --------------------------------------------------------------- */
/* The only print rules in the app, scoped to a report. There is no PDF library
   here and none is needed — "save as PDF" from the browser is the feature. The
   theme scopes all flatten to ink on white: a lime full-bleed cover costs a
   cartridge and reads worse than type. */
@media print{
  .tm-sidebar, .tm-rail, .tm-topbar, .tm-dm, .tm-shell__scrim,
  .tm-report__footer .tm-btn, .tm-callout{ display: none !important; }

  .tm-shell{ display: block !important; }
  .tm-main{ padding: 0 !important; }

  body, .tm-report__section, .tm-report__cover{
    background: #fff !important; color: #111 !important;
  }
  .tm-report{ max-width: none; gap: 18px; }
  .tm-report__section, .tm-report__cover{
    border: 0 !important; box-shadow: none !important; padding: 0 0 12px !important;
    break-inside: avoid;
  }
  .tm-report__cover{ border-bottom: 2px solid #111 !important; }
  .tm-display{ font-size: 28pt; }
  .tm-eyebrow, .tm-stat__num, .tm-prose li::marker{ color: #111 !important; }
  .tm-prose, .tm-stat__label, .tm-small{ color: #333 !important; }
  /* The SVGs scale fine; force their strokes to ink. */
  .tm-arc__line, .tm-arc__dot{ stroke: #111 !important; }
  .tm-arc__dot--now{ fill: #111 !important; }
  .tm-ribbon__seg, .tm-nextweek__pill{ background: #ddd !important; color: #111 !important; }
}

/* ============================================================================
   END — The Marathons brand stylesheet
   ============================================================================ */
