/* Project overrides on top of EdGEL 5. Keep light — prefer EdGEL/Bootstrap
   utilities in templates over custom CSS. */

/* The current central site removed EdGEL's always-on link underline: footer
   links are plain by default and underline only on hover/focus. Scope that
   newer treatment here rather than changing links across the whole site. */
.footer a:not(.btn) {
  font-weight: 400;
  text-decoration: none;
}
.footer a:not(.btn):hover,
.footer a:not(.btn):focus-visible {
  text-decoration: underline;
}

/* The central footer's MyEd button uses the Bootstrap Icons SVG sprite rather
   than the icon webfont, which is intentionally not loaded by this project. */
.footer-login-icon {
  width: 0.75em;
  height: 0.75em;
  margin-left: 0.15rem;
  fill: currentColor;
}

.card {
  transition: box-shadow 0.15s ease-in-out, transform 0.15s ease-in-out;
}
a.card:hover {
  transform: translateY(-2px);
}

/* EdGEL paints dark-navbar links white with dark text on :hover and on the
   server-rendered .active page. Its global .nav-link:active underline can
   become sticky when a pointer press is cancelled by dragging off the link,
   leaving dark text on the dark navbar until the next interaction. Keep the
   chosen page treatment, but make transient pointer/focus states consistently
   light and readable. */
.navbar-dark .navbar-nav .nav-link:not(.active):hover,
.navbar-dark .navbar-nav .nav-link:not(.active):focus,
.navbar-dark .navbar-nav .nav-link:not(.active):active {
  color: #fff;
  background-color: rgba(255, 255, 255, 0.18);
}

/* EdGEL absolutely positions .masthead-hero-image at width/height 100%, which
   STRETCHES any image whose aspect ratio differs from the banner strip's.
   Crop (cover) instead, so a dropped-in photo of any shape survives. */
.masthead-hero-image {
  object-fit: cover;
  object-position: center;
}

/* Inline images in synced editorial bodies (news_item.html). The Datastore
   sanitiser ships plain <img> tags with no Bootstrap classes, so a large
   original would overflow the column. */
.content-body img {
  max-width: 100%;
  height: auto;
}

/* Subtle HTMX in-flight indicator on the results region. */
#results.htmx-request {
  opacity: 0.6;
  transition: opacity 0.2s ease-in-out;
}

/* Facet option lists (rooms/_facets.html): the IS teaching-spaces list's
   button-group pattern — stacked list rows, selected row = brand fill —
   rebuilt on btn-check radios. Bootstrap only styles .btn-check + .btn, so
   the checked/focus states of the list-group labels are painted here, using
   the active EdGEL scheme's brand colour. */
.btn-check:checked + .list-group-item {
  background-color: rgba(var(--edgel-brand-rgb), 1);
  border-color: rgba(var(--edgel-brand-rgb), 1);
  color: #fff;
}
.btn-check:checked + .list-group-item .badge {
  background-color: #fff !important;
}
/* The input is visually hidden, so its keyboard focus must show on the label
   (WCAG 2.4.7). */
.btn-check:focus-visible + .list-group-item {
  outline: 2px solid rgba(var(--edgel-brand-rgb), 1);
  outline-offset: -2px;
}
/* Long facet lists (Building, Room type) scroll past a point so one facet
   can't push the rest of the filter column off screen. */
.facet-scroll {
  max-height: 16rem;
  overflow-y: auto;
}

/* Facility section icons (room detail): Bootstrap Icons sprite glyphs and
   the custom hearing-loop symbol. currentColor inherits the header text
   colour (and therefore its contrast); aria-hidden in markup — the visible
   section title carries the meaning. */
.facility-icon {
  width: 1.25em;
  height: 1.25em;
  flex-shrink: 0;
}

/* EdGEL's muted text is #707070 — 4.96:1 on white, which scrapes past WCAG
   AA but reads faint at the small sizes we use it (card meta, facet counts,
   support access times). Nudged darker to 7:1 (AAA) sitewide; still clearly
   secondary to body text. */
:root {
  --edgel-secondary-color: #595959;
}

/* Support triage cards are .card-high: EdGEL paints the whole card brand
   blue with white text, so the service-details footer stays white-on-blue
   (never text-muted — grey on this blue is ~1.4:1). EdGEL also zeroes the
   card-high footer's padding-top and border, so both are restored here:
   a half-opacity white rule (3.4:1 on the blue, clearing 1.4.11's 3:1) and
   the roomy bottom padding the card body used to carry as pb-4. */
.card-high > .card-footer.support-service {
  border-top: 1px solid rgba(255, 255, 255, 0.5);
  padding-top: 1rem;
  padding-bottom: 1.5rem;
}

/* Small trailing glyph marking a link that leaves the site (browse cards —
   the IS list uses the same box-arrow mark). Decorative: the link text says
   where it goes, and target="_blank" carries the behaviour. */
.link-icon {
  width: 0.8em;
  height: 0.8em;
  margin-left: 0.25rem;
  vertical-align: baseline;
}

/* Room detail photo strip. Every source photo is 4:3 (the survey camera), so
   an explicit aspect-ratio fills the column edge to edge without cropping —
   width alone left the images at intrinsic size. The cap stops a lone photo
   in a full-width column from running the page long; object-fit crops that
   case rather than distorting it. Clicking one opens the gallery modal. */
.room-photo {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  max-height: 26rem;
  object-fit: cover;
}

/* Room photo modal. EdGEL caps .gallery-media at 37.5rem, which leaves most
   of a fullscreen dialog empty — the photos are 4000px wide, so let them use
   the height the modal actually has (viewport minus the modal header and the
   body padding). Same specificity as EdGEL's rule; site.css loads after it. */
.room-gallery-media {
  max-height: calc(100vh - 9rem);
}

/* Holding panel for a room with no curated pictures. Appearance only — the
   two surfaces size it themselves (.room-card-photo on a browse card,
   .room-photo-empty-detail on the room page), so one box cannot inherit the
   other's dimensions. The fill alone defines the space — a step darker than
   whatever is behind it, muted, no edge — so it reads as "nothing here yet"
   rather than as a picture that failed to load. */
.room-photo-empty {
  color: var(--edgel-secondary-color);
  /* Translucent rather than a fixed grey: the panel sits on the page
     background (#e8e8e8) on the room page and on a white card in the
     browse grid, so a literal colour could only be darker than one of
     them. An overlay is a step darker than whatever is behind it. */
  background-color: rgba(0, 0, 0, 0.06);
}
.room-photo-empty-icon {
  width: 1.75rem;
  height: 1.75rem;
  opacity: 0.65;
}

/* The browse card's picture box. Shared by the photo and the holding panel so
   the two can never drift apart and leave the grid ragged. */
.room-card-photo {
  height: 150px;
  object-fit: cover;
}

/* The room page's holding panel matches .room-photo exactly: same 4:3 box,
   same cap, so the facts column sits where it does on a room with pictures. */
.room-photo-empty-detail {
  width: 100%;
  aspect-ratio: 4 / 3;
  max-height: 26rem;
}

/* Card vertical rhythm. EdGEL sets `.card-high .card-header, .card-low
   .card-header` to `1.5rem 1.25rem 0` — generous above the title, nothing at
   all below it — so its cards read top-heavy: the heading is pinned to the
   content beneath it, and the last row stops hard against the foot of the
   card with only its own padding to spare. Give the heading room, and put
   1.5rem at the bottom to answer the 1.5rem at the top.

   Keyed off the header rather than the card, so the browse cards (image +
   body, no header, already symmetric) keep the padding they have. Both
   variants, because EdGEL's rule covers both. */
.card-low > .card-header,
.card-high > .card-header {
  padding-bottom: 0.75rem;
}
/* Flush list rows carry 0.5rem of their own, so 1rem here totals 1.5rem. */
.card-low > .card-header + .list-group,
.card-high > .card-header + .list-group {
  padding-bottom: 1rem;
}
.card-low > .card-header + .card-body,
.card-high > .card-header + .card-body {
  padding-bottom: 1.5rem;
}

/* The photo viewer must clear the university's cookie-settings widget, which
   is injected outside our markup and stacks above EdGEL's modal layer (1055),
   so the viewer opened behind it. This is the only modal on the site, so
   lifting the whole layer is safe; the backdrop rides just below it. */
#room-photos {
  z-index: 2147483647;
}
.modal-backdrop {
  z-index: 2147483646;
}

/* Gallery arrows. EdGEL bottom-aligns them
   (`.gallery .carousel-control-* { align-items: flex-end }`) because its
   thumbnail strip normally sits underneath; we dropped that strip, so centre
   them on the picture instead. */
.gallery .carousel-control-prev,
.gallery .carousel-control-next {
  align-items: center;
  z-index: 2;
}

/* The caption is a label, not a control. It spans the full width at the foot
   of the slide, so while the arrows were bottom-aligned they sat inside it and
   it swallowed the clicks meant for them. Nothing in it is interactive, so it
   should never take a pointer. */
.gallery-caption {
  pointer-events: none;
}
