/*!
 * FancyFields component library — styles.
 *
 * Dependency-free, RTL-aware (CSS logical properties only — no left/right),
 * keyboard-accessible (visible focus), and reduced-motion-aware. Pairs with
 * fancyfields-components.js. See references/components.md for the markup
 * contract the agent must emit. Components: lightbox, carousel, scroll-reveal,
 * sticky header, mobile drawer.
 *
 * Convention: every selector is namespaced under `.ff-*`. Directional CSS uses
 * logical properties (inset-inline-*, margin-inline-*, border-start-*, etc.) so
 * the same rules work in `dir="ltr"` and `dir="rtl"` with no mirrored overrides.
 */

/* --------------------------------------------------------------------------
 * Shared tokens & visible focus
 * ------------------------------------------------------------------------ */
:root {
  --ff-overlay-bg: rgba(0, 0, 0, 0.85);
  --ff-control-bg: rgba(255, 255, 255, 0.12);
  --ff-control-fg: #fff;
  --ff-focus-ring: 3px solid #4d90fe;
  --ff-z-overlay: 9999;
  --ff-transition: 240ms ease;
}

/* Always show a visible focus indicator for component controls (a11y). */
.ff-lightbox :focus-visible,
.ff-carousel :focus-visible,
.ff-drawer :focus-visible,
.ff-drawer-toggle:focus-visible,
.ff-reveal :focus-visible {
  outline: var(--ff-focus-ring);
  outline-offset: 2px;
}

/* Screen-reader-only utility for accessible control labels. */
.ff-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
 * Grouped lightbox
 * ------------------------------------------------------------------------ */
.ff-lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--ff-z-overlay);
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--ff-overlay-bg);
}
.ff-lightbox.is-open {
  display: flex;
}
.ff-lightbox__figure {
  margin: 0;
  max-inline-size: 90vw;
  max-block-size: 90vh;
  text-align: center;
}
.ff-lightbox__img {
  max-inline-size: 90vw;
  max-block-size: 80vh;
  block-size: auto;
  inline-size: auto;
  object-fit: contain;
}
.ff-lightbox__caption {
  color: var(--ff-control-fg);
  margin-block-start: 0.5rem;
}
.ff-lightbox__counter {
  position: absolute;
  inset-block-start: 1rem;
  inset-inline-start: 1rem;
  color: var(--ff-control-fg);
  font-variant-numeric: tabular-nums;
}
.ff-lightbox__close {
  position: absolute;
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
}
.ff-lightbox__nav {
  position: absolute;
  inset-block-start: 50%;
  transform: translateY(-50%);
}
.ff-lightbox__nav--prev {
  inset-inline-start: 1rem;
}
.ff-lightbox__nav--next {
  inset-inline-end: 1rem;
}
.ff-lightbox__close,
.ff-lightbox__nav {
  appearance: none;
  border: 0;
  cursor: pointer;
  background: var(--ff-control-bg);
  color: var(--ff-control-fg);
  font-size: 1.5rem;
  line-height: 1;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: 999px;
}
/* Mirror the chevron glyphs for RTL so "next" still points the reading-forward
 * way. Direction is driven by the document `dir`, never by hardcoded sides. */
[dir="rtl"] .ff-lightbox__nav {
  transform: translateY(-50%) scaleX(-1);
}

/* --------------------------------------------------------------------------
 * Carousel / slider
 * ------------------------------------------------------------------------ */
.ff-carousel {
  position: relative;
  overflow: hidden;
}
.ff-carousel__track {
  display: flex;
  /* translateX is sign-flipped in JS for RTL, so no directional CSS needed. */
  transition: transform var(--ff-transition);
  will-change: transform;
}
.ff-carousel__slide {
  flex: 0 0 100%;
  min-inline-size: 0;
}
.ff-carousel__nav {
  position: absolute;
  inset-block-start: 50%;
  transform: translateY(-50%);
  appearance: none;
  border: 0;
  cursor: pointer;
  background: var(--ff-control-bg);
  color: var(--ff-control-fg);
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border-radius: 999px;
}
.ff-carousel__nav--prev {
  inset-inline-start: 0.5rem;
}
.ff-carousel__nav--next {
  inset-inline-end: 0.5rem;
}
[dir="rtl"] .ff-carousel__nav {
  transform: translateY(-50%) scaleX(-1);
}
.ff-carousel__dots {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  margin-block-start: 0.75rem;
  padding: 0;
  list-style: none;
}
.ff-carousel__dot {
  appearance: none;
  border: 0;
  cursor: pointer;
  inline-size: 0.75rem;
  block-size: 0.75rem;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.4;
}
.ff-carousel__dot.is-active {
  opacity: 1;
}

/* --------------------------------------------------------------------------
 * Scroll-reveal
 * ------------------------------------------------------------------------ */
.ff-reveal {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity var(--ff-transition), transform var(--ff-transition);
}
.ff-reveal.is-revealed {
  opacity: 1;
  transform: none;
}
/* Progressive enhancement: until JS marks the document ready, and whenever JS
 * is absent, content is fully visible — never hidden behind an animation. */
html:not(.ff-js) .ff-reveal {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
 * Sticky header
 * ------------------------------------------------------------------------ */
.ff-sticky-header {
  position: sticky;
  inset-block-start: 0;
  z-index: calc(var(--ff-z-overlay) - 1);
  transition: transform var(--ff-transition), box-shadow var(--ff-transition);
}
.ff-sticky-header.is-condensed {
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
}
.ff-sticky-header.is-hidden {
  transform: translateY(-100%);
}

/* --------------------------------------------------------------------------
 * Mobile drawer
 * ------------------------------------------------------------------------ */
.ff-drawer {
  position: fixed;
  inset-block: 0;
  /* Slides in from the inline-start edge; flips automatically in RTL. */
  inset-inline-start: 0;
  z-index: var(--ff-z-overlay);
  inline-size: min(80vw, 320px);
  max-inline-size: 100%;
  background: #fff;
  transform: translateX(-100%);
  transition: transform var(--ff-transition);
  overflow-y: auto;
}
/* In RTL the panel lives on the inline-start (visual right) edge and must slide
 * out toward that edge; sign is flipped to match. */
[dir="rtl"] .ff-drawer {
  transform: translateX(100%);
}
.ff-drawer.is-open {
  transform: none;
}
.ff-drawer__backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--ff-z-overlay) - 1);
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--ff-transition), visibility var(--ff-transition);
}
.ff-drawer__backdrop.is-open {
  opacity: 1;
  visibility: visible;
}
.ff-drawer__close {
  position: absolute;
  inset-block-start: 0.75rem;
  inset-inline-end: 0.75rem;
}
/* Class-based scroll-lock: applied to <html>/<body> when a drawer or lightbox
 * is open. Uses position:fixed rather than inline overflow:hidden so it doesn't
 * cause a scrollbar-removal layout shift. */
.ff-scroll-locked,
.ff-scroll-locked body {
  overflow: hidden;
}
.ff-scroll-locked body {
  position: fixed;
  inset-inline: 0;
  inline-size: 100%;
}

/* --------------------------------------------------------------------------
 * Reduced motion — suppress all component motion, keep content visible.
 * ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .ff-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .ff-carousel__track,
  .ff-sticky-header,
  .ff-drawer,
  .ff-drawer__backdrop {
    transition: none;
  }
}
