/* Weeks as rows (Components::Calendar::WeekGrid, WeekHead, PlanDay,
   SessionCard, WeekSummary): the plan calendar's month and, in time, the
   cycle planner. On a phone a week stacks, head then days then summary;
   from 64rem it lines up as nine columns under one day-of-week header. */

.week-grid {
  --week-grid-columns: 11rem repeat(7, minmax(0, 1fr)) 11rem;
  display: grid;
  gap: var(--space-2);
}

.week-grid-dow {
  display: none;
}

.week-grid-dow-day {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-muted);
  text-align: center;
}

.week-grid-row {
  display: grid;
  gap: var(--space-1);
  scroll-margin-top: var(--space-6);
  border-radius: var(--radius-md);
  transition: box-shadow 300ms ease-out;
}

/* A row a link pointed at, outlined for a moment (plan_calendar_controller.js). */
.week-grid-row[data-highlight="true"] {
  box-shadow: 0 0 0 2px var(--accent);
}

/* A month's name between its weeks. */
.week-grid-heading {
  padding-top: var(--space-2);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--ink);
}

/* Week head: the week's dates, the cycles it falls in, its actions. */
.week-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: flex-start;
  gap: var(--space-1) var(--space-2);
  padding: var(--space-2);
  background: var(--stratum-head);
  border-radius: var(--radius-md);
}

.week-head-label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}

.week-head-dates {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}

.week-head-cycles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  min-width: 0;
}

/* One cycle in the head: its chip, then its week actions. */
.week-head-cycle {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.week-head-cycle-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.week-head-note {
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.week-head-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

/* A day: its head (date, tags, actions), then its sessions. */
.plan-day {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  min-height: var(--tap);
  padding: var(--space-2);
  background: var(--surface);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
}

.plan-day[aria-current="date"] {
  box-shadow: 0 0 0 2px var(--accent);
}

/* A day outside the span the page is about: kept so the week reads whole,
   stepped back so the span stands out. */
.plan-day-outside {
  background: var(--surface-sunken);
  opacity: 0.6;
}

/* Days a traced row misses step back (month_score_controller.js). */
.plan-day[data-score-match="false"] {
  opacity: 0.3;
  transition: opacity 160ms ease-out;
}

/* Days and sessions the month's highlight misses step back the same way. */
.plan-day[data-lens-match="false"] {
  opacity: 0.3;
  transition: opacity 160ms ease-out;
}

.session-card[data-lens-match="false"] {
  opacity: 0.35;
  transition: opacity 160ms ease-out;
}

/* What a lit session matched ("Push · Squat"), in words, so the light
   never rests on fading alone. */
.session-card-lens {
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--accent-ink);
  line-height: var(--leading);
}

/* The date opens the whole day (the day details: its plan, warnings and
   load). */
.plan-day-date-button {
  min-height: var(--tap-dense);
  padding: 0 var(--space-1);
  margin-inline-start: calc(var(--space-1) * -1);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-muted);
  text-decoration: underline dotted;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.plan-day-date-button:hover {
  background: var(--surface-sunken);
  color: var(--ink);
}

.plan-day-date-button:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

.plan-day-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
}

.plan-day-date {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-muted);
}

.plan-day-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.plan-day-actions {
  display: flex;
  gap: var(--space-1);
  margin-left: auto;
}

.plan-day-error {
  font-size: var(--text-xs);
  color: var(--danger-ink);
}

.plan-day-undo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.plan-day-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* A session: name and state, stimulus, movements, minutes and heavy. */
.session-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  min-width: 0;
}

/* Work that is context rather than this plan's own. */
.session-card-quiet {
  opacity: 0.6;
}

/* Sessions the filter leaves out step back (plan_calendar_controller.js). */
.session-card[data-filtered="out"] {
  opacity: 0.25;
}

/* The context a quiet card sits in ("outside cycle"). */
.session-card-context {
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.session-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  max-width: 100%;
}

.session-card-name {
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: var(--leading-tight);
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.session-card-name:hover {
  text-decoration: underline;
}

.session-card-name:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.session-card-movements {
  font-size: var(--text-xs);
  line-height: var(--leading-tight);
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

/* A movement a repeat is about, toned like the chip that would say so;
   the name's title carries the coach's sentence. */
.session-card-movement-caution {
  color: var(--caution-ink);
  font-weight: 600;
}

.session-card-movement-danger {
  color: var(--danger-ink);
  font-weight: 600;
}

.session-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.session-card-heavy {
  font-weight: 600;
  color: var(--caution-ink);
}

.session-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

/* Week summary: the week's count, stimulus mix, heavy days, focus uses,
   then what needs attention that week. */
.week-summary {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  padding: var(--space-2);
  background: var(--surface);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
  font-size: var(--text-xs);
}

.week-summary-title {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink);
}

.week-summary-fact {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  color: var(--ink-muted);
}

.week-summary-value {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.week-summary-value-warn {
  color: var(--caution-ink);
}

.week-summary-note {
  color: var(--ink-muted);
}

.week-summary-attention {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: 0;
  margin-top: var(--space-1);
  list-style: none;
}

.week-summary-attention-item {
  display: flex;
}

.week-summary-trace {
  padding: 0;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}

.week-summary-trace:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-md);
}

@media (min-width: 64rem) {
  .week-grid-dow {
    display: grid;
    grid-template-columns: var(--week-grid-columns);
    gap: var(--space-1);
  }

  .week-grid-row {
    grid-template-columns: var(--week-grid-columns);
  }

  .week-head {
    flex-direction: column;
    align-items: flex-start;
    flex-wrap: nowrap;
  }

  .week-head-cycles {
    flex-direction: column;
    align-items: stretch;
  }

  .plan-day {
    min-height: 7rem;
  }
}

/* Arrange (Views::PlanCalendars::Day with arrange:): a day's sealed
   workouts, then its loose plan items in an open area of their own. */
.plan-day-sealed {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.plan-day-loose {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-height: var(--tap-dense);
  padding: var(--space-1);
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
}

/* The slot the day's fatigue marker fills; nothing until it does. The
   marker is a chip-sized button, kept at a finger's width to hit. */
.plan-day-fatigue:empty {
  display: none;
}

.plan-day-fatigue-trigger {
  min-height: var(--tap-dense);
}

/* The popover body: one row per muscle, its two readings under its name. */
.day-fatigue {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 16rem;
}

/* The rows scroll inside a capped list so the panel, which opens below its
   marker, never runs past the window and "Open the day" stays in reach. */
.day-fatigue-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-height: min(24rem, 50vh);
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.day-fatigue-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-1) var(--space-2);
}

.day-fatigue-muscle {
  grid-column: 1 / -1;
  font-weight: 600;
}

.day-fatigue-reading {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}

.day-fatigue-caption,
.day-fatigue-none {
  color: var(--ink-muted);
  font-size: var(--text-sm, 0.875rem);
}

/* The same readings as one line per muscle under one caption row, for a
   wide list (the week proposal): name, carried, added. */
.day-fatigue-inline {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.day-fatigue-inline-head {
  display: grid;
  grid-template-columns: minmax(7rem, 1fr) auto auto;
  gap: var(--space-2);
  color: var(--ink-muted);
  font-size: var(--text-xs);
}

.day-fatigue-inline-row {
  display: grid;
  grid-template-columns: minmax(7rem, 1fr) auto auto;
  align-items: center;
  gap: var(--space-2);
}

.day-fatigue-inline-name {
  font-weight: 600;
}

/* A loose plan item: grip, name, minutes and Remove on one row that wraps. */
/* A loose plan item in a narrow day column: grip and name, its minutes,
   then Remove and its menu on one line. The card stays a column (as
   .session-card) so the name keeps the column's full width. */
.session-card-loose {
  padding: var(--space-1);
  background: var(--surface);
  border-radius: var(--radius-sm);
}

.session-card-actions-loose {
  align-self: stretch;
  flex-wrap: nowrap;
}

/* A head with a grip keeps the name beside it however the name wraps; the
   state chip takes the line under the name. */
.session-card-head-grip {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
}

.session-card-state {
  grid-column: 2;
  justify-self: start;
}

/* A narrow strip of dots before the name, the height of its line: a mouse
   grabs it at a desk, the only place drag runs. */
.session-card-handle {
  flex: none;
  align-self: stretch;
  width: 0.625rem;
  min-height: 1rem;
  background-image: radial-gradient(circle, var(--ink-muted) 1px, transparent 1.25px);
  background-size: 0.3125rem 0.3125rem;
  cursor: grab;
  user-select: none;
}

.session-card-handle:active {
  cursor: grabbing;
}



.session-card-remove {
  display: flex;
  margin-left: auto;
}

/* A loose item's ⋯: no box and no caret, so Remove and the menu share one
   line in a day column. */
.session-menu-compact {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap-dense);
  min-height: var(--tap-dense);
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  cursor: pointer;
}

.session-menu-compact:hover {
  background: var(--surface-sunken);
  color: var(--ink);
}

.session-menu-compact:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Drag and the inline Remove are for a desk (plan_arrange_controller.js
   gates drag the same way). Below the grid's width or on a touch screen the
   grip would be a dead control and Remove a second copy of the menu's, so
   both go and the item's menu moves and removes it (Jim, 2026-10-08). */
@media (max-width: 63.99rem), (pointer: coarse) {
  .session-card-handle,
  .session-card-remove {
    display: none;
  }
}

/* A released day: quieter ground, nothing moves in or out. */
.plan-day-locked {
  background: var(--surface-sunken);
}

.plan-day-reopen {
  display: flex;
}

/* What the pointer finds while dragging over a day, in words as well as
   outline (plan_arrange_controller.js sets data-arrange-drop). */
.plan-day[data-arrange-drop] {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.plan-day[data-arrange-drop="over"] {
  outline-color: var(--caution-ink);
}

.plan-day[data-arrange-drop="locked"] {
  outline-color: var(--line);
}

.plan-day[data-arrange-drop]::after {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink);
}

.plan-day[data-arrange-drop="fits"]::after {
  content: "Fits";
}

.plan-day[data-arrange-drop="over"]::after {
  content: "Over session time";
}

.plan-day[data-arrange-drop="locked"]::after {
  content: "Locked";
}
