commit 14909ce4802aadaf0b4c20e6b58dc822ab071da5 Author: bivashy Date: Sat Jan 10 01:59:02 2026 +0500 Initial website implementation with Hero section diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a7f73a --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/README.md b/README.md new file mode 100644 index 0000000..25b5821 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# Nuxt Minimal Starter + +Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. + +## Setup + +Make sure to install dependencies: + +```bash +# npm +npm install + +# pnpm +pnpm install + +# yarn +yarn install + +# bun +bun install +``` + +## Development Server + +Start the development server on `http://localhost:3000`: + +```bash +# npm +npm run dev + +# pnpm +pnpm dev + +# yarn +yarn dev + +# bun +bun run dev +``` + +## Production + +Build the application for production: + +```bash +# npm +npm run build + +# pnpm +pnpm build + +# yarn +yarn build + +# bun +bun run build +``` + +Locally preview production build: + +```bash +# npm +npm run preview + +# pnpm +pnpm preview + +# yarn +yarn preview + +# bun +bun run preview +``` + +Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/app/app.vue b/app/app.vue new file mode 100644 index 0000000..812feb0 --- /dev/null +++ b/app/app.vue @@ -0,0 +1,11 @@ + + + diff --git a/app/assets/css/tailwind.css b/app/assets/css/tailwind.css new file mode 100644 index 0000000..83bc82f --- /dev/null +++ b/app/assets/css/tailwind.css @@ -0,0 +1,120 @@ +@import "tailwindcss"; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.147 0.004 49.25); + --card: oklch(1 0 0); + --card-foreground: oklch(0.147 0.004 49.25); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.147 0.004 49.25); + --primary: oklch(0.216 0.006 56.043); + --primary-foreground: oklch(0.985 0.001 106.423); + --secondary: oklch(0.97 0.001 106.424); + --secondary-foreground: oklch(0.216 0.006 56.043); + --muted: oklch(0.97 0.001 106.424); + --muted-foreground: oklch(0.553 0.013 58.071); + --accent: oklch(0.97 0.001 106.424); + --accent-foreground: oklch(0.216 0.006 56.043); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.923 0.003 48.717); + --input: oklch(0.923 0.003 48.717); + --ring: oklch(0.709 0.01 56.259); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0.001 106.423); + --sidebar-foreground: oklch(0.147 0.004 49.25); + --sidebar-primary: oklch(0.216 0.006 56.043); + --sidebar-primary-foreground: oklch(0.985 0.001 106.423); + --sidebar-accent: oklch(0.97 0.001 106.424); + --sidebar-accent-foreground: oklch(0.216 0.006 56.043); + --sidebar-border: oklch(0.923 0.003 48.717); + --sidebar-ring: oklch(0.709 0.01 56.259); +} + +.dark { + --background: oklch(0.147 0.004 49.25); + --foreground: oklch(0.985 0.001 106.423); + --card: oklch(0.216 0.006 56.043); + --card-foreground: oklch(0.985 0.001 106.423); + --popover: oklch(0.216 0.006 56.043); + --popover-foreground: oklch(0.985 0.001 106.423); + --primary: oklch(0.923 0.003 48.717); + --primary-foreground: oklch(0.216 0.006 56.043); + --secondary: oklch(0.268 0.007 34.298); + --secondary-foreground: oklch(0.985 0.001 106.423); + --muted: oklch(0.268 0.007 34.298); + --muted-foreground: oklch(0.709 0.01 56.259); + --accent: oklch(0.268 0.007 34.298); + --accent-foreground: oklch(0.985 0.001 106.423); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.553 0.013 58.071); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.216 0.006 56.043); + --sidebar-foreground: oklch(0.985 0.001 106.423); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0.001 106.423); + --sidebar-accent: oklch(0.268 0.007 34.298); + --sidebar-accent-foreground: oklch(0.985 0.001 106.423); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.553 0.013 58.071); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/app/components/ui/button-group/ButtonGroup.vue b/app/components/ui/button-group/ButtonGroup.vue new file mode 100644 index 0000000..9dbef6a --- /dev/null +++ b/app/components/ui/button-group/ButtonGroup.vue @@ -0,0 +1,22 @@ + + + diff --git a/app/components/ui/button-group/ButtonGroupSeparator.vue b/app/components/ui/button-group/ButtonGroupSeparator.vue new file mode 100644 index 0000000..e069dd5 --- /dev/null +++ b/app/components/ui/button-group/ButtonGroupSeparator.vue @@ -0,0 +1,24 @@ + + + diff --git a/app/components/ui/button-group/ButtonGroupText.vue b/app/components/ui/button-group/ButtonGroupText.vue new file mode 100644 index 0000000..c436843 --- /dev/null +++ b/app/components/ui/button-group/ButtonGroupText.vue @@ -0,0 +1,29 @@ + + + diff --git a/app/components/ui/button-group/index.ts b/app/components/ui/button-group/index.ts new file mode 100644 index 0000000..474566f --- /dev/null +++ b/app/components/ui/button-group/index.ts @@ -0,0 +1,25 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as ButtonGroup } from "./ButtonGroup.vue" +export { default as ButtonGroupSeparator } from "./ButtonGroupSeparator.vue" +export { default as ButtonGroupText } from "./ButtonGroupText.vue" + +export const buttonGroupVariants = cva( + "flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2", + { + variants: { + orientation: { + horizontal: + "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none", + vertical: + "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none", + }, + }, + defaultVariants: { + orientation: "horizontal", + }, + }, +) + +export type ButtonGroupVariants = VariantProps diff --git a/app/components/ui/button/Button.vue b/app/components/ui/button/Button.vue new file mode 100644 index 0000000..374320b --- /dev/null +++ b/app/components/ui/button/Button.vue @@ -0,0 +1,29 @@ + + + diff --git a/app/components/ui/button/index.ts b/app/components/ui/button/index.ts new file mode 100644 index 0000000..26e2c55 --- /dev/null +++ b/app/components/ui/button/index.ts @@ -0,0 +1,38 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as Button } from "./Button.vue" + +export const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + "default": "h-9 px-4 py-2 has-[>svg]:px-3", + "sm": "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + "lg": "h-10 rounded-md px-6 has-[>svg]:px-4", + "icon": "size-9", + "icon-sm": "size-8", + "icon-lg": "size-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +) +export type ButtonVariants = VariantProps diff --git a/app/components/ui/frame/Frame.vue b/app/components/ui/frame/Frame.vue new file mode 100644 index 0000000..abb798f --- /dev/null +++ b/app/components/ui/frame/Frame.vue @@ -0,0 +1,29 @@ + + + diff --git a/app/components/ui/frame/index.ts b/app/components/ui/frame/index.ts new file mode 100644 index 0000000..3f0c19d --- /dev/null +++ b/app/components/ui/frame/index.ts @@ -0,0 +1,60 @@ +import type { VariantProps } from "class-variance-authority" +import { cva } from "class-variance-authority" + +export { default as Frame } from "./Frame.vue" + +export const frameVariants = cva( + "border-solid", + { + variants: { + border: { + default: "border-border", + input: "border-input", + }, + borderRadius: { + default: "rounded-md", + round: "rounded-2xl", + circle: "rounded-full", + none: "", + }, + borderPlacement: { + default: "border-2", + bottom: "border-b-2", + left: "border-l-2", + right: "border-r-2", + top: "border-t-2", + }, + background: { + default: "bg-background", + muted: "bg-muted", + primary: "bg-primary" + }, + padding: { + default: "p-8", + loose: "p-12", + dense: "p-3", + none: "", + }, + margin: { + default: "m-12", + dense: "m-8", + none: "", + }, + }, + defaultVariants: { + border: "default", + borderRadius: "default", + borderPlacement: "default", + background: "default", + padding: "default", + margin: "default", + }, + }, +) + +export type FrameVariants = VariantProps + + + + + diff --git a/app/components/ui/input-group/InputGroup.vue b/app/components/ui/input-group/InputGroup.vue new file mode 100644 index 0000000..d32d69d --- /dev/null +++ b/app/components/ui/input-group/InputGroup.vue @@ -0,0 +1,35 @@ + + + diff --git a/app/components/ui/input-group/InputGroupAddon.vue b/app/components/ui/input-group/InputGroupAddon.vue new file mode 100644 index 0000000..709f482 --- /dev/null +++ b/app/components/ui/input-group/InputGroupAddon.vue @@ -0,0 +1,36 @@ + + + diff --git a/app/components/ui/input-group/InputGroupButton.vue b/app/components/ui/input-group/InputGroupButton.vue new file mode 100644 index 0000000..4e82e09 --- /dev/null +++ b/app/components/ui/input-group/InputGroupButton.vue @@ -0,0 +1,21 @@ + + + diff --git a/app/components/ui/input-group/InputGroupInput.vue b/app/components/ui/input-group/InputGroupInput.vue new file mode 100644 index 0000000..ca7cbb9 --- /dev/null +++ b/app/components/ui/input-group/InputGroupInput.vue @@ -0,0 +1,19 @@ + + + diff --git a/app/components/ui/input-group/InputGroupText.vue b/app/components/ui/input-group/InputGroupText.vue new file mode 100644 index 0000000..e317337 --- /dev/null +++ b/app/components/ui/input-group/InputGroupText.vue @@ -0,0 +1,19 @@ + + + diff --git a/app/components/ui/input-group/InputGroupTextarea.vue b/app/components/ui/input-group/InputGroupTextarea.vue new file mode 100644 index 0000000..2090be2 --- /dev/null +++ b/app/components/ui/input-group/InputGroupTextarea.vue @@ -0,0 +1,19 @@ + + +