/* Make-a-video view (mockup 02) — three-column grid: brand/style/brief on the
   left, script candidates in the center, "Your video" + render + ready-state
   cards on the right. */

.video-grid {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr) 280px;
  gap: 16px;
  align-items: start;
}

.video-left,
.video-main {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.video-side {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.video-format-grid {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.video-format-card {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 10px;
  text-align: left;
  padding: 10px 12px;
  border: 1px solid var(--border, #e5ddc9);
  border-radius: var(--radius-sm, 8px);
  background: var(--bg-elevated, #fff);
  cursor: pointer;
  font: inherit;
}

.video-format-card.selected {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 8%, transparent);
}

.video-format-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm, 8px);
  background: var(--bg-sunken, #f6efe6);
  font-size: 1.1em;
}

.video-format-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.video-format-body p {
  margin: 0;
}

.video-format-radio {
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  border-radius: 50%;
  border: 2px solid var(--border, #c9beA0);
}

.video-format-card.selected .video-format-radio {
  border-color: var(--primary);
  background: radial-gradient(circle, var(--primary) 0 40%, transparent 44%);
}

.video-empty {
  padding: 32px 8px;
  text-align: center;
}

.video-script-row {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* The chosen script, editable, filling the middle column (owner ask,
   Next-steps.txt item 3 — the space between the style picker on the left and
   the make/review rail on the right was previously empty once a script was
   picked). */
.video-script-box-title {
  margin: 0 0 4px;
  font-size: 1rem;
}

.video-script-fields {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 12px 0;
}

.video-script-input {
  width: 100%;
  resize: vertical;
  min-height: 48px;
}

.video-script-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px;
  border: 1px solid var(--border, #e5ddc9);
  border-radius: var(--radius-sm, 8px);
}

.video-beat-line {
  margin: 0;
}

.video-script-card .btn {
  align-self: flex-start;
}

/* Right rail */
.video-summary {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.video-summary-row {
  display: flex;
  justify-content: space-between;
}

.video-render-callout {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.video-queue-section p {
  margin: 0 0 8px;
}

@media (max-width: 1100px) {
  .video-grid {
    grid-template-columns: 1fr;
  }
}

/* ---- Steps 3-6: b-roll handoff, scenes prompt, platform prompts, next
   steps. Full-width cards under the three-column grid, one per screen,
   revealed in order. Reuses .card/.btn/.input so the glow theme
   (css/glow.css, data-glow="on") applies without new rules. ---- */

.video-flow {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 16px;
}

.video-step-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.video-step-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.video-step-head-body {
  min-width: 0;
}

.video-step-head h2 {
  margin: 0;
}

.video-step-head p {
  margin: 2px 0 0;
}

.video-step-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.video-step-card > .btn,
.video-step-card > .video-open-mac {
  align-self: flex-start;
}

/* Step 3 — chosen b-roll */
.video-broll-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.video-broll-chip {
  max-width: 100%;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill, 999px);
  font-size: 0.85em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Step 4 — the editable prompt */
.video-prompt-meta {
  display: flex;
  gap: 8px;
  align-items: baseline;
}

.video-prompt-text {
  width: 100%;
  min-height: 220px;
  max-height: 55vh;
  resize: vertical;
  overflow: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  line-height: 1.5;
  white-space: pre-wrap;
}

.video-scene-details summary {
  cursor: pointer;
  font-weight: 600;
}

.video-scene-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
  max-height: 340px;
  overflow-y: auto;
}

.video-scene-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  min-width: 0;
}

.video-scene-n {
  flex: none;
  font-weight: 600;
  white-space: nowrap;
}

.video-scene-body {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.video-scene-body p {
  margin: 2px 0 0;
}

.video-scene-secs {
  flex: none;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Step 5 — one card per platform */
.video-platform-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 12px;
}

.video-platform-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 10px);
  min-width: 0;
}

.video-platform-master {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 6%, transparent);
}

.video-platform-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.video-platform-head h3 {
  margin: 0;
  flex: 1;
  min-width: 0;
}

.video-platform-secs {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* How each cut was timed — visually distinct so an AI-adjusted version
   can never be mistaken for a formula-scaled one. */
.video-method-badge {
  border-radius: var(--radius-pill, 999px);
}

.video-method-master {
  border: 1px solid var(--primary);
  color: var(--primary);
}

.video-method-deterministic {
  border: 1px solid var(--border);
}

/* No separate version was made — it's the master, verbatim. Marked, but
   deliberately not amber: nothing here is unverified output. */
.video-method-fallback {
  border: 1px dashed var(--border);
  color: var(--text-muted);
}

.video-platform-card:has(.video-method-fallback) {
  border-style: dashed;
}

.video-method-ai,
.video-method-unknown {
  border: 1px solid var(--sunny);
  background: color-mix(in srgb, var(--sunny) 24%, transparent);
  color: var(--text);
  font-weight: 600;
}

.video-platform-card:has(.video-method-ai),
.video-platform-card:has(.video-method-unknown) {
  border-color: var(--sunny);
}

.video-prompt-pre {
  margin: 0;
  padding: 10px;
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  background: var(--bg-sunken, #f6efe6);
  font-size: 0.85em;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.video-stale-note {
  font-weight: 600;
}

/* "Your wording isn't in this one" — a real loss, so it reads as a
   statement rather than fine print, without shouting like a warning. */
.video-retimed-note {
  border-left: 2px solid var(--border);
  padding-left: 8px;
}

/* Render failure — the renderer's own words, kept readable and scrollable
   rather than truncated: the provider:id it names is the actionable part. */
.video-render-error {
  margin: 0;
  font-weight: 600;
}

.video-render-error-detail {
  margin: 0;
  padding: 8px;
  max-height: 160px;
  overflow: auto;
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm, 6px);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  font-size: 0.85em;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.video-render-plan {
  margin: 0;
}

/* ---- Duration truth ----------------------------------------------------
   An estimate and a measurement must never look like the same kind of
   number. The measured one is the fact, so it carries the weight; the
   estimate is marked as provisional rather than shouted about. */
.video-estimate-badge {
  border: 1px dashed var(--border);
  border-radius: var(--radius-pill, 999px);
  color: var(--text-muted);
  font-weight: 500;
}

.video-measured-badge {
  border: 1px solid var(--primary);
  border-radius: var(--radius-pill, 999px);
  color: var(--primary);
  font-weight: 600;
  white-space: nowrap;
}

/* No measurement yet — stated, not filled in with a script number. Reads
   as an absence rather than a warning: nothing is wrong, it just hasn't
   been measured. */
.video-unmeasured-badge {
  border: 1px dashed var(--border);
  border-radius: var(--radius-pill, 999px);
  color: var(--text-muted);
  font-weight: 500;
  white-space: nowrap;
}

.video-measured-line {
  margin: 0;
  font-weight: 600;
}

/* A real file over a platform's limit. Warns, never blocks — two of the
   five limits are still Fizzavo's own estimate. */
.video-limit-warning {
  margin: 0;
  padding: 8px 10px;
  border: 1px solid var(--sunny);
  border-left-width: 3px;
  border-radius: var(--radius-sm, 6px);
  background: color-mix(in srgb, var(--sunny) 16%, transparent);
  font-weight: 600;
}

/* Spending real money is said at the point of clicking, in normal text —
   not fine print under the button. */
.video-cost-line {
  margin: 0;
  font-weight: 600;
}

.video-make-version {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.video-make-version p {
  margin: 0;
}

/* ---- Step 6: Next steps, as actions ------------------------------------
   One row per thing you can do: what it is, where it stands, and the button
   that does it. Rows stack on narrow widths so nothing is ever cut off. */
.video-action-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.video-action {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 10px);
  min-width: 0;
}

.video-action-body {
  flex: 1 1 240px;
  min-width: 0;
}

.video-action-body p {
  margin: 2px 0 0;
}

.video-action-control {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
  max-width: 100%;
}

.video-action-error {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ---- Review a finished video ------------------------------------------- */
.video-review-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.video-review-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 10px);
  min-width: 0;
}

.video-review-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.video-review-head strong {
  flex: 1 1 auto;
  min-width: 0;
}

.video-review-status {
  border: 1px solid var(--border);
  border-radius: var(--radius-pill, 999px);
  white-space: nowrap;
}

/* Portrait renders (1080x1920) would otherwise fill the whole screen —
   capped by height, centred, and never wider than the card. */
.video-review-frame {
  display: flex;
  justify-content: center;
  padding: 8px;
  border-radius: var(--radius-md, 10px);
  background: var(--bg-sunken, #f6efe6);
  min-width: 0;
}

.video-review-player {
  max-width: 100%;
  max-height: 60vh;
  border-radius: var(--radius-sm, 6px);
}

.video-review-row p {
  margin: 0;
}

.video-queue-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.video-queue-select {
  width: auto;
  min-width: 140px;
  max-width: 100%;
}

/* Narrow widths: every action button becomes a full-width tap target, and
   they all behave the same way — a row of differently-sized buttons reads
   as different KINDS of action when they aren't. */
@media (max-width: 520px) {
  .video-action-control,
  .video-make-version,
  .video-queue-controls,
  .video-queue-select {
    width: 100%;
  }

  .video-action-control > .btn,
  .video-make-version > .btn,
  .video-queue-controls > .btn {
    width: 100%;
  }
}

/* ---------- Card deck builder (views/video_card_deck.js) ---------- */

/* The way through to the card sheet, sized as the main action on this
   column (owner, 2026-08-08: he never found it as a small secondary
   button beside the heading). */
.card-deck-open {
  margin: 8px 0 12px;
}

.card-deck-open .deck-expand-btn {
  width: 100%;
}

/* The plain list is the fallback now: folded, and scrolling once it is
   longer than a glance. */
.card-deck-plain-summary {
  padding: 4px 0;
  color: var(--text-muted);
  font-size: 0.9em;
  cursor: pointer;
}

.card-deck-plain-summary:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.card-deck-plain[open] .card-deck-list {
  max-height: 320px;
  overflow-y: auto;
}

.card-deck-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.card-deck-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
  cursor: grab;
}

/* A card with no time reads differently on purpose — the render refuses an
   untimed deck, so it must not look finished. */
.card-deck-row.untimed {
  border-style: dashed;
}

.card-deck-index {
  min-width: 1.5em;
  text-align: right;
  font-weight: 600;
  color: var(--text-muted);
}

.card-deck-meta {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.card-deck-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-deck-timing {
  font-size: 0.82rem;
  color: var(--text-muted);
}

.card-deck-timing-missing {
  font-style: italic;
}

.card-deck-time-input {
  width: 6.5em;
  font: inherit;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.card-deck-warning {
  margin-top: 10px;
  font-size: 0.88rem;
}

/* Live render progress — one labelled bar per stage, each measured against
   its own denominator. NO width transition anywhere: the encode stages
   report roughly four times over a whole pass, and animating between those
   ticks would draw motion nobody measured. The bar steps, and that is the
   truth of it. */
.render-progress {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 10px 0 0;
}

.render-progress[hidden] {
  display: none;
}

.render-progress-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
  font-size: 0.85rem;
}

/* The stage name answers "what is it doing?" and leads; the percentage is
   the supporting detail, so it is the quieter of the two. */
.render-progress-label {
  font-weight: 600;
  color: var(--text);
}

/* Rides inside the label so it is announced with it, but reads as the aside
   it is: normal weight, muted, never competing with the stage name. */
.render-progress-eta {
  font-weight: 400;
  color: var(--text-muted);
}

.render-progress-percent {
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.render-progress-track {
  position: relative;
  height: 6px;
  border-radius: var(--radius-pill, 999px);
  background: var(--bg-sunken);
  overflow: hidden;
}

.render-progress-fill {
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--accent-gradient, var(--primary));
}

/* An indeterminate stage ("getting the engine ready") has no number to
   show, so it gets a travelling sliver instead of a width that would read
   as a measurement. */
.render-progress-fill-indeterminate {
  width: 35%;
  animation: render-progress-slide 1.4s ease-in-out infinite;
}

@keyframes render-progress-slide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(286%); }
}

/* Without motion, a stage with no number still has to look UNFINISHED. A
   full-width dimmed bar reads as "done", which is a claim nothing measured —
   so the still version is a partial, striped fill: visibly in progress,
   visibly not a percentage. */
@media (prefers-reduced-motion: reduce) {
  .render-progress-fill-indeterminate {
    animation: none;
    transform: none;
    width: 45%;
    background: repeating-linear-gradient(
      -45deg,
      var(--coral) 0 6px,
      var(--violet) 6px 12px
    );
    opacity: 0.75;
  }
}

.render-progress-stall {
  margin: 4px 0 0;
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* ---- Name this video (card decks) -------------------------------------
   A small centred dialog on the way into a render. Same overlay grammar as
   the clip-trim editor (body-level, backdrop + panel, removed whole on
   close) at a fraction of its size — this asks one question. */

.deck-name-overlay {
  position: fixed;
  inset: 0;
  z-index: 1300;          /* over the views, under toasts (1500) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.deck-name-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  animation: deck-name-fade 160ms ease-out;
}

.deck-name-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: min(420px, 100%);
  padding: 20px 22px 18px;
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
  animation: deck-name-rise 200ms cubic-bezier(0.22, 1, 0.36, 1);
}

.deck-name-title {
  margin: 0;
  font-size: 1.05rem;
}

.deck-name-hint {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 0.85rem;
  line-height: 1.4;
}

.deck-name-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font: inherit;
}

.deck-name-input:focus {
  outline: 2px solid var(--focus-ring);
  outline-offset: 1px;
}

.deck-name-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 14px;
}

@keyframes deck-name-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes deck-name-rise {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to { opacity: 1; transform: none; }
}

/* Reduced motion: appear, do not move. */
.deck-name-no-motion .deck-name-backdrop,
.deck-name-no-motion .deck-name-panel {
  animation: none;
}

/* The "Slow motion" control (plans/dreamy-slow-motion/final.md, step 7).
   Label over box over hint, the same stack every other dial uses; its own
   two rules rather than borrowing the Video-to-Script view's .vts-field,
   since the control appears on the render card and in the deck editor. */
.video-slow-mo {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 12px 0;
  max-width: 320px;
}

/* The two dials under it ("How slow", "Dreamy strength") repeat that stack,
   indented so they read as refinements of the choice above rather than as
   three equal questions. [hidden] wins over the flex display. */
.video-slow-mo-dial {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-left: 12px;
}

.video-slow-mo-dial[hidden] {
  display: none;
}

/* Inside the deck editor's style panel: a block, not one of the chip rows'
   flex items — same reason .deck-dest-row is a block. */
.deck-slow-mo-row {
  display: block;
}
