mirror of
https://github.com/Lapikud/lapikud.github.io.git
synced 2026-08-09 01:59:14 +00:00
main page, navbar mobile not fixed
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
146
src/components/FeatureCard.svelte
Normal file
146
src/components/FeatureCard.svelte
Normal 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>
|
||||
@@ -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'
|
||||
|
||||
84
src/components/layout/Section.svelte
Normal file
84
src/components/layout/Section.svelte
Normal 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>
|
||||
Reference in New Issue
Block a user