main page, navbar mobile not fixed

This commit is contained in:
Henri
2026-01-21 12:36:53 +02:00
parent 490d9b2feb
commit cf8b623340
11 changed files with 546 additions and 108 deletions

View File

@@ -6,10 +6,18 @@
:root {
/* color tokens (light defaults) */
--orange: #f0941d;
--orange-light: #ffa940;
--orange-dark: #d67d0a;
--black: #000000;
--off-black: #0d0d0d;
--white: #ffffff;
--off-white: #fffdfa;
--gray-50: #fafafa;
--gray-100: #f5f5f5;
--gray-200: #e5e5e5;
--gray-300: #d4d4d4;
--gray-800: #262626;
--gray-900: #171717;
/* layout tokens */
--site-padding: clamp(1rem, 2vw, 2rem); /* horizontal page padding */
@@ -30,8 +38,12 @@
--radius-sm: 6px;
--radius-md: 10px;
--radius-lg: 14px;
--radius-xl: 20px;
--shadow-1: 0 1px 2px rgba(240, 148, 29, 0.2),
0 1px 3px rgba(240, 148, 29, 0.12);
--shadow-2: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
--shadow-3: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
--shadow-glow: 0 0 20px rgba(240, 148, 29, 0.3);
/* breakpoints */
--bp-sm: 480px;
@@ -72,6 +84,7 @@ html {
-moz-osx-font-smoothing: grayscale;
font-size: var(--fs-base);
-webkit-text-size-adjust: 100%;
overflow-x: hidden;
}
body {
margin: 0;
@@ -81,7 +94,8 @@ body {
min-height: 100vh;
-webkit-tap-highlight-color: transparent;
transition: background-color 160ms ease, color 160ms ease;
padding-top: 20px;
overflow-x: hidden;
font-size: var(--fs-lg);
}
/* Container pattern */
@@ -108,24 +122,6 @@ body {
}
}
/* Headings & paragraph scale */
h1 {
font-size: clamp(1.5rem, 2.8vw, 2.25rem);
margin: 0 0 var(--space-3) 0;
line-height: 1.08;
}
h2 {
font-size: clamp(1.25rem, 2.1vw, 1.75rem);
margin: 0 0 var(--space-3) 0;
}
h3 {
font-size: var(--fs-lg);
margin: 0 0 var(--space-2) 0;
}
p {
margin: 0 0 var(--space-3) 0;
color: var(--color-text);
}
/* Basic link & button defaults that components inherit */
a {

View File

@@ -1,10 +1,17 @@
<script>
// Handler and presentation props
export let onClick = () => {};
export let border = false;
export let textAlign = "left";
export let whiteSpace = "nowrap";
</script>
<button onclick={onClick} class="btn" class:borderless={!border} {...$$restProps}>
<button
onclick={onClick}
class="btn"
class:borderless={!border}
style={`text-align: ${textAlign}; white-space: ${whiteSpace};`}
{...$$restProps}
>
<slot />
</button>

View File

@@ -0,0 +1,146 @@
<script>
export let title = "";
export let description = "";
export let icon = null;
export let href = "";
export let variant = "default"; // 'default' | 'elevated' | 'bordered' | 'glass'
export let iconColor = "var(--orange)";
export let className = "";
const variantClasses = {
default: "card-default",
elevated: "card-elevated",
bordered: "card-bordered",
glass: "card-glass",
};
</script>
{#if href}
<a {href} class={`feature-card ${variantClasses[variant]} ${className}`}>
{#if icon}
<div class="feature-icon" style="color: {iconColor}">
<svelte:component this={icon} size={32} strokeWidth={1.5} />
</div>
{/if}
{#if title}
<h3 class="feature-title">{title}</h3>
{/if}
{#if description}
<p class="feature-description">{description}</p>
{/if}
<div class="feature-content">
<slot />
</div>
</a>
{:else}
<div class={`feature-card ${variantClasses[variant]} ${className}`}>
{#if icon}
<div class="feature-icon" style="color: {iconColor}">
<svelte:component this={icon} size={32} strokeWidth={1.5} />
</div>
{/if}
{#if title}
<h3 class="feature-title">{title}</h3>
{/if}
{#if description}
<p class="feature-description">{description}</p>
{/if}
<div class="feature-content">
<slot />
</div>
</div>
{/if}
<style>
.feature-card {
position: relative;
padding: var(--space-5);
border-radius: var(--radius-lg);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: block;
text-decoration: none;
color: inherit;
}
.feature-card:hover {
transform: translateY(-4px);
}
a.feature-card:hover {
text-decoration: none;
}
.card-default {
background: var(--white);
border: 1px solid var(--gray-200);
}
.card-default:hover {
box-shadow: var(--shadow-2);
border-color: var(--orange);
}
.card-elevated {
background: var(--white);
box-shadow: var(--shadow-2);
border: 1px solid transparent;
}
.card-elevated:hover {
box-shadow: var(--shadow-3);
border-color: var(--orange);
}
.card-bordered {
background: transparent;
border: 2px solid var(--gray-200);
}
.card-bordered:hover {
border-color: var(--orange);
background: var(--gray-50);
}
.card-glass {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.card-glass:hover {
background: rgba(255, 255, 255, 0.9);
box-shadow: var(--shadow-glow);
}
.feature-icon {
margin-bottom: var(--space-3);
display: inline-flex;
}
.feature-title {
font-size: var(--fs-xl);
font-weight: 700;
margin-bottom: var(--space-2);
color: var(--black);
}
.feature-description {
color: var(--gray-800);
line-height: 1.6;
margin-bottom: var(--space-3);
}
.feature-content {
margin-top: var(--space-3);
}
@media (max-width: 768px) {
.feature-card {
padding: var(--space-4);
}
.feature-title {
font-size: var(--fs-lg);
}
}
</style>

View File

@@ -3,6 +3,9 @@ export { default as Card } from './layout/Card.svelte'
export { default as Stack } from './layout/Stack.svelte'
export { default as Grid } from './layout/Grid.svelte'
export { default as Center } from './layout/Center.svelte'
export { default as Section } from './layout/Section.svelte'
export { default as FullWidthBanner } from './layout/FullWidthBanner.svelte'
export { default as Button } from './Button.svelte'
export { default as Dropdown } from './Dropdown.svelte'
export { default as FeatureCard } from './FeatureCard.svelte'

View File

@@ -0,0 +1,84 @@
<script>
export let background = "transparent"; // CSS color code or color variable name from app.css
export let padding = "normal"; // 'none' | 'small' | 'normal' | 'large'
export let fullWidth = false;
export let id = "";
export let className = "";
const paddingClasses = {
none: "py-0",
small: "py-section-sm",
normal: "py-section",
large: "py-section-lg",
};
// Convert background to appropriate CSS value
$: backgroundStyle = (() => {
if (!background || background === "transparent") return "";
// If it starts with # or rgb/rgba or hsl, it's a direct color
if (background.startsWith("#") || background.startsWith("rgb") || background.startsWith("hsl")) {
return background;
}
// Otherwise treat as CSS variable name
return `var(--${background})`;
})();
</script>
<section
{id}
class={`section ${paddingClasses[padding]} ${className}`}
style={backgroundStyle ? `background: ${backgroundStyle};` : ""}
>
<div class="section-inner" class:full-width={fullWidth}>
<slot />
</div>
</section>
<style>
.section {
width: 100%;
position: relative;
}
.section-inner {
max-width: var(--content-max);
margin: 0 auto;
padding: 0 var(--site-padding);
}
.section-inner.full-width {
max-width: none;
}
.py-0 {
padding-top: 0;
padding-bottom: 0;
}
.py-section-sm {
padding-top: var(--space-5);
padding-bottom: var(--space-5);
}
.py-section {
padding-top: var(--space-6);
padding-bottom: var(--space-6);
}
.py-section-lg {
padding-top: clamp(3rem, 8vw, 6rem);
padding-bottom: clamp(3rem, 8vw, 6rem);
}
@media (max-width: 768px) {
.py-section {
padding-top: var(--space-5);
padding-bottom: var(--space-5);
}
.py-section-lg {
padding-top: var(--space-6);
padding-bottom: var(--space-6);
}
}
</style>

View File

@@ -3,7 +3,7 @@
Button,
Dropdown,
Grid,
Center,
Section,
} from "$components";
import { navigate, getPath, currentLang, text, switchLang } from "$lib";
@@ -18,50 +18,49 @@
import Trophy from "lucide-svelte/icons/trophy";
</script>
<Grid>
<nav class="w-full h-32">
<Center gapClass="gap-4">
<Dropdown name={$text.nav.about} variant="borderless">
<Button onClick={() => navigate("/mis-teeme")}
>{$text.nav.aboutPages.info}</Button
>
<Button onClick={() => navigate("/liitu-meiega")}
><Bot />{$text.nav.aboutPages.join}</Button
>
<Button onClick={() => navigate("/mentorid")}
><HandHeart />{$text.nav.aboutPages.mentors}</Button
>
<Button onClick={() => navigate("/juhatus")}
><Lectern />{$text.nav.aboutPages.board}</Button
>
</Dropdown>
<Dropdown name={$text.nav.events} variant="borderless">
<Button onClick={() => navigate("/kalender")}
><CalendarClock />{$text.nav.eventsPages.calendar}</Button
>
<Button
onClick={() => navigate("https://asikarikas.ee/", { external: true })}
><Trophy />ASI Karikas</Button
>
<Button onClick={() => navigate("/mentorid")}
><Presentation />{$text.nav.eventsPages.workshops}</Button
>
<Button onClick={() => navigate("/rebased")}
><Swords />{$text.nav.eventsPages.fresh}</Button
>
<Button
onClick={() =>
navigate("https://remondikohvik.lapikud.ee/", { external: true })}
><Coffee />{$text.nav.eventsPages.repair}</Button
>
</Dropdown>
<Button onClick={() => navigate("/kontakt")}
>{$text.nav.contact}
</Button>
<Button onClick={() => navigate("/helpdesk")}
>{$text.nav.helpdesk}
</Button>
</Center>
</nav>
</Grid>
<Section padding="small">
<Grid>
<nav class="z-10 flex gap-4 justify-end text-xl">
<Dropdown name={$text.nav.about} variant="borderless">
<Button onClick={() => navigate("/mis-teeme")}
>{$text.nav.aboutPages.info}</Button
>
<Button onClick={() => navigate("/liitu-meiega")}
><Bot />{$text.nav.aboutPages.join}</Button
>
<Button onClick={() => navigate("/mentorid")}
><HandHeart />{$text.nav.aboutPages.mentors}</Button
>
<Button onClick={() => navigate("/juhatus")}
><Lectern />{$text.nav.aboutPages.board}</Button
>
</Dropdown>
<Dropdown name={$text.nav.events} variant="borderless">
<Button onClick={() => navigate("/kalender")}
><CalendarClock />{$text.nav.eventsPages.calendar}</Button
>
<Button
onClick={() => navigate("https://asikarikas.ee/", { external: true })}
><Trophy />ASI Karikas</Button
>
<Button onClick={() => navigate("/mentorid")}
><Presentation />{$text.nav.eventsPages.workshops}</Button
>
<Button onClick={() => navigate("/rebased")}
><Swords />{$text.nav.eventsPages.fresh}</Button
>
<Button
onClick={() =>
navigate("https://remondikohvik.lapikud.ee/", { external: true })}
><Coffee />{$text.nav.eventsPages.repair}</Button
>
</Dropdown>
<Button onClick={() => navigate("/kontakt")}
>{$text.nav.contact}
</Button>
<Button onClick={() => navigate("/helpdesk")}
>{$text.nav.helpdesk}
</Button>
</nav>
</Grid>
</Section>

View File

@@ -1,44 +1,207 @@
<script>
import {
Button,
Container,
Card,
Stack,
Section,
Grid,
Card,
Center,
FeatureCard,
} from "$components";
import { navigate } from "$lib";
// Import Lucide icons
import Wrench from "lucide-svelte/icons/wrench";
import Users from "lucide-svelte/icons/users";
import HeartHandshake from "lucide-svelte/icons/heart-handshake";
import ArrowRight from "lucide-svelte/icons/arrow-right";
// Partners data
const partners = [
{ name: "Tehnopol", image: "tehnopollogo.png", url: "https://www.tehnopol.ee/" },
{ name: "Tallinna Tehnikaülikool", image: "taltech_logo.jpg", url: "https://www.ttu.ee/" },
{ name: "Eesti Üliõpilaskondade Liit", image: "eyl_logo.png", url: "https://eyl.ee/" },
{ name: "Tallinna Tehnikaülikooli Robotiklubi", image: "robotiklubi_logo.png", url: "https://www.robotiklubi.ee/" },
{ name: "TalTech IT teaduskond", image: "taltech_IT_teaduskond_logo.png", url: "https://taltech.ee/et/infotehnoloogia-teaduskond" },
{ name: "HexTech Solutions", image: "hextech_logo.svg", url: "https://hextech.ee/" },
{ name: "EAS & MKM", image: "eas.svg", url: "https://eis.ee/" },
];
</script>
<Container>
<Stack gap="var(--space-6)">
<Card>
<h1>Kes me oleme?</h1>
<p>
Organisatsioon loodi 2002. aastal informaatika tudengite poolt, kelle
erialatunnuseks oli “LAP”. Targad mehed otsustasid, et järelikult on nad
Lapikud”.
</p>
<Button href="/docs/getting-started">Get Started</Button>
<Button href="/docs/components">Explore Components</Button>
</Card>
<!-- Header Section -->
<Section background="orange">
<Grid>
<Center>
<img src="/assets/LAP_logo_v3_transp.png" alt="MTÜ Lapikud" class="max-w-md w-full h-auto" style="padding: var(--space-4);"/>
</Center>
<p class="text-3xl leading-relaxed" style="padding: var(--space-4);">
MTÜ Lapikud on Tallinna Tehnikaülikooli Tarkvaraarendusklubi, mis ühendab endisi
ja praegusi IT huvilisi tudengeid.
</p>
</Grid>
</Section>
<Grid min="250px" gap="var(--space-4)">
<Card>
<h2>Mis on HELPDESK?</h2>
<p>
HELPDESK on MTÜ Lapikute poolt pakutav arvutiabiteenus. Teenus on
suunatud tudengitele, õppejõududele ning kõikidele huvilistele ka
väljaspool Tallinna Tehnikaülikooli. Meie meeskond koosneb kogenud ja
nutikatest Tallinna Tehnikaülikooli IT-tudengitest.
</p>
</Card>
<Card>
<h2>Mis teenuseid osutame?</h2>
<p>
Arvuti riistvara diagnostika ja remont Arvuti riistvara hooldus
Tarkvara diagnostika ja seadistamine Tarkvara paigaldamine Muu
elektroonika parandamine
</p>
</Card>
</Grid>
</Stack>
</Container>
<Section>
<Grid gap="var(--space-5)">
<FeatureCard
variant="bordered"
href="/liitu-meiega"
icon={Users}
iconColor="var(--orange)"
title="Tudengile"
description="Tule arenda oma oskuseid ja saa ägedaid sõpru! Omanda praktilist kogemust reaalsetest projektidest."
>
<div style="color: var(--orange)" class="mt-4 font-semibold flex items-center gap-2">
Liitu meiega <ArrowRight size={16} />
</div>
</FeatureCard>
<FeatureCard
variant="bordered"
href="/helpdesk"
icon={Wrench}
iconColor="var(--orange)"
title="Helpdesk"
description="HELPDESK on MTÜ Lapikute poolt pakutav arvutiabiteenus. Teenus on suunatud tudengitele, õppejõududele ning kõikidele huvilistele."
>
<div style="color: var(--orange)" class="mt-4 font-semibold flex items-center gap-2">
Vaata teenuseid <ArrowRight size={16} />
</div>
</FeatureCard>
<FeatureCard
variant="bordered"
href="/ourwork"
icon={HeartHandshake}
iconColor="var(--orange)"
title="Ettevõttele"
description="Aitame sinu ideed ellu viia! Meie kogenud tudengid on valmis teie projekte realiseerima."
>
<div style="color: var(--orange)" class="mt-4 font-semibold flex items-center gap-2">
Tehtud tööd <ArrowRight size={16} />
</div>
</FeatureCard>
</Grid>
</Section>
<!-- What We Do Section -->
<Section>
<Grid gap="var(--space-4)">
<Card>
<h2 class="pb-4 text-4xl font-bold">Mida me loome</h2>
<p>Meie põhieesmärgiks on Tallinna Tehnikaülikooli IT tudengitele erialase lisandväärtuse loomine. Kaasame tudengeid praktilistesse lahendustesse, kus saab ideid reaalselt ellu viia ja oma oskusi päriselt kasutada. Meie projektidest kasvavad välja huvitavad ja tarvilikud lõputööd, millel on selge praktiline väärtus.</p>
</Card>
<Card>
<h2 class="pb-4 text-4xl font-bold">Keda ja kuidas kaasame</h2>
<p>Pakume nutikatele ja motiveeritud tudengitele võimalust saada meie juures esimene töökogemus ning arendada end meeskonnas töötades. Lapikud ei ole ainult IT-tudengite organisatsioon, kaasame projektidesse ka majandusteaduskonna tudengeid, et tehniliste lahenduste kõrval oleks esindatud ka äriline vaade.</p>
</Card>
</Grid>
</Section>
<!-- Partners Section -->
<Section>
<div class="text-center mb-12">
<h2 class="text-3xl">
Koostööpartnerid
</h2>
</div>
<Grid gap="var(--space-4)">
{#each partners as partner}
{#if partner.url}
<a href={partner.url} target="_blank" rel="noopener noreferrer" class="partner-item" title={partner.name}>
{#if partner.image}
<img src="/assets/partners/{partner.image}" alt={partner.name} />
{:else}
<span class="partner-name">{partner.name}</span>
{/if}
</a>
{:else}
<div class="partner-item">
{#if partner.image}
<img src="/assets/partners/{partner.image}" alt={partner.name} />
{:else}
<span class="partner-name">{partner.name}</span>
{/if}
</div>
{/if}
{/each}
</Grid>
</Section>
<style>
.partner-item {
display: flex;
align-items: center;
justify-content: center;
padding: var(--space-3);
border-radius: var(--radius-md);
background: var(--white);
border: 1px solid var(--gray-200);
transition: all 0.3s ease;
text-decoration: none;
width: 100%;
height: 100px;
}
a.partner-item:hover {
transform: scale(1.05);
box-shadow: var(--shadow-2);
border-color: var(--orange);
}
.partner-item img {
max-width: 100%;
max-height: 60px;
object-fit: contain;
filter: grayscale(100%);
opacity: 0.7;
transition: all 0.3s ease;
}
a.partner-item:hover img {
filter: grayscale(0%);
opacity: 1;
}
.partner-name {
font-size: var(--fs-sm);
font-weight: 600;
color: var(--gray-800);
text-align: center;
}
</style>
<!-- EIS Project Highlight -->
<Section background="dark" padding="large">
<div class="text-center text-white">
<h2 class="mb-8 text-white">
EIS Projekt
</h2>
<p class="text-lg max-w-4xl mx-auto mb-8 leading-relaxed text-white/90">
MTÜ Lapikud projekti "Mobiilne Droonituvastussüsteem" rahastatakse riigieelarvest
teadus- ja arendustegevuse rahastamise vahenditest 100 000 € ulatuses, eesmärgiga
luua füüsilised droonituvastusseadmed, mis tagavad kasutajale droonialase olukorra teadlikkuse.
</p>
<p class="max-w-3xl mx-auto leading-relaxed text-white/80">
Projekti lõpptulemusena valmib kaks teineteisest eraldiseisvat seadet
spektrianalüüsi ning Direct Remote Identification tööpõhimõttel toimivad seadmed.
</p>
</div>
</Section>
<!-- CTA Section -->
<Section background="gray" padding="large">
<div class="text-center">
<h2 class="mb-8">
Valmis liituma?
</h2>
<div class="flex gap-4 justify-center flex-wrap">
<Button onClick={() => navigate("/kontakt")} border>
Võta ühendust
</Button>
<Button onClick={() => navigate("/mis-teeme")} border>
Loe rohkem
</Button>
</div>
</div>
</Section>

View File

@@ -2,9 +2,7 @@
// examples: '/page', '/page/:id'
import Home from './Home.svelte'
import Test from './Test.svelte'
export const routes = {
'/': Home,
'/juhatus': Test,
}