{
  "zync-patterns": [
    {
      "id": "no-html-table",
      "title": "Raw <table> HTML element",
      "category": "convention",
      "severity": "high",
      "pattern": "<(table|thead|tbody|tr|td|th|tfoot)\\b",
      "description": "zc-ui-dev bans <table>; use <div> + CSS grid.",
      "resolution": "Build tabular layout with <div> grid (see zc-ui-dev TABULAR DATA).",
      "excludeGlobs": [
        "**/*-pdf.ts",
        "**/pdf-preview.ts",
        ".slopgate/fixtures/os-shell/**"
      ],
      "canary": "<table className=\"x\">"
    },
    {
      "id": "oklch-only",
      "title": "Hardcoded hex/rgb/hsl color",
      "category": "convention",
      "severity": "high",
      "pattern": "(?<!&)#[0-9a-fA-F]{3,8}\\b|\\brgb\\(|\\brgba\\(|\\bhsl\\(",
      "description": "zc-ui-dev: OKLCH tokens only; hex/rgb/hsl banned in source.",
      "resolution": "Use a CSS custom property from packages/ui tokens.",
      "excludeGlobs": [
        "**/tokens/**",
        "**/tokens.css",
        "apps/zync-api/src/services/*-email.ts",
        "packages/notifications/src/email/**",
        "apps/zync-api/src/routes/invoices/index.ts",
        ".slopgate/fixtures/os-shell/**"
      ],
      "canary": "color: #ff0044;"
    },
    {
      "id": "no-raw-drizzle-route",
      "title": "Drizzle import inside a route handler",
      "category": "boundary",
      "severity": "high",
      "pattern": "from '@zync/db'",
      "description": "zc-dba: routes must call query functions, never import drizzle directly.",
      "resolution": "Import from '@zync/db/queries/*' instead.",
      "excludeGlobs": [
        ".slopgate/fixtures/os-shell/**"
      ],
      "canary": "import { db } from '@zync/db'"
    },
    {
      "id": "zync-ui-flat-import",
      "title": "Flat compound-component import from @zync/ui",
      "category": "convention",
      "severity": "high",
      "pattern": "import\\s*\\{[^}]*\\b(DialogContent|DialogHeader|DialogFooter|DialogTitle|PopoverContent|PopoverTrigger|DropdownMenuContent|DropdownMenuItem)\\b[^}]*\\}\\s*from\\s*['\"]@zync/ui['\"]",
      "description": "@zync/ui uses a compound API; import the parent and use Dialog.Content (zc-ui-dev zync-ui-compound-api).",
      "resolution": "Import the compound parent (Dialog, Popover, DropdownMenu) and use dot-access (e.g. Dialog.Content).",
      "excludeGlobs": [
        ".slopgate/fixtures/os-shell/**"
      ],
      "canary": "import { DialogContent, DialogHeader } from '@zync/ui'"
    },
    {
      "id": "no-zync-ui-table-primitive",
      "title": "Deprecated @zync/ui Table primitive (div+ARIA)",
      "category": "convention",
      "severity": "high",
      "pattern": "import\\s*\\{[^}]*\\b(Table|Thead|Tbody|Tr|Th|Td)\\b[^}]*\\}\\s*from\\s*['\"]@zync/ui['\"]",
      "description": "The low-level @zync/ui Table/Tr/Th/Td primitive renders div+ARIA roles (not native <table>) and is deprecated (zc-ui-dev). Use DataTable or an inline div+CSS-grid layout.",
      "resolution": "Replace with <DataTable> (packages/ui data-display) or an inline div+CSS-grid table with role=\"table\"/\"row\"/\"cell\". Do not import Table/Thead/Tbody/Tr/Th/Td from @zync/ui.",
      "excludeGlobs": [
        ".slopgate/fixtures/os-shell/**"
      ],
      "canary": "import { Table, Tr, Th } from '@zync/ui'"
    }
  ]
}
