главная страница
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type Direction = 'bull' | 'bear' | 'flat';
|
||||
|
||||
type Signal = {
|
||||
sym: string;
|
||||
dir: Direction;
|
||||
conf: string;
|
||||
entry: string;
|
||||
tp: string;
|
||||
sl: string;
|
||||
};
|
||||
|
||||
type Level = { label: string; val: string; color: string };
|
||||
|
||||
const signals: Signal[] = [
|
||||
{ sym: 'BTCUSDT', dir: 'bull', conf: '73%', entry: '103.4k', tp: '104.2k', sl: '102.8k' },
|
||||
{ sym: 'ETHUSDT', dir: 'bear', conf: '68%', entry: '3.21k', tp: '3.08k', sl: '3.28k' },
|
||||
{ sym: 'SOLUSDT', dir: 'bull', conf: '81%', entry: '178.2', tp: '183.5', sl: '175.0' },
|
||||
{ sym: 'BNBUSDT', dir: 'flat', conf: '52%', entry: '612.4', tp: '618.0', sl: '608.0' },
|
||||
{ sym: 'XRPUSDT', dir: 'bull', conf: '76%', entry: '0.614', tp: '0.641', sl: '0.598' },
|
||||
{ sym: 'ADAUSDT', dir: 'bear', conf: '61%', entry: '0.482', tp: '0.461', sl: '0.494' }
|
||||
];
|
||||
|
||||
const paths: Record<Direction, string> = {
|
||||
bull: 'M 0 32 L 20 28 L 40 30 L 60 22 L 80 24 L 100 16 L 120 12 L 140 8 L 160 4',
|
||||
bear: 'M 0 8 L 20 12 L 40 10 L 60 18 L 80 16 L 100 24 L 120 28 L 140 32 L 160 36',
|
||||
flat: 'M 0 20 L 40 18 L 80 22 L 120 20 L 160 19'
|
||||
};
|
||||
|
||||
const dirColor: Record<Direction, string> = {
|
||||
bull: 'text-emerald-400',
|
||||
bear: 'text-red-400',
|
||||
flat: 'text-zinc-500'
|
||||
};
|
||||
|
||||
const dirStroke: Record<Direction, string> = {
|
||||
bull: '#34d399',
|
||||
bear: '#f87171',
|
||||
flat: '#71717a'
|
||||
};
|
||||
|
||||
const dirBorder: Record<Direction, string> = {
|
||||
bull: 'border-l-emerald-400',
|
||||
bear: 'border-l-red-400',
|
||||
flat: 'border-l-zinc-500'
|
||||
};
|
||||
|
||||
const dirLabel: Record<Direction, string> = {
|
||||
bull: '▲ LONG',
|
||||
bear: '▼ SHORT',
|
||||
flat: '— FLAT'
|
||||
};
|
||||
|
||||
function getLevels(signal: Signal): Level[] {
|
||||
return [
|
||||
{ label: 'E', val: signal.entry, color: 'text-orange-400' },
|
||||
{ label: 'TP', val: signal.tp, color: 'text-emerald-400' },
|
||||
{ label: 'SL', val: signal.sl, color: 'text-red-400' }
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full max-w-170 z-20" style="perspective: 1000px;">
|
||||
<div
|
||||
class="overflow-hidden rounded-2xl border border-white/10 bg-zinc-950 shadow-[0_40px_100px_rgba(0,0,0,0.7),0_0_0_1px_rgba(255,255,255,0.04)] will-change-transform"
|
||||
style="transform: perspective(1000px) rotateY(-6deg) rotateX(3deg); transform-style: preserve-3d;"
|
||||
>
|
||||
<!-- Title bar -->
|
||||
<div class="flex items-center justify-between border-b border-white/6 bg-white/2 px-4 py-2.5">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-[#ff5f57]"></div>
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-[#febc2e]"></div>
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-[#28c840]"></div>
|
||||
</div>
|
||||
<span class="font-mono text-[0.6rem] tracking-widest text-zinc-500">FLAMY TRADE</span>
|
||||
</div>
|
||||
|
||||
<!-- Signal grid -->
|
||||
<div class="grid grid-cols-2">
|
||||
{#each signals as signal, i (signal.sym)}
|
||||
<div
|
||||
class={cn(
|
||||
'border-l-[3px] p-3',
|
||||
dirBorder[signal.dir],
|
||||
i % 2 === 0 && 'border-r border-r-white/6',
|
||||
i < 4 && 'border-b border-b-white/6'
|
||||
)}
|
||||
>
|
||||
<!-- Header -->
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<span class="font-display text-[0.6875rem] font-black tracking-tight text-zinc-100">
|
||||
{signal.sym}
|
||||
</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class={cn('font-mono text-[0.5625rem]', dirColor[signal.dir])}>
|
||||
{dirLabel[signal.dir]}
|
||||
</span>
|
||||
<span class="font-mono text-[0.5625rem] text-zinc-400">{signal.conf}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mini chart -->
|
||||
<div class="relative mb-2 h-10 overflow-hidden rounded bg-white/2">
|
||||
<svg
|
||||
width="100%"
|
||||
height="40"
|
||||
viewBox="0 0 160 40"
|
||||
preserveAspectRatio="none"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d={paths[signal.dir]}
|
||||
stroke={dirStroke[signal.dir]}
|
||||
stroke-width="1.2"
|
||||
fill="none"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Levels -->
|
||||
<div class="flex gap-3">
|
||||
{#each getLevels(signal) as level (level.label)}
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="font-mono text-[0.5rem] tracking-widest text-zinc-600"
|
||||
>{level.label}</span
|
||||
>
|
||||
<span class={cn('font-mono text-[0.5625rem]', level.color)}>{level.val}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,134 @@
|
||||
<script lang="ts">
|
||||
type Direction = 'bull' | 'bear' | 'flat';
|
||||
|
||||
type Signal = {
|
||||
sym: string;
|
||||
dir: Direction;
|
||||
conf: number;
|
||||
};
|
||||
|
||||
const signals: Signal[] = [
|
||||
{ sym: 'BTCUSDT', dir: 'bull', conf: 73 },
|
||||
{ sym: 'ETHUSDT', dir: 'bear', conf: 68 },
|
||||
{ sym: 'SOLUSDT', dir: 'bull', conf: 81 },
|
||||
{ sym: 'BNBUSDT', dir: 'flat', conf: 52 },
|
||||
{ sym: 'XRPUSDT', dir: 'bull', conf: 76 },
|
||||
{ sym: 'ADAUSDT', dir: 'bear', conf: 61 },
|
||||
{ sym: 'DOGEUSDT', dir: 'bull', conf: 59 },
|
||||
{ sym: 'LINKUSDT', dir: 'bear', conf: 64 }
|
||||
];
|
||||
|
||||
const dirColor: Record<Direction, string> = {
|
||||
bull: 'text-emerald-400',
|
||||
bear: 'text-red-400',
|
||||
flat: 'text-zinc-500'
|
||||
};
|
||||
|
||||
const dirBorder: Record<Direction, string> = {
|
||||
bull: 'border-l-emerald-400',
|
||||
bear: 'border-l-red-400',
|
||||
flat: 'border-l-zinc-500'
|
||||
};
|
||||
|
||||
const dirStroke: Record<Direction, string> = {
|
||||
bull: 'bg-emerald-400',
|
||||
bear: 'bg-red-400',
|
||||
flat: 'bg-zinc-500'
|
||||
};
|
||||
|
||||
const dirBadgeBg: Record<Direction, string> = {
|
||||
bull: 'bg-emerald-400/10',
|
||||
bear: 'bg-red-400/10',
|
||||
flat: 'bg-zinc-500/10'
|
||||
};
|
||||
|
||||
const dirArrow: Record<Direction, string> = {
|
||||
bull: '▲',
|
||||
bear: '▼',
|
||||
flat: '—'
|
||||
};
|
||||
|
||||
const dirLabel: Record<Direction, string> = {
|
||||
bull: 'BULL',
|
||||
bear: 'BEAR',
|
||||
flat: 'FLAT'
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="hidden h-full w-full max-w-140 items-center justify-end lg:flex z-20">
|
||||
<div
|
||||
class="w-full overflow-hidden rounded-2xl border border-white/8 bg-zinc-950 shadow-[0_0_0_1px_rgba(255,255,255,0.03),0_40px_80px_rgba(0,0,0,0.5),0_0_80px_rgba(255,69,0,0.05)]"
|
||||
>
|
||||
<div class="flex items-center justify-between border-b border-white/6 bg-white/2.5 px-4 py-3.5">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex gap-1.5">
|
||||
<div class="h-2 w-2 rounded-full bg-[#ff5f57]"></div>
|
||||
<div class="h-2 w-2 rounded-full bg-[#febc2e]"></div>
|
||||
<div class="h-2 w-2 rounded-full bg-[#28c840]"></div>
|
||||
</div>
|
||||
<span class="font-mono text-[0.57rem] tracking-widest text-zinc-500">
|
||||
FLAMY TRADE · СИГНАЛЫ
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="inline-flex h-1.5 w-1.5 animate-ping rounded-full bg-emerald-400 opacity-75"
|
||||
></span>
|
||||
<span class="font-mono text-[0.57rem] tracking-widest text-emerald-400">LIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="grid grid-cols-[1fr_56px_76px] gap-2.5 border-b border-white/6 bg-white/1 px-4 py-3.5"
|
||||
>
|
||||
<span class="font-mono text-[0.55rem] tracking-widest text-zinc-600">ИНСТРУМЕНТ</span>
|
||||
<span class="text-right font-mono text-[0.55rem] tracking-widest text-zinc-600"
|
||||
>КОНФИД.</span
|
||||
>
|
||||
<span class="pl-2 font-mono text-[0.55rem] tracking-widest text-zinc-600">ПРОГНОЗ</span>
|
||||
</div>
|
||||
|
||||
{#each signals as signal, i (signal.sym)}
|
||||
<div
|
||||
class="grid grid-cols-[1fr_56px_76px] items-center gap-2.5 border-l-2 px-4 py-3 {dirBorder[
|
||||
signal.dir
|
||||
]} {i < signals.length - 1 ? 'border-b border-b-white/[0.06]' : ''}"
|
||||
>
|
||||
<span class="font-display text-[0.6875rem] font-black tracking-tight text-zinc-100">
|
||||
{signal.sym}
|
||||
</span>
|
||||
|
||||
<div class="flex flex-col items-end gap-1">
|
||||
<span class="font-mono text-[0.5625rem] text-zinc-300">{signal.conf}%</span>
|
||||
<div class="h-0.5 w-11 rounded-full bg-zinc-800">
|
||||
<div
|
||||
class="h-full rounded-full transition-[width] duration-300 {dirStroke[signal.dir]}"
|
||||
style="width: {signal.conf}%"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inline-flex items-center gap-1 rounded px-2 py-0.5 {dirBadgeBg[signal.dir]}">
|
||||
<span class="text-[0.5rem] leading-none {dirColor[signal.dir]}"
|
||||
>{dirArrow[signal.dir]}</span
|
||||
>
|
||||
<span
|
||||
class="font-mono text-[0.4375rem] font-semibold tracking-wider {dirColor[signal.dir]}"
|
||||
>{dirLabel[signal.dir]}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
<div class="flex items-center justify-between border-t border-white/6 bg-white/1 px-4 py-2">
|
||||
<span class="font-mono text-[0.6rem] tracking-wider text-zinc-600">
|
||||
ГОРИЗОНТ 19 СВЕЧЕЙ · 5 Mоделей
|
||||
</span>
|
||||
<a
|
||||
href="/dashboard"
|
||||
class="font-mono text-[0.6rem] tracking-wider text-orange-400 transition-opacity duration-200 hover:opacity-70"
|
||||
>
|
||||
ВСЕ СИГНАЛЫ →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,77 @@
|
||||
<script lang="ts">
|
||||
const yr = new Date().getFullYear();
|
||||
|
||||
const navLinks = [
|
||||
{ href: '/dashboard', label: 'Дашборд' },
|
||||
{ href: '/blog', label: 'Блог' },
|
||||
{ href: '/about', label: 'О проекте' }
|
||||
];
|
||||
</script>
|
||||
|
||||
<footer class="mt-auto border-t border-white/6 bg-bg-e">
|
||||
<div class="mx-auto max-w-400 px-5 py-14 sm:px-10">
|
||||
|
||||
<div class="grid grid-cols-2 gap-10 sm:grid-cols-4">
|
||||
<div class="col-span-2 flex flex-col gap-4 sm:col-span-1">
|
||||
<a href="/" class="flex items-center gap-2.5 no-underline">
|
||||
<svg width="24" height="24" viewBox="0 0 26 26" fill="none">
|
||||
<rect width="26" height="26" rx="6" fill="rgba(255,69,0,0.08)" />
|
||||
<path
|
||||
d="M7 20 C7 20 9.5 13 13 15.5 C16.5 18 17 10 20 7"
|
||||
stroke="#fe4b07"
|
||||
stroke-width="1.8"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill="none"
|
||||
/>
|
||||
<circle cx="20" cy="7" r="1.6" fill="#fe4b07" />
|
||||
</svg>
|
||||
<span class="font-display text-sm font-black tracking-tighter">
|
||||
FLAMY<span class="text-primary">TRADE</span>
|
||||
</span>
|
||||
</a>
|
||||
<p class="max-w-[200px] text-[0.8125rem] leading-relaxed text-zinc-600">
|
||||
ML-прогнозы для рыночных инструментов. Только исследования.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<span class="font-mono text-[0.6rem] tracking-widest text-zinc-600 uppercase">Навигация</span>
|
||||
{#each navLinks as link}
|
||||
<a
|
||||
href={link.href}
|
||||
class="text-[0.8125rem] text-desc no-underline transition-colors duration-150 hover:text-zinc-100"
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="col-span-2 flex flex-col gap-3 sm:col-span-2">
|
||||
<span class="font-mono text-[0.6rem] tracking-widest text-zinc-600 uppercase">Дисклеймер</span>
|
||||
<p class="max-w-[380px] text-xs leading-relaxed text-zinc-600">
|
||||
Материалы являются результатом работы исследовательской ML-модели и используются в
|
||||
демонстрационных целях. Не являются индивидуальной инвестиционной рекомендацией.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="mt-10 flex flex-col items-start justify-between gap-2 border-t border-white/6 pt-8 sm:flex-row sm:items-center"
|
||||
>
|
||||
<span class="text-xs text-zinc-600">© {yr} Flamy Trade</span>
|
||||
<span class="text-xs text-zinc-600">
|
||||
implemented in
|
||||
<a
|
||||
href="https://flamy.studio"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-desc no-underline transition-colors duration-150 hover:text-primary"
|
||||
>
|
||||
flamy studio
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
// Ссылки
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
const menuLinks = [
|
||||
{ id: 0, href: 'reg', text: 'Главная' },
|
||||
{ id: 1, href: 'reg', text: 'О проекте' },
|
||||
{ id: 2, href: 'reg', text: 'Блог' },
|
||||
{ id: 3, href: 'reg', text: 'Открыть дашборд', isButton: true }
|
||||
];
|
||||
</script>
|
||||
|
||||
<header class="fixed right-0 left-0 border-b border-b-bg-h bg-bg-e py-5 z-9999">
|
||||
<div class="mx-auto flex max-w-400 items-center justify-between">
|
||||
<a href="/" class="font-display text-lg font-semibold uppercase">Flamy Trade</a>
|
||||
|
||||
<nav>
|
||||
<ul class="flex items-center justify-center gap-5.5 transition-colors duration-300">
|
||||
{#each menuLinks as link (link.id)}
|
||||
<li>
|
||||
<a
|
||||
href={link.href}
|
||||
class={cn('transition-colors duration-300', link.isButton ? 'nav-btn' : 'nav-link')}
|
||||
>
|
||||
{link.text}
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type Props = {
|
||||
href?: string;
|
||||
target?: string;
|
||||
variant?: 'primary' | 'secondary';
|
||||
children: Snippet;
|
||||
};
|
||||
|
||||
let { href, target = '_self', variant = 'primary', children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={href ? 'a' : 'button'}
|
||||
{href}
|
||||
{target}
|
||||
rel={target === '_blank' ? 'noopener noreferrer' : undefined}
|
||||
class={cn(
|
||||
'flex items-center justify-center gap-2 w-fit rounded-xl px-6 py-3 font-display text-lg font-medium transition-colors duration-300',
|
||||
variant === 'primary' && 'bg-primary hover:bg-primary-h',
|
||||
variant === 'secondary' && 'bg-bg border hover:text-desc'
|
||||
)}
|
||||
>
|
||||
{@render children()}
|
||||
|
||||
{#if variant === 'primary'}
|
||||
<img src="images/icons/arrow-right.svg" alt="Перейти" class="h-5 w-5" />
|
||||
{/if}
|
||||
</svelte:element>
|
||||
@@ -0,0 +1,6 @@
|
||||
import { clsx, type ClassValue } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<script>
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
</script>
|
||||
|
||||
<section class="flex h-screen items-center justify-center pt-16">
|
||||
<h1
|
||||
class="flex flex-col text-center font-display text-[110px] leading-[1.1] font-black uppercase"
|
||||
>
|
||||
Страница не найдена
|
||||
<span class="text-[64px] leading-none text-primary"> Возможно стр </span>
|
||||
</h1>
|
||||
</section>
|
||||
@@ -1,9 +1,22 @@
|
||||
<script lang="ts">
|
||||
import './layout.css';
|
||||
import favicon from '$lib/assets/favicon.svg';
|
||||
import Header from '$lib/components/layout/Header.svelte';
|
||||
import Footer from '$lib/components/layout/Footer.svelte';
|
||||
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<svelte:head><link rel="icon" href={favicon} /></svelte:head>
|
||||
<svelte:head>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Unbounded:wght@200..900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
</svelte:head>
|
||||
|
||||
<Header />
|
||||
{@render children()}
|
||||
<Footer />
|
||||
|
||||
+21
-2
@@ -1,2 +1,21 @@
|
||||
<h1>Welcome to SvelteKit</h1>
|
||||
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
|
||||
<script lang="ts">
|
||||
import Hero from './_sections/Hero.svelte';
|
||||
import Ticker from './_sections/Ticker.svelte';
|
||||
import About from './_sections/About.svelte';
|
||||
import Features from './_sections/Features.svelte';
|
||||
import Stats from './_sections/Stats.svelte';
|
||||
import BlogPreview from './_sections/BlogPreview.svelte';
|
||||
import Cta from './_sections/Cta.svelte';
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<Hero />
|
||||
<Ticker />
|
||||
<About />
|
||||
<Features />
|
||||
<Stats />
|
||||
<BlogPreview posts={[]} />
|
||||
<Cta />
|
||||
|
||||
<div class="noise"></div>
|
||||
</main>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import DashboardStatus from '$lib/components/DashboardStatus.svelte';
|
||||
</script>
|
||||
|
||||
<div class="relative bg-bg-e">
|
||||
<section class="flex h-[70vh] items-center justify-center gap-40">
|
||||
<div>
|
||||
<h2 class="font-display text-7xl font-bold">Дашборд</h2>
|
||||
<p class="mt-8 max-w-140 text-xl text-desc">
|
||||
Все инструменты одним взглядом. Интерактивные графики, уровни входа и выхода, статистика
|
||||
winrate — доступно без регистрации.
|
||||
</p>
|
||||
<ul class="mt-6 mb-10 flex flex-col gap-1 text-xl text-desc">
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="h-2 w-2 shrink-0 rounded-full bg-primary"></span>
|
||||
Интерактивные свечные графики с прогнозом
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="h-2 w-2 shrink-0 rounded-full bg-primary"></span>
|
||||
Уровни Entry · TP · SL на каждом графике
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="h-2 w-2 shrink-0 rounded-full bg-primary"></span>
|
||||
Поиск и фильтрация по направлению
|
||||
</li>
|
||||
</ul>
|
||||
<Button href="/dashboard">Перейти к дашборду</Button>
|
||||
</div>
|
||||
|
||||
<DashboardStatus />
|
||||
</section>
|
||||
|
||||
<div class="noise"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,71 @@
|
||||
<script lang="ts">
|
||||
type Post = {
|
||||
slug: string;
|
||||
date: string;
|
||||
title: string;
|
||||
description: string;
|
||||
tags?: string[];
|
||||
};
|
||||
|
||||
let { posts = [] }: { posts: Post[] } = $props();
|
||||
|
||||
function fmtDate(d: string) {
|
||||
try {
|
||||
return new Intl.DateTimeFormat('ru', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
year: 'numeric'
|
||||
}).format(new Date(d));
|
||||
} catch {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if posts.length > 0}
|
||||
<div class="border-b border-white/6">
|
||||
<section class="px-5 py-24 sm:px-10 sm:py-32">
|
||||
<div class="mb-12 flex items-end justify-between">
|
||||
<h2 class="font-display text-4xl font-black uppercase tracking-tighter">БЛОГ</h2>
|
||||
<a
|
||||
href="/blog"
|
||||
class="font-display text-[0.75rem] font-bold tracking-wider text-desc transition-colors duration-150 hover:text-white"
|
||||
>
|
||||
ВСЕ СТАТЬИ →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="grid grid-cols-1 overflow-hidden rounded-xl border border-white/6 sm:grid-cols-[repeat(auto-fit,minmax(20rem,1fr))]"
|
||||
>
|
||||
{#each posts as post, i}
|
||||
<a
|
||||
href="/blog/{post.slug}"
|
||||
class="flex flex-col gap-5 p-10 no-underline transition-colors duration-150 hover:bg-white/2
|
||||
{i > 0 ? 'border-t border-white/6 sm:border-t-0 sm:border-l' : ''}"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<time datetime={post.date} class="font-mono text-[0.6875rem] tracking-widest text-zinc-600">
|
||||
{fmtDate(post.date)}
|
||||
</time>
|
||||
{#if post.tags?.length}
|
||||
<span class="font-mono text-[0.625rem] uppercase tracking-widest text-zinc-600">
|
||||
{post.tags[0]}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<h3
|
||||
class="font-display font-black leading-tight tracking-tight text-[clamp(1.25rem,2.5vw,1.75rem)]"
|
||||
>
|
||||
{post.title}
|
||||
</h3>
|
||||
<p class="flex-1 text-sm leading-relaxed text-desc">{post.description}</p>
|
||||
<span class="font-display text-[0.75rem] font-bold tracking-wider text-primary">
|
||||
ЧИТАТЬ →
|
||||
</span>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
</script>
|
||||
|
||||
<section class="flex flex-col items-center justify-center overflow-hidden px-5 py-36 text-center sm:px-10">
|
||||
<div
|
||||
class="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_100%_80%_at_50%_110%,rgba(255,69,0,0.12)_0%,transparent_65%)]"
|
||||
></div>
|
||||
<div
|
||||
class="pointer-events-none absolute inset-0 opacity-10"
|
||||
style="background-image: radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px); background-size: 48px 48px; mask-image: radial-gradient(ellipse 70% 70% at 50% 50%, black 20%, transparent 80%);"
|
||||
></div>
|
||||
|
||||
<div class="relative flex flex-col items-center gap-8">
|
||||
<span class="font-mono text-[0.6875rem] tracking-widest text-primary">НАЧАТЬ</span>
|
||||
<h2
|
||||
class="font-display font-black uppercase leading-[0.9] tracking-tighter text-[clamp(4rem,10vw,9rem)]"
|
||||
>
|
||||
ОТКРОЙТЕ<br /><span class="text-primary">ДАШБОРД</span>
|
||||
</h2>
|
||||
<Button href="/dashboard">Открыть дашборд</Button>
|
||||
<p class="max-w-[26rem] font-mono text-[0.6875rem] leading-relaxed text-zinc-600">
|
||||
Материалы носят исследовательский характер. Не являются инвестиционными рекомендациями.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,67 @@
|
||||
<script lang="ts">
|
||||
type Feature = { num: string; title: string; desc: string };
|
||||
|
||||
const features: Feature[] = [
|
||||
{
|
||||
num: '01',
|
||||
title: 'Интерактивные графики',
|
||||
desc: 'Свечной график с историческими данными и прогнозной зоной. Zoom, pan, crosshair. Корректно работает на любом экране.'
|
||||
},
|
||||
{
|
||||
num: '02',
|
||||
title: 'Уровни TP и SL',
|
||||
desc: 'Entry, Take Profit, Stop Loss — только когда модель уверена. Если данных нет, уровни не отображаются.'
|
||||
},
|
||||
{
|
||||
num: '03',
|
||||
title: 'История публикаций',
|
||||
desc: 'До 20 дней назад. Выбор даты и времени из реально доступных публикаций. Сравнивайте прогнозы с реальными движениями.'
|
||||
},
|
||||
{
|
||||
num: '04',
|
||||
title: 'Версия модели',
|
||||
desc: 'Каждая публикация помечена версией ML-модели, горизонтом и точным временем публикации.'
|
||||
},
|
||||
{
|
||||
num: '05',
|
||||
title: 'Статистика WR',
|
||||
desc: 'Winrate, количество сделок и накопленная доходность по каждому инструменту — где API предоставляет данные.'
|
||||
},
|
||||
{
|
||||
num: '06',
|
||||
title: 'Блог и обучение',
|
||||
desc: 'Гайды по чтению графиков, управлению рисками и интерпретации ML-прогнозов в формате статей.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="border-b border-white/6">
|
||||
<section class="px-5 py-24 sm:px-10 sm:py-36">
|
||||
<h2 class="mb-16 font-display text-4xl font-black uppercase tracking-tighter">ВОЗМОЖНОСТИ</h2>
|
||||
|
||||
<div class="border-t border-white/6">
|
||||
{#each features as f}
|
||||
<div
|
||||
class="group cursor-default border-b border-white/6 py-6 transition-colors duration-150 hover:bg-primary/2.5
|
||||
md:grid md:grid-cols-[80px_1fr_1fr] md:items-center md:gap-8 md:py-8"
|
||||
>
|
||||
<span
|
||||
class="block font-display text-3xl font-black leading-none tracking-tighter text-primary opacity-20 transition-opacity duration-150 group-hover:opacity-100
|
||||
md:text-[clamp(2rem,4vw,3.5rem)]"
|
||||
>
|
||||
{f.num}
|
||||
</span>
|
||||
<span
|
||||
class="mt-1 block font-display text-xl font-bold tracking-tight
|
||||
md:mt-0 md:text-[clamp(1rem,1.8vw,1.5rem)]"
|
||||
>
|
||||
{f.title}
|
||||
</span>
|
||||
<span class="mt-1 block text-sm leading-relaxed text-desc md:mt-0">
|
||||
{f.desc}
|
||||
</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import DashboardMockup from '$lib/components/DashboardMockup.svelte';
|
||||
</script>
|
||||
|
||||
<section class="flex h-screen items-center justify-between pt-16">
|
||||
<div style="transform: perspective(1000px) rotateY(6deg) rotateX(3deg); z-index: 20;">
|
||||
<h1 class="flex flex-col font-display text-[100px] leading-[0.95] font-black uppercase">
|
||||
<span> Рыночный </span>
|
||||
<span class="text-[128px]"> прогноз </span>
|
||||
<span class="text-[64px] leading-none text-primary"> от ML-модели </span>
|
||||
</h1>
|
||||
|
||||
<p class="mt-10 max-w-180 text-2xl leading-[1.1] text-desc">
|
||||
Исторические свечи, прогнозная зона, уровни входа и выхода — всё на одном интерактивном
|
||||
графике. Горизонт 19 свечей, таймфрейм 5M.
|
||||
</p>
|
||||
|
||||
<div class="mt-10 flex items-center justify-start gap-4">
|
||||
<Button href="/dashboard">Открыть дашборд</Button>
|
||||
<Button href="/about" variant="secondary">Как работает</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DashboardMockup />
|
||||
|
||||
<!-- Визуальные элементы -->
|
||||
<span
|
||||
class="absolute -top-60 left-0 z-0 h-80 w-full rotate-3 rounded-full bg-primary opacity-30 blur-[200px]"
|
||||
></span>
|
||||
<span class="absolute bottom-35 left-0 z-0 h-px w-full bg-bg-h"></span>
|
||||
<span class="absolute top-55 left-0 z-0 h-px w-full bg-bg-h"></span>
|
||||
</section>
|
||||
@@ -0,0 +1,49 @@
|
||||
<script lang="ts">
|
||||
type Stat = { num: string; suffix: string; label: string; sub: string };
|
||||
|
||||
const stats: Stat[] = [
|
||||
{ num: '19', suffix: '', label: 'ГОРИЗОНТ', sub: 'свечей вперёд' },
|
||||
{ num: '5', suffix: 'M', label: 'ТАЙМФРЕЙМ', sub: 'минутные свечи' },
|
||||
{ num: '24/7', suffix: '', label: 'ОБНОВЛЕНИЕ', sub: 'ежечасно' }
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="relative border-b border-white/6 bg-bg-e">
|
||||
<div class="noise"></div>
|
||||
<section class="px-5 py-24 sm:px-10 sm:py-32">
|
||||
<div class="grid grid-cols-1 overflow-hidden rounded-xl border border-white/6 sm:grid-cols-3">
|
||||
{#each stats as stat, i}
|
||||
<div
|
||||
class="relative overflow-hidden px-8 py-12 border-white/6 sm:px-14 sm:py-16
|
||||
{i > 0 ? 'border-t sm:border-t-0 sm:border-l' : ''}"
|
||||
>
|
||||
<div
|
||||
class="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_80%_60%_at_50%_100%,rgba(255,69,0,0.04)_0%,transparent_70%)]"
|
||||
></div>
|
||||
<div class="relative flex flex-col gap-3">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span
|
||||
class="font-display font-black leading-none tracking-tighter text-[clamp(3.5rem,9vw,8rem)]"
|
||||
>
|
||||
{stat.num}
|
||||
</span>
|
||||
{#if stat.suffix}
|
||||
<span
|
||||
class="font-display font-black leading-none tracking-tighter text-primary text-[clamp(2rem,5vw,4rem)]"
|
||||
>
|
||||
{stat.suffix}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="font-mono text-[0.6875rem] tracking-widest text-primary">
|
||||
{stat.label}
|
||||
</span>
|
||||
<span class="text-[0.8125rem] text-desc">{stat.sub}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
const items = [
|
||||
'BTCUSDT',
|
||||
'ETHUSDT',
|
||||
'SOLUSDT',
|
||||
'BNBUSDT',
|
||||
'XRPUSDT',
|
||||
'ML ПРОГНОЗ',
|
||||
'FLAMY TRADE',
|
||||
'ГОРИЗОНТ 19',
|
||||
'ТАЙМФРЕЙМ 5M'
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="overflow-hidden border-y border-white/6 bg-bg-e py-2.5">
|
||||
<div class="ticker-track flex whitespace-nowrap">
|
||||
{#each [0, 1] as _}
|
||||
{#each items as item}
|
||||
<span class="px-8 font-mono text-[0.6875rem] tracking-widest text-zinc-500">{item}</span>
|
||||
<span class="font-mono text-[0.6875rem] text-zinc-700 opacity-30">·</span>
|
||||
{/each}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1 +1,80 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@theme {
|
||||
--font-display: 'Unbounded', sans-serif;
|
||||
--font-sans: 'DM Sans', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
|
||||
--color-primary: #fe4b07;
|
||||
--color-primary-h: #c83e06; /* hover */
|
||||
--color-bg: #09080a;
|
||||
--color-bg-e: #0f0e10; /* elevated */
|
||||
--color-bg-c: #141318; /* card */
|
||||
--color-bg-h: #1a191e; /* hover */
|
||||
--color-title: #f0ede6;
|
||||
--color-desc: #8a887f;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
main {
|
||||
overflow: hidden;
|
||||
}
|
||||
html {
|
||||
background: #09080a;
|
||||
color: #f0ede6;
|
||||
font-family: var(--font-sans), sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
::selection {
|
||||
background: rgba(255, 69, 0, 0.5);
|
||||
color: #f0ede6;
|
||||
}
|
||||
:focus-visible {
|
||||
outline: 1px solid #ff4500;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
section {
|
||||
@apply relative mx-auto max-w-400 min-h-175 max-h-300;
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
}
|
||||
|
||||
@keyframes ticker {
|
||||
to {
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.nav-btn {
|
||||
@apply rounded-xl bg-primary px-5 py-3 font-display text-base font-normal hover:bg-primary-h;
|
||||
}
|
||||
.nav-link {
|
||||
@apply font-display text-base font-normal hover:text-desc;
|
||||
}
|
||||
|
||||
.noise {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
background-image: url('/images/noise.png');
|
||||
background-repeat: repeat;
|
||||
opacity: 0.14;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
.ticker-track {
|
||||
animation: ticker 22s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user