/* ==========================================================================
   VideoTex — page-upload.css   (owner: templates/video_app/upload.html)

   Loaded after tokens.css / chrome.css / components.css / forms.css, so
   everything here builds on those: .yt-alert, .yt-field, .yt-progress,
   .yt-tags, .yt-btn, .yt-card__thumb and the .yt-card__status chip are all
   reused rather than re-implemented. No colour is written literally — every
   one comes from a token; the handful of literal numbers below are the
   one-off geometry this page needs (the 136px icon circle, the 380px drop
   zone, the 336px aside) and there is no token for those.

   The single most important rule in this file is the uploader switch at the
   bottom: html[data-vt-upload-js] is stamped by a blocking script in the
   template's {% block extra_head %}, so the resumable uploader and the plain
   multipart form never both appear and neither one flashes.
   ========================================================================== */


/* ==========================================================================
   1. Page frame
   ========================================================================== */

.yt-upload {
  /* Narrower than the 2560px feed: this is a form, not a grid of thumbnails. */
  max-width: 1440px;
}

.yt-upload__head {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 20px;
}

.yt-upload__lede {
  max-width: 76ch;
  color: var(--yt-fg-secondary);
  font-size: 14px;
  line-height: 1.5;
  text-wrap: pretty;
}

.yt-upload__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 336px;
  gap: 32px;
  align-items: start;
}

.yt-upload__main,
.yt-upload__aside {
  min-width: 0;
}

.yt-upload__main {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.yt-upload__aside {
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: sticky;
  top: calc(var(--yt-masthead-h) + 24px);
}

/* One column from 1080px down: the aside is reference material, so it follows
   the form rather than squeezing it. */
@media (max-width: 1080px) {
  .yt-upload__grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .yt-upload__aside { position: static; top: auto; }
}

/* The shell drops its own padding below 792px; put a little back so the
   bordered panels do not touch the viewport edge. */
@media (max-width: 792px) {
  .yt-upload { padding-inline: 16px; }
}


/* ==========================================================================
   2. Banners  (ffmpeg missing, queue closed, resume prompt, no-JS notice)

   All four are .yt-alert from chrome.css; this only lays out the text column
   inside one, since .yt-alert is a flex row of [icon][body].
   ========================================================================== */

/* The banners sit between the page header and the two-column grid, neither of
   which is a flex parent, so the spacing has to be their own. */
.yt-upload__banner {
  margin-bottom: 20px;
}

.yt-upload__resume {
  min-width: 0;
}

.yt-upload__banner-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.yt-upload__banner-body p { text-wrap: pretty; }

.yt-upload__banner-title {
  font-weight: 500;
  font-size: 15px;
  line-height: 1.35;
}

/* The server's own words, quoted verbatim. Monospaced and scrollable because
   an ffmpeg error is usually a path or a stderr line, not a sentence. */
.yt-upload__reason {
  padding: 8px 10px;
  border-radius: var(--yt-radius-sm);
  background: var(--yt-bg-chip);
  color: var(--yt-fg);
  font-size: 13px;
  line-height: 1.45;
  overflow-x: auto;
  overflow-wrap: anywhere;
}

.yt-upload__resume-file {
  font-size: 14px;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.yt-upload__resume-actions { gap: 8px; }


/* ==========================================================================
   3. Drop zone
   ========================================================================== */

.yt-upload__zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  min-height: 380px;
  padding: 40px 24px;
  border: 2px dashed var(--yt-border);
  border-radius: var(--yt-radius-md);
  background: var(--yt-bg);
  text-align: center;
  transition: border-color var(--yt-transition), background var(--yt-transition);
  cursor: pointer;
}

.yt-upload__zone:hover { border-color: var(--yt-fg-secondary); }

/* Applied by upload.js while a file is dragged over the page. */
.yt-upload__zone--over {
  border-color: var(--yt-accent);
  border-style: solid;
  background: var(--yt-bg-hover);
}

.yt-upload__zone-icon {
  display: grid;
  place-items: center;
  width: 136px;
  height: 136px;
  border-radius: 50%;
  background: var(--yt-bg-chip);
  color: var(--yt-fg-secondary);
  transition: color var(--yt-transition);
}
.yt-upload__zone-icon .yt-icon { width: 64px; height: 64px; }
.yt-upload__zone--over .yt-upload__zone-icon { color: var(--yt-accent); }

.yt-upload__zone-title {
  font-size: 18px;
  font-weight: 500;
  line-height: 1.3;
}

.yt-upload__zone-sub {
  max-width: 46ch;
  color: var(--yt-fg);
  font-size: 14px;
  font-weight: 500;
}

.yt-upload__zone-note {
  max-width: 62ch;
  color: var(--yt-fg-secondary);
  font-size: 12px;
  line-height: 1.5;
  text-wrap: pretty;
}

.yt-upload__zone-actions { margin-top: 4px; }

@media (max-width: 659px) {
  .yt-upload__zone { min-height: 300px; padding: 28px 16px; gap: 12px; }
  .yt-upload__zone-icon { width: 96px; height: 96px; }
  .yt-upload__zone-icon .yt-icon { width: 44px; height: 44px; }
  .yt-upload__zone-title { font-size: 16px; }
}


/* ==========================================================================
   4. Per-file cards

   article.yt-upload__card > .yt-upload__card-thumb + .yt-upload__card-body
   The thumb is a real .yt-card__thumb so that when the transcode lands,
   VT.observeStatus's swapThumbnail() drops the finished poster frame into
   exactly the right box instead of jamming an <img> at the top of the card.
   ========================================================================== */

.yt-upload__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.yt-upload__card {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: 16px;
  padding: 16px;
  border: 1px solid var(--yt-border);
  border-radius: var(--yt-radius-md);
  background: var(--yt-bg-elevated);
  transition: border-color var(--yt-transition);
}

/* Phase is written by upload.js. Only the two ends of the story get a colour;
   everything in between stays neutral so a busy queue is not a rainbow. */
.yt-upload__card[data-phase="failed"] { border-color: var(--yt-danger); }
.yt-upload__card[data-phase="live"]   { border-color: var(--yt-success); }

.yt-upload__card-thumb {
  /* .yt-card__thumb is 16/9 at radius-md; only the size is page-specific. */
  width: 168px;
  border-radius: var(--yt-radius-sm);
}

.yt-upload__card-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.yt-upload__card-head {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
}

/* File names are unmoderated text and can be 255 characters of one word. */
.yt-upload__card-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  min-width: 0;
  flex: 1 1 auto;
  max-height: 2.8em;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.yt-upload__card-head .yt-badge { flex: 0 0 auto; }

.yt-upload__card-field { margin-bottom: 0; gap: 4px; }

.yt-upload__card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 6px;
  color: var(--yt-fg-secondary);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
/* Empty fields (no rate yet, no ETA yet) collapse, and the bullet separator
   only appears between two fields that actually have text. */
.yt-upload__card-meta > span:empty { display: none; }
.yt-upload__card-meta > span + span::before {
  content: "\2022";
  margin-right: 6px;
  color: var(--yt-border);
}

.yt-upload__card-pct {
  color: var(--yt-fg);
  font-weight: 500;
}

.yt-upload__card-stage,
.yt-upload__card-msg {
  font-size: 13px;
  line-height: 1.45;
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

.yt-upload__card-stage { color: var(--yt-fg-secondary); }

.yt-upload__card-msg { color: var(--yt-fg-secondary); }
.yt-upload__card-msg[data-kind="error"]   { color: var(--yt-danger); font-weight: 500; }
.yt-upload__card-msg[data-kind="warning"] { color: var(--yt-warning); }
.yt-upload__card-msg[data-kind="success"] { color: var(--yt-success); }

.yt-upload__card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
}

@media (max-width: 659px) {
  .yt-upload__card {
    grid-template-columns: minmax(0, 1fr);
    padding: 12px;
  }
  .yt-upload__card-thumb { width: 100%; max-width: 260px; }
}


/* ==========================================================================
   5. Metadata form
   ========================================================================== */

.yt-upload__details,
.yt-upload__queue { min-width: 0; }

.yt-upload__form { max-width: 720px; }

/* Category and channel sit side by side on a wide screen; both are short.
   min() rather than a bare 240px: on a 320px viewport a fixed minimum track is
   wider than the container and pushes the whole page into a horizontal
   scroll, which no amount of min-width:0 further up can undo. */
.yt-upload__pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 0 20px;
}

/* One element per field carrying the id Django's own aria-describedby points
   at, wrapping however many messages that field produced. It is a flex column
   only so two messages keep the .yt-field gap between them. */
.yt-upload__errors {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.yt-upload__tags {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
/* .yt-tags collapses itself when empty (forms.css), so the gap does not
   leave a hole before the first chip is added. */

.yt-upload__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin-top: 4px;
}


/* ==========================================================================
   6. Aside panels
   ========================================================================== */

.yt-upload__panel {
  padding: 16px;
  border: 1px solid var(--yt-border);
  border-radius: var(--yt-radius-md);
  background: var(--yt-bg-elevated);
  min-width: 0;
}

.yt-upload__panel-title {
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: .01em;
}

.yt-upload__panel-note {
  margin-top: 12px;
  color: var(--yt-fg-secondary);
  font-size: 12px;
  line-height: 1.5;
  text-wrap: pretty;
}
.yt-upload__panel-note:first-of-type { margin-top: 0; }

.yt-upload__none { margin-top: 0; }

/* -- "Accepting uploads" indicator ---------------------------------------- */
.yt-upload__accepting {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 500;
}

.yt-upload__dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--yt-fg-secondary);
}
.yt-upload__accepting[data-state="ok"]   { color: var(--yt-success); }
.yt-upload__accepting[data-state="ok"]   .yt-upload__dot { background: var(--yt-success); }
.yt-upload__accepting[data-state="warn"] { color: var(--yt-warning); }
.yt-upload__accepting[data-state="warn"] .yt-upload__dot { background: var(--yt-warning); }

/* -- Stat tiles ----------------------------------------------------------- */
.yt-upload__stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.yt-upload__stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 8px;
  border-radius: var(--yt-radius-sm);
  background: var(--yt-bg-chip);
  min-width: 0;
}

.yt-upload__stat-value {
  font-size: 18px;
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.yt-upload__stat-label {
  color: var(--yt-fg-secondary);
  font-size: 11px;
  line-height: 1.3;
}

@media (max-width: 400px) {
  .yt-upload__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* -- Limits table --------------------------------------------------------- */
.yt-upload__facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
  min-width: 0;
}

.yt-upload__facts dt {
  margin-top: 10px;
  color: var(--yt-fg-secondary);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .02em;
  text-transform: uppercase;
}
.yt-upload__facts dt:first-child { margin-top: 0; }

.yt-upload__facts dd {
  font-size: 13px;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

/* -- Recent uploads ------------------------------------------------------- */
.yt-upload__recent {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}


/* ==========================================================================
   7. The uploader switch  (must stay last)

   These rules only ever HIDE, so every element keeps the display value its
   own block gave it — no `display: block` is forced onto the flex drop zone.

   html[data-vt-upload-js="1"]  fetch + File.slice are available -> chunked
   anything else (including the attribute never being stamped, i.e. scripting
   off) -> the plain multipart form.
   ========================================================================== */

html:not([data-vt-upload-js="1"]) .yt-upload__js { display: none; }
html[data-vt-upload-js="1"] .yt-upload__plain { display: none; }
