/* ============================================================
   media.css — shared image-frame architecture
   path: /lib/media.css
   purpose: One sizing contract for every image in every design
            direction. A .media element owns the box; whatever
            sits inside it fills that box exactly. Nothing
            stretches, nothing escapes, nothing overlaps.
   ============================================================ */

:root{
  /* the only aspect ratios any direction is allowed to use */
  --ar-portrait:  3 / 4;   /* gallery frames, digitals, portraits */
  --ar-editorial: 4 / 5;   /* hero plates, triptych panels       */
  --ar-square:    1 / 1;
  --ar-landscape: 3 / 2;   /* full-bleed bands                   */
  --ar-cinema:   21 / 9;

  /* neutral fill behind a frame while its image decodes */
  --media-bg: #0b0c10;
}

/* ------------------------------------------------------------
   The frame. Height is derived from width and the ratio, so a
   frame can never be taller than its column allows and can never
   push a grid track wider than the track was given.
   ------------------------------------------------------------ */
.media{
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: var(--ar, 3 / 4);
  background: var(--media-bg);
  min-width: 0;          /* survives inside flex and grid tracks */
  max-width: 100%;
  isolation: isolate;    /* keeps hover glows off neighbouring frames */
}

/* ------------------------------------------------------------
   The content. Doubled class raises specificity just past the
   per-direction rules (.shot .ph, .neg .ph, .tript .ph) so this
   file wins on geometry while those keep owning filters,
   transitions and colour.
   ------------------------------------------------------------ */
.media.media > img,
.media.media > canvas,
.media.media > svg,
.media.media > video{
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
}

/* An image still waiting on a src paints as an empty plate rather
   than collapsing to zero and pulling the layout in with it. */
.media.media > img:not([src]){ opacity: 0; }

/* ------------------------------------------------------------
   Ratio helpers — set on the frame, not the image.
   ------------------------------------------------------------ */
.media--portrait { --ar: var(--ar-portrait); }
.media--editorial{ --ar: var(--ar-editorial); }
.media--square   { --ar: var(--ar-square); }
.media--landscape{ --ar: var(--ar-landscape); }
.media--cinema   { --ar: var(--ar-cinema); }

/* ------------------------------------------------------------
   Horizontal film strips (digitals, contact sheets). The track
   scrolls; it never widens the page.
   ------------------------------------------------------------ */
.railstrip{
  display: flex;
  align-items: flex-start;
  gap: var(--railstrip-gap, .5rem);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  min-width: 0;
  max-width: 100%;
  padding-bottom: .5rem;
}
.railstrip > *{
  flex: none;
  width: var(--railstrip-item, clamp(140px, 20vw, 200px));
  min-width: 0;
  margin: 0;
  scroll-snap-align: start;
}
.railstrip::-webkit-scrollbar{ height: 3px; }
.railstrip::-webkit-scrollbar-track{ background: transparent; }
.railstrip::-webkit-scrollbar-thumb{ background: currentColor; opacity:.25; border-radius: 99px; }

/* ------------------------------------------------------------
   Anchor targets clear the fixed header instead of hiding under
   it. Each direction sets --anchor-offset to its own bar height.
   ------------------------------------------------------------ */
:where([id]){ scroll-margin-top: var(--anchor-offset, 5.5rem); }

/* ------------------------------------------------------------
   Page-level containment. Long marquee tracks and full-bleed
   bands are clipped at the document edge instead of creating a
   horizontal scrollbar on phones.
   ------------------------------------------------------------ */
html, body{ overflow-x: clip; }
@supports not (overflow-x: clip){ html, body{ overflow-x: hidden; } }

/* Any grid or flex child can shrink below its content width. */
.media, .railstrip, .railstrip > *{ min-width: 0; }
