:root {
  --weekly-schedule-footer-height: 2.25rem;
  --weekly-schedule-days-row-height: 2.5rem;
  --weekly-schedule-week-switcher-height: 2rem;
  
  --weekly-schedule-slot-height: 4.375rem;
  --weekly-schedule-slot-height-thin: 3.25rem;
}

/* A flex column rather than a fixed header allowance. The calendar used to take
   `calc(100% - 8.5rem)`, a hand-measured stand-in for the title row plus the filters — so
   anything else added above it (the Calendar/Analytics tabs, a notice) pushed the calendar
   down without shrinking it, and the footer fell off the bottom of the clipped container.
   Letting the calendar take whatever is left means nothing above it can do that again. */
.weekly-schedule--page-container {
  width: 100%;
  height: 100%;
  overflow: clip;
  display: flex;
  flex-direction: column;
}

.weekly-schedule {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: white;
  border-radius: var(--radius-md);
}

.weekly-schedule--week-nav {
  display: flex;
  align-items: center;
  gap: var(--rem-16);
}

.weekly-schedule--calendar {
  flex: 1;
  overflow: auto;
  padding: 0;
  background: white;
  height: calc(100% - var(--weekly-schedule-footer-height));
  border-top-left-radius: var(--radius-md);
  border-top-right-radius: var(--radius-md);
}

.weekly-schedule--grid-header {
  height: var(--weekly-schedule-days-row-height);
  display: grid;
  grid-template-columns: 5.5rem repeat(7, 1fr);
  background: white;
  border-bottom: 1px solid #E5E7EB;
}

.weekly-schedule--time-header {
  padding: var(--rem-12) var(--rem-16);
  font-size: var(--rem-12);
  font-weight: var(--text-medium);
  color: #6B7280;
  display: flex;
  align-items: center;
  margin-inline: auto;
}

.weekly-schedule--day-header {
  padding: 0;
  text-align: center;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: .5rem;

  &[data-current="true"] {
    background-color: var(--primary-500);
    span {
      color: white;
    }
  }
}

.weekly-schedule--day-name {
  font-size: var(--rem-12);
  font-weight: var(--text-medium);
  color: #6B7280;
  text-transform: uppercase;
}

.weekly-schedule--day-date {
  font-size: var(--rem-18);
  font-weight: var(--text-semibold);
  color: var(--neutral-900);
  margin-top: var(--rem-2);
}

.weekly-schedule--grid {
  display: grid;
  grid-template-columns: 5.5rem repeat(7, 1fr);
  grid-template-rows: repeat(25, var(--weekly-schedule-slot-height-thin));
  position: relative;
  height: calc(100% - var(--weekly-schedule-days-row-height));
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;

  &::-webkit-scrollbar {
    display: none;
  }
}

.weekly-schedule--time-cell {
  grid-column: 1;
  padding: var(--rem-12) var(--rem-16);
  font-size: var(--rem-12);
  color: #6B7280;
  border-bottom: 1px solid #F3F4F6;
  border-right: 1px solid #E5E7EB;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  height: var(--weekly-schedule-slot-height-thin);
}

.weekly-schedule--slot {
  position: relative;
  border-left: 1px solid #E5E7EB;
  border-bottom: 1px solid #F3F4F6;
  padding: 0;
  height: var(--weekly-schedule-slot-height-thin);
  width: 100%;
}

.weekly-schedule--empty-slot {
  display: block;
  width: 100%;
  height: 100%;
  position: relative;
  text-decoration: none;
  padding: .25rem;
}

.weekly-schedule--empty-slot:hover {
  span.weekly-schedule--empty-slot-hover {
    opacity: 1;
  }
}

.weekly-schedule--empty-slot-hover {
  width: 100%;
  height: 100%;
  background-color: var(--primary-50);
  border: dashed 2px var(--primary-500);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
}

.weekly-schedule--appointments-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
}

.weekly-schedule--appointment {
  cursor: pointer;
  position: absolute;
  z-index: 2;
  pointer-events: all;
  opacity: 0;
  transition: opacity 0.2s ease-in-out;

  &:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  }

  &[data-positioned="true"] {
    opacity: 1;
  }

  /* When dropdown menu is open, give the appointment a high z-index */
  &:has(.dropdowns--menu:not([hidden])) {
    z-index: 9999;
  }
}

.weekly-schedule--appointment-inner {
  height: 100%;
  padding: .25rem;
  background: var(--primary-100);
  color: white;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-size: var(--rem-11);
  overflow: hidden;
  border-left: solid 3px var(--primary-500);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: .25rem;

  &[data-appointment-type="new_patient"] {
    background: #FFF4E9;
    border: solid 1px #EEB479;
    border-left: solid 3px #EEB479;
  }

  &[data-appointment-type="follow_up"] {
    background: #EDF6F8;
    border: solid 1px #62B6CB;
    border-left: solid 3px #62B6CB;
  }

  &[data-appointment-type="procedure"] {
    background: #F6EEF9;
    border: solid 1px #BB62D3;
    border-left: solid 3px #BB62D3;
  }

  &[data-appointment-type="other"] {
    background: var(--surface-subtle);
    border: dashed 1px var(--border-primary);
    border-left: solid 3px var(--border-primary);
  }
}

/* The block is packed, so a bad address gets a dot on the corner and nothing
   else. It sits on the outer (unclipped) element, outside the inner box's
   border, and takes no pointer events so the whole block stays clickable. */
.weekly-schedule--appointment-address-flag {
  position: absolute;
  top: -3px;
  left: -3px;
  z-index: 1;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: var(--error-500);
  /* The white ring separates it from the block's own border and the grid line
     behind it; the shadow lifts it off both. */
  box-shadow: 0 0 0 2px var(--surface-primary), 0 1px 2px rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

/* A visit with a note staff must act on (a patient who needs a driver). The ring sits
   apart from the block, with a gap, so it does not read as the live-recording ring, which
   hugs the block. The badge on the far corner from the address dot says the same thing
   when the block is too thin for the ring to stand out. The note itself is in the
   tooltip. */
.weekly-schedule--appointment[data-needs-attention="true"] > .weekly-schedule--appointment-inner {
  outline: 2px solid var(--warning-500);
  outline-offset: 1px;
}

.weekly-schedule--appointment-attention-flag {
  position: absolute;
  top: -5px;
  right: -5px;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background-color: var(--warning-500);
  box-shadow: 0 0 0 2px var(--surface-primary), 0 1px 2px rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

.weekly-schedule--appointment-patient {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: .125rem;
  width: calc(100% - 1.25rem);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  
  a {
    text-decoration: none;
    font-size: var(--rem-13);
    font-variation-settings: 'wght' var(--text-medium);
    color: var(--text-body);
    display: inline-block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

    &:hover {
      opacity: 0.75;
    }
  }

  span {
    font-size: var(--rem-11);
    font-variation-settings: 'wght' var(--text-medium);
    color: var(--text-information);
  }
}

.weekly-schedule--appointment-small-text {
  display: block;
  font-size: var(--rem-11);
  font-variation-settings: 'wght' var(--text-medium);
  color: var(--text-information);
  padding-block: .125rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;

  &:has(.icon) {
    display: flex;
    gap: .25rem;
    align-items: center;
    justify-content: flex-start;
  }
}

.weekly-schedule--footer {
  height: var(--weekly-schedule-footer-height);
  background: var(--neutral-200);
  border-bottom-left-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding-left: 1.5rem;
}

.weekly-schedule--stats {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 1rem;
  span {
    font-size: var(--rem-13);
    color: var(--text-body);
  }
}

.weekly-schedule--stats {
  font-weight: var(--text-semibold);
  color: var(--neutral-900);
}

.weekly-schedule--legend {
  display: flex;
  align-items: center;
  gap: var(--rem-24);
}

.weekly-schedule--legend-item {
  display: flex;
  align-items: center;
  gap: var(--rem-6);
}

.weekly-schedule--legend-dot {
  width: var(--rem-10);
  height: .25rem;
  border-radius: var(--radius-full);

  &[data-type="new_patient"] {
    background-color: #EEB479;
  }
  &[data-type="follow_up"] {
    background-color: #62B6CB;
  }
  &[data-type="procedure"] {
    background-color: #BB62D3;
  }
  &[data-type="other"] {
    background-color: var(--border-primary);
  }
}

.weekly-schedule--current-time-line {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: #EF4444;
  z-index: 10;
  pointer-events: none;
  transition: top 0.5s ease;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
}

.weekly-schedule--hour-indicator {
  display: none;
  position: absolute;
  width: 100%;
  height: 2px;
  background: black;
  z-index: 999;
}

.weekly-schedule--hour-indicator::before {
  content: attr(data-current-time);
  position: absolute;
  left: 0;
  top: 0;
  font-size: var(--rem-11);
  font-weight: var(--text-semibold);
  color: white;
  background-color: black;
  padding: 2px 6px;
  border-radius: var(--radius-xs);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.weekly-schedule--appointment-more-options-container {
  position: absolute;
  top: .5rem;
  right: .25rem;
  z-index: 10;
  display: none;
}

.weekly-schedule--appointment:hover > .weekly-schedule--appointment-inner > .weekly-schedule--appointment-more-options-container,
.weekly-schedule--appointment-more-options-container:has(.menus--more-options-button[data-active="true"]) {
  display: flex;
}

.weekly-schedule--appointment .menus--more-options-menu {
  z-index: 10000 !important;
  position: absolute;
}

.weekly-schedule--appointment .menus--more-options-container {
  z-index: inherit;
}

.weekly-schedule--week-switcher {
  width: fit-content;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 0.75rem;
  padding-left: 1px;
  height: var(--weekly-schedule-week-switcher-height);

  a {
    width: min-content;
  }
}

.weekly-schedule--appointment-top-row {
  width: calc(100% - 1.25rem);
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: .25rem;
}

.weekly-schedule--appointment-row {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: .25rem;
}
/* The turbo frame coverage loads into sits between the page container and the calendar,
   so it has to be transparent to the height chain `.weekly-schedule` measures against. */
/* .tasks--head carries `flex-grow: 1` for the pages it was written for. That was inert
   while this container was a block; as a flex column it grows to eat everything left over
   and pushes the calendar down the page. Only the calendar should absorb slack here. */
.weekly-schedule--page-container > .tasks--head {
  flex-grow: 0;
}

/* The frame sits between the page container and the calendar, so it is the flex child
   that has to absorb the remaining space. min-height: 0 lets it shrink below its content,
   without which the grid's own scrolling never engages. */
turbo-frame#appointments-calendar-frame {
  display: block;
  flex: 1;
  min-height: 0;
}

.weekly-schedule--coverage-note[data-state="ok"] {
  color: var(--text-information);
}

.weekly-schedule--coverage-note[data-state="warning"] {
  color: var(--text-warning);
}

.weekly-schedule--coverage-note[data-state="unavailable"] {
  color: var(--text-information);
  font-style: italic;
}

/* An unfinished setup, not an outage: the fix is on the Settings tab, so this reads as a
   prompt rather than as the apology above. */
.weekly-schedule--coverage-note[data-state="unconfigured"] {
  color: var(--text-warning);
}


/* Availability: a physician's scheduled stretch, drawn on the grid so appointments can be
   booked on top of it.

   pointer-events stay with the slot underneath — the whole point is to click through the
   block to create an appointment in it, so the band must never intercept that. It is also
   why the physician is named in the band itself rather than in a tooltip. */
.weekly-schedule--availability {
  /* Bottom of the three layers stacked on the grid:
       0  availability      — the substrate you book onto
       1  slot cells        — position: relative, z-index auto, later in the DOM, so the
                              empty-slot hover affordance draws over the band
       2  appointment blocks
     Raising this above 0 hides the dashed "add appointment" outline behind the band. */
  position: relative;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  justify-self: start;
  width: calc(100% / var(--lanes));
  margin-left: calc(100% / var(--lanes) * var(--lane));
  padding: var(--rem-2) var(--rem-4);
  border-radius: var(--radius-xs);
  /* --tone is set inline, per physician; the fill itself is shared with the footer key
     further down. */
}

.weekly-schedule--availability-label {
  display: flex;
  align-items: center;
  gap: var(--rem-4);
}

/* The band's one line: the initials say who, so the space the name used to take goes to
   the hours. Shrinks in place on a lane-split day column rather than wrapping under the
   avatar, so the band stays a single line however narrow the column gets. */
.weekly-schedule--availability-hours {
  min-width: 0;
  font-size: var(--rem-11);
  font-weight: var(--text-medium);
  color: var(--text-heading);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Footer key for the availability fills. About pattern, not colour: the colour says which
   physician and the block already spells that out, so the swatches take a neutral tone and
   differ only in the way the band itself differs. */
.weekly-schedule--availability-legend {
  display: flex;
  align-items: center;
  gap: var(--rem-12);
}

.weekly-schedule--availability-swatch {
  /* A band's fill is faint because it sits on a white grid; the footer is neutral-200,
     which the fill lands within a few points of. So the swatch keeps the band's exact
     recipe and takes a darker border to have an edge at all. */
  --tone: var(--neutral-600);
  width: var(--rem-20);
  height: var(--rem-12);
  border: 1px solid var(--border-primary-hover);
  border-radius: var(--radius-xs);
}

/* The two fills, shared by the blocks on the grid and the key in the footer so the two can
   never drift apart.

   Grouped selectors rather than a custom property holding the recipe: a var() inside a
   custom property is resolved against the element that DECLARES it, so hoisting this onto
   an ancestor resolves --tone there — where there is none — and every block silently
   loses its fill. */
.weekly-schedule--availability,
.weekly-schedule--availability-swatch {
  background-color: color-mix(in srgb, var(--tone) 14%, white);
}

/* Not confirmed by the scheduler: shown, because it is still the plan, but striped so it
   does not read as settled. Same tone — the stripes say "provisional", the colour still
   says who. */
.weekly-schedule--availability[data-tentative="true"],
.weekly-schedule--availability-swatch[data-tentative="true"] {
  background-image: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--tone) 30%, white),
    color-mix(in srgb, var(--tone) 30%, white) var(--rem-2),
    transparent var(--rem-2),
    transparent var(--rem-9)
  );
}
