/* Kill the rubber-band/bounce effect at the page edges without taking out
   Android Chrome's pull-to-refresh gesture. There's no single CSS property
   that does this: `overscroll-behavior: none` suppresses both, and `contain`
   preserves both. So `contain` is the default (no scroll-chaining, PTR
   preserved), and `none` is narrowed to two cases that have no PTR to lose:
   (1) fine-pointer devices — desktop browsers on Windows/macOS/Linux,
   including Firefox/Windows where bounce was introduced in v109; (2) iOS
   Safari, which is touch (so the media query doesn't match) but has no
   document-level PTR — caught via the webkit-only @supports trick. Android
   Chrome and Firefox-on-Android don't match either rule, so PTR survives. */
html, body {
  overscroll-behavior-y: contain;
}
@media (hover: hover) and (pointer: fine) {
  html, body {
    overscroll-behavior-y: none;
  }
}
@supports (-webkit-touch-callout: none) {
  html, body {
    overscroll-behavior-y: none;
  }
}

body {
  font-family: 'Noto Sans', sans-serif;
  margin-top: 3.85rem;
  /* The fixed navbar is out of flow but the body is pushed below it via the
     margin-top above. Without this min-height, body's flex column wouldn't
     reach the viewport bottom, so the mt-auto footer would float up next to
     the content on short pages. Subtract the margin so the body box plus its
     top margin together equal exactly 100vh. */
  min-height: calc(100vh - 3.85rem);
}

/* Logo and theme-icon swap based on data-bs-theme. */
[data-bs-theme="light"] .theme-icon-sun,
[data-bs-theme="light"] .logo-dark { display: none; }
[data-bs-theme="dark"] .theme-icon-moon,
[data-bs-theme="dark"] .logo-light { display: none; }

.navbar-brand img { height: 40px; width: auto; }

/* Footer is forced dark in both themes (data-bs-theme="dark" on the footer
   element scopes Bootstrap's color tokens), so the logo is hard-pinned to
   the light-on-dark variant — bypassing the global .logo-light/.logo-dark
   theme swap above. */
.footer-logo { height: 40px; width: auto; }
footer .footer-links a {
  color: var(--bs-body-color);
  text-decoration: none;
}
footer .footer-links a:hover,
footer .footer-links a:focus-visible {
  text-decoration: underline;
}
footer .footer-links li + li { margin-top: 0.25rem; }

/* Theme toggle: subtle circular hover/focus highlight so users get
   feedback when interacting with the icon-only button. The btn-link
   class would otherwise paint the icon Bootstrap's primary blue, so we
   pin the color to the navbar's own nav-link tokens for consistency. */
#themeToggle {
  border-radius: 50%;
  color: var(--bs-navbar-color);
}
#themeToggle:hover,
#themeToggle:focus {
  color: var(--bs-navbar-hover-color);
  background-color: var(--bs-secondary-bg);
  box-shadow: none;
}

/* Kill the blue focus glow site-wide on form fields. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  box-shadow: none;
}

/* Search submit button: kill the focus glow (the global rule above only
   covers form fields, not buttons). */
form[role="search"] .btn:focus {
  box-shadow: none;
}

/* Search field border: resting state uses Bootstrap's default
   --bs-border-color (theme-aware). On focus, darken to a medium gray —
   :focus-within scopes to the parent input-group so the input AND the
   submit button highlight together as a single unit. No primary blue.
   !important is required because the .border utility on the submit button
   declares its border-color with !important too. */
form[role="search"] .input-group:focus-within .form-control,
form[role="search"] .input-group:focus-within .btn {
  border-color: #adb5bd !important;
}

/* In dark mode, override the hardcoded bg-light on the search field so the
   input and submit button adopt a theme-aware dark surface (slightly lighter
   than body, mirroring the light-mode contrast). */
[data-bs-theme="dark"] .input-group .bg-light {
  background-color: var(--bs-tertiary-bg) !important;
}

/* Invert btn-outline-dark and btn-dark in dark mode so they read as
   outline-light and light. Bootstrap 5.3 buttons are driven by CSS vars,
   so we only need to redefine the relevant tokens. */
[data-bs-theme="dark"] .btn-outline-dark {
  --bs-btn-color: #f8f9fa;
  --bs-btn-border-color: #f8f9fa;
  --bs-btn-hover-color: #000;
  --bs-btn-hover-bg: #f8f9fa;
  --bs-btn-hover-border-color: #f8f9fa;
  --bs-btn-active-color: #000;
  --bs-btn-active-bg: #f8f9fa;
  --bs-btn-active-border-color: #f8f9fa;
  --bs-btn-disabled-color: #f8f9fa;
  --bs-btn-disabled-border-color: #f8f9fa;
}
[data-bs-theme="dark"] .btn-dark {
  --bs-btn-color: #000;
  --bs-btn-bg: #f8f9fa;
  --bs-btn-border-color: #f8f9fa;
  --bs-btn-hover-color: #000;
  --bs-btn-hover-bg: #e9ecef;
  --bs-btn-hover-border-color: #e9ecef;
  --bs-btn-active-color: #000;
  --bs-btn-active-bg: #dde0e3;
  --bs-btn-active-border-color: #dde0e3;
}

/* Home-page image grid. Thumbnails are slightly desaturated at rest and
   animate to full saturation with a subtle zoom on hover/keyboard focus.
   The scale is applied inside an overflow:hidden wrapper so the zoom is
   contained within the tile and the grid layout stays put. */
.image-card__thumb {
  width: 100%;
  height: auto;
  filter: saturate(0.65);
  transition: filter 0.3s ease, transform 0.3s ease;
}
.image-card:hover .image-card__thumb,
.image-card:focus-visible .image-card__thumb {
  filter: saturate(1);
  transform: scale(1.04);
}
@media (prefers-reduced-motion: reduce) {
  .image-card__thumb { transition: none; }
  .image-card:hover .image-card__thumb,
  .image-card:focus-visible .image-card__thumb { transform: none; }
}

/* Tag archive page header — museum / catalog-card treatment: a small
   uppercase 'Tag' eyebrow label sits above the subject term, separated
   by a hairline rule from the grid below. */
.header__label {
  letter-spacing: 0.18em;
}
.header__title {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  letter-spacing: -0.01em;
}
.header__back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  text-decoration: none;
  opacity: 0.65;
  transition: opacity 0.15s ease;
  margin-top:0.25rem;
}
.header__back:hover,
.header__back:focus-visible {
  opacity: 1;
}

/* Top-tags pill nav on the home page. Inactive pills sit on a subtle
   secondary surface; on hover/focus they invert to the body's emphasis
   color for a clear affordance. */
.nav-pills .nav-link {
  background-color: var(--bs-secondary-bg);
  color: var(--bs-body-color);
  transition: background-color 0.15s ease, color 0.15s ease;
}
.nav-pills .nav-link:hover,
.nav-pills .nav-link:focus-visible {
  background-color: var(--bs-emphasis-color);
  color: var(--bs-body-bg);
}
/* Variant selector on post pages: subtle tertiary-bg highlight on the
   currently displayed variant, instead of Bootstrap's default primary-blue
   active row, to keep the post page in the site's monochrome scheme. */
.list-group-item.active {
  background-color: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  border-color: var(--bs-border-color);
}

/* Post layout: the selected variant is centered inside a bg-light frame
   that spans the column width. The frame's height is the smaller of the
   column width or the image's natural rendered height. Wide variants
   render at their natural aspect (frame shrinks vertically, no bg-light
   bands); square or taller variants are contained in a square frame, so
   tall variants get bg-light bands on the sides. The 100cqw cap on the
   image's max-height is what enforces the "no taller than the column is
   wide" rule (cqw = the frame's own inline size). */
.post-image-frame {
  width: 100%;
  container-type: inline-size;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: 1px solid var(--bs-border-color);
}
.post-image {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100cqw;
}
/* Variants taller than wide are scaled to fit the square frame and end
   up narrower than it, leaving bg-light bands on the sides. The
   left/right borders delineate the image edge against those bands. */
.post-image.is-narrow {
  border-left: 1px solid var(--bs-gray-500);
  border-right: 1px solid var(--bs-gray-500);
}
/* Alt-text trigger overlaid on the top-left corner of the image frame.
   Square, semi-transparent at rest, fully opaque on hover/focus — the
   colors stay constant (no dark-on-hover inversion). z-index keeps it
   above the image. */
.post-alt-btn {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-bg: var(--bs-body-bg);
  --bs-btn-border-color: var(--bs-border-color);
  --bs-btn-hover-color: var(--bs-body-color);
  --bs-btn-hover-bg: var(--bs-body-bg);
  --bs-btn-hover-border-color: var(--bs-border-color);
  --bs-btn-active-color: var(--bs-body-color);
  --bs-btn-active-bg: var(--bs-body-bg);
  --bs-btn-active-border-color: var(--bs-border-color);
  opacity: 0.65;
  transition: opacity 0.15s ease;
}
.post-alt-btn:hover,
.post-alt-btn:focus,
.post-alt-btn:focus-visible {
  opacity: 1;
}

/* Variant download button: low-contrast surface at rest (light bg / dark
   text in light mode; the tokens flip in dark mode), inverting to a
   high-contrast emphasis surface on hover/focus/active. */
.download-btn {
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-bg: var(--bs-secondary-bg);
  --bs-btn-border-color: var(--bs-border-color);
  --bs-btn-hover-color: var(--bs-body-bg);
  --bs-btn-hover-bg: var(--bs-emphasis-color);
  --bs-btn-hover-border-color: var(--bs-emphasis-color);
  --bs-btn-active-color: var(--bs-body-bg);
  --bs-btn-active-bg: var(--bs-emphasis-color);
  --bs-btn-active-border-color: var(--bs-emphasis-color);
}
.contact-form {
  margin-left: auto;
  margin-right: auto;
  border: 1px solid var(--bs-border-color);
  background-color: var(--bs-light);
  padding: 1rem;
  border-radius: var(--bs-border-radius);
}
.bg-primary-dark {
  background-color: var(--bs-primary-text-emphasis) !important;
}

@media (min-width: 1200px) {
  .contact-form {
    width: 75%;
  }
}

@media (min-width: 1400px) {
  .contact-form {
    width: 50%;
  }
    .fs-xxl-4 {
        font-size: calc(1rem + 0.3vw) !important;
    }
}
