/* Normal Week: a week calendar on one CSS grid (design.md of add-normal-week-view, The grid).
   Ruby works out every position; each element sets only --column, --row-start, --row-end, --lane
   and --lanes, and the rules here place it. Colour means a person: bodies are a tint of the
   attendee's colour, drop-off and pick-up caps are solid (docs/visual-design.md). */

.week-empty {
  color: var(--color-muted);
}

/* The page is wider than page--wide so the legend can sit beside a full-width calendar. */
.page--week {
  max-width: 1400px;
  padding-top: 12px;
  padding-bottom: 8px;
}

/* Title and legend above the calendar on a narrow screen, in a column to its left on a wide one,
   so a laptop window has its height for the hours. */
.week-page {
  display: grid;
  gap: 16px;
}

@media (min-width: 56rem) {
  .week-page {
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: 24px;
    align-items: start;
  }

  .week-page__side h1 {
    margin: 0 0 16px;
    font-size: 1.5rem;
  }

  /* One legend item per line in the narrow column. */
  .week-page__side .week-legend__groups {
    flex-direction: column;
    gap: 16px;
  }

  .week-page__side .week-legend__group {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  .week-page__side .week-legend__group dt {
    flex-basis: auto;
  }
}

/* The calendar scrolls sideways inside this box on a narrow screen, never the page. */
.week-scroll {
  position: relative;
  overflow-x: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.week {
  /* One row of the band for all-day and multi-day dates. */
  --band-row: 1.75rem;
  /* Everything in the window above and below the time rows: the app header, the page's padding,
     the day-name row, the last hour label's row and the box's padding. Measured in the browser
     (about 151px), plus the band above the hours on a week that has one; change it with any of those. */
  --week-chrome: calc(9.5rem + var(--band-rows, 0) * var(--band-row));
  /* One row per five minutes, sized so the whole day fits the window: at least 0.32rem (about 61px
     an hour, enough for a 60-minute block's two caps and a line of body) and at most 0.5rem (96px
     an hour), so short windows scroll and tall ones don't stretch. */
  --slot: clamp(0.32rem, (100dvh - var(--week-chrome)) / var(--slots), 0.5rem);

  display: grid;
  /* --columns comes from Ruby: a busy day gets 7rem for each block side by side. */
  grid-template-columns: var(--columns);
  grid-template-rows: auto repeat(var(--slots), var(--slot)) auto;
  min-width: var(--min-width);
  padding: 0 8px 8px 0;
}

/* Sections keep each day's heading and blocks together for screen readers; visually every
   element sits on the one grid. */
.week__day {
  display: contents;
}

.week__day-name {
  grid-column: var(--column);
  grid-row: 1;
  margin: 0;
  /* The band shares this row, below the name, so no block's row number depends on it. */
  padding: 6px 4px calc(6px + var(--band-rows, 0) * var(--band-row));
  font-size: 0.875rem;
  text-align: center;
  border-bottom: 1px solid var(--color-border);
}

.week__day-name--today {
  color: var(--color-accent);
}

/* An all-day or multi-day date, across the days it covers, under the day names. */
.week-banner {
  grid-column: calc(var(--first) + 1) / calc(var(--last) + 2);
  grid-row: 1;
  position: relative;
  z-index: 1;
  align-self: start;
  /* The name row is about 2rem tall: each lane sits a row further down from there. */
  margin: calc(2rem + var(--lane) * var(--band-row)) 2px 0;
  height: calc(var(--band-row) - 3px);
  overflow: hidden;
  color: var(--color-text);
  text-decoration: none;
  background: var(--color-bg);
  border-radius: 3px;
}

a.week-banner:hover {
  filter: brightness(1.2);
}

a.week-banner:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

.week-banner--neutral {
  background: var(--color-surface);
  box-shadow: inset 0 0 0 1px var(--color-border);
}

.week-banner__content {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  height: 100%;
  padding: 0 4px;
  font-size: 0.75rem;
  font-weight: 600;
}

.week-banner__content .member-badge {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  font-size: 0.8rem;
}

.week-banner__name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* A cancelled date stays in place, muted and struck through, with no caps. */
.week-entry--cancelled,
.week-banner--cancelled {
  opacity: 0.55;
}

.week-entry--cancelled .week-entry__name,
.week-banner--cancelled .week-banner__name,
.week-legend__cancelled {
  text-decoration: line-through;
}

/* Marks a date changed on its own. Never colour alone, and never lime. */
.week-entry__changed {
  flex: none;
  color: var(--color-muted);
  font-size: 0.7rem;
}

.week__column {
  grid-column: var(--column);
  grid-row: 2 / -2;
  border-left: 1px solid var(--color-border);
}

.week__hour {
  grid-column: 1;
  grid-row: var(--row);
  padding-right: 6px;
  color: var(--color-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
  transform: translateY(-0.5em);
}

.week__line {
  grid-column: 2 / -1;
  grid-row: var(--row);
  border-top: 1px solid var(--color-border);
  opacity: 0.5;
}

/* A block: drop-off cap, body, pick-up cap. Overlapping blocks share the day's width by lane. */
.week-entry {
  grid-column: var(--column);
  grid-row: var(--row-start) / var(--row-end);
  /* Positioned so its hidden description stays inside the scrolling box. */
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 2px;
  width: calc(100% / var(--lanes) - 4px);
  margin-left: calc(100% * var(--lane) / var(--lanes) + 2px);
  overflow: hidden;
  color: var(--color-text);
  text-decoration: none;
  background: var(--color-bg);
  border-radius: var(--radius);
}

a.week-entry:hover .week-entry__body {
  filter: brightness(1.2);
}

a.week-entry:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

/* Each part has a fixed place, so a block with no drop-off still keeps its body in the middle. */
.week-cap--dropoff { grid-row: 1; }
.week-entry__body { grid-row: 2; }
.week-cap--pickup { grid-row: 3; }

/* Short blocks put the caps at the sides. */
.week-entry--compact {
  grid-template-rows: none;
  grid-template-columns: auto 1fr auto;
}

.week-entry--compact > * { grid-row: 1; }
.week-entry--compact .week-cap--dropoff { grid-column: 1; }
.week-entry--compact .week-entry__body { grid-column: 2; }
.week-entry--compact .week-cap--pickup { grid-column: 3; }

/* The body's size comes from the grid, never its content, so it can be a container that the icon
   steps and the narrow-name rule below measure. */
.week-entry__body {
  position: relative;
  container-type: size;
  min-height: 0;
  overflow: hidden;
  border-radius: 3px;
}

.week-entry--neutral .week-entry__body {
  background: var(--color-surface);
  box-shadow: inset 0 0 0 1px var(--color-border);
}

/* One pale stripe per attendee, behind the content. */
.week-entry__stripes {
  position: absolute;
  inset: 0;
  display: flex;
}

.week-entry__stripe {
  flex: 1;
  background: color-mix(in srgb, var(--member) 22%, var(--color-surface));
  border-left: 3px solid color-mix(in srgb, var(--member) 60%, var(--color-surface));
}

.week-entry__content {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 2px 4px;
  font-size: 0.75rem;
  line-height: 1.3;
}

.week-entry__title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 2px;
  font-weight: 600;
}

.week-entry__title .member-badge {
  width: 1.1rem;
  height: 1.1rem;
  font-size: 0.8rem;
}

/* Bigger attendee icons when the body has the height for them: a school day gets the largest. */
@container (min-height: 2.75rem) {
  .week-entry__title {
    flex-wrap: nowrap;
    align-items: flex-start;
  }

  .week-entry__title .member-badge {
    width: 1.6rem;
    height: 1.6rem;
    font-size: 1.15rem;
  }

  /* The name wraps beside the icon, not under it, so a short club keeps both lines in view. */
  .week-entry__name {
    flex: 1 1 0;
    min-width: 0;
  }
}

@container (min-height: 8rem) {
  .week-entry__title {
    gap: 2px;
  }

  .week-entry__title .member-badge {
    width: 2rem;
    height: 2rem;
    font-size: 1.4rem;
  }

  .week-entry__title {
    flex-wrap: wrap;
  }

  .week-entry__name {
    flex-basis: 100%;
  }
}

/* A narrow block keeps its name on one line with an ellipsis rather than breaking inside a word;
   the tooltip and description carry the full name. */
@container (max-width: 5rem) {
  .week-entry__title {
    flex-wrap: nowrap;
  }

  .week-entry__title .member-badge {
    width: 1.1rem;
    height: 1.1rem;
    font-size: 0.8rem;
  }

  .week-entry__name {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}

.week-entry__times,
.week-entry__marker {
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* A drop-off or pick-up; its colours come from journeys.css. */
.week-cap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  min-height: 1.3rem;
  padding: 1px 4px;
  font-size: 1rem;
  font-weight: 600;
  border-radius: 3px;
}

.week-entry--compact {
  container-type: inline-size;
}

.week-entry--compact .week-cap {
  justify-content: center;
  width: 1.75rem;
}

/* A compact block in a narrow lane gives its caps less room, so its name has some. */
@container (max-width: 7rem) {
  .week-entry--compact .week-cap {
    width: 1.25rem;
    padding: 0;
  }
}

.week-cap__time {
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

/* Live Calendar: which week, above the legend. */
.week-nav {
  margin-bottom: 16px;
}

.week-hint {
  margin: 0 0 0.75rem;
  color: var(--color-muted);
  font-size: 0.8125rem;
}

.week-nav__range {
  margin: 0 0 8px;
  font-weight: 600;
}

.week-nav__steps {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}

.week-nav__steps .button {
  padding-inline: 10px;
  white-space: nowrap;
}

.week-nav__picker {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: end;
  margin: 0;
}

.week-nav__picker .field {
  margin: 0;
}

.week-nav__picker [hidden] {
  display: none;
}

/* The key above the calendar. */
.week-legend {
  margin-bottom: 16px;
}

.week-legend__groups {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 32px;
  margin: 0;
}

.week-legend__group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 16px;
}

.week-legend__group dt {
  flex-basis: 100%;
  color: var(--color-muted);
  font-size: 0.875rem;
}

.week-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 0.875rem;
}

.week-legend__journey .week-cap {
  width: 1.75rem;
  height: 1.3rem;
  justify-content: center;
}

/* The Live Calendar's popup: over the calendar, filling the screen on a phone. */
.occurrence-popup {
  width: min(640px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100dvh - 2 * var(--gutter));
  padding: 16px 20px;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.occurrence-popup::backdrop {
  background: rgb(1 4 9 / 0.7);
}

@media (max-width: 599px) {
  .occurrence-popup {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border: 0;
    border-radius: 0;
  }
}

.popup__header {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 8px;
}

/* Name, date and who on one line where they fit, to leave the height for the form. */
.popup__heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
}

.popup__title {
  margin: 0;
  font-size: 1.25rem;
}

.popup__date {
  margin: 0;
  color: var(--color-muted);
}

.popup__close {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -10px -10px 0 0;
  color: var(--color-text);
  font-size: 1.25rem;
}

.popup__summary {
  margin-bottom: 12px;
  padding: 2px 8px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.popup__summary .schedule-list__rows {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One line a schedule, with this date's marker beside its times. */
@media (min-width: 600px) {
  .popup__summary .schedule-list__row,
  .popup__summary .schedule-list__row:last-child {
    grid-template-columns: 5.5rem auto 1fr 1.75rem 1.75rem;
    grid-template-areas: "days times extras dropoff pickup";
    padding: 2px 4px;
  }

  .popup-mode__option {
    min-height: 36px;
  }
}

.occurrence-popup .schedule-form__run {
  margin-bottom: 8px;
  padding-bottom: 0;
}

/* Each label beside its field, which saves more height than anything else here. */
.occurrence-popup .schedule-form__run .field:not([hidden]) {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  align-items: center;
  gap: 4px;
  margin-bottom: 6px;
}

.occurrence-popup .schedule-form__run select,
.occurrence-popup .schedule-form__run input[type="text"],
.occurrence-popup .schedule-form__pair input[type="text"] {
  margin-bottom: 0;
}

.occurrence-popup .schedule-form__pair .field {
  margin-bottom: 6px;
}

/* Save stays in sight if the form still has to scroll. */
.occurrence-popup .schedule-form__actions {
  position: sticky;
  bottom: 0;
  z-index: 1;
  margin-top: 0;
  padding: 6px 0;
  background: var(--color-surface);
}

.popup__panel-title {
  margin: 16px 0 8px;
  font-size: 1rem;
}

.popup__notice {
  margin: 0 0 12px;
  padding: 8px 12px;
  background: var(--color-bg);
  border-left: 3px solid var(--color-accent);
  border-radius: 3px;
}

.popup__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px 12px;
  margin-top: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
}

.popup__actions p,
.popup__actions form {
  margin: 0;
}

.popup__actions p {
  flex: 1 1 100%;
}

.popup__cancel {
  display: flex;
  flex: 1 1 320px;
  align-items: flex-end;
  gap: 8px;
}

.popup__cancel .field {
  flex: 1;
  min-width: 0;
  margin: 0;
}

.popup__cancel input[type="text"] {
  margin-bottom: 0;
}

.popup__cancel input[type="submit"],
.popup__actions .button {
  padding-block: 8px;
  white-space: nowrap;
}

.popup-mode {
  display: flex;
  gap: 4px;
  margin-bottom: 12px;
  padding: 4px;
  background: var(--color-bg);
  border-radius: var(--radius);
}

.popup-mode__option {
  flex: 1;
  min-height: 44px;
  color: var(--color-muted);
  font: inherit;
  background: transparent;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
}

.popup-mode__option[aria-pressed="true"] {
  color: var(--color-text);
  font-weight: 600;
  background: var(--color-surface);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}

.popup-mode__option:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
