/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* ── Chrome layout (structure only, no color overrides) ── */
:root {
  --topbar-h:       52px;
  --sidebar-w:      220px;
  --sidebar-coll-w: 60px;
}

.app-sidebar {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--sidebar-w);
  background-color: var(--bs-primary);
  border-right: 1px solid var(--bs-border-color);
  box-shadow: 3px 0 12px rgba(0, 0, 0, 0.08);
  overflow-y: auto;
  overflow-x: hidden;
  z-index: 1035;
  transition: width 0.2s ease;
}

.sidebar-collapsed .app-sidebar { width: var(--sidebar-coll-w); }
.sidebar-collapsed .app-topbar  { left: var(--sidebar-coll-w); }
.sidebar-collapsed .app-content { margin-left: var(--sidebar-coll-w); }

.app-sidebar-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 1.25rem 0.75rem 0.75rem;
  color: inherit;
}

.app-sidebar-brand:hover {
  color: inherit;
  opacity: 0.85;
}

.app-sidebar-logo {
  height: 96px;
  width: auto;
  flex-shrink: 0;
}

.app-sidebar .nav-link {
  font-size: 0.9rem;
  border-radius: 6px;
  color: rgba(255, 255, 255, 0.85) !important;
  display: flex !important;
  align-items: center;
}

.app-sidebar .nav-link:hover {
  color: #fff !important;
  background-color: rgba(255, 255, 255, 0.15);
}

.app-sidebar .nav-pills .nav-link.active {
  font-weight: 700;
  color: #fff !important;
  background-color: rgba(255, 255, 255, 0.2);
  border-left: 3px solid #fff;
  padding-left: calc(var(--bs-nav-link-padding-x) - 3px);
}

.sidebar-collapsed .app-sidebar .nav-link {
  justify-content: center !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
}

.app-sidebar-brand span {
  color: #fff;
  margin-top: -0.5rem;
  font-family: 'Fredoka', sans-serif;
  font-size: 1.4rem;
  letter-spacing: 0.05em;
  white-space: nowrap;
  transition: opacity 0.15s ease;
}

.sidebar-label {
  white-space: nowrap;
}

/* Labels that may be long (a course name) wrap instead of running out of the sidebar. */
.sidebar-label-wrap {
  white-space: normal;
  hyphens: auto;
  overflow-wrap: anywhere;
  min-width: 0;
  line-height: 1.25;
}
.app-sidebar .nav-link:has(.sidebar-label-wrap) {
  align-items: flex-start;
}
.app-sidebar .nav-link:has(.sidebar-label-wrap) > .bi {
  margin-top: 0.1rem;
}

.sidebar-collapsed .sidebar-label { display: none; }

.sidebar-collapsed .app-sidebar-brand {
  padding: 1rem 0.25rem 0.75rem;
}

.sidebar-collapsed .app-sidebar-logo {
  height: 36px;
}

/* Sidebar toggle button */
.sidebar-toggle {
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.8);
  width: calc(100% - 1rem);
  margin: 0 0.5rem;
  text-align: left;
  padding: 0.4rem 0.75rem;
  cursor: pointer;
  border-radius: 6px;
}

.sidebar-toggle:hover {
  color: #fff;
  background-color: rgba(255, 255, 255, 0.15);
}

.sidebar-collapsed .sidebar-toggle {
  text-align: center;
  padding-left: 0;
  padding-right: 0;
}

.sidebar-toggle-icon {
  transition: transform 0.2s ease;
}

.sidebar-collapsed .sidebar-toggle-icon {
  transform: scaleX(-1);
}

.app-topbar {
  left: var(--sidebar-w) !important;
  height: var(--topbar-h);
  border-top: none !important;
  border-bottom: 1px solid var(--bs-border-color);
  z-index: 1030;
  transition: left 0.2s ease;
}

.app-sidebar {
  border-top: none !important;
}

.app-content {
  margin-left: var(--sidebar-w);
  margin-top: var(--topbar-h);
  min-height: calc(100vh - var(--topbar-h));
  display: flex;
  flex-direction: column;
  transition: margin-left 0.2s ease;
}

/* ── Scroll-to-top button ────────────────────────── */
.scroll-top-btn {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 1050;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  padding: 0;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  transition: opacity 0.2s;
}

/* ── Tom Select ─────────────────────────────────── */
.ts-wrapper.form-select-sm .ts-control {
  padding: 0.2rem 0.5rem;
  min-height: unset;
}

/* ── Components ─────────────────────────────────── */
.card-header.card-header-brand {
  font-weight: 600;
}

.thead-brand th {
  background-color: var(--bs-primary) !important;
  color: #fff !important;
  font-weight: 600;
}

.thead-brand th a {
  color: #fff;
}

.thead-brand th .bi-sort {
  opacity: 0.5;
}

/* ── Topic description in modal view ───────────────────── */
.topic-description-view p,
.topic-description-view ul,
.topic-description-view ol {
  margin-bottom: 1.25rem;
}

.topic-description-view hr {
  margin-block: 1.5rem;
}

/* ── Subtle depth: cards & tables ──────────────────────── */
.card {
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
}

.table-responsive,
table.table {
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
}

.table-responsive > .table {
  margin-bottom: 0;
}


/* Favourite heart button */
.fav-btn {
  line-height: 1;
  text-decoration: none !important;
}
.fav-btn:hover .bi-heart { color: var(--bs-danger) !important; }

/* Tom Select fields match the other form fields in the light theme (the dark theme keeps its own). */
:root:not([data-theme="dark"]) .ts-wrapper .ts-control,
:root:not([data-theme="dark"]) .ts-wrapper.single .ts-control {
  background-color: #fbfbfd;
}
:root:not([data-theme="dark"]) .ts-wrapper .ts-control input::placeholder {
  color: var(--ctp-subtext0);
}

/* Availability form: the "only from … to …" times matter only when someone isn't available. */
.availability-day:has(input[value="available"]:checked) .availability-times { display: none !important; }

/* Scheduling board */
/* --board-zoom (schedule_board_controller.js) scales the board; --board-px is one minute's height. */
[data-controller~="schedule-board"] { --board-zoom: 1; --board-px: calc(1.7px * var(--board-zoom)); }
.board-day { min-width: 0; }
/* Horizontal layout: the days next to each other, scrolling sideways together. */
.board-horizontal { display: flex; align-items: flex-start; gap: 1rem; overflow-x: auto; padding-bottom: .5rem; }
.board-horizontal .board-day { flex: 0 0 auto; }
.board-horizontal .board-day > .d-flex.border { overflow-x: visible !important; }
.board-horizontal .board-column { min-width: calc(11rem * var(--board-zoom) * var(--lanes, 1)); }
.board-horizontal .board-card { font-size: calc(.68rem * var(--board-zoom)); line-height: 1.3; }
.board-horizontal .board-card .board-jury .badge { font-size: calc(.56rem * var(--board-zoom)); }
.board-horizontal .board-card-side { min-width: calc(2.6rem * var(--board-zoom)); }
.board-horizontal .board-card-action { width: calc(1.1rem * var(--board-zoom)); height: calc(1.1rem * var(--board-zoom)); font-size: calc(.75rem * var(--board-zoom)); }
.board-column { position: relative; border-left: 1px solid var(--bs-border-color); min-width: calc(11rem * var(--lanes, 1)); }
/* An hour line at the top of each hour; the view sets background-size to the height of an hour. */
/* Hour lines, and fainter quarter-hour lines (the view sets both background sizes). */
.board-grid { position: relative; background-image: linear-gradient(to bottom, var(--bs-border-color) 1px, transparent 1px),
                                                    linear-gradient(to bottom, color-mix(in srgb, var(--bs-border-color) 45%, transparent) 1px, transparent 1px); }
.board-card { position: absolute; left: 3px; right: 3px; overflow: hidden; cursor: grab; font-size: .75rem; line-height: 1.35; z-index: 2; }
/* The track's colour (--track-color, set per card) on the left edge and as a light tint. */
.board-card.card { border-left: 4px solid var(--track-color, var(--bs-primary)); background-color: color-mix(in srgb, var(--track-color, transparent) 10%, var(--bs-body-bg)); }
.board-card.dimmed { opacity: .25; }
/* On a card: the jury wraps over the lines it has; the right side holds start time, ✎ ×, end time. */
.board-card .board-student { overflow-wrap: anywhere; }
.board-card .board-room { font-size: .9em; }
.board-card .board-jury { line-height: 1.45; margin-top: .1rem; }
.board-card .board-jury > span { margin-right: .4rem; white-space: nowrap; }
.board-card .board-jury .badge { font-size: .62rem; vertical-align: .08em; margin-right: .15rem; }
.board-card-side { border-left: 1px solid var(--bs-border-color-translucent); min-width: 2.9rem; }
/* ✎ and × on a card: two equal small square buttons. */
.board-card-action { display: inline-flex; align-items: center; justify-content: center; width: 1.25rem; height: 1.25rem; padding: 0;
                     border: 0; border-radius: .25rem; background: none; color: var(--bs-secondary-color); font-size: .85rem; line-height: 1; }
.board-card-action:hover { background: var(--bs-secondary-bg); color: var(--bs-body-color); }
/* Someone a conflict concerns (red: hard, yellow: soft); the reasons show in a popover on hover. */
.board-card .board-conflict { border-radius: .2rem; padding: 0 .2rem; cursor: help; }
.board-card .board-conflict-hard { background: var(--bs-danger); color: #fff; }
.board-card .board-conflict-soft { background: var(--bs-warning); color: #000; }
.popover-lines .popover-body { white-space: pre-line; }
/* A room or chair that isn't the track's default. */
.board-card .board-override { background: var(--bs-info-bg-subtle); color: var(--bs-info-text-emphasis); border-radius: .2rem; padding: 0 .2rem; }
.board-card [data-person].highlighted { background: var(--bs-warning-bg-subtle); border-radius: .2rem; font-weight: 600; }
/* Bootstrap's .card (loaded after this file) would make cards position: relative. */
.board-grid .board-card { position: absolute; }
.board-card.conflict-hard { outline: 2px solid var(--bs-danger); }
.board-card.conflict-soft { outline: 2px solid var(--bs-warning); }
.board-sidebar .board-card { position: static; margin-bottom: .35rem; }
.board-drop-indicator { position: absolute; left: 0; right: 0; border-top: 2px dashed var(--bs-primary); z-index: 3; pointer-events: none; }
.board-drop-indicator::after { content: attr(data-label); position: absolute; right: 2px; top: -1.1rem; font-size: .7rem; background: var(--bs-primary); color: #fff; padding: 0 .3rem; border-radius: .2rem; }
.board-sidebar.drag-target, .board-column:hover { background-color: rgba(var(--bs-primary-rgb), .03); }

/* Picking several dates in a month (multi_date_controller.js): seven columns, Monday first. */
.multi-date-grid { display: grid; grid-template-columns: repeat(7, 2.4rem); gap: 2px; }
.multi-date-head { text-align: center; font-size: .7rem; color: var(--bs-secondary-color); padding-bottom: 2px; }
.multi-date-day { padding: .2rem 0; }

/* Marking unavailability (availability_grid_controller.js): a row of blocks per day, available (white) until marked. */
.availability-grid { display: grid; gap: 0; user-select: none; touch-action: none; font-size: .8rem; min-width: 36rem; }
.availability-grid .ag-hour { font-size: .7rem; color: var(--bs-secondary-color); padding-left: 2px; border-left: 1px solid var(--bs-border-color); }
.availability-grid .ag-day { background: none; border: 0; text-align: left; padding: .35rem .6rem .35rem 0; font-weight: 600; white-space: nowrap; color: var(--bs-body-color); }
.availability-grid .ag-day:hover { color: var(--bs-primary); text-decoration: underline; }
.availability-grid .ag-cell { height: 2rem; margin: 2px 0; background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); border-left-width: 0; cursor: crosshair; }
.availability-grid .ag-cell { border-right-color: color-mix(in srgb, var(--bs-border-color) 45%, transparent); }
.availability-grid .ag-cell.hour { border-left-width: 1px; }
.availability-grid .ag-cell.half { border-left: 1px dashed var(--bs-border-color); }
.availability-grid .ag-cell.off { background: var(--bs-secondary-bg); cursor: default; }
.availability-grid .ag-cell.soft { background: var(--bs-warning); }
.availability-grid .ag-cell.hard { background: var(--bs-danger); }
.availability-grid .ag-cell.selected { box-shadow: inset 0 0 0 2px var(--bs-primary); background-image: linear-gradient(color-mix(in srgb, var(--bs-primary) 25%, transparent), color-mix(in srgb, var(--bs-primary) 25%, transparent)); }
.availability-grid .ag-summary { padding-left: .75rem; font-size: .75rem; align-self: center; }
.ag-menu.card { position: absolute; z-index: 10; } /* .card (Bootstrap, loaded later) would make it relative */
.ag-swatch { display: inline-block; width: .9rem; height: .9rem; vertical-align: -.1rem; border: 1px solid var(--bs-border-color); background: var(--bs-body-bg); }
.ag-swatch.soft { background: var(--bs-warning); }
.ag-swatch.hard { background: var(--bs-danger); }

/* While an admin impersonates someone: a bar on top of every page. */
.impersonation-bar { background: var(--bs-warning); color: #000; position: sticky; top: 0; z-index: 1020; }
