главная страница
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));
|
||||
}
|
||||
Reference in New Issue
Block a user