/* ============================================================
   UCMS Provider Scheduler (Epic 1) - design prototype
   Calendar family: screens 2, 3 and 4.
     2-home-calendar.html         <- board frame 172:1166
     3-home-calendar-block.html   <- board frame 172:339
     4-home-calendar-session.html <- board frame 172:755

   Loads AFTER css/styles.css and adds only what the calendar
   family needs. Nothing in styles.css is overridden except the
   two shell rules the collapsible navigation requires, which are
   marked below.

   Colour literals appear ONLY in the :root block at the top of
   this file, and only for the three values styles.css does not
   already carry. Every other rule in this file uses var().

   Styling source of truth: TELUS Consistency Design System (CDS),
   reference/cds/. Sample data is illustrative: no real client
   information appears anywhere.
   ============================================================ */

:root {
  /* Three tints CDS ships no lighter step for. Each is an opacity
     ramp off a token colour already declared in styles.css, in the
     same style as --cds-green-400-opacity-07 there.

     green-400 at 5 percent = the bookable-window wash. It sits under
     text, so it has to stay far lighter than the 7 percent badge tint.
     primary-brand at 5 percent = the current-day column.
     neutral-500 at 50 percent = the drawer scrim. */
  --cds-green-400-opacity-05: rgba(43, 128, 0, 0.05);
  --cds-primary-brand-opacity-05: rgba(75, 40, 109, 0.05);
  --cds-neutral-500-opacity-50: rgba(44, 46, 48, 0.5);

  /* Layout metrics, no colour */
  --pp-nav-width-collapsed: 72px;
  --pp-drawer-width: 420px;
  --pp-modal-width-narrow: 520px;
  --pp-cal-gutter: 88px;
  --pp-cal-slot: 44px;        /* one half hour */
  --pp-cal-min-width: 900px;
}

/* A hidden element stays hidden even when its class sets a display value. */
[hidden] {
  display: none !important;
}

/* styles.css builds .notif as a button; on these screens it is a link to
   the notifications drawer, so it needs the link reset too. */
a.notif {
  text-decoration: none;
}

/* ============================================================
   Collapsible side navigation

   The open state lives in a data attribute on the layout root, not
   in a sibling selector: the toggle sits inside the nav header
   beside the brand link, so no sibling combinator can reach the
   nav list or the grid column from it.

   The attribute is written on <html> by a two-line script in the
   head, so a collapsed nav is already collapsed on first paint,
   and mirrored onto .app on load so the state is readable from the
   layout container itself. Both are set by the toggle. The value is
   remembered in localStorage under "pp-nav-collapsed".

   CDS models no collapsed rail: Responsive side navigation ships a
   single 256px width and no icon-only variant. The 72px rail below
   is therefore a documented local extension, not a CDS component.
   ============================================================ */
.app__nav-head {
  display: flex;
  align-items: flex-start;
  gap: var(--cds-space-50);
  padding: 0 var(--cds-space-50) var(--cds-space-100);
}

/* styles.css gives .app__brand its own bottom padding; inside the
   head row the row owns the spacing instead. */
.app__nav-head .app__brand {
  flex: 1;
  min-width: 0;
  padding: 0;
}

.app__nav-toggle {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-top: 2px;
  padding: 0;
  border: 0;
  border-radius: var(--cds-radius-small);
  background: transparent;
  color: var(--cds-neutral-350);
  cursor: pointer;
  transition: background-color 150ms ease-out, color 150ms ease-out;
}

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

:root[data-nav-collapsed="true"] .app__nav-toggle svg {
  transform: rotate(180deg);
}

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

:root[data-nav-collapsed="true"] .app {
  --pp-nav-width: var(--pp-nav-width-collapsed);
}

:root[data-nav-collapsed="true"] .app__nav {
  padding-left: var(--cds-space-50);
  padding-right: var(--cds-space-50);
}

:root[data-nav-collapsed="true"] .app__nav-head {
  flex-direction: column;
  align-items: center;
  gap: var(--cds-space-75);
  padding: 0 0 var(--cds-space-100);
}

:root[data-nav-collapsed="true"] .app__brand-name,
:root[data-nav-collapsed="true"] .app__nav-label {
  display: none;
}

:root[data-nav-collapsed="true"] .app__brand-mark {
  font-size: var(--cds-txt-subhead-size);
  line-height: var(--cds-line-height-subhead);
}

:root[data-nav-collapsed="true"] .app__nav-item {
  justify-content: center;
  padding: 0;
}

/* The rail is icon only, so every item states its name to a screen
   reader and shows it as a native tooltip on hover. */
:root[data-nav-collapsed="true"] .app__nav-toggle {
  margin-top: 0;
}

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

.notif--link {
  text-decoration: none;
}

/* ============================================================
   Setup banner (CDS Info message)
   ============================================================ */
.setup {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cds-space-100) var(--cds-space-150);
  padding: var(--cds-padding-medium) var(--cds-padding-large);
  border: 1px solid var(--cds-primary-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-primary-brand-opacity-05);
}

.setup__icon {
  flex: none;
  display: grid;
  place-items: center;
  color: var(--cds-primary-brand);
}

.setup__icon svg {
  width: 22px;
  height: 22px;
}

.setup__text {
  flex: 1;
  min-width: 260px;
}

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

.setup__note {
  margin-top: 2px;
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

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

/* ============================================================
   Calendar toolbar

   Crit 244:790 resolved: the board carried one "Add to Calendar"
   button that both booked a session and blocked time. It is two
   named actions now, and each one opens the drawer already on the
   matching tab.
   ============================================================ */
.cal-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cds-space-100) var(--cds-space-150);
}

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

.cal-bar__group--end {
  margin-left: auto;
}

/* CDS Segmented control, Size=Medium (40px), track neutral-50,
   full pill at radius-btn-medium. */
.cds-seg {
  display: inline-flex;
  align-items: center;
  gap: var(--cds-space-0);
  padding: var(--cds-space-25);
  border-radius: var(--cds-radius-btn-large);
  background: var(--cds-neutral-50);
}

.cds-seg__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 var(--cds-padding-medium);
  border: 0;
  border-radius: var(--cds-radius-btn-medium);
  background: transparent;
  color: var(--cds-neutral-450);
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 150ms ease-out, color 150ms ease-out;
}

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

.cds-seg__item[aria-pressed="true"],
.cds-seg__item[aria-current="true"] {
  background: var(--cds-primary-brand);
  color: var(--cds-neutral-0);
}

.cds-seg__item[aria-pressed="true"]:hover,
.cds-seg__item[aria-current="true"]:hover {
  background: var(--cds-primary-500);
  color: var(--cds-neutral-0);
}

/* The Today button reads pressed while the calendar is sitting on the week
   that holds today, so a provider can tell at a glance whether stepping the
   arrows has taken them away from it. The tint and the text colour are the
   pair the secondary button already uses on hover. */
.cds-btn--secondary[aria-pressed="true"] {
  background: var(--cds-primary-brand-opacity-10);
}

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

.cal-range__label {
  min-width: 232px;
  text-align: center;
  font-size: var(--cds-txt-body-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

/* ---------- Legend ----------
   Crit 244:797 resolved. On the board orange carried two unrelated
   meanings at once: blocked time on the grid, and the Family
   appointment-type tag on a session card. They are separated here.

     surface layer  green wash  = bookable window
                    grey hatch  = time off
     card layer     green rule  = booked      (Epic 2 392:547)
                    orange rule = hold        (Epic 2 392:547)
     type tags      neutral outline + a type icon, never coloured

   Each legend key is readable by pattern as well as by tone, so the
   grid still parses without colour. */
.cal-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cds-space-50) var(--cds-space-150);
}

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

.cal-legend__key {
  width: 22px;
  height: 14px;
  flex: none;
  border-radius: 3px;
  border: 1px solid var(--cds-neutral-100);
}

.cal-legend__key--avail {
  background: var(--cds-green-400-opacity-05);
  border-color: var(--cds-green-100);
}

.cal-legend__key--off {
  border-color: var(--cds-neutral-200);
  background: repeating-linear-gradient(
    135deg,
    var(--cds-neutral-50) 0 4px,
    var(--cds-neutral-100) 4px 8px
  );
}

.cal-legend__key--booked {
  background: var(--cds-neutral-0);
  border-left: 3px solid var(--cds-green-400);
}

.cal-legend__key--hold {
  background: var(--cds-neutral-0);
  border-left: 3px solid var(--cds-orange-400);
}

/* ============================================================
   Week grid

   Two grids share one column template, so the day headers stay
   locked to the day columns. Hour rules are painted as a repeating
   background on the column rather than as 220 empty divs, which
   keeps the markup to the things that actually carry meaning:
   availability bands, time off, and sessions.

   Rows are half hours. --r1 / --r2 on an element are half-hour row
   indices, 1 = 8:00 am, and are set inline per event because they
   are data, not style.
   ============================================================ */
.cal-scroll {
  overflow-x: auto;
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
}

.cal {
  min-width: var(--pp-cal-min-width);
}

.cal__head,
.cal__body {
  display: grid;
  grid-template-columns: var(--pp-cal-gutter) repeat(7, minmax(0, 1fr));
}

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

.cal__head-day {
  padding: var(--cds-padding-medium) var(--cds-space-50);
  text-align: center;
  border-left: 1px solid var(--cds-neutral-100);
}

.cal__head-name {
  display: block;
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cds-neutral-350);
}

.cal__head-num {
  display: block;
  margin-top: 2px;
  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);
  font-variant-numeric: tabular-nums;
}

.cal__head-day--today {
  background: var(--cds-primary-brand-opacity-05);
}

.cal__head-day--today .cal__head-name,
.cal__head-day--today .cal__head-num {
  color: var(--cds-primary-brand);
}

.cal__times {
  display: grid;
  grid-template-rows: repeat(11, calc(var(--pp-cal-slot) * 2));
}

/* No tabular figures on clock times: this face gives the colon a full figure
   width in tabular mode, which pulls "8:00 am" apart. The gutter is right
   aligned, so nothing needs the extra alignment. */
.cal__time {
  padding: var(--cds-space-50) var(--cds-space-75) 0 0;
  text-align: right;
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
  white-space: nowrap;
}

.cal__day {
  position: relative;
  display: grid;
  grid-template-rows: repeat(22, var(--pp-cal-slot));
  border-left: 1px solid var(--cds-neutral-100);
  background-image: repeating-linear-gradient(
    to bottom,
    var(--cds-neutral-100) 0 1px,
    transparent 1px calc(var(--pp-cal-slot) * 2)
  );
}

/* Today is marked in the header, in brand purple. The column body takes a
   neutral tint instead: a purple wash under the green availability band
   turned both of them muddy. */
.cal__day--today {
  background-color: var(--cds-neutral-50);
}

.cal__band,
.cal__ev {
  grid-column: 1;
  grid-row: var(--r1) / var(--r2);
}

.cal__band {
  margin: 0 1px;
  pointer-events: none;
}

.cal__band--avail {
  background: var(--cds-green-400-opacity-05);
  box-shadow: inset 2px 0 0 0 var(--cds-green-100);
}

/* Time off is grey and hatched, so it reads as unavailable rather
   than as a second kind of appointment. */
.cal__band--off {
  background: repeating-linear-gradient(
    135deg,
    var(--cds-neutral-50) 0 5px,
    var(--cds-neutral-100) 5px 10px
  );
  box-shadow: inset 2px 0 0 0 var(--cds-neutral-200);
}

/* neutral-450, not 350: the label sits on the darker stripe of the hatch,
   where 350 lands at 4.13:1. */
.cal__band-label {
  display: block;
  padding: var(--cds-space-25) var(--cds-space-50);
  font-size: var(--cds-txt-caption-small-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cds-neutral-450);
}

/* ---------- Session card ----------
   Crit 244:804 resolved: the card leads with its time. That is the
   first thing a provider looks for and the board card did not carry
   it at all. Epic 2 392:543 adds the status tag; 392:547 sets the
   status colour code. */
.cal__ev {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 1px var(--cds-space-25) 1px var(--cds-space-25);
  padding: var(--cds-space-25) var(--cds-space-50);
  border: 1px solid var(--cds-neutral-100);
  border-left-width: 3px;
  border-radius: var(--cds-radius-xsmall);
  background: var(--cds-neutral-0);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  transition: border-color 150ms ease-out, box-shadow 150ms ease-out;
}

/* On screen 2 the card is a button, because it opens a panel beside the
   grid rather than going anywhere. Only the three properties a button
   would otherwise impose are reset; the card's own box is unchanged, and
   its width still comes from the grid column it stretches into. Setting
   an explicit 100% here pushed the card's own margins outside the day
   column and made the column scroll. */
button.cal__ev {
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.cal__ev:hover {
  border-color: var(--cds-primary-200);
  box-shadow: 0 2px 8px var(--cds-primary-brand-opacity-10);
}

/* The card whose session is showing in the drawer keeps a ring, so a
   provider moving between sessions can see which one they are reading. */
.cal__ev[aria-expanded="true"] {
  border-color: var(--cds-primary-brand);
  box-shadow: 0 0 0 1px var(--cds-primary-brand);
}

.cal__ev--booked {
  border-left-color: var(--cds-green-400);
}

.cal__ev--hold {
  border-left-color: var(--cds-orange-400);
}

/* A half-hour card is 44px tall, so the two lines it can hold are the
   time and the client. The appointment type and the contact type ride the
   time line as glyphs, each with a screen-reader label, and reappear as
   worded tags on any card an hour or longer. Same pattern as the modality
   icon on screen 1: never shape alone. */
.cal__ev__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cds-space-25);
}

.cal__ev__icons {
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
}

.cal__ev__time {
  font-size: var(--cds-txt-caption-small-size);
  line-height: 1.2;
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-450);
  white-space: nowrap;
}

.cal__ev__name {
  font-size: var(--cds-txt-caption-size);
  line-height: 1.2;
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

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

/* Appointment-type tag. Neutral outline plus a type glyph, so the
   Family tag can never be mistaken for time off. */
.type-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  height: 18px;
  padding: 0 5px;
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-xsmall);
  background: var(--cds-neutral-0);
  color: var(--cds-neutral-450);
  font-size: var(--cds-txt-caption-small-size);
  line-height: 1;
  white-space: nowrap;
}

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

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

.cal__ev__mode svg {
  width: 13px;
  height: 13px;
}

.status-tag {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--cds-radius-xsmall);
  font-size: var(--cds-txt-caption-small-size);
  font-weight: var(--cds-font-weight-semibold);
  line-height: 1;
  white-space: nowrap;
}

.status-tag--hold {
  background: var(--cds-orange-50-opacity-15);
  color: var(--cds-orange-400);
}

.status-tag--moved {
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-450);
}

.cal-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cds-space-50) var(--cds-space-150);
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

/* ============================================================
   Day, Week and Month views

   Which view is showing is one data attribute on the content
   container, data-view, written by the toolbar's segmented
   control. No sibling selector is involved: the segmented buttons
   sit inside the toolbar and the panes are children of the
   container that carries the attribute.

   Day view reuses the week grid unchanged and only drops the
   column count from seven to one, so a session card, an
   availability band and the half-hour rows are the same
   components in both. The scroll box is capped so a single day
   does not stretch a 44px-high card across the whole canvas.
   ============================================================ */
[data-view="day"] .cal__head,
[data-view="day"] .cal__body {
  grid-template-columns: var(--pp-cal-gutter) minmax(0, 1fr);
}

[data-view="day"] .cal {
  min-width: 0;
}

[data-view="day"] [data-pane="grid"] {
  max-width: 640px;
}

[data-view="week"] [data-pane="month"],
[data-view="day"] [data-pane="month"] {
  display: none;
}

[data-view="month"] [data-pane="grid"] {
  display: none;
}

/* ---------- Month grid ----------
   Six rows of seven, so March 2025 keeps its real weekday
   alignment (March 1 is a Saturday). Days the sample does not
   cover are drawn but inert, which is honest about where the
   sample data stops rather than opening an empty day. */
.cal-mo {
  min-width: 760px;
}

.cal-mo__head,
.cal-mo__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

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

.cal-mo__head-cell {
  padding: var(--cds-padding-medium) var(--cds-space-50);
  text-align: center;
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cds-neutral-350);
}

.cal-mo__day {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--cds-space-25);
  /* width comes from the grid column: an explicit 100% on a button in a
     grid cell adds its own box to the track and overflows the row. */
  width: auto;
  min-width: 0;
  min-height: 112px;
  padding: var(--cds-space-50);
  border: 0;
  border-left: 1px solid var(--cds-neutral-100);
  border-bottom: 1px solid var(--cds-neutral-100);
  background: var(--cds-neutral-0);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 150ms ease-out;
}

.cal-mo__day:hover {
  background: var(--cds-neutral-10);
}

.cal-mo__day--today {
  background: var(--cds-primary-brand-opacity-05);
}

.cal-mo__day--out,
.cal-mo__day--out:hover {
  background: var(--cds-neutral-10);
  cursor: default;
}

.cal-mo__num {
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
  font-variant-numeric: tabular-nums;
}

.cal-mo__day--today .cal-mo__num {
  color: var(--cds-primary-brand);
}

.cal-mo__day--out .cal-mo__num {
  font-weight: var(--cds-font-weight-regular);
  color: var(--cds-neutral-350);
}

/* Same two keys as the legend, so the month cell says what the week
   grid says about that day's surface without redrawing the bands. */
.cal-mo__keys {
  display: flex;
  gap: var(--cds-space-25);
}

.cal-mo__key {
  flex: none;
  width: 22px;
  height: 5px;
  border-radius: 3px;
  border: 1px solid var(--cds-neutral-100);
}

.cal-mo__key--avail {
  background: var(--cds-green-400-opacity-05);
  border-color: var(--cds-green-100);
}

.cal-mo__key--off {
  border-color: var(--cds-neutral-200);
  background: repeating-linear-gradient(
    135deg,
    var(--cds-neutral-50) 0 4px,
    var(--cds-neutral-100) 4px 8px
  );
}

.cal-mo__chips {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* Same status rule as the week card: a green left edge is booked, an
   orange one is on hold. */
.cal-mo__chip {
  display: flex;
  align-items: baseline;
  gap: var(--cds-space-25);
  min-width: 0;
  padding: 2px var(--cds-space-25);
  border: 1px solid var(--cds-neutral-100);
  border-left-width: 3px;
  border-radius: var(--cds-radius-xsmall);
  background: var(--cds-neutral-0);
  font-size: var(--cds-txt-caption-small-size);
  line-height: 1.4;
}

.cal-mo__chip--booked {
  border-left-color: var(--cds-green-400);
}

.cal-mo__chip--hold {
  border-left-color: var(--cds-orange-400);
}

.cal-mo__chip-time {
  flex: none;
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-450);
  white-space: nowrap;
}

.cal-mo__chip-name {
  min-width: 0;
  color: var(--cds-neutral-500);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- Inline date picker (filter drawer, Custom range) ----------
   Epic 2 392:539 asks for a datepicker behind the Custom value. It
   opens inside the drawer rather than as a layer, because the drawer
   is already the surface deciding what the calendar shows. */
.mini-cal {
  padding: var(--cds-space-50);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
}

.mini-cal__title {
  padding-bottom: var(--cds-space-50);
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.mini-cal__head,
.mini-cal__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
}

.mini-cal__head-cell {
  padding-bottom: var(--cds-space-25);
  text-align: center;
  font-size: var(--cds-txt-caption-small-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--cds-neutral-350);
}

.mini-cal__day {
  display: grid;
  place-items: center;
  width: auto;
  min-width: 0;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: var(--cds-radius-xsmall);
  background: transparent;
  color: var(--cds-neutral-500);
  font-family: inherit;
  font-size: var(--cds-txt-caption-size);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 150ms ease-out, color 150ms ease-out;
}

.mini-cal__day:hover {
  background: var(--cds-neutral-50);
}

.mini-cal__day[aria-pressed="true"] {
  background: var(--cds-primary-brand);
  color: var(--cds-neutral-0);
}

/* Dates outside the sample range. Disabled controls sit outside the
   contrast floor, and neutral-200 is the disabled tone the icon
   buttons already use at the ends of a stepper. */
.mini-cal__day:disabled,
.mini-cal__day:disabled:hover {
  background: transparent;
  color: var(--cds-neutral-200);
  cursor: not-allowed;
}

.mini-cal__blank {
  height: 30px;
}

/* ============================================================
   Side drawer

   Screens 3 and 4 are the drawer's two tabs and are separate pages,
   so the scrim is a link: clicking away from the panel returns to
   2-home-calendar.html, which is what closing the drawer does.
   ============================================================ */
.scrim {
  position: fixed;
  inset: 0;
  z-index: 20;
  background: var(--cds-neutral-500-opacity-50);
}

.drawer {
  position: fixed;
  z-index: 21;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(var(--pp-drawer-width), 100%);
  display: flex;
  flex-direction: column;
  background: var(--cds-neutral-0);
  border-left: 1px solid var(--cds-neutral-100);
}

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

.drawer__title {
  flex: 1;
  font-size: var(--cds-hd-title-size);
  line-height: var(--cds-line-height-title);
  font-weight: var(--cds-font-weight-semibold);
}

.drawer__tabs {
  display: flex;
  gap: var(--cds-space-200);
  padding: 0 var(--cds-padding-large);
  border-bottom: 1px solid var(--cds-neutral-100);
}

.drawer__tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: 0 var(--cds-space-25);
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-350);
  text-decoration: none;
  transition: color 150ms ease-out;
}

.drawer__tab:hover {
  color: var(--cds-neutral-500);
}

.drawer__tab[aria-current] {
  color: var(--cds-primary-brand);
}

.drawer__tab[aria-current]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 3px;
  border-radius: 2px 2px 0 0;
  background: var(--cds-primary-brand);
}

.drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--cds-padding-large);
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-150);
}

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

.drawer__foot {
  display: flex;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-medium) var(--cds-padding-large);
  border-top: 1px solid var(--cds-neutral-100);
}

.drawer__foot .cds-btn {
  flex: 1;
}

/* ============================================================
   Form primitives (CDS Input field / Dropdown field, Size=Small)
   Label row 21px, 8px gap, 40px control. Helper text 12px below.
   ============================================================ */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-50);
}

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

.field__req {
  color: var(--cds-red-400);
}

.field__opt {
  color: var(--cds-neutral-350);
}

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

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

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

.field__to {
  padding-top: 26px;
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

/* CDS binds Neutral/neutral-200 to the field outline. At 1.98:1 on white
   that outline misses the 3:1 floor for a control boundary, so the border
   runs one step darker at neutral-350 (5.18:1). Same deviation, and the same
   reason, as the UCM-003 billing prototype. Worth raising with the
   design-system team. */
.cds-input,
.cds-select {
  width: 100%;
  height: var(--cds-field-height-small);
  padding: 0 var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-350);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
  color: var(--cds-neutral-500);
  font-family: var(--cds-primary-font-family);
  font-size: var(--cds-txt-body-small-size);
}

.cds-input::placeholder,
.cds-textarea::placeholder {
  color: var(--cds-neutral-350);
}

.cds-select {
  appearance: none;
  padding-right: var(--cds-space-250);
  cursor: pointer;
}

.select-wrap {
  position: relative;
}

.select-wrap__chevron {
  position: absolute;
  top: 50%;
  right: var(--cds-space-75);
  margin-top: -10px;
  display: grid;
  place-items: center;
  color: var(--cds-neutral-450);
  pointer-events: none;
}

.select-wrap__chevron svg {
  width: 20px;
  height: 20px;
}

.input-wrap {
  position: relative;
}

.input-wrap .cds-input {
  padding-left: var(--cds-space-250);
}

.input-wrap__icon {
  position: absolute;
  top: 50%;
  left: var(--cds-space-75);
  margin-top: -9px;
  display: grid;
  place-items: center;
  color: var(--cds-neutral-350);
  pointer-events: none;
}

.input-wrap__icon svg {
  width: 18px;
  height: 18px;
}

.cds-textarea {
  width: 100%;
  min-height: 96px;
  padding: var(--cds-padding-small) var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-350);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
  color: var(--cds-neutral-500);
  font-family: var(--cds-primary-font-family);
  font-size: var(--cds-txt-body-small-size);
  line-height: var(--cds-line-height-body);
  resize: vertical;
}

.cds-input:disabled,
.cds-select:disabled,
.cds-textarea:disabled {
  background: var(--cds-neutral-50);
  color: var(--cds-neutral-350);
  cursor: not-allowed;
}

.fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-50);
}

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

/* Radio pills for a short, mutually exclusive choice. */
.pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cds-space-50);
}

.pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--cds-space-50);
  height: 36px;
  padding: 0 var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-350);
  border-radius: var(--cds-radius-btn-medium);
  background: var(--cds-neutral-0);
  color: var(--cds-neutral-450);
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  cursor: pointer;
  transition: border-color 150ms ease-out, background-color 150ms ease-out,
    color 150ms ease-out;
}

.pill svg {
  width: 16px;
  height: 16px;
  color: var(--cds-neutral-350);
}

.pill input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.pill:hover {
  border-color: var(--cds-neutral-500);
  color: var(--cds-neutral-500);
}

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

.pill:has(input:checked) svg {
  color: var(--cds-primary-brand);
}

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

/* Checkbox rows in the filter drawer */
.check {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-space-25) 0;
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
  cursor: pointer;
}

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

/* ============================================================
   Messages (CDS Info message / Warning message)
   ============================================================ */
.msg-box {
  display: flex;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-medium);
  border-radius: var(--cds-radius-small);
  border: 1px solid var(--cds-neutral-100);
  background: var(--cds-neutral-10);
}

.msg-box__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  color: var(--cds-neutral-350);
}

.msg-box__icon svg {
  width: 20px;
  height: 20px;
}

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

.msg-box__body {
  margin-top: 2px;
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

.msg-box--warn {
  border-color: var(--cds-orange-100);
  background: var(--cds-orange-50-opacity-15);
}

.msg-box--warn .msg-box__icon {
  color: var(--cds-orange-400);
}

.msg-box--warn .msg-box__body {
  color: var(--cds-neutral-450);
}

.msg-box--nested {
  margin-top: var(--cds-space-75);
}

/* Crit 244:808 resolved: the warning used to say only that a clash
   would not cancel anything. It names each clashing session now, with
   the time, who it is with, and links straight to it. */
.clash {
  margin-top: var(--cds-space-75);
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-50);
}

.clash__item {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--cds-space-25) var(--cds-space-75);
  padding: var(--cds-space-50) var(--cds-space-75);
  border: 1px solid var(--cds-orange-100);
  border-radius: var(--cds-radius-xsmall);
  background: var(--cds-neutral-0);
}

.clash__time {
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
  white-space: nowrap;
}

.clash__who {
  flex: 1;
  min-width: 120px;
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-450);
}

.clash__links {
  display: flex;
  gap: var(--cds-space-75);
  font-size: var(--cds-txt-caption-size);
}

.clash__links a {
  font-weight: var(--cds-font-weight-semibold);
  text-decoration: none;
}

.clash__links a:hover {
  text-decoration: underline;
}

/* ============================================================
   Client info block (Bryan 345:1466)
   Key facts about the case behind the booking, sessions remaining
   first, because that is what decides whether the booking is even
   allowed.
   ============================================================ */
.client-card {
  padding: var(--cds-padding-medium);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-10);
}

.client-card__head {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  flex-wrap: wrap;
}

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

.facts {
  margin-top: var(--cds-space-75);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--cds-space-25) var(--cds-space-100);
}

.facts dt {
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
  white-space: nowrap;
}

.facts dd {
  margin: 0;
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-450);
}

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

/* ============================================================
   Appointment type accordion (Bryan 316:371)

   The board had a dropdown. Selecting a type now opens that type's
   session-detail card in place, so the length, the contact types it
   allows and the sessions left on the authorisation are all visible
   before the booking is made.

   The open state is a data attribute on the row, not a sibling
   selector off the control: the control is a label wrapping a radio,
   and the panel is a child of the row.
   ============================================================ */
.apt-types {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-50);
}

.apt-type {
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-0);
  transition: border-color 150ms ease-out;
}

.apt-type[data-open="true"] {
  border-color: var(--cds-primary-brand);
}

.apt-type__head {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-space-75) var(--cds-padding-medium);
  cursor: pointer;
}

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

.apt-type__name {
  flex: 1;
  min-width: 0;
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.apt-type__len {
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
  white-space: nowrap;
}

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

.apt-type__chevron svg {
  width: 18px;
  height: 18px;
  transition: transform 200ms ease-out;
}

.apt-type[data-open="true"] .apt-type__chevron svg {
  transform: rotate(180deg);
}

.apt-type__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 200ms ease-out;
}

.apt-type[data-open="true"] .apt-type__panel {
  grid-template-rows: 1fr;
}

.apt-type__panel > div {
  overflow: hidden;
}

.apt-type__detail {
  margin: 0 var(--cds-padding-medium) var(--cds-padding-medium);
  padding: var(--cds-padding-medium);
  border-radius: var(--cds-radius-xsmall);
  background: var(--cds-neutral-10);
}

/* ============================================================
   Time-off entries (board "Blocked Times")

   Crit 244:810 resolved: the board called this Block. Every label in
   the family reads "time off" now, which is what a provider would
   say out loud.

   Crit 244:809 resolved: the entry named its schedule "Schedule 1",
   which tells a provider nothing about which days it covers. The
   schedule carries its days in its name instead.
   ============================================================ */
.off-list {
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-75);
}

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

.off-item__head {
  display: flex;
  align-items: flex-start;
  gap: var(--cds-space-75);
}

.off-item__when {
  flex: 1;
  min-width: 0;
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
}

.off-item__meta {
  margin-top: var(--cds-space-25);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cds-space-50);
}

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

/* The case chip on screen 1 carries tabular figures, which is right for
   activity numbers and wrong for clock times in this face. */
.meta-chip {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 var(--cds-padding-small);
  border: 1px solid var(--cds-neutral-100);
  border-radius: var(--cds-radius-xsmall);
  background: var(--cds-neutral-0);
  color: var(--cds-neutral-450);
  font-size: var(--cds-txt-caption-size);
  line-height: 1;
  white-space: nowrap;
}

.cds-btn--danger-ghost {
  height: 32px;
  padding: 0 var(--cds-padding-small);
  background: transparent;
  color: var(--cds-red-450);
  border-color: transparent;
}

.cds-btn--danger-ghost:hover {
  background: var(--cds-red-400-opacity-10);
  color: var(--cds-red-450);
}

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

.divider {
  height: 1px;
  background: var(--cds-neutral-100);
}

/* Live read-outs: the end time the duration produces, and the
   provider-time equivalent of the client's start time. */
.readout {
  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);
}

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

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

/* ============================================================
   Filter drawer (Epic 2 392:535 and 392:539)

   Concept parity with Epic 2: one side drawer decides what the
   calendar shows, and it owns the time-period values. It opens and
   closes in place, so its state is a data attribute on the layout
   root rather than a fourth page.
   ============================================================ */
.filter-panel {
  position: fixed;
  z-index: 21;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(360px, 100%);
  display: flex;
  flex-direction: column;
  background: var(--cds-neutral-0);
  border-left: 1px solid var(--cds-neutral-100);
  /* Closed means parked past the right edge and inert, not hidden: a
     transitioned visibility is not settled when the open handler wants to
     move focus into the panel, and the element cannot take focus while the
     old transition is still running. inert keeps it out of the tab order
     and off the accessibility tree without that race. */
  transform: translateX(100%);
  transition: transform 200ms ease-out;
}

.filter-scrim {
  position: fixed;
  inset: 0;
  z-index: 20;
  background: var(--cds-neutral-500-opacity-50);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease-out;
}

:root[data-filter-open="true"] .filter-panel {
  transform: translateX(0);
}

:root[data-filter-open="true"] .filter-scrim {
  opacity: 1;
  pointer-events: auto;
}

/* ============================================================
   Session details drawer, in place (Epic 2 392:555, board frames
   370:2394 and 370:1962)

   User-directed: clicking a session card opens the details panel on
   the right of this same page instead of going to another screen,
   which is what the board frames draw. The panel is the one built on
   screens 6 and 7; the rules below are the parts of css/details.css
   that panel needs, restated here so this file stays additive to
   css/styles.css alone and screens 6 to 9 keep their own stylesheet.

   Open state is data-session-open on the document element, the same
   mechanism as the filter drawer above, and the two are mutually
   exclusive in script. No scrim: screen 7 leaves the drawer scrimless
   so a provider can move straight from one session to the next.
   ============================================================ */
.sess-panel {
  position: fixed;
  z-index: 22;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(var(--pp-drawer-width), 100%);
  display: flex;
  flex-direction: column;
  background: var(--cds-neutral-0);
  border-left: 1px solid var(--cds-neutral-100);
  box-shadow: var(--cds-elevation-default);
  transform: translateX(100%);
  transition: transform 200ms ease-out;
}

:root[data-session-open="true"] .sess-panel {
  transform: translateX(0);
}

/* With the drawer open on a wide screen the page steps aside rather than
   hiding under it, the same rule screens 6 to 9 carry. The week grid keeps
   its column widths and scrolls inside its own container. Below 1280 the
   drawer overlays, which is the right trade when the column is already
   narrow. */
@media (min-width: 1280px) {
  :root[data-session-open="true"] .app__main {
    padding-right: var(--pp-drawer-width);
  }
}

/* The filter body is a flex column with a gap between its fields; the
   session body is ordinary block flow, because its groups carry their
   own rules and padding. */
.sess-panel .drawer__head {
  padding-bottom: var(--cds-padding-large);
  border-bottom: 1px solid var(--cds-neutral-100);
}

.sess-panel .drawer__body {
  display: block;
}

.sess__when {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  padding-bottom: var(--cds-padding-medium);
  border-bottom: 1px solid var(--cds-neutral-100);
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.sess__when svg {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--cds-neutral-350);
}

.sess__who {
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-medium) 0;
  border-bottom: 1px solid var(--cds-neutral-100);
}

.sess__avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 20px;
  background: var(--cds-primary-brand);
  color: var(--cds-neutral-0);
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
}

.sess__name {
  font-size: var(--cds-txt-body-size);
  font-weight: var(--cds-font-weight-semibold);
}

.sess__group {
  padding-top: var(--cds-padding-large);
}

.sess__group-title {
  font-size: var(--cds-txt-caption-size);
  font-weight: var(--cds-font-weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cds-neutral-350);
}

.sess__facts {
  margin: var(--cds-space-75) 0 0;
  display: grid;
  gap: var(--cds-space-100);
}

.sess__fact {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  align-items: start;
  gap: var(--cds-space-75);
}

.sess__fact svg {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  color: var(--cds-neutral-350);
}

.sess__fact dt {
  grid-column: 2;
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

.sess__fact dd {
  grid-column: 2;
  margin: 0;
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-500);
}

.sess__fact-note {
  display: block;
  margin-top: 2px;
  font-size: var(--cds-txt-caption-size);
  color: var(--cds-neutral-350);
}

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

.sess-action {
  display: flex;
  align-items: center;
  gap: var(--cds-space-50);
  min-height: var(--cds-button-height-medium);
  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);
  font-family: inherit;
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 150ms ease-out, background-color 150ms ease-out;
}

.sess-action svg {
  width: 18px;
  height: 18px;
  flex: none;
}

.sess-action:hover {
  border-color: var(--cds-neutral-200);
  background: var(--cds-neutral-10);
}

/* Epic 2 365:2015 asked for the reschedule mark in yellow and the no-show
   mark in grey. CDS publishes no yellow, so reschedule takes
   Orange/orange-350 and no-show takes Neutral/neutral-350, the same
   resolution as screens 6 to 9. */
.sess-action--attended svg {
  color: var(--cds-green-400);
}

.sess-action--cancel svg {
  color: var(--cds-red-400);
}

.sess-action--reschedule svg {
  color: var(--cds-orange-350);
}

.sess-action--noshow svg {
  color: var(--cds-neutral-350);
}

/* ============================================================
   No-show modal and snackbar

   Same components as screens 6 to 9, restated for this file. The
   modal is populated from the card that opened the drawer, so it can
   never name a client other than the one being read.
   ============================================================ */
.mdl-layer {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: start center;
  padding: var(--cds-space-250) var(--cds-padding-medium);
  overflow-y: auto;
  background: var(--cds-neutral-500-opacity-50);
}

.mdl-layer[data-open="false"] {
  display: none;
}

.mdl {
  width: 100%;
  max-width: var(--pp-modal-width-narrow);
  display: flex;
  flex-direction: column;
  border-radius: var(--cds-radius-default);
  background: var(--cds-neutral-0);
  box-shadow: var(--cds-elevation-default);
}

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

.mdl__title {
  flex: 1;
  min-width: 0;
  font-size: var(--cds-hd-title-size);
  line-height: var(--cds-line-height-title);
  font-weight: var(--cds-font-weight-semibold);
}

.mdl__lede {
  margin-top: var(--cds-space-25);
  font-size: var(--cds-txt-body-small-size);
  font-weight: var(--cds-font-weight-regular);
  color: var(--cds-neutral-350);
}

.mdl__body {
  padding: 0 var(--cds-padding-xlarge) var(--cds-padding-large);
}

.mdl__foot {
  display: flex;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-large) var(--cds-padding-xlarge) var(--cds-padding-xlarge);
  border-top: 1px solid var(--cds-neutral-100);
}

.mdl__foot .cds-btn {
  flex: 1;
}

.mdl__section {
  margin-top: var(--cds-space-200);
}

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

.tally {
  display: flex;
  align-items: center;
  gap: 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-50);
}

.tally__value {
  font-size: var(--cds-hd-title-size);
  line-height: 1;
  font-weight: var(--cds-font-weight-semibold);
  color: var(--cds-neutral-500);
  font-variant-numeric: tabular-nums;
}

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

.consequences {
  margin-top: var(--cds-space-100);
  display: flex;
  flex-direction: column;
  gap: var(--cds-space-75);
}

.consequence {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: var(--cds-space-75);
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-450);
}

.consequence svg {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  color: var(--cds-neutral-350);
}

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

.mdl__success {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--cds-space-75);
  padding: var(--cds-padding-xlarge);
  text-align: center;
}

.mdl__success-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 24px;
  background: var(--cds-green-400-opacity-07);
  color: var(--cds-green-400);
}

.mdl__success-icon svg {
  width: 28px;
  height: 28px;
}

.mdl__success-title {
  font-size: var(--cds-hd-title-size);
  line-height: var(--cds-line-height-title);
  font-weight: var(--cds-font-weight-semibold);
}

.mdl__success-body {
  max-width: 46ch;
  font-size: var(--cds-txt-body-small-size);
  color: var(--cds-neutral-350);
}

[data-state="success"] .mdl__form,
[data-state="form"] .mdl__done {
  display: none;
}

/* CDS Snackbar: neutral-500 surface, radius-small, padding-medium. */
.snackbar {
  position: fixed;
  left: 50%;
  bottom: var(--cds-space-150);
  z-index: 80;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--cds-space-75);
  max-width: calc(100vw - var(--cds-space-200));
  padding: var(--cds-padding-medium);
  border-radius: var(--cds-radius-small);
  background: var(--cds-neutral-500);
  color: var(--cds-neutral-0);
  font-size: var(--cds-txt-body-small-size);
  box-shadow: var(--cds-elevation-default);
}

.snackbar__icon {
  display: grid;
  place-items: center;
  flex: none;
  color: var(--cds-green-100);
}

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

.snackbar__close {
  display: grid;
  place-items: center;
  flex: none;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: var(--cds-radius-xsmall);
  background: transparent;
  color: var(--cds-neutral-0);
  cursor: pointer;
}

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

/* ============================================================
   Structural responsiveness
   The week grid keeps its column widths and scrolls inside its own
   container: seven readable day columns beat seven unreadable ones.
   ============================================================ */
@media (max-width: 900px) {
  /* Below 900 the nav is already a horizontal bar, so a collapsed rail would
     mean nothing: the toggle is hidden and every label comes back. Same rule
     as screens 1 and 5 to 9. */
  .app__nav-head,
  :root[data-nav-collapsed="true"] .app__nav-head {
    flex-direction: row;
    align-items: center;
    padding: 0;
  }

  .app,
  :root[data-nav-collapsed="true"] .app {
    --pp-nav-width: auto;
  }

  :root[data-nav-collapsed="true"] .app__nav {
    padding-left: var(--cds-padding-medium);
    padding-right: var(--cds-padding-medium);
  }

  :root[data-nav-collapsed="true"] .app__brand-name,
  :root[data-nav-collapsed="true"] .app__nav-label {
    display: block;
  }

  :root[data-nav-collapsed="true"] .app__nav-item {
    justify-content: flex-start;
    padding: 0 var(--cds-padding-small);
  }

  .app__nav-toggle {
    display: none;
  }

  .cal-range__label {
    min-width: 0;
  }
}

@media (max-width: 720px) {
  .cal-bar__group--end {
    margin-left: 0;
  }

  .drawer,
  .filter-panel,
  .sess-panel {
    width: 100%;
  }

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

  .mdl__foot {
    flex-direction: column-reverse;
  }

  .mdl__head,
  .mdl__body,
  .mdl__foot {
    padding-left: var(--cds-padding-large);
    padding-right: var(--cds-padding-large);
  }

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

  .facts dd {
    margin-bottom: var(--cds-space-25);
  }
}

/* ============================================================
   One drawer at a time on screens 3 and 4

   Those two screens ship with the add drawer already open, which is
   the state the board frames draw. The toolbar Filter button now
   opens the same filter drawer screen 2 carries, and two panels
   cannot share the right edge, so opening the filter suspends the
   add drawer: it slides back off the edge and is made inert, and it
   returns exactly as it was when the filter closes. Nothing in the
   add drawer is reset, so a half-filled form survives the trip.

   The add drawer's own scrim is a link back to the calendar, so it
   is faded out while suspended: leaving it under the filter scrim
   would double the wash and put a navigation target under a panel
   that is only meant to close.
   ============================================================ */
.drawer {
  transition: transform 200ms ease-out;
}

.scrim {
  transition: opacity 200ms ease-out;
}

:root[data-add-suspended="true"] .drawer {
  transform: translateX(100%);
}

:root[data-add-suspended="true"] .scrim {
  opacity: 0;
  pointer-events: none;
}
