/* BAND-002352 (UI-10): the shared component library. One implementation of every building block
   the stations use; the matching behaviour is in js/ui/*.js. Buttons, badges and the inline error
   text (.err) live in app.css next to the base controls; everything here is new or consolidated:
   panel, definition list, inline message, empty state, skeleton, busy spinner, toast, confirm
   dialog, date-time field and upload dropzone. Rules: docs/architecture/components.md. */

/* ---- Panel: a surface nested in a card (previews, status, slots, analytics, recipes). ------- */
.panel {
  min-width: 0;
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-3-5);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-relaxed);
  overflow-wrap: anywhere;
}
.panel:first-child { margin-top: 0; }
.panel > h3:first-child, .panel > h4:first-child { margin-top: 0; }
.panel-raised { background: var(--color-surface); box-shadow: var(--shadow-xs); }
.panel-quiet { border-style: dashed; border-color: var(--color-divider-strong); box-shadow: none; }
.panel[data-tone="info"] { border-color: var(--color-info-border); background: var(--color-info-subtle); }
.panel[data-tone="success"] { border-color: var(--color-success-border); background: var(--color-success-subtle); }
.panel[data-tone="warning"] { border-color: var(--color-warning-border); background: var(--color-warning-subtle); }
.panel[data-tone="danger"] { border-color: var(--color-danger-border); background: var(--color-danger-subtle); }

/* ---- Definition list: "Label: value" rows (js/ui/fields.js). ------------------------------- */
.definition-list {
  display: grid;
  gap: var(--space-1-5);
  margin: 0;
  font-variant-numeric: tabular-nums;
}
.definition-row {
  display: grid;
  grid-template-columns: minmax(120px, max-content) minmax(0, 1fr);
  gap: var(--space-1) var(--space-3);
  align-items: baseline;
  min-width: 0;
}
.definition-row > dt { color: var(--color-text-muted); font-weight: var(--font-weight-medium); }
.definition-row > dd { margin: 0; min-width: 0; color: var(--color-text); overflow-wrap: anywhere; }
.definition-row[hidden] { display: none; }
@media (width < 600px) {
  .definition-row { grid-template-columns: minmax(0, 1fr); gap: 0; }
}

/* ---- Inline message: the one error / confirmation line of a form or panel. ------------------ */
.inline-message {
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-danger-border);
  border-radius: var(--radius-sm);
  background: var(--color-danger-subtle);
  color: var(--color-danger);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.inline-message[data-tone="success"] { border-color: var(--color-success-border); background: var(--color-success-subtle); color: var(--color-success); }
.inline-message[data-tone="info"] { border-color: var(--color-info-border); background: var(--color-info-subtle); color: var(--color-info); }
.inline-message[data-tone="warning"] { border-color: var(--color-warning-border); background: var(--color-warning-subtle); color: var(--color-warning); }
.inline-message:empty { display: none; }

/* ---- Empty state. ------------------------------------------------------------------------- */
.empty-state {
  display: grid;
  gap: var(--space-1);
  justify-items: start;
  padding: var(--space-4);
  border: 1px dashed var(--color-divider-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}
.empty-state-title { margin: 0; color: var(--color-text); font-weight: var(--font-weight-semibold); }
.empty-state-hint { margin: 0; }

/* ---- Loading: skeleton lines inside a container with aria-busy="true". -------------------- */
.skeleton { display: grid; gap: var(--space-2-5); padding: var(--space-1) 0; }
.skeleton-line {
  height: 12px;
  border-radius: var(--radius-sm);
  background: var(--color-surface-3);
  animation: productionstudio-pulse var(--motion-duration-loop) ease-in-out infinite;
}
.skeleton-line:nth-child(3n + 2) { width: 82%; }
.skeleton-line:nth-child(3n) { width: 64%; }
@keyframes productionstudio-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- Busy button: a spinner in front of the label while its action runs. ----------------- */
button.is-busy { cursor: progress; }
button.is-busy::before {
  content: "";
  width: 12px;
  height: 12px;
  margin-right: var(--space-2);
  border: 2px solid currentcolor;
  border-right-color: transparent;
  border-radius: var(--radius-pill);
  animation: productionstudio-spin var(--motion-duration-loop) linear infinite;
  flex-shrink: 0;
}
@keyframes productionstudio-spin { to { transform: rotate(360deg); } }

/* ---- Toasts: one polite live region, bottom right (bottom, full width on a phone). --------- */
.toast-region {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-toast);
  display: grid;
  gap: var(--space-2);
  width: min(380px, calc(100vw - 32px));
  pointer-events: none;
}
.toast {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2);
  align-items: start;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border: 1px solid var(--color-divider);
  border-left: 4px solid var(--color-info-border);
  border-radius: var(--radius-md);
  background: var(--color-overlay);
  color: var(--color-text);
  box-shadow: var(--shadow-md);
  font-size: var(--font-size-md);
  line-height: var(--line-height-normal);
  pointer-events: auto;
  animation: productionstudio-toast-in var(--motion-duration-long) var(--motion-easing-emphasized);
  font-variant-numeric: tabular-nums;
}
.toast[data-tone="success"] { border-left-color: var(--color-success-border); }
.toast[data-tone="error"] { border-left-color: var(--color-danger-border); }
.toast-text { margin: 0; overflow-wrap: anywhere; }
.toast-title { display: block; font-weight: var(--font-weight-semibold); }
.toast[data-tone="success"] .toast-title { color: var(--color-success); }
.toast[data-tone="error"] .toast-title { color: var(--color-danger); }
.toast .toast-close:enabled { min-width: 24px; min-height: 24px; padding: 0 var(--space-1-5); }
@keyframes productionstudio-toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
@media (width < 600px) {
  .toast-region { right: var(--space-4); bottom: var(--space-4); }
}

/* ---- Confirm dialog (native <dialog>, js/ui/dialog.js). ---------------------------------- */
.dialog {
  width: min(440px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
  background: var(--color-overlay);
  color: var(--color-text);
  box-shadow: var(--shadow-lg);
}
.dialog::backdrop { background: var(--color-scrim); }
.dialog-form { display: grid; gap: var(--space-3); padding: var(--space-6); }
.dialog-title { margin: 0; }
.dialog-body { margin: 0; color: var(--color-text-muted); font-size: var(--font-size-md); line-height: var(--line-height-relaxed); }
.dialog-subject { margin: 0; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); background: var(--color-surface-3); font-weight: var(--font-weight-semibold); overflow-wrap: anywhere; }
.dialog-subject:empty { display: none; }
.dialog-actions { justify-content: flex-end; margin-top: var(--space-2); }

/* ---- Date-time field (js/ui/datetime.js). ------------------------------------------------- */
.field-hint {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-normal);
  font-variant-numeric: tabular-nums;
}
.field-hint[data-state="valid"] { color: var(--color-success); }
.field-hint[data-state="invalid"] { color: var(--color-danger); }
input[aria-invalid="true"] { border-color: var(--color-danger-border); }
input[data-datetime] { font-variant-numeric: tabular-nums; }

/* ---- Upload dropzone (js/ui/dropzone.js). ------------------------------------------------- */
.dropzone {
  position: relative;
  margin: 0;
  display: grid;
  gap: var(--space-1-5);
  justify-items: center;
  padding: var(--space-6) var(--space-4);
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  color: var(--color-text-muted);
  text-align: center;
  cursor: pointer;
  transition: background var(--motion-duration-short) var(--motion-easing-standard), border-color var(--motion-duration-short) var(--motion-easing-standard);
}
.dropzone:hover, .dropzone[data-dragging="true"] { border-color: var(--color-accent); background: var(--color-accent-subtle); }
.dropzone:focus-within { border-color: var(--color-focus); box-shadow: var(--shadow-focus-halo); }
.dropzone[data-disabled="true"] { cursor: not-allowed; opacity: 0.7; }
.dropzone-title { margin: 0; color: var(--color-text); font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); }
.dropzone-limits { margin: 0; font-size: var(--font-size-xs); font-variant-numeric: tabular-nums; }
.dropzone-file { margin: 0; color: var(--color-text); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.dropzone-file:empty { display: none; }
.dropzone-choose { color: var(--color-accent); font-weight: var(--font-weight-semibold); text-decoration-line: underline; text-underline-offset: 3px; }
.dropzone input[type=file] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
}
.upload-progress { display: grid; gap: var(--space-1-5); margin-top: var(--space-3); }
.upload-progress[hidden] { display: none; }
.upload-progress-head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); font-size: var(--font-size-sm); }
.upload-progress-value { font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; }
.upload-progress progress {
  width: 100%;
  height: 8px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-surface-3);
  overflow: hidden;
  accent-color: var(--color-accent);
  appearance: none;
}
.upload-progress progress::-webkit-progress-bar { background: var(--color-surface-3); border-radius: var(--radius-pill); }
.upload-progress progress::-webkit-progress-value { background: var(--color-accent); border-radius: var(--radius-pill); }
.upload-progress progress::-moz-progress-bar { background: var(--color-accent); }
.upload-progress progress:indeterminate {
  background-color: var(--color-surface-3);
  background-image: linear-gradient(90deg, transparent, var(--color-accent), transparent);
  background-size: 40% 100%;
  background-repeat: no-repeat;
  animation: productionstudio-indeterminate var(--motion-duration-loop) ease-in-out infinite;
}
.upload-progress progress:indeterminate::-webkit-progress-bar { background: transparent; }
@keyframes productionstudio-indeterminate {
  from { background-position: -40% 0; }
  to { background-position: 140% 0; }
}

/* Reduced motion: no spinner rotation, shimmer or toast slide (transitions are off globally). */
@media (prefers-reduced-motion: reduce) {
  .skeleton-line, button.is-busy::before, .toast, .upload-progress progress:indeterminate { animation: none; }
}

/* ---- Choice: a radio with its label is a selectable pill (targets, visibility). ----------- */
label:has(> input[type=radio]) {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-1-5) var(--space-3);
  border: 1px solid var(--color-divider-strong);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  transition: background var(--motion-duration-short) var(--motion-easing-standard), border-color var(--motion-duration-short) var(--motion-easing-standard);
}
label:has(> input[type=radio]:hover:enabled) { border-color: var(--color-border); }
label:has(> input[type=radio]:checked) { border-color: var(--color-accent); background: var(--color-selected); color: var(--color-accent); }
label:has(> input[type=radio]:disabled) { cursor: not-allowed; color: var(--color-text-muted); background: var(--color-surface-2); }
label:has(> input[type=radio]:focus-visible) { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
label:has(> input[type=radio]) > input[type=radio] { margin: 0; }

/* ---- Picker: a searchable combobox with a listbox popup (js/ui/picker.js, BAND-002355). ------
   It replaces every field that used to ask for an internal id (plan, copy draft, publication). */
.picker { position: relative; min-width: 0; }
.picker-control { position: relative; }
.picker-control input[role="combobox"] { padding-right: var(--space-10); text-overflow: ellipsis; }
.picker.is-open .picker-control input[role="combobox"] { border-color: var(--color-accent); box-shadow: var(--shadow-focus-halo); }
/* With keyboard focus the field draws the brand's ring alone (css/accessibility.css), open or not. */
.picker.is-open .picker-control input[role="combobox"]:focus-visible { box-shadow: none; }
.picker-toggle,
.picker-toggle:hover:not(:disabled) {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: var(--space-10);
  min-height: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
}
.picker-toggle::before {
  content: "";
  width: 8px;
  height: 8px;
  margin-top: calc(var(--space-1) * -1);
  border-right: 2px solid currentcolor;
  border-bottom: 2px solid currentcolor;
  transform: rotate(45deg);
  transition: transform var(--motion-duration-medium) var(--motion-easing-standard);
}
.picker.is-open .picker-toggle::before { margin-top: var(--space-1); transform: rotate(225deg); }
.picker-control input[role="combobox"]:disabled + .picker-toggle { cursor: not-allowed; }
.picker-popup {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  right: 0;
  z-index: var(--z-dropdown);
  max-height: min(340px, 60vh);
  overflow-y: auto;
  padding: var(--space-1);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-overlay);
  box-shadow: var(--shadow-md);
}
.picker-popup[hidden] { display: none; }
.picker-list { display: grid; gap: var(--space-0-5); margin: 0; padding: 0; list-style: none; }
.picker-list[hidden] { display: none; }
.picker-option {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-0-5) var(--space-2);
  align-items: center;
  padding: var(--space-2) var(--space-2-5);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  cursor: pointer;
}
.picker-option:hover, .picker-option.is-active { background: var(--color-accent-subtle); }
.picker-option.is-active { outline: 1px solid var(--color-accent); outline-offset: -1px; }
.picker-option-label { min-width: 0; font-size: var(--font-size-md); font-weight: var(--font-weight-medium); overflow-wrap: anywhere; }
.picker-option[aria-selected="true"] .picker-option-label { color: var(--color-accent); font-weight: var(--font-weight-semibold); }
.picker-option-badge { justify-self: end; }
.picker-option-detail { grid-column: 1 / -1; color: var(--color-text-muted); font-size: var(--font-size-sm); }
.picker-note { margin: 0; padding: var(--space-2) var(--space-2-5); color: var(--color-text-muted); font-size: var(--font-size-sm); }
.picker-note[hidden] { display: none; }
