Compare commits

..
4 Commits
Author SHA1 Message Date
Octoturge 40df04a0c8 Remove upload-artifact step: unsupported on Gitea Actions, redundant with deploy release step
build / build (push) Successful in 19s
2026-08-23 16:41:04 +02:00
Octoturge 690b77f449 Wire up automated deploy via Gitea Releases + site-deployer watcher
build / build (push) Failing after 2m39s
2026-08-23 11:34:44 +02:00
Claude c43e553fae Convert config to ESM
build / build (push) Failing after 1m11s
2026-08-02 01:41:08 +02:00
Claude d02079e3ab Scaffold Eleventy + Pug + Tailwind + i18n landing page
build / build (push) Failing after 2m6s
2026-08-02 01:37:50 +02:00
20 changed files with 40 additions and 244 deletions
+4 -13
View File
@@ -3,19 +3,10 @@
Landing page for continuum-3d.com. Eleventy + Pug + Tailwind CSS, with a Landing page for continuum-3d.com. Eleventy + Pug + Tailwind CSS, with a
small JSON-based i18n setup (`src/locales/en.json`, `src/locales/pl.json`). small JSON-based i18n setup (`src/locales/en.json`, `src/locales/pl.json`).
- English (the default language) lives at `src/en/index.pug` and builds to `/`. - English lives at `src/en/index.pug` and builds to `/`.
- Every other language lives at `src/<lang>/index.pug` and builds to `/<lang>/` - Polish lives at `src/pl/index.pug` and builds to `/pl/`.
(e.g. Polish: `src/pl/index.pug` -> `/pl/`). - Add more languages by adding `src/locales/<lang>.json` and a
- The page markup is shared in `src/_includes/home.pug`; all copy is in `src/<lang>/index.pug` with `lang: <lang>` in its front matter.
`src/locales/<lang>.json`.
- To add a language: copy `src/locales/en.json` to `src/locales/<lang>.json`,
translate it (including `lang_name`, the language's own name), and add a
`src/<lang>/index.pug` with `lang: <lang>` and `permalink: /<lang>/` in its
front matter that includes `../_includes/home.pug`. The footer language
switcher and the `hreflang` tags pick it up automatically.
- Site-wide settings (domain, contact address, default language) are in
`src/_data/site.json`. The contact form opens the visitor's mail client
addressed to `contactEmail`.
## Develop ## Develop
-1
View File
@@ -2,7 +2,6 @@ import pug from "pug";
export default function (eleventyConfig) { export default function (eleventyConfig) {
eleventyConfig.addPassthroughCopy("src/assets/img"); eleventyConfig.addPassthroughCopy("src/assets/img");
eleventyConfig.addPassthroughCopy("src/assets/fonts");
eleventyConfig.addExtension("pug", { eleventyConfig.addExtension("pug", {
compile: (inputContent, inputPath) => { compile: (inputContent, inputPath) => {
+4
View File
@@ -622,6 +622,7 @@
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"anymatch": "~3.1.2", "anymatch": "~3.1.2",
"braces": "~3.0.2", "braces": "~3.0.2",
@@ -1517,6 +1518,7 @@
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"jiti": "bin/jiti.js" "jiti": "bin/jiti.js"
} }
@@ -2075,6 +2077,7 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"nanoid": "^3.3.16", "nanoid": "^3.3.16",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
@@ -2224,6 +2227,7 @@
"integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==", "integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"posthtml-parser": "^0.11.0", "posthtml-parser": "^0.11.0",
"posthtml-render": "^3.0.0" "posthtml-render": "^3.0.0"
-27
View File
@@ -1,27 +0,0 @@
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import site from "./site.json" with { type: "json" };
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// One entry per src/locales/<code>.json. The default language is served from
// "/", every other one from "/<code>/". Order: default first, then alphabetical.
export default function () {
const localesDir = path.join(__dirname, "..", "locales");
return fs
.readdirSync(localesDir)
.filter((file) => file.endsWith(".json"))
.map((file) => {
const code = path.basename(file, ".json");
const dict = JSON.parse(fs.readFileSync(path.join(localesDir, file), "utf8"));
return {
code,
name: dict.lang_name,
href: code === site.defaultLang ? "/" : `/${code}/`,
};
})
.sort((a, b) =>
a.code === site.defaultLang ? -1 : b.code === site.defaultLang ? 1 : a.code.localeCompare(b.code)
);
}
-5
View File
@@ -1,5 +0,0 @@
{
"url": "https://continuum-3d.com",
"contactEmail": "contact@continuum-3d.com",
"defaultLang": "en"
}
-96
View File
@@ -1,96 +0,0 @@
- const t = i18n[lang]
- const gcode = ";WIPE_START\nG1 F1800\nG1 X81.8 Y92.209 E-.31416\nG1 X81.814 Y91.724 E-.36426\nG1 X81.821 Y91.752 E-.02197\nG1 X81.847 Y91.813 E-.04961\n;WIPE_END\nG1 X81.82 Y88.155 Z.4 F24000\nG1 Z.2\nG1 E2.5 F1500\nG1 F1800\nG1 X81.797 Y87.721 E.0165\nG1 X82.12 Y87.733 E.01227\nG1 X82.349 Y87.734 E.00874\nG1 X82.161 Y87.777 E.00734\nG1 X81.955 Y87.909 E.00929\nG1 X81.884 Y88 E.00439\nG1 X81.835 Y88.118 E.00486\nG1 E-1.75 F2700\n;WIPE_START\nG1 F1800\nG1 X81.797 Y87.721 E-.29884\nG1 X82.12 Y87.733 E-.24219\nG1 X82.349 Y87.734 E-.1724\nG1 X82.302 Y87.745 E-.03658\n;WIPE_END"
//- Decorative G-code text block. Positions are in design px, relative to the section.
mixin gcode(style, color, align)
pre(aria-hidden="true" class="hidden lg:block absolute w-[214px] m-0 font-poppins text-[14px] leading-[1.2] whitespace-pre select-none pointer-events-none " + (align === "right" ? "text-right" : "text-left") style=style + ";color:" + color)= gcode
//- Decorative blurred glow ellipse.
mixin glow(left, top, w, h, rot)
div(aria-hidden="true" class="hidden lg:block absolute rounded-full pointer-events-none blur-[60px]" style=`left:${left}px;top:${top}px;width:${w}px;height:${h}px;transform:rotate(${rot}deg);background:linear-gradient(148.5deg,#5272d3 0%,#15164e 42%,#15164e 96%)`)
header(class="relative z-20 h-[68px] border-b border-accent")
div(class="mx-auto flex h-full max-w-[962px] items-center justify-between pl-4 pr-4 lg:pl-[49px] lg:pr-[60px]")
a(href="#top" class="flex items-center gap-[18px]")
span(class="relative block h-[60px] w-[57px] shrink-0")
img(src="/assets/img/logo-mark.svg" alt=t.logo_alt class="absolute left-[-27px] top-[-27px] h-[126px] w-[123px] max-w-none")
span(class="hidden font-chillax text-[24px] sm:inline font-bold capitalize leading-[42px] tracking-[4px] text-white") Continuum
nav(aria-label="Main")
ul(class="m-0 flex list-none gap-4 p-0 text-[14px] leading-[1.2] lg:gap-[50px] lg:text-[16px]")
li: a(href="#about" class="text-accent hover:text-white")= t.nav_about
li: a(href="#products" class="text-accent hover:text-white")= t.nav_products
li: a(href="#contact" class="text-accent hover:text-white")= t.nav_contact
main(id="top" class="relative overflow-x-clip font-poppins")
div(class="relative mx-auto max-w-[962px]")
//- Vertical rule
div(aria-hidden="true" class="absolute bottom-0 left-4 top-0 z-10 w-px bg-accent lg:left-[41px]")
//- Hero
section(class="relative px-10 py-24 lg:h-[552px] lg:p-0")
+gcode("right:19px;top:37px", "rgb(116 139 215 / 0.3)", "right")
h1(class="m-0 font-roboto-flex text-[22px] font-normal leading-[56px] tracking-[0.2em] sm:text-[28px] sm:leading-[72px] sm:tracking-[0.22em] text-white lg:absolute lg:left-[162px] lg:top-[186px] lg:text-[36px] lg:tracking-[8px]")
span(class="block lg:w-[475px] lg:text-center")= t.hero_line_1
span(class="block lg:ml-[166px] lg:mt-[-3px] lg:w-[475px] lg:text-center")= t.hero_line_2
//- About
section(id="about" class="relative px-10 py-16 lg:h-[390px] lg:p-0")
+gcode("left:62px;top:-62px", "rgb(82 114 211 / 0.4)", "left")
div(aria-hidden="true" class="absolute hidden rounded-full lg:block" style="left:117px;top:21px;width:318px;height:318px;background:linear-gradient(150deg,#000 0%,#15164e 42%,#000 100%)")
+glow(780, 111, 286, 101, 301)
+glow(852, 269, 230, 107, 40)
+glow(-112, 315, 286, 101, 350)
div(class="relative z-10 lg:absolute lg:left-[464px] lg:top-[100px] lg:w-[387px]")
h2(class="m-0 text-[18px] font-normal leading-[1.2] text-[#c0ceff]")= t.about_title
p(class="m-0 mt-10 text-[16px] leading-[1.2] text-[#abbfff] lg:mt-[45px]")= t.about_text
//- Products
section(id="products" class="relative px-10 py-16 text-center lg:h-[577px] lg:p-0")
div(aria-hidden="true" class="absolute hidden lg:block pointer-events-none blur-[70px]" style="left:-83px;top:2px;width:1069px;height:138px;transform:rotate(3deg);background:linear-gradient(180deg,#7186c6 0%,#15164e 28%,#15164e 46%,#000 100%)")
+glow(595, 49, 286, 101, 350)
img(src="/assets/img/wave.svg" alt="" aria-hidden="true" class="pointer-events-none absolute hidden max-w-none lg:block" style="left:166px;top:-156px;width:1034px;height:775px")
+gcode("left:62px;top:283px", "rgb(116 139 215 / 0.3)", "left")
div(class="relative z-10 lg:absolute lg:inset-x-0 lg:top-[150px]")
h2(class="m-0 text-[18px] font-normal leading-[1.2] text-white")= t.products_title
p(class="m-0 mt-16 text-[16px] leading-[1.2] text-white lg:mt-[116px]")= t.products_line_1
p(class="m-0 mt-6 text-[16px] leading-[1.2] text-white lg:mt-[40px]")= t.products_line_2
//- Contact
section(id="contact" class="relative px-10 py-16 lg:h-[429px] lg:p-0")
div(aria-hidden="true" class="absolute inset-0 hidden overflow-hidden lg:block")
div(class="absolute" style="left:38px;top:0;width:1088px;height:429px;background:linear-gradient(90deg,rgb(82 114 211 / 0.3) 0%,rgb(82 114 211 / 0) 100%)")
+glow(-39, 248, 286, 101, 58)
+glow(68, 259, 286, 101, 58)
+gcode("right:19px;top:207px", "rgb(116 139 215 / 0.3)", "right")
form(id="contact-form" class="relative z-10 flex flex-col gap-6 lg:static lg:block" action="mailto:" + site.contactEmail method="post" enctype="text/plain" data-to=site.contactEmail data-subject=t.form_subject)
label(class="order-4 block lg:absolute lg:left-[94px] lg:top-[58px] lg:w-[412px]")
span(class="sr-only")= t.form_message
textarea(name="message" required placeholder=t.form_message class="block h-[306px] w-full resize-none rounded-[13px] border-2 border-accent bg-transparent p-4 text-[16px] text-white placeholder:text-accent focus:outline-none focus:ring-2 focus:ring-accent")
div(class="contents lg:block lg:static")
h2(class="order-1 m-0 text-[18px] font-normal leading-[1.2] text-white lg:absolute lg:left-[594px] lg:top-[93px]")= t.contact_title
label(class="order-2 block lg:absolute lg:left-[593px] lg:top-[176px] lg:w-[214px]")
span(class="sr-only")= t.form_name
input(type="text" name="name" required autocomplete="name" placeholder=t.form_name class="block h-[29px] w-full rounded-[13px] border-2 border-accent bg-transparent px-3 text-[14px] text-white placeholder:text-accent focus:outline-none focus:ring-2 focus:ring-accent")
label(class="order-3 block lg:absolute lg:left-[594px] lg:top-[229px] lg:w-[214px]")
span(class="sr-only")= t.form_email
input(type="email" name="email" required autocomplete="email" placeholder=t.form_email class="block h-[29px] w-full rounded-[13px] border-2 border-accent bg-transparent px-3 text-[14px] text-white placeholder:text-accent focus:outline-none focus:ring-2 focus:ring-accent")
button(type="submit" class="order-5 h-[30px] w-[100px] rounded-[13px] border-2 border-accent bg-transparent text-[14px] text-white hover:bg-accent focus:outline-none focus:ring-2 focus:ring-accent lg:absolute lg:left-[594px] lg:top-[276px]")= t.form_send
//- Footer
footer(class="relative z-10 flex h-[139px] flex-col items-center justify-center gap-3 text-xs text-gray-500")
nav(aria-label=t.lang_label)
ul(class="m-0 flex list-none flex-wrap justify-center gap-x-4 gap-y-1 p-0")
each l in languages
li
a(href=l.href lang=l.code hreflang=l.code aria-current=(l.code === lang ? "page" : false) class=(l.code === lang ? "text-white" : "underline underline-offset-4 hover:text-gray-300"))= l.name
p(class="m-0")= t.footer_text
script.
// No backend: compose a mailto: link from the form and hand it to the visitor's mail client.
document.getElementById("contact-form").addEventListener("submit", function (e) {
e.preventDefault();
var f = e.currentTarget, d = new FormData(f);
var subject = f.dataset.subject + " - " + d.get("name");
var body = d.get("message") + "\n\n" + d.get("name") + " <" + d.get("email") + ">";
window.location.href = "mailto:" + f.dataset.to + "?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body);
});
+1 -4
View File
@@ -5,8 +5,5 @@ html(lang=lang)
meta(name="viewport" content="width=device-width, initial-scale=1.0") meta(name="viewport" content="width=device-width, initial-scale=1.0")
title= i18n[lang].meta_title title= i18n[lang].meta_title
link(rel="stylesheet" href="/assets/css/style.css") link(rel="stylesheet" href="/assets/css/style.css")
each l in languages body(class="bg-gray-950 text-white antialiased")
link(rel="alternate" hreflang=l.code href=site.url + l.href)
link(rel="alternate" hreflang="x-default" href=site.url + "/")
body(class="bg-black font-poppins text-white antialiased")
!= content != content
-40
View File
@@ -1,43 +1,3 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@font-face {
font-family: "Poppins";
font-weight: 400;
font-display: swap;
src: url("/assets/fonts/poppins-latin-ext-400-normal.woff2") format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Poppins";
font-weight: 400;
font-display: swap;
src: url("/assets/fonts/poppins-latin-400-normal.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Roboto Flex";
font-weight: 100 1000;
font-display: swap;
src: url("/assets/fonts/roboto-flex-latin-ext-wght-normal.woff2") format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Roboto Flex";
font-weight: 100 1000;
font-display: swap;
src: url("/assets/fonts/roboto-flex-latin-wght-normal.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Chillax";
font-weight: 700;
font-display: swap;
src: url("/assets/fonts/chillax-700.woff2") format("woff2");
}
html {
scroll-behavior: smooth;
scroll-padding-top: 68px;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 316 KiB

+7 -1
View File
@@ -3,4 +3,10 @@ layout: layout.pug
lang: en lang: en
permalink: / permalink: /
--- ---
include ../_includes/home.pug section(class="min-h-screen flex flex-col items-center justify-center px-6 text-center")
h1(class="text-5xl font-bold tracking-tight mb-4")= i18n[lang].hero_title
p(class="text-lg text-gray-400 max-w-xl mb-10")= i18n[lang].hero_subtitle
a(href="/pl/" class="text-sm text-gray-500 hover:text-gray-300 underline underline-offset-4")= i18n[lang].lang_switch_label
footer(class="pb-8 text-center text-xs text-gray-600")
p= i18n[lang].footer_text
+8 -21
View File
@@ -1,23 +1,10 @@
{ {
"meta_title": "Continuum", "meta_title": "Continuum 3D",
"nav_about": "About us", "nav_home": "Home",
"nav_products": "Products", "hero_title": "Continuum 3D",
"nav_contact": "Contact", "hero_subtitle": "3D printing engineering and manufacturing solutions.",
"hero_line_1": "Production", "cta_text": "Contact us",
"hero_line_2": "without limits", "lang_switch_label": "Polski",
"about_title": "Who are we?", "lang_switch_href": "/pl/",
"about_text": "We are an interdisciplinary team who met at university with shared interests and the aim of building something of our own, answering market needs and other people's problems.", "footer_text": "Continuum 3D Sp. z o.o."
"products_title": "Products",
"products_line_1": "We are preparing something extraordinary",
"products_line_2": "Coming soon",
"contact_title": "Get in touch!",
"form_name": "Full name",
"form_email": "Email",
"form_message": "Message",
"form_send": "Send",
"logo_alt": "Continuum logo",
"footer_text": "Continuum 3D Sp. z o.o.",
"lang_name": "English",
"lang_label": "Language",
"form_subject": "Message from the website"
} }
+8 -21
View File
@@ -1,23 +1,10 @@
{ {
"meta_title": "Continuum", "meta_title": "Continuum 3D",
"nav_about": "O nas", "nav_home": "Start",
"nav_products": "Produkty", "hero_title": "Continuum 3D",
"nav_contact": "Kontakt", "hero_subtitle": "Inżynieria i produkcja w druku 3D.",
"hero_line_1": "Production", "cta_text": "Skontaktuj się",
"hero_line_2": "without limits", "lang_switch_label": "English",
"about_title": "Kim jesteśmy?", "lang_switch_href": "/",
"about_text": "Jesteśmy interdyscyplinarnym zespołem, które spotkały się na studiach z wspólnymi zainteresowaniami i zamiarem zbudowania czegoś własnego, odpowiadającego na potrzeby rynku i problemy innych.", "footer_text": "Continuum 3D Sp. z o.o."
"products_title": "Produkty",
"products_line_1": "Szykujemy coś niezwykłego",
"products_line_2": "Już niedługo",
"contact_title": "Skontaktuj się z nami!",
"form_name": "Imię i nazwisko",
"form_email": "E-mail",
"form_message": "Wiadomość",
"form_send": "Wyślij",
"logo_alt": "Logo Continuum",
"footer_text": "Continuum 3D Sp. z o.o.",
"lang_name": "Polski",
"lang_label": "Język",
"form_subject": "Wiadomość ze strony"
} }
+7 -1
View File
@@ -3,4 +3,10 @@ layout: layout.pug
lang: pl lang: pl
permalink: /pl/ permalink: /pl/
--- ---
include ../_includes/home.pug section(class="min-h-screen flex flex-col items-center justify-center px-6 text-center")
h1(class="text-5xl font-bold tracking-tight mb-4")= i18n[lang].hero_title
p(class="text-lg text-gray-400 max-w-xl mb-10")= i18n[lang].hero_subtitle
a(href="/" class="text-sm text-gray-500 hover:text-gray-300 underline underline-offset-4")= i18n[lang].lang_switch_label
footer(class="pb-8 text-center text-xs text-gray-600")
p= i18n[lang].footer_text
+1 -12
View File
@@ -1,18 +1,7 @@
module.exports = { module.exports = {
content: ["./src/**/*.pug"], content: ["./src/**/*.pug"],
theme: { theme: {
extend: { extend: {},
colors: {
accent: "#5272d3",
deep: "#15164e",
"accent-light": "#748bd7",
},
fontFamily: {
poppins: ["Poppins", "sans-serif"],
"roboto-flex": ['"Roboto Flex"', "sans-serif"],
chillax: ["Chillax", "sans-serif"],
},
},
}, },
plugins: [], plugins: [],
}; };