/* Custom admin styles */

/* Navbar: slightly darker gray than Bootstrap bg-light */
.admin-navbar {
  background-color: #e0e0e0 !important; /* more gray */
}

/* Main content centered container */
.main-content-wrapper {
  background: #ffffff; /* keep page sides white */
}

.main-container {
  max-width: 1424px;
  margin: 0 auto;
  background-color: #f5f5f5; /* slightly gray background for content area */
  padding: 12px;
}

/* Status badges for project status */
.status-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  line-height: 1.4;
  color: #fff;
  font-weight: 600;
}
.status-published { background-color: #28a745; }
.status-draft { background-color: #fd7e14; }

/* Materials tree: collapsible folder toggles */
.material-folder-toggle {
  cursor: pointer;
  user-select: none;
}
.material-folder-toggle:hover .material-folder-caret {
  color: #ec3013;
}
.material-folder-caret {
  display: inline-block;
  width: 0.9em;
  color: #6c757d;
  font-size: 0.85em;
}

/* AI Teaching Assistant: flash the answer card when a reply arrives.

   Green, not the site's blue: blue is already the colour of every link and
   button inside this card, so a blue tint reads as chrome rather than as
   change. Two slow cycles at ~0.9 Hz, deliberately nowhere near the 3 Hz
   threshold at which flashing content becomes a seizure risk.

   Selector is .card.assistant-answer-pulse, not the bare class: Bootstrap's
   .card sets background-color, and equal specificity would leave the outcome
   to stylesheet order. The extra class wins outright. */
@keyframes assistantAnswerPulse {
  0%   { background-color: rgba(25, 135, 84, 0.16); }
  50%  { background-color: rgba(25, 135, 84, 0.00); }
  100% { background-color: rgba(25, 135, 84, 0.16); }
}
.card.assistant-answer-pulse {
  background-color: rgba(25, 135, 84, 0.16);
  animation: assistantAnswerPulse 1.1s ease-in-out 2;
}
@media (prefers-reduced-motion: reduce) {
  /* No flashing, but keep the static tint: the JS removes the class on a timer,
     so these visitors still get a visible cue rather than nothing at all. */
  .card.assistant-answer-pulse { animation: none; }
}

/* Admin dashboard: the four statistics tiles that share one card.

   Separators are drawn here rather than with per-tile border utilities because
   WHICH edge needs a line changes at the breakpoint: stacked below 768px every
   tile but the first needs a line above it, while at two columns the second
   tile of a row must not repeat it and the left column gains a vertical rule.
   768px is not a free choice — it is where .row-cols-md-2 folds. */
.stat-tiles > .stat-tile + .stat-tile {
  border-top: 1px solid var(--bs-border-color);
}
@media (min-width: 768px) {
  .stat-tiles > .stat-tile:nth-child(2) {
    border-top: 0;
  }
  /* :not(:last-child) so an ODD number of tiles does not leave the last one
     drawing a vertical rule against empty space. */
  .stat-tiles > .stat-tile:nth-child(odd):not(:last-child) {
    border-right: 1px solid var(--bs-border-color);
  }
}
/* The whole tile is a link (.stretched-link), so it needs to say so on hover. */
.stat-tiles > .stat-tile:hover {
  background-color: var(--bs-tertiary-bg);
}
/* …but not over the figures. .stretched-link::after covers the tile at z-index 1,
   which swallows text selection: mousedown and mouseup on a number both land on
   the link, so dragging to copy "9,836" navigates to the report instead. This is
   the only place those figures appear, and they were plain selectable text before
   the tiles existed, so lifting them back above the overlay keeps both — a
   tile-sized click target, and numbers you can still select. A click directly on
   a figure now does nothing, which is the right answer for clicking text. */
.stat-tiles > .stat-tile h5 {
  position: relative;
  z-index: 2;
}

/* Fine underline on content text links. HISTORY: task 14's first pass made
   link TEXT red, the client read that as broken links, and the rule became
   normal-color + red underline — until the 2026-07-29 feedback reversed it
   again ("all links and buttons should be red, globally"). The COLOR now comes
   from the global --bs-link-* redefinition below, so this rule only shapes the
   underline (and the underline follows currentColor, so it matches in both
   themes). The :not() chain still decides which links get an underline at all:
   buttons, badges, nav pills, dropdowns, pagination, and the card-as-link
   patterns (.text-reset / .text-decoration-none / .stretched-link) keep their
   component styling. */
.page-content a:not(.btn):not(.badge):not(.nav-link):not(.dropdown-item):not(.page-link):not(.text-reset):not(.text-decoration-none):not(.stretched-link) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* --- ESL design system (task 14): red primary, dark banner, Archivo brand --- */

/* Primary buttons in brand red. Both the CSS-variable form (Bootstrap >= 5.2
   resolves buttons through --bs-btn-*) and plain properties, so the override
   holds whichever path the vendored build takes. */
.btn-primary {
  --bs-btn-bg: #ec3013;
  --bs-btn-border-color: #ec3013;
  --bs-btn-hover-bg: #c9280f;
  --bs-btn-hover-border-color: #c9280f;
  --bs-btn-active-bg: #b0220a;
  --bs-btn-active-border-color: #b0220a;
  --bs-btn-disabled-bg: #ec3013;
  --bs-btn-disabled-border-color: #ec3013;
  --bs-btn-focus-shadow-rgb: 236, 48, 19;
  background-color: #ec3013;
  border-color: #ec3013;
}
/* !important is load-bearing (codex catch): the vendored app.min.css pins
   .btn-primary hover/focus/active to template blue WITH !important, so a
   normal override wins at rest and loses the moment the button is touched. */
.btn-primary:hover, .btn-primary:focus {
  background-color: #c9280f !important;
  border-color: #c9280f !important;
}
.btn-primary:active, .btn-primary.active {
  background-color: #b0220a !important;
  border-color: #b0220a !important;
}
.btn-primary:focus, .btn-primary:focus-visible {
  box-shadow: 0 0 0 0.25rem rgba(236, 48, 19, 0.3) !important;
}

/* The banner (top bar with the logo) in the design system's near-black. Every
   header control sits on it, so they all go light. */
.navbar-header {
  background-color: #201e1d;
}
.navbar-header .header-item,
.navbar-header .header-item i,
.navbar-header .fw-medium {
  color: #f2f0ef !important;
}
.navbar-header .header-item:hover {
  color: #ffffff !important;
}
.esl-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}
.esl-brand img {
  height: 38px;
  width: auto;
  display: block;
}
.esl-brand-name {
  font-family: 'Archivo', sans-serif;
  font-weight: 400;
  font-size: 24px;
  color: #ffffff;
  white-space: nowrap;
}
.esl-brand:hover .esl-brand-name { color: #ffffff; }

/* Red bottom border for the SMALL boxes only (landing sidebars for now — not
   the middle column, not anything wider than 6/12; per the design screenshot). */
.card-accent {
  border-bottom: 3px solid #ec3013;
}

/* --- Font-size control (task 15). `zoom` rather than a root font-size bump:
   the vendored template sizes most text with px utilities (font-size-13 etc.)
   that a rem change would not touch, and an "increase font size" button that
   only grows SOME text reads as broken. Zoom scales the page uniformly, like
   the browser's own zoom. --- */
html[data-fontsize="lg"] body { zoom: 1.12; }
html[data-fontsize="xl"] body { zoom: 1.25; }

/* --- Organisation logo carousel (task 16): 6 tiles visible, the track slides
   one tile per second (JS moves the first tile to the end after each step). --- */
.org-carousel { overflow: hidden; }
.org-carousel-track {
  display: flex;
  transition: transform 0.6s ease;
  will-change: transform;
}
.org-carousel-item {
  flex: 0 0 16.6667%;
  max-width: 16.6667%;
  padding: 0 10px;
  text-align: center;
}
.org-carousel-item img {
  max-width: 100%;
  height: 84px;
  object-fit: contain;
}
@media (max-width: 767px) {
  .org-carousel-item { flex: 0 0 33.3333%; max-width: 33.3333%; }
}

/* --- Global red repaint (client feedback 2026-07-29): "all links and buttons
   should be red — globally, not one-by-one."

   Bootstrap 5.3 resolves bare links, .btn-link, .text-primary, .bg-primary,
   .bg-primary-subtle, pagination hover/focus and more through the custom
   properties below, so redefining them recolors every consumer at once —
   including places with no class of their own (the admin tiles' "Details"
   links, the footer, the landing live feed). Values the build BAKED into
   class-local hex (.btn-primary above, .btn-outline-*, the pagination active
   box, form focus tints, checkboxes, the map tooltip) get explicit overrides
   after the variable block. Semantic colors stay untouched: success/danger/
   warning buttons and status/info badges keep their meaning — red everywhere
   would erase what the red ones signal. --- */
:root, [data-bs-theme=light] {
  --bs-primary: #ec3013;
  --bs-primary-rgb: 236, 48, 19;
  --bs-primary-bg-subtle: #fdeae7;
  --bs-primary-border-subtle: #f8b7ab;
  --bs-primary-text-emphasis: #b0220a;
  --bs-link-color: #ec3013;
  --bs-link-color-rgb: 236, 48, 19;
  --bs-link-hover-color: #c9280f;
  --bs-link-hover-color-rgb: 201, 40, 15;
}

/* Outline buttons carry their palette in class-local baked vars. .btn-outline-info
   is included: it is another template blue, and the client wants no blue buttons. */
.btn-outline-primary,
.btn-outline-info {
  --bs-btn-color: #ec3013;
  --bs-btn-border-color: #ec3013;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #ec3013;
  --bs-btn-hover-border-color: #ec3013;
  --bs-btn-focus-shadow-rgb: 236, 48, 19;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #b0220a;
  --bs-btn-active-border-color: #b0220a;
  --bs-btn-disabled-color: #ec3013;
  --bs-btn-disabled-border-color: #ec3013;
}

/* Pagination (incl. DataTables): hover/focus already follow --bs-link-*, but
   the active box and the focus ring are baked. */
.pagination {
  --bs-pagination-active-bg: #ec3013;
  --bs-pagination-active-border-color: #ec3013;
  --bs-pagination-focus-box-shadow: 0 0 0 0.15rem rgba(236, 48, 19, 0.15);
}

/* Form focus tints are baked soft template-blue in this build. */
.form-control:focus,
.form-select:focus {
  border-color: #f3a294;
  box-shadow: 0 0 0 0.15rem rgba(236, 48, 19, 0.15);
}
.form-check-input:checked { background-color: #ec3013; border-color: #ec3013; }
.form-check-input:focus {
  border-color: #f3a294;
  box-shadow: 0 0 0 0.15rem rgba(236, 48, 19, 0.15);
}

/* World-map hover tooltip: the vendored jsvectormap ships it #5c5cff blue, and
   its stylesheet loads AFTER this one (injected by the statistics view), so the
   element selector raises specificity above the vendor's bare class. */
div.jvm-tooltip { background-color: #ec3013; }

/* The banner's black must span the full viewport: the vendored template centers
   .navbar-header at max-width 85%, which left white bands either side. The
   template re-asserts the wrapper background at body[data-layout=horizontal]
   specificity, so a bare class here silently loses — match it. Content keeps
   the template's width; the .topnav row below still lays its own background
   over this. */
body[data-layout=horizontal] .ishorizontal-topbar,
.ishorizontal-topbar { background-color: #201e1d; }

/* Logged-in profile icon reddish: the glyph color lives in the SVG itself
   (img/avatar/generic.svg, only used in the header), the ring here. */
.navbar-header .header-profile-user { border-color: #ec3013; }

/* Topnav hover/focus in brand red (was template blue, pinned by the vendored
   sheet at its own specificity — .nav-link is excluded from the link vars). */
.topnav .navbar-nav .nav-link:hover,
.topnav .navbar-nav .nav-link:focus { color: #ec3013; }
