9 Commits

Author SHA1 Message Date
Rene Arumetsa
2c4cde6df8 expo and timetable pages 2026-05-01 19:18:52 +03:00
Rene Arumetsa
55709a4338 Add lol host 2026-05-01 19:13:43 +03:00
Rene Arumetsa
eeb6583728 Minor stuff in cs2 and lol pages' 2026-05-01 19:00:48 +03:00
Rene Arumetsa
3bdd508218 CS2 and LoL pages 2026-05-01 18:54:19 +03:00
Rene Arumetsa
371082e47f Cs2 page 2026-05-01 18:29:45 +03:00
Rene Arumetsa
e1bb17ee5a tournament page changes 2026-05-01 17:59:16 +03:00
Rene Arumetsa
13d0a32521 rename league_tournament.png to league_ticket.png 2026-05-01 17:47:52 +03:00
Rene Arumetsa
3ea5185842 Minor opacity fixes for ticket page 2026-05-01 17:38:53 +03:00
Rene Arumetsa
b33c7a2b58 Ticket page 2026-05-01 16:03:18 +03:00
15 changed files with 1434 additions and 1540 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

View File

@@ -1,77 +1,27 @@
"use client";
import { useState } from "react";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import { scheduleData } from "@/data/timetable";
import SectionDivider from "@/components/SectionDivider";
import { useTranslations } from "next-intl";
import { getTranslations, setRequestLocale } from "next-intl/server";
const tabs = Object.keys(scheduleData);
export default function Timetable() {
const [activeTab, setActiveTab] = useState(tabs[0]);
const schedule = scheduleData[activeTab];
const t = useTranslations();
export default async function Timetable({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations({ locale });
return (
<div>
<div className="flex flex-col min-h-[90vh] m-6 mt-16 md:m-16">
<h1
className={`text-4xl md:text-5xl lg:text-6xl ${vipnagorgialla.className} font-bold italic uppercase text-[#2A2C3F] dark:text-[#EEE5E5] mt-8 md:mt-16 mb-8`}
>
{t("schedule.title")}
</h1>
{/* Tab menu */}
<div className="flex gap-4 mb-8 flex-wrap">
{tabs.map((tab) => (
<button
key={tab}
onClick={() => setActiveTab(tab)}
className={`${vipnagorgialla.className} cursor-pointer uppercase italic px-4 py-2 text-lg font-semibold ${
activeTab === tab
? "bg-[#00A3E0] text-white"
: "bg-[#007CAB] dark:bg-[#007CAB] text-[#EEE5E5] hover:bg-[#00A3E0] dark:hover:bg-[#007CAB]"
} transition-colors`}
>
{t(`schedule.${tab}`)}
</button>
))}
</div>
{/* Schedule entries */}
<div className="space-y-6">
{schedule.map((item, idx) => (
<div
key={idx}
className="border-l-3 border-[#007CAB] pl-4 flex flex-col sm:flex-row flex-wrap gap-2 sm:gap-5 items-stretch"
>
<div
className={`${vipnagorgialla.className} md:w-[180px] w-30 text-[#00A3E0] text-3xl md:text-4xl font-bold italic flex-shrink-0 flex items-center sm:justify-center`}
>
{item.time}
</div>
<div className="flex-1 flex flex-col justify-center min-w-0 sm:min-h-[120px]">
<div
className={`${vipnagorgialla.className} text-2xl md:text-3xl italic font-bold text-[#2A2C3F] dark:text-[#EEE5E5] text-balance`}
>
{t(item.titleKey)}
</div>
{item.description && (
<div className="text-xl md:text-2xl text-[#938BA1] dark:text-[#938BA1] text-balance">
{item.description}
</div>
)}
<div className="text-xl md:text-2xl text-[#938BA1] dark:text-[#938BA1] text-balance">
{t(item.locationKey)}
</div>
</div>
</div>
))}
</div>
</div>
<SectionDivider />
<div className="bg-[#0E0F19] min-h-screen flex flex-col items-center justify-center">
<h1
className={`${vipnagorgialla.className} font-bold italic text-4xl md:text-5xl text-[#EEE5E5] uppercase mb-4`}
>
{t("schedule.title")}
</h1>
<p
className={`${vipnagorgialla.className} font-bold italic text-5xl md:text-7xl text-[#EEE5E5] uppercase`}
>
{t("schedule.comingSoon")}
</p>
</div>
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,79 @@
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import Link from "next/link";
import SectionDivider from "@/components/SectionDivider";
import Image from "next/image";
import { getTranslations, setRequestLocale } from "next-intl/server";
interface TicketCardProps {
title: string;
subtitle: string;
price: string;
features: string[];
buttonText: string;
buttonHref: string;
backgroundImage?: string;
backgroundOpacity?: number;
}
function TicketCard({
title,
subtitle,
price,
features,
buttonText,
buttonHref,
backgroundImage,
backgroundOpacity = 40,
}: TicketCardProps) {
return (
<div className="relative bg-[#0E0F19] border-r border-[#1F5673] p-8 flex flex-col min-h-[350px]">
{backgroundImage && (
<Image
src={backgroundImage}
alt=""
fill
className="object-cover object-center"
style={{ opacity: backgroundOpacity / 100 }}
/>
)}
<div className="relative z-10 flex flex-col h-full">
<h2
className={`${vipnagorgialla.className} font-bold italic text-[clamp(2rem,1.5rem+2vw,3rem)] leading-none text-[#00A3E0] uppercase`}
>
{title}
</h2>
<h3
className={`${vipnagorgialla.className} font-bold italic text-xl text-[#EEE5E5] uppercase mb-4`}
>
{subtitle}
</h3>
<p
className={`${vipnagorgialla.className} font-bold italic text-[clamp(2.5rem,2rem+2vw,4rem)] leading-none text-[#00A3E0] mb-4`}
>
{price}
</p>
<ul className="flex flex-col gap-1 mb-6 flex-grow">
{features.map((feature, index) => (
<li
key={index}
className="flex items-start gap-2 text-[#EEE5E5] text-sm"
>
<span className="w-1 h-full min-h-[1.25rem] bg-[#00A3E0] flex-shrink-0" />
<span>{feature}</span>
</li>
))}
</ul>
<Link href={buttonHref} target="_blank">
<button
className={`px-4 py-2 bg-[#007CAB] hover:bg-[#00A3E0] text-[#EEE5E5] ${vipnagorgialla.className} font-bold italic uppercase transition`}
>
{buttonText}
</button>
</Link>
</div>
</div>
);
}
export default async function Tickets({
params,
}: {
@@ -11,108 +82,56 @@ export default async function Tickets({
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations({ locale });
return (
<div>
<div className="flex flex-col min-h-[90vh] m-6 mt-16 md:m-16">
<h1
className={`text-4xl wrap-break-word md:text-5xl lg:text-6xl ${vipnagorgialla.className} font-bold italic text-[#2A2C3F] dark:text-[#EEE5E5] mt-8 md:mt-16 mb-4`}
>
{t("tickets.title")}
</h1>
<div className="flex justify-center lg:items-center flex-col lg:flex-row gap-8 md:gap-12 flex-grow mb-16 md:mt-8 lg:mt-0">
<div className="bg-[#007CAB] -skew-x-2 md:-skew-x-5 text-white italic px-8 md:px-12 py-16 hover:scale-103 transition-all duration-150 w-full md:w-xl lg:w-[400px]">
<h2
className={`text-6xl ${vipnagorgialla.className} font-bold text-[#EEE5E5] pb-2`}
>
{t("tickets.visitor.latePrice")}
</h2>
<h3
className={`text-3xl ${vipnagorgialla.className} font-bold text-[#EEE5E5] pb-4`}
>
{t("tickets.visitor.title")}
</h3>
<ul className="pl-4 mb-8 list-[square] marker:text-[#1F5673]">
{t
.raw("tickets.visitor.features")
.map((feature: string, index: number) => (
<li key={index} className="text-xl">
{feature}
</li>
))}
</ul>
<Link href="https://fienta.com/et/tipilan" target="_blank">
<button
className={`px-4 py-2 bg-[#1F5673] cursor-pointer ${vipnagorgialla.className} font-bold`}
>
{t("tickets.buyTicket")}
</button>
</Link>
</div>
<div className="bg-[#007CAB] -skew-x-2 md:-skew-x-5 text-white italic px-8 md:px-12 py-16 hover:scale-103 transition-all duration-150 w-full md:w-xl lg:w-[400px]">
<h2
className={`text-6xl ${vipnagorgialla.className} font-bold text-[#EEE5E5] pb-2`}
>
{t("tickets.computerParticipant.latePrice")}
</h2>
<h3
className={`text-3xl ${vipnagorgialla.className} font-bold text-[#EEE5E5] pb-4`}
>
{t("tickets.computerParticipant.title")}
</h3>
<ul className="pl-4 mb-8 list-[square] marker:text-[#1F5673]">
{t
.raw("tickets.computerParticipant.features")
.map((feature: string, index: number) => (
<li key={index} className="text-xl">
{feature}
</li>
))}
</ul>
<Link href="https://fienta.com/et/tipilan" target="_blank">
<button
className={`px-4 py-2 bg-[#1F5673] cursor-pointer ${vipnagorgialla.className} font-bold`}
>
{t("tickets.buyTicket")}
</button>
</Link>
</div>
<div className="bg-[#0E0F19]">
{/* 2x2 Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 pt-16 md:pt-20">
{/* KÜLASTAJA PILET */}
<TicketCard
title={t("tickets.visitor.name")}
subtitle={t("tickets.subtitle")}
price={t("tickets.visitor.price")}
features={t.raw("tickets.visitor.features")}
buttonText={t("tickets.buyButton")}
buttonHref="https://fienta.com/et/tipilan"
backgroundImage="/images/landing/visitor_tournament.jpg"
/>
{/* TOETAJA PILET */}
<TicketCard
title={t("tickets.supporter.name")}
subtitle={t("tickets.subtitle")}
price={t("tickets.supporter.price")}
features={t.raw("tickets.supporter.features")}
buttonText={t("tickets.buyButton")}
buttonHref="https://fienta.com/et/tipilan"
backgroundImage="/images/landing/explore_teaser.png"
/>
<div className="bg-[#1F5673] -skew-x-2 md:-skew-x-5 text-gray-400 italic px-8 md:px-12 py-16 w-full md:w-xl lg:w-[400px]">
<h2
className={`text-4xl ${vipnagorgialla.className} font-bold pb-2`}
>
<s>{t("tickets.competitor.price")}</s>
</h2>
<h3
className={`text-2xl ${vipnagorgialla.className} font-bold pb-4`}
>
<s>{t("tickets.competitor.title")}</s>
</h3>
<ul className="pl-4 mb-8 list-[square] marker:text-[#007CAB]">
{t
.raw("tickets.competitor.features")
.map((feature: string, index: number) => (
<li key={index} className="text-sm">
{feature}
</li>
))}
</ul>
{/*<Link href="https://fienta.com/et/tipilan" target="_blank">*/}
<button
className={`px-4 py-2 bg-[#007CAB] text-white ${vipnagorgialla.className} font-bold text-xl uppercase opacity-55`}
>
{t("tickets.soldOut")}!
</button>
{/*</Link>*/}
</div>
</div>
{/* LOL TURNIIRI PILET */}
<TicketCard
title={t("tickets.lol.name")}
subtitle={t("tickets.subtitle")}
price={t("tickets.lol.price")}
features={t.raw("tickets.lol.features")}
buttonText={t("tickets.buyButton")}
buttonHref="https://fienta.com/et/tipilan"
backgroundImage="/images/landing/league_ticket.jpg"
/>
{/* CS2 TURNIIRI PILET */}
<TicketCard
title={t("tickets.cs2.name")}
subtitle={t("tickets.subtitle")}
price={t("tickets.cs2.price")}
features={t.raw("tickets.cs2.features")}
buttonText={t("tickets.buyButton")}
buttonHref="https://fienta.com/et/tipilan"
backgroundImage="/images/landing/compete_teaser.jpg"
backgroundOpacity={30}
/>
</div>
<SectionDivider />
</div>
);
}

View File

@@ -0,0 +1,222 @@
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import CS2Sidebar from "@/components/CS2Sidebar";
import CS2Rules from "@/components/CS2Rules";
import Link from "next/link";
import { getTranslations, setRequestLocale } from "next-intl/server";
const sectionKeys = [
{ id: "intro", labelKey: "cs2page.nav.intro" },
{ id: "info", labelKey: "cs2page.nav.info" },
{ id: "prizes", labelKey: "cs2page.nav.prizes" },
{ id: "format", labelKey: "cs2page.nav.format" },
{ id: "vrs", labelKey: "cs2page.nav.vrs" },
// { id: "faq", labelKey: "cs2page.nav.faq" },
{ id: "rules", labelKey: "cs2page.nav.rules" },
];
export default async function CS2Tournament({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations({ locale });
const sections = sectionKeys.map((section) => ({
id: section.id,
label: t(section.labelKey),
}));
return (
<div className="bg-[#0E0F19] min-h-screen pt-16 md:pt-20">
<div className="max-w-[1920px] mx-auto px-6 md:px-12 py-8 md:py-16">
<div className="grid grid-cols-1 lg:grid-cols-[1fr_300px] gap-8 lg:gap-16">
{/* Main content */}
<div>
{/* Header */}
<h1
className={`${vipnagorgialla.className} font-bold italic text-[clamp(2.5rem,2rem+3vw,4rem)] leading-tight text-[#00A3E0] uppercase mb-4`}
>
{t("cs2page.title")}
</h1>
{/* Buttons */}
<div className="flex flex-wrap gap-4 mb-12">
<Link
href="https://fienta.com/et/tipilan"
target="_blank"
className={`${vipnagorgialla.className} font-bold italic px-4 py-2 bg-[#007CAB] hover:bg-[#00A3E0] text-[#EEE5E5] uppercase transition`}
>
{t("cs2page.buyTicket")}
</Link>
<Link
href="https://git.edunaut.ee/slunk/TipiLAN_reeglistik_ruleset/src/branch/main/CS2%20tournament"
target="_blank"
className={`${vipnagorgialla.className} font-bold italic px-4 py-2 bg-[#1F5673] hover:bg-[#007CAB] text-[#EEE5E5] uppercase transition`}
>
{t("cs2page.viewGithub")}
</Link>
</div>
{/* SISSEJUHATUS */}
<section id="intro" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("cs2page.intro.title")}
</h2>
<p className="text-[#EEE5E5]/80 mb-6">
{t("cs2page.intro.description")}
</p>
<h3
className={`${vipnagorgialla.className} font-bold italic text-xl text-[#EEE5E5] uppercase mb-2`}
>
{t("cs2page.intro.previousWinners")}
</h3>
<p className="text-[#EEE5E5]/80 font-bold">2025</p>
<ol className="text-[#EEE5E5]/80 list-decimal list-inside mb-4">
<li>RAID (Eesti)</li>
<li>hypewrld (Läti)</li>
<li>CSDIILIT (Soome/Eesti)</li>
</ol>
</section>
{/* ÜLDINE INFO */}
<section id="info" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("cs2page.info.title")}
</h2>
<p className="text-[#EEE5E5]/80">
{t("cs2page.info.description")}
</p>
</section>
{/* AUHINNAFOND */}
<section id="prizes" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("cs2page.prizes.title")}
</h2>
<h3
className={`${vipnagorgialla.className} font-bold italic text-xl text-[#00A3E0] uppercase mb-2`}
>
{t("cs2page.prizes.mainTitle")}
</h3>
<ul className="text-[#EEE5E5]/80 mb-2">
<li>1. koht - 3000, 600 inimese kohta, 50% ehk 1/2 auhinnafondist.</li>
<li>2. koht - 2000, 400 inimese kohta, 33.3...(3)% ehk 1/3 auhinnafondist.</li>
<li>3. koht - 1000, 200 inimese kohta, 16.6...(6)% ehk 1/6 auhinnafondist.</li>
</ul>
<p className="text-[#EEE5E5]/60 text-sm mb-6">
{t("cs2page.prizes.mainNote")}
</p>
<h3
className={`${vipnagorgialla.className} font-bold italic text-xl text-[#00A3E0] uppercase mb-2`}
>
{t("cs2page.prizes.secondTitle")}
</h3>
<ul className="text-[#EEE5E5]/80 mb-2">
<li>1. koht - 500, 100 inimese kohta, 66.6...(6)% ehk 2/3 auhinnafondist.</li>
<li>2. koht - 250, 50 inimese kohta, 33.3...(3)% ehk 1/3 auhinnafondist.</li>
</ul>
<p className="text-[#EEE5E5]/60 text-sm">
{t("cs2page.prizes.secondNote")}
</p>
</section>
{/* TURNIIRI FORMAAT */}
<section id="format" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("cs2page.format.title")}
</h2>
<p className="text-[#EEE5E5]/80 mb-4">
{t("cs2page.format.description")}
</p>
<p className="text-[#EEE5E5]/80">
{t("cs2page.format.day1")}
</p>
<p className="text-[#EEE5E5]/80">
{t("cs2page.format.day23")}
</p>
</section>
{/* VRS INFO */}
<section id="vrs" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("cs2page.vrs.title")}
</h2>
<p className="text-[#EEE5E5]/80 mb-4">
{t("cs2page.vrs.description1")}
</p>
<p className="text-[#EEE5E5]/80">
{t("cs2page.vrs.description2")}
</p>
</section>
{/* FAQ - commented out until content is ready
<section id="faq" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("cs2page.faq.title")}
</h2>
<h3
className={`${vipnagorgialla.className} font-bold italic text-lg text-[#EEE5E5] uppercase mb-2`}
>
{t("cs2page.faq.q1")}
</h3>
<p className="text-[#EEE5E5]/80 mb-4">
{t("cs2page.faq.a1")}
</p>
</section>
*/}
{/* REEGLID */}
<section id="rules" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("cs2page.rules.title")}
</h2>
<p className="text-[#EEE5E5]/80 mb-6">
{t("cs2page.rules.description")}
</p>
<CS2Rules sections={t.raw("cs2page.rules.sections")} />
<div className="mt-8">
<p className="text-[#EEE5E5]/80 mb-2">{t("cs2page.rules.contact")}</p>
<p className="text-[#00A3E0] font-bold">{t("cs2page.rules.contactName")}</p>
<p className="text-[#EEE5E5]/70">{t("cs2page.rules.contactRole")}</p>
<p className="text-[#EEE5E5]/70">
Discord:{" "}
<a
href="https://discord.com/users/292372329747710013"
target="_blank"
className="text-[#00A3E0] hover:text-[#EEE5E5] transition"
>
hrkruger
</a>
</p>
</div>
</section>
</div>
{/* Sidebar navigation */}
<CS2Sidebar sections={sections} />
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,186 @@
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import CS2Sidebar from "@/components/CS2Sidebar";
import CS2Rules from "@/components/CS2Rules";
import Link from "next/link";
import { getTranslations, setRequestLocale } from "next-intl/server";
const sectionKeys = [
{ id: "intro", labelKey: "lolpage.nav.intro" },
{ id: "info", labelKey: "lolpage.nav.info" },
{ id: "prizes", labelKey: "lolpage.nav.prizes" },
{ id: "format", labelKey: "lolpage.nav.format" },
// { id: "faq", labelKey: "lolpage.nav.faq" },
{ id: "rules", labelKey: "lolpage.nav.rules" },
];
export default async function LoLTournament({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations({ locale });
const sections = sectionKeys.map((section) => ({
id: section.id,
label: t(section.labelKey),
}));
return (
<div className="bg-[#0E0F19] min-h-screen pt-16 md:pt-20">
<div className="max-w-[1920px] mx-auto px-6 md:px-12 py-8 md:py-16">
<div className="grid grid-cols-1 lg:grid-cols-[1fr_300px] gap-8 lg:gap-16">
{/* Main content */}
<div>
{/* Header */}
<h1
className={`${vipnagorgialla.className} font-bold italic text-[clamp(2.5rem,2rem+3vw,4rem)] leading-tight text-[#00A3E0] uppercase mb-4`}
>
{t("lolpage.title")}
</h1>
{/* Buttons */}
<div className="flex flex-wrap gap-4 mb-12">
<Link
href="https://fienta.com/et/tipilan"
target="_blank"
className={`${vipnagorgialla.className} font-bold italic px-4 py-2 bg-[#007CAB] hover:bg-[#00A3E0] text-[#EEE5E5] uppercase transition`}
>
{t("lolpage.buyTicket")}
</Link>
</div>
{/* SISSEJUHATUS */}
<section id="intro" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("lolpage.intro.title")}
</h2>
<p className="text-[#EEE5E5]/80 mb-6">
{t("lolpage.intro.description")}
</p>
<h3
className={`${vipnagorgialla.className} font-bold italic text-xl text-[#EEE5E5] uppercase mb-2`}
>
{t("lolpage.intro.previousWinners")}
</h3>
<p className="text-[#EEE5E5]/80 font-bold">2025</p>
<ol className="text-[#EEE5E5]/80 list-decimal list-inside mb-4">
<li>Ükssilm (Eesti)</li>
<li>Eesti Rästikud (Eesti)</li>
<li>LOMiks (Läti)</li>
</ol>
</section>
{/* ÜLDINE INFO */}
<section id="info" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("lolpage.info.title")}
</h2>
<p className="text-[#EEE5E5]/80">
{t("lolpage.info.description")}
</p>
</section>
{/* AUHINNAFOND */}
<section id="prizes" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("lolpage.prizes.title")}
</h2>
<h3
className={`${vipnagorgialla.className} font-bold italic text-xl text-[#00A3E0] uppercase mb-2`}
>
{t("lolpage.prizes.mainTitle")}
</h3>
<ul className="text-[#EEE5E5]/80 mb-2">
<li>{t("lolpage.prizes.place1")}</li>
<li>{t("lolpage.prizes.place2")}</li>
<li>{t("lolpage.prizes.place3")}</li>
</ul>
<p className="text-[#EEE5E5]/60 text-sm">
{t("lolpage.prizes.note")}
</p>
</section>
{/* TURNIIRI FORMAAT */}
<section id="format" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("lolpage.format.title")}
</h2>
<p className="text-[#EEE5E5]/80 mb-4">
{t("lolpage.format.description")}
</p>
<p className="text-[#EEE5E5]/80">
{t("lolpage.format.day1")}
</p>
<p className="text-[#EEE5E5]/80">
{t("lolpage.format.day2")}
</p>
</section>
{/* FAQ - commented out until content is ready
<section id="faq" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("lolpage.faq.title")}
</h2>
<h3
className={`${vipnagorgialla.className} font-bold italic text-lg text-[#EEE5E5] uppercase mb-2`}
>
{t("lolpage.faq.q1")}
</h3>
<p className="text-[#EEE5E5]/80 mb-4">
{t("lolpage.faq.a1")}
</p>
</section>
*/}
{/* REEGLID */}
<section id="rules" className="mb-12">
<h2
className={`${vipnagorgialla.className} font-bold italic text-2xl md:text-3xl text-[#EEE5E5] uppercase mb-4`}
>
{t("lolpage.rules.title")}
</h2>
<p className="text-[#EEE5E5]/80 mb-6">
{t("lolpage.rules.description")}
</p>
<CS2Rules sections={t.raw("lolpage.rules.sections")} />
<div className="mt-8">
<p className="text-[#EEE5E5]/80 mb-2">{t("lolpage.rules.contact")}</p>
<p className="text-[#00A3E0] font-bold">{t("lolpage.rules.contactName")}</p>
<p className="text-[#EEE5E5]/70">{t("lolpage.rules.contactRole")}</p>
<p className="text-[#EEE5E5]/70">
Discord:{" "}
<a
href="https://discord.com/users/125585160761638912"
target="_blank"
className="text-[#00A3E0] hover:text-[#EEE5E5] transition"
>
Kukkel
</a>
</p>
</div>
</section>
</div>
{/* Sidebar navigation */}
<CS2Sidebar sections={sections} />
</div>
</div>
</div>
);
}

View File

@@ -3,6 +3,47 @@ import Link from "next/link";
import Image from "next/image";
import { getTranslations, setRequestLocale } from "next-intl/server";
interface TournamentCardProps {
title: string;
buttonText: string;
buttonHref: string;
backgroundImage: string;
objectPosition?: string;
}
function TournamentCard({
title,
buttonText,
buttonHref,
backgroundImage,
objectPosition = "center",
}: TournamentCardProps) {
return (
<div className="relative bg-[#0E0F19] border-r border-[#1F5673] flex flex-col items-center justify-center h-[818px]">
<Image
src={backgroundImage}
alt=""
fill
className="object-cover opacity-50"
style={{ objectPosition }}
/>
<div className="relative z-10 flex flex-col items-center text-center">
<h2
className={`${vipnagorgialla.className} font-bold italic text-[clamp(2rem,1.5rem+3vw,4rem)] leading-none text-[#EEE5E5] uppercase mb-4`}
>
{title}
</h2>
<Link
href={buttonHref}
className={`${vipnagorgialla.className} font-bold italic text-xl text-[#00A3E0] hover:text-[#EEE5E5] uppercase transition`}
>
{buttonText}
</Link>
</div>
</div>
);
}
export default async function Tourney({
params,
}: {
@@ -11,254 +52,28 @@ export default async function Tourney({
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations({ locale });
const headingStyle = `text-3xl md:text-5xl lg:text-5xl ${vipnagorgialla.className} font-bold uppercase text-[#2A2C3F] dark:text-[#EEE5E5] -skew-x-2 md:-skew-x-5 break-normal`;
const miniTournaments: {
name: string;
prize: string;
image: string;
objectPosition?: string;
bgClass?: string;
}[] = [
{
name: "Tekken 8",
prize: "200€",
image: "/images/miniturniirid/tekken8.jpg",
objectPosition: "object-center",
},
{
name: "WRC",
prize: "350€",
image: "/images/miniturniirid/wrc.jpg",
objectPosition: "object-center",
},
{
name: "Street Fighter 6",
prize: "150€",
image: "/images/miniturniirid/street_fighter.jpg",
objectPosition: "object-center",
},
{
name: "Gran Turismo",
prize: "200€",
image: "/images/miniturniirid/gran_turismo.jpg",
objectPosition: "object-center",
},
{
name: "FC 26",
prize: "100€",
image: "/images/miniturniirid/fc26.jpg",
objectPosition: "object-center",
},
{
name: "Dwarf Escape",
prize: "50€",
image: "/images/miniturniirid/dwarf_escape.png",
objectPosition: "object-center",
bgClass: "bg-black",
},
{
name: "Buckshot Roulette",
prize: "Merch",
image: "/images/miniturniirid/buckshot_tournament.png",
objectPosition: "object-center",
bgClass: "bg-black",
},
{
name: "2XKO",
prize: "100€",
image: "/images/miniturniirid/2xko.png",
objectPosition: "object-top",
},
{
name: "Super Smash Bros. Ultimate",
prize: "100€",
image: "/images/miniturniirid/super_smash_bros.jpg",
objectPosition: "object-top",
},
];
return (
<div className="flex flex-col min-h-[90vh] mt-16">
<h1
className={`text-4xl md:text-5xl lg:text-6xl ${vipnagorgialla.className} font-bold italic uppercase
text-[#2A2C3F] dark:text-[#EEE5E5] mt-8 md:mt-16 mb-8 m-6 md:m-16`}
>
{t("tournaments.title")}
</h1>
<div className="flex flex-col">
{/* Mini-turniirid */}
<div className="hover:bg-[#007CAB] py-8 md:py-16 border-b-[3px] border-[#1F5673] transition group">
<div className="mx-8 md:mx-16 lg:mx-32 xl:mx-48">
<div className="-skew-x-2 md:-skew-x-5 mb-8">
<h2 className={`${headingStyle}`}>
{t("tournaments.mini.title")}
</h2>
<p
className={
"text-2xl mb-4 text-neutral-500 group-hover:text-black"
}
>
{t("tournaments.mini.timing")}
</p>
<p className="text-balance">
{t("tournaments.mini.description1")}
</p>
<p className="text-balance">
{t("tournaments.mini.description2")}
</p>
<br />
<div className="flex flex-row flex-wrap gap-4 md:gap-8">
<Link href="/kodukord" target="_blank">
<button
className={`px-4 py-2 bg-[#1F5673] cursor-pointer ${vipnagorgialla.className} font-bold italic text-[#ECE5E5]`}
>
{t("tournaments.mini.readRules")}
</button>
</Link>
<a href="https://fienta.com/et/tipilan" target="_blank">
<button
className={`px-4 py-2 bg-[#00A3E0] group-hover:bg-black cursor-pointer ${vipnagorgialla.className} font-bold italic text-[#ECE5E5]`}
>
{t("tournaments.mini.buyTicket")}
</button>
</a>
</div>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 gap-8">
{miniTournaments.map((tournament) => (
<div key={tournament.name} className="text-center">
<Image
src={tournament.image}
alt={tournament.name}
width={400}
height={300}
className={`outline-10 outline-[#007CAB] bg-black object-cover w-full aspect-video -skew-x-2 md:-skew-x-5 ${
tournament.objectPosition || "object-center"
}`}
/>
<div className="-skew-x-2 md:-skew-x-5">
<p className="mt-2 font-semibold">{tournament.name} - {tournament.prize}</p>
</div>
</div>
))}
</div>
</div>
</div>
{/* CS2 turniir */}
<div className="hover:bg-[#007CAB] py-8 md:py-16 transition group">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-16 items-center mx-8 md:mx-16 lg:mx-32 xl:mx-48">
<div className="-skew-x-2 md:-skew-x-5">
<h2 className={`${headingStyle}`}>
{t("tournaments.cs2.title")}
</h2>
<p
className={
"text-2xl mb-4 text-neutral-500 group-hover:text-black"
}
>
{t("tournaments.cs2.timing")}
</p>
<p className="text-balance">
{t("tournaments.cs2.description1")}
</p>
<br />
<p className="text-balance">
{t("tournaments.cs2.description2")}
</p>
<p className="text-balance">
{t("tournaments.cs2.description3")}
</p>
<br />
<div className={"flex flex-row flex-wrap gap-8"}>
<Link href="/reeglid/cs2" target="_blank">
<button
className={`px-4 py-2 bg-[#1F5673] cursor-pointer ${vipnagorgialla.className} font-bold italic text-[#ECE5E5]`}
>
{t("tournaments.cs2.readRules")}
</button>
</Link>
<a href="https://fienta.com/et/tipilan" target="_blank">
<button
className={`px-4 py-2 bg-[#00A3E0] group-hover:bg-black cursor-pointer ${vipnagorgialla.className} font-bold italic text-[#ECE5E5]`}
>
{t("tournaments.cs2.buyTicket")}
</button>
</a>
</div>
</div>
<div className="hidden md:block">
<div>
{/* Outside div needs to remain so that overflow won't occur*/}
<Image
src="/images/cs2_tournament_logo.png"
alt="CS2 tournament"
width={600}
height={400}
/>
</div>
</div>
</div>
</div>
{/* LoL turniir */}
<div className="hover:bg-[#007CAB] py-8 md:py-16 border-t-[3px] border-b-[3px] border-[#1F5673] transition group">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-16 items-center mx-8 md:mx-16 lg:mx-32 xl:mx-48">
<div className="hidden md:block">
<div>
{/* Outside div needs to remain so that overflow won't occur*/}
<Image
src="/images/lol_tournament_logo.png"
alt="LoL tournament"
width={600}
height={400}
/>
</div>
</div>
<div className="flex-auto text-right -skew-x-2 md:-skew-x-5">
<h2 className={`${headingStyle}`}>
{t("tournaments.lol.title")}
</h2>
<p
className={
"text-2xl mb-4 text-neutral-500 group-hover:text-black"
}
>
{t("tournaments.lol.timing")}
</p>
<p className="text-balance">
{t("tournaments.lol.description1")}
</p>
<br />
<p className="text-balance">
{t("tournaments.lol.description2")}
</p>
<br />
<div className="flex flex-row flex-wrap gap-4 md:gap-8 justify-end">
<Link href="/reeglid/lol" target="_blank">
<button
className={`px-4 py-2 bg-[#1F5673] cursor-pointer ${vipnagorgialla.className} font-bold italic text-[#ECE5E5]`}
>
{t("tournaments.lol.readRules")}
</button>
</Link>
<a href="https://fienta.com/et/tipilan" target="_blank">
<button
className={`px-4 py-2 bg-[#00A3E0] group-hover:bg-black cursor-pointer ${vipnagorgialla.className} font-bold italic text-[#ECE5E5]`}
>
{t("tournaments.lol.buyTicket")}
</button>
</a>
</div>
</div>
</div>
</div>
<div className="bg-[#0E0F19]">
{/* 1x2 Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 pt-16 md:pt-20">
{/* CS2 */}
<TournamentCard
title="COUNTER-STRIKE 2"
buttonText={t("tournaments.clickButton")}
buttonHref="/turniirid/cs2"
backgroundImage="/images/landing/cs2_tournament.jpg"
/>
{/* LoL */}
<TournamentCard
title="LEAGUE OF LEGENDS"
buttonText={t("tournaments.clickButton")}
buttonHref="/turniirid/lol"
backgroundImage="/images/landing/lol_tournament.png"
objectPosition="bottom left"
/>
</div>
</div>
);
}
}

View File

@@ -0,0 +1,86 @@
"use client";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
interface RuleSection {
title: string;
rules: (string | { main: string; sub: (string | { main: string; sub: string[] })[] })[];
}
interface CS2RulesProps {
sections: RuleSection[];
}
function RuleItem({ rule, index }: { rule: string | { main: string; sub: (string | { main: string; sub: string[] })[] }; index: number }) {
if (typeof rule === "string") {
return (
<li className="text-[#EEE5E5]/80 mb-2">
<span className="text-[#00A3E0] mr-2">{index}.</span>
{rule}
</li>
);
}
return (
<li className="text-[#EEE5E5]/80 mb-3">
<span className="text-[#00A3E0] mr-2">{index}.</span>
{rule.main}
{rule.sub && rule.sub.length > 0 && (
<ol className="ml-6 mt-2">
{rule.sub.map((subRule, subIndex) => {
if (typeof subRule === "string") {
return (
<li key={subIndex} className="text-[#EEE5E5]/70 mb-1">
<span className="text-[#00A3E0]/70 mr-2">{index}.{subIndex + 1}.</span>
{subRule}
</li>
);
}
return (
<li key={subIndex} className="text-[#EEE5E5]/70 mb-2">
<span className="text-[#00A3E0]/70 mr-2">{index}.{subIndex + 1}.</span>
{subRule.main}
{subRule.sub && subRule.sub.length > 0 && (
<ol className="ml-6 mt-1">
{subRule.sub.map((subSubRule, subSubIndex) => (
<li key={subSubIndex} className="text-[#EEE5E5]/60 mb-1">
<span className="text-[#00A3E0]/50 mr-2">{index}.{subIndex + 1}.{subSubIndex + 1}.</span>
{subSubRule}
</li>
))}
</ol>
)}
</li>
);
})}
</ol>
)}
</li>
);
}
export default function CS2Rules({ sections }: CS2RulesProps) {
let ruleCounter = 0;
return (
<div>
{sections.map((section, sectionIndex) => {
const startIndex = ruleCounter;
ruleCounter += section.rules.length;
return (
<div key={sectionIndex} className="mb-8">
<h3 className={`${vipnagorgialla.className} font-bold italic text-xl text-[#00A3E0] uppercase mb-4`}>
{sectionIndex + 1}) {section.title}
</h3>
<ol className="list-none">
{section.rules.map((rule, ruleIndex) => (
<RuleItem key={ruleIndex} rule={rule} index={ruleIndex + 1} />
))}
</ol>
</div>
);
})}
</div>
);
}

View File

@@ -0,0 +1,66 @@
"use client";
import { useEffect, useState } from "react";
interface CS2SidebarProps {
sections: { id: string; label: string }[];
}
export default function CS2Sidebar({ sections }: CS2SidebarProps) {
const [activeSection, setActiveSection] = useState<string>(sections[0]?.id || "");
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveSection(entry.target.id);
}
});
},
{
rootMargin: "-20% 0px -70% 0px",
threshold: 0,
}
);
sections.forEach((section) => {
const element = document.getElementById(section.id);
if (element) {
observer.observe(element);
}
});
return () => {
sections.forEach((section) => {
const element = document.getElementById(section.id);
if (element) {
observer.unobserve(element);
}
});
};
}, [sections]);
return (
<aside className="hidden lg:block">
<nav className="sticky top-24 border-l border-[#1F5673] pl-6">
<ul className="flex flex-col gap-2">
{sections.map((section) => (
<li key={section.id}>
<a
href={`#${section.id}`}
className={`transition ${
activeSection === section.id
? "text-[#EEE5E5] font-bold"
: "text-[#00A3E0] hover:text-[#EEE5E5]"
}`}
>
{section.label}
</a>
</li>
))}
</ul>
</nav>
</aside>
);
}

View File

@@ -8,7 +8,7 @@ const Footer = () => {
const t = useTranslations();
return (
<div className="flex flex-col justify-center sm:justify-between px-6 py-6 md:px-12 md:py-8 gap-4">
<div className="flex flex-col justify-center sm:justify-between px-6 py-6 md:px-12 md:py-8 gap-4 border-t-3 border-[#1F5673]">
<div className="flex flex-col">
<h2
className={`text-3xl sm:text-4xl ${vipnagorgialla.className} font-bold italic uppercase text-[#2A2C3F] dark:text-[#EEE5E5] mb-4`}

View File

@@ -82,48 +82,49 @@
}
},
"tickets": {
"title": "TICKETS AND REGISTRATION",
"buyNow": "Buy now",
"soldOut": "Sold out",
"available": "Available",
"price": "Price",
"includes": "Includes",
"computerParticipant": {
"title": "Computer Participant",
"earlyPrice": "8€",
"latePrice": "10€",
"features": [
"Personal desk, power and internet connection",
"Access to expo area",
"Tournament spectating",
"Ability to participate in mini-tournaments"
]
},
"competitor": {
"title": "Competitor",
"price": "12-15€",
"features": [
"Ability to participate in the CS2 or LoL tournament",
"Personal desk, power and internet connection",
"Access to expo area",
"Tournament spectating",
"Ability to participate in mini-tournaments"
]
},
"title": "TICKETS",
"subtitle": "TICKET",
"buyButton": "BUY TICKET FROM FIENTA",
"visitor": {
"title": "Visitor",
"earlyPrice": "6€",
"latePrice": "8€",
"name": "VISITOR",
"price": "8€",
"features": [
"Access to expo area",
"Tournament spectating",
"Ability to participate in mini-tournaments"
"Area access throughout the event",
"Ability to enter and leave the event area",
"Access to all TipiLAN activities, side events, good vibes and engaging atmosphere."
]
},
"buyTicket": "BUY TICKETS"
"supporter": {
"name": "SUPPORTER",
"price": "25+€",
"features": [
"TipiLAN t-shirt to thank you for your support",
"Opportunity to contribute to TipiLAN's development and future.",
"Everything that comes with the visitor ticket"
]
},
"lol": {
"name": "LOL TOURNAMENT",
"price": "15€",
"features": [
"Right to participate in LoL tournament",
"Personal desk, power and internet connection",
"Access to all TipiLAN activities, side events, good vibes and engaging atmosphere."
]
},
"cs2": {
"name": "CS2 TOURNAMENT",
"price": "20€",
"features": [
"Right to participate in CS2 tournament",
"Personal desk, power and internet connection",
"Access to all TipiLAN activities, side events, good vibes and engaging atmosphere."
]
}
},
"tournaments": {
"title": "Tournaments",
"clickButton": "CLICK",
"register": "Register",
"participants": "Participants",
"prizePool": "Prize pool",
@@ -156,8 +157,298 @@
"buyTicket": "BUY TICKETS"
}
},
"cs2page": {
"title": "COUNTER-STRIKE 2 TOURNAMENT",
"buyTicket": "BUY TICKET",
"viewGithub": "FULL RULES",
"nav": {
"intro": "Introduction",
"info": "General info",
"prizes": "Prize pool",
"format": "Tournament format",
"vrs": "VRS info",
"faq": "FAQ",
"rules": "Rules"
},
"intro": {
"title": "INTRODUCTION",
"description": "CS competitions have been organized at TalTech for nearly 20 years, from CS1.6 to CS:GO. TipiLAN organized its first CS2 tournament in 2025 at its debut event. TipiLAN 2025 CS tournament became the first in Estonian history to award VRS points, achieving Tier 2 Ranked tournament status. Teams from Estonia, Latvia, Lithuania, Finland, Norway, and Ukraine participated, proving the tournament's international reach and strong competition.",
"previousWinners": "PREVIOUS WINNERS"
},
"info": {
"title": "GENERAL INFO",
"description": "TipiLAN 2026 CS2 tournament takes place September 11-13 at TalTech, Tallinn, Estonia. This is a BYOC LAN tournament. On-site, each participant is provided with: desk, chair, wired internet connection, power connection (2 outlets)."
},
"prizes": {
"title": "PRIZE POOL",
"mainTitle": "MAIN TOURNAMENT - 6000€",
"mainNote": "Teams and players outside the prize pool will not receive additional compensation.",
"secondTitle": "SECOND CHANCE TOURNAMENT - 750€",
"secondNote": "Teams and players outside the prize pool will not receive additional compensation."
},
"format": {
"title": "TOURNAMENT FORMAT",
"description": "The entire tournament is BYOC (bring your own computer) LAN, no qualifications take place.",
"day1": "Day 1: 5 rounds Swiss style tournament (Bo1)",
"day23": "Day 2 & 3: Double Elimination playoffs (Winners' Bracket Bo3, Losers' Bracket Bo1)"
},
"vrs": {
"title": "VRS INFO, INVITES",
"description1": "TipiLAN team will submit an application to HLTV for tournament results to be recorded in VRS standings. HLTV ranking status cannot be guaranteed before official confirmation. HLTV decides which matches count towards VRS points.",
"description2": "TipiLAN CS2 tournament follows Valve Ranked Tier 2 tournament requirements. TipiLAN does not send VRS invites to teams."
},
"faq": {
"title": "FREQUENTLY ASKED QUESTIONS",
"q1": "QUESTION?",
"a1": "Answer"
},
"rules": {
"title": "RULES",
"description": "Official TipiLAN 2026 Counter-Strike 2 tournament rules.",
"contact": "For questions, contact:",
"contactName": "Harles Kadanik",
"contactRole": "Game Official - CS2 Tournament",
"contactDiscord": "Discord: hrkruger",
"sections": [
{
"title": "General Information",
"rules": [
"The Counter-Strike 2 (CS2) tournament will take place on September 11-13, 2026 at Tallinn University of Technology (TalTech), Ehitajate tee 5, Tallinn.",
{"main": "The prize pool of the tournament is €6750, distributed as follows:", "sub": [{"main": "Main Championship TOP 3 prize pool is €6000:", "sub": ["1st place - €600 per player (total €3000)", "2nd place - €400 per player (total €2000)", "3rd place - €200 per player (total €1000)"]}, {"main": "Second Chance Tournament prize pool is €750:", "sub": ["1st place - €100 per player (total €500)", "2nd place - €50 per player (total €250)"]}]},
{"main": "TipiLAN is classified as a Valve Tier 2 (No Invitations) event.", "sub": ["Top 3 results of the Main Championship will be submitted for VRS calculation. HLTV.org will determine which matches count toward VRS. Ranking status cannot be guaranteed prior to official confirmation."]},
{"main": "Prize money will be paid to the player's bank account within 30 days.", "sub": ["In the case of a minor, the prize will be paid to the parent's/guardian's bank account."]},
"Throughout the tournament, every participant must comply with the laws of the Republic of Estonia, the TipiLAN regulations, and the event regulations.",
"By purchasing a ticket, each participant gives consent to be photographed, filmed, and recorded for documentation and marketing purposes.",
"The CS2 main tournament will be recorded and broadcasted on streaming platforms Twitch and YouTube.",
"All communication related to the tournament between team members (in-game chat, voice chat, Discord/TeamSpeak conversations) will be recorded.",
"When streaming independently, the live stream delay must be at least 5 minutes.",
"The organizers have the right to use participants' personal information solely for the purpose of carrying out the event.",
"The organizing team has the right to change and edit the rules without prior notice, provided such changes align with Valve's tournament requirements.",
"The organizing team remains impartial and fair towards all participants."
]
},
{
"title": "CS2 Main Tournament Team and Team Lineup",
"rules": [
"The CS2 main tournament team consists of five core members, one of whom is the team captain.",
"By August 28th 2026 (two weeks before the tournament), each team must confirm its participation, final core roster and team name.",
{"main": "The team captain is the team's representative, who:", "sub": ["Acts as the contact person for the organizing team", "Registers the team for the tournament", "Is responsible for the team's behavior and actions", "Represents the team in matters of warnings, disqualifications, disputes, and timeouts"]},
{"main": "Each team may have one substitute player, who is not part of the core roster:", "sub": ["The substitute must purchase a separate substitute ticket", "The substitute may replace any of the team's core members during the tournament", "The substitute is subject to the same rights and requirements as the core roster"]},
{"main": "Each team may have one coach:", "sub": ["The coach must purchase a separate coach ticket", "The coach can only communicate with the team between matches and during tactical timeouts"]},
{"main": "Changes to the core roster are allowed before the team registration deadline:", "sub": ["Player changes must be made through Fienta", "If a member is replaced, the team still retains the right to have a substitute", "A replacement player is subject to the same rights and requirements as the core roster"]},
"If the team captain is replaced, the team itself decides who will assume the captain's rights and responsibilities.",
"If a team withdraws before the registration deadline, the participation fee will be refunded.",
"All team members may only belong to one team during the tournament and represent only themselves.",
"All team members must be at least 16 years old by the day before the tournament starts.",
"No team member may be a citizen of the Russian Federation or the Republic of Belarus.",
{"main": "Teams are not allowed to:", "sub": ["Display team sponsors during the tournament", "Play in the interest of another team or team member"]},
{"main": "Team name:", "sub": ["Must not be offensive, vulgar, political, or otherwise inappropriate", "Must not contain emojis or other symbols that are not characters", "Must be changed if requested by the organizing team"]}
]
},
{
"title": "Equipment",
"rules": [
"The organizing team will provide participating players with internet access, an internet cable, extension cords, and a seat with a table.",
"Coaches will not be provided with dedicated seating, desk space or internet connections.",
"Each participant is responsible for bringing and ensuring the functionality of all other equipment necessary for participation."
]
},
{
"title": "Schedule",
"rules": [
"All team members must arrive one hour before the scheduled start of the tournament.",
"Teams competing in a match round must be ready at their designated spots 10 minutes before the start of the round.",
"Match start times are determined by the organizing team at the start of the tournament or after the previous round concludes.",
"If a player experiences technical or game-related issues, they must immediately inform the game official or the organizing team.",
"Participants will have at least a 10 minute break between matches and 8 minutes between maps in a Bo3 match.",
"The organizing team has the right to make changes to the schedule.",
"The organizing team is obliged to keep all participants informed about delays or schedule changes."
]
},
{
"title": "Game Version and Settings",
"rules": [
"The most recent version of CS2 will be used throughout the tournament.",
{"main": "The following settings will be used in the CS2 tournament:", "sub": ["Best of 24 rounds (mp_maxrounds 24)", "Round time: 1 minute 55 seconds (mp_roundtime 1.92)", "Starting money: $800 (mp_startmoney 800)", "Freeze time at the start of each round: 20 seconds (mp_freezetime 20)", "Buy time: 20 seconds (mp_buytime 20)", "C4 timer: 40 seconds (mp_c4timer 40)", "Overtime rounds: Best of 6 (mp_overtime_maxrounds 6)", "Overtime starting money: $12,500 (mp_overtime_startmoney 12500)"]},
"Overtime: If the match ends in a tie after 24 rounds, overtime will be played as Best of 6. Overtimes continue until a winner is determined.",
"Timeout: Each team is allowed to call a 30 second timeout up to 3 times during regulation rounds. Use \"!pause\" in the in-game chat.",
"Technical timeout: Each team has the right to call a technical timeout if needed. Use \".tech\" in the in-game chat. Tactical communication is forbidden during all technical timeouts."
]
},
{
"title": "Map Selection & Tournament Structure",
"rules": [
{"main": "The 32-team tournament will take place in two stages:", "sub": ["Swiss stage: 5 rounds, initial phase Bo1, deciding matches Bo3. 3 wins = playoffs (Top 16). 3 losses = Second Chance Tournament.", "Playoffs: Double elimination. Upper bracket Bo3, lower bracket Bo1, Lower Final is Bo3.", "Second Chance Tournament: Double elimination. All matches except Final are Bo1, Final is Bo3."]},
{"main": "Seeding will be conducted according to VRS priority:", "sub": ["Teams with Global VRS rank will be seeded higher than unranked teams", "Teams without Global VRS rank will be assigned initial seeds randomly", "After the initial round, standings will be determined by the Buchholz system"]},
"The map pool will consist of maps from the current Valve Active Duty Map Group.",
{"main": "Best of 1 (Bo1) veto:", "sub": ["Team A removes 2 maps", "Team B removes 3 maps", "Team A removes 1 map", "The remaining map will be played"]},
{"main": "Best of 3 (Bo3) veto:", "sub": ["Team A removes 1 map", "Team B removes 1 map", "Team A picks 1 map", "Team B picks 1 map", "Team A removes 1 map", "Team B removes 1 map", "The remaining map will be played as the decider if necessary"]}
]
},
{
"title": "Forbidden Actions in the CS2 Tournament",
"rules": [
"Any kind of cheating, including methods not listed here, is strictly prohibited.",
"The use of scripts is forbidden (except for weapon/grenade purchase scripts and jump-throw scripts).",
"Moving through walls, floors, and ceilings, including \"sky-walking,\" is forbidden.",
"Pixel walking - standing, crouching, walking on invisible map edges - is forbidden.",
"Bombs must be planted in such a way that they can be defused.",
"Players are not allowed to plant an armed bomb in a location where it cannot be defused.",
"Players are not allowed to assign names (nametags) to items that violate the TipiLAN regulations.",
"Custom game files/data/drivers are not allowed.",
"The use of character models (agent skins) is not allowed.",
"Exploiting in-game bugs is forbidden.",
"Any kind of match-fixing, result manipulation, fraud, or collusion is strictly forbidden and will result in immediate team disqualification."
]
},
{
"title": "Penalties",
"rules": [
"Violations of in-game and out-of-game rules as well as breaches of the TipiLAN regulations are punishable.",
"Teams must maintain at least 4 of their 5 originally registered core members for all matches to remain eligible.",
"A team member who violates the rules will first receive a verbal warning. For a second violation, they will receive a second warning. On the third violation, the player will be disqualified.",
"A team member who does not show up for the tournament or match round without a valid reason will be disqualified.",
"A team member who is not present and ready 10 minutes before their match (no-show situation) will be disqualified.",
"If the organizing team determines that a player has violated section 7 rules, the entire team will be immediately disqualified. The violating player will receive a permanent ban from all future TipiLAN tournaments.",
"A team has the right to voluntarily withdraw from the tournament.",
"In case of a team disqualification, the opposing team will automatically win the current match round.",
"In case of disqualification, the participation fee will not be refunded.",
{"main": "Only the team captain may dispute a disqualification:", "sub": ["A dispute must be submitted within 15 minutes", "The organizing team has up to 25 minutes to make a decision"]},
{"main": "Teams have the right to file a protest:", "sub": ["A protest must be submitted within 5 minutes of discovering the issue", "The organizing team has up to 25 minutes to make a decision"]},
"The game official will inform the violating player, their team, and the opposing team about the violation and its consequences.",
"The organizing team has the right to pause and resume a match round at any time if necessary.",
"The organizing team is obliged to publicly announce all eliminations, disqualifications, and subsequent changes."
]
}
]
}
},
"lolpage": {
"title": "LEAGUE OF LEGENDS TOURNAMENT",
"buyTicket": "BUY TICKET",
"nav": {
"intro": "Introduction",
"info": "General info",
"prizes": "Prize pool",
"format": "Tournament format",
"faq": "FAQ",
"rules": "Rules"
},
"intro": {
"title": "INTRODUCTION",
"description": "TipiLAN organized its first LoL tournament in 2025 at its debut event. Teams from Estonia and Latvia participated.",
"previousWinners": "PREVIOUS WINNERS"
},
"info": {
"title": "GENERAL INFO",
"description": "TipiLAN 2026 LoL tournament takes place September 11-13 at TalTech, Tallinn, Estonia. This is a BYOC LAN tournament. On-site, each participant is provided with: desk, chair, wired internet connection, power connection (2 outlets)."
},
"prizes": {
"title": "PRIZE POOL",
"mainTitle": "MAIN TOURNAMENT - €3000",
"place1": "1st place - €1500, €300 per player, 50% or 1/2 of the prize pool.",
"place2": "2nd place - €1000, €200 per player, 33.3...% or 1/3 of the prize pool.",
"place3": "3rd place - €500, €100 per player, 16.6...% or 1/6 of the prize pool.",
"note": "Teams and players outside the prize pool will not receive additional compensation."
},
"format": {
"title": "TOURNAMENT FORMAT",
"description": "The entire tournament is BYOC (bring your own computer) LAN, no qualifications take place.",
"day1": "Day 1: Round Robin in two groups, 5 games.",
"day2": "Day 2: Single Elimination Playoff."
},
"faq": {
"title": "FREQUENTLY ASKED QUESTIONS",
"q1": "QUESTION?",
"a1": "Answer"
},
"rules": {
"title": "RULES",
"description": "Official TipiLAN 2026 League of Legends tournament rules.",
"contact": "For questions, contact:",
"contactName": "Nils-Hendrik Nõlvak",
"contactRole": "Game Official - LoL Tournament",
"sections": [
{
"title": "General Information",
"rules": [
"The League of Legends (LoL) tournament takes place as a two-day event on September 11-13, 2026 at Tallinn University of Technology (TalTech), Ehitajate tee 5, Tallinn.",
{"main": "The tournament prize pool is €3000, distributed as follows:", "sub": ["1st place team - €300 per player", "2nd place team - €200 per player", "3rd place team - €100 per player"]},
{"main": "Prize money will be paid to the player's bank account.", "sub": ["In the case of a minor, the prize will be paid to the parent's/guardian's bank account."]}
]
},
{
"title": "Teams and Participants",
"rules": [
{"main": "A team must have:", "sub": ["Five members (each member referred to as Participant)", "One member is the team Captain, who is the spokesperson for the entire team", "All members must be at least 16 years old at the time of registration", "Participant may not be a citizen of the Russian Federation or Republic of Belarus", "Teams are not allowed to use a coach during the tournament", "One team member may be substituted, who must also be registered and physically present"]},
"Participant must provide only truthful information and be ready to verify their identity to the Organizer.",
"Team name and logo, as well as Participant's in-game alias and avatar must be appropriate, without profanity, vulgarity, political or religious messages or symbols.",
"Participant represents only themselves throughout the Tournament (i.e., no one else may compete on their behalf).",
"All Participants under 18 must be ready to provide guardian consent for tournament participation.",
"Participant must be polite throughout the tournament and respect fellow participants, organizers and visitors. TipiLAN does not tolerate hate speech, harassment, threatening, insulting or aggressive behavior.",
"Team must be registered on both the TipiLAN website and challengermode tournament page."
]
},
{
"title": "Pre-game Procedures",
"rules": [
{"main": "Tournament participation, matches and bracket work through challengermode.com.", "sub": ["The entire team must be registered, including substitute", "Players must have their highest rank account linked in challengermode", "Tournament takes place on EU West server", "Players may not use any account other than those linked in challengermode"]},
"Matches in challengermode are automatic. For a new match, there is 10 minutes to confirm readiness.",
{"main": "Draft can begin when both sides have confirmed readiness.", "sub": ["Placeholders are not allowed. If a champion is locked in draft, it must be played", "Before draft, players must be in role order: Top-Jungle-Mid-Bot-Support", "Deliberate stalling is not allowed"]},
"Only official streamers and referees may join the match lobby besides players."
]
},
{
"title": "In-game Procedures",
"rules": [
{"main": "A game has officially started (game of record) when all 10 players are on the map and the game has reached the first real interaction. GOR conditions:", "sub": ["Either team successfully uses an attack or ability", "Opponents see each other", "Entering enemy territory", "Game has lasted 2 minutes"]},
{"main": "Game pause:", "sub": ["During pause, players are not allowed to leave the match area", "Organizers may pause the game as needed", "Each team has the right to take up to 15 minutes of pause total during the match for valid reasons"]},
"The game may be resumed only with consent of both parties or referee permission.",
"If an obstacle occurs in fair gameplay (gamebreaking bug, connection issues, etc.), the referee will determine new instructions."
]
},
{
"title": "Match Conclusion",
"rules": [
{"main": "The match winner is the team with the most games won.", "sub": ["Organizer will display team standings in an accessible manner", "After each match, the bracket is updated in challengermode"]}
]
},
{
"title": "Tournament Elimination",
"rules": [
"A team may decide to end tournament participation at any time by notifying the referee and/or organizer.",
"Penalties earned until elimination remain valid until the end of the tournament.",
"If a team does not show up or is not ready by the agreed start time, the Organizer may eliminate the team.",
{"main": "The team roster cannot be changed during the tournament.", "sub": ["If team size falls below the required number due to member departure, the Organizer must eliminate the team"]},
"If a team wishes to withdraw during a match, the team must forfeit.",
"All eliminations and disqualifications must be announced publicly immediately."
]
},
{
"title": "Penalties",
"rules": [
"Referees assign penalties following the guidelines in this document.",
"Only referees may assign penalties.",
"The referee will inform both the offending player, their team, and the opposing team of the offense and penalty.",
"The referee must be impartial; team skill level must not influence monitoring of offenses and penalties.",
"Penalties may be assigned to the entire team or a single team member.",
{"main": "Penalties may include:", "sub": ["WARNING: a notice for a minor offense", "BAN LOSS: Team cannot ban a certain number of champions in the following game", "GAME LOSS: Team receives automatic loss for one game", "MATCH LOSS: Team receives automatic match loss", "DISQUALIFICATION: Applies to the entire team"]},
{"main": "Inappropriate behavior categories:", "sub": ["MINOR OFFENSE: unpleasant, unethical or disruptive behavior - penalty warning", "MEDIUM OFFENSE: ignoring instructions, hate speech, aggression - penalty game loss", "MAJOR OFFENSE: clearly against rules and good practices - penalty disqualification", "COLLUSION: agreement between two teams - penalty disqualification of both teams", "BRIBERY AND BETTING: prohibited - penalty disqualification", "AGGRESSIVE BEHAVIOR: aggression against people - penalty disqualification", "CHEATING: deliberate action to gain advantage - penalty disqualification"]}
]
},
{
"title": "Tournament Format",
"rules": [
"Tournament uses Fearless draft principles. This means champions picked during a series cannot be picked in subsequent games until the series ends.",
{"main": "Tournament uses Round Robin + Single Elimination format:", "sub": ["First round has 2 six-team groups where all teams play each other once", "This determines the top 4 who advance to the next day's single elimination bracket", "In case of group ties, the team that won the head-to-head match advances"]}
]
}
]
}
},
"schedule": {
"title": "Schedule",
"comingSoon": "Coming soon",
"day": "Day",
"time": "Time",
"event": "Event",
@@ -227,6 +518,7 @@
},
"expo": {
"title": "Expo Area",
"comingSoon": "Coming soon",
"description": "The TipiLAN expo area hosts companies, additional activities and lectures.",
"areas": {
"bar": "Bar",

View File

@@ -82,48 +82,49 @@
}
},
"tickets": {
"title": "PILETID JA REGISTREERIMINE",
"buyNow": "Osta nüüd",
"soldOut": "Välja müüdud",
"available": "Saadaval",
"price": "Hind",
"includes": "Sisaldab",
"computerParticipant": {
"title": "Arvutiga osaleja",
"earlyPrice": "8€",
"latePrice": "10€",
"features": [
"Isiklik laud, voolu- ja internetiühendus",
"Ligipääs messialale",
"Turniiride pealt vaatamine",
"Võimalus osaleda miniturniiridel"
]
},
"competitor": {
"title": "Võistleja",
"price": "12-15€",
"features": [
"Võimalus osaleda CS2 või LoL turniiril",
"Isiklik laud, voolu- ja internetiühendus",
"Ligipääs messialale",
"Turniiride pealt vaatamine",
"Võimalus osaleda miniturniiridel"
]
},
"title": "PILETID",
"subtitle": "PILET",
"buyButton": "OSTA PILET FIENTAST",
"visitor": {
"title": "Külastaja",
"earlyPrice": "6€",
"latePrice": "8€",
"name": "KÜLASTAJA",
"price": "8€",
"features": [
"Ligipääs messialale",
"Turniiride pealt vaatamine",
"Võimalus osaleda miniturniiridel"
"Alade ligipääs kogu ürituse vältel",
"Võimalus ürituse alalt sisse ja välja liikuda",
"Juurdepääs kogu TipiLAN melule, tegevustele, kõrvalsündmustele, headele vibe'dele ja kaasahaaravale atmosfäärile."
]
},
"buyTicket": "OSTA PILET"
"supporter": {
"name": "TOETAJA",
"price": "25+€",
"features": [
"TipiLANi t-särk, et tänada sind meie toetamise eest",
"Võimalust anda oma panus TipiLANi arengusse ja tulevikku.",
"Kõik, mis kaasneb külastaja piletiga"
]
},
"lol": {
"name": "LOL TURNIIRI",
"price": "15€",
"features": [
"Õigus osaleda LoL turniiril",
"Isiklik laud, voolu- ja internetiühendus",
"Juurdepääs kogu TipiLAN melule, tegevustele, kõrvalsündmustele, headele vibe'dele ja kaasahaaravale atmosfäärile."
]
},
"cs2": {
"name": "CS2 TURNIIRI",
"price": "20€",
"features": [
"Õigus osaleda CS2 turniiril",
"Isiklik laud, voolu- ja internetiühendus",
"Juurdepääs kogu TipiLAN melule, tegevustele, kõrvalsündmustele, headele vibe'dele ja kaasahaaravale atmosfäärile."
]
}
},
"tournaments": {
"title": "Turniirid",
"clickButton": "VAJUTA",
"register": "Registreeru",
"participants": "Osalejad",
"prizePool": "Auhinnafond",
@@ -157,8 +158,298 @@
"buyTicket": "OSTA PILET"
}
},
"cs2page": {
"title": "COUNTER-STRIKE 2 TURNIIR",
"buyTicket": "OSTA PILET",
"viewGithub": "TÄISREEGLID",
"nav": {
"intro": "Sissejuhatus",
"info": "Üldine info",
"prizes": "Auhinnafond",
"format": "Turniiri formaat",
"vrs": "VRS info",
"faq": "Korduma kippuvad küsimused",
"rules": "Reeglid"
},
"intro": {
"title": "SISSEJUHATUS",
"description": "TalTechis on korraldatud CS võistlusi nii CS1.6 kui ka CS:GOs juba ligi 20 aastat. TipiLAN korraldas esimese CS2 turniiri 2025. aastal oma debüütüritusel. TipiLAN 2025 CS turniir sai esimesena Eesti ajaloos jagada välja VRS punkte, saavutades Tier 2 Ranked turniiri staatuse. Kohal käis tiime Eestist, Lätist, Leedust, Soomest, Norrast ja Ukrainast, mis tõestas turniiri rahvusvahelist haaret ja tugevat konkurentsi.",
"previousWinners": "VARASEMAD VÕITJAD"
},
"info": {
"title": "ÜLDINE INFO",
"description": "TipiLAN 2026 CS2 turniir toimub 11.-13. septembril TalTechis, Tallinnas, Eestis. Tegemist on BYOC LAN turniiriga. Kohapeal pakutakse igale osalejale: laud, tool, võrgukaabliga internetiühendus, vooluühendus (2 pesa)."
},
"prizes": {
"title": "AUHINNAFOND",
"mainTitle": "PEATURNIIR - 6000€",
"mainNote": "Auhinnafondist väljaspoole jäävatele meeskondadele ja mängijatele lisahüvitisi ei pakuta.",
"secondTitle": "TEISE VÕIMALUSE TURNIIR - 750€",
"secondNote": "Auhinnafondist väljaspoole jäävatele meeskondadele ja mängijatele lisahüvitisi ei pakuta."
},
"format": {
"title": "TURNIIRI FORMAAT",
"description": "Terve turniir on BYOC (bring your own computer) LAN, kvalifikatsioone ei toimu.",
"day1": "Päev 1: 5 raundi Swiss stiilis turniiri (Bo1)",
"day23": "Päev 2 & 3: Double Elimination playoff'id (Winners' Bracket Bo3, Losers' Bracket Bo1)"
},
"vrs": {
"title": "VRS INFO, KUTSED",
"description1": "TipiLANi meeskond esitab HLTV-le avalduse, et turniiri tulemused läheksid VRS arvestusse kirja. HLTV rankingu staatust ei saa enne ametlikku kinnitust garanteerida. HLTV otsustab, millised mängud loevad VRS punktide arvestuses.",
"description2": "TipiLANi CS2 turniir jälgib Valve Ranked Tier 2 turniiri nõudeid. TipiLAN ei saada VRS kutseid meeskondadele."
},
"faq": {
"title": "KORDUMA KIPPUVAD KÜSIMUSED",
"q1": "KÜSIMUS?",
"a1": "Vastus"
},
"rules": {
"title": "REEGLID",
"description": "TipiLAN 2026 Counter-Strike 2 turniiri ametlikud reeglid.",
"contact": "Küsimuste korral võta ühendust:",
"contactName": "Harles Kadanik",
"contactRole": "Mänguvana - CS2 turniir",
"contactDiscord": "Discord: hrkruger",
"sections": [
{
"title": "Üldist",
"rules": [
"Counter-Strike 2 (edaspidi CS2) turniir toimub 11.-13. september, 2026 Tallinna Tehnikaülikooli (TalTech) ruumides, Ehitajate tee 5, Tallinn.",
{"main": "Turniiri auhinnafondiks on 6750€, mis jaguneb järgnevalt:", "sub": [{"main": "Põhiturniiri TOP 3 auhinnafond on 6000€:", "sub": ["Esimene koht - 600€ võistleja kohta (kokku 3000€)", "Teine koht - 400€ võistleja kohta (kokku 2000€)", "Kolmas koht - 200€ võistleja kohta (kokku 1000€)"]}, {"main": "Second Chance turniiri auhinnafond on 750€:", "sub": ["Esimene koht - 100€ võistleja kohta (kokku 500€)", "Teine koht - 50€ võistleja kohta (kokku 250€)"]}]},
{"main": "TipiLAN on Valve Tier 2 (No Invitations) nõuetele vastav võistlus.", "sub": ["Põhiturniiri 1.-3. koha tulemused esitatakse VRS-i arvutamiseks. HLTV.org (pärast meiepoolset taotlust) määrab, millised mängud lähevad VRS-i arvestusse. VRS punktide jagamist ei saa enne ametlikku kinnitust garanteerida."]},
{"main": "Võidusumma makstakse välja võistleja pangakontole 30 päeva jooksul.", "sub": ["Alaealise võistleja puhul makstakse võit vanema/eestkostja pangakontole."]},
"Terve turniiri vältel tuleb igal osalejal lähtuda Eesti Vabariigi seadusest, TipiLAN kodukorrast ja ürituse reeglistikust.",
"Piletiostuga annab iga osaleja loa end pildistada, filmida ja kasutada kogu fotograafilist, audio- ja videomaterjali ürituse jäädvustamiseks ja turundamiseks.",
"CS2 põhiturniiri salvestatakse ning kantakse üle voogedastusplatvormidel Twitch ja YouTube.",
"Kõik turniiriga seotud suhtlused tiimiliikmete vahel (nt mängusisene chat, häälvestlused, Discordi ja TeamSpeaki vestlused jne) salvestatakse.",
"Ise mängu üle kandmise puhul peab otseülekande viivis (delay) olema vähemalt 5 minutit.",
"Korraldajatel on õigus kasutada osalejate isiklikku informatsiooni vaid ürituse läbiviimise raames.",
"Korraldustiimil on õigus reegleid vajadusel muuta ja redigeerida etteteatamata, eeldusel et muudatused on kooskõlas Valve'i turniiride nõuetega.",
"Korraldustiim on kõikide osalejate suhtes erapooletu."
]
},
{
"title": "CS2 põhiturniiri tiim ja tiimi koosseis",
"rules": [
"CS2 põhiturniiri tiim (edaspidi tiim) põhikoosseisu kuulub viis põhiliiget, kellest üks on tiimikapten.",
"Hiljemalt 28. augustiks 2026 (kaks nädalat enne turniiri) peab iga tiim kinnitama oma osaluse, lõpliku tiimi põhikoosseisu ning tiimi nime.",
{"main": "Tiimikapten on tiimi esindaja, kes:", "sub": ["On kontaktisikuks korraldustiimile", "Registreerib tiimi turniirile", "Vastutab tiimi käitumise ja tegude eest", "Esindab tiimi hoiatuste, diskvalifikatsioonide, vaidlustuste ja timeout-ide korral"]},
{"main": "Igal tiimil võib olla üks varumängija, kes ei kuulu tiimi põhikoosseisu:", "sub": ["Varumängija peab soetama endale eraldi varumängija pileti", "Varumängija võib asendada ükskõik millist tiimi põhikoosseisu liiget turniiri toimumisel ajal", "Varumängijale kehtivad samad õigused ja nõuded, mis tiimi põhikoosseisule"]},
{"main": "Igal tiimil võib olla üks treener:", "sub": ["Treener peab ostma eraldi treeneri pileti", "Treener võib oma meeskonnaga suhelda ainult mängude vahel ja taktikaliste pauside ajal"]},
{"main": "Tiimi põhikoosseisus on lubatud välja vahetada mängijaid enne tiimide registreerimiskuupäeva lõppemist:", "sub": ["Mängijate väljavahetamine toimub läbi Fienta", "Liikme välja vahetamisel jääb tiimil jätkuvalt õigus varumängijale", "Asendusmängijale kehtivad samad õigused ja nõuded, mis tiimi põhikoosseisule"]},
"Tiimikapteni väljavahetamisel otsustab tiim ise, kellele tiimikapteni õigused ja kohustused tiimisiseselt üle kanduvad.",
"Kui tiim astub turniiril osalemisest tagasi enne registreerimistähtaega, makstakse osalemistasu tiimile tagasi.",
"Kõik tiimiliikmed võivad turniiril kuuluda vaid ühte tiimi korraga ja esindada vaid iseennast.",
"Kõik tiimiliikmed peavad päev enne turniiri algust olema vähemalt 16-aastased.",
"Mitte ükski tiimiliige ei tohi olla Venemaa Föderatsiooni ega Valgevene Rahvavabariigi kodanik.",
{"main": "Tiimidel pole lubatud:", "sub": ["Tiimisponsorite kajastamine turniiril", "Mängida teise tiimi või tiimiliikme huvides"]},
{"main": "Tiimi nimi:", "sub": ["Ei tohi olla solvav, vulgaarne, poliitiline või muud moodi maitsetu", "Ei tohi sisaldada emotikone ega muid sümboleid, mis pole tähemärgid", "Tuleb korraldustiimi poolsel nõudel ära muuta"]}
]
},
{
"title": "Varustus",
"rules": [
"Korraldustiimi poolt on turniiril osalevatele mängijatele tagatud internet, internetikaabel, pikendusjuhtmed ja istekoht lauaga.",
"Treeneritele ei tagata eraldi istekohta, lauapinda ega internetiühendust.",
"Turniiril osaleja vastutab selle eest, et temal on osalemiseks muu vajalik varustus kaasas ja töötab."
]
},
{
"title": "Ajakava",
"rules": [
"Kõik tiimiliikmed peavad kohal olema tund aega enne ettenähtud turniiri algust.",
"Mänguvoorus võistlevad tiimid peavad 10 minutit enne vooru algust olema valmis oma ettenähtud kohtadel.",
"Mänguvoorude algusajad on korraldustiimi välja pandud turniiri alguseks või eelmise mänguvooru lõpuks.",
"Kui mängijal esinevad tehnika või mänguga seotud tehnilised probleemid, peab ta sellest koheselt teavitama mänguvana või korraldustiimi.",
"Osalejatele tagatakse mängude vahel vähemalt 10-minutiline paus ja Bo3 mängude puhul kaartide vahel vähemalt 8-minutiline paus.",
"Korraldustiimil on õigus teha ajakavas muudatusi.",
"Korraldustiimil on kohustus hoida kõiki osalejaid kursis tekkinud viivituste ja muudatusega."
]
},
{
"title": "Mängu versioon ja seaded",
"rules": [
"Terve turniiri jooksul kasutatakse CS2 kõige uuemat versiooni.",
{"main": "CS2 turniiril kasutatakse järgnevaid seadeid:", "sub": ["Parim 24st (mp_maxrounds 24)", "Raundi aeg: 1 minut 55 sekundit (mp_roundtime 1.92)", "Alustusraha: $800 (mp_startmoney 800)", "Liikumise keelu aeg raundi alguses: 20 sekundit (mp_freezetime 20)", "Aeg ostmiseks: 20 sekundit (mp_buytime 20)", "Pommi taimer: 40 sekundit (mp_c4timer 40)", "Lisaajal raunde: parim kuuest (mp_overtime_maxrounds 6)", "Lisaaja alustusraha: $12,500 (mp_overtime_startmoney 12500)"]},
"Lisaaeg: juhul, kui pärast kõigi 24 raundi mängimist on viik, mängitakse lisaaega parim kuuest. Võistkonnad jätkavad lisaaegu, kuni võitja on leitud.",
"Paus: iga tiimil on lubatud kutsuda esile paus (timeout) 30 sekundit kuni 3 korda regulatsiooniraundide ajal. Pausi saavad kutsuda osalejad kirjutades mängusisesesse chatti \"!pause\".",
"Tehniline paus: igal tiimil on vajadusel õigus kasutada tehnilist pausi. Pausi alustamiseks tuleb mängusisesesse chatti sisestada käsklus \".tech\". Taktikaline suhtlus on kõigi tehniliste pauside ajal keelatud."
]
},
{
"title": "Kaardivalik & turniiri struktuur",
"rules": [
{"main": "32 meeskonnaga turniir toimub kahes etapis:", "sub": ["Swiss-süsteem: 5 roundi, algfaasis Bo1, otsustavad mängud Bo3. 3 võitu = playoffid (Top 16). 3 kaotust = Second Chance turniir.", "Playoffid: double elimination. Upper bracket Bo3, lower bracket Bo1, Lower finaal Bo3.", "Second Chance turniir: double elimination. Kõik mängud peale finaali Bo1, finaal Bo3."]},
{"main": "Seeding viiakse läbi vastavalt VRS-i järjestusele:", "sub": ["VRS edetabelis kohaga meeskonnad seeditakse kõrgemale kui edetabelikohata meeskonnad", "Ilma VRS edetabelikohata meeskondadele määratakse esmane paigutus juhuslikult", "Pärast esmast roundi jaotatakse tabeliseis vastavalt Buchholz süsteemile"]},
"Mängitav kaart valitakse välja hetkel aktiivsete Valve'i kaardigrupi kaartidest.",
{"main": "Bo1 kaardivalik:", "sub": ["Võistkond A eemaldab 2 kaarti", "Võistkond B eemaldab 3 kaarti", "Võistkond A eemaldab 1 kaardi", "Järelejäänud kaarti mängitakse"]},
{"main": "Bo3 kaardivalik:", "sub": ["Võistkond A eemaldab 1 kaardi", "Võistkond B eemaldab 1 kaardi", "Võistkond A valib 1 kaardi", "Võistkond B valib 1 kaardi", "Võistkond A eemaldab 1 kaardi", "Võistkond B eemaldab 1 kaardi", "Järelejäänud kaart on vajadusel otsustav"]}
]
},
{
"title": "CS2 turniiril keelatud tegevused",
"rules": [
"Igasugune sohitegemine, sealhulgas meetodid mis siin ei ole mainitud, on keelatud.",
"Skriptide kasutamine on keelatud (v.a. relvade/granaatide ostmine, hüppeviskamine).",
"Liikumine läbi seinte, põrandate ja katuste, k.a. taevas jalutamine (sky-walking) on keelatud.",
"Piksel-jalutamine (Pixel walking) ehk seismine, kükitamine, kõndimine nähtamatutel kaardipiiridel on keelatud.",
"Pomme tuleb asetada nii, et neid saaks desarmeerida.",
"Mängijatel ei ole lubatud armeeritud pommi asetada kohta, kus seda ei saa desarmeerida.",
"Mängijatel ei ole lubatud panna esemetele nimesid (nametags), mis rikuvad TipiLAN kodukorras väljatoodut.",
"Kohandatud mängufailid/andmed/draiverid ei ole lubatud.",
"Mängukarakteri mudelite (agent skins) kasutamine ei ole lubatud.",
"Mängusiseste vigade ära kasutamine on keelatud.",
"Igasugune tulemuste kokkuleppimine, mõjutamine, pettus ja manipuleerimine on rangelt keelatud ning tähendab kohest tiimi diskvalifitseerimist."
]
},
{
"title": "Karistused",
"rules": [
"Karistatav on mängusiseste ja mänguväliste reeglite ning kodukorra rikkumine.",
"Meeskonnad on kohustatud säilitama vähemalt 4 viiest algselt registreeritud mängijast kõigi mängude jaoks.",
"Reegleid rikkunud tiimiliikmele tehakse esmalt esimene verbaalne hoiatus. Teise rikkumise järel tehakse teine hoiatus. Kolmandal korral saab tiimiliige diskvalifikatsiooni.",
"Tiimiliige, kes ei ilmu turniiriks ega mänguvooruks kohale või lahkub turniiri ajal mõjuva põhjuseta, saab turniirilt diskvalifikatsiooni.",
"Tiimiliige, kes pole 10 minutit enne oma mänguvooru algust kohal (no-show olukord), saab turniirilt diskvalifikatsiooni.",
"Kui korraldustiim tuvastab punktis 7 väljatoodud rikkumise, diskvalifitseeritakse kogu tiim koheselt. Reegleid rikkunud mängijale antakse TipiLAN turniiridelt igavene mängukeeld.",
"Tiimil on õigus astuda turniiril osalemisest tagasi.",
"Tiimi diskvalifitseerimise korral võidab vastastiim automaatselt käesoleva mänguvooru.",
"Diskvalifitseerimise puhul ei tagastata osalustasu.",
{"main": "Ainult tiimikapten saab diskvalifitseerimist vaidlustada:", "sub": ["Vaidlustus tuleb esitada 15 minuti jooksul", "Korraldustiimil on aega kuni 25 minutit otsuse tegemiseks"]},
{"main": "Tiimidel on õigus esitada protest:", "sub": ["Protest tuleb esitada 5 minuti jooksul probleemi avastamisest", "Korraldustiimil on aega kuni 25 minutit otsuse tegemiseks"]},
"Mänguvana teavitab eksimusest, selle sisust ja tagajärjest reegleid rikkunud tiimiliiget, tema tiimi ja vastastiimi.",
"Korraldustiimil on õigus panna mänguvoor pausile ja lõpetada paus ükskõik millisel hetkel.",
"Korraldustiimil on kohustus kõikidest väljalangemistest ja diskvalifikatsioonidest avalikult teada anda."
]
}
]
}
},
"lolpage": {
"title": "LEAGUE OF LEGENDS TURNIIR",
"buyTicket": "OSTA PILET",
"nav": {
"intro": "Sissejuhatus",
"info": "Üldine info",
"prizes": "Auhinnafond",
"format": "Turniiri formaat",
"faq": "Korduma kippuvad küsimused",
"rules": "Reeglid"
},
"intro": {
"title": "SISSEJUHATUS",
"description": "TipiLAN korraldas esimese LoL turniiri 2025. aastal oma debüütüritusel. Kohal käis tiime nii Eestist kui ka Lätist.",
"previousWinners": "VARASEMAD VÕITJAD"
},
"info": {
"title": "ÜLDINE INFO",
"description": "TipiLAN 2026 LoL turniir toimub 11.-13. septembril TalTechis, Tallinnas, Eestis. Tegemist on BYOC LAN turniiriga. Kohapeal pakutakse igale osalejale: laud, tool, võrgukaabliga internetiühendus, vooluühendus (2 pesa)."
},
"prizes": {
"title": "AUHINNAFOND",
"mainTitle": "PEATURNIIR - 3000€",
"place1": "1. koht - 1500€, 300€ inimese kohta, 50% ehk 1/2 auhinnafondist.",
"place2": "2. koht - 1000€, 200€ inimese kohta, 33.3...(3)% ehk 1/3 auhinnafondist.",
"place3": "3. koht - 500€, 100€ inimese kohta, 16.6...(6)% ehk 1/6 auhinnafondist.",
"note": "Auhinnafondist väljaspoole jäävatele meeskondadele ja mängijatele lisahüvitisi ei pakuta."
},
"format": {
"title": "TURNIIRI FORMAAT",
"description": "Terve turniir on BYOC (bring your own computer) LAN, kvalifikatsioone ei toimu.",
"day1": "Päev 1: Round Robin kahes grupis, 5 mängu.",
"day2": "Päev 2: Single Elimination Playoff."
},
"faq": {
"title": "KORDUMA KIPPUVAD KÜSIMUSED",
"q1": "KÜSIMUS?",
"a1": "Vastus"
},
"rules": {
"title": "REEGLID",
"description": "TipiLAN 2026 League of Legends turniiri ametlikud reeglid.",
"contact": "Küsimuste korral võta ühendust:",
"contactName": "Nils-Hendrik Nõlvak",
"contactRole": "Mänguvana - LoL turniir",
"sections": [
{
"title": "Üldist",
"rules": [
"League of Legends (edaspidi LoL) turniir toimub kahepäevase üritusena 11.-13. september, 2026 Tallinna Tehnikaülikooli (TalTech) ruumides, Ehitajate tee 5, Tallinn.",
{"main": "Turniiri auhinnafondiks on 3000€, mis jaguneb järgnevalt:", "sub": ["Esimese koha saanud võistkond - 300€ võistleja kohta", "Teise koha saanud võistkond - 200€ võistleja kohta", "Kolmanda koha saanud võistkond - 100€ võistleja kohta"]},
{"main": "Võidusumma makstakse välja võistleja pangakontole.", "sub": ["Alaealise võistleja puhul makstakse võit vanema/eestkostja pangakontole."]}
]
},
{
"title": "Võistkonnad ja võistlejad",
"rules": [
{"main": "Võistkonnas peab olema:", "sub": ["Viis liiget (iga liige edaspidi eraldi kui Võistleja)", "Liikmetest üks on võistkonna Kapten, kes on ühtlasi kogu meeskonna eestkõnelejaks", "Kõik liikmed peavad olema võistkonna registreerumise hetkel vähemalt 16 aastat vanad", "Võistleja ei või olla Venemaa Föderatsiooni ega Valgevene Rahvavabariigi kodanik", "Võistkonnal pole lubatud kasutada turniiri jooksul treenerit", "Lubatud välja vahetada üks võistkonna liige, kes peab samuti olema registreeritud ja füüsiliselt kohal"]},
"Võistleja peab esitama enda kohta ainult tõest informatsiooni ning valmis Korraldajale tõendama enda isikut.",
"Võistkonna nimi ja logo ning Võistleja arvutimängu alias ja avatar peab olema sünnis, sh ei tohi olla kohatu, sisaldada roppusi, vulgaarsusi, poliitilisi või religioosseid sõnumeid ega sümboleid.",
"Võistleja esindab terve Turniiri vältel ainult iseennast (st. enda asemel ei või lasta kellelgi teisel võistelda).",
"Kõik alla 18-aastased Võistlejad on valmis Korraldajale esitama eestkostja nõusoleku turniiril osalemiseks.",
"Võistleja peab olema kogu turniiri vältel viisakas ning austama kaasvõistlejaid, korraldajaid ning külastajaid. TipiLAN ei tolereeri vihakõne, ahistamist, ähvardavat, solvavat või agressiivset käitumist.",
"Võistkond peab olema registreeritud nii TipiLAN lehel kui ka challengermode turniirilehel."
]
},
{
"title": "Mängule eelnev",
"rules": [
{"main": "Turniiril osalemine, matchid ning turniiripuu toimib kõik läbi challengermode.com keskkonna.", "sub": ["Turniirile peab olema registreeritud kogu meeskond, kaasa arvatud varumängija", "Mängijatel peab challengermodes olema linkitud kõige kõrgema rankiga kasutaja", "Turniir toimub EU West serveris", "Mängijad ei tohi kasutada ühtegi teist kasutajat peale challengermodes linkitud kasutajate"]},
"Challengermode keskkonnas on matchid automaatsed. Uue matchi puhul on valmisolekuks aega 10 minutit.",
{"main": "Draft saab alata kui mõlemad pooled on andnud enda valmisolekust märku.", "sub": ["Placeholderid ei ole lubatud. Kui champion on draftis lukustatud, peab seda ka mängima", "Enne drafti peavad mängijad olema rollidele vastavas järjekorras: Top-Jungle-Mid-Bot-Support", "Sihilikult viivitamine ei ole lubatud"]},
"Matchi lobbysse tohivad lisaks mängijatele liituda ainult ametlikud streamerid ja kohtunikud."
]
},
{
"title": "Mängusisesed protseduurid",
"rules": [
{"main": "Mäng on ametlikult alanud (game of record) kui kõik 10 mängijat on kaardil ning mäng on jõudnud esimese reaalse interaktsioonini. GOR'i tingimused:", "sub": ["Kummalgi tiimil õnnestub rünnak või võime kasutamine", "Vastased näevad teineteist", "Sisenetakse vastase territooriumile", "Mäng on kestnud 2 minutit"]},
{"main": "Mängu seiskamine:", "sub": ["Mängu pausile panemise ajal ei ole mängijatel lubatud lahkuda matši alalt", "Korraldajad võivad mängu pausile panna vastavalt vajadusele", "Kummalgi tiimil on õigus matši jooksul võtta kokku kuni 15 minutit pausi mõjuval põhjusel"]},
"Mängu võib uuesti käima panna ainult mõlema poole nõusolekul või kohtuniku loal.",
"Kui tekib mängu ausal läbiviimisel takistus (gamebreaking bug, netiühendus, etc.), määrab kohtunik uued juhised mängu läbiviimiseks."
]
},
{
"title": "Match'i lõpetamine",
"rules": [
{"main": "Match'i võitja on tiim, kellel on kõige rohkem mänge võidetud.", "sub": ["Korraldaja esitab tiimide võitude ja kaotuste seisud kõigile osalejatele kättesaadaval viisil", "Peale igat match'i uuendatakse challengermode keskkonnas turniiripuud"]}
]
},
{
"title": "Turniirilt välja langemine",
"rules": [
"Tiim võib igal ajal otsustada lõpetada turniiril osalemise andes sellest teada kohtunikule ja/või korraldajale.",
"Kuni välja kukkumiseni teenitud karistused jäävad kehtima turniiri lõpuni.",
"Kui tiim ei ilmu kohale või pole kokku lepitud algusajaks valmis, võib Korraldaja arvata tiimi turniirilt välja.",
{"main": "Tiimi registreerunute nimekirja ei saa muuta turniiri vältel.", "sub": ["Kui liikme lahkumise tõttu langeb tiimis osalejate arv alla mängimiseks vajaliku, peab Korraldaja tiimi turniirilt välja arvama"]},
"Kui tiim soovib välja langeda match'i toimumise ajal, peab tiim andma loobumisvõidu.",
"Kõik välja langemised ja välja arvamised tuleb teha koheselt avalikult teatavaks."
]
},
{
"title": "Karistused",
"rules": [
"Kohtunikud määravad karistusi järgides selles dokumendis toodud juhiseid.",
"Karistusi võivad määrata ainult kohtunikud.",
"Kohtunik teavitab nii eksimuse sisu kui ka määratud karistuse nii reeglite vastu eksinud mängijale, tema tiimile kui ka vastasvõistkonnale.",
"Kohtunik peab olema erapooletu, tiimi oskuste tase ei tohi olla määravaks eksimuste ja karistuste jälgimisel.",
"Karistusi võib määrata nii kogu tiimile kui ka ühele tiimiliikmele.",
{"main": "Karistused võivad olla järgnevad:", "sub": ["HOIATUS: märguanne mängijale või tiimile väikese eksimuse eest", "BAN'i KAOTUS: Tiim ei või karistusele järgneval mängul ban'ida kindel arv tegelasi", "MÄNGU KAOTUS: Tiim saab automaatse kaotuse ühel mängul", "MATCH'I KAOTUS: Tiim saab automaatse match'i kaotuse", "DISKVALIFITSEERIMINE: Diskvalifikatsioon kehtib tervele tiimile"]},
{"main": "Mittesobilik käitumine jagunevad:", "sub": ["KERGE EKSIMUS: ebameeldiv, ebaeetiline või häiriv käitumine - karistus hoiatus", "KESKMINE EKSIMUS: juhiste eiramine, vihakõne, agressiivsus - karistus mängu kaotus", "RASKE EKSIMUS: selgelt vastuolus reeglite ning heade tavadega - karistus diskvalifikatsioon", "KOKKUMÄNG: kahe tiimi vaheline kokkulepe - karistus mõlema tiimi diskvalifitseerimine", "ALTKÄEMAKS JA PANUSTAMINE: keelatud - karistus diskvalifitseerimine", "AGRESSIIVNE KÄITUMINE: inimeste vastu suunatud agressioon - karistus diskvalifitseerimine", "SOHK: teadlik tegevus eelise saavutamiseks - karistus diskvalifitseerimine"]}
]
},
{
"title": "Turniiri formaat",
"rules": [
"Turniir toimub Fearless drafti põhimõtetel. See tähendab, et seeria jooksul pickitud champione ei saa pickida järgmistes mängudes kuni seeria lõpuni.",
{"main": "Turniir toimub Round Robin + Single Elimination formaadis:", "sub": ["Esimene round on 2 kuueliimelist gruppi, kus kõik tiimid mängivad üksteisega korra läbi", "Sellega selgitatakse 4 parimat, kes lähevad edasi järgmise päeva single elimination bracketisse", "Gruppides tekkinud viigi korral pääseb edasi võistkond, kes viigistunud tiimide vahelise matchi võitis"]}
]
}
]
}
},
"schedule": {
"title": "Ajakava",
"comingSoon": "Tuleb hiljem",
"day": "Päev",
"time": "Aeg",
"event": "Sündmus",
@@ -228,6 +519,7 @@
},
"expo": {
"title": "Messiala",
"comingSoon": "Tuleb hiljem",
"description": "TipiLANi messialal paiknevad ettevõtted, lisategevused ja toimuvad loengud.",
"areas": {
"bar": "Baar",