<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vertz — One command. Full stack. Running.</title>

  <meta name="description" content="One command. Database, API, and UI — running locally. Define your schema once. Everything else is derived. Zero config." />

  <!-- Favicon -->
  <link rel="icon" type="image/svg+xml" href="/public/logo.svg" />

  <!-- Open Graph -->
  <meta property="og:type" content="website" />
  <meta property="og:url" content="https://vertz.dev" />
  <meta property="og:title" content="Vertz — One command. Full stack. Running." />
  <meta property="og:description" content="Define your schema once. Everything else is derived. Database, API, and UI from a single schema. Zero config." />
  <meta property="og:image" content="https://vertz.dev/public/og.png" />
  <meta property="og:image:width" content="1200" />
  <meta property="og:image:height" content="630" />

  <!-- Twitter Card -->
  <meta name="twitter:card" content="summary_large_image" />
  <meta name="twitter:site" content="@vinicius_dacal" />
  <meta name="twitter:title" content="Vertz — One command. Full stack. Running." />
  <meta name="twitter:description" content="Define your schema once. Everything else is derived. Database, API, and UI from a single schema. Zero config." />
  <meta name="twitter:image" content="https://vertz.dev/public/og.png" />

  <!-- Canonical -->
  <link rel="canonical" href="https://vertz.dev" />

  <!-- LLM Discovery -->
  <link rel="alternate" type="text/plain" href="/llms.txt" />

  <!-- Production CSS -->
  <link rel="stylesheet" href="/assets/vertz.css" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="preload" href="/fonts/dm-sans-latin.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/dm-serif-display-latin.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/jetbrains-mono-latin.woff2" as="font" type="font/woff2" crossorigin>
    <style data-vertz-css>@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
  src: url(/fonts/dm-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'DM Sans';
  font-style: italic;
  font-weight: 100 1000;
  font-display: swap;
  src: url(/fonts/dm-sans-italic-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'DM Sans Fallback';
  src: local('Arial');
  ascent-override: 92.97%;
  descent-override: 29.05%;
  line-gap-override: 0.00%;
  size-adjust: 106.70%;
}

@font-face {
  font-family: 'DM Serif Display';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/dm-serif-display-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'DM Serif Display Fallback';
  src: local('Times New Roman');
  ascent-override: 92.89%;
  descent-override: 30.04%;
  line-gap-override: 0.00%;
  size-adjust: 111.53%;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/fonts/jetbrains-mono-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'JetBrains Mono Fallback';
  src: local('Courier New');
  ascent-override: 102.02%;
  descent-override: 30.00%;
  line-gap-override: 0.00%;
  size-adjust: 99.98%;
}
:root {
  --color-background: oklch(1 0 0);
  --color-foreground: oklch(0.145 0 0);
  --color-card: oklch(1 0 0);
  --color-card-foreground: oklch(0.145 0 0);
  --color-popover: oklch(1 0 0);
  --color-popover-foreground: oklch(0.145 0 0);
  --color-primary: oklch(0.205 0 0);
  --color-primary-foreground: oklch(0.985 0 0);
  --color-secondary: oklch(0.97 0 0);
  --color-secondary-foreground: oklch(0.205 0 0);
  --color-muted: oklch(0.97 0 0);
  --color-muted-foreground: oklch(0.556 0 0);
  --color-accent: oklch(0.97 0 0);
  --color-accent-foreground: oklch(0.205 0 0);
  --color-destructive: oklch(0.577 0.245 27.325);
  --color-destructive-foreground: oklch(0.985 0 0);
  --color-border: oklch(0.922 0 0);
  --color-input: oklch(0.922 0 0);
  --color-ring: oklch(0.708 0 0);
  --color-chart-1: oklch(0.646 0.222 41.116);
  --color-chart-2: oklch(0.6 0.118 184.714);
  --color-chart-3: oklch(0.398 0.07 227.392);
  --color-chart-4: oklch(0.828 0.189 84.429);
  --color-chart-5: oklch(0.769 0.188 70.08);
  --color-sidebar: oklch(0.985 0 0);
  --color-sidebar-foreground: oklch(0.145 0 0);
  --color-sidebar-primary: oklch(0.205 0 0);
  --color-sidebar-primary-foreground: oklch(0.985 0 0);
  --color-sidebar-accent: oklch(0.97 0 0);
  --color-sidebar-accent-foreground: oklch(0.205 0 0);
  --color-sidebar-border: oklch(0.922 0 0);
  --color-sidebar-ring: oklch(0.708 0 0);
  --font-sans: 'DM Sans', 'DM Sans Fallback', system-ui, sans-serif;
  --font-display: 'DM Serif Display', 'DM Serif Display Fallback', Georgia, serif;
  --font-mono: 'JetBrains Mono', 'JetBrains Mono Fallback', monospace;
}
[data-theme="dark"] {
  --color-background: oklch(0.145 0 0);
  --color-foreground: oklch(0.985 0 0);
  --color-card: oklch(0.205 0 0);
  --color-card-foreground: oklch(0.985 0 0);
  --color-popover: oklch(0.205 0 0);
  --color-popover-foreground: oklch(0.985 0 0);
  --color-primary: oklch(0.922 0 0);
  --color-primary-foreground: oklch(0.205 0 0);
  --color-secondary: oklch(0.269 0 0);
  --color-secondary-foreground: oklch(0.985 0 0);
  --color-muted: oklch(0.269 0 0);
  --color-muted-foreground: oklch(0.708 0 0);
  --color-accent: oklch(0.269 0 0);
  --color-accent-foreground: oklch(0.985 0 0);
  --color-destructive: oklch(0.704 0.191 22.216);
  --color-destructive-foreground: oklch(0.985 0 0);
  --color-border: oklch(1 0 0 / 10%);
  --color-input: oklch(1 0 0 / 15%);
  --color-ring: oklch(0.556 0 0);
  --color-chart-1: oklch(0.488 0.243 264.376);
  --color-chart-2: oklch(0.696 0.17 162.48);
  --color-chart-3: oklch(0.769 0.188 70.08);
  --color-chart-4: oklch(0.627 0.265 303.9);
  --color-chart-5: oklch(0.645 0.246 16.439);
  --color-sidebar: oklch(0.205 0 0);
  --color-sidebar-foreground: oklch(0.985 0 0);
  --color-sidebar-primary: oklch(0.488 0.243 264.376);
  --color-sidebar-primary-foreground: oklch(0.985 0 0);
  --color-sidebar-accent: oklch(0.269 0 0);
  --color-sidebar-accent-foreground: oklch(0.985 0 0);
  --color-sidebar-border: oklch(1 0 0 / 10%);
  --color-sidebar-ring: oklch(0.556 0 0);
}</style>
<style data-vertz-css>*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border-width: 0;
  border-style: solid;
  border-color: var(--color-border);
}
button, input, select, textarea {
  font: inherit;
  color: inherit;
}
:root {
  --radius: 0.375rem;
}
body {
  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  line-height: 1.5;
  color: var(--color-foreground);
  background-color: var(--color-background);
}
dialog:not([open]) {
  display: none;
}
input[type="checkbox"] {
  appearance: none;
  width: 1rem;
  height: 1rem;
  border-width: 1px;
  border-style: solid;
  border-color: var(--color-input);
  border-radius: 4px;
  background-color: transparent;
  cursor: pointer;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 150ms, border-color 150ms;
  vertical-align: middle;
}
input[type="checkbox"]:checked {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
}
input[type="checkbox"]:focus-visible {
  outline: none;
  border-color: var(--color-ring);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-ring) 50%, transparent);
}
input[type="checkbox"]:disabled {
  pointer-events: none;
  opacity: 0.5;
}
input:not([type]), input[type="text"], input[type="number"], input[type="email"], input[type="password"], input[type="search"], input[type="tel"], input[type="url"] {
  display: flex;
  width: 100%;
  border-width: 1px;
  border-style: solid;
  border-color: var(--color-input);
  border-radius: var(--radius);
  background-color: transparent;
  height: 2rem;
  padding-left: 0.625rem;
  padding-right: 0.625rem;
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: var(--color-foreground);
  transition: border-color 150ms, box-shadow 150ms;
}
input:not([type]):focus-visible, input[type="text"]:focus-visible, input[type="number"]:focus-visible, input[type="email"]:focus-visible, input[type="password"]:focus-visible, input[type="search"]:focus-visible, input[type="tel"]:focus-visible, input[type="url"]:focus-visible {
  outline: 3px solid color-mix(in oklch, var(--color-ring) 50%, transparent);
  outline-offset: 2px;
  border-color: var(--color-ring);
}
input:not([type]):disabled, input[type="text"]:disabled, input[type="number"]:disabled, input[type="email"]:disabled, input[type="password"]:disabled, input[type="search"]:disabled, input[type="tel"]:disabled, input[type="url"]:disabled {
  pointer-events: none;
  opacity: 0.5;
}
html {
  scroll-behavior: smooth;
}
html body {
  background-color: #111110;
  font-family: var(--font-sans);
  color: #E8E4DC;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
a {
  text-decoration: none;
  color: inherit;
}
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48ZmlsdGVyIGlkPSJuIj48ZmVUdXJidWxlbmNlIHR5cGU9ImZyYWN0YWxOb2lzZSIgYmFzZUZyZXF1ZW5jeT0iMC44IiBudW1PY3RhdmVzPSI0IiBzdGl0Y2hUaWxlcz0ic3RpdGNoIi8+PC9maWx0ZXI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsdGVyPSJ1cmwoI24pIiBvcGFjaXR5PSIxIi8+PC9zdmc+");
  opacity: 0.02;
  pointer-events: none;
  z-index: 9999;
}</style>
<style data-vertz-css>
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

._f75a83f4 {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._79032d22 {
  max-width: 64rem;
  margin-inline: auto;
}
._c07cd83f {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 1rem;
  text-align: center;
}
._a86cf06f {
  font-size: 2.25rem;
  margin-bottom: 1rem;
  text-align: center;
}
._aff9bb4b {
  text-align: center;
  margin-bottom: 3rem;
  max-width: 36rem;
  margin-inline: auto;
}
._e2c08f4b {
  display: flex;
  justify-content: center;
  gap: 0.25rem;
  margin-bottom: 2.5rem;
  padding: 0.25rem;
  margin-inline: auto;
}
._e2c08f4b {
  border-radius: 2px;
  background: #1C1B1A;
  border: 1px solid #2A2826;
  width: fit-content;
}
._1d8fe156 {
  padding-block: 0.5rem;
  padding-inline: 1rem;
  font-size: 0.75rem;
  letter-spacing: wide;
  cursor: pointer;
  transition: colors;
}
._1d8fe156 {
  background: none;
  border: none;
  outline: none;
  border-radius: 2px;
}
._557b23a9 {
  display: grid;
}
._cf82bc19 {
  padding: 1.5rem;
  border-width: 1px;
}
._1e36f001 {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
._b8ccbfec {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
._1e87deb4 {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
._d2624f75 {
  font-size: 0.75rem;
}
._1f3d0051 {
  font-size: 0.75rem;
}
._1f21f0a9 {
  position: relative;
}
._011a392d {
  font-size: 0.75rem;
  text-align: center;
  margin-top: 2rem;
}
._bf0950f0 {
  padding-block: 6rem;
  padding-inline: 1.5rem;
  position: relative;
  overflow: hidden;
}
._e799291e {
  max-width: 56rem;
  margin-inline: auto;
  text-align: center;
}
._72ad40b7 {
  max-width: 42rem;
  margin-inline: auto;
}
._722749ee {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}
._bd525b35 {
  display: inline-flex;
  border-radius: 9999px;
  height: 0.625rem;
  width: 0.625rem;
}
._67a65e53 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
}
._67a65e53 {
  color: #6B6560;
}
._701bbd6b {
  font-size: 2.25rem;
  margin-bottom: 1.5rem;
}
._ec30e81a {
  font-size: 1.125rem;
  line-height: 1.625;
  margin-bottom: 2.5rem;
}
._83474a73 {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding-block: 0.75rem;
  padding-inline: 2rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
}
._83474a73 {
  background: #5865F2;
  color: #fff;
  border-radius: 2px;
  border: none;
  text-decoration: none;
}
._83474a73:hover {
  background: #4752C4;
}
._06ac656e {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._a453551c {
  max-width: 42rem;
  margin-inline: auto;
}
._4d141339 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 3rem;
  text-align: center;
}
._c4469175 {
  display: flex;
  flex-direction: column;
}
._c4451948 {
  padding-block: 1.5rem;
  border-bottom-width: 1;
}
._d7f75d71 {
  font-weight: 600;
  margin-bottom: 0.5rem;
  color: var(--color-gray-200);
}
._d6e29889 {
  line-height: 1.625;
  color: var(--color-gray-400);
}
._fcc585f5 {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._8536b363 {
  max-width: 64rem;
  margin-inline: auto;
}
._8536b363 {
  overflow: hidden;
}
._bf8d6600 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 1rem;
  text-align: center;
}
._add7f270 {
  font-size: 1.5rem;
  margin-bottom: 1rem;
  text-align: center;
}
@media (min-width: 768px) {
  ._add7f270 {
    font-size: 2.25rem;
  }
}
._62c4fd6c {
  text-align: center;
  margin-bottom: 4rem;
  max-width: 42rem;
  margin-inline: auto;
  font-size: 0.875rem;
}
@media (min-width: 768px) {
  ._62c4fd6c {
    font-size: 1rem;
  }
}
._b146eede {
  display: grid;
  gap: 2rem;
}
._b146eede {
  overflow: hidden;
}
@media (min-width: 768px) {
  ._b146eede {
    grid-template-columns: 200px 1fr;
  }
}
._03eff165 {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 1.5rem;
}
._03eff165 {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
._03eff165::-webkit-scrollbar {
  display: none;
}
@media (min-width: 768px) {
  ._03eff165 {
    flex-direction: column;
    margin-bottom: 0;
    gap: 0;
  }
}
._b5eedb69 {
  padding-block: 0.5rem;
  padding-inline: 0.75rem;
  font-size: 0.75rem;
  cursor: pointer;
}
._b5eedb69 {
  background: none;
  border: none;
  text-align: left;
  white-space: nowrap;
  outline: none;
  font-family: var(--font-sans);
  transition: color 0.2s, background 0.2s;
  border-radius: 2px;
  flex-shrink: 0;
}
@media (min-width: 768px) {
  ._b5eedb69 {
    border-radius: 0;
    white-space: normal;
    font-size: 0.875rem;
    padding: 0.75rem 1rem;
  }
}
._453c4c9b {
  display: grid;
  position: relative;
  min-width: 0;
}
._81ef353d {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
._81ef353d {
  min-width: 0;
}
._0cc1fa59 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
}
._452e9d3f {
  font-size: 1.25rem;
}
@media (min-width: 768px) {
  ._452e9d3f {
    font-size: 1.875rem;
  }
}
._a4f8925c {
  font-size: 0.875rem;
  line-height: 1.625;
}
@media (min-width: 768px) {
  ._a4f8925c {
    font-size: 1rem;
  }
}
._d45b3bd5 {
  padding: 1rem;
  border-width: 1px;
  font-size: 0.75rem;
  line-height: 1.625;
}
._d45b3bd5 {
  overflow-x: auto;
}
@media (min-width: 768px) {
  ._d45b3bd5 {
    padding: 1.5rem;
    font-size: 0.875rem;
  }
}
._4a53be9f {
  padding-block: 3rem;
  padding-inline: 1.5rem;
  border-top-width: 1;
}
._4b3f2e73 {
  max-width: 56rem;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: wider;
  color: var(--color-gray-500);
}
@media (min-width: 640px) {
  ._4b3f2e73 {
    flex-direction: row;
    justify-content: space-between;
  }
}
._c344352b {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}
._bbe877be {
  transition: colors;
}
._c745bba1 {
  color: var(--color-gray-700);
}
._1e4e2a5c {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._2b7a0d8a {
  max-width: 56rem;
  margin-inline: auto;
}
._69d4ea53 {
  font-size: 1.125rem;
  line-height: 1.625;
  max-width: 42rem;
  margin-inline: auto;
  margin-bottom: 3rem;
  text-align: center;
  color: var(--color-gray-300);
}
._e42c342d {
  display: grid;
  gap: 3rem;
  max-width: 36rem;
  margin-inline: auto;
}
@media (min-width: 640px) {
  ._e42c342d {
    grid-template-columns: 1fr 1fr;
  }
}
._e429bb81 {
  text-align: center;
}
._2f69af5e {
  margin-inline: auto;
  margin-bottom: 1rem;
  width: 5rem;
  height: 5rem;
}
._e42fc308 {
  font-weight: 600;
  font-size: 1.125rem;
}
._e4322ff9 {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: wider;
  margin-top: 0.25rem;
  color: var(--color-gray-500);
}
._e0204841 {
  font-size: 0.75rem;
  margin-top: 0.5rem;
  line-height: 1.625;
  max-width: 20rem;
  margin-inline: auto;
  color: var(--color-gray-400);
}
._65f3c470 {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.75rem;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
  color: var(--color-gray-500);
}
._9aeb6fda {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._447eaa88 {
  max-width: 56rem;
  margin-inline: auto;
  display: grid;
  gap: 3rem;
  align-items: center;
}
@media (min-width: 768px) {
  ._447eaa88 {
    grid-template-columns: 1fr 1fr;
  }
}
._4bfddc55 {
  font-size: 2.25rem;
  margin-bottom: 1.5rem;
}
._82fb5f44 {
  font-size: 1.125rem;
  margin-bottom: 1rem;
}
._0719f061 {
  padding: 1.5rem;
  font-size: 0.875rem;
  border-width: 1px;
}
._0719f061 {
  overflow-x: auto;
  border-radius: 2px;
}
._e998b2e9 {
  margin-bottom: 0.5rem;
}
._66af6006 {
  margin-top: 1rem;
}
._f745d226 {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 100%;
}
._9e19813d {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
._638e6fc5 {
  font-size: 0.75rem;
  color: var(--color-gray-500);
}
._a77791c9 {
  cursor: pointer;
}
._a77791c9 {
  background: none;
  border: none;
  padding: 0;
  display: inline-flex;
  align-items: center;
  outline: none;
}
._dfebef67 {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-block: 0.625rem;
  padding-inline: 1rem;
  border-width: 1px;
  width: 100%;
}
._dfebef67 {
  background-color: #1C1B1A;
  border-color: #2A2826;
  border-radius: 2px;
  color: #D4D0C8;
}
._3e765e95 {
  font-size: 0.875rem;
  color: var(--color-gray-500);
}
._3e765e95 {
  white-space: nowrap;
}
._c9c3184c {
  font-size: 0.875rem;
  color: var(--color-gray-400);
}
._c9c3184c {
  flex: 1;
  font-style: italic;
}
._132ded1f {
  font-weight: 600;
  color: var(--color-gray-200);
}
._132ded1f {
  font-style: normal;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: #52525b;
}
._278e9911 {
  margin: 0;
}
._5c916a84 {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline: 1.5rem;
  min-height: 100vh;
}
._5c916a84 {
  padding-top: 5rem;
}
@media (min-width: 1024px) {
  ._5c916a84 {
    padding-left: 3rem;
    padding-right: 3rem;
    padding-top: 0;
  }
}
._6bf32555 {
  display: flex;
  flex-direction: column;
  gap: 3rem;
  width: 100%;
  max-width: 72rem;
  margin-inline: auto;
  align-items: center;
}
@media (min-width: 1024px) {
  ._6bf32555 {
    flex-direction: row;
    align-items: center;
    gap: 4rem;
  }
}
._ab070832 {
  display: flex;
  flex-direction: column;
  text-align: center;
}
@media (min-width: 1024px) {
  ._ab070832 {
    text-align: left;
    flex: 1 1 0%;
    min-width: 0;
  }
}
._a44a71e8 {
  width: 100%;
}
@media (min-width: 1024px) {
  ._a44a71e8 {
    flex: 1 1 0%;
    min-width: 0;
  }
}
._e9f3ee82 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}
@media (min-width: 1024px) {
  ._e9f3ee82 {
    justify-content: flex-start;
  }
}
._85b3caa3 {
  position: relative;
  display: flex;
  height: 0.625rem;
  width: 0.625rem;
}
._85afcf57 {
  position: absolute;
  display: inline-flex;
  height: 100%;
  width: 100%;
  border-radius: 9999px;
  opacity: 40;
}
._0bdda749 {
  position: relative;
  display: inline-flex;
  border-radius: 9999px;
  height: 0.625rem;
  width: 0.625rem;
}
._879b2ce7 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
}
._879b2ce7 {
  color: #6B6560;
}
._32fefb50 {
  display: block;
}
._005a2824 {
  display: block;
}
._005a2824 {
  color: #6B6560;
}
._5a7fd031 {
  position: relative;
}
._5a7fd031 {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  height: 1.15em;
}
._5a7fc593 {
  display: block;
}
._5a7fc593 {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}
._61109ccf {
  display: block;
}
._61109ccf {
  position: relative;
}
._32b72433 {
  margin-top: 1.5rem;
  font-size: 1rem;
  max-width: 36rem;
  line-height: 1.625;
}
._32b72433 {
  color: #9C9690;
}
._183f476b {
  font-weight: 500;
}
._183f476b {
  color: #E8E4DC;
}
._6bf0fb5a {
  margin-top: 2.5rem;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1rem;
}
@media (min-width: 1024px) {
  ._6bf0fb5a {
    align-items: flex-start;
  }
}
._6a729dc0 {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding-block: 0.75rem;
  padding-inline: 1.5rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
}
._6a729dc0 {
  color: #6B6560;
}
@media (min-width: 640px) {
  ._6a729dc0 {
    display: inline-flex;
  }
}
._70020ac5 {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding-block: 0.75rem;
  padding-inline: 1.5rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
}
._70020ac5 {
  color: #6B6560;
}
@media (min-width: 640px) {
  ._70020ac5 {
    display: inline-flex;
  }
}
._188788c6 {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding-block: 0.75rem;
  padding-inline: 1.5rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
}
._188788c6 {
  color: #6B6560;
}
@media (min-width: 640px) {
  ._188788c6 {
    display: inline-flex;
  }
}
._e0f8af57 {
  border-width: 1px;
  box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
}
._e0f8af57 {
  overflow: hidden;
  background-color: #1C1B1A;
  border-color: #2A2826;
  border-radius: 2px;
}
._526ce3db {
  display: flex;
  border-bottom-width: 1;
}
._526ce3db {
  border-color: #2A2826;
}
._d4b9ffe6 {
  padding-block: 0.625rem;
  padding-inline: 1rem;
  font-size: 0.75rem;
  letter-spacing: wide;
  cursor: pointer;
  transition: colors;
  border-bottom-width: 2;
}
._d4b9ffe6 {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  outline: none;
}
._2d9821f8 {
  padding: 1.25rem;
  font-size: 0.75rem;
  line-height: 1.625;
}
._2d9821f8 {
  color: #D4D0C8;
}
._2d9821f8 {
  overflow-x: auto;
}
._37415f50 {
  font-size: 0.75rem;
  color: var(--color-gray-500);
  padding-inline: 1.5rem;
  padding-top: 1rem;
  padding-bottom: 0;
}
._535db86c {
  padding: 1.25rem;
}
._535db86c {
  font-family: var(--font-sans);
  font-size: 0.8rem;
}
._e381bc9c {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}
._e3895d10 {
  flex: 1;
  height: 36px;
  padding: 0 0.75rem;
  background: #111110;
  border: 1px solid #2A2826;
  border-radius: 6px;
  box-sizing: border-box;
  color: #E8E4DC;
  font-size: 0.8rem;
  font-family: var(--font-sans);
  outline: none;
}
._e3895d10::placeholder {
  color: #4A4540;
}
._e3895d10:focus {
  border-color: #C8451B;
}
._4d535b93 {
  height: 36px;
  padding: 0 1rem;
  background: #C8451B;
  border: none;
  border-radius: 6px;
  box-sizing: border-box;
  color: #fff;
  font-size: 0.8rem;
  font-family: var(--font-sans);
  cursor: pointer;
  white-space: nowrap;
}
._4d535b93:hover {
  background: #d65229;
}
._7fa4d939 {
  position: relative;
  max-height: 280px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: #4A4540 transparent;
}
._3027762b {
  left: 0;
  right: 0;
  height: 28px;
  pointer-events: none;
  z-index: 1;
  transition: opacity 250ms ease;
}
._65958806 {
  background: linear-gradient(to bottom, #1C1B1A, transparent);
}
._3df30586 {
  background: linear-gradient(to top, #1C1B1A, transparent);
}
._4e6feded {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
._f0d70897 {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
._f0d70897 {
  padding: 0.5rem 0.75rem;
  background: #111110;
  border-radius: 2px;
  border: 1px solid #2A2826;
}
._f0d70897[data-presence="enter"] {
  animation: todo-enter 200ms ease-out;
}
._f0d70897[data-presence="exit"] {
  overflow: hidden;
  pointer-events: none;
}
._caee02df {
  width: 0.875rem;
  height: 0.875rem;
  border-radius: 2px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 0;
  line-height: 1;
  border: 1px solid #4A4540;
  background: transparent;
  color: #fff;
  position: relative;
}
._caee02df[data-state="checked"] {
  background: #C8451B;
  border-color: #C8451B;
}
._caee02df[data-state="checked"][data-toggled] {
  animation: check-bg-in 150ms ease-out forwards;
}
._caee02df[data-state="unchecked"][data-toggled] {
  animation: check-bg-out 150ms ease-out forwards;
}
._caee02df [data-part="indicator"] {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
._caee02df [data-part="indicator-icon"] {
  width: 9px;
  height: 9px;
  opacity: 0;
  transform: scale(0.5);
}
._caee02df [data-icon="check"] path {
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
}
._caee02df[data-state="checked"] [data-icon="check"] {
  opacity: 1;
  transform: scale(1);
}
._caee02df[data-state="checked"] [data-icon="check"] path {
  stroke-dashoffset: 0;
}
._caee02df[data-state="checked"][data-toggled] [data-icon="check"] {
  animation: check-icon-in 150ms ease-out forwards;
}
._caee02df[data-state="checked"][data-toggled] [data-icon="check"] path {
  animation: check-stroke-in 200ms ease-out 50ms forwards;
}
._caee02df[data-state="unchecked"][data-toggled] [data-icon="check"] {
  animation: check-icon-out 150ms ease-out forwards;
}
._caee02df[data-state="unchecked"][data-toggled] [data-icon="check"] path {
  animation: check-stroke-out 150ms ease-out forwards;
}
._d5f3bd91 {
  flex: 1;
  transition: color 0.15s;
  min-width: 0;
}
._58667060 {
  background: none;
  border: none;
  color: #4A4540;
  cursor: pointer;
  padding: 0.25rem;
  font-size: 0.7rem;
  line-height: 1;
  flex-shrink: 0;
  transition: color 0.15s;
}
._58667060:hover {
  color: #ef4444;
}
._a8dcc31c {
  margin-top: 0.75rem;
  font-size: 0.7rem;
  color: #4A4540;
  font-family: var(--font-mono);
}
._c493062e {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
._c493062e {
  margin-top: 0.5rem;
  font-size: 0.65rem;
  color: #6B6560;
  font-family: var(--font-mono);
}
._2c722fb7 {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #10B981;
  flex-shrink: 0;
}
._4136e07d {
  margin-left: auto;
  background: none;
  border: 1px solid #2A2826;
  border-radius: 4px;
  color: #9C9690;
  cursor: pointer;
  padding: 0.15rem 0.5rem;
  font-size: 0.6rem;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: border-color 0.15s, color 0.15s;
}
._4136e07d:hover {
  border-color: #4A4540;
  color: #E8E4DC;
}
._09ae5c4b {
  height: 1.75rem;
}
._f717bd0b {
  position: fixed;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: 1rem;
  padding-block: 1rem;
}
@media (min-width: 640px) {
  ._f717bd0b {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
}
._040a2658 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
._1bdb4a07 {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
@media (min-width: 640px) {
  ._1bdb4a07 {
    gap: 1.5rem;
  }
}
._da0e6714 {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: wider;
  cursor: pointer;
  transition: colors;
  color: var(--color-gray-500);
}
._6fd75a1a {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._040e24c8 {
  max-width: 56rem;
  margin-inline: auto;
}
._eb61ece5 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 1rem;
  text-align: center;
}
._eb61ece5 {
  color: #6B6560;
}
._20e9c695 {
  font-size: 2.25rem;
  margin-bottom: 1rem;
  text-align: center;
}
._38115631 {
  text-align: center;
  margin-bottom: 3rem;
  max-width: 36rem;
  margin-inline: auto;
}
._38115631 {
  color: #9C9690;
}
._2629e5a1 {
  display: flex;
  flex-direction: column;
}
._4ebb8ddd {
  gap: 1rem;
  align-items: center;
  padding-inline: 1.5rem;
  padding-block: 1rem;
}
@media (max-width: 639px) {
  ._4ebb8ddd {
    display: flex;
    flex-wrap: wrap;
  }
}
@media (min-width: 640px) {
  ._4ebb8ddd {
    display: grid;
    grid-template-columns: 1fr 1.5fr 1fr;
  }
}
._4ebb84c7 {
  font-size: 0.875rem;
}
._262fe739 {
  font-size: 0.875rem;
}
._262fe739 {
  color: #B8A080;
}
._9c3e7dd4 {
  font-size: 0.75rem;
}
._9c3e7dd4 {
  color: #4A4540;
}
@media (min-width: 640px) {
  ._9c3e7dd4 {
    text-align: right;
  }
}
._0a733016 {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._b4f769c4 {
  max-width: 64rem;
  margin-inline: auto;
}
._8fd813e1 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 3rem;
  text-align: center;
}
._78b68427 {
  display: grid;
  gap: 1.5rem;
}
@media (min-width: 768px) {
  ._78b68427 {
    grid-template-columns: repeat(3, 1fr);
  }
}
._78b40b7b {
  padding: 2rem;
  border-width: 1px;
  transition: colors;
}
._906d8863 {
  font-size: 1.5rem;
  margin-bottom: 1rem;
}
._78b4a900 {
  line-height: 1.625;
}
._e08bec8e {
  min-height: 100vh;
}
._404f90b5 {
  max-width: 48rem;
  margin-inline: auto;
  padding-inline: 1.5rem;
  padding-top: 8rem;
  padding-bottom: 6rem;
}
._a49ef53d {
  font-size: 1.25rem;
  margin-bottom: 4rem;
  color: var(--color-gray-400);
}
._8a6747a6 {
  margin-bottom: 4rem;
}
._4a6f9948 {
  font-size: 1.5rem;
  margin-bottom: 1.5rem;
  color: var(--color-gray-100);
}
._090ff9a7 {
  font-size: 1.125rem;
  line-height: 1.625;
  margin-bottom: 1.5rem;
  color: var(--color-gray-400);
}
._89243c69 {
  color: var(--color-gray-200);
  font-weight: 500;
}
._e0847b72 {
  font-weight: 600;
  color: var(--color-gray-100);
}
._12640db8 {
  margin-block: 4rem;
}
._e089dead {
  margin-bottom: 1.5rem;
}
._2ebf8c2b {
  font-size: 1.125rem;
  line-height: 1.625;
  margin-bottom: 1rem;
  color: var(--color-gray-400);
}
._baad6fbc {
  font-size: 1.125rem;
  line-height: 1.625;
  margin-bottom: 0.75rem;
  color: var(--color-gray-400);
}
._d25093ea {
  font-size: 1.5rem;
  text-align: center;
  margin-block: 2rem;
  color: var(--color-gray-100);
}
._cbf03180 {
  font-size: 1.125rem;
  text-align: center;
  color: var(--color-gray-400);
}
._538e28ca {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._b0b35f78 {
  max-width: 64rem;
  margin-inline: auto;
}
._2cb54f95 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 1rem;
  text-align: center;
}
._04a09545 {
  font-size: 1.5rem;
  margin-bottom: 1rem;
  text-align: center;
}
@media (min-width: 768px) {
  ._04a09545 {
    font-size: 2.25rem;
  }
}
._92a1fae1 {
  text-align: center;
  margin-bottom: 3rem;
  max-width: 42rem;
  margin-inline: auto;
  font-size: 0.875rem;
}
@media (min-width: 768px) {
  ._92a1fae1 {
    font-size: 1rem;
  }
}
._a441195b {
  display: grid;
  gap: 1.5rem;
}
@media (min-width: 768px) {
  ._a441195b {
    grid-template-columns: 1fr 1fr;
  }
}
._89c04ffb {
  padding: 1.25rem;
  border-width: 1px;
  font-size: 0.75rem;
  line-height: 1.625;
}
._89c04ffb {
  overflow-x: auto;
}
@media (min-width: 768px) {
  ._89c04ffb {
    padding: 1.5rem;
    font-size: 0.875rem;
  }
}
._534d0b43 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}
._e0d8536e {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._b932c31c {
  max-width: 64rem;
  margin-inline: auto;
}
._b932c31c {
  overflow: hidden;
}
._2f6c8139 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 1rem;
  text-align: center;
}
._91eabfe9 {
  font-size: 1.5rem;
  margin-bottom: 1rem;
  text-align: center;
}
@media (min-width: 768px) {
  ._91eabfe9 {
    font-size: 2.25rem;
  }
}
._c9317a05 {
  text-align: center;
  margin-bottom: 4rem;
  max-width: 42rem;
  margin-inline: auto;
  font-size: 0.875rem;
}
@media (min-width: 768px) {
  ._c9317a05 {
    font-size: 1rem;
  }
}
._1d097137 {
  display: grid;
  gap: 2rem;
}
._1d097137 {
  overflow: hidden;
}
@media (min-width: 768px) {
  ._1d097137 {
    grid-template-columns: 200px 1fr;
  }
}
._50acea5e {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 1.5rem;
}
._50acea5e {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
._50acea5e::-webkit-scrollbar {
  display: none;
}
@media (min-width: 768px) {
  ._50acea5e {
    flex-direction: column;
    margin-bottom: 0;
    gap: 0;
  }
}
._21b15dc2 {
  padding-block: 0.5rem;
  padding-inline: 0.75rem;
  font-size: 0.75rem;
  cursor: pointer;
}
._21b15dc2 {
  background: none;
  border: none;
  text-align: left;
  white-space: nowrap;
  outline: none;
  font-family: var(--font-sans);
  transition: color 0.2s, background 0.2s;
  border-radius: 2px;
  flex-shrink: 0;
}
@media (min-width: 768px) {
  ._21b15dc2 {
    border-radius: 0;
    white-space: normal;
    font-size: 0.875rem;
    padding: 0.75rem 1rem;
  }
}
._294f1a14 {
  display: grid;
  position: relative;
  min-width: 0;
}
._664b4d56 {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
._664b4d56 {
  min-width: 0;
}
._f0d4c7d2 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
}
._792aacf8 {
  font-size: 1.25rem;
}
@media (min-width: 768px) {
  ._792aacf8 {
    font-size: 1.875rem;
  }
}
._0b650ef5 {
  font-size: 0.875rem;
  line-height: 1.625;
}
@media (min-width: 768px) {
  ._0b650ef5 {
    font-size: 1rem;
  }
}
._3ac7b86e {
  padding: 1rem;
  border-width: 1px;
  font-size: 0.75rem;
  line-height: 1.625;
}
._3ac7b86e {
  overflow-x: auto;
}
@media (min-width: 768px) {
  ._3ac7b86e {
    padding: 1.5rem;
    font-size: 0.875rem;
  }
}
._4e6976b3 {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._cf99cba1 {
  max-width: 56rem;
  margin-inline: auto;
  display: grid;
  gap: 3rem;
  align-items: center;
}
@media (min-width: 768px) {
  ._cf99cba1 {
    grid-template-columns: 1fr 1fr;
  }
}
._ff7be32e {
  font-size: 2.25rem;
  margin-bottom: 1.5rem;
}
._670e2cbd {
  font-size: 1.125rem;
  margin-bottom: 1rem;
}
._4966a61f {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 1.5rem;
}
._6712a02c {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
}
._6712a02c:hover {
  color: #E8E4DC;
}
._2a58d25a {
  padding: 1.5rem;
  font-size: 0.875rem;
  border-width: 1px;
}
._2a58d25a {
  overflow-x: auto;
  border-radius: 2px;
}
._74f9e962 {
  margin-bottom: 0.5rem;
}
._25172b5f {
  margin-top: 1rem;
}
._313ef487 {
  padding-block: 6rem;
  padding-inline: 1.5rem;
}
._bdc60e75 {
  max-width: 64rem;
  margin-inline: auto;
}
._df560812 {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
  margin-bottom: 3rem;
  text-align: center;
}
._f73e3638 {
  display: grid;
  gap: 1.5rem;
}
@media (min-width: 768px) {
  ._f73e3638 {
    grid-template-columns: repeat(3, 1fr);
  }
}
._f73bbd8c {
  padding: 2rem;
  border-width: 1px;
  transition: colors;
}
._dfeb7c94 {
  font-size: 1.5rem;
  margin-bottom: 1rem;
}
._f73c5b11 {
  line-height: 1.625;
}
._7f8cfb2c {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline: 1.5rem;
  min-height: 100vh;
}
._7f8cfb2c {
  padding-top: 5rem;
}
@media (min-width: 1024px) {
  ._7f8cfb2c {
    padding-left: 3rem;
    padding-right: 3rem;
    padding-top: 0;
  }
}
._406036fd {
  display: flex;
  flex-direction: column;
  gap: 3rem;
  width: 100%;
  max-width: 72rem;
  margin-inline: auto;
  align-items: center;
}
@media (min-width: 1024px) {
  ._406036fd {
    flex-direction: row;
    align-items: center;
    gap: 4rem;
  }
}
._ce0298da {
  display: flex;
  flex-direction: column;
  text-align: center;
}
@media (min-width: 1024px) {
  ._ce0298da {
    text-align: left;
    flex: 1 1 0%;
    min-width: 0;
  }
}
._c7460290 {
  width: 100%;
}
@media (min-width: 1024px) {
  ._c7460290 {
    flex: 1 1 0%;
    min-width: 0;
  }
}
._4c03352a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}
@media (min-width: 1024px) {
  ._4c03352a {
    justify-content: flex-start;
  }
}
._57bd878f {
  font-size: 0.75rem;
  letter-spacing: widest;
  text-transform: uppercase;
}
._94dac8db {
  margin-top: 1.5rem;
  font-size: 1rem;
  max-width: 36rem;
  line-height: 1.625;
}
._fdaaa913 {
  font-weight: 500;
}
._405e0d02 {
  margin-top: 2.5rem;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1rem;
}
@media (min-width: 1024px) {
  ._405e0d02 {
    align-items: flex-start;
  }
}
._69478dd3 {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding-block: 0.75rem;
  padding-inline: 1.5rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
}
._69478dd3 {
  background: #C8451B;
  color: #fff;
  border-radius: 2px;
  text-decoration: none;
}
._69478dd3:hover {
  background: #d65229;
}
@media (min-width: 640px) {
  ._69478dd3 {
    display: inline-flex;
  }
}
._d2ac703d {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding-block: 0.75rem;
  padding-inline: 1.5rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: wider;
  transition: colors;
}
@media (min-width: 640px) {
  ._d2ac703d {
    display: inline-flex;
  }
}
._7fece5f3 {
  padding: 1.5rem;
  font-size: 0.875rem;
  border-width: 1px;
}
._7fece5f3 {
  overflow-x: auto;
  border-radius: 2px;
  background-color: #1C1B1A;
  border-color: #2A2826;
}
._d730217b {
  margin-bottom: 0.5rem;
}
@keyframes todo-enter {
  from {
    opacity: 0;
    transform: translateY(-0.5rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes check-bg-in {
  from {
    background: transparent;
    border-color: #4A4540;
  }
  to {
    background: #C8451B;
    border-color: #C8451B;
  }
}
@keyframes check-bg-out {
  from {
    background: #C8451B;
    border-color: #C8451B;
  }
  to {
    background: transparent;
    border-color: #4A4540;
  }
}
@keyframes check-icon-in {
  from {
    opacity: 0;
    transform: scale(0.5);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes check-icon-out {
  from {
    opacity: 1;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(0.5);
  }
}
@keyframes check-stroke-in {
  from {
    stroke-dashoffset: 30;
  }
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes check-stroke-out {
  from {
    stroke-dashoffset: 0;
  }
  to {
    stroke-dashoffset: 30;
  }
}</style>
  </head>
  <body>
    <div id="app"><div data-theme="dark"><div><div><nav class="_f717bd0b" style="top: 0; left: 0; right: 0; background: rgba(17,17,16,0.85); backdrop-filter: blur(12px); border-bottom: 1px solid #2A2826"><a href="/" class="_040a2658"><svg class="_09ae5c4b" viewBox="0 0 298 298" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="Vertz"><path d="M120.277 66H26L106.5 174.5L151.365 113.67L120.277 66Z" fill="#E8E4DC"></path><path d="M147.986 232L127 203L195.467 113.67L165.731 66H272L147.986 232Z" fill="#E8E4DC"></path></svg></a><div class="_1bdb4a07"><a href="/manifesto" class="_da0e6714">Manifesto</a><a href="https://github.com/vertz-dev/vertz" target="_blank" rel="noopener" class="_da0e6714" style="font-family: var(--font-mono)">GitHub</a><a href="https://discord.gg/C7JkeBhH5" target="_blank" rel="noopener" class="_da0e6714" style="font-family: var(--font-mono)">Discord</a><a href="https://docs.vertz.dev" class="_da0e6714" style="font-family: var(--font-mono)">Docs</a></div></nav><div style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 700px; height: 500px; pointer-events: none; background: radial-gradient(ellipse, rgba(200,69,27,0.06) 0%, transparent 70%); filter: blur(60px)"></div><div style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -60%); width: 350px; height: 350px; pointer-events: none; background: radial-gradient(ellipse, rgba(200,69,27,0.03) 0%, transparent 70%); filter: blur(40px)"></div><div data-hero-flash="" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 900px; height: 600px; pointer-events: none; background: radial-gradient(ellipse, rgba(200,69,27,0.55) 0%, transparent 70%); filter: blur(50px); opacity: 0; transition: opacity 0.8s ease-out"></div><div data-hero-flash-peer="" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 900px; height: 600px; pointer-events: none; background: radial-gradient(ellipse, rgba(50,160,220,0.65) 0%, transparent 70%); filter: blur(50px); opacity: 0; transition: opacity 0.8s ease-out"></div><main style="position: relative; z-index: 2; overflow-x: hidden"><section class="_5c916a84"><div class="_6bf32555"><div class="_ab070832"><div class="_e9f3ee82" style="justify-content: center"><span class="_85b3caa3"><span class="_85afcf57" style="background: #fbbf24"></span><span class="_0bdda749" style="background: #f59e0b"></span></span><span class="_879b2ce7" style="font-family: var(--font-mono)">Canary</span></div><h1 class="_15f61d48" style="font-family: var(--font-display); font-size: clamp(2rem, 4vw, 3.5rem); letter-spacing: -0.025em; line-height: 1.15"><span class="_32fefb50">The agent-native</span><span class="_005a2824"><div data-v-island="src/components/hero.tsx::RotatingWord"><script data-v-island-props="" type="application/json">{}</script><span data-v-id="RotatingWord" class="_5a7fd031"><span class="_61109ccf" style="opacity: 1; transform: translateY(0); transition: transform 0.35s ease, opacity 0.35s ease">framework.</span><span class="_5a7fc593" style="opacity: 0; transform: translateY(-100%); transition: none">stack.</span><span class="_5a7fc593" style="opacity: 0; transform: translateY(-100%); transition: none">ecosystem.</span><span class="_5a7fc593" style="opacity: 0; transform: translateY(-100%); transition: none">compiler.</span><span class="_5a7fc593" style="opacity: 0; transform: translateY(-100%); transition: none">runtime.</span><span class="_5a7fc593" style="opacity: 0; transform: translateY(-100%); transition: none">devtool.</span></span></div></span></h1><p class="_32b72433">One schema derives your database, API, and UI. <span class="_183f476b">Fully typed end-to-end. Built for agents to write, humans to ship.</span></p><div class="_6bf0fb5a"><div data-v-island="src/components/hero.tsx::CopyButton"><script data-v-island-props="" type="application/json">{}</script><div data-v-id="CopyButton" class="_f745d226"><div class="_9e19813d"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6B6560" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg><span class="_638e6fc5" style="font-family: var(--font-mono)">Ask your agent:</span><button type="button" class="_a77791c9" aria-label="Copy prompt"><!--conditional--><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6B6560" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg><!--/conditional--></button></div><div class="_dfebef67" style="font-family: var(--font-mono)"><span class="_c9c3184c">&quot;Build a full-stack to-do app using <span class="_132ded1f">docs.vertz.dev</span>&quot;</span></div></div></div><div data-v-island="src/components/hero.tsx::SocialLinks"><script data-v-island-props="" type="application/json">{}</script><a data-v-id="SocialLinks" href="https://github.com/vertz-dev/vertz" target="_blank" rel="noopener" class="_6a729dc0" style="font-family: var(--font-mono)"><span style="align-items: center; gap: 0.25rem; margin-right: 0.35rem; padding: 0.1rem 0.35rem; font-size: 0.7rem; font-family: var(--font-mono); color: #9C9690; border: 1px solid #2A2826; border-radius: 4px; transition: opacity 0.2s ease; display: inline-flex; opacity: 0"><svg width="12" height="12" viewBox="0 0 16 16" fill="#f59e0b" xmlns="http://www.w3.org/2000/svg"><path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path></svg><!--child-->  <!--/child--></span>View on GitHub<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg></a><a href="https://discord.gg/C7JkeBhH5" target="_blank" rel="noopener" class="_70020ac5" style="font-family: var(--font-mono)"><span style="align-items: center; gap: 0.25rem; margin-right: 0.35rem; padding: 0.1rem 0.35rem; font-size: 0.7rem; font-family: var(--font-mono); color: #9C9690; border: 1px solid #2A2826; border-radius: 4px; transition: opacity 0.2s ease; display: inline-flex; opacity: 0"><svg width="12" height="12" viewBox="0 0 24 24" fill="#5865F2" xmlns="http://www.w3.org/2000/svg"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.095 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.095 2.157 2.42 0 1.333-.947 2.418-2.157 2.418z"></path></svg><!--child-->  <!--/child--></span>Join Discord<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg></a></div><a href="https://docs.vertz.dev" class="_188788c6" style="font-family: var(--font-mono)">Read the Docs →</a></div></div><div class="_a44a71e8"><div data-v-island="src/components/hero.tsx::HeroCodeGroup"><script data-v-island-props="" type="application/json">{}</script><div data-v-id="HeroCodeGroup" class="_e0f8af57" style="border-color: #2A2826"><div class="_526ce3db"><button type="button" class="_d4b9ffe6" style="font-family: var(--font-mono); color: #C8451B; border-bottom-color: #C8451B">UI</button><button type="button" class="_d4b9ffe6" style="font-family: var(--font-mono); color: #6B6560; border-bottom-color: transparent">API</button><button type="button" class="_d4b9ffe6" style="font-family: var(--font-mono); color: #6B6560; border-bottom-color: transparent">Schema</button><button type="button" class="_d4b9ffe6" style="font-family: var(--font-mono); color: #6B6560; border-bottom-color: transparent">App</button></div><div style="display: grid"><div class="_2d9821f8" style="grid-area: 1 / 1; visibility: visible"><pre class="_278e9911"><code><span><span style="color:#C8451B">import</span><span style="color:#D4D0C8"> { query, form } </span><span style="color:#C8451B">from</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">vertz/ui</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">;</span>
</span><span><span style="color:#C8451B">import</span><span style="color:#D4D0C8"> { api } </span><span style="color:#C8451B">from</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">./generated/client</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">;</span>
</span><span>
</span><span><span style="color:#C8451B">export</span><span style="color:#D4D0C8"> </span><span style="color:#C8451B">function</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">TodoList</span><span style="color:#D4D0C8">() {</span>
</span><span><span style="color:#D4D0C8">  </span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todos </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">query</span><span style="color:#D4D0C8">(api.todos.</span><span style="color:#B8A080">list</span><span style="color:#D4D0C8">());</span>
</span><span><span style="color:#D4D0C8">  </span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todoForm </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">form</span><span style="color:#D4D0C8">(api.todos.create, {</span>
</span><span><span style="color:#D4D0C8">    </span><span style="color:#B8A080">onSuccess</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> () </span><span style="color:#C8451B">=&gt;</span><span style="color:#D4D0C8"> todos.</span><span style="color:#B8A080">refetch</span><span style="color:#D4D0C8">(),</span>
</span><span><span style="color:#D4D0C8">  });</span>
</span><span>
</span><span><span style="color:#D4D0C8">  </span><span style="color:#C8451B">return</span><span style="color:#D4D0C8"> (</span>
</span><span><span style="color:#D4D0C8">    &lt;</span><span style="color:#C8451B">form</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080;font-style:italic">onSubmit</span><span style="color:#C8451B">=</span><span style="color:#D4D0C8">{todoForm.onSubmit}&gt;</span>
</span><span><span style="color:#D4D0C8">      &lt;</span><span style="color:#C8451B">input</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080;font-style:italic">name</span><span style="color:#C8451B">=</span><span style="color:#7A9B6D">&quot;</span><span style="color:#7A9B6D">title</span><span style="color:#7A9B6D">&quot;</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080;font-style:italic">placeholder</span><span style="color:#C8451B">=</span><span style="color:#7A9B6D">&quot;</span><span style="color:#7A9B6D">What needs to be done?</span><span style="color:#7A9B6D">&quot;</span><span style="color:#D4D0C8"> /&gt;</span>
</span><span><span style="color:#D4D0C8">      &lt;</span><span style="color:#C8451B">button</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080;font-style:italic">type</span><span style="color:#C8451B">=</span><span style="color:#7A9B6D">&quot;</span><span style="color:#7A9B6D">submit</span><span style="color:#7A9B6D">&quot;</span><span style="color:#D4D0C8">&gt;Add&lt;/</span><span style="color:#C8451B">button</span><span style="color:#D4D0C8">&gt;</span>
</span><span><span style="color:#D4D0C8">      {todos.data.</span><span style="color:#B8A080">map</span><span style="color:#D4D0C8">((</span><span style="color:#E8E4DC;font-style:italic">t</span><span style="color:#D4D0C8">) </span><span style="color:#C8451B">=&gt;</span><span style="color:#D4D0C8"> (</span>
</span><span><span style="color:#D4D0C8">        &lt;</span><span style="color:#C8451B">li</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080;font-style:italic">key</span><span style="color:#C8451B">=</span><span style="color:#D4D0C8">{t.id}&gt;{t.title}&lt;/</span><span style="color:#C8451B">li</span><span style="color:#D4D0C8">&gt;</span>
</span><span><span style="color:#D4D0C8">      ))}</span>
</span><span><span style="color:#D4D0C8">    &lt;/</span><span style="color:#C8451B">form</span><span style="color:#D4D0C8">&gt;</span>
</span><span><span style="color:#D4D0C8">  );</span>
</span><span><span style="color:#D4D0C8">}</span>
</span></code></pre></div><div class="_2d9821f8" style="grid-area: 1 / 1; visibility: hidden"><pre class="_278e9911"><code><span><span style="color:#C8451B">import</span><span style="color:#D4D0C8"> { entity } </span><span style="color:#C8451B">from</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">vertz/server</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">;</span>
</span><span><span style="color:#C8451B">import</span><span style="color:#D4D0C8"> { rules } </span><span style="color:#C8451B">from</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">vertz/auth/rules</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">;</span>
</span><span><span style="color:#C8451B">import</span><span style="color:#D4D0C8"> { todosModel } </span><span style="color:#C8451B">from</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">./schema</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">;</span>
</span><span>
</span><span><span style="color:#C8451B">export</span><span style="color:#D4D0C8"> </span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todos </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">entity</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">todos</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">, {</span>
</span><span><span style="color:#D4D0C8">  model</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> todosModel,</span>
</span><span><span style="color:#D4D0C8">  access</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> {</span>
</span><span><span style="color:#D4D0C8">    list</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">   rules.</span><span style="color:#B8A080">authenticated</span><span style="color:#D4D0C8">(),</span>
</span><span><span style="color:#D4D0C8">    create</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> rules.</span><span style="color:#B8A080">authenticated</span><span style="color:#D4D0C8">(),</span>
</span><span><span style="color:#D4D0C8">    update</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> rules.</span><span style="color:#B8A080">all</span><span style="color:#D4D0C8">(</span>
</span><span><span style="color:#D4D0C8">      rules.</span><span style="color:#B8A080">entitlement</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">todo:update</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">),</span>
</span><span><span style="color:#D4D0C8">      rules.</span><span style="color:#B8A080">where</span><span style="color:#D4D0C8">({ userId</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> rules.user.id }),</span>
</span><span><span style="color:#D4D0C8">    ),</span>
</span><span><span style="color:#D4D0C8">    delete</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> rules.</span><span style="color:#B8A080">entitlement</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">todo:delete</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">),</span>
</span><span><span style="color:#D4D0C8">  },</span>
</span><span><span style="color:#D4D0C8">});</span>
</span><span><span style="color:#4A4540">// GET  /api/todos     — auto-generated</span>
</span><span><span style="color:#4A4540">// POST /api/todos     — auto-generated</span>
</span><span><span style="color:#4A4540">// GET  /api/openapi   — auto-generated</span>
</span></code></pre></div><div class="_2d9821f8" style="grid-area: 1 / 1; visibility: hidden"><pre class="_278e9911"><code><span><span style="color:#C8451B">import</span><span style="color:#D4D0C8"> { d } </span><span style="color:#C8451B">from</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">vertz/db</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">;</span>
</span><span>
</span><span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> users </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">table</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">users</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">, {</span>
</span><span><span style="color:#D4D0C8">  id</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">    d.</span><span style="color:#B8A080">uuid</span><span style="color:#D4D0C8">().</span><span style="color:#B8A080">primary</span><span style="color:#D4D0C8">({ generate</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#B8A080">uuid</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8"> }),</span>
</span><span><span style="color:#D4D0C8">  name</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">  d.</span><span style="color:#B8A080">text</span><span style="color:#D4D0C8">(),</span>
</span><span><span style="color:#D4D0C8">  email</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">email</span><span style="color:#D4D0C8">().</span><span style="color:#B8A080">unique</span><span style="color:#D4D0C8">(),</span>
</span><span><span style="color:#D4D0C8">});</span>
</span><span>
</span><span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todos </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">table</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">todos</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">, {</span>
</span><span><span style="color:#D4D0C8">  id</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">     d.</span><span style="color:#B8A080">uuid</span><span style="color:#D4D0C8">().</span><span style="color:#B8A080">primary</span><span style="color:#D4D0C8">({ generate</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'</span><span style="color:#B8A080">uuid</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8"> }),</span>
</span><span><span style="color:#D4D0C8">  title</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">  d.</span><span style="color:#B8A080">text</span><span style="color:#D4D0C8">(),</span>
</span><span><span style="color:#D4D0C8">  done</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">   d.</span><span style="color:#B8A080">boolean</span><span style="color:#D4D0C8">().</span><span style="color:#B8A080">default</span><span style="color:#D4D0C8">(</span><span style="color:#D4A053">false</span><span style="color:#D4D0C8">),</span>
</span><span><span style="color:#D4D0C8">  userId</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">uuid</span><span style="color:#D4D0C8">(),</span>
</span><span><span style="color:#D4D0C8">});</span>
</span><span>
</span><span><span style="color:#C8451B">export</span><span style="color:#D4D0C8"> </span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todosModel </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">model</span><span style="color:#D4D0C8">(todos, {</span>
</span><span><span style="color:#D4D0C8">  user</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> d.ref.</span><span style="color:#B8A080">one</span><span style="color:#D4D0C8">(() </span><span style="color:#C8451B">=&gt;</span><span style="color:#D4D0C8"> users, </span><span style="color:#7A9B6D">'</span><span style="color:#7A9B6D">userId</span><span style="color:#7A9B6D">'</span><span style="color:#D4D0C8">),</span>
</span><span><span style="color:#D4D0C8">});</span>
</span></code></pre></div><div style="grid-area: 1 / 1; visibility: hidden"><div data-v-id="MiniTodoApp" class="_535db86c"><form class="_e381bc9c"><input type="text" class="_e3895d10" style="height: 36px; padding: 0 0.75rem; border: 1px solid #2A2826; border-radius: 6px; background: #111110; color: #E8E4DC; font-size: 0.8rem" placeholder="What needs to be done?" value=""><button type="submit" class="_4d535b93" style="height: 36px; border-radius: 6px; border: 1px solid #2A2826">Add</button></form><div class="_7fa4d939" data-todo-scroll=""><div class="_3027762b _65958806" style="opacity: 0; position: sticky; top: 0; margin-bottom: -28px"></div><ul class="_4e6feded"><!--child--><!--lv-s--><li class="_f0d70897"><!--child--><button type="button" role="checkbox" aria-checked="true" data-state="checked" class="_caee02df"><span data-part="indicator" data-state="checked"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" data-part="indicator-icon" data-icon="check"><path d="M4 12 9 17 20 6"></path></svg></span></button><span class="_d5f3bd91" style="color: #4A4540; text-decoration: line-through">Design the schema</span><button type="button" class="_58667060">×</button><!--/child--></li><li class="_f0d70897"><!--child--><button type="button" role="checkbox" aria-checked="true" data-state="checked" class="_caee02df"><span data-part="indicator" data-state="checked"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" data-part="indicator-icon" data-icon="check"><path d="M4 12 9 17 20 6"></path></svg></span></button><span class="_d5f3bd91" style="color: #4A4540; text-decoration: line-through">Generate the API</span><button type="button" class="_58667060">×</button><!--/child--></li><li class="_f0d70897"><!--child--><button type="button" role="checkbox" aria-checked="false" data-state="unchecked" class="_caee02df"><span data-part="indicator" data-state="unchecked"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" data-part="indicator-icon" data-icon="check"><path d="M4 12 9 17 20 6"></path></svg></span></button><span class="_d5f3bd91" style="color: #E8E4DC; text-decoration: none">Build the UI</span><button type="button" class="_58667060">×</button><!--/child--></li><li class="_f0d70897"><!--child--><button type="button" role="checkbox" aria-checked="false" data-state="unchecked" class="_caee02df"><span data-part="indicator" data-state="unchecked"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" data-part="indicator-icon" data-icon="check"><path d="M4 12 9 17 20 6"></path></svg></span></button><span class="_d5f3bd91" style="color: #E8E4DC; text-decoration: none">Ship to production</span><button type="button" class="_58667060">×</button><!--/child--></li><!--lv-e--><!--/child--></ul><div class="_3027762b _3df30586" style="opacity: 0; position: sticky; bottom: 0; margin-top: -28px"></div></div><div class="_a8dcc31c"><!--child-->2<!--/child--> remaining</div><!--conditional--><!--/conditional--></div></div></div></div></div></div></div></section><!--conditional--><!--/conditional--><div style="height: 1px; width: 100%; max-width: 56rem; margin: 3rem auto; background: linear-gradient(to right, transparent, #2A2826, transparent)"></div><section class="_fcc585f5"><div class="_8536b363"><p class="_bf8d6600" style="font-family: var(--font-mono); color: #6B6560">Features</p><h2 class="_add7f270" style="font-family: var(--font-display); color: #E8E4DC">Not another framework wrapper.</h2><p class="_62c4fd6c" style="color: #9C9690">Every feature exists because the compiler knows your entire stack — schema, API, and UI — at build time.</p><div data-v-island="src/components/features.tsx::FeatureShowcase"><script data-v-island-props="" type="application/json">{}</script><div data-v-id="FeatureShowcase" class="_b146eede"><nav class="_03eff165"><button type="button" class="_b5eedb69" style="color: #E8E4DC; background: rgba(200,69,27,0.06)"><span style="font-family: var(--font-mono); font-size: 0.65rem; color: #C8451B; margin-right: 0.5rem">01</span>Auto Field Selection</button><button type="button" class="_b5eedb69" style="color: #9C9690; background: transparent"><span style="font-family: var(--font-mono); font-size: 0.65rem; color: #4A4540; margin-right: 0.5rem">02</span>End-to-End Types</button><button type="button" class="_b5eedb69" style="color: #9C9690; background: transparent"><span style="font-family: var(--font-mono); font-size: 0.65rem; color: #4A4540; margin-right: 0.5rem">03</span>Instant OpenAPI</button><button type="button" class="_b5eedb69" style="color: #9C9690; background: transparent"><span style="font-family: var(--font-mono); font-size: 0.65rem; color: #4A4540; margin-right: 0.5rem">04</span>TypeScript SDK</button><button type="button" class="_b5eedb69" style="color: #9C9690; background: transparent"><span style="font-family: var(--font-mono); font-size: 0.65rem; color: #4A4540; margin-right: 0.5rem">05</span>Agent-Native</button><button type="button" class="_b5eedb69" style="color: #9C9690; background: transparent"><span style="font-family: var(--font-mono); font-size: 0.65rem; color: #4A4540; margin-right: 0.5rem">06</span>Zero-Runtime Signals</button></nav><div class="_453c4c9b"><div class="_81ef353d" style="grid-area: 1 / 1; opacity: 1; transform: translateY(0); transition: opacity 0.35s ease, transform 0.35s ease; pointer-events: auto"><div><p class="_0cc1fa59" style="font-family: var(--font-mono); color: #C8451B; margin-bottom: 0.5rem">01</p><h3 class="_452e9d3f" style="font-family: var(--font-display); color: #E8E4DC">Your UI decides the query.</h3></div><p class="_a4f8925c" style="color: #9C9690"><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">Reference </code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">task.title</code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC"> in a component — the compiler traces the access and generates a SELECT with only that column. Add </code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">task.dueDate</code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC"> to the template, the query adapts. Remove it, the column drops. No field lists to maintain. No GraphQL fragments. The compiler knows what your UI needs.</code></p><div class="_d45b3bd5" style="font-family: var(--font-mono); background: #111110; border-color: #2A2826; border-radius: 2px; white-space: pre"><div style=""><span style="color:#4A4540">Your component accesses title and status</span></div><div style=""><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> tasks </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">query</span><span style="color:#D4D0C8">(todoApi.</span><span style="color:#B8A080">list</span><span style="color:#D4D0C8">());</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#C8451B">return</span><span style="color:#D4D0C8"> (</span></div><div style=""><span style="color:#D4D0C8">  &lt;</span><span style="color:#C8451B">ul</span><span style="color:#D4D0C8">&gt;</span></div><div style=""><span style="color:#D4D0C8">    {tasks.data.</span><span style="color:#B8A080">map</span><span style="color:#D4D0C8">((</span><span style="color:#E8E4DC;font-style:italic">t</span><span style="color:#D4D0C8">) </span><span style="color:#C8451B">=&gt;</span><span style="color:#D4D0C8"> (</span></div><div style=""><span style="color:#D4D0C8">      &lt;</span><span style="color:#C8451B">li</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080;font-style:italic">key</span><span style="color:#C8451B">=</span><span style="color:#D4D0C8">{t.id}&gt;{t.title} — {t.status}&lt;/</span><span style="color:#C8451B">li</span><span style="color:#D4D0C8">&gt;</span></div><div style=""><span style="color:#D4D0C8">    ))}</span></div><div style=""><span style="color:#D4D0C8">  &lt;/</span><span style="color:#C8451B">ul</span><span style="color:#D4D0C8">&gt;</span></div><div style=""><span style="color:#D4D0C8">)</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#4A4540">Generated: </span><span style="color:#7A9B6D">SELECT &quot;id&quot;, &quot;title&quot;, &quot;status&quot; FROM &quot;todo&quot;</span></div><div style=""><span style="color:#4A4540">Never SELECT * — only what the UI actually uses.</span></div></div></div><div class="_81ef353d" style="grid-area: 1 / 1; opacity: 0; transform: translateY(8px); transition: opacity 0.35s ease, transform 0.35s ease; pointer-events: none"><div><p class="_0cc1fa59" style="font-family: var(--font-mono); color: #C8451B; margin-bottom: 0.5rem">02</p><h3 class="_452e9d3f" style="font-family: var(--font-display); color: #E8E4DC">Rename a field. Everything breaks — at compile time.</h3></div><p class="_a4f8925c" style="color: #9C9690"><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">One schema defines the shape. One type chain flows from database column to API route to form input. Rename </code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">title</code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC"> to </code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">name</code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC"> — TypeScript finds every broken reference across your entire stack before you run a single test.</code></p><div class="_d45b3bd5" style="font-family: var(--font-mono); background: #111110; border-color: #2A2826; border-radius: 2px; white-space: pre"><div style=""><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todos </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">table</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'todos'</span><span style="color:#D4D0C8">, {</span></div><div style=""><span style="color:#D4D0C8">  id</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">   d.</span><span style="color:#B8A080">uuid</span><span style="color:#D4D0C8">().</span><span style="color:#B8A080">primary</span><span style="color:#D4D0C8">(),</span></div><div style="background: rgba(239,68,68,0.08); border-left: 3px solid #ef4444; margin: 0 -1.5rem; padding: 0 1.5rem 0 calc(1.5rem - 3px)"><span style="color:#ef4444">- </span><span style="color:#D4D0C8">title</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">text</span><span style="color:#D4D0C8">(),</span></div><div style="background: rgba(34,197,94,0.08); border-left: 3px solid #22c55e; margin: 0 -1.5rem; padding: 0 1.5rem 0 calc(1.5rem - 3px)"><span style="color:#22c55e">+ </span><span style="color:#D4D0C8">name</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">  d.</span><span style="color:#B8A080">text</span><span style="color:#D4D0C8">(),</span></div><div style=""><span style="color:#D4D0C8">  done</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">  d.</span><span style="color:#B8A080">boolean</span><span style="color:#D4D0C8">().</span><span style="color:#B8A080">default</span><span style="color:#D4D0C8">(</span><span style="color:#D4A053">false</span><span style="color:#D4D0C8">),</span></div><div style=""><span style="color:#D4D0C8">});</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#ef4444">✗ </span><span style="color:#D4D0C8">api.todos.</span><span style="color:#B8A080">create</span><span style="color:#D4D0C8">({ </span><span style="color:#ef4444">title</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'Buy milk'</span><span style="color:#D4D0C8"> });</span></div><div style=""><span style="color:#6B6560">  Property 'title' does not exist. Did you mean 'name'?</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#ef4444">✗ </span><span style="color:#D4D0C8">&lt;</span><span style="color:#C8451B">li</span><span style="color:#D4D0C8">&gt;{t.</span><span style="color:#ef4444">title</span><span style="color:#D4D0C8">}&lt;/</span><span style="color:#C8451B">li</span><span style="color:#D4D0C8">&gt;</span></div><div style=""><span style="color:#6B6560">  Property 'title' does not exist on type 'Todo'.</span></div></div></div><div class="_81ef353d" style="grid-area: 1 / 1; opacity: 0; transform: translateY(8px); transition: opacity 0.35s ease, transform 0.35s ease; pointer-events: none"><div><p class="_0cc1fa59" style="font-family: var(--font-mono); color: #C8451B; margin-bottom: 0.5rem">03</p><h3 class="_452e9d3f" style="font-family: var(--font-display); color: #E8E4DC">Your schema is the documentation.</h3></div><p class="_a4f8925c" style="color: #9C9690"><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">Every entity gets REST endpoints and a fully documented OpenAPI spec. No decorators. No separate spec file. No drift between code and docs. Define the entity, get CRUD operations with complete request/response schemas at </code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">/api/openapi</code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">.</code></p><div class="_d45b3bd5" style="font-family: var(--font-mono); background: #111110; border-color: #2A2826; border-radius: 2px; white-space: pre"><div style=""><span style="color:#C8451B">export</span><span style="color:#D4D0C8"> </span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todos </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">entity</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'todos'</span><span style="color:#D4D0C8">, {</span></div><div style=""><span style="color:#D4D0C8">  model</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> todosModel,</span></div><div style=""><span style="color:#D4D0C8">  access</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> {</span></div><div style=""><span style="color:#D4D0C8">    list</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8">   rules.</span><span style="color:#B8A080">authenticated</span><span style="color:#D4D0C8">(),</span></div><div style=""><span style="color:#D4D0C8">    create</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> rules.</span><span style="color:#B8A080">authenticated</span><span style="color:#D4D0C8">(),</span></div><div style=""><span style="color:#D4D0C8">    delete</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> rules.</span><span style="color:#B8A080">entitlement</span><span style="color:#D4D0C8">(</span><span style="color:#7A9B6D">'todo:delete'</span><span style="color:#D4D0C8">),</span></div><div style=""><span style="color:#D4D0C8">  },</span></div><div style=""><span style="color:#D4D0C8">});</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#4A4540">Auto-generated REST + OpenAPI:</span></div><div style=""><span style="color:#7A9B6D">GET  /api/todos</span><span style="color:#4A4540">      </span><span style="color:#7A9B6D">POST /api/todos</span></div><div style=""><span style="color:#7A9B6D">GET  /api/todos/:id</span><span style="color:#4A4540">  </span><span style="color:#7A9B6D">PUT  /api/todos/:id</span></div><div style=""><span style="color:#C8451B">GET  /api/openapi</span><span style="color:#4A4540">    ← full OpenAPI spec</span></div></div></div><div class="_81ef353d" style="grid-area: 1 / 1; opacity: 0; transform: translateY(8px); transition: opacity 0.35s ease, transform 0.35s ease; pointer-events: none"><div><p class="_0cc1fa59" style="font-family: var(--font-mono); color: #C8451B; margin-bottom: 0.5rem">04</p><h3 class="_452e9d3f" style="font-family: var(--font-display); color: #E8E4DC">Generate. Publish. Let agents consume.</h3></div><p class="_a4f8925c" style="color: #9C9690"><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">One command generates a typed client SDK from your API. Publish to npm for third-party developers. Feed it to an LLM agent. Every endpoint typed, every response validated, every breaking change caught at compile time — for your consumers too.</code></p><div class="_d45b3bd5" style="font-family: var(--font-mono); background: #111110; border-color: #2A2826; border-radius: 2px; white-space: pre"><div style=""><span style="color:#6B6560">$ vertz codegen</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#4A4540">Your consumers get fully typed access:</span></div><div style=""><span style="color:#C8451B">import</span><span style="color:#D4D0C8"> { </span><span style="color:#B8A080">createClient</span><span style="color:#D4D0C8"> } </span><span style="color:#C8451B">from</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'@myapp/sdk'</span><span style="color:#D4D0C8">;</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> api </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">createClient</span><span style="color:#D4D0C8">({ baseUrl</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'https://...'</span><span style="color:#D4D0C8"> });</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> todos </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#C8451B">await</span><span style="color:#D4D0C8"> api.todos.</span><span style="color:#B8A080">list</span><span style="color:#D4D0C8">();</span></div><div style=""><span style="color:#4A4540">   ^? { id: string; title: string; done: boolean }[]</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#C8451B">await</span><span style="color:#D4D0C8"> api.todos.</span><span style="color:#B8A080">create</span><span style="color:#D4D0C8">({ title</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> </span><span style="color:#7A9B6D">'Ship it'</span><span style="color:#D4D0C8"> });</span></div><div style=""><span style="color:#4A4540">                      ^? CreateTodoInput — fully typed</span></div></div></div><div class="_81ef353d" style="grid-area: 1 / 1; opacity: 0; transform: translateY(8px); transition: opacity 0.35s ease, transform 0.35s ease; pointer-events: none"><div><p class="_0cc1fa59" style="font-family: var(--font-mono); color: #C8451B; margin-bottom: 0.5rem">05</p><h3 class="_452e9d3f" style="font-family: var(--font-display); color: #E8E4DC">One pattern per task. Agents get it right the first time.</h3></div><p class="_a4f8925c" style="color: #9C9690"><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">Every API has one canonical pattern. No framework trivia, no hidden conventions. Add one line to the schema — database, API, SDK, validation, and forms all update. An LLM agent writes correct code on the first try because there's only one way to do it.</code></p><div class="_d45b3bd5" style="font-family: var(--font-mono); background: #111110; border-color: #2A2826; border-radius: 2px; white-space: pre"><div style=""><span style="color:#7A9B6D">Agent prompt: &quot;Add a due date to todos&quot;</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#4A4540">Schema — the only code the agent writes:</span></div><div style=""><span style="color:#D4D0C8">dueDate</span><span style="color:#C8451B">:</span><span style="color:#D4D0C8"> d.</span><span style="color:#B8A080">date</span><span style="color:#D4D0C8">().</span><span style="color:#B8A080">optional</span><span style="color:#D4D0C8">(),</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#4A4540">Vertz derives everything else:</span></div><div style=""><span style="color:#7A9B6D">✓ Database migration</span></div><div style=""><span style="color:#7A9B6D">✓ API endpoint updates</span></div><div style=""><span style="color:#7A9B6D">✓ OpenAPI spec update</span></div><div style=""><span style="color:#7A9B6D">✓ SDK type update</span></div><div style=""><span style="color:#7A9B6D">✓ Form validation rules</span></div><div style=""><span style="color:#C8451B">One line of schema → full-stack feature.</span></div></div></div><div class="_81ef353d" style="grid-area: 1 / 1; opacity: 0; transform: translateY(8px); transition: opacity 0.35s ease, transform 0.35s ease; pointer-events: none"><div><p class="_0cc1fa59" style="font-family: var(--font-mono); color: #C8451B; margin-bottom: 0.5rem">06</p><h3 class="_452e9d3f" style="font-family: var(--font-display); color: #E8E4DC">The compiler does the work. Not the browser.</h3></div><p class="_a4f8925c" style="color: #9C9690"><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC"></code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">let count = 0</code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC"> becomes a reactive signal. </code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC">const double = count * 2</code><code style="font-family: var(--font-mono); font-size: 0.85em; background: rgba(200,69,27,0.08); padding: 0.15em 0.4em; border-radius: 3px; color: #E8E4DC"> becomes a computed value. The compiler transforms at build time — not the browser at runtime. No virtual DOM, no diffing, no framework overhead. Just direct DOM updates.</code></p><div class="_d45b3bd5" style="font-family: var(--font-mono); background: #111110; border-color: #2A2826; border-radius: 2px; white-space: pre"><div style=""><span style="color:#4A4540">You write this:</span></div><div style=""><span style="color:#C8451B">export</span><span style="color:#D4D0C8"> </span><span style="color:#C8451B">function</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080">Counter</span><span style="color:#D4D0C8">() {</span></div><div style=""><span style="color:#D4D0C8">  </span><span style="color:#C8451B">let</span><span style="color:#D4D0C8"> count </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> </span><span style="color:#D4A053">0</span><span style="color:#D4D0C8">;</span></div><div style=""><span style="color:#D4D0C8">  </span><span style="color:#C8451B">const</span><span style="color:#D4D0C8"> double </span><span style="color:#C8451B">=</span><span style="color:#D4D0C8"> count </span><span style="color:#C8451B">*</span><span style="color:#D4D0C8"> </span><span style="color:#D4A053">2</span><span style="color:#D4D0C8">;</span></div><div style="min-height: 1em"></div><div style=""><span style="color:#D4D0C8">  </span><span style="color:#C8451B">return</span><span style="color:#D4D0C8"> (</span></div><div style=""><span style="color:#D4D0C8">    &lt;</span><span style="color:#C8451B">button</span><span style="color:#D4D0C8"> </span><span style="color:#B8A080;font-style:italic">onClick</span><span style="color:#C8451B">=</span><span style="color:#D4D0C8">{() </span><span style="color:#C8451B">=&gt;</span><span style="color:#D4D0C8"> count</span><span style="color:#C8451B">++</span><span style="color:#D4D0C8">}&gt;</span></div><div style=""><span style="color:#D4D0C8">      {count} × 2 = {double}</span></div><div style=""><span style="color:#D4D0C8">    &lt;/</span><span style="color:#C8451B">button</span><span style="color:#D4D0C8">&gt;</span></div><div style=""><span style="color:#D4D0C8">  );</span></div><div style=""><span style="color:#D4D0C8">}</span></div><div style=""><span style="color:#4A4540">Compiler: let → signal(), const → computed()</span></div><div style=""><span style="color:#4A4540">Runtime: </span><span style="color:#C8451B">direct DOM updates. Zero overhead.</span></div></div></div></div></div></div></div></section><div style="height: 1px; width: 100%; max-width: 56rem; margin: 3rem auto; background: linear-gradient(to right, transparent, #2A2826, transparent)"></div><section class="_0a733016"><div class="_b4f769c4"><p class="_8fd813e1" style="font-family: var(--font-mono); color: #6B6560">Why Vertz</p><div class="_78b68427"><div class="_78b40b7b" style="background: #1C1B1A; border-color: #2A2826; border-radius: 2px"><h3 class="_906d8863" style="font-family: var(--font-display); color: #E8E4DC">One schema, every layer</h3><p class="_78b4a900" style="color: #9C9690">Define your data once. The compiler derives your database, API, client SDK, and form validation. Change a field — it updates everywhere.</p></div><div class="_78b40b7b" style="background: #1C1B1A; border-color: #2A2826; border-radius: 2px"><h3 class="_906d8863" style="font-family: var(--font-display); color: #E8E4DC">One way to do things</h3><p class="_78b4a900" style="color: #9C9690">No choice paralysis. No tribal knowledge. Every API has one canonical pattern. Your team and your AI agent write the same code — correctly, on the first try.</p></div><div class="_78b40b7b" style="background: #1C1B1A; border-color: #2A2826; border-radius: 2px"><h3 class="_906d8863" style="font-family: var(--font-display); color: #E8E4DC">Production-ready by default</h3><p class="_78b4a900" style="color: #9C9690">Auth, validation, error handling, OpenAPI docs, deployment — built in, not bolted on. You add business logic. Vertz handles the rest.</p></div></div></div></section><section class="_6fd75a1a"><div class="_040e24c8"><p class="_eb61ece5" style="font-family: var(--font-mono)">The stack</p><h2 class="_20e9c695" style="font-family: var(--font-display); color: #E8E4DC">One framework. Not fifteen npm installs.</h2><p class="_38115631">Every layer works together because they were built together.</p><div class="_2629e5a1"><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #a78bfa">vertz/schema</div><div class="_262fe739">Runtime-safe type definitions</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Zod</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #60a5fa">vertz/db</div><div class="_262fe739">Typed queries &amp; migrations</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Drizzle / Prisma</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #34d399">vertz/server</div><div class="_262fe739">Entity-based CRUD + OpenAPI</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Express + tRPC</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #fbbf24">vertz/compiler</div><div class="_262fe739">Static analysis + SDK codegen</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Manual glue code</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #f472b6">vertz/ui</div><div class="_262fe739">Signals, query(), form(), css()</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces React + Tailwind</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #e879f9">vertz/ui-primitives</div><div class="_262fe739">Accessible components</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Radix / Base UI</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #f9a8d4">vertz/theme-shadcn</div><div class="_262fe739">Pre-built styled components</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces shadcn/ui</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #c084fc">vertz/ui-server</div><div class="_262fe739">SSR, streaming, HMR dev server</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Next.js + Vite</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #4ade80">vertz/testing</div><div class="_262fe739">API &amp; UI test utilities on vtz</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Vitest + Testing Library</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #fb923c">vertz/cloudflare</div><div class="_262fe739">Edge deployment</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces Dockerfile + infra</div></div><div class="_4ebb8ddd" style="border-bottom: 1px solid #2A2826"><div class="_4ebb84c7" style="font-family: var(--font-mono); color: #94a3b8">vertz/icons</div><div class="_262fe739">Tree-shakeable Lucide icons</div><div class="_9c3e7dd4" style="font-family: var(--font-mono)">replaces lucide-react</div></div></div></div></section><div style="height: 1px; width: 100%; max-width: 56rem; margin: 3rem auto; background: linear-gradient(to right, transparent, #2A2826, transparent)"></div><section class="_9aeb6fda" style="background: #0F0F0E; border-top: 1px solid #2A2826; border-bottom: 1px solid #2A2826"><div class="_447eaa88"><div><h2 class="_4bfddc55" style="font-family: var(--font-display); color: #E8E4DC">Get started in 30 seconds.</h2><p class="_82fb5f44" style="color: #9C9690">SQLite database, REST API, and UI — all running locally. No Docker. No config files. Edit any layer and see it update instantly.</p></div><div class="_0719f061" style="background: #1C1B1A; border-color: #2A2826; font-family: var(--font-mono)"><div class="_e998b2e9 _e04a4c35" style="color: #6B6560">$ curl -fsSL vertz.dev/vtz/install | sh</div><div class="_e998b2e9 _e04a4c35" style="color: #6B6560">$ vtz create my-app</div><div class="_e998b2e9 _e04a4c35" style="color: #6B6560">$ cd my-app</div><div class="_e04a4c35" style="color: #6B6560">$ vtz dev</div><div class="_66af6006" style="color: #C8451B">✓ SQLite database ready</div><div class="_c03496fe" style="color: #C8451B">✓ API server on http://localhost:3000/api</div><div class="_c03496fe" style="color: #C8451B">✓ UI on http://localhost:3000</div></div></div></section><section class="_06ac656e"><div class="_a453551c"><p class="_4d141339" style="font-family: var(--font-mono)">What about...</p><div class="_c4469175"><div class="_c4451948" style="border-color: #1e1e22"><p class="_d7f75d71">Is it production-ready?</p><p class="_d6e29889">Pre-v1 and moving fast. Cloudflare Workers deployment works today. We break APIs intentionally to find the best design — and we ship every improvement as a patch.</p></div><div class="_c4451948" style="border-color: #1e1e22"><p class="_d7f75d71">Can I use existing libraries?</p><p class="_d6e29889">Yes. Standard TypeScript, npm-compatible. Use any library you want alongside Vertz.</p></div><div class="_c4451948" style="border-color: #1e1e22"><p class="_d7f75d71">What if I only want the UI?</p><p class="_d6e29889">Use vertz/ui standalone. The full stack is optional — each layer works independently.</p></div><div class="_c4451948" style="border-color: #1e1e22"><p class="_d7f75d71">What about React / Next.js?</p><p class="_d6e29889">Vertz isn't a React wrapper. It's a different model: signals instead of VDOM, compile-time instead of runtime. If you're happy with React, stay. If you're tired of the ceremony, try Vertz.</p></div></div></div></section><div style="height: 1px; width: 100%; max-width: 56rem; margin: 3rem auto; background: linear-gradient(to right, transparent, #2A2826, transparent)"></div><section id="founders" class="_1e4e2a5c" style="background: #111110; border-top: 1px solid #2A2826"><div class="_2b7a0d8a"><p class="_69d4ea53">We spent years stitching together ORMs, API frameworks, validation libraries, and UI toolkits — and watching them drift apart. We built Vertz so the next team doesn't have to.</p><div class="_e42c342d"><div class="_e429bb81"><div class="_2f69af5e"><img src="/public/viniciusdacal.jpg" alt="Vinicius Dacal" width="80" height="80" style="width: 80px; height: 80px; object-fit: cover; border-radius: 9999px; outline: 2px solid #2A2826; outline-offset: 2px"></div><p class="_e42fc308">Vinicius Dacal</p><p class="_e4322ff9" style="font-family: var(--font-mono)">Co-founder</p><p class="_e0204841">15+ years building at scale. Senior Engineer at Scrunch. Previously Staff Engineer at Voiceflow. Led Angular-to-React migrations, built GraphQL servers, shipped NestJS backends — and got tired of fighting the frameworks.</p><a href="https://x.com/vinicius_dacal" target="_blank" rel="noopener" class="_65f3c470" style="font-family: var(--font-mono)"><span style="display: inline-flex; align-items: center; width: 16px; height: 16px; flex-shrink: 0">
<svg
  class="lucide lucide-twitter"
  xmlns="http://www.w3.org/2000/svg"
  width="16"
  height="16"
  viewBox="0 0 24 24"
  fill="none"
  stroke="currentColor"
  stroke-width="2"
  stroke-linecap="round"
  stroke-linejoin="round"
>
  <path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z" />
</svg>
</span>@vinicius_dacal</a></div><div class="_e429bb81"><div class="_2f69af5e"><img src="/public/matheuspoleza.jpg" alt="Matheus Poleza" width="80" height="80" style="width: 80px; height: 80px; object-fit: cover; border-radius: 9999px; outline: 2px solid #2A2826; outline-offset: 2px"></div><p class="_e42fc308">Matheus Poleza</p><p class="_e4322ff9" style="font-family: var(--font-mono)">Co-founder</p><p class="_e0204841">10+ years full-stack. Seed to Series C startups. Microservices, AI integration, performance at scale — now channeling it all into one stack that does it right.</p><a href="https://x.com/matheeuspoleza" target="_blank" rel="noopener" class="_65f3c470" style="font-family: var(--font-mono)"><span style="display: inline-flex; align-items: center; width: 16px; height: 16px; flex-shrink: 0">
<svg
  class="lucide lucide-twitter"
  xmlns="http://www.w3.org/2000/svg"
  width="16"
  height="16"
  viewBox="0 0 24 24"
  fill="none"
  stroke="currentColor"
  stroke-width="2"
  stroke-linecap="round"
  stroke-linejoin="round"
>
  <path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z" />
</svg>
</span>@matheeuspoleza</a></div></div></div></section><div style="height: 1px; width: 100%; max-width: 56rem; margin: 3rem auto; background: linear-gradient(to right, transparent, #2A2826, transparent)"></div><section id="community" class="_bf0950f0" style="background: #0F0F0E; border-top: 1px solid #2A2826"><div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 600px; height: 400px; pointer-events: none; background: radial-gradient(ellipse, rgba(88,101,242,0.15) 0%, transparent 70%); filter: blur(60px)"></div><div class="_e799291e" style="position: relative; z-index: 1"><div class="_72ad40b7"><div class="_722749ee"><span class="_bd525b35" style="background: #5865F2"></span><span class="_67a65e53" style="font-family: var(--font-mono)">Community</span></div><h2 class="_701bbd6b" style="font-family: var(--font-display); color: #E8E4DC">Build this with us.</h2><p class="_ec30e81a" style="color: #9C9690">Join the Discord. Talk to the founders, preview breaking changes, and help shape the APIs before v1.</p><a href="https://discord.gg/C7JkeBhH5" target="_blank" rel="noopener" class="_83474a73" style="font-family: var(--font-mono)"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.095 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.095 2.157 2.42 0 1.333-.947 2.418-2.157 2.418z"></path></svg>Join Discord →</a></div></div></section></main><footer class="_4a53be9f" style="border-color: #1e1e22"><div class="_4b3f2e73" style="font-family: var(--font-mono)"><div class="_c344352b"><a href="https://github.com/vertz-dev/vertz" target="_blank" rel="noopener" class="_bbe877be">GitHub</a><span class="_c745bba1">|</span><a href="https://discord.gg/C7JkeBhH5" target="_blank" rel="noopener" class="_bbe877be">Discord</a><span class="_c745bba1">|</span><a href="https://x.com/vinicius_dacal" target="_blank" rel="noopener" class="_bbe877be">@vinicius_dacal</a><span class="_c745bba1">|</span><a href="https://x.com/matheeuspoleza" target="_blank" rel="noopener" class="_bbe877be">@matheeuspoleza</a></div><div class="_c344352b"><a href="/openapi" class="_bbe877be">OpenAPI SDK Generator</a><span class="_c745bba1">|</span><span>MIT License</span><span class="_c745bba1">|</span><span>Powered by vtz</span></div></div></footer></div></div></div></div>
    <script type="module" crossorigin src="/assets/entry-client-mkd8330a.js"></script>
</body>
</html>