/* A readable step sequence, with one expanded editor and one list scroller. */
#workspace { overflow: hidden; }
/* The header is short so the steps get the room: the way back, the name, and one quiet line for where the test is and
   who changed it last (the whole record, and the file, are that line's tooltip). */
/* The settings column is the wider one, so Retries and Persona fit on one line at a laptop's 1366 px. */
#workspace .toolbar { display: grid; grid-template-columns: minmax(240px, .7fr) minmax(280px, 1.25fr) auto; align-items: center; padding: 10px 24px 8px; gap: 8px 22px; }
#workspace .toolbar-title { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; column-gap: 8px; }
#workspace .toolbar-title > .editor-context, #workspace .toolbar-title > .input-title { flex: 0 0 100%; }
#workspace .editor-context { padding: 0; gap: 10px; font-size: 9px; }
/* "Test editor" repeats what the breadcrumb and the page already say. */
#workspace .editor-context > span { display: none; }
#workspace .editor-context .btn-link { padding: 0; font-size: 12px; }
#workspace .input-title { padding: 2px 0; margin: 2px 0; font-size: 20px; line-height: 1.3; }
#workspace .file-row { gap: 4px 8px; flex-wrap: nowrap; min-width: 0; max-width: 100%; }
#workspace .file-name { padding: 0; font-size: 10px; overflow-wrap: anywhere; }
#workspace #test-file { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
#workspace #btn-move-folder { padding: 0; max-width: 100%; text-align: left; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: none; }
/* The project and environment are links to the project page; Move after them is a separate control. */
#workspace .test-placement { display: inline-flex; align-items: baseline; gap: 4px; min-width: 0; font-size: 12px; white-space: nowrap; }
#workspace .test-placement:empty { display: none; }
#workspace .test-placement .btn-link { padding: 0; font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; text-decoration: none; }
#workspace .test-placement .btn-link:hover { text-decoration: underline; }
#workspace .test-placement-sep { color: var(--muted); }
#workspace #test-attribution { flex: 1 1 120px; min-width: 0; font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default; }
#workspace #test-attribution::before { content: "·"; margin-right: 8px; color: var(--faint); }
#workspace .toolbar-actions { max-width: 390px; position: relative; }
/* "Unsaved changes" sits under the buttons without taking room in the header, so marking the test changed (choosing
   a retries option, say) never moves the fields beside it. */
#workspace #dirty { position: absolute; top: 100%; right: 0; margin-top: 2px; text-align: right; font-size: 11px; white-space: nowrap; }
/* Discard changes is part of that note, so it takes no room in the row of buttons either. */
#workspace #btn-discard { font-size: inherit; font-weight: 600; vertical-align: baseline; }
/* The test's description and its Starting URL: a small label over each field, or beside it where the header is one wide row. */
.test-purpose { display: grid; gap: 1px; min-width: 0; margin: 0; padding: 2px 0 2px 18px; border-left: 1px solid var(--border); }
/* Each field with its label beside it, the labels in one column, so three short rows stand where six did. */
.test-purpose-row { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; }
.test-purpose-row > label { flex: 0 0 104px; font-size: 11px; font-weight: 600; color: var(--muted); letter-spacing: .02em; white-space: nowrap; }
#workspace .test-purpose .input-desc { flex: 1 1 160px; width: auto; min-width: 0; margin: 0; padding: 4px 0; background: transparent; border: 0; border-radius: 0; border-bottom: 1px solid transparent; color: var(--muted); font-size: 12px; }
#workspace .test-purpose .input-desc:hover { border-bottom-color: var(--border); }
#workspace .test-start-note { flex-basis: 100%; margin: 0 0 2px; }
#workspace .test-purpose .input-desc:focus { border-color: var(--focus-ring); outline: none; }
#workspace .test-purpose .input-desc::placeholder { color: var(--placeholder); }
#workspace .test-purpose .input-desc[aria-invalid="true"] { border-color: var(--fail); }
.test-start-note { margin: 2px 0 0; font-size: 11px; line-height: 1.4; color: var(--muted); overflow-wrap: anywhere; }
.test-start-note.is-invalid { color: var(--fail-ink); }
/* How many times a failed run of this test starts again: one line beside its label, so the run panel keeps its room.
   Its choices show the range and the default, in the text colour so the choice reads clearly. The longer explanation
   is its description to a screen reader, and shows only while the ⓘ after the list is hovered or focused: never while
   the list is in use, where as the list's tooltip it drew over the open list (Priyank) and below it covered the run
   panel's tabs and report (Lovish). */
#workspace .test-retries-row { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 10px; position: relative; }
#workspace .test-retries-row > label { display: inline; flex: 0 0 104px; }
#workspace .test-purpose select { max-width: 100%; padding: 2px 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--muted); font-size: 12px; }
#workspace .test-purpose #test-retries { min-height: 26px; padding: 2px 8px; border-color: var(--border-strong); color: var(--text); font-size: 13px; }
#workspace .test-purpose select:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
#workspace .test-retries-row > .field-info { margin-left: -4px; }
/* The persona the test runs as, on the test beside Retries. It asks for little room, so it stays on Retries' line at a
   laptop's 1366 px (More settings goes under it when there is no room for both), then takes what is free for a long
   name. With no personas, its sentence keeps its own width and goes under Retries when there is no room beside it. */
#workspace .test-persona-field { flex: 1 1 140px; display: inline-flex; align-items: center; gap: 8px; min-width: 0; max-width: 230px; margin-left: 4px; }
#workspace .test-persona-field.is-none { flex: 0 1 auto; max-width: 100%; }
#workspace .test-persona-field > label { flex: none; font-size: 11px; font-weight: 600; color: var(--muted); letter-spacing: .02em; white-space: nowrap; }
#workspace .test-purpose #test-persona { flex: 0 1 auto; min-width: 0; min-height: 26px; max-width: 170px; padding: 2px 8px; border-color: var(--border-strong); color: var(--text); font-size: 13px; }
#workspace .test-persona-none { padding: 0; font-size: 12px; text-align: left; }
#workspace span.test-persona-none { color: var(--muted); cursor: default; }
.field-info { flex: none; display: inline-grid; place-items: center; width: 18px; height: 18px; padding: 0; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); color: var(--muted); font: italic 600 11px/1 Georgia, "Times New Roman", serif; cursor: help; }
.field-info:hover, .field-info:focus-visible { border-color: var(--accent); color: var(--accent-ink); }
.field-info:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.test-retries-help { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.test-retries-row:has(> .field-info:hover, > .field-info:focus):not(:has(> select:focus)) > .test-retries-help {
  top: calc(100% + 6px); left: 0; z-index: 30; width: max-content; max-width: min(340px, calc(100vw - 32px)); height: auto; margin: 0; padding: 8px 10px;
  overflow: visible; clip: auto; white-space: normal; border: 1px solid var(--border-strong); border-radius: 8px; background: var(--panel); color: var(--text);
  box-shadow: var(--shadow-md); font-size: 12px; line-height: 1.45; pointer-events: none;
}
#workspace .panes, #workspace.is-recording .panes { grid-template-columns: minmax(360px, 430px) minmax(0, 1fr); min-height: 0; padding: 10px 24px 22px; gap: 20px; align-items: stretch; overflow: hidden; }
#workspace .pane-steps { padding: 0; max-height: none; min-height: 0; overflow: hidden; background: var(--surface-muted); }
#workspace #test-fieldset { display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0; }
#workspace .pane-steps .pane-head { padding: 17px 18px; gap: 12px; background: var(--surface); flex: none; }
#workspace .pane-steps h2 { display: flex; align-items: center; gap: 7px; font-size: 15px; }
#workspace #step-count { display: inline-grid; place-items: center; min-width: 22px; height: 22px; margin: 0; padding: 0 5px; border-radius: 6px; background: var(--surface-hover); color: var(--muted); font-size: 11px; font-weight: 600; }
.step-list-hint { margin: 5px 0 0; font-size: 11px; color: var(--muted); }
#workspace #btn-add-step { font-size: 12px; min-height: 34px; padding: 7px 10px; }
#workspace #steps { min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-gutter: stable; padding: 14px 12px 18px 18px; }
#workspace .step-card { position: relative; border: 1px solid var(--border); border-radius: 9px; margin: 0; background: var(--surface); overflow: hidden; }
/* The place between two steps: the gap the cards already leave, made clickable.
   It draws the divider whether or not it can be used, so a read-only list keeps
   the same rhythm, and it never grows the list beyond that gap. */
#workspace .step-insert { display: flex; align-items: center; gap: 6px; width: 100%; height: 20px; padding: 0; margin: 0; border: 0; background: transparent; cursor: pointer; }
#workspace .step-insert::before, #workspace .step-insert::after { content: ""; flex: 1; height: 1px; background: var(--surface-active); }
#workspace .step-insert-plus { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 999px; border: 1px solid var(--accent-border); background: var(--surface); color: var(--accent); font-size: 14px; line-height: 1; font-weight: 600; }
#workspace .step-insert:hover:not(:disabled)::before, #workspace .step-insert:hover:not(:disabled)::after,
#workspace .step-insert:focus-visible::before, #workspace .step-insert:focus-visible::after { background: var(--accent-border); }
#workspace .step-insert:hover:not(:disabled) .step-insert-plus, #workspace .step-insert:focus-visible .step-insert-plus { border-color: var(--accent); background: var(--accent-fill); color: var(--on-fill); }
#workspace .step-insert:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; border-radius: 6px; }
#workspace .step-insert:disabled { cursor: default; }
#workspace .step-insert:disabled .step-insert-plus { visibility: hidden; }
#workspace .step-insert[aria-expanded="true"] .step-insert-plus { border-color: var(--accent); background: var(--accent-fill); color: var(--on-fill); }
/* What can be done at a place between steps, opened in the list under its +. */
#workspace .step-insert-menu { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 8px; padding: 8px; border: 1px solid var(--accent-border); border-radius: 8px; background: var(--accent-wash); }
#workspace .step-insert-item { min-height: 30px; padding: 4px 10px; border: 1px solid var(--border-strong); border-radius: 6px; background: var(--surface); color: var(--accent-ink); font: inherit; font-size: 12px; cursor: pointer; }
#workspace .step-insert-item:hover, #workspace .step-insert-item:focus-visible { border-color: var(--accent); background: var(--accent-soft); }
#workspace .step-insert-note { flex-basis: 100%; margin: 0; font-size: 12px; }
/* A breakpoint before a step: the steps running in the recorder's browser stop there. */
#workspace .step-breakpoint { flex: none; align-self: center; width: 22px; height: 22px; margin-left: 4px; padding: 0; border: 0; border-radius: 999px; background: transparent; color: var(--fail); font-size: 14px; line-height: 22px; cursor: pointer; }
#workspace .step-breakpoint:hover, #workspace .step-breakpoint:focus-visible { background: var(--fail-soft); }
#workspace .record-progress-tools .record-breakpoint { color: var(--faint); }
#workspace .record-progress-tools .record-breakpoint.is-on { color: var(--fail); border-color: var(--fail-border); }
.record-progress-step.has-breakpoint { box-shadow: inset 3px 0 0 var(--fail); }
#workspace .step-card:not(.step-collapsed) { border-color: var(--accent-border); box-shadow: 0 2px 7px var(--shadow-faint); }
#workspace .step-head { display: flex; flex-wrap: nowrap; padding: 0; border: 0; border-radius: 0; gap: 0; background: transparent; }
#workspace .step-select { display: grid; grid-template-columns: 28px minmax(0, 1fr) 14px; align-items: center; gap: 10px; flex: 1; min-width: 0; border: 0; background: transparent; color: var(--text); padding: 14px 13px; text-align: left; cursor: pointer; }
#workspace .step-select:hover { background: var(--bg); }
#workspace .step-select:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -3px; border-radius: 8px; }
#workspace .step-card:not(.step-collapsed) .step-head { background: var(--accent-soft); }
#workspace .step-head .step-index { width: 27px; height: 27px; border: 0; border-radius: 7px; background: var(--surface-hover); color: var(--muted); font-size: 12px; }
#workspace .step-card:not(.step-collapsed) .step-index { background: var(--accent-fill); color: var(--on-fill); }
.step-summary-copy { display: grid; gap: 4px; min-width: 0; }
.step-title { font-size: 13px; font-weight: 650; }
.step-title .step-soft { margin-left: 6px; padding: 1px 6px; border-radius: 999px; background: var(--warn-soft); color: var(--warn-ink); font-size: 10px; font-weight: 600; vertical-align: middle; }
.step-title .step-condition { margin-left: 6px; padding: 1px 6px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-ink); font-size: 10px; font-weight: 600; vertical-align: middle; }
#workspace .step-body .step-condition-help, #workspace .step-body .field-help { margin: 6px 0 0; font-size: 11px; line-height: 1.45; }
#workspace .step-head .step-desc { display: block; min-width: 0; padding: 0; margin: 0; order: 0; font-size: 11px; line-height: 1.5; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.step-chevron { font-size: 15px; color: var(--faint); }
.step-collapsed .step-chevron { transform: rotate(-90deg); }
#workspace .step-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 15px; border: 0; border-top: 1px solid var(--border); padding: 16px; margin: 0; min-width: 0; }
#workspace .step-fields { display: grid; grid-template-columns: minmax(0, 1fr); gap: 13px; min-width: 0; }
#workspace .step-body .field { min-width: 0; }
#workspace .step-body .span-2 { grid-column: auto; }
#workspace .step-body label { font-size: 11px; font-weight: 600; color: var(--muted); margin-bottom: 6px; }
#workspace .step-body input, #workspace .step-body select { width: 100%; min-width: 0; min-height: 38px; padding: 9px 10px; border: 1px solid var(--border-strong); border-radius: 6px; background: var(--surface); color: var(--text); font-size: 12px; }
#workspace .step-body input:focus-visible, #workspace .step-body select:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
#workspace .step-body:disabled input, #workspace .step-body:disabled select { color: var(--muted); background: var(--bg); }
/* An upload step's file: the stored files, and a button to upload a new one beside them. */
#workspace .step-body .upload-input { display: flex; flex-wrap: wrap; gap: 6px; align-items: stretch; min-width: 0; }
#workspace .step-body .upload-input > select { flex: 1 1 100%; width: auto; }
#workspace .step-body .upload-input > .btn { flex: 0 0 auto; }
/* The files of an upload, in the step editor and the recorder's upload dialog: each with its size, how far it has been sent, and a button to take it out. */
.upload-files { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: grid; gap: var(--space-1); }
.upload-file { display: flex; align-items: center; gap: var(--space-2); min-width: 0; padding: var(--space-1) var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-muted); font-size: 12px; }
.upload-file.is-failed { border-color: var(--fail); background: var(--fail-soft); }
.upload-file-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upload-file-size, .upload-file-status { flex: none; color: var(--muted); }
.upload-file.is-failed .upload-file-status { flex: 1 1 100%; color: var(--fail); white-space: normal; }
.upload-file { flex-wrap: wrap; }
.upload-file-progress { flex: 0 0 90px; height: 8px; }
.upload-file-remove { flex: none; min-height: 24px; padding: 0 8px; }
.step-no-fields { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
.step-advanced { border-top: 1px solid var(--border-subtle); padding-top: 13px; font-size: 12px; color: var(--muted); }
.step-advanced > summary { cursor: pointer; width: fit-content; }
.step-advanced[open] > summary { margin-bottom: 14px; }
/* Check text and Check image, added right after the step. */
.step-checks { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; border-top: 1px solid var(--border); padding-top: 12px; }
.step-checks-label { font-size: 12px; color: var(--muted); margin-right: 2px; }
/* Pick on screen beside a Verify image step's selector, with a line on what picking keeps. */
.step-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 6px; }
.step-pick .field-help { margin: 0; flex: 1; min-width: 200px; }
#workspace .step-tools { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin: 0; padding-top: 12px; border-top: 1px solid var(--border-subtle); }
#workspace .step-tools .btn-icon { width: 30px; height: 30px; min-width: 30px; min-height: 30px; border: 1px solid var(--border); background: var(--surface); font-size: 15px; }
#workspace .step-tools .btn-link { min-height: 30px; padding: 4px 7px; font-size: 11px; }
#workspace .step-head .step-delete { flex: none; min-height: 32px; margin-right: 8px; padding: 7px 8px; border: 0; border-radius: 5px; background: transparent; color: var(--fail-ink); font-size: 11px; }
#workspace .step-head .step-delete:hover:not(:disabled) { background: var(--fail-soft); color: var(--fail-ink); }
#workspace .step-head .step-delete:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
#workspace .record-after { display: block; width: 100%; padding: 10px 16px 13px; border-top: 1px solid var(--border-subtle); text-align: left; font-size: 11px; color: var(--accent); }
#workspace .step-collapsed .step-body, #workspace .step-collapsed .record-after { display: none; }
#workspace .step-status { flex: none; margin: 0 0 0 9px; }
#workspace .step-card.invalid, #workspace .step-card.run-failed { border-color: var(--fail-line); }
.step-empty { padding: 38px 20px; text-align: center; color: var(--muted); font-size: 13px; line-height: 1.7; }
.step-empty p { color: var(--muted); font-size: 12px; }
#workspace #test-validation { margin: 0; padding: 12px 18px; flex: none; font-size: 12px; }
#workspace #test-design { margin: 12px 18px 0; flex: none; }
#workspace #test-design-content { max-height: 220px; }
/* Focus mode (setFocusMode in app.js): the sidebar, the top bar and the test's details go, so the run's screen and the
   steps get the room; the test's name and Save, Run and Stop stay in one short row. */
#app-shell.focus-mode .app { grid-template-columns: minmax(0, 1fr); }
#app-shell.focus-mode .sidebar, #app-shell.focus-mode .app-header, #app-shell.focus-mode #nav-backdrop,
#workspace.focus-mode .test-purpose, #workspace.focus-mode .editor-context, #workspace.focus-mode .file-row, #workspace.focus-mode #test-attribution { display: none; }
#workspace.focus-mode .toolbar { grid-template-columns: minmax(0, 1fr) auto; padding: 6px 16px; }
#workspace.focus-mode .input-title { margin: 0; font-size: 17px; }
#workspace.focus-mode:not(.playback-expanded) .panes { grid-template-columns: minmax(280px, 26%) minmax(0, 1fr); padding: 6px 16px 14px; gap: 14px; }
.focus-toggle[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
/* With the details put away the actions have the row to themselves (Resume, Run and Stop side by side), and full
   screen, which puts away more still, has no use for the switch. */
#workspace.focus-mode .toolbar-actions { max-width: none; flex-wrap: nowrap; }
#workspace.playback-expanded .focus-toggle { display: none; }
/* Expand the existing panel, keeping the current run, draft and recorder intact. */
.expanded-only { display: none; }
.playback-expand { white-space: nowrap; }
#app-shell.playback-expanded .app { grid-template-columns: minmax(0, 1fr); }
#app-shell.playback-expanded .sidebar, #app-shell.playback-expanded .app-header, #app-shell.playback-expanded #nav-backdrop,
#workspace.playback-expanded .toolbar, #workspace.playback-expanded .toolbar-title, #workspace.playback-expanded .test-purpose,
#workspace.playback-expanded .toolbar-actions, #workspace.playback-expanded .pane-steps { display: none; }
#workspace.playback-expanded { overflow: hidden; }
#workspace.playback-expanded .panes { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); flex: 1; min-height: 0; padding: 0; gap: 0; overflow: hidden; }
#workspace.playback-expanded .pane-run { min-height: 0; height: 100%; border: 0; border-radius: 0; padding: 14px 20px; }
#workspace.playback-expanded .expanded-only { display: inline-block; }
#workspace.playback-expanded .playback-test-name { flex-basis: 100%; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
#workspace.playback-expanded #run-body { min-height: 0; }
#workspace.playback-expanded .run-split { display: grid; grid-template-columns: minmax(190px, 240px) minmax(0, 1fr); gap: 14px; }
#workspace.playback-expanded .run-steps { display: flex; flex-direction: column; gap: 6px; min-height: 0; padding: 0 6px 8px 0; overflow-y: auto; overflow-x: hidden; }
#workspace.playback-expanded .run-step { display: flex; align-items: center; min-height: 42px; gap: 8px; padding: 10px; font-size: 12px; }
#workspace.playback-expanded .run-step.selected { border-color: var(--accent); background: var(--accent-soft); }
#workspace.playback-expanded .run-step:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
#workspace.playback-expanded .run-step .time { display: block; }
#workspace.playback-expanded .viewer { display: flex; flex-direction: column; min-width: 0; }
#workspace.playback-expanded #viewer-img { flex: 1; min-height: 0; height: 0; width: 100%; object-fit: contain; }
#workspace.playback-expanded .playback-controls { position: sticky; top: 0; z-index: 1; flex: none; }
#workspace.playback-expanded .history { max-height: 75px; }
#workspace.playback-expanded .embedded-recorder { flex: 1; min-height: 0; overflow-y: auto; }
#workspace.playback-expanded .embedded-recorder > .pane-head { position: sticky; top: 0; z-index: 2; background: var(--surface); flex-wrap: wrap; }
#workspace.playback-expanded .record-screen img { max-width: 100%; max-height: calc(100dvh - 260px); width: auto; min-height: 0; object-fit: contain; }
@media (max-width: 760px) {
  #workspace.playback-expanded .pane-run { padding: 10px; }
  #workspace.playback-expanded .run-split { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  #workspace.playback-expanded .run-steps { flex-direction: row; max-height: 64px; overflow-x: auto; overflow-y: hidden; padding: 0 0 6px; }
  #workspace.playback-expanded .pane-head { padding: 8px 0; }
}
@media (max-width: 760px) {
  #workspace .panes, #workspace.is-recording .panes { padding: 10px 14px 20px; gap: 16px; }
  #workspace .toolbar { padding: 12px 18px 6px; }
  #workspace .step-body, #workspace .step-fields { grid-template-columns: minmax(0, 1fr); }
  #workspace .step-body input, #workspace .step-body select { font-size: 16px; }
  #workspace .toolbar-actions { padding: 9px 14px; gap: 7px; }
  #workspace .toolbar-actions .btn { min-height: 40px; padding: 8px 10px; font-size: 12px; }
  #workspace .step-head .step-delete { min-height: 44px; min-width: 54px; font-size: 12px; }
  /* A touch-sized place to tap between two steps, still only a few pixels taller than the gap it replaces. */
  #workspace .step-insert { height: 22px; }
  #workspace .step-insert-plus { width: 20px; height: 20px; font-size: 13px; }
  #workspace .step-tools .btn-icon, #workspace .step-tools .btn-link { min-width: 40px; min-height: 40px; }
  #workspace .record-step-tools button { min-width: 40px; min-height: 40px; }
  #workspace .test-purpose .input-desc { font-size: 14px; }
  #workspace .pane-run { padding: 12px; }
}

/* The screen owns the right panel. Supporting evidence has its own tabs,
   and scrolling the sequence never moves the browser or the save controls. */
#workspace:not(.playback-expanded) .panes { display: grid; grid-template-columns: minmax(300px, 32%) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); flex: 1; min-height: 0; padding: 8px 20px 18px; gap: 16px; overflow: hidden; }
#workspace .pane-run { padding: 12px; }
#workspace .pane-run > .pane-head { padding: 4px 4px 10px; gap: 8px; flex: none; }
#workspace .pane-run > .pane-head h2 { font-size: 14px; }
#workspace .pane-run > .pane-head .btn { min-height: 34px; padding: 7px 10px; font-size: 11px; }
#workspace .run-status { gap: 6px 10px; font-size: 11px; margin: 0; }
#workspace .run-status .btn-link, #workspace .run-status a { font-size: 11px; }
#workspace #btn-collapse-steps, #workspace #btn-expand-steps { font-size: 11px; white-space: nowrap; padding: 6px 0; }
#workspace .pane-steps .pane-head { padding: 12px; gap: 8px; }
/* A narrow steps panel puts its buttons on a line of their own rather than cutting off + Add step. */
#workspace .pane-steps .pane-head { flex-wrap: wrap; row-gap: 8px; }
#workspace .pane-steps .pane-head > div:first-child { flex: 1 1 150px; min-width: 0; }
#workspace .pane-steps h2 { white-space: nowrap; }
#workspace .steps-head-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-left: auto; }
#workspace .step-list-hint { font-size: 10px; }
#workspace #steps { padding: 10px; flex: 1; }
#workspace .step-select { padding: 10px; gap: 8px; }
#workspace .step-card { margin-bottom: 0; }
.editor-panel-tabs { display: flex; gap: 20px; flex: none; border-bottom: 1px solid var(--border); margin-bottom: 10px; }
#workspace .pane-head > .editor-panel-tabs { flex: 1; min-width: 200px; margin: 0; border: 0; gap: 16px; }
#app-shell:has(#workspace:not([hidden])) .app-header { min-height: 56px; }
.editor-panel-tabs button { white-space: nowrap; border: 0; border-bottom: 2px solid transparent; background: transparent; padding: 10px 2px; font-size: 12px; color: var(--muted); cursor: pointer; }
.editor-panel-tabs [aria-selected=true] { color: var(--accent-strong); border-color: var(--accent); font-weight: 600; }
.editor-panel-tabs button:focus-visible, .editor-view-switch button:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
#workspace .editor-panel-content { flex: 1; min-height: 0; min-width: 0; overflow-y: auto; overscroll-behavior: contain; }
#workspace #editor-screen { display: flex; flex-direction: column; overflow: hidden; }
#workspace #run-empty { flex: 1; min-height: 0; padding: 24px; font-size: 13px; }
#workspace #editor-screen .viewer { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; }
#workspace #viewer-img { flex: 1; min-height: 0; height: 0; width: 100%; object-fit: contain; }
#workspace #viewer-error { flex: 0 1 auto; max-height: 45%; min-height: min(7.5rem, 45%); overflow-y: auto; overscroll-behavior: contain; font-size: 12px; }
#workspace #viewer-error.error-only { flex: 0 1 auto; max-height: 100%; }
#workspace .playback-controls { flex: none; padding: 6px 10px; gap: 6px; }
#workspace #viewer-title { flex: 1; min-width: 0; font-size: 10px; }
#workspace #viewer-mode { font-size: 9px; white-space: nowrap; }
#workspace .playback-controls .btn-icon { width: 28px; height: 30px; flex: none; }
#workspace .record-tabs { flex: none; }
#workspace .browser-address { flex: none; display: flex; align-items: center; gap: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 7px 10px; }
#workspace .record-address-form { flex: 1; min-width: 0; display: flex; margin: 0; }
#workspace .record-address-form input { flex: 1; min-width: 0; height: 26px; padding: 0 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--text); text-overflow: ellipsis; }
#workspace .record-address-form input:focus { outline: 2px solid var(--focus-ring); outline-offset: -1px; }
#workspace .record-address-form input[aria-invalid="true"] { border-color: var(--fail); }
#workspace .record-history { flex: none; color: var(--muted); border: 1px solid var(--border); background: var(--surface); border-radius: 6px; min-width: 28px; min-height: 28px; }
#workspace .record-history:hover:not(:disabled) { color: var(--accent-strong); background: var(--accent-soft); }
#workspace #editor-details .run-report, #workspace #editor-details .log pre, #workspace #editor-history .history { max-height: none; overflow: visible; }
/* Run details and History take the panel's width and scroll only up and down: a long log line wraps inside the log
   instead of running past its dark box and widening the whole tab, and nothing in them is wider than the panel. */
#workspace #editor-details, #workspace #editor-history { overflow-x: hidden; }
#workspace #editor-details > *, #workspace #editor-history > *, #workspace #editor-details .run-report > * { min-width: 0; max-width: 100%; }
#workspace #editor-details .log pre { white-space: pre-wrap; overflow-wrap: anywhere; }
#workspace #editor-history .history-head { padding-top: 6px; }
.editor-view-switch { display: none; }

/* Captured steps use the left rail. Stop and the full live canvas remain on
   the right; review/add controls never sit below a growing list of steps. */
#record-sidebar { display: none; }
#workspace.is-recording #test-fieldset { display: none; }
#workspace.is-recording #record-sidebar { display: flex; flex-direction: column; flex: 1; min-height: 0; }
/* The whole test in one list: the steps before the captured ones, the captured steps, the steps after them.
   It is as tall as what it holds and scrolls as one when that is more than the pane, so no part of it keeps
   a fixed height and leaves a gap; the add-to-draft controls sit at the bottom of the pane. */
#workspace .record-flow { flex: 0 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; padding: 6px 8px 10px; }
#workspace #record-sidebar > .record-apply { margin-top: auto; }
#workspace #record-steps { flex: none; min-height: 0; max-height: none; overflow: visible; padding: 2px 0; margin: 0; }
#workspace .record-captured { margin: 6px 0; padding: 4px 6px; border: 1px dashed var(--accent-border); border-radius: 8px; background: var(--surface); }
#workspace .record-captured[hidden] { display: none; }
#workspace .record-captured-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; padding: 4px 4px 2px; }
#workspace .record-captured-head h3 { margin: 0; font-size: 12px; color: var(--text); }
#workspace .record-captured-head .step-list-hint { margin: 0; }
#workspace #record-steps > li.muted { padding: 4px; font-size: 12px; }
#workspace .record-step { padding: 10px 6px; font-size: 12px; }
#workspace .record-step-body { min-width: 0; }
#workspace .record-step-detail { overflow-wrap: anywhere; }
/* Drop must read as actionable while recording: the default muted icon looked disabled. */
#workspace .record-drop { color: var(--fail-ink); border: 1px solid var(--fail-border); background: var(--surface); border-radius: 6px; min-width: 28px; min-height: 28px; }
#workspace .record-drop:hover:not(:disabled) { color: var(--fail-ink); background: var(--fail-soft); border-color: var(--fail-border); }
#workspace .record-drop:disabled { opacity: .35; }
/* Run, move, edit and drop sit on one line beside each captured step (Abhishek Sharma). A rail too narrow for that line
   and a readable description beside it puts the line under the description, never on several lines. The test's own
   steps do the same (.record-progress-tools). */
#workspace .record-step { flex-wrap: wrap; }
#workspace .record-step > .record-step-body { flex: 1 1 140px; }
#workspace .record-step-tools { flex: none; display: flex; flex-wrap: nowrap; gap: 4px; align-items: center; margin-left: auto; }
#workspace .record-step-tools > button { display: inline-flex; align-items: center; justify-content: center; padding: 0; }
#workspace .record-pointer-move { min-width: 28px; min-height: 28px; }
#workspace .record-move, #workspace .record-edit { color: var(--accent-strong); border: 1px solid var(--border); background: var(--surface); border-radius: 6px; min-width: 28px; min-height: 28px; }
#workspace .record-move:hover:not(:disabled), #workspace .record-edit:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent-border); }
#workspace .record-edit:disabled, #workspace .record-move:disabled { opacity: .35; cursor: default; text-decoration: none; }
/* A step that typed a value offers a value that changes on every run, right under what it typed. */
#workspace .record-dynamic { display: inline-block; margin-top: 4px; min-height: 24px; padding: 0; font-size: 11px; }
#workspace .record-dynamic:disabled { opacity: .35; cursor: default; text-decoration: none; }
#workspace .record-apply { flex: none; padding: 12px; gap: 8px; background: var(--surface); }
#workspace .record-apply select { min-width: 0; flex: 1; width: 100%; }
#workspace .record-apply .checkbox-row { font-size: 11px; }
/* A disabled option looks disabled, and its reason sits on its own line beneath it, visible without hovering. */
#workspace .record-apply .checkbox-row:has(> input:disabled) { color: var(--muted); cursor: not-allowed; }
#workspace .record-apply .checkbox-row > input:disabled { cursor: not-allowed; }
#workspace .record-apply-help { flex: 1 1 100%; margin: -4px 0 0; color: var(--muted); font-size: 11px; line-height: 1.4; overflow-wrap: anywhere; }
#workspace .record-apply-note { flex: 1 1 100%; margin: 0; padding: 8px 10px; border-radius: 6px; background: var(--warn-soft); color: var(--warn-ink); font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; }
#workspace .record-tidy { flex: none; font-size: 11px; margin: 0; border-radius: 0; padding: 8px 12px; max-height: 100px; overflow-y: auto; }
#workspace .embedded-recorder { overflow: hidden; }
#workspace .embedded-recorder > .pane-head { flex: none; padding: 4px 0 10px; gap: 6px; flex-wrap: wrap; }
#workspace .embedded-recorder h2 { flex: 1; font-size: 14px; }
#workspace .embedded-recorder .pane-head .btn { padding: 7px 10px; font-size: 11px; }
/* With a floor under the screen the column can outgrow the pane; scroll it
   rather than cutting off Stop recording or the add-to-draft controls. */
#workspace #record-live { overflow-x: hidden; overflow-y: auto; }
#workspace .record-status { flex: none; gap: 8px; padding: 8px 0; margin: 0; font-size: 11px; }
#workspace .record-status .btn { font-size: 11px; padding: 6px 8px; }
/* The controls read in order and wrap from the left, rather than spreading across each line when the pane is narrow. */
#workspace .record-status { justify-content: flex-start; align-items: center; }
#workspace .record-status .btn { margin-left: 0; }
/* Every control in the row is the same height, its words and icons centred, so the row reads as one line. A hidden
   control stays hidden, and Add to draft on the screen is left to phone widths (below). */
#workspace .record-status > .btn:not([hidden]):not(.record-apply-inline), #workspace .record-status > select:not([hidden]), #workspace .record-status > details:not([hidden]) > summary.btn { box-sizing: border-box; height: 30px; min-height: 30px; display: inline-flex; align-items: center; line-height: 1; }
#workspace .record-status > select { padding: 0 8px; font-size: 11px; }
/* The checks (text, notification, image, screenshot, two-factor code) are one Check menu in the row, so Back and
   Forward, Add action, Stop and Save stay together on one line; its items are a plain list. */
#workspace .record-check-menu { flex: none; }
#workspace .record-check-menu .dropdown-panel { left: 0; right: auto; min-width: 230px; padding: 6px; }
#workspace .record-status .record-check-panel #record-secret-actions { display: contents; }
#workspace .record-status .record-check-panel .btn { display: flex; width: 100%; justify-content: flex-start; min-height: 34px; margin: 0; padding: 7px 12px; border: 0; border-radius: 7px; background: none; box-shadow: none; font-size: 13px; font-weight: 500; color: var(--text); text-align: left; white-space: nowrap; }
#workspace .record-status .record-check-panel .btn:hover { background: var(--surface-sunken); }
#workspace .record-status .record-check-panel .btn:focus-visible { outline-offset: -2px; }
/* The recorded browser is the thing being watched: it takes the room left in
   the pane, but never shrinks below a size you can work in. On a short window
   the floor follows the viewport so the controls below it stay reachable. */
#workspace .record-screen, #workspace.is-reviewing .record-screen { display: flex; align-items: center; justify-content: center; flex: 1; min-height: 0; }
/* On a wide window the screen keeps a workable floor; the stacked phone layout
   sizes itself and must not be pushed past the bottom of the page. */
@media (min-width: 761px) {
  #workspace .record-screen, #workspace.is-reviewing .record-screen { min-height: min(264px, 41vh); }
}
#workspace .record-screen img, #workspace.playback-expanded .record-screen img { display: block; width: 100%; height: 100%; min-height: 0; max-height: 100%; max-width: 100%; object-fit: contain; }
#workspace.is-reviewing .browser-address { display: flex; }
/* Full screen while recording: the test's steps keep a readable column; the screen is centred in the rest anyway. */
#workspace.playback-expanded.is-recording .panes { grid-template-columns: minmax(300px, 24%) minmax(0, 1fr); gap: 12px; }
#workspace.playback-expanded.is-recording .pane-steps { display: flex; }
/* After "Add to draft" the draft steps return, while the recorded browser stays usable until Save. */
#workspace.is-recording.recording-applied #test-fieldset { display: flex; }
#workspace.is-recording.recording-applied #record-sidebar { display: none; }
.record-apply-inline { display: none; }
/* What the recording has to say never pushes the screen and its controls out of view: a long message scrolls within itself. */
#record-error { max-height: 6.5em; overflow-y: auto; overscroll-behavior: contain; }
/* Steps that ran with a fallback selector: one folded line; opened, a list that scrolls within itself. The run panel shows the same. */
.record-fallbacks { flex: none; }
.record-fallbacks[hidden] { display: none; }
.fallback-notice { margin: 0 0 8px; border: 1px solid var(--warn-border); border-radius: 6px; background: var(--warn-soft); color: var(--warn-ink); font-size: 12px; }
.fallback-notice > summary { padding: 6px 10px; cursor: pointer; font-weight: 600; }
.fallback-notice > summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.fallback-notice-help { margin: 0 10px 6px; }
.fallback-notice-list { margin: 0; padding: 0 10px 8px; list-style: none; max-height: 13em; overflow-y: auto; overscroll-behavior: contain; display: grid; gap: 4px; }
.fallback-notice-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
.fallback-notice-step { font-weight: 600; }
.fallback-notice-what { flex: 1 1 18em; min-width: 0; overflow-wrap: anywhere; }
.fallback-notice code { font-size: 11px; padding: 0 3px; border-radius: 3px; background: var(--surface-translucent); }
.fallback-notice-done { color: var(--pass-ink); }
.run-status .fallback-notice { flex: 1 1 100%; margin: 4px 0 0; }
/* A kept browser closed to free its run slot says why on a line of its own, and what to do now. */
.run-status .run-slot-freed { flex: 1 1 100%; color: var(--text); overflow-wrap: anywhere; }
#workspace .record-screen-note { flex: none; margin: 0 0 8px; padding: 8px 10px; border-radius: 6px; background: var(--warn-soft); color: var(--warn-ink); font-size: 12px; overflow-wrap: anywhere; }
/* Cancel while a click picks an element, beside the words that say what to click. */
#workspace .record-screen-note .record-pick-cancel { margin-left: 6px; padding: 2px 10px; vertical-align: baseline; }
#workspace .record-screen.picking { cursor: cell; outline: 3px dashed var(--warn); outline-offset: -3px; }
/* What a pick takes, outlined on the recorded screen: the element under the pointer while picking, then the one
   picked while its dialog is open, with its tag and size above it (inside it at the top of the screen). */
.record-pick-box { position: absolute; z-index: 2; box-sizing: border-box; border: 2px solid var(--focus-ring); border-radius: 2px; background: var(--focus-halo); box-shadow: 0 0 0 1px var(--surface); pointer-events: none; }
.record-pick-box[hidden] { display: none; }
.record-pick-label { position: absolute; left: -2px; bottom: 100%; margin-bottom: 2px; padding: 1px 6px; border-radius: 4px; background: var(--accent-fill); color: var(--on-fill); font: 600 11px/16px var(--mono); white-space: nowrap; }
.record-pick-box.label-inside .record-pick-label { top: 0; bottom: auto; left: 0; margin: 2px; }
/* The pick's dialog says what was picked and shows that part of the screen with the element outlined. */
.pick-summary { margin: 10px 0; }
.pick-summary[hidden] { display: none; }
.pick-summary-text { margin: 0 0 6px; font-size: 13px; overflow-wrap: anywhere; }
.pick-summary-what { font-family: var(--mono); }
.pick-preview { position: relative; max-width: 100%; overflow: hidden; border: 1px solid var(--border-strong); border-radius: 6px; background: var(--surface-active); }
.pick-preview img { position: absolute; max-width: none; height: auto; user-select: none; }
.pick-preview-box { position: absolute; box-sizing: border-box; border: 2px solid var(--focus-ring); background: var(--focus-halo); }
/* An image check pointed at something that is not an image offers the images in it or near it, and a text check. */
.image-help { margin: 8px 0 0; }
.image-help[hidden] { display: none; }
.image-help-title { margin: 8px 0 4px; font-size: 13px; overflow-wrap: anywhere; }
.image-help-choices { display: flex; flex-wrap: wrap; gap: 6px; }
.image-help-choice { max-width: 100%; text-align: left; overflow-wrap: anywhere; }
/* A tooltip check reads the tooltip of the element picked, and says what it shows beside the button that reads it again. */
.tooltip-read { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0; }
.tooltip-read p { margin: 0; font-size: 13px; overflow-wrap: anywhere; }
/* A Check image step's saved picture: the picture as recorded, on a checkered ground so its own background shows, and Remove. */
.saved-picture-frame { max-width: 100%; max-height: 160px; overflow: auto; border: 1px solid var(--border-strong); border-radius: 6px; padding: 4px; box-sizing: border-box; background: repeating-conic-gradient(var(--surface-active) 0% 25%, var(--surface) 0% 50%) 0 0 / 12px 12px; }
.saved-picture-frame img { display: block; max-width: 100%; height: auto; }
.saved-picture-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; font-size: 12px; }
.saved-picture > p { margin: 0; font-size: 12px; }
/* The page's own dialog, over the recorded screen it belongs to. On a short
   screen it scrolls inside the screen rather than widening the page. */
.record-dialog { position: absolute; inset: 0; z-index: 3; display: flex; align-items: flex-start; justify-content: center; padding: 16px; box-sizing: border-box; background: var(--overlay); overflow-y: auto; overscroll-behavior: contain; cursor: default; }
.record-dialog[hidden] { display: none; }
.record-dialog-box { box-sizing: border-box; width: min(420px, 100%); margin: 0; padding: 16px; display: flex; flex-direction: column; gap: 10px; border: 1px solid var(--border-strong); border-radius: 10px; background: var(--surface); color: var(--ink); box-shadow: 0 12px 32px var(--shadow-strong); }
.record-dialog-box h3 { margin: 0; font-size: 14px; }
.record-dialog-message { margin: 0; max-height: 9em; overflow-y: auto; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 13px; line-height: 1.45; }
.record-dialog-message[hidden], .record-dialog-answer[hidden], .record-dialog-note[hidden], .record-dialog-box .checkbox-row[hidden], .record-dialog-actions .btn[hidden] { display: none; }
.record-dialog-answer { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.record-dialog-answer input { box-sizing: border-box; width: 100%; min-width: 0; padding: 8px; border: 1px solid var(--border-strong); border-radius: 6px; font: inherit; font-size: 14px; }
.record-dialog-answer input:focus { outline: 2px solid var(--focus-ring); outline-offset: -1px; }
.record-dialog-note { margin: 0; padding: 6px 8px; border-radius: 6px; background: var(--warn-soft); color: var(--warn-ink); font-size: 12px; }
.record-dialog-actions { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 8px; }
.record-dialog-actions .btn { min-height: 34px; }
/* A native dropdown's own options, listed over the recorded screen where its list would open. */
.record-select { position: absolute; z-index: 4; box-sizing: border-box; max-width: calc(100% - 8px); display: flex; flex-direction: column; border: 1px solid var(--border-firm); border-radius: 6px; background: var(--surface); color: var(--ink); box-shadow: 0 10px 28px var(--shadow-strong); cursor: default; font-size: 13px; }
.record-select-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 4px 0; outline: none; }
.record-select-list:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring); }
.record-select-group { padding: 6px 10px 2px; color: var(--muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; }
.record-select-option { padding: 5px 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
[role="group"] > .record-select-option { padding-left: 20px; }
.record-select-option[aria-selected="true"] { font-weight: 600; }
.record-select-option.is-active, .record-select-option:hover { background: var(--accent-soft); }
.record-select-option[aria-disabled="true"] { color: var(--muted); cursor: default; background: none; }
.record-select.is-multiple .record-select-option::before { content: "☐"; display: inline-block; width: 1.4em; }
.record-select.is-multiple .record-select-option[aria-selected="true"]::before { content: "☑"; }
.record-select-actions { flex: none; display: flex; justify-content: flex-end; gap: 6px; padding: 6px 8px; border-top: 1px solid var(--border); }
@media (max-width: 760px) {
  .record-select-option { padding-top: 10px; padding-bottom: 10px; }
  .record-dialog { padding: 8px; }
  /* A phone zooms into a field typed in below 16px. */
  .record-dialog-answer input { font-size: 16px; }
  .record-dialog-actions .btn { min-height: 44px; flex: 1 1 auto; }
}
/* The test's own steps in the recorder, each with how it went in the recording
   browser, and the execution pointer at the next step to run. */
.record-progress-steps { list-style: none; margin: 0; padding: 0; font-size: 12px; }
.record-progress-steps[hidden] { display: none; }
.record-progress-step { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px; padding: 6px 4px; border-radius: 6px; }
.record-progress-step .step-index { flex: none; min-width: 20px; text-align: center; color: var(--muted); font-size: 11px; line-height: 18px; }
.record-progress-step .record-step-body { flex: 1 1 150px; min-width: 0; }
.record-progress-step .record-step-action { overflow-wrap: anywhere; }
.record-progress-step .record-step-detail { color: var(--muted); overflow-wrap: anywhere; }
.record-progress-mark { flex: none; min-width: 16px; text-align: center; font-weight: 700; line-height: 18px; }
.record-progress-step.is-running, .record-progress-step.is-waiting { background: var(--accent-soft); }
.record-progress-step.is-passed .record-progress-mark { color: var(--pass); }
.record-progress-step.is-failed .record-progress-mark { color: var(--fail-ink); }
.record-progress-step.is-soft-failed .record-progress-mark { color: var(--soft-fail-ink); }
.record-progress-step.is-pending, .record-progress-step.is-skipped { color: var(--muted); }
.record-progress-step.is-running .record-progress-mark { color: var(--accent-strong); }
/* The execution pointer: the next step to run. */
.record-progress-step.is-next { box-shadow: inset 3px 0 0 var(--accent); background: var(--accent-wash); }
.record-progress-step.is-next.is-failed { box-shadow: inset 3px 0 0 var(--fail-strong); background: var(--fail-wash); }
.record-next-tag { display: inline-block; margin-top: 3px; padding: 1px 7px; border-radius: 999px; background: var(--accent-soft-hover); color: var(--accent-ink); font-size: 10px; font-weight: 600; }
.record-progress-end .record-step-action { font-weight: 600; color: var(--text); }
/* The step's controls on one line, beside it or, in a narrow rail, under it, as a captured step's are. */
.record-progress-tools { flex: none; display: flex; flex-wrap: nowrap; gap: 4px; align-items: center; margin-left: auto; }
#workspace .record-progress-tools .btn-icon, #workspace .record-progress-tools .btn-link { display: inline-flex; align-items: center; justify-content: center; min-width: 28px; min-height: 28px; padding: 0 5px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--accent-strong); font-size: 11px; }
#workspace .record-progress-tools button:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent-border); }
#workspace .record-progress-tools button:disabled { opacity: .4; cursor: default; }
/* What the tester can do about the step the session waits at after it failed. */
.record-failure { margin-top: 6px; padding: 8px; border: 1px solid var(--fail-border); border-radius: 6px; background: var(--surface); }
.record-failure-message { margin: 0 0 6px; color: var(--fail-ink); font-size: 12px; line-height: 1.45; overflow-wrap: anywhere; white-space: pre-wrap; }
.record-failure-actions { display: flex; flex-wrap: wrap; gap: 6px; }
#workspace .record-failure-actions .btn { min-height: 30px; padding: 4px 9px; font-size: 11px; }
#workspace .record-failure-actions .record-retry { border-color: var(--accent-fill-strong); background: var(--accent-fill-strong); color: var(--on-fill); }
#workspace .record-failure-actions .record-retry:hover { background: var(--accent-fill-strong); }
/* How far the test has run, read out as it changes. */
#workspace #record-progress-summary { color: var(--text-2); }
/* Add action and the recorder's own step editor reuse the step editor's fields. */
.record-add-form .step-fields, .record-test-edit .step-fields { display: grid; gap: 10px; margin: 10px 0; }
.record-add-form .field label, .record-test-edit .field label { display: block; font-size: 12px; font-weight: 600; margin-bottom: 4px; }
.record-add-form .field-head, .record-test-edit .field-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.record-random-field { display: flex; flex-direction: column; }
.record-random-field > .random-insert { align-self: flex-end; margin-top: -2px; }
/* Run from here sits beside Record from here at the foot of a step. */
#workspace .record-from { display: flex; flex-wrap: wrap; border-top: 1px solid var(--border-subtle); }
#workspace .record-from .record-after { width: auto; flex: 1 1 auto; border-top: 0; }
#workspace .record-from .run-from { padding: 10px 16px 13px; font-size: 11px; color: var(--accent); }
#workspace .step-collapsed .record-from { display: none; }
#workspace .step-head .step-fix { flex: none; align-self: center; margin-right: 4px; min-height: 30px; padding: 4px 8px; font-size: 11px; color: var(--fail-ink); border-color: var(--fail-border); background: var(--surface); }
@media (max-width: 760px) {
  /* Touch-sized controls for the step list's pointer, edit and failure actions. */
  #workspace .record-progress-tools .btn-icon, #workspace .record-progress-tools .btn-link, #workspace .record-failure-actions .btn { min-width: 40px; min-height: 40px; }
}
/* At phone widths the captured-step list is a separate pane, so the screen offers Add to draft itself. */
@media (max-width: 900px) {
  #workspace .record-status > .record-apply-inline:not([hidden]) { box-sizing: border-box; height: 30px; min-height: 30px; display: inline-flex; align-items: center; line-height: 1; }
}


@media (max-width: 1200px) {
  #workspace .toolbar { grid-template-columns: minmax(0, 1fr) auto; gap: 8px 14px; padding: 10px 20px; }
  #workspace .test-purpose { grid-column: 1 / -1; grid-row: 2; display: flex; flex-wrap: wrap; align-items: flex-start; gap: 2px 28px; border: 0; padding: 0; }
  #workspace .test-purpose-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0 12px; flex: 1 1 300px; }
  #workspace .test-purpose-row > label { white-space: nowrap; flex: none; }
  #workspace .test-purpose .input-desc { flex: 1 1 160px; width: auto; margin: 0; }
  #workspace .test-start-note { flex-basis: 100%; margin: 0 0 2px; }
}
/* At phone/tablet widths, choose a pane instead of stacking two workspaces.
   Both stay mounted, preserving draft fields and the recording connection. */
@media (max-width: 900px) {
  #workspace .toolbar { padding: 8px 14px; gap: 6px; }
  #workspace .input-title { font-size: 18px; margin: 3px 0; }
  #workspace .toolbar-title { grid-column: 1 / -1; }
  #workspace .toolbar-actions { grid-column: 1 / -1; grid-row: 3; max-width: none; padding: 0; justify-content: flex-start; }
  /* Here the view switch is right under the buttons and the test's fields right above them, so the note has a line of
     its own under the buttons rather than lying over the Run button or the view switch (focus mode keeps one row). */
  #workspace:not(.focus-mode) #dirty { position: static; order: 1; flex-basis: 100%; margin: -3px 0 0; text-align: left; font-size: 10px; }
  #workspace .test-purpose { margin: 0; }
  #workspace .test-purpose .input-desc { font-size: 12px; }
  #workspace .editor-view-switch { display: flex; flex: none; gap: 6px; padding: 2px 14px 6px; }
  .editor-view-switch button { flex: 1; border: 1px solid var(--border); background: var(--surface); border-radius: 6px; padding: 9px; font-size: 12px; color: var(--muted); cursor: pointer; }
  .editor-view-switch [aria-pressed=true] { background: var(--accent-soft); border-color: var(--accent-border); color: var(--accent-strong); font-weight: 600; }
  #workspace:not(.playback-expanded) .panes, #workspace.playback-expanded.is-recording .panes { grid-template-columns: minmax(0, 1fr); padding: 4px 12px 12px; gap: 0; }
  #workspace:not(.playback-expanded):not(.show-browser) .pane-run, #workspace.playback-expanded.is-recording:not(.show-browser) .pane-run { display: none; }
  #workspace.show-browser .pane-steps { display: none; }
  /* The Browser screen view is for watching the test run: the fields that describe and set up the test (description,
     Starting URL, retries) and who changed it wait in the Test steps view, so the run and its failure fit on the screen. */
  #workspace.show-browser .test-purpose, #workspace.show-browser #test-attribution { display: none; }
  #workspace .pane-run { order: 0; }
  #workspace.playback-expanded:not(.is-recording) .editor-view-switch { display: none; }
  #workspace.playback-expanded.is-recording.show-browser .pane-steps { display: none; }
  #workspace.playback-expanded.is-recording:not(.show-browser) .pane-steps { display: flex; }
  #workspace .playback-controls { flex-wrap: wrap; }
  #workspace #viewer-title { flex-basis: 60%; }
  #workspace .playback-controls .btn-icon { width: 34px; height: 34px; }
}

/* Short windows: the recorder's own chrome (title row, status row, address bar)
   costs about 200px on a 640px-tall screen, which leaves the recorded browser
   too small to work in. Tighten that chrome so the screen keeps the room. */
@media (max-height: 760px) {
  #workspace .embedded-recorder > .pane-head { padding: 0 0 4px; gap: 4px; }
  #workspace .embedded-recorder > .pane-head h2 { font-size: 12px; }
  #workspace .embedded-recorder > .pane-head .btn { padding: 3px 7px; font-size: 10px; }
  #workspace .record-status { padding: 2px 0; gap: 4px; row-gap: 3px; }
  #workspace .record-status .btn { padding: 3px 6px; }
  #workspace .record-status .badge { padding: 2px 6px; }
  #workspace .browser-address { padding: 5px 8px; }
  /* While recording on a short window the editor's own description of the test
     (breadcrumb, file name, attribution, description) is not what the tester is
     watching; the recorded browser is. They come back when recording ends. */
  #workspace.is-recording .editor-context,
  #workspace.is-recording .file-row,
  #workspace.is-recording #test-attribution,
  #workspace.is-recording .test-purpose { display: none; }
}

/* Validate notification: the messages the recorded page showed lately, newest first. */
.notification-choices { display: grid; gap: 6px; max-height: 240px; overflow-y: auto; margin: 8px 0 12px; }
.notification-choice { display: flex; align-items: baseline; gap: 8px; font-size: 13px; line-height: 1.4; padding: 6px 8px; border: 1px solid var(--border-strong); border-radius: 6px; cursor: pointer; }
.notification-choice input { flex: none; }
.notification-choice span { overflow-wrap: anywhere; }
.notification-choice small { flex: none; white-space: nowrap; }

/* A field that takes one entry per line, such as fallback selectors. */
.field-lines { width: 100%; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; resize: vertical; }

/* The code editor of a script step (code-editor.js): line numbers, coloured text behind a transparent textarea. */
.code-editor { display: grid; gap: 6px; }
.code-toolbar, .code-find-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.code-find { min-width: 0; flex: 1 1 140px; font-size: 12px; }
.code-insert { font-size: 12px; max-width: 180px; }
.code-body { display: grid; grid-template-columns: auto 1fr; border: 1px solid var(--border); border-radius: 6px; background: var(--surface-muted); max-height: 360px; min-height: 120px; overflow: hidden; }
.code-gutter { padding: 8px 6px; text-align: right; color: var(--faint); background: var(--surface-sunken); font: 12px/18px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; overflow: hidden; user-select: none; }
.code-gutter span { display: block; }
.code-gutter .code-line-error { color: var(--on-fill); background: var(--fail-strong); border-radius: 3px; padding: 0 3px; }
.code-stack { position: relative; min-width: 0; }
.code-colours, .code-input { margin: 0; padding: 8px 10px; font: 12px/18px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: pre; tab-size: 2; border: 0; box-sizing: border-box; width: 100%; height: 100%; min-height: 120px; max-height: 360px; overflow: auto; }
.code-colours { position: absolute; inset: 0; pointer-events: none; color: var(--ink); }
.code-input { position: relative; resize: vertical; background: transparent; color: transparent; caret-color: var(--ink); outline: none; }
.code-input::placeholder { color: var(--placeholder); }
.code-input:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring); }
.code-keyword { color: var(--violet-ink); } .code-string { color: var(--pass); } .code-number, .code-literal { color: var(--brand-orange-ink); }
.code-comment { color: var(--muted); font-style: italic; } .code-variable { color: var(--accent); font-weight: 600; }
.code-status { margin: 0; font-size: 12px; overflow-wrap: anywhere; white-space: pre-wrap; }
.code-status-ok { color: var(--pass-ink); } .code-status-error { color: var(--fail-ink); }
.code-toolbar .btn, .code-find-row .btn { padding: 4px 10px; font-size: 12px; min-height: 0; }

/* Steps inside If, Repeat, For each and groups sit indented by how deep they are; a group folds its steps away. */
#steps > .step-card.step-in-block { margin-left: calc(var(--flow-depth, 0) * 18px); border-left: 3px solid var(--border-firm); }
.step-fold { flex: none; }

/* Test data and parameters (test-data.js): a table of rows the test runs once each, and the Run dialog's choices. */
.project-dialog.test-data-modal { width: min(980px, calc(100vw - 32px)); }
.test-data-dialog { display: grid; gap: 10px; min-width: 0; }
.test-data-dialog h3 { margin: 6px 0 0; font-size: 14px; }
.data-tools { display: flex; flex-wrap: wrap; gap: 6px; }
.data-table-wrap { overflow: auto; max-height: 46dvh; border: 1px solid var(--border); border-radius: 8px; }
.data-table { border-collapse: collapse; font-size: 12px; min-width: 100%; }
.data-table th, .data-table td { padding: 3px 4px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
.data-table thead th { position: sticky; top: 0; background: var(--surface-sunken); z-index: 1; font-weight: 600; }
.data-table input:not([type]), .data-table input[type="text"] { width: 100%; min-width: 110px; font-size: 12px; padding: 4px 6px; }
.data-table input.invalid { border-color: var(--fail); box-shadow: 0 0 0 1px var(--fail); }
.data-column { display: flex; gap: 2px; align-items: center; }
.data-row-number { color: var(--muted); text-align: right; }
.data-row-off td:not(:first-child) { opacity: .55; }
.data-row-actions { display: inline-flex; gap: 2px; }
.data-param-table { width: 100%; }
.data-check { display: grid; gap: 4px; }
.data-check p { margin: 0; font-size: 12px; overflow-wrap: anywhere; }
.data-problem { color: var(--fail-ink); font-weight: 600; }
.data-warning { color: var(--warn-ink); }
.data-import-note { margin: 0; font-size: 12px; overflow-wrap: anywhere; }
.data-run-params, .data-run-rows { display: grid; gap: 8px; border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px 12px; margin: 0; min-width: 0; }
.data-run-params label { display: grid; gap: 2px; }
.data-run-rows .checkbox-row { flex-wrap: wrap; }
.data-run-rows .checkbox-row input:not([type="radio"]):not([type="checkbox"]) { width: 9em; max-width: 100%; }
.run-steps .run-data-summary { color: inherit; font-size: 11px; }
.run-steps .run-data-row.failed { color: var(--fail-ink); }
.run-steps .run-data-row.passed { color: var(--pass-ink); }
@media (max-width: 600px) {
  .data-table input:not([type]) { min-width: 80px; }
}
.data-column-rule { display: flex; gap: 6px; align-items: center; margin-top: 3px; font-weight: 400; }
.data-column-rule select { font-size: 11px; padding: 2px 4px; max-width: 120px; }
.data-column-rule .checkbox-row { font-size: 11px; gap: 3px; white-space: nowrap; }
.data-table input.invalid-cell { border-color: var(--fail); background: var(--fail-wash); }
.data-row-invalid .data-row-number { color: var(--fail-ink); font-weight: 700; }
.run-steps .run-data-row { cursor: pointer; }
.run-steps .run-data-row:hover, .run-steps .run-data-row:focus-visible { text-decoration: underline; }

/* Record steps on/off: a switch, green with its knob to the right while what is done on the page is recorded, amber
   with the knob to the left while it is not, and the word On or Off beside it, so the state reads without colour. */
.record-toggle { display: inline-flex; align-items: center; gap: 4px; border-color: var(--pass-border); color: var(--pass-ink); background: var(--pass-soft); }
.record-toggle.is-off { border-color: var(--warn-border); color: var(--warn-ink); background: var(--warn-soft); }
.record-switch { position: relative; flex: none; width: 24px; height: 14px; margin-right: 2px; border-radius: 999px; background: currentColor; }
.record-switch::after { content: ""; position: absolute; top: 2px; left: 12px; width: 10px; height: 10px; border-radius: 50%; background: var(--surface); transition: left .15s var(--ease); }
.record-toggle.is-off .record-switch::after { left: 2px; }
/* Reload says in words whether it is recorded as a step. A phone keeps the address its room: there it is ↻, and its
   tooltip says whether it is recorded. */
#workspace .record-reload { width: auto; padding: 0 8px; font-size: 11px; white-space: nowrap; }
@media (max-width: 760px) {
  #workspace .record-reload { padding: 0; }
  #workspace .record-reload > span { display: none; }
}
/* A waiting run's Back, Forward and Reload sit before its address, which takes the rest of the row and is cut short there. */
#workspace .run-page-moves { flex: none; display: inline-flex; gap: 4px; }
#workspace .run-page-moves[hidden] { display: none; }
#workspace #playback-url { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Where people look for an image check: under the Check menu's items, and on a captured click on an image. */
#workspace .record-check-hint { max-width: 260px; margin: 6px 0 0; padding: 8px 12px 4px; border-top: 1px solid var(--border); font-size: 11px; line-height: 1.45; color: var(--muted); white-space: normal; }
#workspace .record-check-image { display: inline-block; margin: 4px 0 0; min-height: 24px; padding: 0; font-size: 11px; }
#workspace .record-dynamic + .record-check-image { margin-left: 12px; }
/* The recorder's Edit test step dialog: the action, then its fields, and whether to run again from the step. */
.record-test-edit > label { display: block; font-size: 12px; font-weight: 600; margin: 8px 0 4px; }
.record-test-edit > select { width: 100%; }
.record-test-edit > label.check-label { display: flex; gap: 6px; align-items: flex-start; font-weight: 400; margin-top: 12px; }
#workspace .record-progress-tools .record-test-delete { color: var(--fail-ink); }
/* Selected text in a value field opens a menu right under it (offerValueFromSelection): a function, an existing value, or a new variable or parameter. */
.value-selection-menu { position: fixed; z-index: 1200; display: flex; flex-direction: column; min-width: 260px; max-width: min(360px, calc(100vw - 16px)); padding: 4px 0; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-raised); box-shadow: 0 8px 24px var(--shadow-medium); }
.value-selection-menu .value-selection-item { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; padding: 8px 14px; border: 0; border-radius: 0; background: transparent; color: var(--ink); text-align: left; cursor: pointer; font: inherit; }
.value-selection-menu .value-selection-item + .value-selection-item { border-top: 1px solid var(--border-subtle); }
.value-selection-menu .value-selection-item:hover, .value-selection-menu .value-selection-item:focus-visible { background: var(--surface-hover); outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.value-selection-title { font-size: 13px; font-weight: 600; }
.value-selection-about { font-size: 12px; color: var(--muted); }
.value-name-list { width: 100%; margin: 8px 0; }
.value-name-new { display: flex; flex-wrap: wrap; gap: 8px; }
#record-page-width { width: auto; max-width: 130px; padding: 2px 6px; font-size: 12px; }

/* More settings beside Retries: the test's time limit and browser width, in a panel that opens over the page. */
#workspace .test-more-settings { display: inline-block; margin-left: 8px; vertical-align: middle; }
#workspace .test-more-settings > summary { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
#workspace .test-more-panel { display: grid; gap: 12px; width: 260px; padding: 12px; }
#workspace .test-more-panel .test-purpose-row { display: block; }
#workspace .test-more-panel .test-purpose-row > label { display: block; margin-bottom: 4px; }
#workspace .test-more-panel select { width: 100%; }
/* In the panel each setting says what it does under it, so nothing floats over the others. */
#workspace .test-more-help { margin: 4px 0 0; font-size: 11px; line-height: 1.4; color: var(--muted); }
/* A run that keeps its browser (src/runHold.ts): one line with its actions, so the run's screen keeps its room; what it means unfolds below. */
#workspace .run-held-box { margin: 2px 0; padding: 5px 10px; font-size: 12px; line-height: 1.35; }
#workspace .run-held-box .run-held-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
#workspace .run-held-box .run-held-title { flex: 1 1 320px; min-width: 0; font-weight: 600; }
#workspace .run-held-box .run-held-left { font-weight: 400; color: var(--muted); }
#workspace .run-held-box .run-held-actions { flex: none; margin-top: 0; }
#workspace .run-held-box .run-held-actions .btn { min-height: 28px; padding: 4px 10px; }
#workspace .run-held-box .run-held-why { flex: none; padding: 2px 0; font-size: 11px; white-space: nowrap; }
#workspace .run-held-box .run-held-explain { margin: 4px 0 2px; font-size: 11px; }
#workspace .run-held-box.run-held-paused { border-color: var(--accent); }
.badge.paused { background: var(--accent-soft); color: var(--accent); }
/* The failure under the screen folds to one line while the run waits at it, or while the screen is made larger. */
#workspace #viewer-error { position: relative; }
#workspace #viewer-error > .error-title { padding-right: 96px; }
#workspace #viewer-error > .error-fold { position: absolute; top: 9px; right: 12px; font-size: 11px; white-space: nowrap; }
#workspace #viewer-error.error-folded { flex: none; min-height: 0; max-height: none; overflow: hidden; margin: 6px 10px; padding-top: 7px; padding-bottom: 7px; }
#workspace #viewer-error.error-folded > :not(.error-title):not(.error-fold):not(.error-summary) { display: none; }
#workspace #viewer-error.error-folded > .error-title { margin-bottom: 2px; }
#workspace #viewer-error.error-folded > .error-summary { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Larger screen: full screen with the run's step list and its notes folded away, so the screen takes the room. */
#workspace .screen-large-toggle { flex: none; white-space: nowrap; font-size: 11px; }
#workspace.playback-expanded.screen-large .run-split { grid-template-columns: minmax(0, 1fr); }
#workspace.playback-expanded.screen-large .run-steps, #workspace.screen-large .run-status .run-origin, #workspace.screen-large .run-status .fallback-notice { display: none; }
/* Run from here on every step card, folded or not. The card's actions keep together, under the step's name when the list is narrow. */
#workspace .step-head { flex-wrap: wrap; }
#workspace .step-head > .step-select { flex: 1 1 120px; }
#workspace .step-head > .step-actions { display: flex; flex: none; align-items: center; margin-left: auto; }
#workspace .step-head .step-run-from { flex: none; align-self: center; padding: 6px 6px; border: 0; background: transparent; color: var(--accent); font-size: 11px; white-space: nowrap; }
#workspace .step-head .step-run-from:disabled { color: var(--muted); }
/* A step action that waits while the test runs reads as unavailable but stays focusable, so its reason can be read. */
#workspace #steps [data-run-change][aria-disabled="true"] { color: var(--muted); cursor: not-allowed; }
#workspace #steps .step-head .step-delete[aria-disabled="true"]:hover { color: var(--muted); background: transparent; }
/* A waiting run's page is its person's to use: a click reaches it, and a dropdown's options are listed over it. */
#workspace .viewer:has(> img.run-screen-usable) { position: relative; }
#workspace .viewer img.run-screen-usable { cursor: pointer; outline: 2px solid var(--accent-soft); outline-offset: -2px; }
/* Pause beside Stop, and Stop run's own Pause in full screen. While the run goes they take the place of Run, which waits for it to end. */
#workspace .toolbar-actions #btn-pause, #workspace #btn-pause-expanded { white-space: nowrap; }
#workspace .toolbar-actions:has(#btn-pause:not([hidden])) #btn-run { display: none; }
/* Resume beside Run: the last run carries on from its step. */
#workspace .toolbar-actions .btn-resume { white-space: nowrap; }
