feat: initial commit!
39
.github/workflows/deploy.yml
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
name: Deploy to GitHub Pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Trigger the workflow every time you push to the `main` branch
|
||||||
|
# Using a different branch name? Replace `main` with your branch’s name
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
# Allows you to run this workflow manually from the Actions tab on GitHub.
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# Allow this job to clone the repo and create a page deployment
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout your repository using git
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Install, build, and upload your site
|
||||||
|
uses: withastro/action@v1
|
||||||
|
# with:
|
||||||
|
# path: . # The root location of your Astro project inside the repository. (optional)
|
||||||
|
# node-version: 18 # The specific version of Node that should be used to build your site. Defaults to 18. (optional)
|
||||||
|
# package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v1
|
||||||
20
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# build output
|
||||||
|
dist/
|
||||||
|
.output/
|
||||||
|
|
||||||
|
# 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
|
||||||
22
README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# qsv.pro
|
||||||
|
|
||||||
|
Promotional website for qsv pro. Based on the [Tailcast template](https://github.com/matt765/Tailcast) using Astro.
|
||||||
|
|
||||||
|
## Tech stack:
|
||||||
|
|
||||||
|
Astro, React, Tailwind, Framer Motion
|
||||||
|
|
||||||
|
## Live link
|
||||||
|
|
||||||
|
[https://dathere.github.io/qsv.pro](https://dathere.github.io/qsv.pro)
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
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:3000` |
|
||||||
|
| `npm run build` | Build your production site to `./dist/` |
|
||||||
|
| `npm run preview` | Preview your build locally, before deploying |
|
||||||
7
astro.config.mjs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
import react from '@astrojs/react';
|
||||||
|
import tailwind from "@astrojs/tailwind";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
integrations: [react(), tailwind()]
|
||||||
|
});
|
||||||
21
license
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 matt765
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
14508
package-lock.json
generated
Normal file
26
package.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "@example/basics",
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev",
|
||||||
|
"start": "astro dev",
|
||||||
|
"build": "astro build",
|
||||||
|
"preview": "astro preview",
|
||||||
|
"astro": "astro"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/tailwind": "^3.1.1",
|
||||||
|
"@fontsource/inter": "^4.5.15",
|
||||||
|
"astro": "^2.2.0",
|
||||||
|
"framer-motion": "^10.11.2",
|
||||||
|
"npm-check-updates": "^16.10.7",
|
||||||
|
"tailwindcss": "^3.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@astrojs/react": "^2.1.1",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
5407
pnpm-lock.yaml
generated
Normal file
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
public/sm-preview.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
13
src/assets/icons/CheckArrowIcon.jsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
export const CheckArrowIcon = () => (
|
||||||
|
<div className="rounded-full bg-transparent w-5 h-5 flex justify-center items-center mr-4">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
width="20px"
|
||||||
|
height="20px"
|
||||||
|
className="fill-customSecondary"
|
||||||
|
>
|
||||||
|
<path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
5
src/assets/icons/CloseIcon.jsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const CloseIcon = () => (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" className="fill-[rgb(255,255,255,0.7)]">
|
||||||
|
<path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
10
src/assets/icons/FacebookIcon.jsx
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export const FacebookIcon = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 320 512"
|
||||||
|
fill="white"
|
||||||
|
className="h-5 w-5"
|
||||||
|
>
|
||||||
|
<path d="M279.14 288l14.22-92.66h-88.91v-60.13c0-25.35 12.42-50.06 52.24-50.06h40.42V6.26S260.43 0 225.36 0c-73.22 0-121.08 44.38-121.08 124.72v70.62H22.89V288h81.39v224h100.17V288z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
9
src/assets/icons/GithubIcon.jsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export const GithubIcon = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 496 512"
|
||||||
|
className="w-6 h-6 mr-3 fill-gray-400"
|
||||||
|
>
|
||||||
|
<path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
10
src/assets/icons/InstagramIcon.jsx
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export const InstagramIcon = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 448 512"
|
||||||
|
fill="white"
|
||||||
|
className="h-5 w-5"
|
||||||
|
>
|
||||||
|
<path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
10
src/assets/icons/QuoteIcon.jsx
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export const QuoteIcon = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 448 512"
|
||||||
|
className="fill-customContentSubtitle"
|
||||||
|
width="35px"
|
||||||
|
>
|
||||||
|
<path d="M0 216C0 149.7 53.7 96 120 96h8c17.7 0 32 14.3 32 32s-14.3 32-32 32h-8c-30.9 0-56 25.1-56 56v8h64c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V320 288 216zm256 0c0-66.3 53.7-120 120-120h8c17.7 0 32 14.3 32 32s-14.3 32-32 32h-8c-30.9 0-56 25.1-56 56v8h64c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H320c-35.3 0-64-28.7-64-64V320 288 216z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
10
src/assets/icons/TwitterIcon.jsx
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export const TwitterIcon = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
fill="white"
|
||||||
|
className="h-5 w-5"
|
||||||
|
>
|
||||||
|
<path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
BIN
src/assets/images/configurator.gif
Normal file
|
After Width: | Height: | Size: 19 MiB |
BIN
src/assets/images/dashboard.jpg
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
src/assets/images/dashboard.png
Normal file
|
After Width: | Height: | Size: 331 KiB |
BIN
src/assets/images/drag-and-drop.gif
Normal file
|
After Width: | Height: | Size: 356 KiB |
BIN
src/assets/images/recipe-demo.gif
Normal file
|
After Width: | Height: | Size: 4.8 MiB |
BIN
src/assets/images/testimonial1.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/images/testimonial2.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/images/testimonial3.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/images/upload-to-ckan.gif
Normal file
|
After Width: | Height: | Size: 5.6 MiB |
11
src/assets/logos/NextLogo.jsx
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
export const NextLogo = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
className="fill-[rgb(215,215,215)]"
|
||||||
|
>
|
||||||
|
<path d="M64 0C28.7 0 0 28.7 0 64s28.7 64 64 64c11.2 0 21.7-2.9 30.8-7.9L48.4 55.3v36.6h-6.8V41.8h6.8l50.5 75.8C116.4 106.2 128 86.5 128 64c0-35.3-28.7-64-64-64zm22.1 84.6l-7.5-11.3V41.8h7.5v42.8z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
11
src/assets/logos/RustLogo.jsx
Normal file
25
src/assets/logos/TauriLogo.jsx
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
export const TauriLogo = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="#ffc131"
|
||||||
|
d="M86.242 46.547a12.19 12.19 0 0 1-24.379 0c0-6.734 5.457-12.191 12.191-12.191a12.19 12.19 0 0 1 12.188 12.191zm0 0"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#24c8db"
|
||||||
|
d="M41.359 81.453a12.19 12.19 0 1 1 24.383 0c0 6.734-5.457 12.191-12.191 12.191S41.36 88.187 41.36 81.453zm0 0"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#ffc131"
|
||||||
|
d="M99.316 85.637a46.5 46.5 0 0 1-16.059 6.535a32.675 32.675 0 0 0 1.797-10.719a33.3 33.3 0 0 0-.242-4.02a32.69 32.69 0 0 0 6.996-3.418a32.7 32.7 0 0 0 12.066-14.035a32.71 32.71 0 0 0-21.011-44.934a32.72 32.72 0 0 0-33.91 10.527a32.85 32.85 0 0 0-1.48 1.91a54.32 54.32 0 0 0-17.848 5.184A46.536 46.536 0 0 1 60.25 2.094a46.53 46.53 0 0 1 26.34-.375c8.633 2.418 16.387 7.273 22.324 13.984s9.813 15 11.16 23.863a46.537 46.537 0 0 1-20.758 46.071zM30.18 41.156l11.41 1.402a32.44 32.44 0 0 1 1.473-6.469a46.44 46.44 0 0 0-12.883 5.066zm0 0"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#24c8db"
|
||||||
|
d="M28.207 42.363a46.49 46.49 0 0 1 16.188-6.559a32.603 32.603 0 0 0-2.004 11.297a32.56 32.56 0 0 0 .188 3.512a32.738 32.738 0 0 0-6.859 3.371A32.7 32.7 0 0 0 23.652 68.02c-2.59 5.742-3.461 12.113-2.52 18.34s3.668 12.051 7.844 16.77s9.617 8.129 15.684 9.824s12.496 1.605 18.512-.262a32.72 32.72 0 0 0 15.402-10.266a34.9 34.9 0 0 0 1.484-1.918a54.283 54.283 0 0 0 17.855-5.223a46.528 46.528 0 0 1-8.723 16.012a46.511 46.511 0 0 1-21.918 14.609a46.53 46.53 0 0 1-26.34.375a46.6 46.6 0 0 1-22.324-13.984A46.56 46.56 0 0 1 7.453 88.434a46.53 46.53 0 0 1 3.582-26.098a46.533 46.533 0 0 1 17.172-19.973zm69.074 44.473c-.059.035-.121.066-.18.102c.059-.035.121-.066.18-.102zm0 0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
14
src/assets/logos/TypescriptLogo.jsx
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
export const TypescriptLogo = () => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
>
|
||||||
|
<path fill="#fff" d="M22.67 47h99.67v73.67H22.67z" />
|
||||||
|
<path
|
||||||
|
fill="#007acc"
|
||||||
|
d="M1.5 63.91v62.5h125v-125H1.5zm100.73-5a15.56 15.56 0 0 1 7.82 4.5a20.58 20.58 0 0 1 3 4c0 .16-5.4 3.81-8.69 5.85c-.12.08-.6-.44-1.13-1.23a7.09 7.09 0 0 0-5.87-3.53c-3.79-.26-6.23 1.73-6.21 5a4.58 4.58 0 0 0 .54 2.34c.83 1.73 2.38 2.76 7.24 4.86c8.95 3.85 12.78 6.39 15.16 10c2.66 4 3.25 10.46 1.45 15.24c-2 5.2-6.9 8.73-13.83 9.9a38.32 38.32 0 0 1-9.52-.1a23 23 0 0 1-12.72-6.63c-1.15-1.27-3.39-4.58-3.25-4.82a9.34 9.34 0 0 1 1.15-.73L82 101l3.59-2.08l.75 1.11a16.78 16.78 0 0 0 4.74 4.54c4 2.1 9.46 1.81 12.16-.62a5.43 5.43 0 0 0 .69-6.92c-1-1.39-3-2.56-8.59-5c-6.45-2.78-9.23-4.5-11.77-7.24a16.48 16.48 0 0 1-3.43-6.25a25 25 0 0 1-.22-8c1.33-6.23 6-10.58 12.82-11.87a31.66 31.66 0 0 1 9.49.26zm-29.34 5.24v5.12H56.66v46.23H45.15V69.26H28.88v-5a49.19 49.19 0 0 1 .12-5.17C29.08 59 39 59 51 59h21.83z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
BIN
src/assets/logos/datHere-logo-light.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/logos/datHereLogo.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
57
src/components/Brands.jsx
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import { AmazonLogo } from "../assets/logos/AmazonLogo";
|
||||||
|
import { DropboxLogo } from "../assets/logos/DropboxLogo";
|
||||||
|
import { NetflixLogo } from "../assets/logos/NetflixLogo";
|
||||||
|
import { SlackLogo } from "../assets/logos/SlackLogo";
|
||||||
|
import { SpotifyLogo } from "../assets/logos/SpotifyLogo";
|
||||||
|
import { StripeLogo } from "../assets/logos/StripeLogo";
|
||||||
|
|
||||||
|
export const Brands = () => (
|
||||||
|
<section className="py-12 sm:py-24 bg-customDarkBg1 w-full mt-16 mb-16">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className="container px-4 mx-auto 2xl:w-[1200px] xl:w-[1100px] lg:w-[1000px] md:w-4/5">
|
||||||
|
<div className="flex lg:flex-row flex-col items-center -mx-4 justify-center lg:text-left text-center">
|
||||||
|
<div className="w-full lg:w-1/2 px-4 mb-12 lg:mb-0">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<h2 className="mb-2 text-4xl sm:text-5xl 2xl:text-6xl font-bold tracking-normal text-white">
|
||||||
|
Trusted by brands
|
||||||
|
</h2>
|
||||||
|
<h2 className=" text-4xl sm:text-5xl 2xl:text-6xl font-bold tracking-normal text-customSecondary">
|
||||||
|
all over the world
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-2/3 sm:w-[620px] lg:w-1/2 mx-auto lg:mx-0 lg:pl-10">
|
||||||
|
<div className="flex flex-wrap -m-4">
|
||||||
|
<div className="w-1/2 sm:w-1/3 py-6 flex justify-center">
|
||||||
|
<AmazonLogo />
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 sm:w-1/3 py-6 flex justify-center">
|
||||||
|
<DropboxLogo />
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 sm:w-1/3 py-6 flex justify-center">
|
||||||
|
<NetflixLogo />
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 sm:w-1/3 py-6 flex justify-center">
|
||||||
|
<StripeLogo />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-1/2 sm:w-1/3 py-6 flex justify-center">
|
||||||
|
<SpotifyLogo />
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 sm:w-1/3 py-6 flex justify-center">
|
||||||
|
<SlackLogo />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
5
src/components/Divider.jsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const Divider = () => (
|
||||||
|
<div className="w-full lg:w-3/5 mx-auto">
|
||||||
|
<div className="border-t border-customGrayBorder"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
96
src/components/FAQ.jsx
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
const FAQData = [
|
||||||
|
{
|
||||||
|
question: "What is qsv pro?",
|
||||||
|
answer: "qsv pro is a desktop application that allows you to run qsv commands with a graphical user interface based on the qsv CLI tool. It also features a suite of recipes (scripts) for common data wrangling tasks to perform on your spreadsheet, including sorting rows, removing duplicate rows, and removing Personally Identifiable Information (PII).",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "How do I get qsv pro?",
|
||||||
|
answer: "qsv pro is currently in beta. You can get beta access by purchasing a subscription to qsv pro on our store. You will receive an email with a download link to qsv pro after purchasing a subscription, or you may click the Download button on this page's navigation bar to download qsv pro (license key still required).",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "Where can I provide feedback?",
|
||||||
|
answer: "There is a feedback button in the top right corner of qsv pro. You may also email us at dathere.com/contact.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const FAQ = () => (
|
||||||
|
<section className="relative pt-16 pb-16 bg-blueGray-50 overflow-hidden">
|
||||||
|
<div className="absolute -top-10" id="FAQ" />
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className="relative z-10 container px-2 sm:px-8 lg:px-4 mx-auto w-11/12 sm:w-full">
|
||||||
|
<div className="md:max-w-4xl mx-auto">
|
||||||
|
<p className="mb-7 custom-block-subtitle text-center">
|
||||||
|
Have any questions?
|
||||||
|
</p>
|
||||||
|
<h2 className="mb-16 custom-block-big-title text-center">
|
||||||
|
Frequently Asked Questions
|
||||||
|
</h2>
|
||||||
|
<div className="mb-11 flex flex-wrap -m-1">
|
||||||
|
{FAQData.map((item, index) => (
|
||||||
|
<div className="w-full p-1">
|
||||||
|
<FAQBox
|
||||||
|
title={item.question}
|
||||||
|
content={item.answer}
|
||||||
|
key={`${item.question}-${item.answer}`}
|
||||||
|
defaultOpen={index === 0}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
const FAQBox = ({ defaultOpen, title, content }) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(defaultOpen);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="pt-2 sm:pt-6 pb-2 px-3 sm:px-8 rounded-3xl bg-customDarkBg3 custom-border-gray-darker mb-4 relative hover:bg-customDarkBg3Hover cursor-pointer"
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col p-2 justify-center items-start">
|
||||||
|
<h3 className=" custom-content-title pt-3 sm:pt-0 pr-8 sm:pr-0">
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
<p
|
||||||
|
className={`text-customGrayText pt-4 transition-all duration-300 overflow-hidden ${
|
||||||
|
isOpen ? "max-h-96" : "max-h-0"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="absolute top-6 right-4 sm:top-8 sm:right-8">
|
||||||
|
<svg
|
||||||
|
width="28px"
|
||||||
|
height="30px"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={`transition-all duration-500 ${
|
||||||
|
isOpen ? "rotate-[180deg]" : "rotate-[270deg]"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M4.16732 12.5L10.0007 6.66667L15.834 12.5"
|
||||||
|
stroke="#007AFF"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
75
src/components/Features0.jsx
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import draganddrop from "../assets/images/drag-and-drop.gif";
|
||||||
|
import { CheckArrowIcon } from "../assets/icons/CheckArrowIcon";
|
||||||
|
|
||||||
|
export const Features0 = () => {
|
||||||
|
return (
|
||||||
|
<section
|
||||||
|
className="w-full bg-customDarkBg2 mt-20 mb-8 sm:mt-16 sm:mb-16 xl:mt-0 pt-[2rem] md:pt-[12vw] lg:pt-16"
|
||||||
|
id="features"
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className="flex flex-wrap items-center 2xl:w-[1450px] xl:w-[1300px] w-11/12 mx-auto md:pl-4 xl:pr-16 xl:pl-16">
|
||||||
|
<div className="w-full md:w-1/2 mb-8 md:mb-0 lg:pl-16 flex justify-center mx-auto pt-16 lg:pt-0">
|
||||||
|
<img
|
||||||
|
src={draganddrop}
|
||||||
|
alt="Drag and Drop Demo"
|
||||||
|
className="rounded-xl custom-border-gray"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="w-full lg:w-1/2 mb-12 lg:mb-0">
|
||||||
|
<div className="mx-auto lg:mx-auto w-11/12 sm:w-4/5 md:w-3/4 lg:w-unset">
|
||||||
|
<span className="custom-block-subtitle">
|
||||||
|
Import Your Data
|
||||||
|
</span>
|
||||||
|
<h2 className="mt-6 mb-8 text-4xl lg:text-5xl custom-block-big-title">
|
||||||
|
<u>Drag & drop</u> your data into qsv pro
|
||||||
|
</h2>
|
||||||
|
<p className="mb-10 text-customGrayText leading-loose">
|
||||||
|
Drag and drop a spreadsheet file anywhere within
|
||||||
|
the Workflow section to import your data and
|
||||||
|
begin exploring your data in a data table.
|
||||||
|
</p>
|
||||||
|
<ul className="mb-6 text-white">
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>
|
||||||
|
File formats: .csv, .tsv, .tab, .xlsx,
|
||||||
|
.xls, .ods, .xlsm, .xlsb
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>
|
||||||
|
Supports large spreadsheets with
|
||||||
|
millions of rows
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>
|
||||||
|
Begins scanning and analyzing your data
|
||||||
|
on import
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>
|
||||||
|
Generates stats, frequency, and file
|
||||||
|
metadata
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
59
src/components/Features1.jsx
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import recipedemo from "../assets/images/recipe-demo.gif";
|
||||||
|
import { CheckArrowIcon } from "../assets/icons/CheckArrowIcon";
|
||||||
|
|
||||||
|
export const Features1 = () => {
|
||||||
|
return (
|
||||||
|
<section className="w-full bg-customDarkBg2 mt-20 mb-8 sm:mt-16 sm:mb-16 xl:mt-4 pt-16">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className="flex flex-wrap items-center 2xl:w-[1450px] xl:w-[1300px] w-11/12 mx-auto md:pl-4 xl:pr-16 xl:pl-16">
|
||||||
|
<div className="w-full lg:w-1/2 mb-12 lg:mb-0">
|
||||||
|
<div className="mx-auto lg:mx-auto w-11/12 sm:w-4/5 md:w-3/4 lg:w-unset">
|
||||||
|
<span className="custom-block-subtitle">
|
||||||
|
Transform Your Data
|
||||||
|
</span>
|
||||||
|
<h2 className="mt-6 mb-8 text-4xl lg:text-5xl custom-block-big-title">
|
||||||
|
Transform your data with <u>recipes</u>
|
||||||
|
</h2>
|
||||||
|
<p className="mb-10 text-customGrayText leading-loose">
|
||||||
|
qsv pro features a suite of recipes (scripts)
|
||||||
|
for common data wrangling tasks to perform on
|
||||||
|
your spreadsheet, including:
|
||||||
|
</p>
|
||||||
|
<ul className="mb-6 text-white">
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>Sort rows</span>
|
||||||
|
</li>
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>Remove duplicate rows</span>
|
||||||
|
</li>
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>
|
||||||
|
Remove Personally Identifiable
|
||||||
|
Information (PII)
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full md:w-1/2 mb-8 md:mb-0 mx-auto lg:w-1/2 flex flex-wrap lg:-mx-4 sm:pr-8 justify-center">
|
||||||
|
<img
|
||||||
|
src={recipedemo}
|
||||||
|
alt="Recipe Demo"
|
||||||
|
className="rounded-xl custom-border-gray"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
55
src/components/Features2.jsx
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import uploadtockan from "../assets/images/upload-to-ckan.gif";
|
||||||
|
import { CheckArrowIcon } from "../assets/icons/CheckArrowIcon";
|
||||||
|
|
||||||
|
export const Features2 = () => (
|
||||||
|
<section className="w-full bg-customDarkBg2 mt-12 sm:mt-20 mb-10 lg:my-20 pt-4">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className="flex flex-wrap items-center 2xl:w-[1450px] xl:w-[1300px] w-11/12 mx-auto md:pl-4 xl:pr-16 xl:pl-16">
|
||||||
|
<div className="w-full md:w-1/2 mb-8 md:mb-0 lg:pl-16 flex justify-center mx-auto pt-16 lg:pt-0">
|
||||||
|
<img
|
||||||
|
src={uploadtockan}
|
||||||
|
alt="CKAN Upload Demo"
|
||||||
|
className="rounded-xl custom-border-gray"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full lg:w-1/2 mb-12 lg:mb-0 xl:pl-8">
|
||||||
|
<div className="mx-auto lg:mx-auto w-11/12 sm:w-4/5 md:w-3/4 lg:w-unset">
|
||||||
|
<span className="custom-block-subtitle">
|
||||||
|
Load to CKAN with ease
|
||||||
|
</span>
|
||||||
|
<h2 className="mt-6 mb-8 text-4xl lg:text-5xl custom-block-big-title">
|
||||||
|
Upload your data to a <u>CKAN</u> datastore
|
||||||
|
</h2>
|
||||||
|
<p className="mb-12 text-customGrayText leading-loose">
|
||||||
|
qsv pro allows you to upload your transformed data
|
||||||
|
to a CKAN datastore & a data dictionary to specify
|
||||||
|
file metadata.
|
||||||
|
</p>
|
||||||
|
<ul className="mb-6 text-white">
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>Integrated with the CKAN API</span>
|
||||||
|
</li>
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>In-app data dictionary form</span>
|
||||||
|
</li>
|
||||||
|
<li className="mb-4 flex">
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>Automatically inferred data types</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
76
src/components/FeaturesDiagonal.jsx
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import configurator from "../assets/images/configurator.gif";
|
||||||
|
|
||||||
|
export const FeaturesDiagonal = () => {
|
||||||
|
return (
|
||||||
|
<section className="lg:mb-16 w-full flex flex-col justify-center items-center bg-customDarkBg1">
|
||||||
|
<div className="custom-shape-divider-bottom-1665696614">
|
||||||
|
<svg
|
||||||
|
data-name="Layer 1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 1200 120"
|
||||||
|
preserveAspectRatio="none"
|
||||||
|
className="custom-bg-dark2"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1200 120L0 16.48 0 0 1200 0 1200 120z"
|
||||||
|
className="custom-bg-dark1"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className=" 2xl:w-[1150px] xl:w-[1050px] md:w-4/5 flex justify-center bg-customDarkBg1 pt-12 lg:pt-24 pb-8 lg:pb-20 mx-auto lg:flex-row flex-col">
|
||||||
|
<div className="w-3/4 lg:w-1/2 flex flex-col lg:mx-unset mx-auto">
|
||||||
|
<span className="custom-block-subtitle">
|
||||||
|
Early Access
|
||||||
|
</span>
|
||||||
|
<h2 className="mt-10 mb-8 text-4xl lg:text-5xl custom-block-big-title">
|
||||||
|
Run qsv commands with our qsv Configurator GUI
|
||||||
|
</h2>
|
||||||
|
<p className="mb-16 text-customGrayText leading-loose">
|
||||||
|
No need to run qsv commands in your terminal. Try
|
||||||
|
out our early access qsv Configurator GUI to use qsv
|
||||||
|
commands with a graphical user interface.
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href="https://store.dathere.com/checkout/buy/41f919fd-2b68-40ea-a5ed-0f531b2efba5"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<div className="w-[210px] h-12 custom-button-colored mr-10 ">
|
||||||
|
Start Your Free Trial
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="w-4/5 lg:w-2/3 lg:pl-16 flex justify-center mx-auto pt-16 lg:pt-0">
|
||||||
|
<img
|
||||||
|
src={configurator}
|
||||||
|
alt="Configurator Demo"
|
||||||
|
className="rounded-xl custom-border-gray"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<div className="custom-shape-divider-top-1665696661 w-full">
|
||||||
|
<svg
|
||||||
|
data-name="Layer 1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 1200 120"
|
||||||
|
preserveAspectRatio="none"
|
||||||
|
className="custom-bg-dark2"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1200 120L0 16.48 0 0 1200 0 1200 120z"
|
||||||
|
className="custom-bg-dark1"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
126
src/components/Footer.jsx
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
import { FacebookIcon } from "../assets/icons/FacebookIcon";
|
||||||
|
import { InstagramIcon } from "../assets/icons/InstagramIcon";
|
||||||
|
import datHereLogoFull from "../assets/logos/datHere-logo-light.png";
|
||||||
|
import { TwitterIcon } from "../assets/icons/TwitterIcon";
|
||||||
|
|
||||||
|
const footerData = [
|
||||||
|
{
|
||||||
|
title: "Products",
|
||||||
|
items: ["Services", "About Us", "News and Stories", "Roadmap"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Important Links",
|
||||||
|
items: [
|
||||||
|
"Organization Team",
|
||||||
|
"Our Journeys",
|
||||||
|
"Pricing Plans",
|
||||||
|
"Roadmap",
|
||||||
|
"Terms & Conditions",
|
||||||
|
"Privacy Policy",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Company",
|
||||||
|
items: ["About Us", "Jobs", "Press", "Contact Us"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Footer = () => {
|
||||||
|
return (
|
||||||
|
<footer>
|
||||||
|
<div className="pt-10 lg:pt-20 lg:pb-12 bg-customDarkBg1 radius-for-skewed">
|
||||||
|
<div className="container mx-auto px-4 w-4/5 md:w-11/12 lg:w-10/12 xl:w-4/5 2xl:w-2/3">
|
||||||
|
<div className="flex flex-wrap">
|
||||||
|
<div className="w-full lg:w-1/3 mb-16 lg:mb-0">
|
||||||
|
<div className="flex justify-center lg:justify-start items-center grow basis-0">
|
||||||
|
<div className="text-white mr-2 text-6xl">
|
||||||
|
<img
|
||||||
|
src={datHereLogoFull}
|
||||||
|
alt="datHere Logo"
|
||||||
|
className="w-48"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mb-10 mt-4 sm:w-[22rem] lg:w-[20rem] xl:w-[24rem] text-gray-400 leading-loose text-center lg:text-left mx-auto lg:mx-0">
|
||||||
|
Making data Useful, Usable, and Used.
|
||||||
|
</p>
|
||||||
|
{/* <div className="w-36 mx-auto lg:mx-0">
|
||||||
|
<a
|
||||||
|
className="inline-block w-10 h-10 mr-2 p-2 bg-customDarkBg2 custom-border-gray hover:bg-gray-700 rounded-xl"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<TwitterIcon />
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="inline-block w-10 h-10 mr-2 p-2 bg-customDarkBg2 custom-border-gray hover:bg-gray-700 rounded-xl"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<InstagramIcon />
|
||||||
|
</a>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
<div className="w-full lg:w-2/3 lg:pl-16 hidden lg:flex flex-wrap justify-between">
|
||||||
|
{/* <div className="w-full md:w-1/3 lg:w-auto mb-16 md:mb-0">
|
||||||
|
<h3 className="mb-6 text-2xl font-bold text-white">
|
||||||
|
Products
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{footerData[0].items.map((item, i) => (
|
||||||
|
<li key={i} className="mb-4">
|
||||||
|
<a
|
||||||
|
className="text-gray-400 hover:text-gray-300"
|
||||||
|
href="#"
|
||||||
|
aria-label=""
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div> */}
|
||||||
|
{/* <div className="w-full md:w-1/3 lg:w-auto mb-16 md:mb-0">
|
||||||
|
<h3 className="mb-6 text-2xl font-bold text-white">
|
||||||
|
Important Links
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{footerData[1].items.map((item, i) => (
|
||||||
|
<li key={i} className="mb-4">
|
||||||
|
<a
|
||||||
|
className="text-gray-400 hover:text-gray-300"
|
||||||
|
href="#"
|
||||||
|
aria-label=""
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div> */}
|
||||||
|
{/* <div className="w-full md:w-1/3 lg:w-auto">
|
||||||
|
<h3 className="mb-6 text-2xl font-bold text-white">
|
||||||
|
Company
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{footerData[2].items.map((item, i) => (
|
||||||
|
<li key={i} className="mb-4">
|
||||||
|
<a
|
||||||
|
className="text-gray-400 hover:text-gray-300"
|
||||||
|
href="#"
|
||||||
|
aria-label=""
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="lg:text-center text-sm text-gray-400 border-t border-[rgb(255,255,255,0.2)] pt-4 hidden lg:block">
|
||||||
|
© 2023 datHere Inc.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
};
|
||||||
110
src/components/Hero.jsx
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import dashboard from "../assets/images/dashboard.png";
|
||||||
|
|
||||||
|
export const Hero = () => {
|
||||||
|
return (
|
||||||
|
<section
|
||||||
|
className="w-screen flex justify-center items-center bg-customDarkBg1 mb-[28vw] md:mb-[18vw] lg:mb-[10vw] xl:mb-[13vw] 2xl:mb-60 hero-bg-gradient pb-24 sm:pb-32 md:pb-44 lg:pb-0"
|
||||||
|
id="home"
|
||||||
|
>
|
||||||
|
<div className="w-full w-[900px] md:w-[1100px] flex flex-col justify-center items-center pt-16 md:pt-16 lg:pt-20 text-center">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 10 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
>
|
||||||
|
<div className="text-customSecondary text-sm sm:text-base mb-6 sm:mt-32 mt-16 font-bold">
|
||||||
|
Spreadsheet Data Wrangling Desktop App
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 10 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.05 }}
|
||||||
|
>
|
||||||
|
<div className="text-5xl sm:text-6xl lg:text-7xl xl:text-7xl font-bold tracking-wide text-white px-8 sm:px-8 md:px-20 lg:px-4">
|
||||||
|
<span>qsv pro</span>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 10 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.1 }}
|
||||||
|
>
|
||||||
|
<div className="text-customGrayText text-sm lg:text-base xl:text-lg sm:text-base mt-10 px-12 sm:px-48 ">
|
||||||
|
Transform and upload spreadsheet data to{" "}
|
||||||
|
<a
|
||||||
|
href="https://ckan.org"
|
||||||
|
target="_blank"
|
||||||
|
className="text-blue-300"
|
||||||
|
>
|
||||||
|
CKAN
|
||||||
|
</a>{" "}
|
||||||
|
with our streamlined desktop app, featuring "recipes"
|
||||||
|
for common data wrangling tasks. Based on the{" "}
|
||||||
|
<a
|
||||||
|
href="https://github.com/jqnatividad/qsv"
|
||||||
|
target="_blank"
|
||||||
|
className="text-blue-300"
|
||||||
|
>
|
||||||
|
qsv
|
||||||
|
</a>{" "}
|
||||||
|
CLI tool.
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 10 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.15 }}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col gap-2 sm:flex-row mt-14 mb-24 sm:mb-40 justify-center">
|
||||||
|
<a
|
||||||
|
href="https://store.dathere.com/checkout/buy/41f919fd-2b68-40ea-a5ed-0f531b2efba5"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<div className="custom-button-colored w-64 sm:w-52 h-12 mr-0 sm:mr-4 lg:mr-6 mb-2 sm:mb-0">
|
||||||
|
Start Your Free Trial
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{/* <div
|
||||||
|
className="w-64 sm:w-52 h-12 rounded-xl font-bold text-white border border-solid flex justify-center items-center cursor-pointer bg-customDarkBg2 hover:bg-customDarkBg3 border-customPrimary transition"
|
||||||
|
>
|
||||||
|
Live demo
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 10, zIndex: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0, zIndex: 20 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.15 }}
|
||||||
|
>
|
||||||
|
<div className="relative w-screen flex justify-center ">
|
||||||
|
<img
|
||||||
|
src={dashboard}
|
||||||
|
alt="123"
|
||||||
|
className="w-4/5 2xl:w-[1200px] mx-auto absolute z-10 rounded-xl custom-border-gray hero-dashboard-border-gradient lg:top-6 xl:top-0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<div className="relative w-screen flex justify-center ">
|
||||||
|
<div className="custom-shape-divider-bottom-1665343298 mt-4 sm:mt-16 md:mt-52 hidden lg:block">
|
||||||
|
<svg
|
||||||
|
data-name="Layer 1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 1200 120"
|
||||||
|
preserveAspectRatio="none"
|
||||||
|
className=" bg-customDarkBg2"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1200 0L0 0 598.97 114.72 1200 0z"
|
||||||
|
className="shape-fill custom-bg-dark1"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
129
src/components/Navbar.jsx
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
|
|
||||||
|
import datHereLogo from "../assets/logos/datHereLogo.png";
|
||||||
|
import { GithubIcon } from "../assets/icons/GithubIcon";
|
||||||
|
|
||||||
|
const navbarLinks = [
|
||||||
|
{ label: "Home", href: "#home", ariaLabel: "Home" },
|
||||||
|
{ label: "Features", href: "#features", ariaLabel: "Features" },
|
||||||
|
// { label: "Feedback", href: "#feedback", ariaLabel: "Feedback" },
|
||||||
|
{ label: "Pricing", href: "#pricing", ariaLabel: "Pricing" },
|
||||||
|
// { label: "FAQ", href: "#FAQ", ariaLabel: "FAQ" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Navbar = () => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<nav className="w-full h-20 flex flex-col justify-center items-center fixed bg-customDarkBg1 lg:bg-customDarkBgTransparent z-40 lg:backdrop-blur-xl">
|
||||||
|
<div className="2xl:w-[1280px] xl:w-10/12 w-11/12 flex justify-between items-center relative">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
>
|
||||||
|
<a className="navbar-link" href="#home" aria-label="Home">
|
||||||
|
<div className="flex justify-start items-center grow basis-0">
|
||||||
|
<div className="text-white mr-2 text-6xl">
|
||||||
|
<img
|
||||||
|
src={datHereLogo}
|
||||||
|
alt="datHere logo"
|
||||||
|
className="w-6 h-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-white font-['Inter'] font-bold text-xl">
|
||||||
|
qsv pro
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
>
|
||||||
|
<div className="hidden lg:flex h-full pl-12 pb-2">
|
||||||
|
{navbarLinks.map(({ href, label, ariaLabel }) => (
|
||||||
|
<a
|
||||||
|
className="navbar-link"
|
||||||
|
href={href}
|
||||||
|
aria-label={ariaLabel}
|
||||||
|
key={label}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
>
|
||||||
|
<div className="grow basis-0 justify-end hidden lg:flex">
|
||||||
|
<a
|
||||||
|
className="text-white custom-border-gray rounded-xl
|
||||||
|
bg-customDarkBg2 hover:bg-customDarkBg3 border-gray-700 pl-6 pr-8 pt-2 pb-2 text-sm flex"
|
||||||
|
href="https://github.com/dathere/qsv-pro-releases/releases/latest"
|
||||||
|
target="_blank"
|
||||||
|
aria-label="source code"
|
||||||
|
>
|
||||||
|
<GithubIcon />
|
||||||
|
<span className="pt-px">Download</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<div
|
||||||
|
className="lg:hidden flex flex-col px-2 py-3 border-solid border border-gray-600 rounded-md cursor-pointer hover:bg-customDarkBg2"
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
>
|
||||||
|
<div className="w-5 h-0.5 bg-gray-500 mb-1"></div>
|
||||||
|
<div className="w-5 h-0.5 bg-gray-500 mb-1"></div>
|
||||||
|
<div className="w-5 h-0.5 bg-gray-500 "></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Mobile navbar */}
|
||||||
|
<AnimatePresence>
|
||||||
|
{isOpen && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col mt-16 lg:hidden absolute top-4 left-0 bg-customDarkBg1 z-50 w-full
|
||||||
|
items-center gap-10 pb-10 border-y border-solid border-customDarkBg3 pt-10
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{navbarLinks.map(({ label, href, ariaLabel }) => (
|
||||||
|
<a
|
||||||
|
key={href}
|
||||||
|
className="navbar-link"
|
||||||
|
href={href}
|
||||||
|
onClick={() => setIsOpen(false)}
|
||||||
|
aria-label={ariaLabel}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
<a
|
||||||
|
className="text-white custom-border-gray rounded-xl
|
||||||
|
bg-customDarkBg2 hover:bg-customDarkBg3 border-gray-700 pl-6 pr-8 pt-2 pb-2 text-sm flex"
|
||||||
|
href="https://github.com/dathere/qsv-pro-releases/releases/latest"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<GithubIcon />
|
||||||
|
Download
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
194
src/components/Pricing.jsx
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import { CheckArrowIcon } from "../assets/icons/CheckArrowIcon";
|
||||||
|
|
||||||
|
const pricingData = [
|
||||||
|
"Import local spreadsheet data",
|
||||||
|
"Transform data with recipes",
|
||||||
|
"Upload to CKAN datastores",
|
||||||
|
"Interactive data table view",
|
||||||
|
"Early access to Configurator",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Pricing = () => {
|
||||||
|
const [isMonthly, setIsMonthly] = useState(true);
|
||||||
|
|
||||||
|
const handleChange = () => {
|
||||||
|
setIsMonthly(!isMonthly);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="w-screen flex justify-center bg-customDarkBg2 relative">
|
||||||
|
<div className="absolute -top-16" id="pricing" />
|
||||||
|
<div className="pb-20 pt-12 bg-customDarkBg2 2xl:w-[1150px] lg:w-[1050px] md:w-4/5 ">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className="container mx-auto px-4">
|
||||||
|
<div className="max-w-2xl mx-auto text-center mb-16">
|
||||||
|
<span className="custom-block-subtitle">
|
||||||
|
Pick a Plan
|
||||||
|
</span>
|
||||||
|
<h2 className="mt-6 mb-6 text-4xl lg:text-5xl font-bold font-heading text-white">
|
||||||
|
Choose your plan
|
||||||
|
</h2>
|
||||||
|
<p className="mb-6 text-customGrayText">
|
||||||
|
Select the subscription plan that suits your
|
||||||
|
needs and benefit from qsv pro.
|
||||||
|
</p>
|
||||||
|
<label className="mx-auto bg-customDarkBg3 relative flex justify-between items-center group text-xl w-44 h-12 rounded-lg pr-36 pl-1 cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="peer appearance-none"
|
||||||
|
checked={!isMonthly}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
<span className="h-8 w-[5.5rem] flex items-center pr-2 bg-customDarkBg3 after:rounded-lg duration-300 ease-in-out after:w-[30rem] after:h-10 after:bg-customPrimary after:shadow-md after:duration-300 peer-checked:after:translate-x-[5.5rem] cursor-pointer"></span>
|
||||||
|
<div className="flex absolute text-white text-sm font-bold">
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
isMonthly
|
||||||
|
? "mr-9 ml-3"
|
||||||
|
: "mr-9 ml-3 text-gray-400"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Monthly
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={isMonthly && "text-gray-400"}
|
||||||
|
>
|
||||||
|
Yearly
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap flex-col lg:flex-row -mx-4 items-center mt-20">
|
||||||
|
<div className="w-[350px] sm:w-[380px] lg:w-1/3 px-4 mb-8 lg:mb-0">
|
||||||
|
{/* <div className="p-8 bg-customDarkBg3 rounded-3xl">
|
||||||
|
<h4 className="mb-2 text-xl font-bold font-heading text-white text-left">
|
||||||
|
Beginner
|
||||||
|
</h4>
|
||||||
|
<div className="flex justify-start items-end">
|
||||||
|
<div className="text-4xl sm:text-5xl font-bold text-white text-left mt-4 mr-2">
|
||||||
|
$0
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-500">
|
||||||
|
{isMonthly ? "/ month" : "/ year"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="mt-4 mb-6 2xl:mb-10 text-gray-500 leading-loose text-left">
|
||||||
|
The perfect way to get started and get
|
||||||
|
used to our tools.
|
||||||
|
</p>
|
||||||
|
<ul className="mb-2 2xl:mb-6 text-white">
|
||||||
|
{pricingData.map((text, index) => (
|
||||||
|
<li
|
||||||
|
className="mb-4 flex"
|
||||||
|
key={`${text}-${index}`}
|
||||||
|
>
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>{text}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<div
|
||||||
|
className="inline-block text-center py-2 px-4 w-full rounded-xl rounded-t-xl custom-button-colored font-bold leading-loose mt-16"
|
||||||
|
>
|
||||||
|
Get Started
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
<div className="w-[350px] sm:w-[380px] lg:w-1/3 px-4 mb-8 lg:mb-0">
|
||||||
|
<div className="px-8 py-8 bg-customDarkBg3 rounded-3xl">
|
||||||
|
<h4 className="mb-2 2xl:mb-4 text-2xl font-bold font-heading text-white text-left">
|
||||||
|
qsv pro
|
||||||
|
</h4>
|
||||||
|
<div className="flex justify-start items-end">
|
||||||
|
<div className="text-4xl sm:text-5xl font-bold text-white text-left mt-4 mr-2">
|
||||||
|
{isMonthly ? "$99.99" : "$999.00"}
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-500">
|
||||||
|
{isMonthly ? "/ month" : "/ year"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mt-8 mb-8 2xl:mb-12 text-gray-500 leading-loose text-left">
|
||||||
|
1 license key + 7 days free trial
|
||||||
|
</p>
|
||||||
|
<ul className="mb-14 text-white">
|
||||||
|
{pricingData
|
||||||
|
.concat(
|
||||||
|
!isMonthly
|
||||||
|
? ["~$200 saved per year!"]
|
||||||
|
: []
|
||||||
|
)
|
||||||
|
.map((text, index) => (
|
||||||
|
<li
|
||||||
|
className="mb-4 flex"
|
||||||
|
key={`${text}-${index}`}
|
||||||
|
>
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>{text}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<a
|
||||||
|
href={
|
||||||
|
isMonthly
|
||||||
|
? "https://store.dathere.com/checkout/buy/41f919fd-2b68-40ea-a5ed-0f531b2efba5"
|
||||||
|
: "https://store.dathere.com/checkout/buy/88fed582-ffd4-41e0-a94e-457fdd038130"
|
||||||
|
}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<div className="inline-block text-center py-2 px-4 w-full custom-button-colored leading-loose transition duration-200 mt-20">
|
||||||
|
Start Your 7-Day Free Trial
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-[350px] sm:w-[380px] lg:w-1/3 px-4 mb-8 lg:mb-0">
|
||||||
|
{/* <div className="p-8 bg-customDarkBg3 rounded-3xl">
|
||||||
|
<h4 className="mb-2 text-xl font-bold font-heading text-white text-left">
|
||||||
|
Premium
|
||||||
|
</h4>
|
||||||
|
<div className="flex justify-start items-end">
|
||||||
|
<div className="text-4xl sm:text-5xl font-bold text-white text-left mt-4 mr-2">
|
||||||
|
{isMonthly ? "$36" : "$390"}
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-500">
|
||||||
|
{isMonthly ? "/ month" : "/ year"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mt-4 mb-6 2xl:mb-10 text-gray-500 leading-loose text-left">
|
||||||
|
Experience the full power of our
|
||||||
|
analytic platform
|
||||||
|
</p>
|
||||||
|
<ul className="mb-2 2xl:mb-6 text-white">
|
||||||
|
{pricingData.map((text, index) => (
|
||||||
|
<li
|
||||||
|
className="mb-4 flex"
|
||||||
|
key={`${text}-${index}`}
|
||||||
|
>
|
||||||
|
<CheckArrowIcon />
|
||||||
|
<span>{text}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<div
|
||||||
|
className="inline-block text-center py-2 px-4 w-full rounded-xl rounded-t-xl custom-button-colored font-bold leading-loose mt-16"
|
||||||
|
>
|
||||||
|
Get Started
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
52
src/components/ScrollUpButton.jsx
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export const ScrollUpButton = () => {
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("scroll", toggleVisible);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const toggleVisible = () => {
|
||||||
|
const scrolled = document.documentElement.scrollTop;
|
||||||
|
if (scrolled > 300) {
|
||||||
|
setIsVisible(true);
|
||||||
|
} else if (scrolled <= 300) {
|
||||||
|
setIsVisible(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollToTop = () => {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isVisible && (
|
||||||
|
<div
|
||||||
|
className="w-12 h-12 fixed bottom-6 right-6 custom-border-gray rounded-xl bg-customDarkBg2 hover:bg-customDarkBg3 cursor-pointer flex justify-center items-center transition z-50"
|
||||||
|
onClick={scrollToTop}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="35px"
|
||||||
|
height="35px"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M4.16732 12.5L10.0007 6.66667L15.834 12.5"
|
||||||
|
stroke="#007AFF"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
62
src/components/Tech.jsx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import { TauriLogo } from "../assets/logos/TauriLogo";
|
||||||
|
import { RustLogo } from "../assets/logos/RustLogo";
|
||||||
|
import { TypescriptLogo } from "../assets/logos/TypescriptLogo";
|
||||||
|
import { NextLogo } from "../assets/logos/NextLogo";
|
||||||
|
|
||||||
|
export const Tech = () => (
|
||||||
|
<section className="py-12 sm:py-24 bg-customDarkBg1 w-full mt-16 mb-16">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className="container px-4 mx-auto 2xl:w-[1200px] xl:w-[1100px] lg:w-[1000px] md:w-4/5">
|
||||||
|
<div className="flex lg:flex-row flex-col items-center -mx-4 justify-center lg:text-left text-center">
|
||||||
|
<div className="w-full lg:w-1/2 px-4 mb-12 lg:mb-0">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<h2 className="mb-2 text-4xl sm:text-5xl 2xl:text-6xl font-bold tracking-normal text-white">
|
||||||
|
Built with
|
||||||
|
</h2>
|
||||||
|
<h2 className=" text-4xl sm:text-5xl 2xl:text-6xl font-bold tracking-normal text-customSecondary">
|
||||||
|
modern tech
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-2/3 sm:w-[620px] lg:w-1/2 mx-auto lg:mx-0 lg:pl-10">
|
||||||
|
<div className="flex flex-wrap -m-4">
|
||||||
|
<div className="w-1/2 sm:w-1/4 py-6 flex justify-center">
|
||||||
|
<a href="https://tauri.app" target="_blank">
|
||||||
|
<TauriLogo />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 sm:w-1/4 py-6 flex justify-center">
|
||||||
|
<a
|
||||||
|
href="https://www.typescriptlang.org/"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<TypescriptLogo />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 sm:w-1/4 py-6 flex justify-center">
|
||||||
|
<a
|
||||||
|
href="https://www.rust-lang.org/"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<RustLogo />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 sm:w-1/4 py-6 flex justify-center">
|
||||||
|
<a href="https://nextjs.org/" target="_blank">
|
||||||
|
<NextLogo />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
82
src/components/Testimonials.jsx
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import { QuoteIcon } from "../assets/icons/QuoteIcon";
|
||||||
|
import testimonial1 from "../assets/images/testimonial1.png";
|
||||||
|
import testimonial2 from "../assets/images/testimonial2.png";
|
||||||
|
import testimonial3 from "../assets/images/testimonial3.png";
|
||||||
|
|
||||||
|
const testimonialsData = [
|
||||||
|
{
|
||||||
|
customerName: "John Watkins",
|
||||||
|
customerTitle: "Founder of Dashflow",
|
||||||
|
content:
|
||||||
|
"The powerful analytic tools have helped us streamline our processes and make data-driven decisions that positively impact our efficiency. Tailcast has been a game-changer for our business. The platform is easy to use, and the insights we've gained have driven significant improvements.",
|
||||||
|
image: testimonial1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
customerName: "John Watkins",
|
||||||
|
customerTitle: "Founder of Dashflow",
|
||||||
|
content:
|
||||||
|
"The powerful analytic tools have helped us streamline our processes and make data-driven decisions that positively impact our efficiency. Tailcast has been a game-changer for our business. The platform is easy to use, and the insights we've gained have driven significant improvements.",
|
||||||
|
image: testimonial2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
customerName: "John Watkins",
|
||||||
|
customerTitle: "Founder of Dashflow",
|
||||||
|
content:
|
||||||
|
"The powerful analytic tools have helped us streamline our processes and make data-driven decisions that positively impact our efficiency. Tailcast has been a game-changer for our business. The platform is easy to use, and the insights we've gained have driven significant improvements.",
|
||||||
|
image: testimonial3,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Testimonials = () => (
|
||||||
|
<section className="w-full flex justify-center pt-10 mb-16 lg:mb-32 bg-customDarkBg2 relative">
|
||||||
|
<div className="absolute -top-16" id="feedback" />
|
||||||
|
<div className="flex flex-col w-full lg:w-[1150px] justify-center">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
whileInView={{ opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.4, delay: 0.3 }}
|
||||||
|
>
|
||||||
|
{/* <div className="custom-block-subtitle text-center mb-6">
|
||||||
|
Testimonials
|
||||||
|
</div> */}
|
||||||
|
<div className="custom-block-big-title text-center mb-16 px-8 sm:px-24 md:px-48">
|
||||||
|
Testimonials
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col lg:flex-row gap-8 lg:gap-5 xl:gap-10 px-6 xl:px-0 items-center">
|
||||||
|
{testimonialsData.map((testimonial, index) => (
|
||||||
|
<div
|
||||||
|
className="w-11/12 sm:w-4/5 md:w-[560px] lg:w-1/3 custom-border-gray-darker rounded-xl bg-customDarkBg3 flex flex-col px-6 py-4"
|
||||||
|
key={`${testimonial.customerName}-${index}`}
|
||||||
|
>
|
||||||
|
<div className="flex mb-2">
|
||||||
|
<QuoteIcon />
|
||||||
|
</div>
|
||||||
|
<div className="custom-content-text-white">
|
||||||
|
"{testimonial.content}"
|
||||||
|
</div>
|
||||||
|
<div className="flex mt-4 mb-2 xl:mt-8 xl:mb-4">
|
||||||
|
<img
|
||||||
|
src={testimonial.image}
|
||||||
|
alt=""
|
||||||
|
width="45px"
|
||||||
|
/>
|
||||||
|
<div className="flex flex-col ml-4">
|
||||||
|
<div className="custom-content-text-white font-medium">
|
||||||
|
{testimonial.customerName}
|
||||||
|
</div>
|
||||||
|
<div className="custom-content-text-gray">
|
||||||
|
{testimonial.customerTitle}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
1
src/env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="astro/client" />
|
||||||
54
src/layouts/Layout.astro
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
import "@fontsource/inter";
|
||||||
|
import "@fontsource/inter/500.css";
|
||||||
|
import "@fontsource/inter/600.css";
|
||||||
|
import "@fontsource/inter/700.css";
|
||||||
|
import "@fontsource/inter/800.css";
|
||||||
|
import "@fontsource/inter/900.css";
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
<!-- Primary Meta Tags -->
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta name="title" content={title} />
|
||||||
|
<meta name="description" content="Transform and upload spreadsheet data to CKAN with our streamlined desktop app, featuring 'recipes' for common data wrangling tasks. Based on the qsv CLI tool." />
|
||||||
|
|
||||||
|
<!-- Open Graph / Facebook -->
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="https://dathere.github.io/qsv.pro" />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content="Transform and upload spreadsheet data to CKAN with our streamlined desktop app, featuring 'recipes' for common data wrangling tasks. Based on the qsv CLI tool." />
|
||||||
|
<meta property="og:image" content="/sm-preview.png" />
|
||||||
|
|
||||||
|
<!-- Twitter -->
|
||||||
|
<meta property="twitter:card" content="summary_large_image" />
|
||||||
|
<meta property="twitter:url" content="https://dathere.github.io/qsv.pro" />
|
||||||
|
<meta property="twitter:title" content={title} />
|
||||||
|
<meta property="twitter:description" content="Transform and upload spreadsheet data to CKAN with our streamlined desktop app, featuring 'recipes' for common data wrangling tasks. Based on the qsv CLI tool." />
|
||||||
|
<meta property="twitter:image" content="/sm-preview.png" />
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<slot />
|
||||||
|
<style is:global>
|
||||||
|
html {
|
||||||
|
font-family: Inter;
|
||||||
|
background-color: #26272b;
|
||||||
|
overflow-x: hidden;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
38
src/pages/index.astro
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
import Layout from "../layouts/Layout.astro";
|
||||||
|
import { Hero } from "../components/Hero.jsx";
|
||||||
|
import { Navbar } from "../components/Navbar.jsx";
|
||||||
|
import { Features1 } from "../components/Features1.jsx";
|
||||||
|
import { Features2 } from "../components/Features2.jsx";
|
||||||
|
import { Testimonials } from "../components/Testimonials.jsx";
|
||||||
|
import { FeaturesDiagonal } from "../components/FeaturesDiagonal.jsx";
|
||||||
|
import { Pricing } from "../components/Pricing.jsx";
|
||||||
|
import { FAQ } from "../components/FAQ.jsx";
|
||||||
|
// import { Brands } from "../components/Brands.jsx";
|
||||||
|
import { Tech } from "../components/Tech.jsx";
|
||||||
|
import { Divider } from "../components/Divider";
|
||||||
|
import { Footer } from "../components/Footer.jsx";
|
||||||
|
import { ScrollUpButton } from "../components/ScrollUpButton";
|
||||||
|
import "../styles/Theme.css";
|
||||||
|
import "../styles/Diagonals.css";
|
||||||
|
import { Features0 } from "../components/Features0";
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="qsv pro">
|
||||||
|
<Navbar client:load />
|
||||||
|
<Hero client:load />
|
||||||
|
<Features0 client:load />
|
||||||
|
<Divider />
|
||||||
|
<Features1 client:load />
|
||||||
|
<Divider />
|
||||||
|
<Features2 client:load />
|
||||||
|
<!-- <Testimonials client:load /> -->
|
||||||
|
<FeaturesDiagonal client:load />
|
||||||
|
<Pricing client:load />
|
||||||
|
<!-- <Brands client:load /> -->
|
||||||
|
<Tech client:load />
|
||||||
|
<FAQ client:load />
|
||||||
|
<Footer />
|
||||||
|
<ScrollUpButton client:load />
|
||||||
|
</Layout>
|
||||||
48
src/styles/Diagonals.css
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* Hero */
|
||||||
|
|
||||||
|
.custom-shape-divider-bottom-1665343298 {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.custom-shape-divider-bottom-1665343298 svg {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
width: calc(100% + 1.3px);
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
.hero-title-gradient {
|
||||||
|
background: -webkit-linear-gradient(white, #b4add1);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Features Top */
|
||||||
|
|
||||||
|
.custom-shape-divider-bottom-1665696614 {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.custom-shape-divider-bottom-1665696614 svg {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
width: calc(100% + 1.3px);
|
||||||
|
height: 127px;
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Features Bottom */
|
||||||
|
|
||||||
|
.custom-shape-divider-top-1665696661 {
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.custom-shape-divider-top-1665696661 svg {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
width: calc(100% + 1.3px);
|
||||||
|
height: 127px;
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
62
src/styles/Theme.css
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* Typography */
|
||||||
|
|
||||||
|
.custom-block-title {
|
||||||
|
@apply text-white text-3xl font-bold tracking-normal;
|
||||||
|
}
|
||||||
|
.custom-block-big-title {
|
||||||
|
@apply text-white text-4xl xl:text-5xl font-bold tracking-normal;
|
||||||
|
}
|
||||||
|
.custom-block-subtitle {
|
||||||
|
@apply text-xs text-customSecondary tracking-wider font-bold uppercase;
|
||||||
|
}
|
||||||
|
.custom-content-title {
|
||||||
|
@apply text-white text-lg font-bold tracking-normal;
|
||||||
|
}
|
||||||
|
.custom-content-text-white {
|
||||||
|
@apply text-white text-base leading-relaxed;
|
||||||
|
}
|
||||||
|
.custom-content-text-gray {
|
||||||
|
@apply text-gray-400 text-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backgrounds */
|
||||||
|
|
||||||
|
.custom-bg-dark1 {
|
||||||
|
@apply bg-customDarkBg1 fill-customDarkBg1;
|
||||||
|
}
|
||||||
|
.custom-bg-dark2 {
|
||||||
|
@apply bg-customDarkBg2 fill-customDarkBg2;
|
||||||
|
}
|
||||||
|
.custom-bg-dark3 {
|
||||||
|
@apply bg-customDarkBg3 fill-customDarkBg3;
|
||||||
|
}
|
||||||
|
body,
|
||||||
|
html {
|
||||||
|
@apply bg-customDarkBg2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Borders */
|
||||||
|
|
||||||
|
.custom-border-gray {
|
||||||
|
@apply border border-solid border-[rgb(255,255,255,0.15)];
|
||||||
|
}
|
||||||
|
.custom-border-gray-darker {
|
||||||
|
@apply border border-solid border-[rgb(255,255,255,0.07)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
|
||||||
|
.custom-button-colored {
|
||||||
|
@apply rounded-lg font-bold bg-customPrimary text-white flex justify-center items-center hover:bg-[rgb(0,142,200)] cursor-pointer transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navbar */
|
||||||
|
|
||||||
|
.navbar-link {
|
||||||
|
@apply text-white lg:text-base text-2xl leading-6 mr-4 ml-4 2xl:mr-6 2xl:ml-6 cursor-pointer font-normal lg:font-medium hover:scale-110 transition duration-300 h-full pt-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Preventing FOUC */
|
||||||
|
@font-face {
|
||||||
|
font-display: var(--fontsource-Inter-font-display, optional);
|
||||||
|
}
|
||||||
34
tailwind.config.cjs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
customPrimary: "rgb(0,122,255)",
|
||||||
|
customSecondary: "rgb(0,142,200)",
|
||||||
|
customDarkBg1: "rgb(31, 32, 35)",
|
||||||
|
customDarkBg2: "rgb(38, 39, 43)",
|
||||||
|
customDarkBg3: "rgb(48, 49, 54)",
|
||||||
|
customDarkBg3Hover: "rgb(55, 56, 62)",
|
||||||
|
customContentSubtitle: "rgb(178, 184, 205)",
|
||||||
|
customGrayBorder: "rgb(255,255,255,0.1)",
|
||||||
|
customGrayText: "rgb(174, 178, 183)",
|
||||||
|
customDarkBgTransparent: "rgb(31, 32, 35, 0.7)",
|
||||||
|
customDarkBgTransparentDarker: "rgb(0,0,0,0.5)",
|
||||||
|
customDarkBgTransparentLighter: "rgb(48, 49, 54, 0.7)",
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
Inter: "Inter",
|
||||||
|
},
|
||||||
|
screens: {
|
||||||
|
xs: "530px",
|
||||||
|
sm: "640px",
|
||||||
|
md: "768px",
|
||||||
|
lg: "1024px",
|
||||||
|
xl: "1280px",
|
||||||
|
xll: "1400px",
|
||||||
|
"2xl": "1536px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
3
tsconfig.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/base"
|
||||||
|
}
|
||||||