# Card

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, } from "@/components/starwind/select";
---

<Card class="w-[360px]">
  <CardHeader>
    <CardTitle>Create project</CardTitle>
    <CardDescription>Deploy your new project in one-click.</CardDescription>
  </CardHeader>
  <CardContent class="flex flex-col gap-4">
    <div class="flex w-full flex-col gap-2">
      <Label for="project-name">Name</Label>
      <Input type="text" id="project-name" placeholder="Name of your project" />
    </div>
    <div class="flex w-full flex-col gap-2">
      <Label for="project-framework">Framework</Label>
      <Select name="framework" required>
        <SelectTrigger id="project-framework" class="w-full">
          <SelectValue placeholder="Select" />
        </SelectTrigger>
        <SelectContent>
          <SelectGroup>
            <SelectLabel>Frameworks</SelectLabel>
            <SelectItem value="astro">Astro</SelectItem>
            <SelectItem value="next">Next.js</SelectItem>
            <SelectItem value="svelte">SvelteKit</SelectItem>
            <SelectItem value="solid">SolidStart</SelectItem>
          </SelectGroup>
        </SelectContent>
      </Select>
    </div>
  </CardContent>
  <CardFooter class="flex justify-between">
    <Button variant="outline">Cancel</Button>
    <Button type="submit">Deploy</Button>
  </CardFooter>
</Card>
```
  </div>
  <div slot="react">
```tsx
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, } from "@/components/starwind/select";

export function Example() {
  return (
    <Card className="w-[360px]">
      <CardHeader>
        <CardTitle>Create project</CardTitle>
        <CardDescription>Deploy your new project in one-click.</CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <div className="flex w-full flex-col gap-2">
          <Label htmlFor="project-name">Name</Label>
          <Input type="text" id="project-name" placeholder="Name of your project" />
        </div>
        <div className="flex w-full flex-col gap-2">
          <Label htmlFor="project-framework">Framework</Label>
          <Select name="framework" required>
            <SelectTrigger id="project-framework" className="w-full">
              <SelectValue placeholder="Select" />
            </SelectTrigger>
            <SelectContent>
              <SelectGroup>
                <SelectLabel>Frameworks</SelectLabel>
                <SelectItem value="astro">Astro</SelectItem>
                <SelectItem value="next">Next.js</SelectItem>
                <SelectItem value="svelte">SvelteKit</SelectItem>
                <SelectItem value="solid">SolidStart</SelectItem>
              </SelectGroup>
            </SelectContent>
          </Select>
        </div>
      </CardContent>
      <CardFooter className="flex justify-between">
        <Button variant="outline">Cancel</Button>
        <Button type="submit">Deploy</Button>
      </CardFooter>
    </Card>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
  SelectGroup,
  SelectLabel,
  SelectSeparator,
} from "@/components/starwind/select";
</script>

<template>
  <Card class="w-[360px]">
    <CardHeader>
      <CardTitle>Create project</CardTitle>
      <CardDescription>Deploy your new project in one-click.</CardDescription>
    </CardHeader>
    <CardContent class="flex flex-col gap-4">
      <div class="flex w-full flex-col gap-2">
        <Label for="project-name">Name</Label>
        <Input type="text" id="project-name" placeholder="Name of your project" />
      </div>
      <div class="flex w-full flex-col gap-2">
        <Label for="project-framework">Framework</Label>
        <Select name="framework" required>
          <SelectTrigger id="project-framework" class="w-full">
            <SelectValue placeholder="Select" />
          </SelectTrigger>
          <SelectContent>
            <SelectGroup>
              <SelectLabel>Frameworks</SelectLabel>
              <SelectItem value="astro">Astro</SelectItem>
              <SelectItem value="next">Next.js</SelectItem>
              <SelectItem value="svelte">SvelteKit</SelectItem>
              <SelectItem value="solid">SolidStart</SelectItem>
            </SelectGroup>
          </SelectContent>
        </Select>
      </div>
    </CardContent>
    <CardFooter class="flex justify-between">
      <Button variant="outline">Cancel</Button>
      <Button type="submit">Deploy</Button>
    </CardFooter>
  </Card>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Installation

```bash
npx starwind@latest add card --framework astro
```
</DocsTabsContent>
```bash
npx starwind@latest add card --framework react
```
</DocsTabsContent>
```bash
npx starwind@latest add card --framework vue
```
</DocsTabsContent>
</DocsTabs>

## Usage

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, } from "@/components/starwind/select";
---

<Card class="w-[360px]">
  <CardHeader>
    <CardTitle>Create project</CardTitle>
    <CardDescription>Deploy your new project in one-click.</CardDescription>
  </CardHeader>
  <CardContent class="flex flex-col gap-4">
    <div class="flex w-full flex-col gap-2">
      <Label for="project-name">Name</Label>
      <Input type="text" id="project-name" placeholder="Name of your project" />
    </div>
    <div class="flex w-full flex-col gap-2">
      <Label for="project-framework">Framework</Label>
      <Select name="framework" required>
        <SelectTrigger id="project-framework" class="w-full">
          <SelectValue placeholder="Select" />
        </SelectTrigger>
        <SelectContent>
          <SelectGroup>
            <SelectLabel>Frameworks</SelectLabel>
            <SelectItem value="astro">Astro</SelectItem>
            <SelectItem value="next">Next.js</SelectItem>
            <SelectItem value="svelte">SvelteKit</SelectItem>
            <SelectItem value="solid">SolidStart</SelectItem>
          </SelectGroup>
        </SelectContent>
      </Select>
    </div>
  </CardContent>
  <CardFooter class="flex justify-between">
    <Button variant="outline">Cancel</Button>
    <Button type="submit">Deploy</Button>
  </CardFooter>
</Card>
```
  </div>
  <div slot="react">
```tsx
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, } from "@/components/starwind/select";

export function Example() {
  return (
    <Card className="w-[360px]">
      <CardHeader>
        <CardTitle>Create project</CardTitle>
        <CardDescription>Deploy your new project in one-click.</CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <div className="flex w-full flex-col gap-2">
          <Label htmlFor="project-name">Name</Label>
          <Input type="text" id="project-name" placeholder="Name of your project" />
        </div>
        <div className="flex w-full flex-col gap-2">
          <Label htmlFor="project-framework">Framework</Label>
          <Select name="framework" required>
            <SelectTrigger id="project-framework" className="w-full">
              <SelectValue placeholder="Select" />
            </SelectTrigger>
            <SelectContent>
              <SelectGroup>
                <SelectLabel>Frameworks</SelectLabel>
                <SelectItem value="astro">Astro</SelectItem>
                <SelectItem value="next">Next.js</SelectItem>
                <SelectItem value="svelte">SvelteKit</SelectItem>
                <SelectItem value="solid">SolidStart</SelectItem>
              </SelectGroup>
            </SelectContent>
          </Select>
        </div>
      </CardContent>
      <CardFooter className="flex justify-between">
        <Button variant="outline">Cancel</Button>
        <Button type="submit">Deploy</Button>
      </CardFooter>
    </Card>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
  SelectGroup,
  SelectLabel,
  SelectSeparator,
} from "@/components/starwind/select";
</script>

<template>
  <Card class="w-[360px]">
    <CardHeader>
      <CardTitle>Create project</CardTitle>
      <CardDescription>Deploy your new project in one-click.</CardDescription>
    </CardHeader>
    <CardContent class="flex flex-col gap-4">
      <div class="flex w-full flex-col gap-2">
        <Label for="project-name">Name</Label>
        <Input type="text" id="project-name" placeholder="Name of your project" />
      </div>
      <div class="flex w-full flex-col gap-2">
        <Label for="project-framework">Framework</Label>
        <Select name="framework" required>
          <SelectTrigger id="project-framework" class="w-full">
            <SelectValue placeholder="Select" />
          </SelectTrigger>
          <SelectContent>
            <SelectGroup>
              <SelectLabel>Frameworks</SelectLabel>
              <SelectItem value="astro">Astro</SelectItem>
              <SelectItem value="next">Next.js</SelectItem>
              <SelectItem value="svelte">SvelteKit</SelectItem>
              <SelectItem value="solid">SolidStart</SelectItem>
            </SelectGroup>
          </SelectContent>
        </Select>
      </div>
    </CardContent>
    <CardFooter class="flex justify-between">
      <Button variant="outline">Cancel</Button>
      <Button type="submit">Deploy</Button>
    </CardFooter>
  </Card>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Composition

Use the parts that match the content in your card:

```text
Card
├── CardHeader
│   ├── CardTitle
│   ├── CardDescription
│   └── CardAction
├── CardContent
└── CardFooter
```

## Form Submission

You can easily add a standard html form submission to your card. Here is a full example with the javascript submission code.

> **Tip:** Open up your browser's dev tools and view the console to see the form data.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/starwind/select";
---

<Card class="w-[360px]">
  <CardHeader>
    <CardTitle>Create project</CardTitle>
    <CardDescription>Deploy your new project in one-click.</CardDescription>
  </CardHeader>
  <form id="create-project-form">
    <CardContent class="flex flex-col gap-4">
      <div class="flex w-full flex-col gap-2">
        <Label for="create-project-name">Name</Label>
        <Input
          type="text"
          id="create-project-name"
          name="name"
          placeholder="Name of your project"
          required
        />
      </div>
      <div class="flex w-full flex-col gap-2">
        <Label for="create-project-framework">Framework</Label>
        <Select name="framework" required>
          <SelectTrigger id="create-project-framework" class="w-full">
            <SelectValue placeholder="Select" />
          </SelectTrigger>
          <SelectContent>
            <SelectGroup>
              <SelectLabel>Frameworks</SelectLabel>
              <SelectItem value="astro">Astro</SelectItem>
              <SelectItem value="next">Next.js</SelectItem>
              <SelectItem value="svelte">SvelteKit</SelectItem>
              <SelectItem value="solid">SolidStart</SelectItem>
            </SelectGroup>
          </SelectContent>
        </Select>
      </div>
    </CardContent>
    <CardFooter class="mt-6 flex justify-between">
      <Button type="button" variant="outline">Cancel</Button>
      <Button type="submit">Deploy</Button>
    </CardFooter>
  </form>
</Card>

<script>
  const setupForm = () => {
    const form = document.getElementById("create-project-form") as HTMLFormElement;
    if (!form) return;

    form.addEventListener("submit", (e) => {
      e.preventDefault();

      console.log(
        "Form submission data:",
        Object.fromEntries(new FormData(form).entries()),
      );
    });
  };

  setupForm();

  document.addEventListener("astro:after-swap", setupForm);
</script>
```
  </div>
  <div slot="react">
```tsx
import type { FormEvent } from "react";
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/starwind/select";

export function Example() {
  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    console.log(
      "Form submission data:",
      Object.fromEntries(new FormData(event.currentTarget).entries()),
    );
  }

  return (
    <Card className="w-[360px]">
      <CardHeader>
        <CardTitle>Create project</CardTitle>
        <CardDescription>Deploy your new project in one-click.</CardDescription>
      </CardHeader>
      <form onSubmit={handleSubmit}>
        <CardContent className="flex flex-col gap-4">
          <div className="flex w-full flex-col gap-2">
            <Label htmlFor="create-project-name">Name</Label>
            <Input
              type="text"
              id="create-project-name"
              name="name"
              placeholder="Name of your project"
              required
            />
          </div>
          <div className="flex w-full flex-col gap-2">
            <Label htmlFor="create-project-framework">Framework</Label>
            <Select name="framework" required>
              <SelectTrigger id="create-project-framework" className="w-full">
                <SelectValue placeholder="Select" />
              </SelectTrigger>
              <SelectContent>
                <SelectGroup>
                  <SelectLabel>Frameworks</SelectLabel>
                  <SelectItem value="astro">Astro</SelectItem>
                  <SelectItem value="next">Next.js</SelectItem>
                  <SelectItem value="svelte">SvelteKit</SelectItem>
                  <SelectItem value="solid">SolidStart</SelectItem>
                </SelectGroup>
              </SelectContent>
            </Select>
          </div>
        </CardContent>
        <CardFooter className="mt-6 flex justify-between">
          <Button type="button" variant="outline">Cancel</Button>
          <Button type="submit">Deploy</Button>
        </CardFooter>
      </form>
    </Card>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/starwind/select";

function submit(event: Event) {
  const form = event.currentTarget as HTMLFormElement;
  console.log("Form submission values:", Object.fromEntries(new FormData(form)));
}
</script>

<template>
  <Card class="w-[360px]">
    <CardHeader>
      <CardTitle>Create project</CardTitle>
      <CardDescription>Deploy your new project in one-click.</CardDescription>
    </CardHeader>
    <form @submit.prevent="submit" id="create-project-form">
      <CardContent class="flex flex-col gap-4">
        <div class="flex w-full flex-col gap-2">
          <Label for="create-project-name">Name</Label>
          <Input
            type="text"
            id="create-project-name"
            name="name"
            placeholder="Name of your project"
            required
          />
        </div>
        <div class="flex w-full flex-col gap-2">
          <Label for="create-project-framework">Framework</Label>
          <Select name="framework" required>
            <SelectTrigger id="create-project-framework" class="w-full">
              <SelectValue placeholder="Select" />
            </SelectTrigger>
            <SelectContent>
              <SelectGroup>
                <SelectLabel>Frameworks</SelectLabel>
                <SelectItem value="astro">Astro</SelectItem>
                <SelectItem value="next">Next.js</SelectItem>
                <SelectItem value="svelte">SvelteKit</SelectItem>
                <SelectItem value="solid">SolidStart</SelectItem>
              </SelectGroup>
            </SelectContent>
          </Select>
        </div>
      </CardContent>
      <CardFooter class="mt-6 flex justify-between">
        <Button type="button" variant="outline">Cancel</Button>
        <Button type="submit">Deploy</Button>
      </CardFooter>
    </form>
  </Card>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Size

Card supports `sm` and `md` sizes. It defaults to `md` when `size` is omitted; use `size="sm"`
for tighter spacing.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
---

<Card size="sm" class="mx-auto w-full max-w-sm">
  <CardHeader>
    <CardTitle>Small Card</CardTitle>
    <CardDescription>This card uses the small size variant.</CardDescription>
  </CardHeader>
  <CardContent>
    <p>
      The card component supports a size prop that can be set to "sm" for a more compact
      appearance.
    </p>
  </CardContent>
  <CardFooter>
    <Button variant="outline" size="sm" class="w-full">Action</Button>
  </CardFooter>
</Card>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";

export function Example() {
  return (
    <>
      <Card size="sm" className="mx-auto w-full max-w-sm">
        <CardHeader>
          <CardTitle>Small Card</CardTitle>
          <CardDescription>This card uses the small size variant.</CardDescription>
        </CardHeader>
        <CardContent>
          <p>
            The card component supports a size prop that can be set to "sm" for a more compact
            appearance.
          </p>
        </CardContent>
        <CardFooter>
          <Button variant="outline" size="sm" className="w-full">Action</Button>
        </CardFooter>
      </Card>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
</script>

<template>
  <Card size="sm" class="mx-auto w-full max-w-sm">
    <CardHeader>
      <CardTitle>Small Card</CardTitle>
      <CardDescription>This card uses the small size variant.</CardDescription>
    </CardHeader>
    <CardContent>
      <p>
        The card component supports a size prop that can be set to "sm" for a more compact
        appearance.
      </p>
    </CardContent>
    <CardFooter>
      <Button variant="outline" size="sm" class="w-full">Action</Button>
    </CardFooter>
  </Card>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Spacing

Use the `--card-spacing` CSS variable to control both the spacing between sections and the inset of Card parts.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { ToggleGroup, ToggleGroupItem } from "@/components/starwind/toggle-group";

const spacingOptions = [
  { className: "[--card-spacing:--spacing(4)]", label: "16px", value: "4" },
  { className: "[--card-spacing:--spacing(5)]", label: "20px", value: "5" },
  { className: "[--card-spacing:--spacing(6)]", label: "24px", value: "6" },
  { className: "[--card-spacing:--spacing(8)]", label: "32px", value: "8" },
] as const;
---

<div data-card-spacing-demo class="mx-auto grid w-full max-w-sm gap-4">
  <ToggleGroup
    data-card-spacing-controls
    defaultValue={["5"]}
    variant="outline"
    size="sm"
    spacing={2}
    class="mx-auto"
    aria-label="Card spacing"
  >
    {spacingOptions.map((option) => (
      <ToggleGroupItem value={option.value}>{option.label}</ToggleGroupItem>
    ))}
  </ToggleGroup>

  <Card data-card-spacing-preview class="[--card-spacing:--spacing(5)]">
    <CardHeader>
      <CardTitle>Login to your account</CardTitle>
      <CardDescription>Enter your email below to login to your account.</CardDescription>
      <CardAction>
        <Button variant="ghost" size="sm">Sign Up</Button>
      </CardAction>
    </CardHeader>
    <CardContent>
      <form class="flex flex-col gap-6">
        <div class="grid gap-2">
          <Label for="card-spacing-email">Email</Label>
          <Input id="card-spacing-email" type="email" placeholder="m@example.com" required />
        </div>
        <div class="grid gap-2">
          <div class="flex items-center">
            <Label for="card-spacing-password">Password</Label>
            <a href="#" class="ml-auto text-sm underline-offset-4 hover:underline">
              Forgot your password?
            </a>
          </div>
          <Input id="card-spacing-password" type="password" required />
        </div>
      </form>
    </CardContent>
    <CardFooter class="flex-col gap-2">
      <Button type="button" class="w-full">Login</Button>
      <Button type="button" variant="outline" class="w-full">Login with Google</Button>
    </CardFooter>
  </Card>
</div>

<script>
  const spacingClasses = [
    "[--card-spacing:--spacing(4)]",
    "[--card-spacing:--spacing(5)]",
    "[--card-spacing:--spacing(6)]",
    "[--card-spacing:--spacing(8)]",
  ];

  const setupCardSpacingDemos = () => {
    document.querySelectorAll<HTMLElement>("[data-card-spacing-demo]").forEach((demo) => {
      if (demo.dataset.cardSpacingReady === "true") return;

      const controls = demo.querySelector<HTMLElement>("[data-card-spacing-controls]");
      const card = demo.querySelector<HTMLElement>("[data-card-spacing-preview]");
      if (!controls || !card) return;

      controls.addEventListener("starwind:value-change", (event) => {
        const [value] = (event as CustomEvent<{ value: string[] }>).detail.value;
        const nextClass = spacingClasses.find((className) =>
          className.includes(`spacing(${value})`),
        );
        if (!nextClass) return;

        card.classList.remove(...spacingClasses);
        card.classList.add(nextClass);
      });

      demo.dataset.cardSpacingReady = "true";
    });
  };

  setupCardSpacingDemos();
  document.addEventListener("astro:after-swap", setupCardSpacingDemos);
</script>
```
  </div>
  <div slot="react">
```tsx
import { useState } from "react";
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { ToggleGroup, ToggleGroupItem } from "@/components/starwind/toggle-group";

const spacingOptions = [
  { className: "[--card-spacing:--spacing(4)]", label: "16px", value: "4" },
  { className: "[--card-spacing:--spacing(5)]", label: "20px", value: "5" },
  { className: "[--card-spacing:--spacing(6)]", label: "24px", value: "6" },
  { className: "[--card-spacing:--spacing(8)]", label: "32px", value: "8" },
] as const;

export function Example() {
  const [spacing, setSpacing] = useState("5");
  const cardClassName = spacingOptions.find((option) => option.value === spacing)?.className;

  return (
    <div className="mx-auto grid w-full max-w-sm gap-4">
      <ToggleGroup
        value={[spacing]}
        onValueChange={(values) => setSpacing(values[0] ?? spacing)}
        variant="outline"
        size="sm"
        spacing={2}
        className="mx-auto"
        aria-label="Card spacing"
      >
        {spacingOptions.map((option) => (
          <ToggleGroupItem key={option.value} value={option.value}>
            {option.label}
          </ToggleGroupItem>
        ))}
      </ToggleGroup>

      <Card className={cardClassName}>
        <CardHeader>
          <CardTitle>Login to your account</CardTitle>
          <CardDescription>Enter your email below to login to your account.</CardDescription>
          <CardAction>
            <Button variant="ghost" size="sm">Sign Up</Button>
          </CardAction>
        </CardHeader>
        <CardContent>
          <form className="flex flex-col gap-6">
            <div className="grid gap-2">
              <Label htmlFor="card-spacing-email">Email</Label>
              <Input id="card-spacing-email" type="email" placeholder="m@example.com" required />
            </div>
            <div className="grid gap-2">
              <div className="flex items-center">
                <Label htmlFor="card-spacing-password">Password</Label>
                <a href="#" className="ml-auto text-sm underline-offset-4 hover:underline">
                  Forgot your password?
                </a>
              </div>
              <Input id="card-spacing-password" type="password" required />
            </div>
          </form>
        </CardContent>
        <CardFooter className="flex-col gap-2">
          <Button type="button" className="w-full">Login</Button>
          <Button type="button" variant="outline" className="w-full">Login with Google</Button>
        </CardFooter>
      </Card>
    </div>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { ToggleGroup, ToggleGroupItem } from "@/components/starwind/toggle-group";
import { computed, ref } from "vue";

const spacingOptions = [
  { className: "[--card-spacing:--spacing(4)]", label: "16px", value: "4" },
  { className: "[--card-spacing:--spacing(5)]", label: "20px", value: "5" },
  { className: "[--card-spacing:--spacing(6)]", label: "24px", value: "6" },
  { className: "[--card-spacing:--spacing(8)]", label: "32px", value: "8" },
] as const;

const spacing = ref(["5"]);
const spacingClass = computed(
  () => spacingOptions.find((option) => option.value === spacing.value[0])?.className,
);
</script>

<template>
  <div data-card-spacing-demo class="mx-auto grid w-full max-w-sm gap-4">
    <ToggleGroup
      data-card-spacing-controls
      v-model="spacing"
      variant="outline"
      size="sm"
      :spacing="2"
      class="mx-auto"
      aria-label="Card spacing"
    >
      <template v-for="option in spacingOptions" :key="option.value">
        <ToggleGroupItem :value="option.value">{{ option.label }}</ToggleGroupItem>
      </template>
    </ToggleGroup>

    <Card data-card-spacing-preview :class="spacingClass">
      <CardHeader>
        <CardTitle>Login to your account</CardTitle>
        <CardDescription>Enter your email below to login to your account.</CardDescription>
        <CardAction>
          <Button variant="ghost" size="sm">Sign Up</Button>
        </CardAction>
      </CardHeader>
      <CardContent>
        <form class="flex flex-col gap-6">
          <div class="grid gap-2">
            <Label for="card-spacing-email">Email</Label>
            <Input id="card-spacing-email" type="email" placeholder="m@example.com" required />
          </div>
          <div class="grid gap-2">
            <div class="flex items-center">
              <Label for="card-spacing-password">Password</Label>
              <a href="#" class="ml-auto text-sm underline-offset-4 hover:underline">
                Forgot your password?
              </a>
            </div>
            <Input id="card-spacing-password" type="password" required />
          </div>
        </form>
      </CardContent>
      <CardFooter class="flex-col gap-2">
        <Button type="button" class="w-full">Login</Button>
        <Button type="button" variant="outline" class="w-full">Login with Google</Button>
      </CardFooter>
    </Card>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Image

Add an image before the card header to create a card with an image. Use the `CardAction` component to position a badge or other action in the header.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { Badge } from "@/components/starwind/badge";
import {
  Card,
  CardAction,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
---

<Card class="relative mx-auto w-full max-w-sm">
  <img
    src="https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=600&h=400&fit=crop"
    alt="Event cover"
    class="aspect-video w-full object-cover"
  />
  <CardHeader>
    <CardAction>
      <Badge size="sm" variant="primary">Featured</Badge>
    </CardAction>
    <CardTitle>Design systems meetup</CardTitle>
    <CardDescription>
      A practical talk on component APIs, accessibility, and shipping faster.
    </CardDescription>
  </CardHeader>
  <CardFooter>
    <Button class="w-full">View Event</Button>
  </CardFooter>
</Card>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { Badge } from "@/components/starwind/badge";
import {
  Card,
  CardAction,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";

export function Example() {
  return (
    <>
      <Card className="relative mx-auto w-full max-w-sm">
        <img
          src="https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=600&h=400&fit=crop"
          alt="Event cover"
          className="aspect-video w-full object-cover"
        />
        <CardHeader>
          <CardAction>
            <Badge size="sm" variant="primary">Featured</Badge>
          </CardAction>
          <CardTitle>Design systems meetup</CardTitle>
          <CardDescription>
            A practical talk on component APIs, accessibility, and shipping faster.
          </CardDescription>
        </CardHeader>
        <CardFooter>
          <Button className="w-full">View Event</Button>
        </CardFooter>
      </Card>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { Badge } from "@/components/starwind/badge";
import {
  Card,
  CardAction,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
</script>

<template>
  <Card class="relative mx-auto w-full max-w-sm">
    <img
      src="https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=600&h=400&fit=crop"
      alt="Event cover"
      class="aspect-video w-full object-cover"
    />
    <CardHeader>
      <CardAction>
        <Badge size="sm" variant="primary">Featured</Badge>
      </CardAction>
      <CardTitle>Design systems meetup</CardTitle>
      <CardDescription>
        A practical talk on component APIs, accessibility, and shipping faster.
      </CardDescription>
    </CardHeader>
    <CardFooter>
      <Button class="w-full">View Event</Button>
    </CardFooter>
  </Card>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## API Reference
### Card
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `size` | `"sm" \| "md"` | No | `"md"` | Styled variant | Selects the component's visual size. |
- Inherits div attributes.

### CardHeader
- Inherits div attributes.

### CardTitle
- Inherits div attributes.

### CardDescription
- Inherits div attributes.

### CardContent
- Inherits div attributes.

### CardFooter
- Inherits div attributes.

### CardAction
- Inherits div attributes.

## Changelog

### v2.3.1

- Named the generated aggregate default export so React and Astro tooling can identify the installed component cleanly.

### v2.3.0

- Renamed the standard Card size from `default` to `md`. Omitting `size` keeps the same medium spacing.

### v2.2.0

- Added the overridable `--card-spacing` CSS variable and default and small presets for coordinating section gaps and part insets consistently in Astro and React.

### v2.1.0

- Added contract-generated Astro and React implementations while preserving the component's existing public API and styling.

### v2.0.2

- Refactor tailwind variants functions into separate `variants.ts` file

### v2.0.0

- Added `size` prop to Card component (`"default"` | `"sm"`)
- Added `CardAction` component for positioning actions in card headers
- Added support for images within cards with automatic rounded corners
- Update styling to more closely match the shadcn/ui card component

### v1.3.0

- style updates

### v1.2.0

- Add a `data-slot` attribute to all components to enable global styling updates

### v1.1.0

- `tailwind-variants` now implemented. This uses `tailwind-merge` under the hood to merge Tailwind classes without style conflicts, allowing you to override any existing classes using the "class" prop.