commit d2a5fe5afd43bb968dfd5e0d422544b79e3432bd Author: invosset Date: Sun Jun 21 11:43:36 2026 +0800 Initial commit: add FothiFihaara landingpage diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd6810e --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# FothiFihaara.com Landing Page + +A premium black/white landing page for FothiFihaara.com, a directory of textile materials, tools, and services. + +## Preview locally + +Open `index.html` in any web browser. + +## Features + +- Dark and light mode toggle +- Scroll reveal animations +- Responsive layout +- Placeholder directory cards + +## Deployment + +This site is deployed via Coolify from the `master` branch on Forgejo. diff --git a/images/materials.webp b/images/materials.webp new file mode 100644 index 0000000..0d084fc Binary files /dev/null and b/images/materials.webp differ diff --git a/images/services.webp b/images/services.webp new file mode 100644 index 0000000..868e9ae Binary files /dev/null and b/images/services.webp differ diff --git a/images/tools.webp b/images/tools.webp new file mode 100644 index 0000000..2745476 Binary files /dev/null and b/images/tools.webp differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..cb557ae --- /dev/null +++ b/index.html @@ -0,0 +1,123 @@ + + + + + + FothiFihaara.com — Textile Materials, Tools & Services + + + + + + +
+
+
+

The textile network

+

A directory of textile
materials, tools, and services

+

Connecting suppliers and makers in one curated place.

+ +
+
+ +
+
+

Directory Preview

+
+
+ Textile materials preview +
+ Materials +

Premium Cotton Blends

+

Supplier: Nordic Textiles

+
+
+
+ Textile tools preview +
+ Tools +

Industrial Looms

+

Service: WeaveTech

+
+
+
+ Textile services preview +
+ Services +

Dyeing & Finishing

+

Supplier: ColorWorks

+
+
+
+
+
+ +
+
+

Why Join?

+
+
+
+

Reach buyers

+

Get discovered by makers actively looking for suppliers.

+
+
+
+

Premium placement

+

Curated listings, not a crowded marketplace.

+
+
+
+

Direct contact

+

Visitors reach you via your preferred messaging app.

+
+
+
+
+ +
+
+

Ready to list your business?

+

Send us a message and we will guide you through the process.

+ Contact us + +
+
+
+ + + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..891970d --- /dev/null +++ b/script.js @@ -0,0 +1,75 @@ +// Theme toggle with localStorage +const themeToggle = document.getElementById('theme-toggle'); +const html = document.documentElement; +const savedTheme = localStorage.getItem('theme'); + +function applyTheme(theme) { + if (theme === 'light') { + html.setAttribute('data-theme', 'light'); + themeToggle.textContent = '☀'; + themeToggle.setAttribute('aria-label', 'Switch to dark mode'); + } else { + html.removeAttribute('data-theme'); + themeToggle.textContent = '☾'; + themeToggle.setAttribute('aria-label', 'Switch to light mode'); + } +} + +if (savedTheme) { + applyTheme(savedTheme); +} + +themeToggle.addEventListener('click', () => { + const current = html.getAttribute('data-theme'); + const next = current === 'light' ? 'dark' : 'light'; + applyTheme(next); + localStorage.setItem('theme', next); +}); + +// Dynamic current year in footer +const yearSpan = document.getElementById('current-year'); +if (yearSpan) { + yearSpan.textContent = new Date().getFullYear(); +} + +// Scroll reveal animation +const revealElements = document.querySelectorAll('section'); + +const revealObserver = new IntersectionObserver((entries) => { + entries.forEach((entry, index) => { + if (entry.isIntersecting) { + setTimeout(() => { + entry.target.classList.add('visible'); + }, index * 80); + revealObserver.unobserve(entry.target); + } + }); +}, { + threshold: 0.15, + rootMargin: '0px 0px -40px 0px' +}); + +revealElements.forEach((el) => { + el.classList.add('reveal'); + revealObserver.observe(el); +}); + +// Stagger cards inside directory preview +const cards = document.querySelectorAll('.card'); +const cardObserver = new IntersectionObserver((entries) => { + entries.forEach((entry, index) => { + if (entry.isIntersecting) { + setTimeout(() => { + entry.target.classList.add('visible'); + }, index * 120); + cardObserver.unobserve(entry.target); + } + }); +}, { + threshold: 0.2 +}); + +cards.forEach((card) => { + card.classList.add('reveal'); + cardObserver.observe(card); +}); diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..40a1279 --- /dev/null +++ b/styles.css @@ -0,0 +1,377 @@ +:root { + --bg: #0a0a0a; + --surface: #111; + --surface-2: #1a1a1a; + --text: #f5f5f5; + --text-muted: #888; + --border: #222; + --accent: #fff; +} + +[data-theme="light"] { + --bg: #fafafa; + --surface: #fff; + --surface-2: #f2f2f2; + --text: #111; + --text-muted: #666; + --border: #e5e5e5; + --accent: #000; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background-color: var(--bg); + color: var(--text); + line-height: 1.6; + transition: background-color 0.3s ease, color 0.3s ease; +} + +.container { + width: 90%; + max-width: 1100px; + margin: 0 auto; + padding: 0 1rem; +} + +.site-header { + padding: 1.25rem 0; + border-bottom: 1px solid var(--border); + background-color: var(--bg); + position: sticky; + top: 0; + z-index: 100; +} + +.header-inner { + display: flex; + justify-content: space-between; + align-items: center; +} + +.brand { + font-size: 1.125rem; + font-weight: 500; + color: var(--text); + text-decoration: none; + letter-spacing: 0.01em; +} + +.main-nav { + display: flex; + align-items: center; + gap: 1.5rem; +} + +.main-nav a { + color: var(--text-muted); + text-decoration: none; + font-size: 0.9rem; + transition: color 0.2s ease; +} + +.main-nav a:hover { + color: var(--text); +} + +.theme-toggle { + background: transparent; + border: 1px solid var(--border); + color: var(--text); + width: 2rem; + height: 2rem; + border-radius: 50%; + cursor: pointer; + font-size: 1rem; + line-height: 1; + transition: transform 0.2s ease, border-color 0.2s ease; +} + +.theme-toggle:hover { + transform: scale(1.05); + border-color: var(--text-muted); +} + +.hero { + text-align: center; + padding: 6rem 0 5rem; +} + +.hero .label { + text-transform: uppercase; + letter-spacing: 0.15em; + font-size: 0.8rem; + color: var(--text-muted); + margin-bottom: 1rem; +} + +.hero h1 { + font-size: clamp(2rem, 5vw, 3.25rem); + font-weight: 300; + line-height: 1.15; + margin-bottom: 1rem; +} + +.hero .subtitle { + font-size: 1.125rem; + color: var(--text-muted); + max-width: 32rem; + margin: 0 auto 2rem; +} + +.hero-actions { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; +} + +.btn { + display: inline-block; + padding: 0.85rem 1.75rem; + border-radius: 999px; + text-decoration: none; + font-weight: 600; + font-size: 0.95rem; + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.btn:hover { + transform: translateY(-2px); +} + +.btn-primary { + background-color: var(--accent); + color: var(--bg); +} + +.btn-secondary { + background-color: transparent; + color: var(--text); + border: 1px solid var(--border); +} + +.directory-preview, +.benefits, +.join-cta { + padding: 4rem 0; +} + +.directory-preview h2, +.benefits h2, +.join-cta h2 { + text-align: center; + font-weight: 400; + font-size: 1.75rem; + margin-bottom: 2.5rem; +} + +.cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; +} + +.card { + background-color: var(--surface); + border: 1px solid var(--border); + border-radius: 1rem; + overflow: hidden; + transition: transform 0.25s ease, box-shadow 0.25s ease; +} + +.card:hover { + transform: translateY(-6px); + box-shadow: 0 12px 30px rgba(0, 0, 0, 0.15); +} + +.card img { + width: 100%; + height: 180px; + object-fit: cover; + display: block; +} + +.card-body { + padding: 1.25rem; +} + +.card .category { + text-transform: uppercase; + font-size: 0.7rem; + letter-spacing: 0.1em; + color: var(--text-muted); +} + +.card h3 { + font-size: 1.15rem; + font-weight: 600; + margin: 0.5rem 0 0.25rem; +} + +.card p { + font-size: 0.9rem; + color: var(--text-muted); +} + +.benefit-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 2rem; + max-width: 800px; + margin: 0 auto; + text-align: center; +} + +.benefit-icon { + font-size: 1.5rem; + margin-bottom: 0.5rem; + color: var(--text-muted); +} + +.benefit h3 { + font-size: 1.1rem; + margin-bottom: 0.5rem; +} + +.benefit p { + font-size: 0.9rem; + color: var(--text-muted); +} + +.join-cta { + background-color: var(--surface); + text-align: center; +} + +.join-cta p { + color: var(--text-muted); + margin-bottom: 1.5rem; +} + +.social-links { + display: flex; + justify-content: center; + gap: 1.5rem; + margin-top: 2rem; +} + +.social-links a { + color: var(--text-muted); + text-decoration: none; + font-size: 0.9rem; + transition: color 0.2s ease; +} + +.social-links a:hover { + color: var(--text); +} + +.site-footer { + background-color: var(--surface-2); + padding: 4rem 0 3rem; + text-align: center; + border-top: 1px solid var(--border); +} + +.footer-brand { + font-size: 1.75rem; + font-weight: 500; + margin-bottom: 0.25rem; +} + +.footer-tagline { + color: var(--text-muted); + margin-bottom: 2rem; +} + +.copyright, +.credit { + font-size: 0.8rem; + color: var(--text-muted); + max-width: 700px; + margin: 0 auto 1rem; +} + +.credit a { + color: var(--text); + text-decoration: none; +} + +.reveal { + opacity: 0; + transform: translateY(24px); + transition: opacity 0.6s ease, transform 0.6s ease; +} + +.reveal.visible { + opacity: 1; + transform: translateY(0); +} + +@media (max-width: 600px) { + .header-inner { + flex-wrap: wrap; + gap: 0.75rem; + } + + .main-nav { + gap: 1rem; + } + + .hero { + padding: 4rem 0 3rem; + } + + .hero-actions { + flex-direction: column; + align-items: center; + } + + .btn { + width: 100%; + max-width: 280px; + text-align: center; + } + + .directory-preview, + .benefits, + .join-cta { + padding: 3rem 0; + } + + .directory-preview h2, + .benefits h2, + .join-cta h2 { + font-size: 1.5rem; + } + + .footer-brand { + font-size: 1.5rem; + } + + .copyright, + .credit { + font-size: 0.75rem; + } +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +}