added web-app and landing
30
landing/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
118
landing/AGENTS.md
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
# Landing Interface - CLAUDE.md
|
||||
|
||||
Vue 3 + Vite application serving as the main interface for KRAIKEN protocol.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **Vue 3** (Composition API)
|
||||
- **TypeScript** - Type-safe development
|
||||
- **Vite** - Fast build tooling
|
||||
- **Vue Router** - Client-side routing
|
||||
- **Sass** - Advanced styling
|
||||
|
||||
## Architecture
|
||||
|
||||
### Views
|
||||
|
||||
**HomeView.vue** - Landing page
|
||||
- Launch countdown timer
|
||||
- Project introduction
|
||||
- Feature highlights
|
||||
- Call-to-action for staking
|
||||
|
||||
**DocsView.vue** - Documentation portal
|
||||
- Comprehensive protocol documentation
|
||||
- Auto-generated table of contents
|
||||
- Mobile-responsive navigation
|
||||
- Sections: Introduction, Liquidity, AI Agent, Tokenomics, Staking, FAQ
|
||||
|
||||
### Key Components
|
||||
|
||||
**Layout Components**:
|
||||
- `KNavbar.vue` - Main navigation with scroll effects
|
||||
- `KFooter.vue` - Site footer
|
||||
- `LeftRightComponent.vue` - Content layout helper
|
||||
|
||||
**UI Components**:
|
||||
- `KButton.vue` - Reusable button with hover states
|
||||
- `Countdown.vue` - Launch countdown display
|
||||
- `SocialButton.vue` - Social media links
|
||||
- `NavItem.vue` - Navigation menu items
|
||||
|
||||
**Icons** (`components/icons/`):
|
||||
- Custom SVG icons for UI elements
|
||||
- Social media icons (Twitter, Discord, Telegram)
|
||||
|
||||
## Styling
|
||||
|
||||
### Design System
|
||||
- **Primary Color**: #07111B (deep ocean)
|
||||
- **Accent**: #9667BE (purple)
|
||||
- **Background**: Dark theme throughout
|
||||
- **Typography**: Custom fonts (Audiowide, DM Sans, Orbitron)
|
||||
|
||||
### Responsive Design
|
||||
- Mobile-first approach
|
||||
- Breakpoint: 768px
|
||||
- Slide-out mobile navigation
|
||||
- Optimized images for different screen sizes
|
||||
|
||||
## Development Commands
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start development server
|
||||
npm run dev
|
||||
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# Preview production build
|
||||
npm run preview
|
||||
|
||||
# Type checking
|
||||
npm run type-check
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
Configured for GitHub Pages:
|
||||
- Hash-based routing for compatibility
|
||||
- Base URL configuration in vite.config.ts
|
||||
- Assets optimized for CDN delivery
|
||||
|
||||
## Future Integrations
|
||||
|
||||
### Wallet Connection (Planned)
|
||||
- Web3 wallet integration
|
||||
- Network switching to Base
|
||||
- Transaction signing
|
||||
|
||||
### Staking Interface (Planned)
|
||||
- Position management
|
||||
- Tax rate adjustment
|
||||
- Real-time position monitoring
|
||||
- Snatching interface
|
||||
|
||||
### Data Visualization (Planned)
|
||||
- Protocol metrics dashboard
|
||||
- Liquidity depth charts
|
||||
- Staking statistics
|
||||
|
||||
## Code Quality Guidelines
|
||||
|
||||
- Use Composition API for all components
|
||||
- Leverage TypeScript for type safety
|
||||
- Keep components small and focused
|
||||
- Use Sass variables for consistent theming
|
||||
- Follow Vue 3 best practices
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
- Lazy load route components
|
||||
- Optimize images (WebP format)
|
||||
- Minimize bundle size
|
||||
- Use CSS animations over JavaScript
|
||||
- Implement proper caching strategies
|
||||
33
landing/README.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# vue-kraiken
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vite.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
1
landing/env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
||||
14
landing/index.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KrAIken</title>
|
||||
<script defer src="https://cloud.umami.is/script.js" data-website-id="6e2869f2-02a5-4346-9b3e-3c27e24ea5d3"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
3796
landing/package-lock.json
generated
Normal file
31
landing/package.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "vue-kraiken",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build",
|
||||
"subtree": "git subtree push --prefix dist origin gh-pages"
|
||||
},
|
||||
"dependencies": {
|
||||
"sass": "^1.83.4",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node22": "^22.0.0",
|
||||
"@types/node": "^22.10.7",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"npm-run-all2": "^7.0.2",
|
||||
"typescript": "~5.7.3",
|
||||
"vite": "^6.0.11",
|
||||
"vite-plugin-vue-devtools": "^7.7.0",
|
||||
"vue-tsc": "^2.2.0",
|
||||
"gh-pages": "^6.1.1"
|
||||
}
|
||||
}
|
||||
BIN
landing/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
13
landing/src/App.vue
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { RouterLink, RouterView } from 'vue-router'
|
||||
import KFooter from '@/components/KFooter.vue'
|
||||
import KNavbar from '@/components/KNavbar.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<k-navbar />
|
||||
<main>
|
||||
<RouterView />
|
||||
</main>
|
||||
<k-footer />
|
||||
</template>
|
||||
BIN
landing/src/assets/fonts/Audiowide-Regular.ttf
Normal file
BIN
landing/src/assets/fonts/DMSans-Regular.ttf
Normal file
BIN
landing/src/assets/fonts/DMSans_Medium.ttf
Normal file
BIN
landing/src/assets/fonts/DMSans_Regular.ttf
Normal file
BIN
landing/src/assets/fonts/Inter.ttf
Normal file
BIN
landing/src/assets/fonts/Orbitron.ttf
Normal file
BIN
landing/src/assets/fonts/exo2.ttf
Normal file
BIN
landing/src/assets/img/arielle.png
Normal file
|
After Width: | Height: | Size: 240 KiB |
BIN
landing/src/assets/img/chest.png
Normal file
|
After Width: | Height: | Size: 246 KiB |
BIN
landing/src/assets/img/header-image-mobile.png
Normal file
|
After Width: | Height: | Size: 362 KiB |
BIN
landing/src/assets/img/header-image.png
Normal file
|
After Width: | Height: | Size: 397 KiB |
BIN
landing/src/assets/img/header-imageold.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
landing/src/assets/img/kraken.png
Normal file
|
After Width: | Height: | Size: 423 KiB |
BIN
landing/src/assets/img/liquidityMangerAgentContract.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
landing/src/assets/img/logo.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
64
landing/src/assets/styles/main.sass
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
@font-face
|
||||
font-family: "DM Sans Regular"
|
||||
src: url("@/assets/fonts/DMSans_Regular.ttf") format('truetype')
|
||||
font-weight: 200
|
||||
font-style: normal
|
||||
@font-face
|
||||
font-family: "DM Sans Medium"
|
||||
src: url("@/assets/fonts/DMSans_Medium.ttf") format('truetype')
|
||||
font-weight: 200
|
||||
font-style: normal
|
||||
@font-face
|
||||
font-family: "exo2"
|
||||
src: url("@/assets/fonts/exo2.ttf") format('truetype')
|
||||
font-style: normal
|
||||
@font-face
|
||||
font-family: "orbitron"
|
||||
src: url("@/assets/fonts/Orbitron.ttf") format('truetype')
|
||||
font-style: normal
|
||||
@font-face
|
||||
font-family: "Audiowide"
|
||||
src: url("@/assets/fonts/Audiowide-Regular.ttf") format('truetype')
|
||||
|
||||
*
|
||||
font-family: 'exo2', sans-serif
|
||||
font-weight: 50
|
||||
html
|
||||
body
|
||||
margin: 0
|
||||
background: radial-gradient(96.91% 121.32% at 1.49% 17.97%, rgba(117, 80, 174, 0.00) 46.5%, rgba(37, 37, 71, 0.50) 100%), radial-gradient(91.35% 111.13% at 12.96% 16.43%, rgba(117, 80, 174, 0.00) 46.5%, rgba(30, 34, 63, 0.50) 100%), var(--Color, #07111B)
|
||||
margin: 0
|
||||
font-family: 'Roboto', sans-serif
|
||||
text-align: center
|
||||
// variables
|
||||
color: #F0F0F0
|
||||
letter-spacing: 0.15px
|
||||
font-size: 14px
|
||||
@media (min-width: 992px)
|
||||
font-size: 18px
|
||||
#app
|
||||
display: flex
|
||||
flex-direction: column
|
||||
min-height: 100vh
|
||||
main
|
||||
|
||||
overflow-x: hidden
|
||||
display: flex
|
||||
flex-direction: column
|
||||
padding-bottom: 120px
|
||||
@media (min-width: 992px)
|
||||
margin-top: 0
|
||||
|
||||
footer
|
||||
margin-top: auto
|
||||
.k-container
|
||||
width: auto
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 80px
|
||||
padding: 0 32px
|
||||
@media (min-width: 992px)
|
||||
gap: 120px
|
||||
width: 850px
|
||||
135
landing/src/components/Countdown.vue
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
<template>
|
||||
<div class="countdown">
|
||||
<div class="countdown__title">
|
||||
Time until launch
|
||||
</div>
|
||||
<div class="countdown__time">
|
||||
<slot :days="differenceDays" :hours="differenceHours" :minutes="differenceMinutes">
|
||||
<div>{{ differenceDays }}d {{ differenceHours }}h {{ differenceMinutes }}m {{ differenceSeconds }}s</div>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, computed } from "vue";
|
||||
const seconds = ref(0);
|
||||
let _timerId:ReturnType<typeof setTimeout>;
|
||||
|
||||
interface Props {
|
||||
modelValue: number;
|
||||
end: Date;
|
||||
}
|
||||
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: 0,
|
||||
});
|
||||
|
||||
const differenceDays = computed(() => {
|
||||
if(seconds.value <= 0){
|
||||
return 0
|
||||
}
|
||||
return Math.floor(seconds.value / (3600 * 24))
|
||||
});
|
||||
//tage abziehen
|
||||
const differenceHours = computed(() => {
|
||||
if(seconds.value <= 0){
|
||||
return 0
|
||||
}
|
||||
return Math.floor((seconds.value - differenceDays.value * 3600 * 24) / 3600)
|
||||
});
|
||||
//tage + stunden abziehen
|
||||
const differenceMinutes = computed(() =>
|
||||
{
|
||||
if(seconds.value <= 0){
|
||||
return 0
|
||||
}
|
||||
return Math.floor((seconds.value - differenceDays.value * 3600 * 24 - differenceHours.value * 3600) / 60)
|
||||
}
|
||||
);
|
||||
|
||||
const differenceSeconds = computed(() =>
|
||||
{
|
||||
if (seconds.value <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return seconds.value - differenceDays.value * 86400 - differenceHours.value * 3600 - differenceMinutes.value * 60;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
seconds.value = Math.round((props.end.getTime() - new Date().getTime()) / 1000);
|
||||
if (seconds.value > 0) {
|
||||
_timerId = setInterval(() => {
|
||||
seconds.value--;
|
||||
emit("update:modelValue", seconds.value)
|
||||
|
||||
if (seconds.value <= 0) {
|
||||
|
||||
clearInterval(_timerId);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
}
|
||||
emit("update:modelValue", seconds.value)
|
||||
|
||||
});
|
||||
|
||||
|
||||
onUnmounted(() => clearInterval(_timerId));
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="sass">
|
||||
|
||||
@keyframes borderAnimation
|
||||
0%
|
||||
background-position: 0% 50%
|
||||
50%
|
||||
background-position: 100% 50%
|
||||
100%
|
||||
background-position: 0% 50%
|
||||
|
||||
|
||||
.countdown
|
||||
z-index: 10
|
||||
align-self: center
|
||||
font-weight: bold
|
||||
width: calc( 100vw - 48px)
|
||||
@media (min-width: 768px)
|
||||
width: 500px
|
||||
.countdown__title
|
||||
text-align: left
|
||||
font-size: 18px
|
||||
font-weight: 400
|
||||
margin: 8px
|
||||
@media (min-width: 768px)
|
||||
font-size: 20px
|
||||
.countdown__time
|
||||
box-sizing: border-box
|
||||
padding: 12px 24px
|
||||
font-size: 32px
|
||||
position: relative
|
||||
border-radius: 12px
|
||||
@media (min-width: 768px)
|
||||
font-size: 40px
|
||||
&>div
|
||||
font-family: 'orbitron', sans-serif
|
||||
font-weight: 400
|
||||
&::before
|
||||
content: ""
|
||||
position: absolute
|
||||
inset: 0
|
||||
border-radius: inherit
|
||||
/* Erbt die Abrundung */
|
||||
padding: 2px
|
||||
/* Dicke des Borders */
|
||||
background: linear-gradient(10deg, #BF62B2, black)
|
||||
-webkit-mask: linear-gradient(white, white) content-box, linear-gradient(white, white)
|
||||
-webkit-mask-composite: destination-out
|
||||
mask-composite: exclude
|
||||
z-index: -1
|
||||
</style>
|
||||
43
landing/src/components/KButton.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<button class="kraken-button" :class="{'kraken-button--outlined': props.outlined}">
|
||||
<slot></slot>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
outlined?: boolean
|
||||
}>(), {
|
||||
outlined: false
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="sass">
|
||||
.kraken-button
|
||||
background-color: #000000
|
||||
color: white
|
||||
font-family: 'Exo 2 Bold', sans-serif
|
||||
font-weight: 500
|
||||
line-height: 26px
|
||||
letter-spacing: 0.46px
|
||||
font-size: 14px
|
||||
padding: 16px 64px
|
||||
border-radius: 12px
|
||||
border: none
|
||||
cursor: pointer
|
||||
color: #BF62B2
|
||||
display: inline-block
|
||||
text-align: center
|
||||
text-decoration: none
|
||||
transition: all 0.3s ease-in-out
|
||||
box-shadow: 0px 0px 7.6px 0px #000, 0px 0px 20.6px 0px #BF62B2
|
||||
@media (min-width: 768px)
|
||||
font-size: 20px
|
||||
|
||||
&:hover,&:active
|
||||
background-color: #F9F9FA
|
||||
color: #9667BE
|
||||
box-shadow: 4px 4px 4px 0px rgba(0, 0, 0, 0.25) inset
|
||||
</style>
|
||||
20
landing/src/components/KFooter.vue
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<footer class="k-container">
|
||||
<div class="k-footer">
|
||||
KrAIken is a project by <u><a href="https://sovraigns.network/" target="_blank">SovrAIgns.network</a></u>.<br /> Resarch and Development in DeFAI (DeFi x AI) Agents. Use at your own risk.
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
|
||||
<style lang="sass">
|
||||
.k-footer
|
||||
font-size: 14px
|
||||
line-height: 22px
|
||||
letter-spacing: 0.15px
|
||||
padding-bottom: 48px
|
||||
a
|
||||
color: #F0F0F0
|
||||
@media (min-width: 992px)
|
||||
font-size: 16px
|
||||
</style>
|
||||
238
landing/src/components/KNavbar.vue
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
<template>
|
||||
<header>
|
||||
<div class="kraken-navbar" :class="{ scrolled: isScrolled }">
|
||||
<div class="navbar-left" @click="router.push('/')">
|
||||
<div class="navbar-title">
|
||||
<span>K</span>
|
||||
<span class="big-spacing">r</span>
|
||||
<span class="small-spacing">A</span>
|
||||
<span class="big-spacing">I</span>
|
||||
<span>ken</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="desktop-nav">
|
||||
<RouterLink to="/docs">Docs</RouterLink>
|
||||
<div class="social-buttons">
|
||||
<social-button type="telegram" href="https://t.me/kraikenportal"></social-button>
|
||||
<social-button type="twitter" href="https://x.com/KrAIkenProtocol"></social-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-trigger" @click.stop="toggleMenu">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<circle cx="12" cy="5" r="2" :fill="isScrolled ? '#D6D6D6' : '#07111B'" />
|
||||
<circle cx="12" cy="12" r="2" :fill="isScrolled ? '#D6D6D6' : '#07111B'" />
|
||||
<circle cx="12" cy="19" r="2" :fill="isScrolled ? '#D6D6D6' : '#07111B'" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-overlay" v-if="isMenuOpen" @click="closeMenu"></div>
|
||||
<div class="slide-menu" :class="{ 'is-open': isMenuOpen }">
|
||||
<div class="menu-items">
|
||||
<RouterLink
|
||||
to="/"
|
||||
@click="closeMenu"
|
||||
:class="{ active: $route.path === '/' }"
|
||||
>Start</RouterLink>
|
||||
<RouterLink
|
||||
to="/docs"
|
||||
@click="closeMenu"
|
||||
:class="{ active: $route.path === '/docs' }"
|
||||
>Docs</RouterLink>
|
||||
</div>
|
||||
<div class="menu-socials">
|
||||
<social-button type="telegram" href="https://t.me/kraikenportal"></social-button>
|
||||
<social-button type="twitter" href="https://x.com/KrAIkenProtocol"></social-button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { RouterLink, useRouter } from "vue-router";
|
||||
import SocialButton from "./SocialButton.vue";
|
||||
import { onMounted, onUnmounted, ref,computed } from "vue";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const scrollPosition = ref(0);
|
||||
|
||||
const isMenuOpen = ref(false);
|
||||
|
||||
const isScrolled = computed(() =>
|
||||
router.currentRoute.value.fullPath.includes('/docs') ||
|
||||
scrollPosition.value > 50
|
||||
);
|
||||
|
||||
function updateScroll() {
|
||||
scrollPosition.value = window.scrollY;
|
||||
}
|
||||
function toggleMenu() {
|
||||
isMenuOpen.value = !isMenuOpen.value;
|
||||
if (isMenuOpen.value) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
} else {
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
isMenuOpen.value = false;
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
onMounted(() => window.addEventListener("scroll", updateScroll));
|
||||
onUnmounted(() => window.removeEventListener("scroll", updateScroll));document.body.style.overflow = '';
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
|
||||
.desktop-nav
|
||||
display: none
|
||||
align-items: center
|
||||
gap: 24px
|
||||
@media (min-width: 768px)
|
||||
display: flex
|
||||
a
|
||||
color: #07111B
|
||||
text-decoration: none
|
||||
font-size: 18px
|
||||
line-height: 24px
|
||||
font-weight: 500
|
||||
&:hover, &:active, &:focus
|
||||
color: #F9F9FA
|
||||
.social-buttons
|
||||
display: flex
|
||||
gap: 16px
|
||||
margin-left: 16px
|
||||
.social-badge
|
||||
border: 2px solid #07111B
|
||||
transition: all 0.2s ease
|
||||
svg
|
||||
fill: #07111B
|
||||
&:hover
|
||||
border: 2px solid #07111B
|
||||
svg
|
||||
fill: #07111B
|
||||
|
||||
.menu-trigger
|
||||
display: none
|
||||
cursor: pointer
|
||||
padding: 8px
|
||||
z-index: 99
|
||||
@media (max-width: 767px)
|
||||
display: block
|
||||
|
||||
.menu-overlay
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
background: rgba(0, 0, 0, 0.6)
|
||||
z-index: 96
|
||||
display: none
|
||||
@media (max-width: 767px)
|
||||
display: block
|
||||
|
||||
.slide-menu
|
||||
position: fixed
|
||||
border-top-left-radius: 20px
|
||||
border-bottom-left-radius: 20px
|
||||
top: 0
|
||||
right: -240px
|
||||
width: 240px
|
||||
height: 400px
|
||||
background: #07111B
|
||||
z-index: 99
|
||||
transition: transform 0.3s ease
|
||||
display: none
|
||||
@media (max-width: 767px)
|
||||
display: flex
|
||||
flex-direction: column
|
||||
&.is-open
|
||||
transform: translateX(-240px)
|
||||
.menu-items
|
||||
padding: 80px 32px
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 24px
|
||||
flex: 1
|
||||
a
|
||||
color: #9A9898
|
||||
text-decoration: none
|
||||
font-size: 24px
|
||||
font-weight: 500
|
||||
&.router-link-active,
|
||||
&.active
|
||||
color: #D6D6D6
|
||||
&:hover
|
||||
opacity: 0.8
|
||||
.menu-socials
|
||||
padding: 32px
|
||||
display: flex
|
||||
gap: 16px
|
||||
justify-content: center
|
||||
|
||||
.kraken-navbar
|
||||
box-sizing: border-box
|
||||
background-color: transparent
|
||||
padding: 8px 24px
|
||||
height: 60px
|
||||
border-bottom: 2px solid transparent
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: space-between
|
||||
position: fixed
|
||||
top: 0
|
||||
transition: 0.2s ease
|
||||
color: #07111B
|
||||
width: 100%
|
||||
z-index: 99
|
||||
&.scrolled
|
||||
background-color: #07111B
|
||||
color: #D6D6D6
|
||||
border-bottom: 2px solid #9A9898
|
||||
.desktop-nav
|
||||
a
|
||||
color: #D6D6D6
|
||||
&:hover
|
||||
color: #F9F9FA
|
||||
.social-buttons
|
||||
.social-badge
|
||||
border-color: #D6D6D6
|
||||
svg
|
||||
fill: #D6D6D6
|
||||
&:hover
|
||||
border-color: #F9F9FA
|
||||
svg
|
||||
fill: #07111B
|
||||
.navbar-left
|
||||
display: flex
|
||||
gap: 8px
|
||||
letter-spacing: 3.6px
|
||||
align-items: center
|
||||
font-size: 32px
|
||||
font-weight: 400
|
||||
&:hover, &:active, &:focus
|
||||
cursor: pointer
|
||||
img
|
||||
height: 40px
|
||||
width: 40px
|
||||
@media (min-width: 768px)
|
||||
height: auto
|
||||
width: auto
|
||||
.navbar-title
|
||||
font-size: 24px
|
||||
font-family: 'Audiowide', sans-serif
|
||||
>*
|
||||
font-family: 'Audiowide', sans-serif
|
||||
@media (min-width: 768px)
|
||||
display: block
|
||||
font-size: 36px
|
||||
font-weight: bold
|
||||
.big-spacing
|
||||
letter-spacing: 5.76px
|
||||
.small-spacing
|
||||
letter-spacing: 1.8px
|
||||
|
||||
|
||||
</style>
|
||||
71
landing/src/components/LeftRightComponent.vue
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<template>
|
||||
<div class="left-right-component" :class="{ 'left-right-component--reverse': props.reverse }">
|
||||
<div class="left">
|
||||
<slot name="left">
|
||||
<img src="@/assets/img/chest.png" alt="kraken" class="image-card" />
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<slot name="right">
|
||||
<h2>Challenge the AI</h2>
|
||||
<p>
|
||||
KrAIken is a <u>DeFAI</u> Protocol in open beta.<br /><br />
|
||||
Everyone is invited to train the AI by trading and challenge it's liquidity positions.
|
||||
</p>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
reverse?: boolean;
|
||||
}>(),
|
||||
{
|
||||
reverse: false,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.left-right-component
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
gap: 24px
|
||||
flex-direction: column
|
||||
text-align: center
|
||||
@media (min-width: 768px)
|
||||
flex-direction: row
|
||||
text-align: unset
|
||||
&.left-right-component--reverse
|
||||
flex-direction: column
|
||||
@media (min-width: 768px)
|
||||
flex-direction: row-reverse
|
||||
.left
|
||||
img
|
||||
height: 255px
|
||||
width: 255px
|
||||
@media (min-width: 768px)
|
||||
width: unset
|
||||
height: unset
|
||||
.right
|
||||
max-width: 480px
|
||||
text-align: center
|
||||
@media (min-width: 768px)
|
||||
text-align: unset
|
||||
text-align: left
|
||||
|
||||
h2
|
||||
font-size: 24px
|
||||
font-weight: 400
|
||||
@media (min-width: 768px)
|
||||
font-size: 27px
|
||||
|
||||
p
|
||||
margin-bottom: 32px
|
||||
@media (min-width: 768px)
|
||||
font-size: 18px
|
||||
</style>
|
||||
69
landing/src/components/NavItem.vue
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<li :class="{ active: isActive, parentActive: hasActiveChild }">
|
||||
<router-link :to="'#' + props.item.id">{{ props.item.title }}</router-link>
|
||||
|
||||
<ul class="nav" v-if="props.item.children && props.item.children.length > 0">
|
||||
<NavItem v-for="(child, index) in props.item.children" :key="index" :item="child" />
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, inject, type Ref } from "vue";
|
||||
|
||||
interface MenuItem {
|
||||
title: string;
|
||||
id: string | null;
|
||||
children: MenuItem[];
|
||||
}
|
||||
|
||||
// Props für das aktuelle Element
|
||||
const props = defineProps<{ item: MenuItem }>();
|
||||
|
||||
// `inject` für die aktive Referenz
|
||||
const activeSection: any = inject("activeSection");
|
||||
|
||||
// Prüfen, ob das aktuelle Element aktiv ist
|
||||
const isActive = computed(() => {
|
||||
return activeSection.value === props.item.id;
|
||||
});
|
||||
|
||||
// Rekursive Prüfung, ob ein untergeordnetes Element aktiv ist
|
||||
const hasActiveChild = computed(() => {
|
||||
return props.item.children.some((child) => checkChildActive(child));
|
||||
});
|
||||
|
||||
function checkChildActive(child: MenuItem): boolean {
|
||||
if (child.id === activeSection.value) {
|
||||
return true;
|
||||
}
|
||||
return child.children.some((subChild) => checkChildActive(subChild));
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.nav {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav li {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
text-decoration: none;
|
||||
color: #D6D6D6;
|
||||
}
|
||||
|
||||
.nav li.active a {
|
||||
font-weight: bold;
|
||||
color: #9667BE;
|
||||
}
|
||||
|
||||
.nav li.parentActive > a {
|
||||
font-weight: bold;
|
||||
color: #9667BE;
|
||||
}
|
||||
</style>
|
||||
67
landing/src/components/SocialButton.vue
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<a :href="props.href" target="_blank">
|
||||
<div
|
||||
class="social-badge"
|
||||
>
|
||||
<div class="social-badge-icon">
|
||||
<component :is="img" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineAsyncComponent, computed } from "vue";
|
||||
|
||||
interface Props {
|
||||
type?: string;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
|
||||
const img = computed(() => {
|
||||
let img;
|
||||
switch (props.type) {
|
||||
case "discord":
|
||||
img = defineAsyncComponent(() => import(`../components/icons/IconDiscord.vue`));
|
||||
break;
|
||||
case "twitter":
|
||||
img = defineAsyncComponent(() => import(`../components/icons/IconTwitter.vue`));
|
||||
break;
|
||||
case "telegram":
|
||||
img = defineAsyncComponent(() => import(`../components/icons/IconTelegram.vue`));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return img;
|
||||
});
|
||||
</script>
|
||||
<style lang="sass">
|
||||
.social-badge
|
||||
border-radius: 14px
|
||||
display: flex
|
||||
border: 2px solid #D6D6D6
|
||||
padding: 8px 24px
|
||||
align-items: center
|
||||
flex: 0 1 0
|
||||
color: black
|
||||
height: 100%
|
||||
box-sizing: border-box
|
||||
@media (min-width: 768px)
|
||||
padding: 8px 48px
|
||||
.social-badge-icon
|
||||
display: flex
|
||||
svg
|
||||
fill: #D6D6D6
|
||||
&:hover,&:active,&:focus
|
||||
cursor: pointer
|
||||
background-color: #F9F9FA
|
||||
svg
|
||||
fill: unset
|
||||
|
||||
</style>
|
||||
7
landing/src/components/icons/IconCommunity.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
||||
<path
|
||||
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
29
landing/src/components/icons/IconDiscord.vue
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<svg width="23" height="18" viewBox="0 0 23 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2590_494)">
|
||||
<path
|
||||
ref="svgPath"
|
||||
d="M19.419 3.40166C16.7691 1.45664 14.2483 1.51053 14.2483 1.51053L13.9906 1.79865C17.1188 2.73512 18.5723 4.08593 18.5723 4.08593C16.6585 3.05941 14.7817 2.55501 13.0336 2.35694C11.7088 2.21276 10.4391 2.24892 9.3167 2.39287C9.20634 2.39287 9.11433 2.41083 9.00397 2.42879C8.35994 2.48292 6.79584 2.71692 4.82702 3.56357C4.14628 3.86966 3.74131 4.08593 3.74131 4.08593C3.74131 4.08593 5.2687 2.66303 8.58065 1.72656L8.39664 1.51053C8.39664 1.51053 5.87579 1.4564 3.22598 3.40166C3.22598 3.40166 0.576172 8.10242 0.576172 13.9018C0.576172 13.9018 2.12191 16.5134 6.18851 16.6393C6.18851 16.6393 6.86925 15.8289 7.42129 15.1446C5.08444 14.4601 4.20109 13.0195 4.20109 13.0195C4.20109 13.0195 4.3851 13.1454 4.71642 13.3256C4.73477 13.3435 4.75313 13.3615 4.79007 13.3797C4.84537 13.4156 4.90043 13.4338 4.95573 13.4697C5.41576 13.7219 5.87579 13.92 6.29911 14.0821C7.05351 14.3703 7.95521 14.6584 9.00397 14.8565C10.3841 15.1087 12.0032 15.1987 13.7697 14.8744C14.6344 14.7303 15.5178 14.4783 16.4378 14.0999C17.0819 13.8656 17.7996 13.5236 18.554 13.0372C18.554 13.0372 17.6339 14.514 15.2234 15.1805C15.7754 15.865 16.4378 16.6393 16.4378 16.6393C20.5047 16.5131 22.0688 13.9018 22.0688 13.9018C22.0688 8.10242 19.419 3.40166 19.419 3.40166ZM7.8818 12.2267C6.85138 12.2267 6.00498 11.3262 6.00498 10.2276C6.00498 9.12894 6.83303 8.22841 7.8818 8.22841C8.93056 8.22841 9.77697 9.12894 9.75861 10.2276C9.75861 11.3262 8.93056 12.2267 7.8818 12.2267ZM14.598 12.2267C13.5675 12.2267 12.7211 11.3262 12.7211 10.2276C12.7211 9.12894 13.5492 8.22841 14.598 8.22841C15.6467 8.22841 16.4748 9.12894 16.4748 10.2276C16.4748 11.3262 15.647 12.2267 14.598 12.2267Z"
|
||||
:fill="props.color"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2590_494">
|
||||
<rect width="22" height="17" fill="white" transform="translate(0.333984 0.58667)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
const svgPath = ref();
|
||||
|
||||
interface Props {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
</script>
|
||||
7
landing/src/components/icons/IconDocumentation.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
|
||||
<path
|
||||
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
7
landing/src/components/icons/IconEcosystem.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
|
||||
<path
|
||||
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
5
landing/src/components/icons/IconMenu.vue
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<!-- Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc. -->
|
||||
<path d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"/></svg>
|
||||
</template>
|
||||
7
landing/src/components/icons/IconSupport.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
||||
<path
|
||||
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
22
landing/src/components/icons/IconTelegram.vue
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<template>
|
||||
<svg width="18" height="15" viewBox="0 0 18 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Group">
|
||||
<path id="Vector" d="M16.558 0.345906L1.24462 6.2506C0.199293 6.66992 0.205631 7.2531 1.05407 7.5128L4.98317 8.73926L6.33449 13.1866C6.51217 13.677 6.42458 13.8716 6.93975 13.8716C7.33718 13.8716 7.51274 13.6899 7.7346 13.4742L9.64412 11.6175L13.6166 14.5525C14.3477 14.9559 14.8754 14.7469 15.0575 13.8739L17.6654 1.58466C17.9324 0.51398 17.2574 0.0283891 16.558 0.345906Z" />
|
||||
<path id="Vector_2" d="M6.95616 12.6891L5.66016 8.424L15.6361 2.50586L8.26406 9.76418L6.95616 12.6891Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
const svgPath = ref();
|
||||
|
||||
interface Props {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
</script>
|
||||
19
landing/src/components/icons/IconTooling.vue
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
|
||||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
aria-hidden="true"
|
||||
role="img"
|
||||
class="iconify iconify--mdi"
|
||||
width="24"
|
||||
height="24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
18
landing/src/components/icons/IconTwitter.vue
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<template>
|
||||
<svg width="19" height="19" viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M0.5 0.5L7.4306 10.625L0.646792 18.5H2.14979L8.0944 11.5946L12.8213 18.5H18.5L11.2592 7.92259L17.6488 0.5H16.1504L10.5945 6.95025L6.17872 0.5H0.5ZM2.29474 1.44737H5.6811L16.7053 17.5526H13.3189L2.29474 1.44737Z"/>
|
||||
</svg>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
const svgPath = ref();
|
||||
|
||||
interface Props {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
</script>
|
||||
30
landing/src/composables/useMobile.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
|
||||
// by convention, composable function names start with "use"
|
||||
export function useMobile() {
|
||||
const isMobile = ref<boolean>(false);
|
||||
|
||||
const handleWindowSizeChange = () => {
|
||||
isMobile.value = isMobileFunc();
|
||||
};
|
||||
|
||||
isMobile.value = isMobileFunc();
|
||||
function isMobileFunc() {
|
||||
if (screen.width <= 768) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
window.addEventListener("resize", handleWindowSizeChange);
|
||||
handleWindowSizeChange();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener("resize", handleWindowSizeChange);
|
||||
});
|
||||
|
||||
return isMobile;
|
||||
}
|
||||
10
landing/src/main.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import './assets/styles/main.sass'
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
94
landing/src/router/index.ts
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: HomeView,
|
||||
},
|
||||
{
|
||||
path: "/docs",
|
||||
name: "Docs",
|
||||
meta: {
|
||||
title: "Docs",
|
||||
group: "navbar",
|
||||
// group: "navbar",
|
||||
},
|
||||
redirect: "/docs/Introduction",
|
||||
component: () => import("../views/DocsView.vue"),
|
||||
children: [
|
||||
{
|
||||
path: "/docs/Introduction",
|
||||
name: "Introduction",
|
||||
meta: {
|
||||
title: "Docs",
|
||||
// group: "navbar",
|
||||
},
|
||||
component: () => import("../views/docs/Introduction.vue"),
|
||||
},
|
||||
{
|
||||
path: "/docs/Liquidity-Management",
|
||||
name: "Liquidity Management",
|
||||
meta: {
|
||||
title: "Docs",
|
||||
// group: "navbar",
|
||||
},
|
||||
component: () => import("../views/docs/Liquidity-Management.vue"),
|
||||
},
|
||||
{
|
||||
path: "/docs/AI-agent",
|
||||
name: "AI-agent",
|
||||
meta: {
|
||||
title: "Docs",
|
||||
// group: "navbar",
|
||||
},
|
||||
component: () => import("../views/docs/ai-agent.vue"),
|
||||
},
|
||||
{
|
||||
path: "/docs/Tokenomics",
|
||||
name: "Tokenomics",
|
||||
meta: {
|
||||
title: "Docs",
|
||||
// group: "navbar",
|
||||
},
|
||||
component: () => import("../views/docs/Tokenomics.vue"),
|
||||
},
|
||||
{
|
||||
path: "/docs/Staking",
|
||||
name: "Staking",
|
||||
meta: {
|
||||
title: "Docs",
|
||||
// group: "navbar",
|
||||
},
|
||||
component: () => import("../views/docs/Staking.vue"),
|
||||
},
|
||||
{
|
||||
path: "/docs/FAQ",
|
||||
name: "FAQ",
|
||||
meta: {
|
||||
title: "Docs",
|
||||
// group: "navbar",
|
||||
},
|
||||
component: () => import("../views/docs/FAQ.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
// Überprüfen, ob der Zielort ein Hash enthält
|
||||
if (to.hash) {
|
||||
// Warten, bis die Komponente geladen ist und dann zum Ziel scrollen
|
||||
return {
|
||||
el: to.hash,
|
||||
behavior: "smooth", // Optional: für sanftes Scrollen
|
||||
top: 80,
|
||||
};
|
||||
}
|
||||
return savedPosition || { top: 0 }; // Scrollen zum Anfang der Seite, falls kein Hash vorhanden ist
|
||||
},
|
||||
})
|
||||
|
||||
export default router
|
||||
364
landing/src/views/DocsView.vue
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
<template>
|
||||
<div class="docs-overlay" :class="{ open: sideMenuOpen }" @click="sideMenuOpen = false"></div>
|
||||
<div class="docs-view" ref="docsView" style="
|
||||
padding-top: 60px;
|
||||
">
|
||||
<div class="docs--header">
|
||||
<div class="side-menu-toggle">
|
||||
<div class="menu-circle"></div>
|
||||
<icon-menu @click="openSideMenu"></icon-menu>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<div class="side-menu" v-if="sideMenuOpen">
|
||||
<h4>Navigation</h4>
|
||||
<RouterLink
|
||||
@click="sideMenuOpen = false"
|
||||
v-for="route in docsRoute?.children"
|
||||
:key="route.name"
|
||||
:to="route.path"
|
||||
>{{ route.name }}</RouterLink
|
||||
>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="docs--body">
|
||||
<div class="left">
|
||||
<div class="left-navigation">
|
||||
<h4>Navigation</h4>
|
||||
<RouterLink v-for="route in docsRoute?.children" :key="route.name" :to="route.path">{{
|
||||
route.name
|
||||
}}</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center">
|
||||
<RouterView @onmounted="routeOnMounted" />
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="content" :key="rerender">
|
||||
<div class="outline-marker" style="top: 71px; opacity: 1"></div>
|
||||
<div><b>On this page</b></div>
|
||||
<ul class="nav">
|
||||
<NavItem v-for="(item, index) in subMenu" :key="index" :item="item" />
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute, useRouter, RouterLink } from "vue-router";
|
||||
import { ref, onMounted, onBeforeUnmount, watch, provide } from "vue";
|
||||
import IconMenu from "@/components/icons/IconMenu.vue";
|
||||
import NavItem from "@/components/NavItem.vue";
|
||||
|
||||
const route = useRoute();
|
||||
console.log("route", route);
|
||||
|
||||
const router = useRouter();
|
||||
console.log("router", router.getRoutes());
|
||||
const rerender = ref(0);
|
||||
const docsView = ref();
|
||||
const sideMenuOpen = ref(false);
|
||||
|
||||
const headings = ref();
|
||||
const subMenu = ref<Array<any>>([]);
|
||||
|
||||
const docsRoute = router.getRoutes().find((obj) => obj.name === "Docs");
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
loadHeadlines();
|
||||
});
|
||||
|
||||
function loadHeadlines() {
|
||||
console.log("loadHeadlines");
|
||||
|
||||
headings.value = [];
|
||||
subMenu.value = [];
|
||||
const headings1 = docsView.value.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
||||
|
||||
console.log("headings1", headings1);
|
||||
generateIds(headings1);
|
||||
subMenu.value = createMenuStructure(headings1);
|
||||
console.log("subMenu.value", subMenu.value);
|
||||
}
|
||||
|
||||
function generateIds(headings: any) {
|
||||
for (let index = 0; index < headings.length; index++) {
|
||||
const element = headings[index];
|
||||
if (!element.id) {
|
||||
element.id = element.tagName + index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createMenuStructure(headings: any) {
|
||||
const menu: Array<any> = [];
|
||||
const stack = [{ level: 0, children: menu }];
|
||||
let i = 0;
|
||||
headings.forEach((heading: any) => {
|
||||
const level = parseInt(heading.tagName.slice(1), 10);
|
||||
const title = heading.textContent.trim();
|
||||
let id = heading.id || null;
|
||||
console.log("heading.id", heading.id);
|
||||
|
||||
if (!id) {
|
||||
id = heading.tagName + i;
|
||||
}
|
||||
|
||||
const newItem = { title, id, children: [] };
|
||||
|
||||
// Passende Position im Stack finden
|
||||
while (stack.length > 0 && stack[stack.length - 1].level >= level) {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
// Neues Element als Kind des aktuellen Stack-Eintrags hinzufügen
|
||||
stack[stack.length - 1].children.push(newItem);
|
||||
|
||||
// Aktuelles Element auf den Stack legen
|
||||
stack.push({ level, children: newItem.children });
|
||||
i++;
|
||||
});
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
function openSideMenu() {
|
||||
sideMenuOpen.value = true;
|
||||
}
|
||||
|
||||
function routeOnMounted() {
|
||||
console.log("routeOnMounted");
|
||||
rerender.value++;
|
||||
console.log("rerender", rerender);
|
||||
loadHeadlines();
|
||||
}
|
||||
|
||||
const activeSection = ref("");
|
||||
|
||||
// Überwache den Scrollvorgang
|
||||
const handleScroll = () => {
|
||||
const sections = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
||||
|
||||
sections.forEach((section) => {
|
||||
const rect = section.getBoundingClientRect();
|
||||
if (rect.top <= window.innerHeight / 2 && rect.bottom >= window.innerHeight / 2) {
|
||||
activeSection.value = section.id;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
provide("activeSection", activeSection);
|
||||
|
||||
// Scroll-Events verwalten
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("scroll", handleScroll);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.docs-view
|
||||
.docs--body
|
||||
pre
|
||||
overflow: auto
|
||||
max-width: 100%
|
||||
width: calc(100vw - 48px)
|
||||
@media (min-width: 992px)
|
||||
width: auto
|
||||
overflow: unset
|
||||
// docs styling e.g. warning-class
|
||||
.warning
|
||||
color: #e6a23c
|
||||
font-weight: bold
|
||||
.danger
|
||||
color: #f56c6c
|
||||
font-weight: bold
|
||||
.docs-overlay
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
height: 100%
|
||||
width: 100%
|
||||
background-color: rgba(15, 15, 15, 0.7)
|
||||
display: none
|
||||
z-index: 100
|
||||
&.open
|
||||
display: block
|
||||
.docs-view
|
||||
position: relative
|
||||
font-size: 16px
|
||||
text-align: left
|
||||
.docs--header
|
||||
height: 40px
|
||||
top: unset
|
||||
bottom: 24px
|
||||
left: 24px
|
||||
position: fixed
|
||||
height: 40px
|
||||
padding: 4px
|
||||
display: flex
|
||||
align-items: center
|
||||
background-color: var(--color-primary)
|
||||
z-index: 96
|
||||
@media (min-width: 992px)
|
||||
display: none
|
||||
.side-menu-toggle
|
||||
height: 40px
|
||||
padding: 12px
|
||||
position: fixed
|
||||
top: unset
|
||||
bottom: 24px
|
||||
left: 24px
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
z-index: 97
|
||||
.menu-circle
|
||||
position: absolute
|
||||
width: 64px
|
||||
height: 64px
|
||||
background-color: rgba(0, 0, 0, 0.89)
|
||||
border-radius: 50%
|
||||
z-index: 96
|
||||
svg
|
||||
height: 36px
|
||||
position: relative
|
||||
z-index: 98
|
||||
path
|
||||
fill: white
|
||||
.docs--body
|
||||
display: flex
|
||||
pre
|
||||
line-height: 1
|
||||
font-family: monospace
|
||||
h1, h2, h3
|
||||
text-align: left !important
|
||||
h1
|
||||
letter-spacing: -0.02em
|
||||
line-height: 40px
|
||||
font-size: 32px
|
||||
h2
|
||||
margin: 48px 0 16px
|
||||
border-top: 1px solid lightgrey
|
||||
padding-top: 24px
|
||||
letter-spacing: -0.02em
|
||||
line-height: 32px
|
||||
font-size: 24px
|
||||
h3
|
||||
margin: 24px 0 16px
|
||||
font-size: 20px
|
||||
ul
|
||||
padding-left: 1.25rem
|
||||
margin: 16px 0
|
||||
|
||||
>div
|
||||
flex: 0 0 auto
|
||||
.right
|
||||
width: 224px
|
||||
padding: 0 32px 0 0
|
||||
position: relative
|
||||
display: none
|
||||
@media (min-width: 992px)
|
||||
display: block
|
||||
.content
|
||||
position: fixed
|
||||
border-left: 1px solid lightgrey
|
||||
padding-left: 16px
|
||||
font-size: 13px
|
||||
font-weight: 500
|
||||
margin-top: 20px
|
||||
ul
|
||||
padding: 0 12px
|
||||
margin: 0
|
||||
li
|
||||
list-style: none
|
||||
&.active
|
||||
color: #9667BE
|
||||
font-weight: bold
|
||||
.left
|
||||
width: 272px
|
||||
padding: 0 16px
|
||||
position: relative
|
||||
display: none
|
||||
color: #D6D6D6
|
||||
@media (min-width: 992px)
|
||||
display: block
|
||||
padding: 0 64px
|
||||
.left-navigation
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 8px
|
||||
position: fixed
|
||||
a
|
||||
color: inherit
|
||||
text-decoration: none
|
||||
&.router-link-active
|
||||
color: #9667BE
|
||||
font-weight: bold
|
||||
h4
|
||||
font-size: 20px
|
||||
margin-bottom: 16px
|
||||
.center
|
||||
padding: 0 24px
|
||||
flex: 1 1 auto
|
||||
a
|
||||
text-decoration: underline
|
||||
color: #3451b2
|
||||
font-weight: bold
|
||||
|
||||
|
||||
.side-menu
|
||||
display: flex
|
||||
flex-direction: column
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
z-index: 101
|
||||
padding: 112px 32px 96px 32px
|
||||
width: 50vw
|
||||
max-width: 320px
|
||||
background-color: var(--vp-sidebar-bg-color, #0F0F0F)
|
||||
// opacity: 0
|
||||
box-shadow: var(--vp-c-shadow-3)
|
||||
overflow-x: hidden
|
||||
overflow-y: auto
|
||||
transition: opacity 0.5s, transform 0.25s ease
|
||||
overscroll-behavior: contain
|
||||
color: #9A9898
|
||||
background-color: var(--midnight-black, #0F0F0F)
|
||||
height: 100vh
|
||||
gap: 4px
|
||||
transform: translateX(0)
|
||||
.router-link-active
|
||||
color: white
|
||||
font-weight: bold
|
||||
a
|
||||
color: white
|
||||
text-decoration: none
|
||||
font-size: 20px
|
||||
padding: 4px 0
|
||||
h4
|
||||
colour: #9A9898
|
||||
font-size: 24px // Made the Navigation title bigger too
|
||||
margin-bottom: 20px
|
||||
|
||||
|
||||
.slide-enter
|
||||
transform: translateX(-100%)
|
||||
|
||||
|
||||
.slide-enter-active
|
||||
transition: all .1s ease-in
|
||||
transform: translateX(-100%)
|
||||
|
||||
|
||||
|
||||
|
||||
.slide-leave-active
|
||||
transition: all .2s ease-in
|
||||
|
||||
.slide-leave-to
|
||||
transform: translateX(-100%)
|
||||
</style>
|
||||
188
landing/src/views/HomeView.vue
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
<template>
|
||||
<div class="header-section">
|
||||
<img v-if="isMobile" src="@/assets/img/header-image-mobile.png" width="800" height="600" alt="Kraiken Boss" />
|
||||
<img v-else src="@/assets/img/header-image.png" width="1920" height="1080" alt="Kraiken Boss" />
|
||||
<div class="header-text">
|
||||
Deep Liquidity <br />
|
||||
AI Agent
|
||||
</div>
|
||||
<div class="blur-effect"></div>
|
||||
</div>
|
||||
<countdown v-model="countdownExpired" :end="endDt">
|
||||
<template #default>
|
||||
Coming soon
|
||||
</template>
|
||||
</countdown>
|
||||
<div class="k-container">
|
||||
<section class="token-liquidity-section">
|
||||
<h2>Unruggable Token Liquidity</h2>
|
||||
<p>
|
||||
$KRK is the first token with unruggable liquidity managed by AI.<br /><br />
|
||||
The liquidity pool is protected by a sovereign AI Agent that optimizes liquidity positions based on real
|
||||
time market data.
|
||||
</p>
|
||||
<br />
|
||||
<!-- <k-button outlined @click="openUniswap" @mouseover="onMouseOver" @mouseout="onMouseOut"> {{ getKrkText }} </k-button> -->
|
||||
<k-button outlined @mouseover="onMouseOver" @mouseout="onMouseOut"> {{ getKrkText }} </k-button>
|
||||
</section>
|
||||
<section class="challenge-section">
|
||||
<left-right-component reverse>
|
||||
<template #left>
|
||||
<img src="@/assets/img/chest.png" alt="kraken" class="image-card" />
|
||||
</template>
|
||||
<template #right>
|
||||
<h2>Going Deeper</h2>
|
||||
<p>
|
||||
KrAIken is built to deepen token liquidity, starting in the $KRK pool—an ideal ground for
|
||||
mastering market tides. <br /><br />
|
||||
|
||||
Once matured, it extends its reach across the crypto ocean, managing diverse pools, generating
|
||||
profit, and expanding utility.
|
||||
</p>
|
||||
</template>
|
||||
</left-right-component>
|
||||
<left-right-component>
|
||||
<template #left>
|
||||
<img src="@/assets/img/arielle.png" alt="kraken" class="image-card" />
|
||||
</template>
|
||||
<template #right>
|
||||
<h2>Meet Arielle (coming soon)</h2>
|
||||
<p>
|
||||
Ask questions, challenge the protocol, and find edge cases for KrAIken. <br /><br />
|
||||
Arielle is here to assist.
|
||||
</p>
|
||||
<k-button @click="router.push('/docs')"> Read Docs</k-button>
|
||||
</template>
|
||||
</left-right-component>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import KButton from "@/components/KButton.vue";
|
||||
import LeftRightComponent from "@/components/LeftRightComponent.vue";
|
||||
import Countdown from "@/components/Countdown.vue";
|
||||
import { useMobile } from "@/composables/useMobile";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const endDt = new Date(1742572800000);
|
||||
const countdownExpired = ref(1);
|
||||
const getKrkText = ref("Get $KRK");
|
||||
const isMobile = useMobile();
|
||||
const router = useRouter();
|
||||
|
||||
function openUniswap() {
|
||||
window.open(
|
||||
"https://app.uniswap.org/swap?chain=base&inputCurrency=NATIVE&outputCurrency=0x45caa5929f6ee038039984205bdecf968b954820",
|
||||
"_blank"
|
||||
);
|
||||
}
|
||||
|
||||
function onMouseOver(event: any) {
|
||||
getKrkText.value = "On launch";
|
||||
|
||||
}
|
||||
|
||||
function onMouseOut(event: any) {
|
||||
getKrkText.value = "Get $KRK";
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.header-section
|
||||
position: relative
|
||||
.blur-effect
|
||||
filter: blur(45px)
|
||||
height: 300px
|
||||
position: absolute
|
||||
bottom: -150px
|
||||
width: 100%
|
||||
background-color: #07111B
|
||||
left: -10%
|
||||
width: 120%
|
||||
|
||||
img
|
||||
max-width: 100%
|
||||
min-width: 100%
|
||||
height: auto
|
||||
.header-text
|
||||
color: #E6E6E6
|
||||
mix-blend-mode: color-dodge
|
||||
font-weight: 500
|
||||
position: absolute
|
||||
text-align: left
|
||||
top: 50%
|
||||
left: 35%
|
||||
transform: translate(-50%, -50%)
|
||||
font-size: 35px
|
||||
font-weight: 500
|
||||
@media (min-width: 768px)
|
||||
width: unset
|
||||
font-size: 78px
|
||||
.image-card
|
||||
box-shadow: 0px 0px 50px 0px #000
|
||||
border-radius: 14.5px
|
||||
.section-block
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 32px
|
||||
.kraken-button
|
||||
align-self: center
|
||||
|
||||
h2
|
||||
line-height: 133%
|
||||
letter-spacing: 0px
|
||||
|
||||
.hero-section
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
text-align: center
|
||||
flex-direction: column
|
||||
@media (min-width: 768px)
|
||||
text-align: left
|
||||
flex-direction: row-reverse
|
||||
img
|
||||
height: 450px
|
||||
width: 250px
|
||||
@media (min-width: 768px)
|
||||
width: unset
|
||||
height: unset
|
||||
|
||||
.hero-text
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
@media (min-width: 768px)
|
||||
width: 365px
|
||||
h1
|
||||
font-size: 27px
|
||||
@media (min-width: 768px)
|
||||
font-size: 42px
|
||||
|
||||
p
|
||||
font-size: 18px
|
||||
.token-liquidity-section
|
||||
text-align: center
|
||||
align-self: center
|
||||
margin-top: 88px
|
||||
max-width: 840px
|
||||
z-index: 10
|
||||
p
|
||||
text-align: center
|
||||
font-weight: 50
|
||||
@media (min-width: 768px)
|
||||
text-align: unset
|
||||
h2
|
||||
font-weight: 400
|
||||
letter-spacing: 0.25px
|
||||
font-size: 24px
|
||||
@media (min-width: 768px)
|
||||
font-size: 27px
|
||||
.challenge-section
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 120px
|
||||
</style>
|
||||
38
landing/src/views/docs/FAQ.vue
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1 id="first">FAQ</h1>
|
||||
<h3>Where to buy $KRK?</h3>
|
||||
<p>Once launched you can buy $KRK on Uniswap on Base Layer 2.</p>
|
||||
<h3>What is the utility of $KRK?</h3>
|
||||
<p>$KRK serves as training data for the AI agent and will eventually generate returns through cross-pool liquidity management.</p>
|
||||
<h3>Why is the liquidity unruggable?</h3>
|
||||
<p>Liquidity is permanently locked in Uniswap and managed by immutable contracts, with 75-95% ETH reserved in the Floor position to prevent full withdrawals even through a bank run event.</p>
|
||||
<h3>How often does supply expand?</h3>
|
||||
<p>The AI liquidity manager mints new $KRK based on market conditions - typically during sustained buying pressure or liquidity needs.</p>
|
||||
<h3>What happens to the supply during price drops?</h3>
|
||||
<p>The protocol automatically burns surplus $KRK from the liquidity pool to stabilize prices during sell pressure.</p>
|
||||
<h3>Is the AI Agent owned by anyone?</h3>
|
||||
<p>The AI Agent is fully sovereign. No owner or admin can intervene or change the behaviour of the agent. It operates in a closed environment on-chain.</p>
|
||||
<h3>How does the AI agent respond to volatile markets?</h3>
|
||||
<p>The agent adjusts the Anchor width, Discovery depth of the liquidity positions, and capital allocation based on volatility ratios and staking signals in real time.</p>
|
||||
<h3>Is my $KRK at risk if the AI fails?</h3>
|
||||
<p>Yes – Per the disclaimer, failed AI decisions could negatively impact $KRK's value. The Floor position mitigates but doesn't eliminate this risk.</p>
|
||||
<h3>Are there any fees when using the protocol?</h3>
|
||||
<p>There are no fees and there is no fee switch. Kraiken is an immutable protocol that has been fair launched and will continue so.</p>
|
||||
<h3>How can I stake my $KRK?</h3>
|
||||
<p>You can get access to staking by contacting the team.</p>
|
||||
<h3>Can the protocol code be changed later?</h3>
|
||||
<p>No – All contracts are permanently immutable after deployment. Liquidity Manager and AI agent operate autonomously with no upgrade path or admin controls.</p>
|
||||
<h3>Are there team allocations or unlocks?</h3>
|
||||
<p>No – Kraiken is a fair-launch protocol with zero allocations for teams or investors. All tokens enter circulation via the liquidity pool.</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const emit = defineEmits(["onmounted"])
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
22
landing/src/views/docs/Harberger Tax.vue
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1 id="first">Fair Market Mechanism</h1>
|
||||
<p>The Harberger Tax, developed by economist Arnold Harberger and popularized in the book Radical Markets and the RadicalxChange movement’s “Partial Common Ownership” concept, is a system where property owners pay a tax based on their own assessed value of their property. However, they must be willing to sell the property at that value to anyone who wants to buy it. This approach encourages owners to be honest about the value of their assets and helps allocate resources to those who value them the most.</p>
|
||||
<h2 id="second">Implementation in the Crypto Context</h2>
|
||||
<p>In crypto, limited assets or positions are often held by a select few without options for redistributing ownership—examples include early investors, protocol teams, fee distributions, multisig holders, NFT owners etc. The HARBERG protocol aims to challenge the current model of protocol ownership and test an alternative approach.</p>
|
||||
<h2 id="third">Key Differences</h2>
|
||||
<p>In the traditional model, the value of the asset is constantly changeable to reflect the current market value and dynamics. In the HARBERG protocol, the tax rate is constantly changeable, and owners must evaluate it regularly to retain their ownership positions.
|
||||
</p>
|
||||
<h3>Read More:</h3>
|
||||
<p> See <a href="website.org">Harberger Tax Blog Post</a> or <a href="website.org">Owner Tax</a> </p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const emit = defineEmits(["onmounted"])
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
24
landing/src/views/docs/Holders.vue
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1 id="first">Generate Passive Income</h1>
|
||||
<p>In traditional protocol designs, holders benefit from a protocol’s success only indirectly through an increase in token price. HARBERG changes this by allowing holders to earn directly through a passive income stream funded by protocol owners, who pay for the privilege of staying in their positions of power. </p>
|
||||
<br>
|
||||
<p>Token holders are essential for decentralisation, governance and decision-making in crypto. Their role is key to a project’s long-term success. It’s only fair that token holders should have the right to become owners of the very protocol they support.</p>
|
||||
<h2 id="second">Buy $HARB</h2>
|
||||
<p> $HARB tokens and the Harberg Protocol are deployed on Base an $ETHeum Layer 2. $HARB can be bought on <a href="uniswap.org">Uniswap</a> there. </p>
|
||||
<h2 id="third">Passive Income</h2>
|
||||
<p>By holding $HARB, holders can claim a passive income funded by the owner’s tax. The more owners are competing for limited owner slots the higher the tax for the token holders.</p>
|
||||
<p>The longer the token is held, the more tax holders can claim. No protocol fee is taken. </p>
|
||||
<h2 id="fourth">Sell $HARB</h2>
|
||||
<p>$HARB can be sold anytime on <a href="uniswap.org">Uniswap</a> </p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
const emit = defineEmits(["onmounted"])
|
||||
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
52
landing/src/views/docs/Introduction.vue
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1 id="first">Introduction</h1>
|
||||
<p>Welcome to KrAIken, a decentralized finance (DeFi) protocol that integrates artificial intelligence (AI) to optimize liquidity management. KrAIken operates autonomously, ensuring on-chain execution of adaptive liquidity strategies.</p>
|
||||
<p>At the core of KrAIken is the $KRK token and its liquidity pool, which acts as a testing ground and learning environment for the AI agent. The agent dynamically adjusts liquidity positions based on real-time market data, aiming to maintain stability and efficiency within the pool. Disclaimer: If the agent fails in its tasks, it may negatively impact the value of $KRK.</p>
|
||||
<p>This initiative not only tests the resilience of the protocol but also offers the community an opportunity to interact with and evaluate its performance. Through continuous iteration, KrAIken’s AI will eventually expand to other Uniswap liquidity pools, generating profits through liquidity fees and creating real utility for the protocol and the $KRK token.</p>
|
||||
<p>KrAIken is not just another centralized, hosted large language model (LLM). It is fully sovereign. Developed by <a href="https://sovraigns.network">SovrAIgns.network</a>, KrAIken represents an evolution in DeFi, combining decentralized finance principles with adaptive AI to create a truly innovative financial platform.</p>
|
||||
<p>In the chapters ahead, we will delve into KrAIken’s liquidity management strategies, the architecture of its AI agent, the tokenomics of $KRK, and staking mechanisms available to our community members.</p>
|
||||
<br>
|
||||
<pre>
|
||||
..-.
|
||||
-+:.:==-=++=-
|
||||
-=++++=++==+++++:
|
||||
.=+++===:=++++==+++= :---:::
|
||||
=-++=--. -+++**+: .-=======::
|
||||
=-+*+:. :*****+ :--========-=:
|
||||
+=**+. :+***+ .++===-==+++=+==: :::
|
||||
=+**+-:--==-: *****: +**+===+=+++++++=: .--=--:: .::.
|
||||
-=+*+=::- :--: *****- =***++┬┐*+ +┬┐+- : ======-:-=--: --
|
||||
:--=++:.::+.:- -****=. :-++++**└┴=**+└┴+++=: =+=++++==+=----: --
|
||||
*:*+++= :*+==+=..=++-. -****++ -+**********+*+*++: =- =+++++++++++=+=--==: :=-
|
||||
:*:+*******+*=-+=-:.+-++-: =++***++ -=**********+││*****+=+ =+***++++== .==++===== -==
|
||||
*:*:*:*:****+*++++-- :***= :++*****+=.=*******++***││****+=+*- .++****++-+ +=-+=++==-: ===
|
||||
***:: *+*+++++- :+**= *****************++*+*****+++*+**********+*+: =+++++++.- .===
|
||||
*: ++*++++=. =+***+- *********::****+=+=****+-=+********::**+= +++++++= . --=
|
||||
+===++++. :+******= +******:::****+=:=+****-:=+****:::::**** .:++==-= ::--
|
||||
:-+*+++++= :-=*+****:: ::::**:*****=::::*****=:.+*****::***=..:----. ::-++++=== -:
|
||||
+.:=+++++*+:.:=+*+*****:*:::******+-::::-****++:::-********+-+++++++++=- .:+++++=++--. -==-
|
||||
+:** +***+-=++++++=::.==+******+********+:::::=******+=::::******++**+++++++++=-. ++++++++++:.: --:
|
||||
**::*+****+++++==:+=++*= :--=******=******+=::::::*******++:::::+***=***+++:::=-----:: =+==++++==:----:
|
||||
***=== =++++=-+=*++++::-::++**+=+***+==::::::********+++::::+***+=++++:: ----:.==+++++++=--::
|
||||
+=*++=+++:--.+++++-++++=:::::=+**********++=:::::++==+++ ::::..=++++*++-----:
|
||||
-+-+++*+++=.:--===:==+===-=+===+****++++*++++:::::-=.=== ..:-----=++++++::+:
|
||||
++++**++++-:-..--=. :--- ---==========- . +=+-:::::.--=-+======-.=++++++++::
|
||||
:+++++++++-::..:-::=: . .:-.: . . :-.:--.::--:=---:.:::- -++++:+:
|
||||
:--:-+++==-:- -: .- :---=-=--=-: . =++++*+=
|
||||
: .:.=-:.--:.... : : :.::---=-. .:-===+++=
|
||||
:: .. .... :. . - ::: . . .. .====+++******:.:
|
||||
:-..-==: . : : :====++++++++++*****++++=-++**************=+
|
||||
***-:::::::= ++++- -+=- .--:::--=-= ++++++=++=++++==+ *++********** ******
|
||||
</pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const emit = defineEmits(["onmounted"])
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
87
landing/src/views/docs/Liquidity-Management.vue
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>Liquidity Management</h1>
|
||||
|
||||
<p>The liquidity of $KRK tokens is fully managed by an immutable Liquidity Manager (LM) contract. This contract governs the minting, burning, and allocation of liquidity to ensure market stability, efficient trading, and adaptive responses to market dynamics. The LM operates through three distinct liquidity positions: Floor, Anchor, and Discovery (inspired by <a href="https://docs.baseline.markets/btokenomics/dynamic_liquidity#protocol-owned-liquidity-positions">Baseline</a>). Each serves a specific role in maintaining a balanced and resilient ecosystem.</p>
|
||||
|
||||
<p>The Liquidity Manager operates exclusively on a Uniswap V3 pool on the Base network with a tick spacing of 200, equivalent to 1% fee tier. Other liquidity pools on different networks will only receive liquidity indirectly through arbitrage.</p>
|
||||
|
||||
<br>
|
||||
<pre>
|
||||
▲ ┌─────────────┐
|
||||
│ │ ┌─┐ │
|
||||
│ Floor │ │%│ $ETH │
|
||||
│ ┌─┐ │ └─┘ │
|
||||
│ │%│ │ ┌─┐ │
|
||||
│ │%│ │ │+│ $KRK │
|
||||
│ │%│ │ └─┘ │
|
||||
│ │%│ └─────────────┘
|
||||
│ │%│
|
||||
│ │%│
|
||||
│ │%│
|
||||
L │ │%│
|
||||
i │ │%│
|
||||
q │ │%│ Discovery
|
||||
u │ │%│
|
||||
i │ │%│ ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐
|
||||
d │ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
i │ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
t │ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
y │ │%│ Anchor │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%│┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐│+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘
|
||||
─┼─────────────────────────────────────────────────────────────────►
|
||||
▲ Price
|
||||
current Price
|
||||
</pre>
|
||||
<h2>Floor Position</h2>
|
||||
|
||||
<p>The Floor is a highly concentrated liquidity position within a narrow price range. Its primary function is to provide a guaranteed minimum buyback price for $KRK tokens. This reserve stabilizes the protocol by ensuring that token holders always have a predictable exit value. As the protocol grows, the LM allocates more $ETH to the Floor, increasing its depth and reliability. Between 75% and 95% of all $ETH managed by the protocol is typically held in the Floor position.</p>
|
||||
|
||||
<p>A critical aspect of the Floor position is its use of Volume Weighted Average Price (VWAP) to determine its pricing strategy. VWAP represents the average sale price of $KRK tokens weighted by trading volume, providing a kind of approximate and compressed memory over historic sales of tokens from its liquidity. The LM calculates the VWAP using cumulative trade data, ensuring that on average tokens are bought back for cheaper than they were sold for. By anchoring the protocol’s liquidity to a VWAP-adjusted price, the system retains a sober approach to Floor positioning while allowing for market-responsive adjustments of Anchor and Discovery.</p>
|
||||
|
||||
<h2>Anchor Position</h2>
|
||||
|
||||
<p>The Anchor position offers less liquidity depth than the Floor but spans a broader price range. It is always positioned at the current market price, ensuring its relevance to active trading. The size of the Anchor position dynamically adjusts based on the "sentiment" input, a value generated by an on-chain AI agent analyzing staking signals and trading data. Sentiment determines the allocation of 5% to 25% of the total $ETH supply to the Anchor, influencing its liquidity depth and responsiveness. This adaptive sizing strategy puts more capital at risk during market uptrends while adopting a defensive posture when sentiment turns negative. The exact adjustment strategy depends on the training embedded in the on-chain AI agent, which targets developing the token price and maximizing trading fees for the protocol. For more on staking signals, visit the "For Owners" chapter, and for details about the AI agent, see the "AI-Agent" chapter.</p>
|
||||
|
||||
<h2>Discovery Position</h2>
|
||||
|
||||
<p>The Discovery position provides the broadest price coverage and greater liquidity depth compared to the Anchor. It is designed for price exploration beyond the current range, supporting efficient trading during periods of high demand or significant market growth. Discovery covers a price range up to three times the current price, and holds liquidity at a depth twice as concentrated as the Anchor position. This ensures robust liquidity for price exploration while incentivizing trading activity in less active price ranges. $ETH accumulated in the Discovery position is periodically redistributed to the Floor and Anchor positions.</p>
|
||||
|
||||
<h2>Rebalancing Mechanism</h2>
|
||||
|
||||
<p>The Liquidity Manager rebalances the Floor, Anchor, and Discovery positions based on market price movements. This process is triggered through an open contract call that anyone can execute at any time. Before rebalancing occurs, the function ensures a key condition is met: the price must have moved significantly, surpassing a minimum amplitude threshold of twice the tick spacing (2%).</p>
|
||||
|
||||
<p>When the token price moves:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Upwards:</strong> The Liquidity Manager reallocates more $ETH to the Floor position to enhance its stability and increases the size of the Discovery position for further price exploration. New $KRK tokens are minted to support this growth.</li>
|
||||
<li><strong>Downwards:</strong> The Liquidity Manager reduces the Anchor and Discovery positions proportionally and burns excess tokens, maintaining equilibrium and reducing supply pressure.</li>
|
||||
</ul>
|
||||
|
||||
<p>This dynamic system ensures that the protocol responds effectively to market conditions while safeguarding token holders and traders. The contract is immutable, guaranteeing that neither the team nor any other entity can access or control the liquidity. Users are encouraged to review the code to understand the mechanics before participating.</p>
|
||||
|
||||
<h2>Risk Profile</h2>
|
||||
|
||||
<p>
|
||||
While the Liquidity Manager offers a "guaranteed minimum buyback" through the Floor position, the price is dynamic because some $ETH is always allocated to the Anchor position for active trading. This ensures efficient price discovery and liquidity optimization but also introduces variability in the Floor’s backing. Compared to systems like Baseline, which use similar Floor, Anchor, and Discovery positions, Kraiken operates with a more dynamic and risk-tolerant approach. This allows for potentially higher rewards but comes with increased exposure to market fluctuations.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const emit = defineEmits(["onmounted"])
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
120
landing/src/views/docs/Staking.vue
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>Staking</h1>
|
||||
<p>Staking has two important benefits:</p>
|
||||
<p>1. It helps the AI Agent with market sentiment analysis.</p>
|
||||
<p>2. It transparently rewards users that promote the $KRK token and the KrAIken protocol without the need of backdoor deals or insider allocation.</p>
|
||||
<h2>1. Staking Slots</h2>
|
||||
<p>As a token holder you can stake your $KRK tokens to claim staking slots and become a Staker of the KrAIken Protocol. Stakers earn a share of newly minted tokens when the token supply expands (see Tokenomics).</p>
|
||||
<p>In exchange for that benefit stakers have to pay a self-assessed tax. At any time, another token holder who agrees to pay a higher tax can buyout lower-tax staking slots. This creates a fair and dynamic market for staking slots.</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Owner Slots:</strong> How many slots you can claim depends on the percentage of tokens you own compared to the total supply. Staking 0.001% of $KRK total supply gives 1 owner slot.</li>
|
||||
<li><strong>Dynamic Value:</strong> As new tokens are minted (see supply expansion in Tokenomics), your claim automatically applies to the new total supply</li>
|
||||
<li><strong>Limited Capacity:</strong> There are only 20,000 staking slots that represent 20% of all $KRK at any time.</li>
|
||||
</ul>
|
||||
<p class="warning">Example: Alice stakes 10,000 $KRK. The current total supply sits at 1M. As she holds 1% of the current total supply she gets 1,000 owner slots. When the supply increases to 2M, the 1% (1,000 slots) are worth now 20,000 $KRK after expansion.</p>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<pre>
|
||||
*** ### ### ***
|
||||
*## ++ ##*
|
||||
*## ++ ##*
|
||||
*## ++ ##*
|
||||
*# ++ ##*
|
||||
*## ++ 20% ##*
|
||||
*## ++ Staking +++ ##*
|
||||
*## ++ +++ ##*
|
||||
*## ++ ++ ##*
|
||||
*## ++ ++++ ##*
|
||||
*## ++ ++++ ##*
|
||||
*## ++ ++++ ##*
|
||||
*## +++++ ##*
|
||||
*## ##*
|
||||
*## ##*
|
||||
*## 80% Open Market ##*
|
||||
*## ##*
|
||||
*## ##*
|
||||
*## ##*
|
||||
*## ##*
|
||||
*## ##*
|
||||
*# ##*
|
||||
*## ##*
|
||||
*## ##*
|
||||
*** ### ### ***
|
||||
</pre>
|
||||
<div class="concept-block">
|
||||
<h2>2. Harberger Tax Mechanism</h2>
|
||||
<p>To keep things fair and transparent, stakers need to pay a sel-assessed tax on their position. Inspired by the <a href="https://en.wikipedia.org/wiki/Harberger_tax" target="_blank">Harberger tax concept</a> but adapted for crypto:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Traditional Model:</strong> Owners self-assess property value and pay tax accordingly</li>
|
||||
<li><strong>KrAIken Adaptation:</strong> Stakers choose tax <em>rates</em> instead of values, creating a competitive market for positions</li>
|
||||
</ul>
|
||||
|
||||
<p>This system achieves three key goals:</p>
|
||||
<ol>
|
||||
<li><strong>Market Efficiency:</strong> Positions flow to those willing to pay highest maintenance costs (tax)</li>
|
||||
<li><strong>Anti-Squating:</strong> Staking positions can get replaced anytime someone is willing to pay a higher tax, preventing permanent control</li>
|
||||
<li><strong>Protocol Funding:</strong> Collected taxes finance ongoing development</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="concept-block">
|
||||
<h2>3. Earning Potential</h2>
|
||||
<p>Staking provides leveraged exposure to $KRK's growth through two channels:</p>
|
||||
|
||||
<h3>A. Supply Expansion</h3>
|
||||
<p>The protocol's AI liquidity manager regularly mints new tokens to:</p>
|
||||
<ul>
|
||||
<li>Maintain exchange liquidity</li>
|
||||
<li>Respond to market demand</li>
|
||||
</ul>
|
||||
|
||||
<p>Your staked percentage automatically applies to the new larger supply. Regular holders only benefit from price changes - stakers gain from both price <em>and</em> supply growth.</p>
|
||||
|
||||
<h3>B. Position Protection</h3>
|
||||
<p>By choosing optimal tax rates, you can:</p>
|
||||
<ul>
|
||||
<li>Maintain your percentage through market cycles</li>
|
||||
<li>Compound earnings through repeated staking</li>
|
||||
<li>Outpace simple token holding returns</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="concept-block">
|
||||
<h2>4. Position Security</h2>
|
||||
<p>While others can buyout your position at any time, crucial protections exist:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Full Principal Return:</strong> If replaced, you receive all untaxed $KRK and potential profit immediately</li>
|
||||
<li><strong>Three-Day Grace Period:</strong> New positions must pay minimum 3 days' tax upfront</li>
|
||||
<li><strong>Rate Transparency:</strong> All positions display current tax rates for informed decisions</li>
|
||||
</ul>
|
||||
|
||||
<p class="warning">Key Insight: Losing a postion due to a buyout means lossing the benefit of <em>future</em> earnings from that stake, not existing tokens or profit.</p>
|
||||
</div>
|
||||
|
||||
<div class="concept-block">
|
||||
<h2>5. Strategic Considerations</h2>
|
||||
<p>Successful staking requires balancing:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Tax Rate Selection:</strong> Higher rates protect positions but reduce net returns</li>
|
||||
<li><strong>Market Monitoring:</strong> Track competing stakers' tax rates</li>
|
||||
<li><strong>Supply Forecasts:</strong> Anticipate minting events through protocol announcements</li>
|
||||
</ul>
|
||||
|
||||
<p>Example Strategy: Use medium tax rates (5-15% daily) during high-growth periods to balance protection and returns</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
const emit = defineEmits(["onmounted"])
|
||||
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
145
landing/src/views/docs/Tokenomics.vue
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>Tokenomics</h1>
|
||||
|
||||
<p>
|
||||
This section describes the design and distribution of the protocol's native digital token, Kraiken ($KRK). The token is issued exclusively through its Uniswap V3 liquidity pool, and its supply adjusts dynamically with network growth and demand.</p>
|
||||
<p>Kraiken is a fair-launch protocol, meaning there are no allocations or unlocks for teams or investors. This ensures equal opportunities for all participants from the very beginning.
|
||||
</p>
|
||||
|
||||
<h2>Dynamic Supply</h2>
|
||||
<p>There is no fixed supply for $KRK. The minting and burning of $KRK tokens are fully managed by an immutable Liquidity Manager (LM) contract, which oversees the token's supply and liquidity.</p>
|
||||
|
||||
|
||||
|
||||
<h3>Supply Expansion</h3>
|
||||
<p>When buys exceed sells (rising demand), new $KRK tokens are minted to "refill" the liquidity pool (e.g., after tokens are purchased from Uniswap). This expands the total supply, which, assuming price stability, increases the protocol’s market capitalization.</p>
|
||||
<pre>
|
||||
▲ ┬─────────┬ = ▲
|
||||
┌─────┐ [ ] ┌─────┐ ^-----^
|
||||
A $ETH │ │ ▼ [ 00110 1 ] │ │ ^ ^
|
||||
/ \ ───────> │ │ ┌─────┐ [ 1100 11 ] │ │ ^-----^
|
||||
\/'-'\/ │ │ │ │ ─────> [ 0100 10 ] +$KRK │ │ │ + │
|
||||
\_;_/ $KRK │ + │ │ - │ ─────> [ 0011110 ] ──────> │ ETH │ │ KRK │
|
||||
/ \ <─────── │ ETH │ │ KRK │ [ ] │ │ │ │
|
||||
│ │ │ │ ┴─────────┴ │ │ │ │
|
||||
|
||||
Alice buys $KRK from Uniswap Pool LM Contract mints $KRK and fills up Uniswap Pool
|
||||
</pre>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<h3>Token Burn</h3>
|
||||
<p>When sells outpace buys, surplus $KRK tokens from the liquidity pool are automatically burned to maintain its balance (further stabilizing the price).</p>
|
||||
<pre>
|
||||
▲ ┬─────────┬ ▼
|
||||
┌─────┐ [ ] v-----v
|
||||
A $KRK ▼ │ │ [ 00110 1 ] = v v
|
||||
/ \ ───────> ┌─────┐ │ │ [ 1100 11 ] ┌─────┐ v-----v
|
||||
\/'-'\/ │ │ │ │ ─────> [ 0100 10 ] -$KRK │ │ │ │
|
||||
\_;_/ $ETH │ - │ │ + │ ─────> [ 0011110 ] <───── │ │ │ - │
|
||||
/ \ <─────── │ ETH │ │ KRK │ [ ] │ ETH │ │ KRK │
|
||||
│ │ │ │ ┴─────────┴ │ │ │ │
|
||||
|
||||
Alice sells $KRK to Uniswap Pool LM Contract burns $KRK and balances Uniswap Pool
|
||||
|
||||
</pre>
|
||||
<br>
|
||||
|
||||
<p>These dynamic supply changes make tokenomics fair and transparent for everyone. Read further for more details.</p>
|
||||
|
||||
<h2>Primer to Liquidity Management</h2>
|
||||
|
||||
<p>
|
||||
The LM maintains three key liquidity positions:
|
||||
</p>
|
||||
|
||||
<h3>1. Floor</h3>
|
||||
<p>
|
||||
The Floor is a liquidity position of narrow price range with highly concentrated liquidity. The Floor position is a reserve designed to provide a guaranteed minimum buyback price for $KRK. As the protocol grows, the LM allocates more ETH to the Floor position, increasing its stability and appeal to holders. At any time between 75% and 95% of all ETH managed by the protocol are located in the Floor position.
|
||||
</p>
|
||||
|
||||
<h3>2. Anchor</h3>
|
||||
<p>
|
||||
The Anchor position with lower liquidity depth compared to the Floor, but covers a broader price span. It is dynamically balanced to support trading around the current price. It ensures smooth trading experiences by reducing slippage and maintaining efficient liquidity deployment.
|
||||
</p>
|
||||
|
||||
<h3>3. Discovery</h3>
|
||||
<p>
|
||||
The Discovery position has more dept and range than the Anchor. It allows for price exploration beyond the current range, enabling efficient trading during periods of high demand or market growth. This position grows with network activity and serves to attract more liquidity. $ETH that is accumulated in this position is regularly moved to Floor and Anchor.
|
||||
</p>
|
||||
<br>
|
||||
<pre>
|
||||
▲ ┌─────────────┐
|
||||
│ │ ┌─┐ │
|
||||
│ Floor │ │%│ $ETH │
|
||||
│ ┌─┐ │ └─┘ │
|
||||
│ │%│ │ ┌─┐ │
|
||||
│ │%│ │ │+│ $KRK │
|
||||
│ │%│ │ └─┘ │
|
||||
│ │%│ └─────────────┘
|
||||
│ │%│
|
||||
│ │%│
|
||||
│ │%│
|
||||
L │ │%│
|
||||
i │ │%│
|
||||
q │ │%│ Discovery
|
||||
u │ │%│
|
||||
i │ │%│ ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐
|
||||
d │ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
i │ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
t │ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
y │ │%│ Anchor │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%│ │+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%│┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐│+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ │%││%││%││%││%││+││+││+││+││+││+││+││+││+││+││+││+││+││+││+│
|
||||
│ └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘
|
||||
─┼─────────────────────────────────────────────────────────────────►
|
||||
▲ Price
|
||||
current Price
|
||||
</pre>
|
||||
<br>
|
||||
<p>
|
||||
When the price moves up, the LM rebalances by allocating more ETH to the Floor position and expanding Discovery. To support this growth, new $KRK tokens are minted. Conversely, when the price moves down, the LM shrinks the Floor and Discovery positions proportionally and burns excess tokens. For more details, see the <a href="#/docs/Liquidity-Management">Liquidity Management</a> section.
|
||||
</p>
|
||||
|
||||
<h2>Protocol Initialization</h2>
|
||||
|
||||
<p>
|
||||
The Kraiken Protocol is initialized with a single transaction. The team deposits 1 $ETH into the Liquidity Manager, which sets the initial pool price at 1 cent per token. The Liquidity Manager bootstraps the Uniswap V3 liquidity pool and begins adjusting positions dynamically.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
From the start, the LM rebalances positions whenever the price moves more than 2% up or down, ensuring liquidity is always optimized for current market conditions.
|
||||
</p>
|
||||
|
||||
<h2>Utility</h2>
|
||||
<p>
|
||||
The $KRK token and its liquidity pool generates sufficient training data to continuously improve the AI agent’s performance. It kickstarts AI-driven liquidity management systems across the crypto ecosystem.
|
||||
The end goal: Enable the AI to autonomously manage liquidity positions across multiple token pools on Uniswap and other DEXs. This will result in fee revenue flowing back to $KRK holders.
|
||||
</p>
|
||||
|
||||
<h2>Objective of Token Design</h2>
|
||||
|
||||
<p>
|
||||
The Kraiken Protocol is designed to provide a fair and adaptive token ecosystem. By launching with minimal initial liquidity and no team or investor allocations, the protocol ensures equal opportunities for all participants. Minting and burning respond dynamically to market conditions, supporting growth during expansion and reducing supply (and sell pressure) during contraction.
|
||||
</p>
|
||||
<p>
|
||||
The Liquidity Manager provides deep liquidity and stabilizes the price. This design allows casual holders to "hold and forget," benefiting from well-managed, stable token ecosystem without needing to actively participate in liquidity management or market decisions.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const emit = defineEmits(["onmounted"])
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
158
landing/src/views/docs/ai-agent.vue
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>AI Agent</h1>
|
||||
<p>KrAIken is not just another LLM that suggests on-chain actions requiring admin or owner approval. Instead, KrAIken operates independently within its own on-chain execution environment, making decisions based on open data and a self-improving algorithm. No admin or owner can veto or interfere with its actions.</p>
|
||||
<p>
|
||||
In the chapter <strong>Liquidity Management</strong>, we described the static behavior of the contract, outlining how the liquidity manager maintains predefined parameters for market interactions. While effective in stable conditions, this static behavior lacks adaptability to dynamic market changes. Passive liquidity providers, acting as buyers of last resort, are inherently exposed to impermanent loss, as they bear the risk of price fluctuations during their provision of liquidity. By introducing an AI agent into the system, the previously static contract is now enabled to dynamically adjust to market conditions, optimizing its liquidity management strategy in real-time.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The AI agent not only relies on its training to optimize the pool but also incorporates real-time data directly sourced from stakers. Parameters such as the percentage staked and average tax rate provide valuable sentiment indicators that would otherwise only be available through off-chain analysis, enriching the agent’s decision-making capabilities with actionable insights from on-chain activity.
|
||||
</p>
|
||||
|
||||
<h2>Inputs to the AI Agent</h2>
|
||||
<p>
|
||||
The AI agent interacts with its environment by consuming key input parameters that capture the state of the market, user behavior, and the system itself. These inputs are normalized and structured to enable efficient decision-making by the agent.
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Price Position Relative to Range:</strong>
|
||||
<ul>
|
||||
<li><em>Description:</em> The normalized position of the current token price within a predefined range (e.g., VWAP ± volatility bounds).</li>
|
||||
<li><em>Range:</em> 0 (lower bound) to 1e18 (upper bound).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Volatility Ratio:</strong>
|
||||
<ul>
|
||||
<li><em>Description:</em> The ratio of current price volatility to a baseline, such as weekly historical volatility.</li>
|
||||
<li><em>Range:</em> 0 (low volatility) to 1e18 (high volatility relative to baseline).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Volume-to-Liquidity Ratio:</strong>
|
||||
<ul>
|
||||
<li><em>Description:</em> The ratio of trading volume to liquidity in the relevant range, indicating potential profitability.</li>
|
||||
<li><em>Range:</em> 0 (low volume relative to liquidity) to 1e18 (high volume relative to liquidity).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Time Since Last Call:</strong>
|
||||
<ul>
|
||||
<li><em>Description:</em> The elapsed time since the last AI agent update, expressed as a fraction of a predefined target interval.</li>
|
||||
<li><em>Range:</em> 0 (just called) to 1e18 (maximum target interval elapsed).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Percentage Staked:</strong>
|
||||
<ul>
|
||||
<li><em>Description:</em> The proportion of available staking slots currently utilized by users.</li>
|
||||
<li><em>Range:</em> 0 (no stake) to 1e18 (maximum stake capacity utilized).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Average Tax Rate:</strong>
|
||||
<ul>
|
||||
<li><em>Description:</em> The average tax rate applied to transactions, representing the system’s cost structure.</li>
|
||||
<li><em>Range:</em> 0 (0% tax) to 1e18 (4700% tax, maximum rate).</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h2>Outputs from the AI Agent</h2>
|
||||
<p>The AI agent optimizes specific liquidity management parameters based on its input data, dynamically adjusting them to improve market responsiveness and profitability. These outputs are sent to the liquidity manager contract for execution.</p>
|
||||
<ol>
|
||||
<li><strong>Capital Inefficiency:</strong>
|
||||
<ul>
|
||||
<li><strong>Description:</strong> Measures the deviation from optimal capital allocation, indicating potential areas for improvement in resource utilization.</li>
|
||||
<li><strong>Type:</strong> <code>uint256</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Anchor Share:</strong>
|
||||
<ul>
|
||||
<li><strong>Description:</strong> Represents the proportion of resources allocated to the anchor position, reflecting the agent's confidence in the current market stability.</li>
|
||||
<li><strong>Type:</strong> <code>uint256</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Anchor Width:</strong>
|
||||
<ul>
|
||||
<li><strong>Description:</strong> Defines the range or bandwidth of the anchor position, determining the scope of market conditions under consideration.</li>
|
||||
<li><strong>Type:</strong> <code>uint24</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Discovery Depth:</strong>
|
||||
<ul>
|
||||
<li><strong>Description:</strong> Indicates the extent to which the agent explores new strategies or market opportunities beyond the established anchor parameters.</li>
|
||||
<li><strong>Type:</strong> <code>uint256</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h2>Agent Contract</h2>
|
||||
<p>
|
||||
The Agent Contract serves as the execution layer for the AI agent, interfacing directly with the liquidity manager contract. It is invoked periodically by the liquidity manager to collect input data, run the genetic algorithm, and return actionable outputs for liquidity adjustments. The Agent Contract performs the following key functions:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Input Collection and Preprocessing:</strong>
|
||||
<ul>
|
||||
<li>The contract gathers all necessary data points, such as price position, volatility ratio, volume-to-liquidity ratio, percentage staked, and average tax rate.</li>
|
||||
<li>These inputs are normalized and placed onto the stack of the Push3 Virtual Machine (VM) for efficient computation.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Algorithm Loading:</strong>
|
||||
<ul>
|
||||
<li>The genetic algorithm, stored within the contract’s state, is loaded and also placed onto the stack of the Push3 VM.</li>
|
||||
<li>This setup initializes the VM for execution.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Execution and Output Retrieval:</strong>
|
||||
<ul>
|
||||
<li>The Push3 VM executes the genetic algorithm using the input parameters on the stack.</li>
|
||||
<li>The execution results in a set of outputs, which may include adjustments to liquidity parameters or a non-action signal indicating no immediate changes are necessary.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Forwarding Outputs to Liquidity Manager:</strong>
|
||||
<ul>
|
||||
<li>The outputs are forwarded to the liquidity manager contract, which applies the recommended changes to reposition liquidity if necessary.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
By introducing the Agent Contract, the previously static liquidity manager becomes capable of real-time optimization, driven by on-chain evolutionary computation. If you want to know how genetic algorithms work, or why the system is considered an agent, read this <a href="https://github.com/Sovraigns/SoLUSH-3/blob/main/vision.md">vision document</a>.
|
||||
</p>
|
||||
|
||||
<h2>Dynamic Adaptation Through AI</h2>
|
||||
<p>
|
||||
The AI agent’s ability to dynamically adapt parameters allows the liquidity manager to respond to market volatility, trading volume, and user behavior in real-time. For example:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Volatile Markets:</strong> The agent can widen Anchor and Discovery spacing to reduce exposure and maintain stability.
|
||||
</li>
|
||||
<li>
|
||||
<strong>High Volume:</strong> The agent can increase liquidity in Discovery to capture more trading fees.
|
||||
</li>
|
||||
<li>
|
||||
<strong>User Engagement:</strong> High staking utilization might lead the agent to prioritize profitability over conservatism.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
By replacing static configurations with adaptive intelligence, the liquidity manager evolves into a dynamic system capable of optimizing for diverse and changing conditions. This integration enables a more resilient and efficient approach to decentralized liquidity management, where the AI agent collaborates with stakers to form a cybernetic system. Staking signals, such as the percentage staked and the average tax rate, provide critical real-time sentiment data that the agent uses to refine its decisions and adapt dynamically to market behaviors.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const emit = defineEmits(["onmounted"])
|
||||
onMounted(() => {
|
||||
emit("onmounted")
|
||||
})
|
||||
</script>
|
||||
12
landing/tsconfig.app.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
11
landing/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
19
landing/tsconfig.node.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "@tsconfig/node22/tsconfig.json",
|
||||
"include": [
|
||||
"vite.config.*",
|
||||
"vitest.config.*",
|
||||
"cypress.config.*",
|
||||
"nightwatch.conf.*",
|
||||
"playwright.config.*",
|
||||
"eslint.config.*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"types": ["node"]
|
||||
}
|
||||
}
|
||||
19
landing/vite.config.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
// base: "/KraikenLanding/",
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
},
|
||||
},
|
||||
})
|
||||