/* ---------- appointments (calendar) ---------- */

.calendar {
  --slot-height: 1.25rem;   /* height of one 15-minute slot */
  --slots-per-hour: 4;      /* keep in sync with CalendarHelper::SLOT_MINUTES */
  --gutter-width: 4rem;     /* time labels column */
  --hour-line: var(--color-border);
  --slot-line: var(--color-surface-sunken);
}

/* ---------- "Booking for <customer>" banner ---------- */

.calendar-booking {
  align-items: center;
  margin-bottom: var(--space-4);
}

.calendar-booking__cancel {
  margin-left: auto;
  color: inherit;
  font-weight: var(--weight-medium);
  text-decoration: underline;
}

/* ---------- Toolbar ---------- */

.calendar-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.calendar-toolbar__nav,
.calendar-toolbar__controls {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.calendar-toolbar__title {
  margin-left: var(--space-2);
  font-size: var(--text-lg);
}

/* Segmented control: Day / Week / Month / Rooms */
.segmented {
  display: inline-flex;
  gap: var(--space-0-5);
  padding: var(--space-0-5);
  background: var(--color-surface-sunken);
  border: var(--border);
  border-radius: var(--radius-md);
}

.segmented__item {
  display: inline-flex;
  align-items: center;
  height: calc(var(--control-height-sm) - 2px);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);

  &:hover {
    color: var(--color-text);
    text-decoration: none;
  }

  &[aria-current="page"] {
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-xs);
  }
}

/* ---------- Time grid (day, week, rooms) ---------- */

.time-grid {
  overflow-x: auto;
}

.time-grid__head,
.time-grid__body {
  display: grid;
  grid-template-columns: var(--gutter-width) repeat(var(--columns), minmax(7rem, 1fr));
  /* Same space for a scrollbar in both, so head and body columns line up */
  scrollbar-gutter: stable;
}

.time-grid__head {
  overflow: hidden;
  border-bottom: var(--border);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.time-grid__body {
  max-height: calc(100dvh - 16rem);
  min-height: 24rem;
  overflow-y: auto;
}

.time-grid__day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-0-5);
  padding: var(--space-2) var(--space-1);
  border-left: var(--border);
  color: var(--color-text-muted);

  &:hover {
    color: var(--color-text);
    text-decoration: none;
  }
}

.time-grid__weekday {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

.time-grid__date {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-full);
  color: var(--color-text);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.time-grid__day[aria-current="date"] {
  color: var(--color-primary-text);

  .time-grid__date {
    background: var(--color-primary);
    color: var(--color-on-primary);
  }
}

.time-grid__room {
  color: var(--color-text);
  font-weight: var(--weight-semibold);
  text-align: center;
}

.time-grid__hours {
  display: grid;
  grid-template-rows: repeat(var(--slots), var(--slot-height));
}

.time-grid__hour {
  padding: var(--space-0-5) var(--space-2) 0 0;
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  text-align: right;
  line-height: var(--leading-none);
}

/* One day (or room). The gradient draws a solid line each hour and a faint one each slot. */
.time-grid__column {
  position: relative;
  border-left: var(--border);
  background-image:
    repeating-linear-gradient(
      to bottom,
      var(--hour-line) 0 1px,
      transparent 1px calc(var(--slot-height) * var(--slots-per-hour))
    ),
    repeating-linear-gradient(
      to bottom,
      var(--slot-line) 0 1px,
      transparent 1px var(--slot-height)
    );
}

/* Background layer: clickable empty slots */
.time-grid__slots {
  display: grid;
  grid-template-rows: repeat(var(--slots), var(--slot-height));
}

.time-grid__slot {
  display: block;
  transition: background-color var(--duration-fast) var(--ease-out);

  &:hover {
    background: var(--color-primary-subtle);
  }
}

/* Foreground layer: appointments and gaps.
   Items get an explicit grid-row; when two overlap, CSS grid places the
   second one in a new column automatically, so they sit side by side. */
.time-grid__events {
  position: absolute;
  inset: 0 var(--space-1) 0 var(--space-0-5);
  display: grid;
  grid-template-rows: repeat(var(--slots), var(--slot-height));
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: row dense; /* reuse the first free column */
  column-gap: var(--space-0-5);
  pointer-events: none; /* clicks fall through to the slots… */

  > * {
    pointer-events: auto; /* …except on the blocks themselves */
  }
}

/* ---------- Appointment block ---------- */

.cal-event {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
  min-width: 0;
  margin: 1px 0;
  padding: var(--space-1) var(--space-2);
  overflow: hidden;
  background: var(--color-primary-subtle);
  border: var(--border-width) solid var(--color-primary-border);
  border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  line-height: var(--leading-tight);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out);

  &:hover {
    background: var(--color-primary-subtle-hover);
    box-shadow: var(--shadow-sm);
  }
}

/* In its room's colour: _appointment.html.erb adds this together with a
   color-swatch--<name> class, which sets --swatch / --swatch-highlight (color_picker.css).
   Appointments in a room without a colour keep the teal above. */
.cal-event--themed {
  background: var(--swatch-highlight);
  border-color: color-mix(in srgb, var(--swatch) 35%, transparent);
  border-left-color: var(--swatch);

  &:hover {
    background: color-mix(in srgb, var(--swatch-highlight), var(--swatch) 12%);
  }

  .cal-event__time {
    color: var(--swatch);
  }
}

/* Short appointments don't have room for everything. overflow: hidden (needed for the
   ellipsis) lets a flex item shrink to 0, so without flex-shrink: 0 the title and time
   were squeezed away first. Now they keep their height, the links give way instead,
   and whatever doesn't fit is cut off at the bottom by .cal-event's overflow: hidden. */
.cal-event__title {
  flex-shrink: 0;
  color: var(--color-text);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;

  /* Stretch the link over the whole block */
  &::after {
    content: "";
    position: absolute;
    inset: 0;
  }

  &:hover {
    color: var(--color-text);
    text-decoration: none;
  }
}

.cal-event__time {
  flex-shrink: 0;
  color: var(--color-primary-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cal-event__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  /* The first thing to go when the block is short */
  min-height: 0;
  overflow: hidden;
}

/* Above the stretched title link, so these stay clickable */
.cal-event__link {
  position: relative;
  z-index: 1;
  max-width: 100%;
  padding: 0 var(--space-1-5);
  overflow: hidden;
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  text-overflow: ellipsis;

  &:hover {
    color: var(--color-primary-text);
  }
}

.cal-event__link--pet::before {
  content: "🐾 ";
}

/* Day view has one wide column, so lay title, time and links out in a row */
.time-grid--day .cal-event {
  flex-direction: row;
  align-items: flex-start;
  gap: var(--space-3);

  .cal-event__title {
    flex-shrink: 1; /* in a row it's the width that shrinks: undo the flex-shrink: 0 above */
    min-width: 0; /* lets a long title shrink and get its ellipsis */
  }

  .cal-event__time {
    flex-shrink: 0;
  }

  .cal-event__links {
    flex-wrap: nowrap;
    min-width: 0;
  }
}

/* ---------- Free gap (rooms view) ---------- */

.cal-gap {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin: 2px 0;
  overflow: hidden;
  background: var(--color-success-subtle);
  border: var(--border-width) dashed var(--color-success-border);
  border-radius: var(--radius-sm);
  color: var(--color-success-text);
  font-size: var(--text-xs);
  line-height: var(--leading-tight);
  text-align: center;
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);

  &:hover {
    border-style: solid;
    border-color: var(--color-success);
    color: var(--color-success-text);
    text-decoration: none;
  }
}

.cal-gap__label {
  font-weight: var(--weight-semibold);
}

.cal-gap__time {
  font-variant-numeric: tabular-nums;
}

/* ---------- Rooms view: each room in its colour ---------- */

/* The room's colour comes from a color-swatch--<name> class on the header cell and the
   column (it sets --swatch and --swatch-highlight). A room without a colour has neither,
   so every var() falls back to the usual teal. The appointments themselves are
   coloured by .cal-event--themed, in every view. */
.time-grid--rooms {
  .time-grid__day {
    border-top: 3px solid var(--swatch, transparent);
  }

  /* Coloured dot before the room name */
  .time-grid__room {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1-5);

    &::before {
      content: "";
      width: 0.5rem;
      height: 0.5rem;
      border-radius: var(--radius-full);
      background: var(--swatch, var(--color-primary));
    }
  }
}

/* ---------- Month grid ---------- */

.month-grid {
  overflow: hidden;
}

.month-grid__head,
.month-grid__body {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.month-grid__head {
  background: var(--color-surface-sunken);
  border-bottom: var(--border);
}

.month-grid__weekday {
  padding: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  text-align: center;
}

.month-grid__cell {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-height: 7.5rem;
  padding: var(--space-1-5);
  border-right: var(--border);
  border-bottom: var(--border);

  &:nth-child(7n) {
    border-right: 0;
  }
}

.month-grid__cell--outside {
  background: var(--color-bg);

  .month-grid__date {
    color: var(--color-text-disabled);
  }
}

.month-grid__cell-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.month-grid__date {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-full);
  color: var(--color-text);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;

  &:hover {
    background: var(--color-surface-hover);
    text-decoration: none;
  }
}

.month-grid__cell[aria-current="date"] .month-grid__date {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.month-grid__add {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--radius-sm);
  color: var(--color-text-subtle);
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-out);

  svg {
    width: var(--icon-sm);
    height: var(--icon-sm);
  }

  &:hover {
    background: var(--color-primary-subtle);
    color: var(--color-primary-text);
  }

  &:focus-visible {
    opacity: 1;
  }
}

.month-grid__cell:hover .month-grid__add {
  opacity: 1;
}

.month-grid__events {
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
  padding: 0;
  list-style: none;
}

.month-event {
  display: flex;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-1-5);
  border-radius: var(--radius-sm);
  background: var(--color-primary-subtle);
  color: var(--color-text);
  font-size: var(--text-xs);
  white-space: nowrap;
  overflow: hidden;

  &:hover {
    background: var(--color-primary-subtle-hover);
    color: var(--color-text);
    text-decoration: none;
  }
}

.month-event__time {
  color: var(--color-primary-text);
  font-variant-numeric: tabular-nums;
}

.month-event__title {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* In its room's colour, same idea as .cal-event--themed: color-swatch--<name> on the
   same link sets --swatch / --swatch-highlight. No room colour → the teal above */
.month-event--themed {
  background: var(--swatch-highlight);

  &:hover {
    background: color-mix(in srgb, var(--swatch-highlight), var(--swatch) 12%);
  }

  .month-event__time {
    color: var(--swatch);
  }
}

.month-grid__more {
  padding: 0 var(--space-1-5);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
}

/* ---------- Modal (new / edit) ---------- */

/* Opened over the calendar, or over any page whose modal frame has .modal-host
   (e.g. the profile's appointment list). Opened as its own page (/appointments/5/edit)
   it has neither, so it stays a plain card in the page flow */
:is(.calendar, .modal-host) .modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: var(--space-4);
}

.modal__backdrop {
  display: none;
}

:is(.calendar, .modal-host) .modal__backdrop {
  display: block;
  position: absolute;
  inset: 0;
  background: var(--color-overlay);
}

.modal__panel {
  position: relative;
  width: min(40rem, 100%);
  margin: 0 auto;
}

:is(.calendar, .modal-host) .modal__panel {
  max-height: calc(100dvh - var(--space-8));
  overflow-y: auto;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
}

.modal__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.modal__footer-actions {
  display: flex;
  gap: var(--space-2);
  margin-left: auto;
}

.modal__shortcuts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: var(--border);
}

/* Two fields side by side, stacked on narrow screens */
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.form-errors {
  padding-left: var(--space-4);
}

@media (max-width: 40rem) {
  .form-grid {
    grid-template-columns: 1fr;
  }

  .calendar-toolbar__title {
    width: 100%;
    margin-left: 0;
    order: -1;
  }

  .month-grid__cell {
    min-height: 4.5rem;
  }

  .month-event__title {
    display: none;
  }
}
