/* Planner */
/* ======= */
#page_container:has(#gear_planner) {
  height: 100vh;
}

#page_content:has(#gear_planner) {
  flex-grow: 1;

  min-height: 0;
  padding: 0;

  display: flex;
}

.planner {
  flex-grow: 1;

  display: flex;
  flex-direction: row;
  align-items: stretch;

  min-height: 0;
}


/* Blade - the resizable side panel holding Controls / Events / Items. Sits on the right by
   default; [data-planner-blade-side-value="left"] on the root (see planner_blade_controller.js)
   flips it and the content pane to the other side. The resize handle's own order (2) keeps it
   between the two regardless of which side the blade is on, so it never needs a side rule of
   its own. */
.planner__blade {
  width: var(--planner-blade-width, 470px);
  flex: none;
  order: 3;

  display: flex;
  flex-direction: column;
  min-height: 0;

  overflow-y: auto;

  background-color: var(--bs-tertiary-bg);
}

.planner[data-planner-blade-side-value="left"] .planner__blade {
  order: 1;
}

.planner[data-planner-blade-side-value="left"] .planner__content {
  order: 3;
}

.planner__resize-handle {
  width: 6px;
  flex: none;
  order: 2;

  cursor: col-resize;

  border-left: var(--bs-border-width) solid var(--bs-border-color);
  border-right: var(--bs-border-width) solid var(--bs-border-color);
  background-color: transparent;
}

.planner__resize-handle:hover,
.planner__resize-handle:active {
  background-color: var(--bs-secondary-bg);
}

/* Fixed height (rather than letting padding + content decide it) so this lines up exactly
   with .planner__content-header's own border-bottom across the resize handle - the two
   contain different content (a button vs a heading) that would otherwise settle at slightly
   different natural heights. */
.planner__finish {
  flex: none;
  height: 3.5rem;

  display: flex;
  align-items: center;

  padding: 0 0.75rem;

  border-bottom: var(--bs-border-width) solid var(--bs-border-color);
}

.planner-finish-button-container {
  display: flex;

  width: 100%;
}

.planner-finish-button-container .pg-button {
  flex: 1;
}


/* Collapsible sections (Controls / Events / Items) - the calendar's own event-detail view uses
   this same <details>/<summary> idiom (.calendar-view__disclosure et al in calendar-form.css);
   copied here rather than sharing a class, since the two live in different colour contexts. */
.planner-section {
  flex: none;

  border-bottom: var(--bs-border-width) solid var(--bs-border-color);
}

.planner-section__summary {
  display: flex;
  align-items: center;
  gap: 8px;

  padding: 0.9rem 1rem;

  font-weight: 600;
  color: var(--bs-emphasis-color);

  cursor: pointer;
  list-style: none;
}

.planner-section__summary::-webkit-details-marker {
  display: none;
}

.planner-section__title {
  flex: 1;
}

.planner-section__meta {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--pg-accent);
}

.planner-section__clear {
  font-size: 0.75rem;

  color: var(--bs-link-color);
  text-decoration: none;
}

.planner-section__clear:hover {
  color: var(--bs-danger);
}

.planner-section__clear.disabled {
  color: var(--bs-secondary-color);
  opacity: 0.4;
  pointer-events: none;
}

.planner-section__caret {
  flex: none;

  color: var(--bs-secondary-color);

  transition: transform 0.15s ease-in-out;
}

.planner-section[open] .planner-section__caret {
  transform: rotate(180deg);
}

.planner-section__body {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;

  padding: 0 1rem 1rem;
}


/* Controls */
.planner-control-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.planner-control-row__label {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}

/* Notify (admin mode only) - recipient chips sit inline with their label, right-aligned like
   the other controls, same fixed width/height as .planner-segmented so the whole row of
   switches lines up, joined into a single group with a thin divider (not a gap) between
   recipients so each still reads as its own button. */
.planner-notify-recipients {
  display: flex;

  width: 10.5rem;
  height: 2rem;
  flex-shrink: 0;

  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  overflow: hidden;
}

/* Avatar + name segment, toggled by its (visually hidden but still focusable) checkbox - same
   "filled when active" idiom as .planner-segmented__option--active, just with an avatar
   alongside the name and individually toggleable, since any number of recipients can be
   selected. */
.planner-notify-chip {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex: 1;
  min-width: 0;

  padding: 0 0.5rem;

  border: 0;
  background-color: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);

  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;

  cursor: pointer;
  transition: background-color 0.1s ease, color 0.1s ease;
}

.planner-notify-chip:not(:last-child) {
  border-right: var(--bs-border-width) solid var(--bs-border-color);
}

.planner-notify-chip:has(input:checked) {
  background-color: var(--pg-accent);
  color: var(--pg-accent-contrast);
}

.planner-notify-chip:has(input:focus-visible) {
  outline: 2px solid var(--pg-accent);
  outline-offset: -2px;
}

.planner-notify-chip__avatar {
  display: block;
  width: 1rem;
  height: 1rem;
  flex: none;

  border-radius: 50%;
  object-fit: cover;
}

.planner-notify-chip__avatar--icon {
  display: flex;
  align-items: center;
  justify-content: center;

  font-size: 1rem;
  line-height: 1;
  color: currentColor;
}

.planner-notify-chip__name {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.planner-range-field {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;

  width: 10.5rem;
  flex-shrink: 0;
  box-sizing: border-box;
  min-height: 2rem;
  padding: 0 0.65rem;

  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background-color: var(--bs-body-bg);
}

.planner-range-field__label {
  flex: none;

  font-size: 0.7rem;
  font-weight: 700;
  color: var(--bs-secondary-color);
}

.planner-range {
  flex: 1;
  min-width: 0;

  accent-color: var(--pg-accent);
}


/* Segmented (two-option) toggle - Item sort, Already-worn, Blade placement, All/Unplanned */
.planner-segmented {
  display: flex;

  width: 10.5rem;
  flex-shrink: 0;

  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  overflow: hidden;
}

.planner-segmented--block {
  width: 100%;
}

.planner-segmented__option {
  flex: 1;

  padding: 0.4rem 0.6rem;

  border: 0;
  background-color: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);

  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;

  cursor: pointer;
}

.planner-segmented--block .planner-segmented__option {
  display: flex;
  align-items: center;
  justify-content: center;
}

.planner-segmented__option--active {
  background-color: var(--pg-accent);
  color: var(--pg-accent-contrast);
}

.planner-select {
  width: 100%;
  box-sizing: border-box;
  height: 2.375rem;
  padding: 0 0.65rem;

  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background-color: var(--bs-body-bg);
  color: var(--bs-body-color);

  font-size: 0.8rem;
}


/* Events list */
/* Match the gap below the toggle to the gap above the scope select - the latter comes from
   the summary's own padding (0.9rem, see .planner-section__summary) rather than the body's
   (zero) top padding, so the bottom padding needs to equal that 0.9rem, not the body's usual
   1rem, to look even. */
.planner-section__body:has(+ .planner-events-list) {
  padding-bottom: 0.9rem;
}

/* max-height is kept in sync with how much room Controls/Items leave available (rather than a
   fixed cap) by planner_events_fit_controller.js, which sets --planner-events-max-height on
   this element whenever a section is opened/closed or the window is resized. The literal 21rem
   is only a pre-JS fallback (e.g. before Stimulus connects). */
.planner-events-list {
  flex: 1;
  min-height: 6rem;
  max-height: var(--planner-events-max-height, 21rem);

  display: flex;
  flex-direction: column;
  gap: 0.5rem;

  padding: 0 1rem 1rem;

  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Each row reads as its own card - matching the border+radius idiom used by the item tiles
   (.compact-itemgrid-card) - rather than only gaining a border once checked. */
.planner-event-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;

  padding: 0.6rem 0.65rem;

  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background-color: var(--bs-secondary-bg);
}

.planner-event-row:has(.planner-event-row__check:checked) {
  border-color: var(--pg-accent);
}

.planner-event-row__check {
  flex: none;
  margin-top: 0.15rem;

  accent-color: var(--pg-accent);
  cursor: pointer;
}

.planner-event-row__label {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;

  flex: 1;
  min-width: 0;

  cursor: pointer;
}

.planner-event-row__main {
  flex: 1;
  min-width: 0;
}

.planner-event-row__title-line {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.planner-event-row__title {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--bs-emphasis-color);

  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.planner-event-row__datetime {
  margin-top: 0.1rem;

  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

.planner-event-row__location {
  margin-top: 0.05rem;

  font-size: 0.7rem;
  color: var(--bs-secondary-color);

  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.planner-event-row__pill {
  flex: none;

  padding: 0.2rem 0.5rem;

  border-radius: 999px;
  background-color: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);

  font-size: 0.7rem;
}

.planner-event-row__pill--empty {
  background-color: var(--bs-warning-bg-subtle);
  color: var(--bs-warning-text-emphasis);
}

/* Completed events are de-emphasised in the events list (label only - leave the checkbox alone
   so it doesn't look disabled) */
.planner-event-row--completed .planner-event-row__label {
  opacity: 0.6;
}

.planner-event-row--completed .planner-event-row__title {
  text-decoration: line-through;
}

.planner-event-row__completed {
  color: var(--bs-success);
  text-decoration: none;
}

.planner-event-row__weather {
  display: inline-flex;
  align-items: center;
}

.planner-event-row__weather:empty {
  display: none;
}

.planner-event-row__none {
  padding: 1rem;

  text-align: center;
  color: var(--bs-secondary-color);
}

/* Unplanned filter - a pure CSS rule keyed off each row's server-rendered item count, toggled
   by planner_controller.js#setEventsFilter */
.planner-unplanned-only .planner-event-row:not([data-item-count="0"]) {
  display: none;
}


/* Item categories */
.planner-categories {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.planner-category {
  padding: 0.5rem 0.75rem;

  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background-color: var(--bs-secondary-bg);
}

.planner-category__summary {
  display: flex;
  align-items: center;
  gap: 8px;

  cursor: pointer;
  list-style: none;
}

.planner-category__summary::-webkit-details-marker {
  display: none;
}

.planner-category__title {
  flex: 1;

  font-size: 0.8rem;
  font-weight: 700;
  color: var(--bs-emphasis-color);
}

.planner-category__count {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--bs-secondary-color);
}

.planner-category__count--assigned {
  color: var(--pg-accent);
}

.planner-category__caret {
  flex: none;

  color: var(--bs-secondary-color);

  transition: transform 0.15s ease-in-out;
}

.planner-category[open] .planner-category__caret {
  transform: rotate(180deg);
}

.planner-category>.planner-tile-grid {
  margin-top: 0.85rem;
}


/* Tile grid - used for a category's items and for an event card's assigned items */
.planner-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, var(--planner-tile-size, 110px));
  gap: 0.7rem;
}

/* Its own (outer) container context, distinct from .compact-itemgrid-card's nested
   "itemgrid-card" one below - needed because .compact-itemgrid-usage-dates sits alongside
   .compact-itemgrid-card as a sibling, not inside it, so it can't query that container. */
.planner-tile {
  container-type: inline-size;
  container-name: planner-tile;

  position: relative;
}

/* Already-worn filter - a pure CSS rule keyed off the same in-use marker class
   planner_controller.js already maintains for the checkmark badge / highlighting, toggled by
   planner_controller.js#setHideWorn */
.planner-hide-worn .planner-tile:has(.compact-itemgrid-item-in-use) {
  display: none;
}

/* Card wrapping the thumbnail and (catalogue tiles only) its bulk-action footer, so the two
   share one border/radius and read as a single card with the footer flush against the image's
   bottom edge, rather than a separate block floating below it. Establishes a container query
   context so the footer can hide itself once the card is too narrow to show it usefully. */
.compact-itemgrid-card {
  container-type: inline-size;
  container-name: itemgrid-card;

  overflow: hidden;
  border-radius: var(--bs-border-radius);
  border: var(--bs-border-width) solid var(--bs-border-color);
}

.compact-itemgrid-thumbnail-container {
  position: relative;

  width: var(--planner-tile-size, 110px) !important;
  height: var(--planner-tile-size, 110px) !important;

  overflow: hidden;
  /* Transparent by default - .compact-itemgrid-item-in-use below overrides the width/color to
     draw the "assigned to a selected event" highlight around just the image. */
  border: var(--bs-border-width) solid transparent;
  background-color: var(--bs-white);
}

.compact-itemgrid-thumbnail-image {
  z-index: 0;

  padding: 0;

  width: 100%;
  height: 100%;

  object-fit: contain;
  border: 0;
}

.compact-itemgrid-item-reference-overlay {
  z-index: 1;

  position: absolute;

  width: 100%;

  bottom: 0;

  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;

  font-weight: 600;
  font-size: 0.65rem;

  background-color: rgba(var(--bs-white-rgb), 0.8);
  color: var(--bs-dark);

  overflow: hidden;
}

.compact-itemgrid-item-in-use {
  border-width: 2px;
  border-color: var(--pg-accent);
}

/* Checkmark badge - shown on a catalogue tile once it's assigned to at least one selected
   event. A pseudo-element rather than a DOM node, since the marker class it keys off
   (.compact-itemgrid-item-in-use) is already toggled by planner_controller.js. */
.compact-itemgrid-item-in-use::after {
  content: "\2713";

  position: absolute;
  top: 0.15rem;
  right: 0.15rem;
  z-index: 2;

  width: 1.1rem;
  height: 1.1rem;

  border-radius: 999px;
  background-color: var(--pg-accent);
  color: var(--pg-accent-contrast);

  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1.1rem;
  text-align: center;
}

/* Remove button - shown on an item slot inside an event card, overlaid on the thumbnail's
   corner so it doesn't take up its own row. Sized/positioned to match the catalogue's
   "in use" checkmark badge (.compact-itemgrid-item-in-use::after) so the two read as the
   same kind of corner indicator. */
.planner-tile__remove {
  position: absolute;
  top: 0.15rem;
  right: 0.15rem;
  z-index: 3;

  display: flex;
  align-items: center;
  justify-content: center;

  width: 1.1rem;
  height: 1.1rem;
  padding: 0;

  border: none;
  border-radius: 999px;
  background-color: var(--bs-danger);
  color: var(--bs-white);

  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
}

.planner-tile__remove:hover {
  filter: brightness(0.9);
}

/* Footer - bulk add/remove across every selected event, shown on catalogue tiles only. Flush
   against the thumbnail above it (same card, see .compact-itemgrid-card) rather than a
   separately-spaced block, and hidden once the card is too narrow to show it usefully. */
.planner-tile__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.2rem;

  padding: 0.15rem 0.25rem;

  border-top: var(--bs-border-width) solid var(--bs-border-color);
  background-color: var(--bs-tertiary-bg);
}

@container itemgrid-card (max-width: 40px) {
  .planner-tile__footer {
    display: none;
  }
}

.planner-tile__action {
  flex: none;

  display: flex;
  align-items: center;
  justify-content: center;

  width: 1.1rem;
  height: 1.1rem;
  padding: 0;

  border: 0;
  border-radius: var(--bs-border-radius);
  background-color: transparent;
  color: var(--bs-emphasis-color);

  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
}

.planner-tile__action:hover {
  background-color: var(--bs-secondary-bg);
}

.planner-tile__action:disabled {
  opacity: 0.4;
  cursor: default;
}

.planner-tile__action--minus {
  color: var(--bs-danger-text-emphasis);
}

.planner-tile__in-count {
  flex: 1;
  /* Flex items default to min-width: auto, which stops them shrinking below their own content
     and forces the row to overflow instead - min-width: 0 here lets the count give way to the
     buttons at very small tile sizes rather than blowing out the footer's width. */
  min-width: 0;
  overflow: hidden;
  text-overflow: clip;
  white-space: nowrap;

  text-align: center;

  font-size: 0.6rem;
  font-weight: 600;
  color: var(--pg-accent);
}

/* Last/next-used row - side by side (rather than stacked) so each value is a short, non-wrapping
   token ("6d" / "in 3d" - see relative_date_description_short); icon + column position conveys
   last vs. next, so there's no label text to wrap either. Hidden below a tile width where even
   the abbreviated values can't read cleanly (see the container query below), matching the
   .planner-tile__footer cutoff pattern. */
.compact-itemgrid-usage-dates {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem;

  margin-top: 0.35rem;

  font-size: 0.65rem;
  color: var(--bs-secondary-color);
}

.compact-itemgrid-usage-date {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  min-width: 0;

  overflow: hidden;
  white-space: nowrap;
  text-overflow: clip;
}

@container planner-tile (max-width: 60px) {
  .compact-itemgrid-usage-dates {
    display: none;
  }
}

.compact-itemgrid__item-notes {
  box-sizing: border-box;
  width: 100%;

  border-radius: 0.25rem;
  border: 1px solid var(--bs-dark-border-subtle);

  background-color: rgb(var(--bs-secondary-bg-rgb));
  color: var(--bs-dark-text-emphasis);

  font-size: 0.6rem;
  margin-top: 0.25rem;
  padding: 0.25rem;

  text-wrap: wrap;
  white-space: normal;
  overflow-wrap: break-word;
}

.compact-itemgrid__item-notes-header {
  width: 100%;

  margin-bottom: 0.25rem;

  border-bottom: 1px solid var(--bs-dark-border-subtle);

  font-size: 0.6rem;
  font-weight: 600;
}


/* Content pane - "Selected events" */
.planner__content {
  flex: 1;
  min-width: 0;
  order: 1;

  display: flex;
  flex-direction: column;
  min-height: 0;
}

.planner__content-header {
  flex: none;
  height: 3.5rem;

  display: flex;
  align-items: center;

  padding: 0 1.25rem;

  border-bottom: var(--bs-border-width) solid var(--bs-border-color);
}

.planner__content-title {
  margin: 0;

  font-size: 1.05rem;
  font-weight: 600;
  color: var(--bs-emphasis-color);
}

.planner__content-body {
  flex: 1;
  min-height: 0;

  display: flex;
  flex-direction: column;
  gap: 1rem;

  padding: 1.25rem;

  overflow-y: auto;
  overscroll-behavior: contain;
}

/* .pg-card sets overflow: hidden, which makes this flex item's automatic min-height resolve to
   0 instead of its content size - so without flex-shrink: 0, the flex column above would
   compress (and clip) cards to fit instead of actually overflowing and letting the pane
   scroll. */
.selected-event-card {
  flex: none;
}

.selected-event-card-drop-highlight {
  background-color: var(--bs-warning-bg-subtle);
}

.selected-event-card-highlighted-item {
  border-color: var(--bs-warning) !important;
}

.selected-event-card-highlighted-item::before {
  content: "";
  display: block;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  position: absolute;
  pointer-events: none;
  background: rgba(var(--bs-warning-rgb), 0.5);
}

.selected-event-card__header {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.selected-event-card__main {
  flex: 1;
  min-width: 0;
}

.selected-event-card__title-line {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.selected-event-card-title {
  font-weight: 600;
  font-size: 1.25rem;
}

.selected-event-card-datetime {
  font-size: 0.875rem;
}

.selected-event-card__location {
  margin-top: 0.1rem;

  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

.selected-event-card__weather {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;

  font-size: 0.8rem;
  font-weight: 700;
}

.selected-event-card__weather:empty {
  display: none;
}

.selected-event-card__count {
  flex: none;

  padding: 0.25rem 0.55rem;

  border-radius: 999px;
  background-color: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);

  font-size: 0.7rem;
  font-weight: 600;
}

.selected-event-card__count--empty {
  background-color: var(--bs-warning-bg-subtle);
  color: var(--bs-warning-text-emphasis);
}

/* The event's ruleset: a line saying how many required rules are filled, and the
   missing-rules bar under it when any are short (see calendar-rulesets.css) */
.selected-event-card__ruleset {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin-bottom: 0.75rem;
}

.selected-event-card__ruleset-line {
  font-size: 0.8125rem;
  font-weight: 600;
}

.selected-event-card__empty {
  margin-bottom: 0.75rem;
  padding: 0.85rem 1rem;

  border: 1px dashed var(--bs-border-color);
  border-radius: var(--bs-border-radius);

  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}