/* recap-mini — studio page (`/`). Owned by card U2.
 * Loaded after tokens.css + components.css; adds only page-local classes
 * plus two deliberate, scoped overrides of shared components (documented
 * where they appear). No token is redefined here — DESIGN.md §2 is law.
 */

/* [hidden] must win over a component's own `display`. RM.dropzone sets
   `.dropzone { display: block }` on its host, which beats the UA
   `[hidden] { display: none }` rule — the file pane would stay visible
   after a file is chosen without this. */
.studio [hidden] {
  display: none !important;
}

/* ------------------------------------------------------------- header */
.studio-head {
  margin-bottom: var(--space-5);
}

.studio-sub {
  margin-top: var(--space-2);
  max-width: 60ch;
}

/* --------------------------------------------------------------- grid */
.studio-grid {
  display: grid;
  gap: var(--space-4);
  align-items: start;
}

/* Card B: the LEFT 7/12 column is the video preview and it is the sticky one
   (DESIGN.md §4). The right 5/12 column is the Properties flow + cost +
   recent jobs and scrolls normally — it is the taller of the two. */
@media (min-width: 900px) {
  .studio-grid {
    grid-template-columns: 7fr 5fr;
    gap: var(--space-5);
  }
  .studio-main {
    position: sticky;
    top: calc(var(--nav-h) + var(--space-5));
    align-self: start;
  }
  /* A pinned card taller than the viewport is not pinned at all: at 1280x844
     with a 9:16 crop the card measured 1167 px and the player controls sat
     ~245 px BELOW the fold while the user worked the right-hand panel. Cap
     the stage so the whole card fits: viewport minus the nav, minus the
     sticky offset above the card, minus the card's own chrome — its header
     row, the controls row, the caption/hint lines and the card padding,
     measured at 252 px on the tallest state (source-ready) with a little
     slack. `.vp-stage` is width:auto/max-width:100%, so this shrinks the box
     along its ratio instead of squashing it (see components.css). */
  .studio-preview {
    --vp-max-h: calc(100svh - var(--nav-h) - var(--space-5) - 264px);
  }
}

.studio-main,
.studio-side {
  min-width: 0;
}

/* One column: the video preview comes first, so a running job's progress
   card would land below it and every option. studio.js sets `has-job` while
   the action card belongs to a job; `order` moves the column visually
   without touching DOM or tab order (and the properties card is swapped out
   for the progress card at that point anyway). */
@media (max-width: 899px) {
  .studio-grid.has-job .studio-side {
    order: -1;
  }
}

.studio-card > header {
  align-items: center;
  /* the progress/result header pairs a bilingual title with a nowrap
     bilingual status chip; at 320 px they measured 336 px on one line, so
     the chip is allowed to drop to a second row instead of overflowing. */
  flex-wrap: wrap;
  row-gap: var(--space-2);
}

.studio-sec-title {
  margin: 0;
}

.studio-sec {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.studio-note {
  color: var(--warn);
}

.studio-sub-title {
  margin: 0;
  font-weight: 600;
}

.studio-lock {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-s);
  background: var(--info-soft);
  color: var(--info);
}

/* ------------------------------------------------------------- source */
.src-pane {
  min-width: 0;
}

/* name+meta | Remove. The thumbnail that used to sit here is gone: the
   left-hand Video Preview panel now shows the frame itself, so a 76 px
   duplicate of it was noise. Below 520 px Remove drops to its own row
   rather than stealing the file name's width. */
.src-chosen {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--surface-2);
}

@media (max-width: 519px) {
  .src-chosen {
    grid-template-columns: minmax(0, 1fr);
  }
  .src-chosen > .btn {
    justify-self: start;
  }
}

.prev-media {
  display: block;
  background: #000;
  object-fit: cover;
}

.prev-media.is-placeholder {
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, #232838, #171a21 60%);
  color: var(--text-3);
}

.src-meta {
  flex: 1;
  min-width: 0;
}

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

.src-sub {
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}

.src-state {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
  font-size: 12px;
  line-height: 16px;
  color: var(--text-2);
}

.src-state.is-ok {
  color: var(--ok);
}
.src-state.is-bad {
  color: var(--danger);
}
.src-state.is-busy::before {
  content: "";
  width: 12px;
  height: 12px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: rm-spin 700ms linear infinite;
}

.src-plat {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* The three mode tiles carry a one-line hint each. `.seg` centres its
   content vertically, so if any hint wraps the three tiles' titles stop
   sharing a baseline; top-aligning them keeps the row even whatever the
   viewport does to the text (review item 14). */
.studio-modecard .seg {
  justify-content: flex-start;
}

.studio-modecard .seg-hint {
  margin-top: 2px;
}

/* -------------------------------------------------------- form extras */
.swatch-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.swatch {
  width: 14px;
  height: 14px;
  border-radius: 4px;
  border: 1px solid rgb(255 255 255 / 0.25);
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.25);
}

.range {
  width: 100%;
  height: 44px;
  padding: 0;
  background: transparent;
  accent-color: var(--accent);
  cursor: pointer;
}

.range-out {
  margin-left: auto;
  color: var(--text);
  font-weight: 600;
}

.field > .label {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.studio-toggles {
  display: grid;
  gap: 2px;
}

/* (The `.studio-pro` <details> disclosure is gone with card B: the Pro
   Editor's controls are the Finish step now, so there is no collapsed
   drawer to style.) */

.pick-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.pick-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ------------------------------------------------------ source preview */
.prev-video {
  border-radius: var(--radius-m);
  overflow: hidden;
  background: #000;
}

.prev-media {
  width: 100%;
  aspect-ratio: 16 / 9;
}

.prev-cap {
  margin-top: var(--space-2);
  display: flex;
  gap: 2px;
  min-width: 0;
}

.prev-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.prev-fallback {
  padding: var(--space-4);
}

.prev-link {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--surface-2);
}

.prev-link-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-s);
  background: var(--accent-soft);
  color: var(--accent);
}

.prev-link-meta {
  min-width: 0;
}

.prev-url {
  margin-top: var(--space-2);
  color: var(--text-2);
  overflow-wrap: anywhere;
}

/* The empty state of the preview card, before anything is chosen. RM.empty's
   56 px badge and centred sentence made a ~215 px grey slab out of the first
   card on the page; this is one quiet row (review item 14). */
.prev-empty {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
}

.prev-empty-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-s);
  border: 1px dashed var(--line);
  color: var(--text-3);
}

.prev-empty-text {
  min-width: 0;
  color: var(--text-2);
}

/* ----------------------------------------------------------- cost card */
.studio-action.is-short {
  border-color: color-mix(in srgb, var(--danger) 50%, transparent);
}

.cost-big {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.cost-num {
  font-size: 34px;
  line-height: 38px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent);
}

.studio-action.is-short .cost-num {
  color: var(--danger);
}

.cost-unit {
  color: var(--text-2);
  font-size: 14px;
}

/* sits inline after the unit, not shoved to the far edge: pushed right it
   wrapped onto a line of its own and read as an unrelated badge. */
.cost-tag {
  margin-left: var(--space-1);
}

.cost-sub {
  margin-top: var(--space-3);
}

/* the estimate's arithmetic, one labelled row per term — the single
   concatenated "7 min x 1.5 = 10.5" sentence could not be made bilingual
   (it spliced an English word into a Burmese-first line). */
.cost-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 3px 0;
  font-size: 13px;
  line-height: 18px;
  color: var(--text-2);
}

.cost-line + .cost-line {
  border-top: 1px solid var(--line);
}

.cost-k {
  min-width: 0;
}

.cost-v {
  flex: none;
  color: var(--text);
  font-weight: 600;
  white-space: nowrap;
}

.cost-note {
  font-weight: 400;
}

.cost-round {
  margin-top: var(--space-2);
}

.cost-warn {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-s);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 14px;
}

.cost-warn .btn {
  margin-left: auto;
}

.studio-action .btn--block {
  margin-top: var(--space-4);
}

/* an error line outside a .field (the submit result, the duration cap):
   same anatomy as components.css `.field .error`, icon + text, never
   colour alone. */
.studio-action .error.is-shown,
.submit-error {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin-top: var(--space-3);
  font-size: 13px;
  line-height: 18px;
  color: var(--danger);
}

.studio-action .error.is-shown::before,
.submit-error::before {
  content: "!";
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--danger);
  color: #2a0006;
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

.submit-error {
  flex-wrap: wrap;
}

.submit-error .btn {
  margin-left: auto;
}

/* the operator's maintenance sentence, on its own line under the coded
   error (`.submit-error` is a wrapping flex row) */
.submit-error-note {
  flex-basis: 100%;
  color: var(--text-2);
}

/* --------------------------------------------------------- progress */
/* RM.stepper OVERWRITES its host's className with "stepper", so the
   `.studio-stepper` class studio.js puts on the host is gone by the time the
   component has rendered — the margin has to hang off the component's own
   class inside this card. */
.studio-action .stepper {
  margin-bottom: var(--space-2);
}

/* components.css turns the stepper horizontal at ≥900 px. In the 5/12
   sticky column six steps would be ~55 px wide each, which wraps every
   Burmese label to four lines — so inside this column only, keep the
   vertical rail and draw the connector downward instead. */
@media (min-width: 900px) {
  .studio-side .steps {
    grid-auto-flow: row;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
  }
  .studio-side .step {
    grid-template-columns: 26px minmax(0, 1fr);
    justify-items: start;
    text-align: left;
    gap: var(--space-3);
    padding-bottom: var(--space-3);
  }
  .studio-side .step:last-child {
    padding-bottom: 0;
  }
  .studio-side .step::before {
    top: 28px;
    bottom: 2px;
    left: 12px;
    right: auto;
    width: 1.5px;
    height: auto;
    display: block;
  }
  .studio-side .step:last-child::before {
    display: none;
  }
  .studio-side .step-label {
    max-width: none;
  }
  /* this override put the dot back in column 1, so the error has to go back
     under the LABEL — components.css's >=900 px rule (`grid-column: 1`) is
     written for the single-column horizontal stepper it ships up here, and
     following it inside this column would drop the failure text into the
     26 px dot track one character per line. Not the old page-wide
     workaround: it is the companion of the grid-template-columns above. */
  .studio-side .step-error {
    grid-column: 2;
  }
}

/* one column at every width: this card lives in the 5/12 sticky column
   (~380 px at 1280), where two bilingual buttons side by side wrapped
   "MP4 ဒေါင်းလုဒ် · Download MP4" onto three lines. */
.result-actions {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* ------------------------------------------------------- recent jobs */
.recent {
  display: grid;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.recent-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius-s);
  background: var(--surface-2);
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: border-color 150ms var(--ease), background-color 150ms var(--ease);
}

.recent-row:hover {
  border-color: #384054;
}

.recent-main {
  flex: 1;
  min-width: 0;
}

.recent-mode {
  display: block;
  font-weight: 600;
  font-size: 14px;
}

.recent-meta {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.recent-chip {
  flex: none;
}

/* A status chip is nowrap and bilingual ("လုပ်ဆောင်နေသည် · processing"
   ~200 px) and Burmese words do not break, so below ~420 px the title and
   the chip could not share a line: measured 395 px of content in a 320 px
   viewport (a horizontal scrollbar, which preamble rule 8 forbids). Under
   that width the chip takes its own line. */
@media (max-width: 419px) {
  .recent-row {
    flex-wrap: wrap;
  }
  .recent-main {
    flex: 1 1 100%;
  }
}

/* ------------------------------------------------------------ failure */
.studio-fail {
  max-width: 560px;
}

/* ------------------------------------------------------- mobile dock
   On a phone the whole form is one column, so the Start button in the
   right-hand card sits ~3 000 px below the fold: the primary action of
   the page was unreachable without scrolling past every option. This is
   a fixed bar that rides above the shell's bottom tab bar and mirrors
   whatever the action card currently is (cost + Start / running job /
   finished download). Desktop keeps the sticky column and hides it.
   studio.js adds `has-studio-dock` to <body> when the dock exists. */
.studio-dock {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
  z-index: 45; /* above .tabbar (40), below .toasts (60) and modals */
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--line);
  background: rgb(23 26 33 / 0.96);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow-2);
}

@media (min-width: 900px) {
  .studio-dock {
    display: none;
  }
}

.dock-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* a chip must keep its own width, not stretch */
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.dock-num {
  font-size: 20px;
  line-height: 24px;
  font-weight: 700;
  color: var(--accent);
}

.dock-sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* the dock's own copy of the CTA is the one a phone user actually presses,
   so it keeps the 48 px `l` height and never shrinks below a thumb width */
.dock-action {
  flex: none;
}

.dock-action .btn {
  min-width: 132px;
}

/* content must be able to scroll clear of BOTH bars; components.css only
   reserves room for the tab bar (this rule is scoped to the body class
   studio.js sets, so it can never affect another page). */
@media (max-width: 899px) {
  body.has-studio-dock {
    padding-bottom: var(--space-5);
  }

  /* toasts default to sitting just above the tab bar — that is exactly
     where the dock is now, so lift them by the dock's height. */
  body.has-studio-dock .toasts {
    bottom: var(--space-5);
  }
}

/* (The `.studio .step-error { grid-column: 2 }` workaround that used to live
   here is gone: components.css now carries both halves of the rule — column 2
   under 900 px where `.step` has a dot column, column 1 at 900 px+ where it
   does not. The `.studio-side` stepper below keeps its two columns at every
   width, and the base rule is right for it at both. */

/* ==================================================================
   Card B — preview-first layout: the Video Preview card (left) and the
   Properties step flow (right).
   ================================================================== */

/* ------------------------------------------------------ preview card */
.studio-preview > header {
  margin-bottom: var(--space-3);
}

.studio-preview .prev-cap {
  margin-top: var(--space-3);
}

/* the keyboard affordance for the overlay boxes. It is a hint, not a
   control, so it stays quiet — but it must be readable, because arrow-key
   nudging is the only way to place a box precisely with a keyboard. */
.studio-overlay-keys {
  margin-top: var(--space-2);
}

/* ------------------------------------------------ properties / wizard */
.studio-props > header {
  margin-bottom: var(--space-3);
}

.wiz-steps {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--space-2);
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
}

.wiz-step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 13px;
  line-height: 18px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: border-color 150ms var(--ease), color 150ms var(--ease),
    background-color 150ms var(--ease);
}

/* a step you have not reached yet is disabled — the house rule is opacity
   .5 + no pointer, but a THIRD of the header greyed out reads as broken, so
   these keep full contrast on the number and drop only the interaction. */
.wiz-step:disabled {
  cursor: default;
  pointer-events: none;
}

.wiz-step:not(:disabled):hover {
  border-color: #384054;
  color: var(--text);
}

.wiz-step.is-current {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text);
}

.wiz-step.is-done {
  color: var(--text);
}

.wiz-num {
  flex: none;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text-2);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.wiz-step.is-current .wiz-num {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
}

.wiz-step.is-done .wiz-num {
  border-color: var(--ok);
  color: var(--ok);
}

.wiz-name {
  min-width: 0;
}

.wiz-pane[hidden] {
  display: none;
}

.wiz-nav {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.wiz-nav .btn {
  flex: 1;
}

.wiz-nav .btn[hidden] {
  display: none;
}

/* ----------------------------------------------------- source step */
.url-row {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
  flex-wrap: wrap;
}

.url-row .btn {
  flex: 1 1 auto;
}

.url-row .btn[hidden] {
  display: none;
}

/* ----------------------------------------------- disabled-with-reason
   DESIGN.md §5.4: a control that cannot change the output is disabled with
   its reason visible, never hidden. The reason line keeps full contrast —
   only the control itself dims. */
.field.is-disabled > .label,
.field.is-disabled .range,
.field.is-disabled .segmented {
  opacity: 0.5;
}

.field.is-disabled .hint {
  opacity: 1;
}

/* ----------------------------------------------------- finish step */
.blur-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.blur-row .btn {
  flex: none;
}

/* ------------------------------------------------ script review checkpoint */
.review-grid {
  display: grid;
  gap: var(--space-4);
}

.review-video {
  width: 100%;
  max-height: 62vh;
  border-radius: var(--radius-m);
  background: #000;
}

.review-blocks {
  display: grid;
  gap: var(--space-3);
}

.review-block {
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--surface-2);
}

.review-block--timing {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--danger) 35%, transparent);
}

.review-timing-alert {
  margin: 0;
  padding: var(--space-3);
  border: 1px solid color-mix(in srgb, var(--danger) 55%, var(--line));
  border-radius: var(--radius-m);
  background: color-mix(in srgb, var(--danger) 10%, var(--surface-1));
  color: var(--text);
  font-weight: 700;
  line-height: 1.65;
}

.review-timing-line {
  margin: 0 0 var(--space-2);
  font-weight: 650;
}

.review-block-head,
.review-block-actions,
.review-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.review-block-head {
  justify-content: space-between;
  margin-bottom: var(--space-2);
}

.review-block .textarea {
  min-height: 104px;
  font-family: "Noto Sans Myanmar", Inter, sans-serif;
}

.review-source-line {
  margin: 0 0 var(--space-2);
  padding: var(--space-2);
  border-radius: var(--radius-s);
  background: var(--surface-1);
}

.review-script {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--surface-1);
  font-family: "Noto Sans Myanmar", Inter, sans-serif;
  line-height: 1.8;
}

.review-warning {
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--warn);
  background: color-mix(in srgb, var(--warn) 8%, transparent);
}

@media (min-width: 900px) {
  .review-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .review-source { position: sticky; top: var(--space-4); align-self: start; }
}
