# DeployView

> A deploy run as ordered steps with status, live durations, expandable ANSI logs that follow the output, and retry for failed steps.

Source: https://docs.nasaqui.com/components/deploy-view

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/deploy-view.json
```

Shows one deploy or pipeline run. The header has the title, meta (commit, branch, who), an overall status badge,
the total duration and a progress bar. Under it, each step has a status icon that differs by shape (not just
colour), the step name, its command, and a duration that counts up while it runs. A step opens to show its logs
(ANSI colours allowed) which follow the newest line while it runs, and a failed step shows its error and a Retry
button. Presentational: you update `steps` as the pipeline advances and handle `onRetry` and `onCancel`.

## When to use

- Deploys, CI runs, migrations, installs: any ordered list of steps with output.

## When not to use

- Free-form output: use [Terminal](https://docs.nasaqui.com/components/terminal).
- A searchable stream: use [LogViewer](https://docs.nasaqui.com/components/log-viewer).
- A user-facing checklist: use a stepper or `CheckoutSteps`.

## Import

```tsx
import { DeployView } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"
```

## Quick start

```tsx
import { DeployView } from "@fadymondy/nasaq/web";

export function Deploy() {
  return (
    <DeployView
      title="Deploy api to production"
      meta="main · 4f2a91c"
      steps={[
        { id: "install", name: "Install", command: "pnpm install", status: "success", durationMs: 8200 },
        { id: "build", name: "Build", command: "pnpm build", status: "running", startedAt: Date.now() - 4000, logs: "compiling..." },
        { id: "ship", name: "Release", status: "pending" },
      ]}
      onRetry={async (id) => {}}
    />
  );
}
```

## Anatomy

```
DeployView      data-slot="deploy-view"          <section>
├─ header       data-slot="deploy-view-header"   title, meta, status badge, duration, cancel, progress
└─ steps        data-slot="deploy-view-steps"    <ol>
   └─ step      data-slot="deploy-step"          <li> Collapsible: icon, name, command, duration, chevron
      ├─ error  (Alert)                          when failed
      ├─ logs   data-slot="deploy-step-logs"     ANSI text, follows the tail while running
      └─ retry  (Button)                         when failed and onRetry is set
```

## API

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `steps` | `DeployStep[]` | required | `{ id, name, command?, status, startedAt?, durationMs?, logs?, error? }`. |
| `title?` | `ReactNode` | "Deploy" / "النشر" | What is being deployed. |
| `meta?` | `ReactNode` | none | Commit, branch, author. |
| `status?` | `DeployStatus` | derived | `pending running success failed skipped cancelled`. |
| `onCancel?` | `() => Promise<DeployResult> \| DeployResult` | none | Shows Cancel while running. |
| `onRetry?` | `(stepId) => Promise<{ error? } \| void>` | none | Shows Retry on failed steps. Resolve `{ error }` to keep it failed with a message. |
| `defaultExpanded?` | `string[]` | failed and running | Step ids open at the start. |
| `maxLogLines?` | `number` | `500` | Lines kept per step. |
| `logHeight?` | `string` | `"14rem"` | Height of a step's log. |
| `labels?` | `Partial<DeployViewLabels>` | built-in en/ar | Translations. |

Helpers: `deriveStatus`, `stepDuration`, `totalDuration`, `formatDuration`, `tailLines`, `completedCount`.

## Examples

### Retry

```tsx
<DeployView steps={steps} onRetry={async (id) => { const r = await api.retry(id); return r.ok ? undefined : { error: r.message }; }} />
```

## Accessibility

| Key | Action |
| --- | --- |
| `Tab` | Each step trigger, then its buttons |
| `Enter` / `Space` | Open or close a step |

- Each step trigger is a button with `aria-expanded` and a name that includes the status text.
- Status is text and shape, never colour alone. The overall status is a badge with text.
- The step list is an ordered list. Running durations update once a second, not through a live region.

## RTL & i18n

- Commands and logs are `dir="ltr"` inside Arabic pages; step names, status text and buttons follow the page.
- The chevron mirrors. Durations use Latin digits with translated units (`1m 04s` / `1د 04ث`).
- Built-in Arabic strings; override with `labels`.

## Styling & tokens

- Status colours: `text-nq-success-text`, `-danger-text`, `-warning-text`, `-info-text`, `text-muted-foreground`. Logs on `bg-nq-surface-soft`.
- Slots: `deploy-view`, `deploy-view-header`, `deploy-view-steps`, `deploy-step`, `deploy-step-logs`. `data-status` on each step.

## Do / Don't

- **Do** send `startedAt` for running steps so the duration is accurate after a refresh.
- **Do** return `{ error }` from `onRetry` instead of throwing.
- **Don't** put secrets in `logs`; mask them at the source.
- **Don't** reorder steps while running.

## Related

- [Terminal](https://docs.nasaqui.com/components/terminal) · [LogViewer](https://docs.nasaqui.com/components/log-viewer) · [Progress](https://docs.nasaqui.com/components/progress) · [Collapsible](https://docs.nasaqui.com/components/collapsible)

## Lab

https://docs.nasaqui.com/?path=/docs/components-server-tools-deploy-view--docs

## Code

### React

```tsx
import { DeployView } from "@fadymondy/nasaq/web";

export function Deploy() {
  return (
    <DeployView
      title="Deploy api to production"
      meta="main · 4f2a91c"
      steps={[
        { id: "install", name: "Install", command: "pnpm install", status: "success", durationMs: 8200 },
        { id: "build", name: "Build", command: "pnpm build", status: "running", startedAt: Date.now() - 4000, logs: "compiling..." },
        { id: "ship", name: "Release", status: "pending" },
      ]}
      onRetry={async (id) => {}}
    />
  );
}
```

### shadcn

```tsx
import { DeployView } from "@/components/ui/deploy-view";

export function Deploy() {
  return (
    <DeployView
      title="Deploy api to production"
      meta="main · 4f2a91c"
      steps={[
        { id: "install", name: "Install", command: "pnpm install", status: "success", durationMs: 8200 },
        { id: "build", name: "Build", command: "pnpm build", status: "running", startedAt: Date.now() - 4000, logs: "compiling..." },
        { id: "ship", name: "Release", status: "pending" },
      ]}
      onRetry={async (id) => {}}
    />
  );
}
```

### Vue

```vue
<script setup lang="ts">
import { NqDeployView, type DeployStep } from "@fadymondy/nasaq/vue";
import { ref } from "vue";

const steps = ref<DeployStep[]>([
  { id: "install", name: "Install dependencies", command: "pnpm install --frozen-lockfile", status: "success", durationMs: 8200, logs: "Lockfile is up to date\nPackages: +412" },
  { id: "build", name: "Build", command: "pnpm build", status: "running", startedAt: Date.now() - 4000, logs: "\u001b[32m✓\u001b[0m compiling...\n" },
  { id: "ship", name: "Ship to production", command: "pnpm deploy --prod", status: "pending" },
]);

const retry = async (id: string) => {
  steps.value = steps.value.map((s) => (s.id === id ? { ...s, status: "running", startedAt: Date.now(), error: undefined } : s));
};
</script>

<template>
  <NqDeployView title="Deploy api to production" :steps="steps" :on-retry="retry">
    <template #meta>main · 4f2a91c</template>
  </NqDeployView>
</template>
```

### Blade

```blade
@php
    $esc = chr(27);
    $steps = [
        ['id' => 'install', 'name' => 'Install dependencies', 'command' => 'pnpm install --frozen-lockfile', 'status' => 'success', 'durationMs' => 8400, 'logs' => "Lockfile is up to date\nPackages: +214\nDone in 8.4s"],
        ['id' => 'build', 'name' => 'Build', 'command' => 'pnpm build', 'status' => 'failed', 'durationMs' => 21300, 'error' => 'The build exited with code 1.', 'logs' => "{$esc}[32mcompiled{$esc}[0m 214 modules\n{$esc}[31merror{$esc}[0m src/app.ts: Type 'string' is not assignable to type 'number'"],
        ['id' => 'ship', 'name' => 'Ship to production', 'command' => 'pnpm deploy', 'status' => 'pending'],
    ];
@endphp
<x-nq::deploy-view title="Deploy api to production" can-retry :steps="$steps"
    x-on:retry="$event.detail.wait(Promise.resolve())"
    x-on:cancel="$event.detail.wait(Promise.resolve())">
    main · 4f2a91c
</x-nq::deploy-view>
```

### HTML + Alpine

```html
<section data-slot="deploy-view" data-status="failed" aria-label="Deploy api to production" x-data="nqDeployView(JSON.parse('{\u0022units\u0022:{\u0022ms\u0022:\u0022ms\u0022,\u0022s\u0022:\u0022s\u0022,\u0022m\u0022:\u0022m\u0022,\u0022h\u0022:\u0022h\u0022},\u0022genericError\u0022:\u0022Could not retry. Try again.\u0022,\u0022steps\u0022:[{\u0022id\u0022:\u0022install\u0022,\u0022status\u0022:\u0022success\u0022,\u0022startedAt\u0022:null,\u0022durationMs\u0022:8400},{\u0022id\u0022:\u0022build\u0022,\u0022status\u0022:\u0022failed\u0022,\u0022startedAt\u0022:null,\u0022durationMs\u0022:21300},{\u0022id\u0022:\u0022ship\u0022,\u0022status\u0022:\u0022pending\u0022,\u0022startedAt\u0022:null,\u0022durationMs\u0022:null}]}'))"
    x-on:retry="$event.detail.wait(Promise.resolve())" x-on:cancel="$event.detail.wait(Promise.resolve())" class="flex min-w-0 flex-col overflow-hidden rounded-card border border-border bg-card text-start">
    <header class="flex flex-col gap-3 border-b border-border p-4">
        <div class="flex flex-wrap items-start justify-between gap-3">
            <div class="flex min-w-0 flex-col gap-1">
                <div class="flex flex-wrap items-center gap-2">
                    <h3 class="text-h3 text-foreground">Deploy api to production</h3>
                    <span data-slot="badge"     class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border px-1.5 text-caption font-medium [&_svg]:size-3 border-nq-danger/40 bg-nq-danger-soft text-nq-danger-text"><svg aria-hidden="true" class="size-3 text-nq-danger-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>                        Failed</span>
                </div>
                <div class="text-body-sm text-muted-foreground">main · 4f2a91c</div>            </div>
            <div class="flex items-center gap-3">
                <span class="text-body-sm text-muted-foreground">
                    Duration <bdi dir="ltr" data-deploy-total class="font-mono text-foreground tabular-nums">30s</bdi>
                </span>
                            </div>
        </div>
        <div data-slot="progress" data-tone="danger" role="progressbar"  aria-labelledby="nq-progress-61260073-label"     aria-valuemin="0" aria-valuemax="100"  aria-valuenow="33.333333333333"     aria-valuetext="33%" data-progressing
    class="flex w-full flex-col gap-1.5">
            <div data-slot="progress-head" class="flex items-baseline justify-between gap-3 text-body-sm">
            <span id="nq-progress-61260073-label" class="text-label text-foreground">1 of 3 steps</span>                    </div>
        <div data-slot="progress-track" data-progressing class="relative block w-full overflow-hidden rounded-full bg-nq-surface-soft h-1">
        <div data-slot="progress-indicator" data-progressing style="inset-inline-start:0;width:33.3333%"
            class="block h-full rounded-full transition-[width] duration-300 ease-nq motion-reduce:transition-none bg-nq-danger"></div>
    </div>
</div>
    </header>
    <ol aria-label="Deploy steps" class="m-0 flex list-none flex-col p-0">
                                <li data-slot="deploy-step" data-status="success" class="border-b border-border last:border-b-0">
                <div data-slot="collapsible" x-data="nqCollapsible(false)" x-modelable="open" x-id="['nq-collapsible']"
    :data-open="open ? '' : undefined" :data-closed="open ? undefined : ''"
     data-closed     >
    <div class="flex items-center gap-1 pe-2">
                        <button data-slot="collapsible-trigger"
     type="button"                         x-bind:aria-controls="$id(&#039;nq-collapsible&#039;, &#039;panel&#039;)" x-bind:data-panel-open="open ? &#039;&#039; : undefined" x-on:click="toggle()" :aria-expanded="open" aria-label="Step 1: Install dependencies, Succeeded" class="inline-flex shrink-0 select-none items-center whitespace-nowrap border border-transparent font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 text-foreground hover:bg-nq-hover group/step h-auto min-w-0 flex-1 justify-start gap-3 rounded-none px-4 py-3 text-start font-normal">
        <svg aria-hidden="true" class="size-4 shrink-0 text-muted-foreground transition-transform duration-150 group-data-[panel-open]/step:rotate-90 rtl:-scale-x-100 rtl:group-data-[panel-open]/step:-rotate-90" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m9 18 6-6-6-6"/>
</svg>                            <svg aria-hidden="true" class="size-4 shrink-0 text-nq-success-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m9 12 2 2 4-4"/>
</svg>                            <span class="flex min-w-0 flex-1 flex-col gap-0.5">
                                <span class="truncate text-label text-foreground">Install dependencies</span>
                                <bdi dir="ltr" class="truncate text-start font-mono text-caption text-muted-foreground">pnpm install --frozen-lockfile</bdi>                            </span>
                            <span class="hidden shrink-0 text-caption text-muted-foreground sm:inline">Succeeded</span>
                            <bdi dir="ltr" data-step-duration="install" class="w-16 shrink-0 text-end font-mono text-caption text-muted-foreground tabular-nums">8.4s</bdi></button>
                                            </div>
                    <div data-slot="collapsible-panel" x-ref="panel" x-nq-presence="open" :id="$id('nq-collapsible', 'panel')"
     data-closed style="display:none"     class="h-(--collapsible-panel-height) overflow-hidden transition-[height,opacity] duration-200 ease-nq motion-reduce:transition-none data-starting-style:h-0 data-starting-style:opacity-0 data-ending-style:h-0 data-ending-style:opacity-0"><div class="flex flex-col gap-2 px-4 pb-4 ps-11">
                                                        <template x-if="errors['install']"><div data-slot="alert" data-tone="danger" role="alert"
        class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-danger/30 bg-nq-danger-soft">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-danger-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                            <div data-slot="alert-description" class="text-body-sm text-foreground"><span x-text="errors['install']"></span></div>
            </div>
    </div>
</template>
                            <div class="relative overflow-hidden rounded-control border border-border bg-nq-surface-soft" dir="ltr">
                                                                <pre role="log" aria-label="Logs for Install dependencies" aria-live="off" tabindex="0" style="max-height: 14rem"
                                    class="m-0 overflow-auto p-3 font-mono text-code text-nq-fg-body outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-nq-focus"><code class="block w-max min-w-full">Lockfile is up to date
Packages: +214
Done in 8.4s</code></pre>
                            </div>
                        </div></div>
</div>
            </li>
                                <li data-slot="deploy-step" data-status="failed" class="border-b border-border last:border-b-0">
                <div data-slot="collapsible" x-data="nqCollapsible(true)" x-modelable="open" x-id="['nq-collapsible']"
    :data-open="open ? '' : undefined" :data-closed="open ? undefined : ''"
     data-open     >
    <div class="flex items-center gap-1 pe-2">
                        <button data-slot="collapsible-trigger"
     type="button"                         x-bind:aria-controls="$id(&#039;nq-collapsible&#039;, &#039;panel&#039;)" x-bind:data-panel-open="open ? &#039;&#039; : undefined" x-on:click="toggle()" :aria-expanded="open" aria-label="Step 2: Build, Failed" class="inline-flex shrink-0 select-none items-center whitespace-nowrap border border-transparent font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 text-foreground hover:bg-nq-hover group/step h-auto min-w-0 flex-1 justify-start gap-3 rounded-none px-4 py-3 text-start font-normal">
        <svg aria-hidden="true" class="size-4 shrink-0 text-muted-foreground transition-transform duration-150 group-data-[panel-open]/step:rotate-90 rtl:-scale-x-100 rtl:group-data-[panel-open]/step:-rotate-90" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m9 18 6-6-6-6"/>
</svg>                            <svg aria-hidden="true" class="size-4 shrink-0 text-nq-danger-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>                            <span class="flex min-w-0 flex-1 flex-col gap-0.5">
                                <span class="truncate text-label text-foreground">Build</span>
                                <bdi dir="ltr" class="truncate text-start font-mono text-caption text-muted-foreground">pnpm build</bdi>                            </span>
                            <span class="hidden shrink-0 text-caption text-muted-foreground sm:inline">Failed</span>
                            <bdi dir="ltr" data-step-duration="build" class="w-16 shrink-0 text-end font-mono text-caption text-muted-foreground tabular-nums">21s</bdi></button>
                                                    <button data-slot="button"
     type="button"                         x-on:click="retry(&#039;build&#039;)" x-bind:aria-busy="retrying[&#039;build&#039;] ? &#039;true&#039; : null" x-bind:data-disabled="retrying[&#039;build&#039;] ? &#039;&#039; : null" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" class="rtl:-scale-x-100" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
  <path d="M3 3v5h5"/>
</svg>                                Retry step</button>
                                            </div>
                    <div data-slot="collapsible-panel" x-ref="panel" x-nq-presence="open" :id="$id('nq-collapsible', 'panel')"
     data-open     class="h-(--collapsible-panel-height) overflow-hidden transition-[height,opacity] duration-200 ease-nq motion-reduce:transition-none data-starting-style:h-0 data-starting-style:opacity-0 data-ending-style:h-0 data-ending-style:opacity-0"><div class="flex flex-col gap-2 px-4 pb-4 ps-11">
                                                            <div data-slot="alert" data-tone="danger" role="alert"
        class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-danger/30 bg-nq-danger-soft">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-danger-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                            <div data-slot="alert-description" class="text-body-sm text-foreground">The build exited with code 1.</div>
            </div>
    </div>
                                                        <template x-if="errors['build']"><div data-slot="alert" data-tone="danger" role="alert"
        class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-danger/30 bg-nq-danger-soft">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-danger-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                            <div data-slot="alert-description" class="text-body-sm text-foreground"><span x-text="errors['build']"></span></div>
            </div>
    </div>
</template>
                            <div class="relative overflow-hidden rounded-control border border-border bg-nq-surface-soft" dir="ltr">
                                                                <pre role="log" aria-label="Logs for Build" aria-live="off" tabindex="0" style="max-height: 14rem"
                                    class="m-0 overflow-auto p-3 font-mono text-code text-nq-fg-body outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-nq-focus"><code class="block w-max min-w-full">compiled 214 modules
error src/app.ts: Type &#039;string&#039; is not assignable to type &#039;number&#039;</code></pre>
                            </div>
                        </div></div>
</div>
            </li>
                                <li data-slot="deploy-step" data-status="pending" class="border-b border-border last:border-b-0">
                <div data-slot="collapsible" x-data="nqCollapsible(false)" x-modelable="open" x-id="['nq-collapsible']"
    :data-open="open ? '' : undefined" :data-closed="open ? undefined : ''"
     data-closed     >
    <div class="flex items-center gap-1 pe-2">
                        <button data-slot="collapsible-trigger"
     type="button"                         x-bind:aria-controls="$id(&#039;nq-collapsible&#039;, &#039;panel&#039;)" x-bind:data-panel-open="open ? &#039;&#039; : undefined" x-on:click="toggle()" :aria-expanded="open" aria-label="Step 3: Ship to production, Queued" class="inline-flex shrink-0 select-none items-center whitespace-nowrap border border-transparent font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 text-foreground hover:bg-nq-hover group/step h-auto min-w-0 flex-1 justify-start gap-3 rounded-none px-4 py-3 text-start font-normal">
        <svg aria-hidden="true" class="size-4 shrink-0 text-muted-foreground transition-transform duration-150 group-data-[panel-open]/step:rotate-90 rtl:-scale-x-100 rtl:group-data-[panel-open]/step:-rotate-90" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m9 18 6-6-6-6"/>
</svg>                            <svg aria-hidden="true" class="size-4 shrink-0 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M10.1 2.182a10 10 0 0 1 3.8 0"/>
  <path d="M13.9 21.818a10 10 0 0 1-3.8 0"/>
  <path d="M17.609 3.721a10 10 0 0 1 2.69 2.7"/>
  <path d="M2.182 13.9a10 10 0 0 1 0-3.8"/>
  <path d="M20.279 17.609a10 10 0 0 1-2.7 2.69"/>
  <path d="M21.818 10.1a10 10 0 0 1 0 3.8"/>
  <path d="M3.721 6.391a10 10 0 0 1 2.7-2.69"/>
  <path d="M6.391 20.279a10 10 0 0 1-2.69-2.7"/>
</svg>                            <span class="flex min-w-0 flex-1 flex-col gap-0.5">
                                <span class="truncate text-label text-foreground">Ship to production</span>
                                <bdi dir="ltr" class="truncate text-start font-mono text-caption text-muted-foreground">pnpm deploy</bdi>                            </span>
                            <span class="hidden shrink-0 text-caption text-muted-foreground sm:inline">Queued</span>
                            <bdi dir="ltr" data-step-duration="ship" class="w-16 shrink-0 text-end font-mono text-caption text-muted-foreground tabular-nums"></bdi></button>
                                            </div>
                    <div data-slot="collapsible-panel" x-ref="panel" x-nq-presence="open" :id="$id('nq-collapsible', 'panel')"
     data-closed style="display:none"     class="h-(--collapsible-panel-height) overflow-hidden transition-[height,opacity] duration-200 ease-nq motion-reduce:transition-none data-starting-style:h-0 data-starting-style:opacity-0 data-ending-style:h-0 data-ending-style:opacity-0"><div class="flex flex-col gap-2 px-4 pb-4 ps-11">
                                                        <template x-if="errors['ship']"><div data-slot="alert" data-tone="danger" role="alert"
        class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-danger/30 bg-nq-danger-soft">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-danger-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                            <div data-slot="alert-description" class="text-body-sm text-foreground"><span x-text="errors['ship']"></span></div>
            </div>
    </div>
</template>
                            <div class="relative overflow-hidden rounded-control border border-border bg-nq-surface-soft" dir="ltr">
                                                                <pre role="log" aria-label="Logs for Ship to production" aria-live="off" tabindex="0" style="max-height: 14rem"
                                    class="m-0 overflow-auto p-3 font-mono text-code text-nq-fg-body outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-nq-focus"><span class="text-muted-foreground">No output for this step.</span></pre>
                            </div>
                        </div></div>
</div>
            </li>
            </ol>
</section>
```
