/* ============================================================
   UCMS Provider Scheduler (Epic 1) - design prototype
   My Availability family: screens 10 to 19.

     10-my-availability.html          <- board frame 172:1503
     11-schedule-details.html         <- 172:1695 (upper) + 172:2430
     12-wizard-session-details.html   <- 172:2692
     13-wizard-weekly-hours.html      <- 172:1840, nested in 172:1695
     14-wizard-date-specific.html     <- 172:2949
     15-wizard-calendar-view.html     <- 172:3148
     16-wizard-capacity-pacing.html   <- 172:3458
     17-wizard-time-blocking.html     <- 172:3635
     18-wizard-preview-confirm.html   <- 172:3814
     19-availability-published.html   <- 172:4184

   Loads AFTER css/styles.css and css/calendar.css. The shell, the
   collapsible rail, the form primitives, the drawer, the segmented
   control, the message boxes and the snackbar all come from those
   two files unchanged; this file adds only what this section needs.

   No rule below states a colour value. The one :root block declares
   the two tints CDS ships no lighter step for, in the same style as
   calendar.css, and nothing else here writes a colour.

   Styling source of truth: TELUS Consistency Design System (CDS),
   reference/cds/. Sample data is illustrative throughout.
   ============================================================ */

:root {
  /* Two washes, each an opacity ramp off a colour styles.css already
     declares. green-400 at 12 percent is the "available" day cell in
     the two month grids: it sits under a date, so it stays light
     enough for neutral-450 to clear 4.5:1 on it. neutral-350 at 6
     percent is the read-only surface an admin-set value sits on. */
  --cds-green-400-opacity-12: rgba(43, 128, 0, 0.12);
  --cds-neutral-350-opacity-06: rgba(104, 110, 113, 0.06);

  /* Layout metrics, no colour */
  --pp-av-cal-min: 640px;
  --pp-av-panel: 400px;
}

/* ============================================================
   Page head - title, lede and the section toolbar
   ============================================================ */
.av-head {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-25);
}

.av-head__title {
  font-size: var(--cds-hd-title-size);
  line-height: var(--cds-line-height-title);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.av-head__lede {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.av-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cds-space-100);
  flex-wrap: wrap;
}

.av-bar__title {
  font-size: var(--cds-txt-subhead-size);
  line-height: var(--cds-line-height-subhead);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.av-bar__note {
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

/* ============================================================
   Success banner (board frame 172:4184)
   Dismissed in place: the banner is a state of this page, not a
   page of its own.
   ============================================================ */
.av-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-medium);
  border: 1px solid var(--cds-green-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-green-400-opacity-07);
}

.av-banner__icon {
  display: grid;
  place-items: center;
  flex: none;
  color: var(--cds-green-400);
}

.av-banner__icon svg {
  width: 20px;
  height: 20px;
}

.av-banner__title {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.av-banner__body {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.av-banner__text {
  flex: 1;
  min-width: 0;
}

/* ============================================================
   Schedule cards

   Crit 242:246 closed: the board coded each schedule with a bare
   purple or orange bar and nothing to read it by, and orange already
   means "on hold" on the calendar. The publish state is now carried
   by the Live or Draft badge beside the name and by nothing else, so
   there is one signal for one fact. Bryan 317:454 asks for exactly
   that badge in the card header.
   ============================================================ */
.sch-list {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-150);
}

.sch {
  position: relative;
  overflow: hidden;
}

/* The schedule the panel beside the list is reading. Selection is a
   different fact from publish state, so it keeps a marker: a brand
   rule down the leading edge plus a tint on the card, with
   aria-current carrying the same fact to a screen reader. */
.sch[aria-current="true"] {
  border-color: var(--cds-primary-brand);
  background: var(--cds-primary-brand-opacity-10);
}

.sch[aria-current="true"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  background: var(--cds-primary-brand);
}

/* The selected card sits on a 10 percent purple wash over the neutral-10
   canvas, which composites to rgb(233, 229, 236). Secondary text at
   neutral-350 measures 4.16:1 there, under the floor, so it runs one step
   darker on this card only. Same deviation the session list already makes
   on its own selected row. */
.sch[aria-current="true"] .sch__meta,
.sch[aria-current="true"] .sch__note {
  color: var(--cds-neutral-450);
}

.sch__head {
  display: flex;
  align-items: center;
  gap: var(--cds-space-100);
  padding: var(--cds-padding-medium) var(--cds-padding-large);
}

.sch__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--cds-primary-brand-opacity-10);
  color: var(--cds-primary-brand);
}

.sch[data-state="draft"] .sch__icon {
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-450);
}

.sch__icon svg {
  width: 20px;
  height: 20px;
}

.sch__text {
  flex: 1;
  min-width: 0;
}

.sch__name {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  flex-wrap: wrap;
  font-size: var(--cds-txt-body-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.sch__meta {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

.sch__note {
  margin-top: var(--cds-space-25);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

.sch__actions {
  display: flex;
  align-items: center;
  gap: var(--cds-space-25);
  flex: none;
}

.sch__toggle {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--cds-radius-small);
  background: transparent;
  color: var(--cds-neutral-350);
  cursor: pointer;
}

.sch__toggle svg {
  width: 20px;
  height: 20px;
  transition: transform 200ms ease-out;
}

.sch__toggle[aria-expanded="false"] svg {
  transform: rotate(180deg);
}

.sch__toggle:hover {
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-500);
}

.sch__panel {
  padding: var(--cds-padding-medium) var(--cds-padding-large) var(--cds-padding-large);
  border-top: 1px solid var(--cds-neutral-100);
  background: var(--cds-neutral-10);
}

.sch__panel-label {
  margin-bottom: var(--cds-space-75);
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cds-neutral-350);
}

/* Session type rows inside an expanded schedule card */
.st-list {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-50);
}

.st-row {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-small) var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
}

.st-row__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-450);
}

.st-row__icon svg {
  width: 16px;
  height: 16px;
}

.st-row__text {
  flex: 1;
  min-width: 0;
}

.st-row__name {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.st-row__meta {
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

/* ============================================================
   Wizard step rail (board frames 172:2692 onward)

   Every step is a link, so the prototype walks in both directions.
   The board draws the steps ahead of the current one as inert
   circles; that is recorded as a judgement call on the index.

   The rail is one row and stays one row. It used to wrap, which
   dropped step 5 onto a second line with a connector dangling off
   the end whenever the column narrowed, and the column narrows by
   the width of a panel on the Calendar View tab. Three rules keep
   it honest instead: the row never wraps, the connectors are the
   only elastic part so they take the squeeze before anything else,
   and the rail is its own query container, so when even the
   squeezed row will not fit the step names step aside and the
   numbers carry the rail. Nothing about that depends on which
   screen it is or whether a panel is open, so all seven wizard
   screens behave the same way at the same width.
   ============================================================ */
.wiz {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  container-type: inline-size;
  container-name: wizrail;
}

.wiz__step {
  display: flex;
  align-items: center;
  flex: none;
}

.wiz__link {
  display: inline-flex;
  align-items: center;
  gap: var(--cds-space-50);
  padding: var(--cds-space-25);
  border-radius: var(--cds-radius-btn-medium);
  text-decoration: none;
  color: var(--cds-neutral-350);
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
}

.wiz__name {
  white-space: nowrap;
}

.wiz__link:hover {
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-500);
}

.wiz__num {
  display: grid;
  place-items: center;
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--cds-neutral-200);
  background: var(--cds-neutral-0);
  color: var(--cds-neutral-350);
  font-size: var(--cds-txt-caption-size);
  font-variant-numeric: tabular-nums;
}

.wiz__num svg {
  width: 16px;
  height: 16px;
}

.wiz__step[data-state="done"] .wiz__num {
  border-color: var(--cds-primary-brand);
  background: var(--cds-primary-brand);
  color: var(--cds-neutral-0);
}

.wiz__step[data-state="done"] .wiz__link {
  color: var(--cds-neutral-450);
}

.wiz__step[data-state="current"] .wiz__num {
  border-color: var(--cds-primary-brand);
  color: var(--cds-primary-brand);
}

.wiz__step[data-state="current"] .wiz__link {
  color: var(--cds-primary-brand);
}

/* The connector is the elastic part of the rail: it draws at 24px
   where there is room and gives up to 8px back before any label is
   touched. Four of them carry 64px of squeeze on their own. */
.wiz__rule {
  flex: 0 1 24px;
  min-width: 8px;
  height: 1px;
  background: var(--cds-neutral-200);
}

/* Below this the squeezed row would run past the column, so the
   step names give way and the numbers carry the rail, exactly as
   they already do on a narrow screen. The current step keeps its
   name, so the rail always says where you are. */
@container wizrail (max-width: 675px) {
  .wiz__name {
    display: none;
  }

  .wiz__step[data-state="current"] .wiz__name {
    display: inline;
  }
}

.wiz-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cds-space-100);
  flex-wrap: wrap;
  padding-top: var(--cds-padding-medium);
  border-top: 1px solid var(--cds-neutral-100);
}

.wiz-foot__end {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  margin-left: auto;
}

/* ============================================================
   Card body inside the wizard
   ============================================================ */
.pane {
  padding: var(--cds-padding-large);
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-150);
}

.pane__head {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-25);
}

.pane__title {
  font-size: var(--cds-txt-subhead-size);
  line-height: var(--cds-line-height-subhead);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.pane__lede {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.pane__split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--cds-space-150);
  align-items: start;
}

/* ============================================================
   Session type cards (board frame 172:2692)

   Bryan 317:399 "yes I want to add an edit pencil to each card":
   the pencil sits in the card header beside the checkbox.
   Crit 242:347 is answered by the same control - it is the way out
   of a read-only card to the place the values are actually set.
   ============================================================ */
.type-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--cds-space-150);
}

/* A card is a choice, so it has to look like one. Unselected it is a
   neutral card; selected it takes the brand fill, a brand border and a
   second inset edge, so the state survives a greyscale print as well as
   a colour screen. Everything but the pencil is inside a label, so the
   whole card is the hit area. Screen 18 shows the same cards as a
   record of what was chosen, and marks them with data-selected. */
.type-card {
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  overflow: hidden;
  background: var(--cds-neutral-0);
}

.type-card:has(input:checked),
.type-card[data-selected="true"] {
  border-color: var(--cds-primary-brand);
  box-shadow: inset 0 0 0 1px var(--cds-primary-brand);
}

.type-card__head {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-medium);
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-500);
}

.type-card:has(input:checked) .type-card__head,
.type-card[data-selected="true"] .type-card__head {
  background: var(--cds-primary-brand);
  color: var(--cds-neutral-0);
}

/* The clickable part of the card. The pencil sits outside it, so
   reaching Preferences never toggles the choice. */
.type-card__hit {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.type-card__glyph {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--cds-neutral-100);
  color: var(--cds-neutral-450);
}

.type-card:has(input:checked) .type-card__glyph,
.type-card[data-selected="true"] .type-card__glyph {
  background: var(--cds-primary-300);
  color: var(--cds-neutral-0);
}

.type-card__glyph svg {
  width: 18px;
  height: 18px;
}

.type-card__name {
  flex: 1;
  min-width: 0;
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
}

.type-card__pencil {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: var(--cds-radius-small);
  color: var(--cds-neutral-450);
  text-decoration: none;
}

.type-card:has(input:checked) .type-card__pencil {
  color: var(--cds-neutral-0);
}

.type-card__pencil svg {
  width: 18px;
  height: 18px;
}

.type-card__pencil:hover {
  background: var(--cds-neutral-100);
  color: var(--cds-neutral-500);
}

.type-card:has(input:checked) .type-card__pencil:hover {
  background: var(--cds-primary-500);
  color: var(--cds-neutral-0);
}

.type-card__check {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.type-card__check input {
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--cds-primary-brand);
}

.type-card:has(input:checked) .type-card__check input {
  accent-color: var(--cds-neutral-0);
}

.type-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-50);
  padding: var(--cds-padding-medium);
}

/* The body is the second half of the card's hit area on step 1. On the
   preview step it is a plain div and inherits nothing from this. */
label.type-card__body {
  cursor: pointer;
}

.type-card__fact {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.type-card__fact svg {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--cds-neutral-350);
}

.type-card__fact + .type-card__fact {
  margin-top: 0;
}

.type-card__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cds-space-50) var(--cds-space-150);
}

/* The validation line under the grid. It states the rule at rest and
   turns into an error only once a provider has cleared every box. */
.validate {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

.validate[data-error="true"] {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  color: var(--cds-red-450);
}

.validate svg {
  width: 16px;
  height: 16px;
  flex: none;
}

/* ============================================================
   Switch (day on/off, pacing toggles)

   CDS ships a Toggle at 48 x 24. There is no icon inside it, so the
   state is always paired with a word beside it - "Available" or
   "Unavailable" on a day, "On" or "Off" on a setting.
   ============================================================ */
.switch {
  display: inline-flex;
  align-items: center;
  flex: none;
  width: 44px;
  height: 24px;
  padding: 2px;
  border: 0;
  border-radius: 12px;
  background: var(--cds-neutral-200);
  cursor: pointer;
  transition: background-color 150ms ease-out;
}

.switch::before {
  content: "";
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--cds-neutral-0);
  transition: transform 150ms ease-out;
}

.switch[aria-checked="true"] {
  background: var(--cds-primary-brand);
}

.switch[aria-checked="true"]::before {
  transform: translateX(20px);
}

.switch:focus-visible {
  outline: 2px solid var(--cds-states-focus);
  outline-offset: 2px;
}

.switch-row {
  display: flex;
  align-items: flex-start;
  gap: var(--cds-space-100);
  padding: var(--cds-padding-medium) 0;
}

.switch-row + .switch-row {
  border-top: 1px solid var(--cds-neutral-100);
}

.switch-row__text {
  flex: 1;
  min-width: 0;
}

.switch-row__title {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.switch-row__help {
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

.switch-row__state {
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-450);
  min-width: 28px;
  text-align: right;
}

/* The state as its own word on its own line, which is how the weekly
   hours screen and the schedule panel say it. It used to be buried at
   the end of a help sentence as "Currently Off.", where the one thing a
   provider is scanning for read as an afterthought. */
.switch-row__word {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-450);
}

.switch-row__detail {
  margin-top: var(--cds-space-75);
  padding: var(--cds-padding-medium);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-10);
}

/* ============================================================
   Weekly hours rows (board frame 172:1840)
   ============================================================ */
.days {
  display: flex;
  flex-direction: column;
}

.day {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--cds-space-100);
  align-items: start;
  padding: var(--cds-padding-medium) 0;
}

.day + .day {
  border-top: 1px solid var(--cds-neutral-100);
}

.day__head {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
}

.day__name {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.day__off {
  display: flex;
  align-items: center;
  gap: var(--cds-space-100);
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

/* An available day states itself with its time ranges, so the word beside
   the switch appears only while the day is off. */
.day__off:empty {
  display: none;
}

.day__slots {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-50);
}

.slot-row {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
}

.slot-row .cds-input {
  max-width: 180px;
}

.slot-row__to {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

.slot-row__label {
  min-width: 52px;
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

.icon-x {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--cds-neutral-350);
  cursor: pointer;
}

.icon-x svg {
  width: 16px;
  height: 16px;
}

/* The last time slot on a day cannot be removed, so its X is disabled.
   It used to look exactly like a live one. */
.icon-x:disabled {
  color: var(--cds-neutral-200);
  cursor: not-allowed;
}

.icon-x:disabled:hover {
  background: transparent;
  color: var(--cds-neutral-200);
}

.icon-x:hover {
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-500);
}

.add-slot {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: var(--cds-space-50);
  height: 32px;
  padding: 0 var(--cds-padding-small);
  border: 0;
  border-radius: var(--cds-radius-btn-small);
  background: transparent;
  color: var(--cds-primary-brand);
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  cursor: pointer;
}

.add-slot svg {
  width: 16px;
  height: 16px;
}

.add-slot:hover {
  background: var(--cds-primary-brand-opacity-10);
}

/* ============================================================
   Copy a day's hours across other days

   The picker opens in normal flow under the day it belongs to
   rather than as a popover, for the same reason the appointments
   filter does: the card that holds it clips its own overflow, and
   an inline panel needs no outside-click handling to be correct.
   ============================================================ */
.day__actions {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  flex-wrap: wrap;
}

.copy {
  margin-top: var(--cds-space-75);
  padding: var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-10);
  max-width: 420px;
}

.copy__set {
  margin: 0;
  padding: 0;
  border: 0;
}

.copy__legend {
  padding: 0;
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.copy__days {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--cds-space-100);
  margin-top: var(--cds-space-50);
}

.copy__foot {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  margin-top: var(--cds-space-100);
}

.copy__error {
  margin-top: var(--cds-space-50);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-red-450);
}

.copy__error:empty {
  display: none;
}

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

/* ============================================================
   Month grid - the wizard's Calendar View tab and the preview
   ============================================================ */
/* calendar.css builds the segmented control for text-only items, so it sets
   no size on a glyph inside one. These three tabs carry an icon. */
.cds-seg__item svg {
  width: 16px;
  height: 16px;
  flex: none;
  margin-right: var(--cds-space-50);
}

.mgrid-scroll {
  overflow-x: auto;
}

.mgrid {
  min-width: var(--pp-av-cal-min);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  overflow: hidden;
  background: var(--cds-neutral-0);
}

/* The preview grid sits in half a card and carries no per-cell text, so it
   fits the column it is given rather than scrolling inside it. */
.mgrid--compact {
  min-width: 0;
}

.mgrid--compact .mgrid__cell {
  min-height: 56px;
  text-align: center;
}

.mgrid__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cds-space-100);
  padding: var(--cds-padding-medium);
  background: var(--cds-primary-brand);
  color: var(--cds-neutral-0);
}

.mgrid__month {
  font-size: var(--cds-txt-subhead-size);
  line-height: var(--cds-line-height-subhead);
  font-weight: var(--cds-font-weight-semibold);
}

.mgrid__head,
.mgrid__body {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.mgrid__head {
  border-bottom: 1px solid var(--cds-neutral-100);
}

.mgrid__head-cell {
  padding: var(--cds-space-50) 0;
  text-align: center;
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.06em;
  color: var(--cds-neutral-350);
}

.mgrid__cell {
  position: relative;
  min-height: 76px;
  padding: var(--cds-space-50);
  border-top: 1px solid var(--cds-neutral-100);
  border-left: 1px solid var(--cds-neutral-100);
  background: var(--cds-neutral-0);
  text-align: left;
  font: inherit;
  color: var(--cds-neutral-450);
  cursor: pointer;
}

.mgrid__cell:nth-child(7n + 1) {
  border-left: 0;
}

.mgrid__cell[data-state="available"] {
  background: var(--cds-green-400-opacity-12);
}

/* Reserved for a day with no bookable hour left at all. A day that keeps
   most of its hours and gives up a window is still an available day, so
   it keeps the green wash and takes the band below instead. Painting it
   fully peach said the whole of March 20 was gone, which was untrue. */
.mgrid__cell[data-state="blocked"] {
  background: var(--cds-orange-50-opacity-15);
}

.mgrid__cell[data-partial="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: var(--cds-orange-400);
}

/* Declared after the two state washes so a day that cannot be opened
   reads as inert whatever state it carries. neutral-300 measured
   3.22:1 on the inert wash. A disabled control is outside WCAG 1.4.3,
   but the date is still information, so it runs at neutral-350: one
   step darker, clears 4.5:1, and still sits two steps lighter than
   the neutral-450 a day you can open uses. */
.mgrid__cell[data-in="false"] {
  color: var(--cds-neutral-350);
  background: var(--cds-neutral-10);
  cursor: default;
}

.mgrid__cell[data-in="false"] .mgrid__tag {
  color: var(--cds-neutral-350);
}

.mgrid__cell[aria-pressed="true"] {
  outline: 2px solid var(--cds-primary-brand);
  outline-offset: -2px;
}

.mgrid__cell:hover[data-in="true"] {
  background: var(--cds-neutral-50);
}

.mgrid__num {
  display: block;
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  font-variant-numeric: tabular-nums;
}

/* neutral-350 on the available wash measures 4.40:1, so the cell tag runs
   one step darker at neutral-450. It runs at caption size rather than the
   10px caption-small it used to: an hour range is content, not a footnote,
   and 10px is under the floor this set holds everywhere else. Each range
   is its own line, so every one of them reads start-to-end with both
   meridiems rather than being shortened to fit. */
.mgrid__tag {
  display: block;
  margin-top: var(--cds-space-25);
  font-size: var(--cds-txt-caption-size);
  line-height: 1.25;
  color: var(--cds-neutral-450);
}

/* The band along the cell foot carries the orange; this line does not.
   orange-400 is the darkest orange CDS publishes and it measures 4.25:1
   on the available wash, under the floor, so the line runs at neutral-450
   and takes its emphasis from the weight. It also means the fact is never
   carried by colour alone. */
.mgrid__tag--off {
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-450);
}

.mgrid__foot {
  padding: var(--cds-padding-small) var(--cds-padding-medium);
  border-top: 1px solid var(--cds-neutral-100);
  background: var(--cds-neutral-10);
}

/* Legend. Bryan 317:436 removed Unavailable, and crit 244:501 asked
   for the difference to be explained rather than colour-coded, so
   each key carries a one-line meaning and the two grids share it. */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cds-space-50) var(--cds-space-200);
}

.legend__item {
  display: flex;
  align-items: flex-start;
  gap: var(--cds-space-50);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-450);
}

.legend__key {
  flex: none;
  width: 14px;
  height: 14px;
  margin-top: 2px;
  border-radius: var(--cds-radius-xsmall);
  border: 1px solid var(--cds-neutral-200);
}

.legend__key--available {
  background: var(--cds-green-400-opacity-12);
  border-color: var(--cds-green-400);
}

.legend__key--blocked {
  background: var(--cds-orange-50-opacity-15);
  border-color: var(--cds-orange-400);
}

/* The third state: a day that keeps its hours and gives one window up.
   The key is drawn the way the cell is, green with the band along its
   foot, so the legend and the grid cannot read two ways. */
.legend__key--partial {
  position: relative;
  overflow: hidden;
  background: var(--cds-green-400-opacity-12);
  border-color: var(--cds-green-400);
}

.legend__key--partial::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: var(--cds-orange-400);
}

.legend__name {
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

/* ============================================================
   Read-only values an administrator sets (Bryan 345:1447)
   ============================================================ */
.limits {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--cds-space-150);
}

.limit__label {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.limit__value {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  margin-top: var(--cds-space-50);
  padding: var(--cds-space-50) var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-350-opacity-06);
}

.limit__number {
  font-size: var(--cds-txt-subhead-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
  font-variant-numeric: tabular-nums;
}

.limit__unit {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.limit__lock {
  margin-left: auto;
  display: grid;
  place-items: center;
  color: var(--cds-neutral-350);
}

.limit__lock svg {
  width: 16px;
  height: 16px;
}

.limit__help {
  margin-top: var(--cds-space-50);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

/* ============================================================
   Summary rows on the preview step
   ============================================================ */
.sum {
  display: flex;
  flex-direction: column;
}

.sum__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--cds-space-100);
  padding: var(--cds-space-75) 0;
  border-bottom: 1px solid var(--cds-neutral-100);
}

.sum__name {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.sum__value {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
  text-align: right;
}

.sum__value--muted {
  font-weight: var(--cds-font-weight-regular);
  font-style: italic;
  color: var(--cds-neutral-350);
}

.sum__label {
  margin-top: var(--cds-space-100);
  margin-bottom: var(--cds-space-50);
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cds-neutral-350);
}

/* The day read-out crit 239:514 asked for: clicking a day in the
   preview grid states that day's hours instead of leaving the
   calendar day-level only. Bryan 317:429 "yes we need ot iterate
   this". */
.dayout {
  display: flex;
  align-items: flex-start;
  gap: var(--cds-space-50);
  padding: var(--cds-space-50) var(--cds-padding-small);
  border-radius: var(--cds-radius-xsmall);
  background: var(--cds-neutral-50);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-450);
}

.dayout svg {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 2px;
  color: var(--cds-neutral-350);
}

.dayout strong {
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

/* ============================================================
   Labelled sections inside the schedule drawer

   Crit 239:303 and 239:507 resolved, with Bryan 317:392 permitting
   it: the board hid buffers, limits, booking options, notifications
   and calendar invitations behind a "More options" button that
   opened a second panel on top of the first, three layers deep.
   They are labelled sections in the one drawer now.
   ============================================================ */
.sect {
  border-top: 1px solid var(--cds-neutral-100);
}

/* The section name was a span inside its button, so a screen reader
   moving by heading skipped all six sections. The heading wraps the
   button and carries no look of its own: the button keeps every
   pixel it had. */
.sect__h {
  margin: 0;
  font: inherit;
}

.sect__head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-medium) 0;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}

.sect__icon {
  display: grid;
  place-items: center;
  flex: none;
  color: var(--cds-neutral-350);
}

.sect__icon svg {
  width: 18px;
  height: 18px;
}

.sect__text {
  flex: 1;
  min-width: 0;
}

.sect__title {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.sect__sub {
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

.sect__chevron {
  flex: none;
  display: grid;
  place-items: center;
  color: var(--cds-neutral-350);
}

.sect__chevron svg {
  width: 20px;
  height: 20px;
  transition: transform 200ms ease-out;
}

.sect__head[aria-expanded="false"] .sect__chevron svg {
  transform: rotate(180deg);
}

.sect__body {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-100);
  padding-bottom: var(--cds-padding-medium);
}

/* Session type rows inside the drawer, each with a checkbox and a
   pencil, exactly as the board draws them. */
.stpick {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-small);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
}

.stpick:has(input:checked) {
  border-color: var(--cds-primary-brand);
  background: var(--cds-primary-brand-opacity-10);
}

.stpick input {
  width: 18px;
  height: 18px;
  flex: none;
  margin: 0;
  accent-color: var(--cds-primary-brand);
}

.stpick__text {
  flex: 1;
  min-width: 0;
}

.stpick__name {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

/* neutral-350 on the checked tint measures 4.33:1, under the 4.5:1 floor,
   so this meta line runs one step darker. */
.stpick__meta {
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-450);
}

/* ============================================================
   Blocked times (board frame 172:3635)
   ============================================================ */
.blk-list {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-75);
}

.blk {
  padding: var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
}

.blk__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--cds-space-100);
}

.blk__when {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.blk__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cds-space-50);
  margin-top: var(--cds-space-50);
}

.blk__reason {
  margin-top: var(--cds-space-50);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

/* ============================================================
   Side panel on the Calendar View tab

   It reuses .drawer for its geometry and its chrome. It used to
   paint its own brand-purple header while the schedule panel three
   screens away kept the white one every other drawer in the set
   uses; two chromes for one component is a difference that carries
   no meaning, so the purple one is gone and only the second line
   under the title is added here.
   ============================================================ */
.drawer__title-wrap {
  min-width: 0;
}

.drawer--day .drawer__sub {
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

/* Wide enough and the page beside it stays usable, so the panel is a
   non-modal side panel, the same contract screens 6 to 9 give the
   session panel. Narrow enough that the panel covers the page instead
   and it becomes a real modal: a scrim behind it, aria-modal set,
   the page behind it held still and the Tab ring kept inside. The
   switch is made in script, because ARIA cannot be written by a media
   query; the width below is the visual half of the same decision, and
   the two now change at the same width.

   They used to disagree. The modal treatment started at 1280 while the
   panel only went full width at 900, so between those two the panel was
   a 420px card with a scrim over a calendar that stayed on screen and
   could still be read but not touched. The panel covers the page at
   every width it claims to be modal at. */
@media (max-width: 1280px) {
  .drawer--day {
    --pp-drawer-width: 100vw;
  }
}

/* The page behind a modal panel holds still, so a scroll gesture over
   the scrim moves the panel's own body and nothing else. */
:root[data-day-modal="true"],
:root[data-day-modal="true"] body {
  overflow: hidden;
}

.drawer[data-open="false"] {
  transform: translateX(100%);
  visibility: hidden;
}

.drawer[data-open="true"] {
  transform: translateX(0);
  visibility: visible;
}

/* Content steps aside from an open panel on a wide screen rather than
   hiding under it, which is the rule screens 6 to 9 set. The column is
   given the width that is actually left over and left-aligned in it:
   keeping the auto margins and only pushing the right one over-constrains
   the box, and an over-constrained auto margin resolves to zero, which
   puts the content back under the panel. Both the top bar and the page
   body take the same treatment, so no action in either can hide. */
@media (min-width: 1281px) {
  .app__main[data-panel-open="true"] .content,
  .app__main[data-panel-open="true"] .topbar__inner,
  .app__main[data-panel-open="true"] .cds-tabs {
    max-width: min(var(--pp-content-max), calc(100% - var(--pp-drawer-width)));
    margin-left: 0;
    margin-right: 0;
  }
}

/* ============================================================
   Small print
   ============================================================ */
.note-line {
  display: flex;
  align-items: flex-start;
  gap: var(--cds-space-50);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

.note-line svg {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 2px;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-100);
}

.stack--tight {
  gap: var(--cds-space-50);
}

.row-end {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  flex-wrap: wrap;
}

/* ============================================================
   Narrow widths
   ============================================================ */
@media (max-width: 900px) {
  .type-grid,
  .limits,
  .pane__split {
    grid-template-columns: minmax(0, 1fr);
  }

  .day {
    grid-template-columns: minmax(0, 1fr);
  }

  .slot-row .cds-input {
    max-width: none;
  }

  /* The step names are handled by the rail's own container query
     above, which measures the space the rail actually has rather
     than the width of the window. Only the connector length is a
     screen-size decision. */
  .wiz__rule {
    flex-basis: 12px;
  }
}
