/* Chroma Noir — Studio, reels 1.37.0 (2026-11-04)
   ---------------------------------------------------------------------------
   ONLY WHAT IS GENUINELY NEW. studio.css is loaded whole before this file and
   carries every token, every button, the cards, the sheets and the dialogs; a
   reel card IS a film card. What is added here is the portrait still, the
   share row that appears under one, the preview and the accounts form.

   No new colour and no new type size. Gold is already spent on "live" and on
   the thing the pointer is on, so nothing below introduces a second accent.

   CHROME 79 IS NOT A TARGET FOR THIS PAGE — the Studios are never served to
   the wall television — but the rules here are written as if it were, because
   the two public stylesheets are read alongside these and a habit copied out
   of a Studio is a habit that breaks over there. So: no `inset` shorthand, no
   flex `gap` (grid `gap` is fine, Chrome 66), no `:has()`, no nesting, no
   `dvh`, and `aspect-ratio` only behind @supports with a plain height first.
   `:focus-visible` is never in a selector list with a rule that must work —
   an engine that does not know the pseudo-class throws away the whole list.
*/

/* ---- a reel is tall ------------------------------------------------------- */

/* studio.css lays a card out as FOUR columns — grip, still, body, actions —
   and sizes the still 176px wide at 16:9. A reel is 9:16, so the same width
   would be a 313px tower next to a two-line title. The still gets narrower
   instead and the column follows it.

   RESTATED AT EVERY BREAKPOINT, which looks redundant and is not: studio.css
   redefines both the row and the still at 1100, 900 and 560, and this file is
   read AFTER it, so one base rule would win on source order and leave a reel
   card with the same still at every width. The photographs Studio carries the
   identical note for the identical reason. */
.film__row { grid-template-columns: auto 92px minmax(0, 1fr) auto; }
.film__thumb { width: 92px; height: 164px; }

@media (min-width: 1100px) {
  .film__row { grid-template-columns: auto 80px minmax(0, 1fr); }
  .film__thumb { width: 80px; height: 142px; }
}

@media (max-width: 900px) {
  .film__row { grid-template-columns: auto 80px minmax(0, 1fr); }
  .film__thumb { width: 80px; height: 142px; }
}

@media (max-width: 560px) {
  /* The grip column is gone at this width — studio.css removes it — so the
     row is two columns here and not three. */
  .film__row { grid-template-columns: 72px minmax(0, 1fr); }
  .film__thumb { width: 72px; height: 128px; }
}

/* A reel with no poster. ffmpeg's frame grab is allowed to fail without
   failing the upload, so this is a real state and not a placeholder for one. */
.film__thumb .none {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 0 4px;
  text-align: center;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

/* The still is the preview button, so it says so. */
.film__thumb--play { cursor: pointer; border: 0; padding: 0; }
.film__thumb--play:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---- the upload row's still ----------------------------------------------- */

/* .job__still is a 16:9 box in studio.css. A reel's is the same height and a
   third of the width, so a queue of uploads reads as reels at a glance. The
   grid column it sits in has to shrink with it or the name starts 84px in. */
.rjob { grid-template-columns: 34px 1fr auto; }
.rjob .job__still { width: 34px; height: 60px; }

@media (max-width: 900px) {
  .rjob { grid-template-columns: 34px 1fr; }
}

/* ---- what a reel actually is ---------------------------------------------- */

/* Dimensions, length, weight. .film__meta already carries the state dot and
   the date; this is the second line, and it is tabular so a column of reels
   lines up. */
.rfacts {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  font-size: 12px;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

/* No flex gap — see the header. Margins instead, so the row survives an older
   engine with its spacing intact rather than collapsing into one word. */
.rfacts > * { margin: 0 14px 0 0; }
.rfacts > *:last-child { margin-right: 0; }
.rfacts b { font-weight: 500; color: var(--dim); }

/* ---- the gate, on the card ------------------------------------------------- */

/* .film__vis is inline-flex, which is the right shape — but .film__body is a
   flex COLUMN, and a column stretches its children, so the three-segment pill
   came out the full width of the card with the segments packed at one end. On
   a film card the control sits in the actions column and never meets that
   rule; here it is in the body, so it has to opt out of the stretch.
   Not applied under 560px: studio.css deliberately gives the control the full
   width there, because Private/Gated/Live is the question the card exists to
   answer and a 70px segment is not a target. */
.film__body > .film__vis { align-self: flex-start; }

@media (max-width: 560px) {
  .film__body > .film__vis { align-self: stretch; }
}

/* ---- the share row --------------------------------------------------------- */

/* Appears under the body when a link has just been minted, and only then. It
   is deliberately not drawn from stored state: the service records nothing
   that says "this reel has a link out", only a revoke counter, so a row drawn
   on page load would be the page claiming to know something it does not. */
.rshare {
  margin: 10px 0 0;
  padding: 12px 14px;
  border-left: 2px solid var(--gold);
  background: var(--surface);
}

.rshare__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin: 0 0 8px;
}

.rshare__row > * { margin: 0 8px 6px 0; }
.rshare__row > *:last-child { margin-right: 0; }

/* Wide enough to show the whole token on a desktop; readonly, because the
   link is minted by the server and typing into it would be editing a thing
   that is not editable. */
.rshare__url {
  flex: 1 1 320px;
  min-width: 0;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.rshare__exp { margin: 0 0 6px; font-size: 12px; color: var(--dim); }

/* THE HONEST SENTENCE. Facebook takes a link; Instagram and TikTok have no
   share-by-URL at all and no button on this page pretends otherwise. */
.rshare__note { margin: 0; font-size: 12px; line-height: 1.55; color: var(--faint); }

/* ---- the preview ----------------------------------------------------------- */

/* Narrow, because the thing inside it is 9:16. A full-width sheet around a
   portrait video is two black fields with a stripe of film between them. */
.sheet__box--reel { width: min(460px, 100%); }

.rplay {
  display: block;
  width: 100%;
  max-width: 340px;
  margin: 10px auto 0;
  /* 9:16 of 340px, and the @supports block at the foot of this file says the
     same thing as a ratio so the box keeps its shape at any width. The element
     is a <video>, whose default object-fit is `contain`, so a reel that is not
     9:16 — a 4:5, now that the gate takes one — is shown WHOLE with the box's
     own black beside or under it, never cropped. */
  height: 604px;
  max-height: 70vh;
  background: #000;
  box-shadow: inset 0 0 0 1px var(--rule);
}

.rplay__note {
  margin: 14px 0 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--faint);
  text-align: center;
}

/* ---- the accounts form ------------------------------------------------------ */

.acc__why { margin: 14px 0 20px; font-size: 13px; line-height: 1.6; color: var(--dim); }
.acc__why b { font-weight: 500; color: var(--ink); }

.acc__f { margin: 0 0 18px; }
.acc__f .label { display: block; margin: 0 0 6px; }

/* What the server made of what is stored, or nothing at all. An unset account
   says nothing rather than "not configured" — empty is the shipped state and
   is not a warning. */
.acc__now { margin: 6px 0 0; font-size: 12px; line-height: 1.5; color: var(--faint); }
.acc__now:empty { display: none; }
.acc__now.bad { color: var(--gold); }
.acc__now a { color: var(--dim); text-decoration: underline; text-underline-offset: 3px; }
.acc__now a:hover { color: var(--ink); }

.acc__hint { margin: 0 0 18px; font-size: 12px; line-height: 1.55; color: var(--faint); }

.acc__acts { display: flex; flex-wrap: wrap; align-items: center; }
.acc__acts > * { margin: 0 12px 0 0; }
.acc__acts > *:last-child { margin-right: 0; }

.acc__msg { font-size: 12px; color: var(--dim); }
.acc__msg.bad { color: var(--gold); }

/* ---- a finger ---------------------------------------------------------------
   studio.css carries the whole of this pass — 44px targets and the 16px input
   floor on every shared control. What is left is the two fields it cannot
   reach, because they are declared in THIS file and are read after it. */

@media (pointer: coarse) {
  .rshare__url { font-size: 16px; min-height: 44px; }
}

/* ---- a reel that is wider than 9:16 -----------------------------------------
   studio.css fills .film__thumb with object-fit:cover, which is what a reel
   TALLER than the column wants: cropped top and bottom reads correctly. A 4:5
   or 2:3 reel — which the upload gate now accepts — loses a third of its width
   to the same rule, so the row builder adds this class and the still is shown
   whole against the thumb's own black. The public wall does the same thing in
   .tile__still--fit. */
.film__thumb--fit img { object-fit: contain; }

/* ---- ticking one reel -------------------------------------------------------
   The count and the two quiet buttons that go with it live in the toolbar; the
   tick itself sits in the corner of the still. */

.tools__picked { font-size: 12px; color: var(--ink); font-variant-numeric: tabular-nums; }

/* THE STILL'S CELL, WRAPPED. Not a fifth grid column: .film__row's template is
   declared four times in this file and four more in studio.css, and a new
   column would have to be added to all eight of them. */
.film__pickcell { position: relative; }

.pick {
  position: absolute;
  top: 0; left: 0;
  /* A hit area bigger than the square it draws. 18px is the right size for the
     mark and the wrong size for a target. */
  width: 32px; height: 32px;
  display: grid;
  place-items: center;
  cursor: pointer;
  /* Over the still, which is a button with a position of its own. */
  z-index: 2;
}

/* THE REAL CHECKBOX IS THE CONTROL and is only visually hidden (.sr), so the
   keyboard and a screen reader get a checkbox rather than a styled div. This
   square is the picture of it: `:checked + .pick__b` is the whole mechanism,
   because accent-color is Chrome 93 and this house builds to 79.

   The dark fill is not decoration — the mark sits on a photograph, and an
   unfilled box disappears into a bright frame. */
.pick__b {
  width: 18px; height: 18px;
  border: 1px solid var(--rule2);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.62);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
}
.pick:hover .pick__b { border-color: var(--ink); }
.pick__i:checked + .pick__b {
  border-color: var(--gold);
  background-color: var(--gold);
  /* Drawn, not typed: a tick glyph in an 18px box lands somewhere different in
     every font stack. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.3l2.6 2.7L10 3.4' fill='none' stroke='%23050505' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
}
/* :focus, not :focus-visible — the input is off-screen, so this ring is the
   only thing that says where the keyboard is, and :focus-visible is Chrome 86. */
.pick__i:focus + .pick__b { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Dragging a list into order and ticking boxes in it are different jobs, and
   the toolbar hides every bulk control in reorder mode for the same reason. */
.reordering .pick { display: none; }

@media (pointer: coarse) {
  .pick { width: 40px; height: 40px; }
}

/* ---- the real aspect ratio --------------------------------------------------
   LAST IN THE FILE ON PURPOSE. Every height above is the Chrome 79 fallback,
   and an @supports block has no extra specificity — so it only beats them by
   coming after all of them. Moving this block up would silently restore the
   fixed heights for everybody. */

@supports (aspect-ratio: 9 / 16) {
  .film__thumb { height: auto; aspect-ratio: 9 / 16; }
  .rjob .job__still { height: auto; aspect-ratio: 9 / 16; }
  .rplay { height: auto; aspect-ratio: 9 / 16; }
}

/* ---- the date filter and the batch delete --------------------------------
   .field is width:100%, which in the flex toolbar would push the count and
   the buttons off the end. Sized to sit beside .btn--sm rather than beside
   the search box whose border it borrows. */
.tools__date { width: auto; flex: 0 0 auto; padding: 6px 8px; font-size: 13px; }
.tools__dash { color: var(--faint); font-size: 13px; }
/* Chrome draws the picker glyph dark-on-dark; invert turns it legible without
   restyling the control. Harmless where the UA ignores it. */
.tools__date::-webkit-calendar-picker-indicator { filter: invert(0.75); cursor: pointer; }

/* The typed confirmation. Full width of the dialog, and it only exists while
   ask() has been handed a `typed` value. */
.ask__typelabel { display: block; margin: 14px 0 6px; font-size: 12px; color: var(--dim); }
.ask__type { width: 100%; font-variant-numeric: tabular-nums; }

/* ---- the render cap ------------------------------------------------------
   Sits under the list and reads as a note, not as an error — nothing is
   missing, it is only undrawn. */
.more { margin: 18px 0 0; font-size: 13px; color: var(--dim); text-align: center; }
.more button {
  margin-left: 8px; padding: 5px 12px; border: 1px solid var(--rule2);
  border-radius: 999px; background: none; color: var(--ink);
  font: inherit; font-size: 13px; cursor: pointer;
}
.more button:hover { border-color: var(--gold); color: var(--gold); }
.more button:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
