diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..016b59e --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,24 @@ +# build output +dist/ + +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store + +# jetbrains setting folder +.idea/ diff --git a/web/.vscode/extensions.json b/web/.vscode/extensions.json new file mode 100644 index 0000000..22a1505 --- /dev/null +++ b/web/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + "recommendations": ["astro-build.astro-vscode"], + "unwantedRecommendations": [] +} diff --git a/web/.vscode/launch.json b/web/.vscode/launch.json new file mode 100644 index 0000000..d642209 --- /dev/null +++ b/web/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "command": "./node_modules/.bin/astro dev", + "name": "Development server", + "request": "launch", + "type": "node-terminal" + } + ] +} diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..1db3fb3 --- /dev/null +++ b/web/README.md @@ -0,0 +1,54 @@ +# Astro Starter Kit: Basics + +```sh +npm create astro@latest -- --template basics +``` + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics) +[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics) +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json) + +> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! + +![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554) + +## 🚀 Project Structure + +Inside of your Astro project, you'll see the following folders and files: + +```text +/ +├── public/ +│ └── favicon.svg +├── src/ +│ ├── components/ +│ │ └── Card.astro +│ ├── layouts/ +│ │ └── Layout.astro +│ └── pages/ +│ └── index.astro +└── package.json +``` + +Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. + +There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. + +Any static assets, like images, can be placed in the `public/` directory. + +## 🧞 Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `npm install` | Installs dependencies | +| `npm run dev` | Starts local dev server at `localhost:4321` | +| `npm run build` | Build your production site to `./dist/` | +| `npm run preview` | Preview your build locally, before deploying | +| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Get help using the Astro CLI | + +## 👀 Want to learn more? + +Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). diff --git a/web/astro.config.mjs b/web/astro.config.mjs new file mode 100644 index 0000000..1e8d329 --- /dev/null +++ b/web/astro.config.mjs @@ -0,0 +1,12 @@ +import { defineConfig } from "astro/config"; + +import tailwind from "@astrojs/tailwind"; + +// https://astro.build/config +export default defineConfig({ + integrations: [ + tailwind({ + applyBaseStyles: false, + }), + ], +}); diff --git a/web/bun.lockb b/web/bun.lockb new file mode 100755 index 0000000..9a27960 Binary files /dev/null and b/web/bun.lockb differ diff --git a/web/package.json b/web/package.json new file mode 100644 index 0000000..8728dbe --- /dev/null +++ b/web/package.json @@ -0,0 +1,28 @@ +{ + "name": "web", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro check && astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/check": "^0.7.0", + "@astrojs/tailwind": "^5.1.0", + "astro": "^4.11.3", + "autoprefixer": "^10.4.19", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "marked": "^13.0.1", + "motion": "^10.18.0", + "postcss": "^8.4.38", + "postcss-custom-media": "^10.0.6", + "postcss-import": "^16.1.0", + "tailwind-merge": "^2.3.0", + "tailwindcss": "^3.4.4", + "typescript": "^5.5.2" + } +} \ No newline at end of file diff --git a/web/postcss.config.cjs b/web/postcss.config.cjs new file mode 100644 index 0000000..228a086 --- /dev/null +++ b/web/postcss.config.cjs @@ -0,0 +1,11 @@ +const postcssImport = require("postcss-import"); +const nesting = require("tailwindcss/nesting"); +const tailwind = require("tailwindcss"); +const autoprefixer = require("autoprefixer"); +const customMedia = require("postcss-custom-media"); + +const config = { + plugins: [postcssImport, nesting, tailwind, autoprefixer, customMedia], +}; + +module.exports = config; diff --git a/web/public/favicon.svg b/web/public/favicon.svg new file mode 100644 index 0000000..f157bd1 --- /dev/null +++ b/web/public/favicon.svg @@ -0,0 +1,9 @@ + + + + diff --git a/web/src/components/Button.astro b/web/src/components/Button.astro new file mode 100644 index 0000000..1e7dd08 --- /dev/null +++ b/web/src/components/Button.astro @@ -0,0 +1,46 @@ +--- +import type { HTMLAttributes } from "astro/types"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/lib/utils"; + +export const button = cva( + cn( + "inline-flex items-center justify-center rounded-md text-sm font-medium", + "transition-colors focus-visible:outline-none", + "ring-main focus-visible:ring-2 focus-visible:ring-ring", + "focus-visible:ring-offset-2 disabled:opacity-50", + "disabled:pointer-events-none ring-offset-background" + ), + { + variants: { + variant: { + default: "bg-main text-neutral hocus:bg-main/80", + primary: + "bg-primary dark:bg-primary/50 text-neutral dark:text-main hocus:bg-primary/80 dark:hocus:bg-primary/80", + destructive: + "bg-error text-destructive-foreground hocus:bg-destructive/90", + outline: + "border border-input hover:bg-accent hover:text-accent-foreground", + secondary: "bg-main/10 text-main hocus:bg-main/20", + ghost: "hocus:bg-accent hocus:text-accent-foreground", + link: "underline-offset-4 hocus:underline text-primary", + }, + size: { + default: "h-10 text-base py-2 px-4", + sm: "h-9 px-3 rounded-md", + lg: "h-11 px-8 rounded-md", + }, + }, + } +); + +export interface Props + extends HTMLAttributes<"button">, + VariantProps {} + +const { variant = "default", size = "default", ...props } = Astro.props; +--- + + diff --git a/web/src/components/Card.astro b/web/src/components/Card.astro new file mode 100644 index 0000000..973b8bd --- /dev/null +++ b/web/src/components/Card.astro @@ -0,0 +1,36 @@ +--- +import type { HTMLAttributes } from "astro/types"; +import { type VariantProps, cva } from "class-variance-authority"; + +const card = cva( + "card rounded-card transition-colors bg-neutral-accent ring-2 ring-main/10", + { + variants: { + interactable: { + false: "transition-shadow focus-within:shadow-lg ring-2 ring-neutral", + true: "cursor-pointer shadow-sm hocus:bg-neutral-accent/50 \ + hocus:shadow-lg hocus:ring-2 hocus:outline-none", + }, + padding: { + true: "py-6 px-8", + false: "p-0", + }, + }, + } +); + +export interface Props + extends HTMLAttributes<"div">, + VariantProps {} + +const { + interactable = false, + padding = true, + class: _class, + ...props +} = Astro.props; +--- + +
+ +
diff --git a/web/src/components/Heading.astro b/web/src/components/Heading.astro new file mode 100644 index 0000000..f90ca39 --- /dev/null +++ b/web/src/components/Heading.astro @@ -0,0 +1,52 @@ +--- +import { cn } from "@/lib/utils"; +import type { HTMLAttributes } from "astro/types"; +import { VariantProps, cva } from "class-variance-authority"; + +const heading = cva("max-w-3xl m-[var(--section-heading-margin)]", { + variants: { + main: { + true: "font-bold", + false: "font-semibold", + }, + padding: { + true: "py-4", + false: "p-0", + }, + }, +}); + +export interface Props + extends HTMLAttributes<"h1" | "h2">, + VariantProps { + subtitle?: string; +} + +const { main = false, padding = true, subtitle } = Astro.props; + +const titleClass = cn( + heading({ main, padding }), + subtitle ? "mb-[calc(var(--section_heading-margin-bottom)_/_2)]" : "" +); +--- + +
+ { + main ? ( +

+ +

+ ) : ( +

+ +

+ ) + } + { + subtitle && ( +

+ {subtitle} +

+ ) + } +
diff --git a/web/src/components/Layout/Footer.astro b/web/src/components/Layout/Footer.astro new file mode 100644 index 0000000..f7f9522 --- /dev/null +++ b/web/src/components/Layout/Footer.astro @@ -0,0 +1,92 @@ +--- +import Section from "../Section.astro"; + +enum NavigationItemType { + Link, + Text, +} + +type NavigationItem = + | { + path: string; + label: string; + type: NavigationItemType.Link; + } + | { + type: NavigationItemType.Text; + content: string; + }; + +type NavigationGroup = { + title: string; + class?: string; + items: Array; +}; + +const tree: Array = [ + { + title: "Overview", + items: [ + { + path: "/", + type: NavigationItemType.Link, + label: "Landing", + }, + { + path: "https://github.com/tempblade/creator", + type: NavigationItemType.Link, + label: "GitHub", + }, + { + path: "https://tempblade.com", + type: NavigationItemType.Link, + label: "tempblade", + }, + ], + }, + { + title: "Legal", + items: [ + { + path: "/legal/imprint", + label: "Imprint", + type: NavigationItemType.Link, + }, + ], + }, + { + title: "", + class: "ml-auto mr-0 self-end", + items: [ + { + type: NavigationItemType.Text, + content: "Made with ❤️ in Rottweil", + }, + ], + }, +]; +--- + +
+
+
+ { + tree.map((group) => ( +
+ {group.title &&

{group.title}

} +
+ {group.items.map((item) => { + switch (item.type) { + case NavigationItemType.Link: + return {item.label}; + case NavigationItemType.Text: + return

{item.content}

; + } + })} +
+
+ )) + } +
+
+
diff --git a/web/src/components/Layout/Header.astro b/web/src/components/Layout/Header.astro new file mode 100644 index 0000000..2847ccb --- /dev/null +++ b/web/src/components/Layout/Header.astro @@ -0,0 +1,18 @@ +--- +import { button } from "../Button.astro"; +import Logo from "components/Logo/Logo.astro"; +--- + +
+
+
+ +
+ Download +
+
diff --git a/web/src/components/Logo/Logo.astro b/web/src/components/Logo/Logo.astro new file mode 100644 index 0000000..70ea964 --- /dev/null +++ b/web/src/components/Logo/Logo.astro @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/web/src/components/Section.astro b/web/src/components/Section.astro new file mode 100644 index 0000000..d612a9b --- /dev/null +++ b/web/src/components/Section.astro @@ -0,0 +1,27 @@ +--- +import type { HTMLAttributes } from "astro/types"; +import { cva, type VariantProps } from "class-variance-authority"; + +const section = cva("relative w-full", { + variants: { + padding: { + true: "p-main", + false: "p-0", + }, + maxWidth: { + true: "max-w-section mx-auto", + false: "", + }, + }, +}); + +export interface Props + extends HTMLAttributes<"section">, + VariantProps {} + +const { padding = true, maxWidth = true, ...props } = Astro.props; +--- + +
+ +
diff --git a/web/src/env.d.ts b/web/src/env.d.ts new file mode 100644 index 0000000..f964fe0 --- /dev/null +++ b/web/src/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/web/src/layouts/RootLayout.astro b/web/src/layouts/RootLayout.astro new file mode 100644 index 0000000..b501596 --- /dev/null +++ b/web/src/layouts/RootLayout.astro @@ -0,0 +1,32 @@ +--- +import Footer from "@/components/Layout/Footer.astro"; +import Header from "@/components/Layout/Header.astro"; +import "@/styles/global.css"; + +export interface Props { + title: string; +} + +const { title } = Astro.props; +--- + + + + + + + + + + + {title} + + +
+ +