{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "security-data-flow",
  "title": "Security — Data Flow",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/security-data-flow/SecurityDataFlow.vue",
      "content": "<script setup lang=\"ts\">\nimport { ArrowRight, Building2, Cloud, Lock } from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Separator } from '@/components/ui/separator'\n\n// The point of the diagram is the second list: naming what never crosses is\n// more reassuring than any number of things that do.\nconst zones = [\n  {\n    icon: Building2,\n    label: 'Your warehouse',\n    detail: 'Snowflake, BigQuery, Redshift, Postgres',\n    holds: ['Customer rows', 'PII and PHI', 'Raw event history'],\n  },\n  {\n    icon: Cloud,\n    label: 'Northwind',\n    detail: 'Your chosen region',\n    holds: ['Metric definitions', 'Query plans and timings', 'Access decisions'],\n  },\n  {\n    icon: Lock,\n    label: 'Your viewers',\n    detail: 'Scoped per identity',\n    holds: ['Aggregated results only', 'Nothing cached in the browser'],\n  },\n]\n\nconst crosses = ['Column names and types', 'Aggregate results, scoped', 'Query metadata and timings']\nconst neverCrosses = ['Customer rows', 'Primary keys', 'Free-text fields', 'Anything you have not modelled']\n</script>\n\n<template>\n  <section data-slot=\"security-data-flow\" class=\"bg-background\">\n    <div class=\"mx-auto max-w-6xl px-6 py-20 lg:py-28\">\n      <div class=\"max-w-2xl\">\n        <Badge variant=\"secondary\">Data flow</Badge>\n        <h2 class=\"mt-4 text-3xl font-semibold tracking-tight sm:text-4xl\">What crosses the boundary</h2>\n        <p class=\"text-muted-foreground mt-3 text-lg\">\n          And, more usefully, what never does. Both lists are below the diagram.\n        </p>\n      </div>\n\n      <Card class=\"mt-10\">\n        <CardContent class=\"p-6 lg:p-8\">\n          <div class=\"grid items-stretch gap-4 lg:grid-cols-[1fr_auto_1fr_auto_1fr]\">\n            <template v-for=\"(zone, index) in zones\" :key=\"zone.label\">\n              <div class=\"border-border bg-muted/30 rounded-lg border p-5\">\n                <span\n                  class=\"border-border bg-background text-muted-foreground flex size-9 items-center justify-center rounded-lg border\"\n                  aria-hidden=\"true\"\n                >\n                  <component :is=\"zone.icon\" class=\"size-4\" />\n                </span>\n                <p class=\"mt-4 text-sm font-semibold\">{{ zone.label }}</p>\n                <p class=\"text-muted-foreground mt-0.5 text-xs\">{{ zone.detail }}</p>\n                <ul class=\"mt-3 space-y-1\">\n                  <li v-for=\"item in zone.holds\" :key=\"item\" class=\"text-muted-foreground font-mono text-xs\">\n                    {{ item }}\n                  </li>\n                </ul>\n              </div>\n\n              <div\n                v-if=\"index < zones.length - 1\"\n                class=\"text-muted-foreground/50 flex items-center justify-center lg:px-2\"\n                aria-hidden=\"true\"\n              >\n                <ArrowRight class=\"size-4 rotate-90 lg:rotate-0\" />\n              </div>\n            </template>\n          </div>\n\n          <Separator class=\"my-8\" />\n\n          <div class=\"grid gap-8 sm:grid-cols-2\">\n            <div>\n              <p class=\"text-muted-foreground font-mono text-xs tracking-[0.14em] uppercase\">Crosses the boundary</p>\n              <ul class=\"mt-3 space-y-2\">\n                <li v-for=\"item in crosses\" :key=\"item\" class=\"flex items-center gap-2.5 text-sm\">\n                  <span class=\"bg-primary size-1.5 shrink-0 rounded-full\" aria-hidden=\"true\" />\n                  <span>{{ item }}</span>\n                </li>\n              </ul>\n            </div>\n\n            <div>\n              <p class=\"text-muted-foreground font-mono text-xs tracking-[0.14em] uppercase\">Never crosses</p>\n              <ul class=\"mt-3 space-y-2\">\n                <li v-for=\"item in neverCrosses\" :key=\"item\" class=\"flex items-center gap-2.5 text-sm\">\n                  <span class=\"bg-muted-foreground/40 size-1.5 shrink-0 rounded-full\" aria-hidden=\"true\" />\n                  <span class=\"text-muted-foreground\">{{ item }}</span>\n                </li>\n              </ul>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      <Button variant=\"outline\" class=\"mt-6\">Read the architecture note</Button>\n    </div>\n  </section>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/SecurityDataFlow.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",
    "https://uipkge.dev/r/vue/separator.json"
  ],
  "description": "Diagram of what crosses the boundary and what does not: three labelled zones joined by drawn arrows, with a legend separating metadata from customer rows.",
  "categories": [
    "marketing"
  ]
}