/* Listing documents. Same rule as the gallery: no opinion about colour, it
   inherits the theme. Only layout, sizing and the things that affect CLS. */

.ss-docs {
  --ss-docs-radius: 4px;
  --ss-docs-gap: 0.75rem;
  --ss-docs-min: 190px;          /* narrowest a grid card may get */

  /* EVERY neutral is mixed from currentColor, and none of them switch on
     prefers-color-scheme.

     That media query was actively wrong here. It asks what the operating
     system prefers; what matters is what the THEME actually painted. A visitor
     with dark mode on, reading a light listing template, got white-on-white
     borders and an invisible card — the component was picking its colours off
     a signal that had nothing to do with the page it was sitting on.
     currentColor is the page's own text colour, so these track the surface
     they are drawn on and are right on either theme with no query at all.

     Each is declared twice: an rgba value tuned for a light theme, then the
     color-mix that supersedes it. A browser without color-mix (pre-Chrome 111,
     Safari 16.2, Firefox 113) ignores the second line and keeps a working
     light-theme component. */
  --ss-docs-ink: currentColor;

  --ss-docs-line: rgba(0, 0, 0, 0.14);
  --ss-docs-line: color-mix(in srgb, currentColor 16%, transparent);

  --ss-docs-wash: rgba(0, 0, 0, 0.035);
  --ss-docs-wash: color-mix(in srgb, currentColor 5%, transparent);

  /* Heavier than --ss-docs-line, which is only a divider. This one has to
     define a card edge against the page from a normal viewing distance, and a
     14%-alpha hairline simply does not. */
  --ss-docs-card-line: rgba(0, 0, 0, 0.18);
  --ss-docs-card-line: color-mix(in srgb, currentColor 22%, transparent);

  /* The mat behind a page — TRANSPARENT, so the card's own surface shows
     through and a contained image has nothing visible around it.

     This was a toned grey, to give the card a visible extent when a landscape
     floor plan left space above and below it. The border does that job now,
     and the grey was doing a second thing nobody asked for: drawing a box
     around the empty part of every landscape document, so a floor plan read as
     a small picture inside a frame rather than as the page it is. The border
     alone keeps the equal heights legible without framing the whitespace. */
  --ss-docs-paper: transparent;

  /* PORTRAIT, and that is the point. These are pages: a letter-size scan is
     0.77 and a PDF page-one preview is always one. A landscape window would
     letterbox every document in the set, where a portrait one fits them almost
     exactly and letterboxes only the floor plans — the items least hurt by it,
     since a floor plan stays readable wide and short. Cards are all this shape
     whatever is inside them, which is what makes the row line up. */
  --ss-docs-ratio: 3 / 4;

  /* The caption band. Solid and dark on both themes by design: it sits under a
     white page scan, and a band that inherits the surface reads as part of the
     document rather than a label for it. Override both to theme it. */
  --ss-docs-caption-bg: #2f2f2f;
  --ss-docs-caption-ink: #fff;
  /* Sized to the type, not to two lines of it. The band was 46px to allow a
     wrapped label; a single line with an ellipsis is what the rest of the site
     does and it gives the document back the vertical space. The full name
     stays in the DOM, so a screen reader still reads a truncated one in full. */
  --ss-docs-caption-h: 34px;

  display: flex;
  flex-direction: column;
  gap: var(--ss-docs-gap);
}

.ss-docs__heading {
  margin: 0;
}

/* ---------- shared tile internals -------------------------------------- */

.ss-docs__link {
  display: flex;
  color: inherit;
  text-decoration: none;
  border: 1px solid var(--ss-docs-line);
  border-radius: var(--ss-docs-radius);
  overflow: hidden;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.ss-docs__link:hover,
.ss-docs__link:focus-visible {
  border-color: var(--ss-docs-ink);
  background: var(--ss-docs-wash);
}

.ss-docs :focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* A floor plan is worth examining; a PDF is worth opening. The cursor is the
   only place that difference shows before the click. */
.ss-docs__link--zoom { cursor: zoom-in; }

.ss-docs__preview {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  overflow: hidden;
  background: var(--ss-docs-paper);
}

/* contain, NOT cover — and this is the one place documents genuinely need
   different treatment from photos.

   A PDF page-one preview is portrait (8.5x11 -> 0.77) and a floor plan is
   landscape (often 1.6 or wider). Those sit in the same grid. cover would crop
   a floor plan to a letterbox strip of its middle and cut the title block off
   the top of every PDF — the two parts that identify what the file actually
   is. Letterboxing wastes a little space and shows the whole page. */
/* Absolutely positioned, NOT max-height: 100%.

   The preview box gets its height from aspect-ratio, and a percentage
   max-height does not resolve against a height derived that way — so a
   portrait PDF page ignored the cap, overflowed the box and stretched its card
   taller than the landscape floor plan beside it. Every card in a row was a
   different height. Absolute inset works because the box is a resolved
   containing block whatever produced its height. */
.ss-docs__preview img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  /* contain, never cover. A floor plan cropped to fill a portrait box loses
     half its width — rooms and dimensions, the entire reason the document is
     on the page. Letterboxing is the right trade here, and with a transparent
     mat there is nothing to see in the leftover space anyway. */
  object-fit: contain;
  /* Top, not centre: a landscape plan then starts at the card's top edge and
     all of its slack collects at the bottom, instead of being split into two
     gaps that make the image look like it is floating in the middle. Portrait
     pages are within a few percent of the box ratio, so this moves them
     barely at all. */
  object-position: top;
}

.ss-docs__icon {
  width: 34px;
  height: 34px;
  opacity: 0.45;
}

.ss-docs__text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;   /* lets the label ellipsis instead of stretching the card */
}

.ss-docs__label {
  font-weight: 600;
  line-height: 1.3;
}

/* ---------- carousel layout (default) -----------------------------------
   One horizontal strip you flick through. Built on native overflow scrolling
   with scroll-snap rather than a carousel library:

     - swiping IS the browser's own touch scrolling, with real momentum and
       rubber-banding, which no JS carousel matches on a phone;
     - it works before any script runs and if every script fails, so the
       documents are never trapped behind a library that did not load;
     - it needs nothing from the gallery plugin's vendor folder, unlike the
       floor-plan lightbox, which degrades to a new tab when that is absent.

   The arrow buttons are an enhancement on top — they nudge the same scroll
   container — and stay hidden until the script confirms there is overflow.
   The one thing this gives up against Splide is click-and-drag with a mouse;
   desktop gets the arrows and trackpad scrolling instead.
   ---------------------------------------------------------------------- */

.ss-docs--carousel {
  /* Sized against the column, not the window: the listing template puts this
     in a narrow-ish column inside a much wider page, so a viewport media query
     would read a number that has nothing to do with the space the strip has.
     Same reasoning as the gallery mosaic. */
  container-type: inline-size;

  /* FIXED HEIGHT, AUTO WIDTH — the opposite of the grid, and the whole point.

     Every card is exactly this tall and as wide as its image is at that
     height. A letter-size page comes out narrow, a wide floor plan comes out
     wide, and both fill the card top to bottom with nothing cropped and
     nothing boxed. A fixed-width card cannot do that for a mixed set: it has
     to either letterbox the shape that does not match or crop it, and a
     floor plan is the one document where cropping destroys the content.

     38cqw of the column is what the Kadence gallery this replaces measures
     at; the clamp keeps a phone from getting a 140px strip and an ultrawide
     from getting a 700px one. */
  --ss-docs-h: clamp(300px, 38cqw, 500px);
  --ss-docs-preview-h: calc(var(--ss-docs-h) - var(--ss-docs-caption-h) - 2px);
}

.ss-docs__strip {
  position: relative;

  /* Contain the track's overflow. Without this the strip's scrollable content
     escapes into the DOCUMENT's scroll area: the listing page ends up ~1500px
     wider than the viewport on a phone (~1900px at 1280px), all of it blank.
     The cards still paint clipped, so it reads as a stray horizontal scroll
     with nothing in it — and on touch it steals the swipe, because the page
     can satisfy a horizontal drag and moves instead of the strip.

     `clip`, not `hidden`: hidden would make the strip its own scroll
     container, and the track's overflow-y:hidden already keeps it flat.
     `overflow-clip-margin` gives back the 3px the track bleeds through its
     negative margin, so the focus ring on the first and last card survives.
     An engine without `clip` drops both declarations and is no worse off. */
  overflow-x: clip;
  overflow-clip-margin: 3px;
}

.ss-docs--carousel .ss-docs__items {
  display: flex;
  gap: var(--ss-docs-gap);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  /* proximity, not mandatory: mandatory fights a fast flick, yanking the strip
     back to the nearest card mid-gesture. proximity snaps when the scroll ends
     near a card and leaves a deliberate long swipe alone. */
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;   /* don't trigger the browser's back gesture */
  /* Room for the focus ring, which sits 2px outside the card and would
     otherwise be clipped by the scroll container on the top and bottom edges. */
  padding: 3px;
  margin: -3px;
  /* Hidden because the dots below say the same thing better. Two position
     indicators on one strip is one too many, and a raw scrollbar under a row
     of cards reads as a page scrollbar that escaped its container.

     Hiding it costs nothing: the strip still scrolls by wheel, trackpad,
     touch, keyboard and the arrow tabs — only the painted bar goes. */
  scrollbar-width: none;
}

.ss-docs--carousel .ss-docs__items::-webkit-scrollbar {
  display: none;
}

/* ---------- carousel dots ----------------------------------------------- */

.ss-docs__dots {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.ss-docs__dot {
  width: 9px;
  height: 9px;
  padding: 0;
  /* Not --ss-docs-line: at 0.14 alpha the inactive dots vanish on a white page
     and the control reads as a single stray dot rather than a position out of
     three. A border colour and a UI control want different weights. */
  background: currentColor;
  opacity: 0.25;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.ss-docs__dot:hover { opacity: 0.5; }
.ss-docs__dot[aria-current="true"] { opacity: 1; }

/* The dot itself is a 9px target, which is far under the 24px minimum. Grow
   the hit area with a transparent pseudo-element rather than the dot, so it
   stays a dot and still takes a fingertip. */
.ss-docs__dot { position: relative; }
.ss-docs__dot::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 26px;
  height: 26px;
  transform: translate(-50%, -50%);
}

.ss-docs--carousel .ss-docs__link {
  flex: 0 0 auto;            /* width from the image, never stretched or shrunk */
  max-width: 100%;           /* a plan wider than a phone is contained, not cut */
  height: var(--ss-docs-h);
  box-sizing: border-box;    /* the border is inside the height, so the row is exact */
  flex-direction: column;
  scroll-snap-align: start;
}

.ss-docs--carousel .ss-docs__preview {
  flex: none;
  height: var(--ss-docs-preview-h);
  width: auto;
  max-width: 100%;
  aspect-ratio: auto;
}

/* Explicit height, not 100% of the preview: the card's width is derived FROM
   this image's width, and that has to be computable during intrinsic sizing —
   a percentage height resolving against a box whose width depends on this
   image is a loop the browser breaks by giving up. A definite height and the
   width/height attributes on the tag are enough for it to lay every card out
   at its final width before a single preview has loaded. */
.ss-docs--carousel .ss-docs__preview img {
  position: static;
  inset: auto;
  height: var(--ss-docs-preview-h);
  width: auto;
  max-width: 100%;
  object-fit: contain;       /* only ever bites when max-width caps the card */
  object-position: center;
}

/* No image to take a width from, so give it the shape of a page. */
.ss-docs--carousel .ss-docs__preview--icon {
  width: calc(var(--ss-docs-preview-h) * 0.75);
}

/* The caption must not set the card's width. With nowrap text, a long name's
   max-content width would win over a narrow portrait page and widen the card
   past its image. width: 0 removes it from intrinsic sizing; min-width: 100%
   then stretches it back to whatever width the image decided. */
.ss-docs--carousel .ss-docs__text {
  width: 0;
  min-width: 100%;
  box-sizing: border-box;
}

/* Grid: a fixed-shape page window, so the row lines up. The band has a fixed
   height for the same reason: a long title must not make one card taller. */
.ss-docs--grid .ss-docs__preview {
  aspect-ratio: var(--ss-docs-ratio);
  width: 100%;
}

.ss-docs--carousel .ss-docs__text,
.ss-docs--grid .ss-docs__text {
  height: var(--ss-docs-caption-h);
  padding: 0 0.75rem;
  text-align: center;
  color: var(--ss-docs-caption-ink);
  background: var(--ss-docs-caption-bg);
}

.ss-docs--carousel .ss-docs__label,
.ss-docs--grid .ss-docs__label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.875rem;
  line-height: 1.25;
}

/* The card keeps a visible edge. In the grid a letterboxed page would
   otherwise have no extent against a white page; in the carousel it is what
   separates two white documents sitting side by side. */
.ss-docs--carousel .ss-docs__link,
.ss-docs--grid .ss-docs__link {
  border: 1px solid var(--ss-docs-card-line);
}

/* The band is opaque and covers the lower part of the card, so tinting the
   card background — which is what the shared hover does — is invisible here.
   Move the hover onto the two things a visitor can actually see. */
.ss-docs--carousel .ss-docs__link:hover,
.ss-docs--carousel .ss-docs__link:focus-visible,
.ss-docs--grid .ss-docs__link:hover,
.ss-docs--grid .ss-docs__link:focus-visible {
  background: transparent;
  border-color: var(--ss-docs-caption-bg);
}

.ss-docs--carousel .ss-docs__link:hover .ss-docs__text,
.ss-docs--grid .ss-docs__link:hover .ss-docs__text {
  filter: brightness(1.45);
}

/* ---------- carousel arrows --------------------------------------------- */

.ss-docs__nav {
  position: absolute;
  /* Centred on the page window, not on the card: half the caption band is
     subtracted so the tab sits against the document rather than straddling the
     label at the bottom of it. */
  top: calc(50% - var(--ss-docs-caption-h) / 2);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 84px;
  padding: 0;
  color: #fff;
  background: rgba(45, 45, 45, 0.55);
  border: 0;
  border-radius: 2px;
  cursor: pointer;
  transform: translateY(-50%);
  transition: background 0.15s ease;
}

.ss-docs__nav:hover { background: rgba(30, 30, 30, 0.8); }
.ss-docs__nav svg { width: 22px; height: 22px; }
.ss-docs__nav--prev { left: 0; }
.ss-docs__nav--next { right: 0; }

/* Greyed rather than removed at the ends: a tab that disappears makes the
   strip's edge jump, and the button reappearing under the cursor on the way
   back is worse than one that is simply inert. */
.ss-docs__nav:disabled {
  opacity: 0.3;
  cursor: default;
}

/* Touch devices scroll the strip directly and the arrows would just sit on top
   of the first and last card. Hover is the closest available proxy for "has a
   pointer that can reach a 34px target comfortably". */
@media (hover: none) {
  .ss-docs__nav { display: none; }
}

/* ---------- grid layout ------------------------------------------------- */

.ss-docs--grid .ss-docs__items {
  display: grid;
  /* auto-fill, not auto-fit: a listing with two documents should show two
     cards at card width, not two cards stretched across the whole column. */
  grid-template-columns: repeat(auto-fill, minmax(var(--ss-docs-min), 1fr));
  gap: var(--ss-docs-gap);
}

.ss-docs--grid .ss-docs__link {
  flex-direction: column;
}

/* The window and the band are defined once, with the carousel's — see above.
   A fixed window is what keeps a row of cards the same height whatever shape
   the pages inside them are, and it is known before any preview arrives, so a
   grid of seven documents reserves its space and never shifts. */

/* ---------- list layout ------------------------------------------------- */

.ss-docs--list .ss-docs__items {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.ss-docs--list .ss-docs__link {
  flex-direction: row;
  align-items: center;
  gap: 0.85rem;
  padding: 0.6rem 0.85rem 0.6rem 0.6rem;
}

.ss-docs--list .ss-docs__preview {
  width: 52px;
  height: 52px;
  border-radius: 4px;
  overflow: hidden;
}

.ss-docs--list .ss-docs__icon {
  width: 24px;
  height: 24px;
}

.ss-docs--list .ss-docs__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- private note ------------------------------------------------ */

.ss-docs__private {
  margin: 0;
  font-size: 0.85rem;
  opacity: 0.7;
}

/* ---------- accessibility ----------------------------------------------- */

/* The theme usually defines this; documents must not depend on it doing so,
   or the "(opens in a new tab)" hint becomes visible body text on every row. */
.ss-docs .screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .ss-docs__link { transition: none; }

  /* The arrows and dots deliberately pass no `behavior` to scrollBy/scrollTo,
     which makes them defer to this property — so turning it off here turns off
     the animation for the buttons as well as for native scrolling, and the JS
     needs to know nothing about the preference. */
  .ss-docs--carousel .ss-docs__items { scroll-behavior: auto; }
}

/* PhotoSwipe is borrowed from the gallery plugin and defaults to z-index
   100000, the same as a sticky header stack. The gallery raises it for its own
   viewer; set it here too so a document list works on a page with no gallery
   on it. */
.pswp {
  --pswp-root-z-index: 100010;
}
