/* The plan calendar's month review (Views::PlanCalendars::MonthReview):
   days left to right as one line, one row per thing that needs attention.
   Rows share one column template through --score-columns, so a mark in
   any row sits under its day in the head. Marks fill their column edge to
   edge with a hairline gap, so consecutive days join into a bar and a
   clump reads as one shape. */

.month-review {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--surface);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
}

/* The month in one line, with the filter beside it. */
.month-review-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
}

.month-review-status {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}

.score-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}

.score-heading {
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: var(--leading-tight);
}

.score-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  padding: 0;
  list-style: none;
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.score-legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* What the pointer is over, in words: the movements and sessions behind a
   mark. One line, so the grid below never moves. */
.score-readout {
  justify-self: start;
  max-width: 100%;
  min-height: calc(var(--text-sm) * var(--leading));
  padding: 0 var(--space-2);
  overflow: hidden;
  border-radius: 999px;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  line-height: var(--leading);
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Stays in view above the weeks, so what a trace or a highlight found
     is on screen while the grid scrolls under it. */
  position: sticky;
  top: var(--space-1);
  z-index: 1;
  border: var(--line-width) solid var(--line);
  background: var(--surface);
}

/* The readout takes the chip look of the mark it names (UI::Chip's tones),
   so its words read in the same colour as the mark. */
.score-readout[data-tone="caution"] {
  background: var(--caution-soft);
  color: var(--caution-ink);
}

.score-readout[data-tone="danger"] {
  background: var(--danger-soft);
  color: var(--danger-ink);
}

.score-readout[data-tone="severe"] {
  background: var(--severe);
  color: var(--ink-on-accent);
}

.score-readout[data-tone="quiet"] {
  background: var(--surface-sunken);
  color: var(--ink);
}

/* Wide months scroll sideways on a phone; the labels stay put. */
.score-scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.score-grid {
  display: grid;
  min-width: max-content;
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}

.score-group {
  display: grid;
}

.score-group[hidden] {
  display: none;
}

/* A row's ground, read by its sticky label too, so the label and every
   day of the row light up together under the pointer. */
.score-row {
  --score-row-ground: var(--surface);
  display: grid;
  grid-template-columns: var(--score-columns);
  align-items: stretch;
  min-height: 1.5rem;
  background: var(--score-row-ground);
  box-shadow: inset 0 calc(-1 * var(--line-width)) 0 var(--surface-sunken);
  transition: opacity 160ms ease-out;
}

.score-row:hover {
  --score-row-ground: var(--accent-soft);
}

.score-row[hidden] {
  display: none;
}

/* Focus on one row: the rest step back. */
.score-row[data-dimmed="true"] {
  opacity: 0.28;
}

.score-row-head {
  position: sticky;
  top: 0;
  z-index: 2;
  min-height: 2rem;
  background: var(--surface);
  border-bottom: var(--line-width) solid var(--line);
}

.score-row-lane {
  min-height: 1.75rem;
  border-bottom: var(--line-width) solid var(--line);
}

.score-row-cycles {
  min-height: 1.75rem;
  border-bottom: var(--line-width) solid var(--line);
}

.score-row-group {
  grid-template-columns: 1fr;
  min-height: 2rem;
  align-items: end;
}

.score-label {
  position: sticky;
  left: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
  padding-right: var(--space-2);
  background: var(--score-row-ground, var(--surface));
}

.score-label-head {
  align-items: end;
  padding-bottom: var(--space-1);
}

.score-month {
  font-weight: 600;
  color: var(--ink-muted);
}

.score-label-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.score-focus {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  min-height: 1.375rem;
  padding: 0 var(--space-1);
  margin-left: calc(-1 * var(--space-1));
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  font-size: var(--text-sm);
  text-align: left;
  cursor: pointer;
}

.score-focus:hover {
  background: var(--surface-sunken);
}

.score-focus:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

/* The row being traced through the month (month_score_controller.js). */
.score-focus[aria-current="true"] {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: 600;
}

.score-group-head {
  position: sticky;
  left: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: max-content;
  padding-top: var(--space-2);
}

.score-group-name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}

.score-group-note {
  color: var(--ink-muted);
}

/* Day head */
.score-day {
  display: grid;
  justify-items: center;
  align-content: end;
  padding-bottom: var(--space-1);
  color: var(--ink-muted);
  line-height: 1.1;
}

.score-day[aria-current="date"] {
  color: var(--accent-ink);
  font-weight: 700;
}

.score-day-name {
  font-size: var(--text-xs);
  text-transform: uppercase;
}

.score-day-number {
  white-space: nowrap;
}

.score-fact {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding-left: var(--space-2);
  color: var(--ink-muted);
}

.score-fact-count {
  min-width: 1.25rem;
  color: var(--ink);
  font-weight: 600;
  text-align: right;
}

.score-fact-head {
  align-items: end;
  padding-bottom: var(--space-1);
}

/* A day's cell. The week's first day carries a hairline so weeks still
   read; nothing else divides the line. */
.score-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px 1px;
  min-width: 0;
}

.score-week-start {
  box-shadow: inset var(--line-width) 0 0 var(--line);
}

.score-today {
  background: var(--accent-soft);
}

/* Sessions lane: one pip per workout, open plan block or draft. */
.score-cell-lane {
  padding: 0;
}

.score-sessions {
  display: flex;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  height: 100%;
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  text-decoration: none;
}

.score-sessions:hover {
  background: var(--surface-sunken);
}

.score-sessions:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.score-session {
  display: block;
  width: 0.75rem;
  height: 0.25rem;
  border-radius: var(--radius-sm);
  background: var(--accent);
}

.score-session-planned {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--accent);
}

.score-session-draft {
  background: transparent;
  outline: 1px dashed var(--accent);
  outline-offset: -1px;
}

.score-sessions-more {
  font-size: var(--text-xs);
  line-height: 1;
}

/* Cycles lane: each cycle spans its days. */
.score-cycles {
  display: grid;
  grid-column: 2 / span var(--score-days);
  grid-template-columns: repeat(var(--score-days), var(--score-day));
  grid-auto-flow: row dense;
  gap: 2px 0;
  padding: 2px 0;
}

.score-cycle {
  display: grid;
  min-width: 0;
  padding: 0 1px;
}

/* A day's sessions menu: each session's name heads its actions. */
.score-menu-name {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-1) var(--space-2) 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}

.score-menu-name-later {
  margin-top: var(--space-1);
  padding-top: var(--space-2);
  border-top: var(--line-width) solid var(--line);
}

.score-menu-kind {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink-muted);
}

.score-move {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-1) var(--space-2);
}

/* The month review's first answer (Components::AttentionGrid): one
   row per warning subject, marked in its tone on the days it falls, so a
   clump of the same trouble reads as one bar. */
/* The attention grid sets its own columns (Components::AttentionGrid
   writes --score-days), so it draws the same on the plan calendar and the
   plan dashboard. */
.attention {
  --score-label: 9.5rem;
  --score-fact: 2.5rem;
  --score-day: minmax(1.25rem, 1fr);
  --score-columns: var(--score-label) repeat(var(--score-days), var(--score-day)) var(--score-fact);
  display: grid;
  gap: var(--space-2);
}

@media (min-width: 64rem) {
  .attention {
    --score-label: 13rem;
  }
}

.attention-note {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.attention-mark {
  display: block;
  width: 100%;
  height: 0.875rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.attention-mark:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

.attention-mark-caution {
  background: var(--caution);
}

.attention-mark-danger {
  background: var(--danger);
}

/* The top fatigue level only (Very High): the solid severe token. */
.attention-mark-severe {
  background: var(--severe);
}

/* Pointing at a mark lifts it with an outline in its own ink, so the
   cursor always says which day it is on. */
.attention-mark:hover {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

.attention-mark-caution:hover {
  outline-color: var(--caution-ink);
}

.attention-mark-danger:hover {
  outline-color: var(--danger-ink);
}

.attention-mark-severe:hover {
  outline-color: var(--severe);
}

.attention-mark-forecast-severe:hover {
  outline-color: var(--severe);
}

.attention-mark-forecast-caution:hover {
  outline-color: var(--caution-ink);
}

.attention-mark-forecast-danger:hover {
  outline-color: var(--danger-ink);
}

/* A mark on a day not built yet reads from its plan: the same tone, in
   stripes, so a forecast never looks like a scheduled workout. */
.attention-mark-forecast-caution {
  background: repeating-linear-gradient(-45deg, var(--caution) 0 3px, var(--caution-soft) 3px 6px);
}

.attention-mark-forecast-danger {
  background: repeating-linear-gradient(-45deg, var(--danger) 0 3px, var(--danger-soft) 3px 6px);
}

.attention-mark-forecast-severe {
  background: repeating-linear-gradient(-45deg, var(--severe) 0 3px, var(--danger-soft) 3px 6px);
}

/* A pill whose repeat belongs to a planned cycle carries the cycle mark,
   centred, in white on the pill's tone. */
.attention-mark-cycle {
  display: block;
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 0.875rem;
  color: var(--ink-on-accent);
}

/* On a striped pill the cycle mark stays white, lifted off the stripes by
   a dark halo (Jim, 2026-10-07: ink alone did not stand out). */
.attention-mark-cycle-forecast {
  display: block;
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 0.875rem;
  color: var(--ink-on-accent);
  text-shadow: 0 0 2px var(--ink), 0 0 2px var(--ink), 0 0 1px var(--ink);
}

/* A day a warning reaches without marking it (the start of a run, the day
   a similar movement or a shared muscle sits on): the same pill, outlined
   and dotted, empty. */
.attention-context {
  display: block;
  width: 100%;
  height: 0.875rem;
  border: 2px dotted var(--line);
  border-radius: var(--radius-sm);
}

.attention-context-caution {
  border-color: var(--caution);
}

.attention-context-danger {
  border-color: var(--danger);
}

/* Pointing at a mark joins it to the days it reaches: the cells between
   carry a dotted line at the pill's middle, and the reached day's outline
   goes solid. month_score_controller.js sets the attributes. */
.score-cell[data-linked="between"] {
  background-image: linear-gradient(to right, var(--ink-muted) 50%, transparent 50%);
  background-size: 6px 2px;
  background-repeat: repeat-x;
  background-position: center;
}

.attention-context[data-linked="end"] {
  border-style: solid;
}

.attention-shortfalls {
  display: grid;
  gap: var(--space-1);
}

.attention-subheading {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}


/* The grid's top line: its note on the left, the key to its marks on the
   right (Components::AttentionGrid#render_legend). */
.attention-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1) var(--space-4);
}

.attention-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  margin: 0 0 0 auto;
  padding: 0;
  list-style: none;
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.attention-legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* A swatch is a small pill drawn by the mark's own tone class beside it. */
.attention-legend-swatch {
  display: inline-block;
  width: 1.5rem;
  height: 0.75rem;
  border-radius: var(--radius-sm);
}

.attention-legend-cycle {
  font-weight: 700;
  color: var(--ink);
}

/* A grid that carries its own readout (the dashboard, the What repeats
   modal). */
.attention-standalone {
  display: grid;
  gap: var(--space-2);
}

/* The month review's closed sections in one row (targets, needs
   attention, highlight). The open one drops below the row at full width,
   so the summaries stay together and the weeks follow straight after. */
.month-review-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-4);
}

.month-review-tool[open] {
  flex-basis: 100%;
  order: 1;
}

/* Nothing to say yet: the readout keeps its line but shows no empty pill. */
.score-readout:empty {
  visibility: hidden;
}

/* The month's highlight (Views::PlanCalendars::LensBar): how picks
   combine, then one row per thing a session is picked by, the group's
   name in a fixed column so the rows' toggles line up. */
.lens-bar {
  display: grid;
  gap: var(--space-1);
}

.lens-bar-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.lens-bar-title {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.lens-group {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1) var(--space-2);
}

.lens-group-label {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-muted);
}

/* A phone keeps each group to one line that scrolls sideways, every
   toggle at its full width. */
.lens-options {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: max-content;
  justify-content: start;
  overflow-x: auto;
  scrollbar-width: thin;
}

/* How many of the month's days carry the choice, beside its name. */
.lens-count {
  margin-inline-start: var(--space-1);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  color: inherit;
  opacity: 0.75;
}

.lens-more {
  justify-self: start;
  width: 14rem;
  max-width: 100%;
  min-height: var(--tap);
  padding: 0 var(--space-2);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  font-size: 1rem;
  color: var(--ink);
}

.lens-more:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

@media (min-width: 48rem) {
  .lens-group {
    grid-template-columns: 5rem minmax(0, 1fr);
    align-items: start;
  }

  .lens-group-label {
    padding-top: var(--space-2);
  }

  .lens-options {
    display: flex;
    flex-wrap: wrap;
    overflow-x: visible;
  }

  .lens-more {
    grid-column: 2;
  }
}

@media (pointer: fine) {
  .lens-more {
    min-height: var(--tap-fine);
    font-size: var(--text-sm);
  }
}
