{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "code-terminal-session",
  "title": "Code — Terminal Session",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/code-terminal-session/CodeTerminalSession.vue",
      "content": "<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref } from 'vue'\nimport { Terminal } from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\n\nconst props = withDefaults(defineProps<{ lineDelay?: number }>(), { lineDelay: 420 })\n\nconst lines = [\n  { kind: 'prompt', text: 'npx @northwind/cli connect snowflake' },\n  { kind: 'out', text: 'Testing credentials…  ok' },\n  { kind: 'out', text: 'Mirroring schema…     412 tables' },\n  { kind: 'prompt', text: 'npx @northwind/cli certify revenue_net' },\n  { kind: 'out', text: 'Reconciling 4 quarters…' },\n  { kind: 'out', text: 'Q1 ✓   Q2 ✓   Q3 ✓   Q4 ✓' },\n  { kind: 'ok', text: 'revenue_net certified · 41 consumers notified' },\n]\n\n// Renders the whole transcript immediately when the viewer prefers reduced\n// motion; otherwise reveals a line at a time from mount.\nconst shown = ref(0)\nlet timer: ReturnType<typeof setInterval> | undefined\n\nonMounted(() => {\n  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches\n  if (reduced) {\n    shown.value = lines.length\n    return\n  }\n  timer = setInterval(() => {\n    shown.value += 1\n    if (shown.value >= lines.length) clearInterval(timer)\n  }, props.lineDelay)\n})\n\nonBeforeUnmount(() => clearInterval(timer))\n\nfunction toneClass(kind: string) {\n  if (kind === 'prompt') return 'text-foreground'\n  if (kind === 'ok') return 'text-success'\n  return 'text-muted-foreground'\n}\n</script>\n\n<template>\n  <section data-slot=\"code-terminal-session\" class=\"bg-background\">\n    <div class=\"mx-auto max-w-3xl px-6 py-20\">\n      <Badge variant=\"secondary\" class=\"gap-1.5\">\n        <Terminal class=\"size-3\" aria-hidden=\"true\" />\n        CLI\n      </Badge>\n      <h2 class=\"mt-4 text-2xl font-semibold tracking-tight\">Connected and certified in two commands</h2>\n      <p class=\"text-muted-foreground mt-2\">\n        The CLI does everything the UI does, so the first rollout can live in a script.\n      </p>\n\n      <Card class=\"mt-6\">\n        <CardContent class=\"p-0\">\n          <div class=\"border-border flex items-center gap-1.5 border-b px-4 py-2.5\">\n            <span class=\"bg-muted-foreground/30 size-2.5 rounded-full\" aria-hidden=\"true\" />\n            <span class=\"bg-muted-foreground/30 size-2.5 rounded-full\" aria-hidden=\"true\" />\n            <span class=\"bg-muted-foreground/30 size-2.5 rounded-full\" aria-hidden=\"true\" />\n            <span class=\"text-muted-foreground ml-2 font-mono text-xs\">bash — northwind</span>\n          </div>\n\n          <!-- min-h holds the final transcript height from the first paint, so\n               the card does not grow line by line and shove the page down. -->\n          <div class=\"min-h-[13.5rem] space-y-1 p-4 font-mono text-xs leading-relaxed\">\n            <p v-for=\"(line, index) in lines.slice(0, shown)\" :key=\"index\" :class=\"toneClass(line.kind)\">\n              <span v-if=\"line.kind === 'prompt'\" class=\"text-primary select-none\">$ </span>{{ line.text }}\n            </p>\n          </div>\n        </CardContent>\n      </Card>\n\n      <Button variant=\"outline\" class=\"mt-6\">Read the CLI reference</Button>\n    </div>\n  </section>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/CodeTerminalSession.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json"
  ],
  "description": "Terminal transcript that types itself out line by line on mount, showing prompts, output, and a success summary, and rendering instantly under reduced-motion.",
  "categories": [
    "marketing"
  ]
}