/* FOLIO // LOUPE — v7
   The print always fits the window.

   The player used to be sized by width alone. On a short, wide window (a 1080p
   monitor once the browser's own bars are counted, or any laptop) it grew taller
   than the viewport while playing and the control capsule slid under the bottom
   edge; at other sizes the window's edge sliced the film title in half.

   Now the print's height is chosen from the room that is actually there:
     · if the title block fits under it, nothing changes;
     · if shrinking the print by up to 15 % would bring the title block into
       view, it shrinks that much;
     · otherwise it fills the window and the title starts cleanly below the fold.
   The whole right-hand column (header, print, notes, contact sheet, skin notes)
   shares the resulting width, so every edge still lines up.                   */
@media (min-width: 901px) {
  .sheet {
    container: sheet / inline-size;
    --plate-pad: clamp(8px, 1vw, 14px);
    /* viewport height left under the page header */
    --avail: calc(100vh - (clamp(22px, 4vh, 40px) + 44px + clamp(14px, 2.4vh, 24px)));
    --fill: calc(var(--avail) - 28px);     /* print + a little air */
    --fit: calc(var(--avail) - 172px);     /* print + kicker, title and tech line */
  }
  @supports (height: 100dvh) {
    .sheet { --avail: calc(100dvh - (clamp(22px, 4vh, 40px) + 44px + clamp(14px, 2.4vh, 24px))); }
  }
  .sheet > * {
    --nat: calc((100cqw - 2 * var(--plate-pad)) * 9 / 16 + 2 * var(--plate-pad));   /* height at full column width */
    --m: min(var(--nat), var(--fill));
    --x: calc(var(--m) - var(--fit));                                                 /* how much too tall for the title */
    /* shrink by x while x <= 15 % of the height; past that (a steep ramp, so no window size leaves the title half cut) do not shrink */
    --h: calc(var(--m) - max(0px, min(var(--x), (var(--m) * 0.155 - var(--x)) * 30)));
    max-width: max(520px, calc((var(--h) - 2 * var(--plate-pad)) * 16 / 9 + 2 * var(--plate-pad)));
    margin-inline: auto;
  }
}
/* phones and tablets: the header is not pinned above the print there, so only
   the print itself is capped (a phone held sideways keeps the capsule on screen) */
@media (max-width: 900px) {
  .plate { max-width: max(300px, calc((100vh - 24px - 12px) * 16 / 9 + 12px)); margin-inline: auto; }
}

/* the viewfinder only opens when there are frames to show. The contrast test
   cards have no thumbnail sheet, and an empty globe read as a black ball with
   "FRM 0000" over the white card. The time bubble still follows the pointer. */
.fl-seek[data-fl-nofinder] .fl-finder { display: none; }
.fl-seek[data-fl-nofinder] .fl-preview { inset-block-end: calc(50% + var(--fl-lz) / 2 + 6px); }

/* ===================== v7b · darkroom backlight: still, four-way, no gaps ===
   The v5 bass pulse scaled this glow ring with the music. The ring is a
   transparent box with an outset shadow, so scaling it up opened a hard black
   band between the plate and its glow that throbbed with the beat. It is now
   fixed in size and starts 3 px inside the plate's edge, so the plate always
   covers the hollow middle. Each side carries the colour of the matching edge
   of the picture (folio-v4.js sampleAmbient), eased over ~2 s. */
@property --amb-t { syntax: "<color>"; inherits: true; initial-value: rgb(255 176 108); }
@property --amb-r { syntax: "<color>"; inherits: true; initial-value: rgb(255 176 108); }
@property --amb-b { syntax: "<color>"; inherits: true; initial-value: rgb(255 176 108); }
@property --amb-l { syntax: "<color>"; inherits: true; initial-value: rgb(255 176 108); }
.plate { transition: --amb 1.2s ease, --amb-t 1.2s ease, --amb-r 1.2s ease, --amb-b 1.2s ease, --amb-l 1.2s ease; }
.plate::before { inset: 3px; scale: 1; }
:root[data-theme="dark"] .plate::before {
  animation: none;
  scale: 1;
  opacity: 0.9;
  box-shadow:
    0 -26px 70px -16px color-mix(in srgb, var(--amb-t) 52%, transparent),
    28px 0 70px -16px color-mix(in srgb, var(--amb-r) 52%, transparent),
    0 26px 70px -16px color-mix(in srgb, var(--amb-b) 52%, transparent),
    -28px 0 70px -16px color-mix(in srgb, var(--amb-l) 52%, transparent),
    0 0 34px 3px color-mix(in srgb, var(--amb) 34%, transparent),
    0 0 130px 22px color-mix(in srgb, var(--amb) 16%, transparent);
}

/* ======================== v7b · paused slip: frame number + frame link ===== */
.fl-badge__frm { font-family: "IBM Plex Mono", ui-monospace, monospace; font-weight: 500; letter-spacing: 0.04em; }
.fl-badge__frm:not(:empty)::before { content: " · "; font-family: var(--fl-sans, inherit); }
.fl-badge__link {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 3px 0 0 -4px;
  padding: 3px 6px 3px 4px;
  border: 0;
  border-radius: 6px;
  background: none;
  font: 500 11.5px/1.1 "IBM Plex Mono", ui-monospace, monospace;
  letter-spacing: 0.03em;
  color: var(--fl-ink-soft);
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.fl-badge__link svg { inline-size: 13px; block-size: 13px; flex: none; }
.fl-badge__link[data-done] { color: var(--fl-accent-ink); }
@media (hover: hover) { .fl-badge__link:hover { background: rgb(90 66 44 / 0.08); color: var(--fl-ink); } }
/* only the open slip takes the pointer; the rest of the badge stays click-through */
.fl-skin:not([data-fl-fresh]):has(.fl-btn--play[data-paused]) .fl-badge__link { pointer-events: auto; }
@container fl-player (max-width: 560px) { .fl-badge__link { display: none; } }

/* visually hidden live text for frame steps */
.fl-frame-live { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* v8 · before the first play, the cover seal steps aside while the ruler is in
   use: scrubbing for a frame should not happen behind a 200 px medallion. It
   returns as soon as the pointer leaves the ruler. */
.fl-skin[data-fl-fresh]:has(.fl-seek:is([data-pointing], [data-dragging])) .fl-seal { opacity: 0; transition: opacity 0.25s ease; }
