├── .husky
├── .gitignore
├── pre-commit
├── commit-msg
├── prepare-commit-msg
└── common.sh
├── .npmrc
├── .commitlintrc.json
├── public
├── screenshot.png
├── images
│ ├── case-1.webp
│ ├── case-2.webp
│ ├── case-3.webp
│ ├── social-1.webp
│ └── social-2.webp
└── logo.svg
├── src
├── styles
│ └── global.css
├── constants
│ └── svg
│ │ ├── quote.svg
│ │ ├── arrow.svg
│ │ ├── play.svg
│ │ ├── check.svg
│ │ ├── nike.svg
│ │ ├── figma.svg
│ │ ├── aws.svg
│ │ ├── netlify.svg
│ │ ├── preferences.svg
│ │ └── features.svg
├── pages
│ ├── api
│ │ └── hello.ts
│ ├── _app.tsx
│ ├── index.tsx
│ └── _document.tsx
├── twind.config.js
└── components
│ ├── page
│ └── index.tsx
│ ├── button
│ └── index.tsx
│ ├── video-section
│ └── index.tsx
│ ├── header
│ └── index.tsx
│ ├── list-section
│ └── index.tsx
│ ├── pricing-table
│ └── index.tsx
│ ├── footer
│ └── index.tsx
│ ├── cases-section
│ └── index.tsx
│ ├── feature-section
│ └── index.tsx
│ ├── social-proof
│ └── index.tsx
│ └── navigation
│ └── index.tsx
├── .editorconfig
├── renovate.json
├── next.config.js
├── next-env.d.ts
├── .prettierrc
├── .gitignore
├── tsconfig.json
├── LICENSE.md
├── package.json
├── README.md
└── .eslintrc
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | save-exact = true
2 |
--------------------------------------------------------------------------------
/.commitlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@commitlint/config-conventional"]
3 | }
4 |
--------------------------------------------------------------------------------
/public/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkytoela/next-startd/HEAD/public/screenshot.png
--------------------------------------------------------------------------------
/public/images/case-1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkytoela/next-startd/HEAD/public/images/case-1.webp
--------------------------------------------------------------------------------
/public/images/case-2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkytoela/next-startd/HEAD/public/images/case-2.webp
--------------------------------------------------------------------------------
/public/images/case-3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkytoela/next-startd/HEAD/public/images/case-3.webp
--------------------------------------------------------------------------------
/public/images/social-1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkytoela/next-startd/HEAD/public/images/social-1.webp
--------------------------------------------------------------------------------
/public/images/social-2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkytoela/next-startd/HEAD/public/images/social-2.webp
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 | . "$(dirname "$0")/common.sh"
4 |
5 | yarn lint-staged
6 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 | . "$(dirname "$0")/common.sh"
4 |
5 | yarn commitlint --edit $1
6 |
--------------------------------------------------------------------------------
/src/styles/global.css:
--------------------------------------------------------------------------------
1 | @import "@fontsource/inter/400.css";
2 | @import "@fontsource/inter/500.css";
3 | @import "@fontsource/inter/700.css";
4 |
--------------------------------------------------------------------------------
/.husky/prepare-commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 | . "$(dirname "$0")/common.sh"
4 |
5 | exec < /dev/tty && yarn cz --hook || true
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | charset = utf-8
7 | end_of_line = lf
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["config:base"],
3 | "semanticCommits": true,
4 | "stabilityDays": 3,
5 | "prCreation": "not-pending",
6 | "labels": ["type: dependencies"]
7 | }
8 |
--------------------------------------------------------------------------------
/.husky/common.sh:
--------------------------------------------------------------------------------
1 | command_exists () {
2 | command -v "$1" >/dev/null 2>&1
3 | }
4 |
5 | # Workaround for Windows 10, Git Bash and Yarn
6 | if command_exists winpty && test -t 1; then
7 | exec < /dev/tty
8 | fi
9 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpack(config) {
3 | config.module.rules.push({
4 | test: /\.svg$/,
5 | use: [`@svgr/webpack`],
6 | });
7 |
8 | return config;
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // eslint-disable-next-line prettier/prettier
5 | declare module "*.svg" {
6 | const content: any;
7 | export default content;
8 | }
9 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "singleQuote": true,
4 | "tabWidth": 2,
5 | "printWidth": 120,
6 | "proseWrap": "preserve",
7 | "useTabs": false,
8 | "bracketSpacing": true,
9 | "arrowParens": "always"
10 | }
11 |
--------------------------------------------------------------------------------
/src/constants/svg/quote.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/constants/svg/arrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/constants/svg/play.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/pages/api/hello.ts:
--------------------------------------------------------------------------------
1 | import { NextApiRequest, NextApiResponse } from 'next';
2 |
3 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
4 | export default (req: NextApiRequest, res: NextApiResponse) => {
5 | res.statusCode = 200;
6 | res.json({ name: `John Doe` });
7 | };
8 |
--------------------------------------------------------------------------------
/src/twind.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | theme: {
3 | extend: {
4 | fontFamily: {
5 | sans: `Inter, ui-sans-serif, system-ui, -apple-system,
6 | BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans",
7 | sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"`,
8 | },
9 | },
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import { AppProps } from 'next/app';
2 | import '@/styles/global.css';
3 | import '@fontsource/inter';
4 |
5 | import { setup } from 'twind';
6 | import twindConfig from '../twind.config';
7 |
8 | if (typeof window !== `undefined`) {
9 | setup(twindConfig);
10 | }
11 |
12 | export default function MyApp({ Component, pageProps }: AppProps) {
13 | return ;
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/page/index.tsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head';
2 | import Navigation from '@/components/navigation';
3 | import { tw } from 'twind';
4 |
5 | interface IProps {
6 | children: React.ReactNode;
7 | }
8 |
9 | const Page = ({ children }: IProps) => (
10 |
11 |
12 |
13 |
14 |
15 |
16 | {children}
17 |
18 |
19 | );
20 |
21 | export default Page;
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/src/constants/svg/check.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2015",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "baseUrl": "./src",
17 | "paths": {
18 | "@/*": ["./*"]
19 | }
20 | },
21 | "exclude": ["node_modules"],
22 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/button/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 |
3 | interface IButton {
4 | primary?: boolean;
5 | children: React.ReactNode;
6 | modifier?: string;
7 | }
8 |
9 | const Button = ({ primary, modifier, children, ...rest }: IButton) => {
10 | const baseStyle = `font-sans font-medium py-2 px-4 border rounded`;
11 | const styles = primary
12 | ? `bg-indigo-600 text-white border-indigo-500 hover:bg-indigo-700`
13 | : `bg-white text-gray-600 border-gray-300 hover:bg-gray-100`;
14 |
15 | return (
16 |
17 | {children}
18 |
19 | );
20 | };
21 |
22 | export default Button;
23 |
--------------------------------------------------------------------------------
/src/constants/svg/nike.svg:
--------------------------------------------------------------------------------
1 | Nike
2 |
--------------------------------------------------------------------------------
/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { NextSeo } from 'next-seo';
2 | import Page from '@/components/page';
3 | import Header from '@/components/header';
4 | import VideoSection from '@/components/video-section';
5 | import ListSection from '@/components/list-section';
6 | import FeatureSection from '@/components/feature-section';
7 | import CasesSection from '@/components/cases-section';
8 | import SocialProof from '@/components/social-proof';
9 | import PricingTable from '@/components/pricing-table';
10 | import Footer from '@/components/footer';
11 |
12 | export default function Home() {
13 | return (
14 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Jaakko Kytölä
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/components/video-section/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import Preferences from '@/constants/svg/preferences.svg';
3 | import Play from '@/constants/svg/play.svg';
4 |
5 | const PlayButton = () => (
6 |
14 |
15 | Watch the video (5 min)
16 |
17 | );
18 |
19 | const VideoSection = () => (
20 |
32 | );
33 |
34 | export default VideoSection;
35 |
--------------------------------------------------------------------------------
/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import Document, { DocumentContext, Html, Head, Main, NextScript } from 'next/document';
3 | import { setup } from 'twind';
4 | import { asyncVirtualSheet, getStyleTagProperties } from 'twind/server';
5 | import twindConfig from '../twind.config';
6 |
7 | const sheet = asyncVirtualSheet();
8 |
9 | setup({ ...twindConfig, sheet });
10 |
11 | class MyDocument extends Document {
12 | static async getInitialProps(ctx: DocumentContext) {
13 | sheet.reset();
14 | const initialProps = await Document.getInitialProps(ctx);
15 | const { id, textContent } = getStyleTagProperties(sheet);
16 | const styleProps = {
17 | id,
18 | key: id,
19 | dangerouslySetInnerHTML: {
20 | __html: textContent,
21 | },
22 | };
23 |
24 | return {
25 | ...initialProps,
26 | styles: [
27 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
28 | // @ts-ignore
29 | ...initialProps.styles,
30 | React.createElement(`style`, styleProps),
31 | ],
32 | };
33 | }
34 |
35 | render() {
36 | return (
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | );
47 | }
48 | }
49 |
50 | export default MyDocument;
51 |
--------------------------------------------------------------------------------
/src/components/header/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw, css } from 'twind/css';
2 | import Button from '@/components/button';
3 | import Netlify from '@/constants/svg/netlify.svg';
4 | import Nike from '@/constants/svg/nike.svg';
5 | import Figma from '@/constants/svg/figma.svg';
6 | import Aws from '@/constants/svg/aws.svg';
7 |
8 | const headerStyle = css`
9 | background-color: #ffffff;
10 | min-height: calc(100vh - 6rem);
11 | `;
12 |
13 | const Header = () => (
14 |
42 | );
43 |
44 | export default Header;
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "startd-theme",
3 | "description": "A TypeScript/Next.js theme that includes everything you need to build amazing landing page!",
4 | "version": "1.0.0",
5 | "private": true,
6 | "author": "Jaakko Kytölä (jaakkokytola.com)",
7 | "license": "MIT",
8 | "keywords": [
9 | "nextjs",
10 | "starter",
11 | "typescript",
12 | "tailwind",
13 | "theme"
14 | ],
15 | "scripts": {
16 | "dev": "next",
17 | "build": "next build",
18 | "start": "next start",
19 | "type-check": "tsc",
20 | "lint": "eslint --ignore-path .gitignore \"src/**/*.+(ts|js|tsx)\"",
21 | "format": "prettier --ignore-path .gitignore \"src/**/*.+(ts|js|tsx)\" --write",
22 | "postinstall": "husky install"
23 | },
24 | "lint-staged": {
25 | "./src/**/*.{ts,js,jsx,tsx}": [
26 | "yarn lint --fix",
27 | "yarn format"
28 | ]
29 | },
30 | "dependencies": {
31 | "@fontsource/inter": "4.2.1",
32 | "@svgr/webpack": "5.5.0",
33 | "next": "10.0.7",
34 | "next-seo": "4.20.0",
35 | "react": "17.0.1",
36 | "react-dom": "17.0.1",
37 | "react-particles-js": "3.4.1",
38 | "twind": "0.15.4"
39 | },
40 | "devDependencies": {
41 | "@commitlint/cli": "11.0.0",
42 | "@commitlint/config-conventional": "11.0.0",
43 | "@types/node": "14.14.28",
44 | "@types/react": "17.0.2",
45 | "@types/react-dom": "17.0.1",
46 | "@typescript-eslint/eslint-plugin": "4.15.1",
47 | "@typescript-eslint/parser": "4.15.1",
48 | "commitizen": "4.2.3",
49 | "cz-conventional-changelog": "3.3.0",
50 | "eslint": "7.20.0",
51 | "eslint-config-airbnb": "18.2.1",
52 | "eslint-config-prettier": "7.2.0",
53 | "eslint-import-resolver-typescript": "2.4.0",
54 | "eslint-plugin-import": "2.22.1",
55 | "eslint-plugin-jsx-a11y": "6.4.1",
56 | "eslint-plugin-prettier": "3.3.1",
57 | "eslint-plugin-react": "7.22.0",
58 | "eslint-plugin-react-hooks": "4.2.0",
59 | "husky": "5.0.9",
60 | "lint-staged": "10.5.4",
61 | "prettier": "2.2.1",
62 | "typescript": "4.1.5"
63 | },
64 | "config": {
65 | "commitizen": {
66 | "path": "cz-conventional-changelog"
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | A free Next.js TypeScript landing page template for SaaS products, online services and more.
13 |
14 | Live demo
15 |
16 | - ⚡ **Next.js** — The React Framework
17 | - 🔥 **next-seo** — Manage SEO easily
18 | - 💡 **Twind** — The smallest, fastest, most feature complete Tailwind-in-JS solution in existence
19 | - 📏 **ESLint** — Pluggable JavaScript linter
20 | - 💖 **Prettier** — Opinionated Code Formatter
21 | - 🐶 **Husky** — Use git hooks with ease
22 | - 📄 **Commitizen** — Conventional commit messages CLI
23 | - 🚓 **Commitlint** — Lint commit messages
24 | - 🖌 **Renovate** — Dependency update tool
25 | - 🚫 **lint-staged** — Run linters against staged git files
26 | - 🗂 **Absolute import** — Import folders and files using the `@` prefix
27 |
28 | ## 🚀 Getting started
29 |
30 | If you're logged in, easiest way to get started is to [click here](https://github.com/jkytoela/next-startd/generate).
31 |
32 | Run the following commands inside the project folder:
33 |
34 | 1. `yarn`
35 | 2. `yarn dev`
36 |
37 | To view the project open `http://localhost:3000`
38 |
39 |
40 | ## 🤝 Contributing
41 |
42 | 1. Fork this repository
43 | 2. Create your branch: `git checkout -b my-new-feature`
44 | 3. Commit your changes: `git commit -m 'Add some feature'`
45 | 4. Push to the branch: `git push origin my-new-feature`
46 |
47 | Consider contributing to the original TypeScript Starter, which you can find [here](https://github.com/jpedroschmitz).
48 |
49 | **After your pull request is merged**, you can safely delete your branch.
50 |
51 | ## 📝 License
52 |
53 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for more information.
54 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "parserOptions": {
7 | "ecmaFeatures": {
8 | "jsx": true
9 | },
10 | "ecmaVersion": 2019,
11 | "sourceType": "module"
12 | },
13 | "globals": {
14 | "Atomics": "readonly",
15 | "SharedArrayBuffer": "readonly"
16 | },
17 | "plugins": ["import", "jsx-a11y", "react", "react-hooks", "prettier"],
18 | "extends": ["airbnb", "eslint-config-prettier", "prettier/react"],
19 | "rules": {
20 | "prettier/prettier": "error",
21 | "camelcase": "off",
22 | "import/prefer-default-export": "off",
23 | "react/prop-types": "off",
24 | "react/jsx-filename-extension": "off",
25 | "react/jsx-props-no-spreading": "off",
26 | "react/no-unused-prop-types": "off",
27 | "react/react-in-jsx-scope": "off",
28 | "react/require-default-props": "off",
29 | "import/extensions": [
30 | "error",
31 | "ignorePackages",
32 | {
33 | "ts": "never",
34 | "tsx": "never",
35 | "js": "never",
36 | "jsx": "never"
37 | }
38 | ],
39 | "quotes": "off",
40 | "jsx-a11y/anchor-is-valid": [
41 | "error",
42 | {
43 | "components": ["Link"],
44 | "specialLink": ["hrefLeft", "hrefRight"],
45 | "aspects": ["invalidHref", "preferButton"]
46 | }
47 | ]
48 | },
49 | "overrides": [
50 | {
51 | "files": "**/*.+(ts|tsx)",
52 | "parser": "@typescript-eslint/parser",
53 | "plugins": ["@typescript-eslint/eslint-plugin"],
54 | "extends": [
55 | "plugin:@typescript-eslint/recommended",
56 | "eslint-config-prettier/@typescript-eslint"
57 | ],
58 | "rules": {
59 | "@typescript-eslint/explicit-function-return-type": "off",
60 | "@typescript-eslint/explicit-module-boundary-types": "off",
61 | "no-use-before-define": [0],
62 | "@typescript-eslint/no-use-before-define": [1],
63 | "@typescript-eslint/no-explicit-any": "off",
64 | "@typescript-eslint/no-var-requires": "off",
65 | "max-len": ["error", {"code": 120, "ignoreUrls": true}],
66 | "react/jsx-first-prop-new-line": [2, "multiline"],
67 | "react/jsx-max-props-per-line": [
68 | 2,
69 | { "maximum": 1, "when": "multiline" }
70 | ],
71 | "@typescript-eslint/quotes": [
72 | 2,
73 | "backtick",
74 | {
75 | "avoidEscape": true
76 | }
77 | ]
78 | }
79 | }
80 | ],
81 | "settings": {
82 | "import/resolver": {
83 | "typescript": {
84 | "project": "."
85 | }
86 | },
87 | "react": {
88 | "version": "detect"
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/components/list-section/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import FeatureSvg from '@/constants/svg/features.svg';
3 |
4 | const listItems = [
5 | {
6 | title: `Designers`,
7 | description: `Officia et fugiat mollit qui. Dolor elit aliqua voluptate ipsum
8 | excepteur cillum consequat consectetur duis magna qui eu consequat occaecat.
9 | Deserunt nisi sit.`,
10 | },
11 | {
12 | title: `Developers`,
13 | description: `Pariatur consectetur laboris exercitation duis laboris.
14 | Commodo duis fugiat magna fugiat et ut anim elit. Tempor aute ex qui
15 | tempor tempor.`,
16 | },
17 | {
18 | title: `Product owners`,
19 | description: `Ullamco consectetur ipsum eiusmod nisi adipisicing sint anim
20 | dolore aute excepteur. Voluptate ea ullamco sunt eu elit qui aliquip.
21 | Adipisicing.`,
22 | },
23 | ];
24 |
25 | const ListSection = () => (
26 |
27 |
28 |
29 |
Grow your revenue
30 |
31 | Transform your business
32 |
33 |
34 |
62 |
63 |
64 | );
65 |
66 | export default ListSection;
67 |
--------------------------------------------------------------------------------
/src/components/pricing-table/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import Check from '@/constants/svg/check.svg';
3 | import Button from '@/components/button';
4 |
5 | const features = [
6 | `Laboris nulla`,
7 | `Lorem pariatur nisi`,
8 | `Id aute amet pariatur`,
9 | `Do duis sint aliquip`,
10 | `Nostrud duis tempor`,
11 | `Consequat eiusmod`,
12 | `Reprehenderit`,
13 | `Adipisicing reprehenderit`,
14 | ];
15 |
16 | const PricingTable = () => (
17 |
18 |
19 |
20 |
21 |
Are you ready?
22 |
23 | Lorem id ullamco pariatur eiusmod labore qui deserunt incididunt deserunt nostrud. Tempor duis in
24 | adipisicing exercitation ipsum nostrud esse. Reprehenderit cupidatat sint est deserunt id eiusmod amet
25 | aliqua officia.
26 |
27 |
28 |
29 |
35 | What is included
36 |
37 |
38 |
39 |
40 | {features.map((feature) => (
41 |
42 |
43 |
44 |
45 | {feature}
46 |
47 | ))}
48 |
49 |
50 |
51 |
57 |
If you order now...
58 |
59 | $99/mo
60 |
61 |
62 | Contact sales
63 |
64 |
65 |
66 |
67 |
68 | );
69 |
70 | export default PricingTable;
71 |
--------------------------------------------------------------------------------
/src/constants/svg/figma.svg:
--------------------------------------------------------------------------------
1 | Figma
2 |
--------------------------------------------------------------------------------
/src/components/footer/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import Button from '@/components/button';
3 |
4 | const productLinks = [`Features`, `Customers`, `Platform`, `Pricing`, `Enterprise`, `What's new?`];
5 | const aboutLinks = [`About Us`, `Careers`, `Leadership`, `Blog`, `Events`, `Press`];
6 | const resourceLinks = [
7 | `Get started`,
8 | `Guides`,
9 | `Tools`,
10 | `Case studies`,
11 | `Solutions`,
12 | `FAQs`,
13 | `Help Center`,
14 | `Training`,
15 | `Other resources`,
16 | ];
17 |
18 | const Footer = () => (
19 |
20 |
21 |
22 |
23 |
STARTD
24 |
25 |
26 |
27 |
28 |
29 |
Product
30 |
31 | {productLinks.map((link) => (
32 |
33 | {link}
34 |
35 | ))}
36 |
37 |
38 |
39 |
40 |
41 |
Resources
42 |
43 | {resourceLinks.map((link) => (
44 |
45 | {link}
46 |
47 | ))}
48 |
49 |
50 |
51 |
52 |
53 |
About Us
54 |
55 | {aboutLinks.map((link) => (
56 |
57 | {link}
58 |
59 | ))}
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
Subscribe our newsletter
68 |
69 |
75 | Subscribe
76 |
77 |
78 |
79 |
80 |
81 | );
82 |
83 | export default Footer;
84 |
--------------------------------------------------------------------------------
/src/constants/svg/aws.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/src/constants/svg/netlify.svg:
--------------------------------------------------------------------------------
1 | Netlify
2 |
--------------------------------------------------------------------------------
/src/components/cases-section/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import Particles from 'react-particles-js';
3 | import Arrow from '@/constants/svg/arrow.svg';
4 |
5 | const ParticleBg = () => (
6 |
44 | );
45 |
46 | const articles = [
47 | {
48 | title: `Velit reprehenderit culpa Lorem reprehenderit excepteur ipsum esse.`,
49 | image: `/images/case-1.webp`,
50 | alt: `Proident pariatur est.`,
51 | },
52 | {
53 | title: `Velit reprehenderit culpa Lorem reprehenderit ipsum esse.`,
54 | image: `/images/case-2.webp`,
55 | alt: `Proident pariatur est.`,
56 | },
57 | {
58 | title: `Velit reprehenderit culpa Lorem reprehenderit excepteur esse.`,
59 | image: `/images/case-3.webp`,
60 | alt: `Proident pariatur est.`,
61 | },
62 | ];
63 |
64 | const CasesSection = () => (
65 |
66 |
67 |
70 |
71 |
What will you build?
72 |
73 | Don’t just take our word for it — see what leaders in digital are saying
74 |
75 |
76 |
77 | {articles.map((article) => (
78 |
85 |
86 |
93 |
94 |
95 |
Case study
96 |
{article.title}
97 |
98 |
99 | ))}
100 |
106 | See all case studies
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | );
115 |
116 | export default CasesSection;
117 |
--------------------------------------------------------------------------------
/src/constants/svg/preferences.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/feature-section/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import Check from '@/constants/svg/check.svg';
3 |
4 | const FeatureSection = () => (
5 |
6 |
7 |
8 |
9 |
Features
10 |
11 | How we change the game
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Increase sales
19 |
20 |
21 | Consectetur pariatur irure exercitation sit amet id consectetur consecteturmagna et Lorem labore qui
22 | velit.
23 |
24 |
25 |
26 |
27 |
28 |
Enterprise-ready
29 |
30 |
31 | Labore duis pariatur est exercitation laboris cupidatat amet cillum. Amet nisi ullamco.
32 |
33 |
34 |
35 |
36 |
37 |
Unlimited growth
38 |
39 |
40 | Elit deserunt nisi esse duis cupidatat proident sit minim mollit officia pariatur incididunt in tempor.
41 |
42 |
43 |
44 |
45 |
46 |
Recommended by experts
47 |
48 |
49 | Velit sit tempor pariatur quis pariatur incididunt culpa dolor voluptate officia incididunt velit dolore.
50 |
51 |
52 |
53 |
54 |
55 |
Modern platform
56 |
57 |
58 | Laboris elit consectetur sint nisi eu mollit proident sit magna velit adipisicing consequat amet
59 | reprehenderit.
60 |
61 |
62 |
63 |
64 |
65 |
Integrations
66 |
67 |
68 | Nostrud excepteur incididunt proident sit nulla ipsum sunt nostrud est esse adipisicing irure officia
69 | consectetur.
70 |
71 |
72 |
73 |
74 |
75 |
76 | );
77 |
78 | export default FeatureSection;
79 |
--------------------------------------------------------------------------------
/src/components/social-proof/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import { useState } from 'react';
3 | import Quote from '@/constants/svg/quote.svg';
4 |
5 | const socialProofs = [
6 | {
7 | name: `John Doe`,
8 | company: `Alphabet Inc.`,
9 | image: `/images/social-1.webp`,
10 | text: `Commodo Lorem consequat ea consectetur pariatur proident excepteur.
11 | Pariatur eiusmod minim minim ipsum tempor aute excepteur minim eu nisi laboris.
12 | Duis sunt labore eu eu cupidatat labore commodo id aliquip.`,
13 | },
14 | {
15 | name: `Jack Doe`,
16 | company: `Amazon.com, Inc.`,
17 | image: `/images/social-2.webp`,
18 | text: `Anim labore ut amet cupidatat pariatur pariatur labore ad est.
19 | Fugiat eiusmod dolore aliquip aute duis esse excepteur amet.
20 | Sit cupidatat ipsum culpa nisi esse ipsum culpa in consectetur.
21 | Enim incididunt do sunt ex do. Proident duis nulla minim sunt irure est
22 | magna nostrud Lorem consectetur irure.`,
23 | },
24 | ];
25 |
26 | const SocialProof = () => {
27 | const [currentIndex, setCurrentIndex] = useState(0);
28 |
29 | const next = () => {
30 | if (currentIndex + 1 < socialProofs.length) {
31 | setCurrentIndex(currentIndex + 1);
32 | }
33 | };
34 |
35 | const previous = () => {
36 | if (currentIndex - 1 >= 0) {
37 | setCurrentIndex(currentIndex - 1);
38 | }
39 | };
40 |
41 | return (
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
{socialProofs[currentIndex].text}
50 |
51 |
52 |
53 |
60 |
61 |
62 | {socialProofs[currentIndex].name}
63 |
64 | {socialProofs[currentIndex].company}
65 |
66 |
67 |
68 |
69 |
81 |
82 |
83 |
84 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | );
108 | };
109 |
110 | export default SocialProof;
111 |
--------------------------------------------------------------------------------
/src/components/navigation/index.tsx:
--------------------------------------------------------------------------------
1 | import { tw } from 'twind';
2 | import { useState } from 'react';
3 | import Button from '@/components/button';
4 |
5 | interface IMenuButton {
6 | toggleMenu: React.MouseEventHandler;
7 | showMenu: boolean;
8 | }
9 |
10 | type Link = {
11 | label: string;
12 | href: string;
13 | };
14 |
15 | const links = [
16 | {
17 | label: `Features`,
18 | href: `/`,
19 | },
20 | {
21 | label: `Testimonials`,
22 | href: `/`,
23 | },
24 | {
25 | label: `Pricing`,
26 | href: `/`,
27 | },
28 | {
29 | label: `Blog`,
30 | href: `/`,
31 | },
32 | ];
33 |
34 | const secondaryLinks = [
35 | {
36 | label: `Contact sales`,
37 | href: `/`,
38 | },
39 | {
40 | label: `Log in`,
41 | href: `/`,
42 | },
43 | {
44 | label: `Get Started`,
45 | href: `/`,
46 | },
47 | ];
48 |
49 | const MenuButton = ({ toggleMenu, showMenu }: IMenuButton) => (
50 |
57 | Open menu
58 | {showMenu ? (
59 |
69 |
70 |
71 | ) : (
72 |
82 |
83 |
84 | )}
85 |
86 | );
87 |
88 | const MobileMenu = () => (
89 |
111 | );
112 |
113 | const Navigation = () => {
114 | const [showMenu, setShowMenu] = useState(false);
115 | const toggleMenu = () => setShowMenu(!showMenu);
116 |
117 | return (
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
138 |
139 |
140 |
141 | Contact sales
142 | Log in
143 | Get started
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | {showMenu ? : null}
152 |
153 | );
154 | };
155 |
156 | export default Navigation;
157 |
--------------------------------------------------------------------------------
/src/constants/svg/features.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------