/* 11-project-detail-media.css — work/*.html pages: the cover, stacked screens,
   the photo gallery (.project-media), and the browser-window chrome and Vimeo
   embed that JS wraps around web covers and the .project-screens screenshot
   galleries (the chrome: initBrowserFrames in js/site/project-page.js; the
   embed's playback: js/vimeo-covers.js). */

/* PROJECT DETAIL — image at natural ratio, info below */
.project-detail { margin-top: var(--header-h); }
.project-cover {
  width: 100%;
  background: var(--bg-raised);
  overflow: hidden;
  display: flex;
  justify-content: center;
}
.project-cover[data-frame="browser"] {
  background: transparent;            /* no black field — the window floats on the page bg */
  overflow: visible;                 /* let the window's drop-shadow breathe */
  padding: var(--section-space) var(--sp-6);
}
.project-cover img,
.project-cover video {
  width: auto;
  max-width: 100%;
  max-height: 90vh;
  height: auto;
  object-fit: contain;
  display: block;
}

/* stacked frame gallery — browser-framed web mockups */
.project-screens {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--section-space);
  padding: var(--section-space) var(--gutter);
  background: #000;
}
.project-screens img,
.project-screens video {
  width: auto;
  max-width: 100%;
  max-height: 88vh;
  height: auto;
  object-fit: contain;
  display: block;
}

/* full case-study galleries — real photos extracted from the source PDFs.
   Two columns, not a width-driven count: `column-width: 20rem` resolved to
   THREE columns on a desktop window, which left every photo about 390px wide.
   That is too small to read a poster, a label or a spread in — and a set of
   three landed as three thumbnails in a row. Two columns give each image
   ~590px and a set of three reads as a hero over a pair.
   Still CSS columns rather than a grid: the images in a set have different
   heights, and columns flow around that instead of leaving a hole under the
   shorter one in each row.
   No background of its own — it used to sit on --bg-raised, which put a band of
   a second colour behind whichever projects happened to have photos. */
.project-media {
  column-count: 2;
  column-gap: var(--grid-gap);
  padding: var(--section-space) var(--gutter);
}
.project-media img,
.project-media video {
  width: 100%;
  height: auto;
  display: block;
  margin: 0 0 var(--grid-gap);
  break-inside: avoid;
  border-radius: 2px;
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.45);
}
/* A gallery video (motion poster, screen recording) takes its box from the
   generator's --r before its poster or first frame arrives; preload="none"
   would otherwise leave it at the UA default 300×150 until then. cover absorbs
   the odd pixel of difference between an Instagram cover and its clip. */
.project-media video {
  aspect-ratio: var(--r, 1);
  object-fit: cover;
  background: var(--bg-raised);
}
/* Lead image as the page's hero. Which image earns this is decided in
   scripts/templates/detail-page.js, where the file's real dimensions are known: it has
   to be landscape or square, and the set has to be three or more. The old rule
   here counted siblings instead, so a portrait lead became a 1600px wall. */
.project-media .project-media-lead {
  column-span: all;
  margin-bottom: var(--grid-gap);
}
/* A single-item project: span both columns so the row is not half empty, but
   cap the height — most of these are portrait, and full width would make one
   picture taller than the screen. The width is solved from the height cap and
   the item's own ratio (--r, w/h, from the generator), which works the same for
   a video whose intrinsic size is unknown until it loads. */
.project-media .project-media-solo {
  column-span: all;
  width: min(100%, calc(78svh * var(--r, 1)));
  margin-inline: auto;
}
/* Phones: one column. Two columns of 160px would be worse than the three-wide
   desktop layout this replaces. */
@media (max-width: 700px) {
  .project-media { column-count: 1; }
}

/* browser chrome wrapper (injected by JS) */
.browser-wrap {
  display: inline-flex;   /* shrinks to image's natural width */
  flex-direction: column;
  max-width: 100%;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--rule);
  box-shadow: 0 24px 64px rgba(0,0,0,0.55);
}
/* Cap the WINDOW width by the viewport-height budget (bar is 36px tall) using
   the media's aspect ratio (--ar = w/h, set by JS). This is what kills the
   black pillarbox: if we instead clamp the image's max-height, a tall shot
   shrinks its own width while the inline-flex wrap stays at the image's
   intrinsic width — so the chrome bar ends up wider than the image. Capping
   the wrap width means the image always fills it and the bar matches. */
.browser-wrap:not(.browser-wrap--embed) {
  max-width: min(100%, calc((88vh - 36px) * var(--ar, 1.6)));
}
.browser-wrap img,
.browser-wrap video {
  width: auto;
  max-width: 100%;
  max-height: none;   /* the wrap's max-width now enforces the height budget */
  height: auto;
  display: block;
  flex-shrink: 0;
}
/* Vimeo cover embed: fills a capped width instead of shrink-wrapping to an
   intrinsic media size, holding each clip's aspect ratio via the --r variable. */
.browser-wrap--embed {
  display: flex;
  width: min(100%, 1340px);   /* fill the width on laptops so the window isn't boxed in black */
}
.vimeo-embed {
  position: relative;
  width: 100%;
  background: #000;
  overflow: hidden;      /* clips the pillarbox crop below */
}
.vimeo-embed::before {
  content: '';
  display: block;
  padding-top: calc(var(--r, .5625) * 100%);
}
/* --r is the ratio of the CONTENT; --vr, when present, is the ratio of the
   uploaded FILE. Two clips were exported into a 16:9 canvas with the recording
   pillarboxed inside, so widening the iframe by --r/--vr pushes those baked-in
   black bars past the frame edges to be clipped, while the iframe box itself
   keeps the file's own ratio — at an exact ratio match the player's own fit is
   a no-op, so it neither letterboxes nor crops on top of us.
   No --vr means file ratio = content ratio and the factor collapses to 1. */
.vimeo-embed iframe {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% * var(--r, .5625) / var(--vr, var(--r, .5625)));
  height: 100%;
  border: 0;
  display: block;
}
.browser-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  height: 36px;
  padding: 0 var(--item-space);
  background: #1A1A18;
  border-bottom: 1px solid var(--rule);
  flex-shrink: 0;
}
.browser-bar-dot {
  width: 11px; height: 11px;
  border-radius: 50%;
  flex-shrink: 0;
}
.browser-bar-dot--red { background: #FF5F57; }
.browser-bar-dot--yellow   { background: #FEBC2E; }
.browser-bar-dot--green   { background: #28C840; }
.browser-bar-url {
  flex: 1;
  display: flex;
  justify-content: center;
}
.browser-bar-url span {
  font-family: var(--sans);
  font-size: var(--text-label);
  letter-spacing: 0.04em;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: var(--sp-half) var(--sp-3);
  max-width: 260px;
  width: 100%;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
