Compare commits

...
Sign in to create a new pull request.

9 commits
main ... main

Author SHA1 Message Date
Strix
2912e33760 fix: typo 2025-03-25 22:48:19 +01:00
Strix
a6ff285b2e feat: update site 2025-03-25 22:46:50 +01:00
71b2aaae4f style: drop-shadow fix 2024-07-06 21:58:34 +02:00
3ef20e8d42 style+fix: z-index and alignment 2024-07-06 21:10:02 +02:00
b77808e38e style: drop-shadow 2024-07-06 20:53:13 +02:00
d01b2adb8e doc: words in meta 2024-07-06 20:49:58 +02:00
bfe0084c93 fix: responsive n stuff 2024-07-06 20:45:46 +02:00
32e4ccdcb5 fix: meta tags 2024-07-06 20:42:33 +02:00
c3a2d96dd8 doc+style: update styling and write some extra words 2024-07-06 20:37:12 +02:00
6 changed files with 347 additions and 56 deletions

BIN
public/assets/logo.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

View file

@ -4,66 +4,105 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nebulosus</title>
<meta name="description" content="Nebulosus is a dutch company focusing on intuitivism, simplicity, redundancy, reliability and friendliness.">
<link rel="icon" href="/assets/logo.webp" type="image/webp">
<link rel="stylesheet" href="./res/style.css">
<script src="./res/cases.js" defer></script>
<script src="./res/anchors.js" defer></script>
<script src="./res/locale.js" defer></script>
</head>
<style>
[data-i18n-show] {
display: none;
}
</style>
<body>
<header style="display: flex; justify-content: space-between;">
<div class="logo">
<span class="mono">[N]</span>
<div class="logo" style="display: flex; align-items: center; gap: .75rem;">
<img src="/assets/logo.webp" height="40" width="40" alt="" />
<span>Nebulosus</span>
</div>
<div class="columns" style="padding: 1.5rem; justify-content: center;">
<a href="/">Home</a>
</div>
</header>
<main>
<main data-i18n-show>
<section id="intro">
<h1>Nebulosus</h1>
</section>
<div class="columns">
<div>
<section id="offer">
<h2>What does Nebulosus offer?</h2>
<span>Nebulosus offers a variety of services:</span>
<ol>
<li><span>Server Hosting</span></li>
<li><span>Website / Application Development</span></li>
<li><span>Technical Support</span></li>
</ol>
<button id="cases-button" hidden>Cases</button>
<div id="cases" hidden></div>
</section>
<section id="about">
<h2>About Nebulosus</h2>
<p>
Nebulosus is simplicity, redundancy, reliability and friendliness. <br />
Software should be intuitive, aware of it's environment. That's what Nebulosus strives for.
<br />
If you want simple, intuitive and reliable software, you're in the right spot.
</p>
</section>
<div class="columns" style="align-items: flex-start; padding: 2rem; gap: 2rem;">
<img src="/assets/logo.webp" height="100" width="100" style="filter: drop-shadow(0 0 20px #fff);" />
<div class="rows">
<h1>Nebulosus</h1>
<span data-i18n="$.motto"></span>
</div>
</div>
<section id="contact" hidden>
<!-- Not done yet :) -->
<!-- Technical question? dev (at) faulty (dot) nl -->
<h2>Contact</h2>
<span>To contact me please use the following form:</span>
<form action="/api/form">
<input name="name" type="text" placeholder="Name">
<input name="email" type="text" placeholder="E-Mail">
<textarea name="message" rows="5" placeholder="Your message"></textarea>
<input type="button" value="Submit">
</form>
</section>
</div>
<section id="more-info">
<h2>More information about Nebulosus</h2>
</section>
<!-- keep some sample text for SEO n stuff -->
<section id="about">
<h2 data-i18n="about.title">About</h2>
<p data-i18n="about.text">
Nebulosus is a dutch company focusing on intuitivism, simplicity, redundancy, reliability and
friendliness.
Software should be intuitive, aware of it's environment. That's what Nebulosus strives for.
If you want to develop an app with intuitive design and a redundant infrastructure, please reach out!
If you're looking for a company site, let's discuss it!
</p>
</section>
<section id="offer">
<h2 data-i18n="offer.title">Offer</h2>
<div style="display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));">
<div>
<h4 data-i18n="offer.it-consultancy.title"></h4>
<p data-i18n="offer.it-consultancy.tagline"></p>
<p data-i18n="offer.it-consultancy.description"></p>
<span data-i18n="offer.it-consultancy.solutions"></span>
</div>
<div>
<h4 data-i18n="offer.managed-hosting.title"></h4>
<p data-i18n="offer.managed-hosting.tagline"></p>
<p data-i18n="offer.managed-hosting.description"></p>
<span data-i18n="offer.managed-hosting.solutions"></span>
</div>
<div>
<h4 data-i18n="offer.tech-support.title"></h4>
<p data-i18n="offer.tech-support.tagline"></p>
<p data-i18n="offer.tech-support.description"></p>
<span data-i18n="offer.tech-support.solutions"></span>
</div>
<div>
<h4 data-i18n="offer.development.title"></h4>
<p data-i18n="offer.development.tagline"></p>
<p data-i18n="offer.development.description"></p>
<span data-i18n="offer.development.solutions"></span>
</div>
</div>
</section>
<section id="info">
<h2>Information</h2>
<div class="rows">
<span>Chamber of Commerce number: <strong>93409583</strong></span>
<span>E-mail: <strong>info@nebulosus.nl</strong></span>
<span><span data-i18n="dict.mail"></span>: <a href="#" data-i18n="$.mail"
onclick="window.open('mailto:info'+'@'+''+'nebulosus'+'.n'+'l', '_self')"></a></span>
<span><span data-i18n="dict.kvk"></span>: <strong data-i18n="$.kvk" href="#"></strong></span>
</div>
</section>
</main>
<footer>
<div style="display: flex; justify-content: space-between">
<span>&copy; 2025 Nebulosus</span>
<div>
<button onclick="locale.setPreferredLocale('en')">EN</button>
<button onclick="locale.setPreferredLocale('nl')">NL</button>
</div>
</div>
</footer>
<!-- Want to collaborate? -->
<!-- E-Mail: didier (at) nebulosus (dot) nl -->
</body>
</html>

103
public/res/locale.js Normal file
View file

@ -0,0 +1,103 @@
(() => {
const getLocale = () => {
const cacheLocale = localStorage.getItem('preferredLocale')
if (cacheLocale) return cacheLocale
localStorage.setItem('preferredLocale', navigator.language);
return locale
}
const setPreferredLocale = (locale) => {
localStorage.setItem('preferredLocale', locale);
setLocale()
}
const getLocaleURL = (locale = getLocale()) => {
const lang = locale.split('-')[0];
return `/res/locale/${lang}.json`
}
const loadLocale = async (locale = getLocale()) => {
// check localStorage
const cacheDate = localStorage.getItem(`locale-${locale}`)
if (cacheDate) {
if (Date.now() - cacheDate < 1000 * 60 * 60 * 24) { // 1 day
return JSON.parse(localStorage.getItem(`locale-${locale}-data`))
}
}
try {
const response = await fetch(getLocaleURL(locale), { cache: 'no-store' })
if (response.ok) {
const data = await response.json()
localStorage.setItem(`locale-${locale}`, Date.now())
localStorage.setItem(`locale-${locale}-data`, JSON.stringify(data))
return data
}
} catch (error) {
console.error(error)
if (cacheDate) { // if error then return cache even if expired
return JSON.parse(localStorage.getItem(`locale-${locale}-data`))
} else {
if (locale !== 'en') return await loadLocale('en');
}
}
return {}
}
const setLocale = async (locale = getLocale()) => {
const data = await loadLocale(locale)
document.querySelectorAll('[data-i18n]').forEach(async (element) => {
try {
// main.intro.title => {main: {intro: {title: 'value'}}}
const keys = element.getAttribute('data-i18n').split('.');
console.log(keys)
let value = data;
keys.forEach((key) => value = value[key]);
console.log(value)
// if array then into ul list
if (Array.isArray(value)) {
element.innerHTML = ''
const ul = document.createElement('ul')
value.forEach((item) => {
const li = document.createElement('li')
li.innerHTML = item
ul.appendChild(li)
})
element.appendChild(ul)
} else {
element.innerHTML = value ?? '###';
}
} catch (error) {
console.error(error)
element.innerHTML = '###';
}
});
document.querySelectorAll('[data-i18n-show]').forEach(el => el.removeAttribute('data-i18n-show'))
}
window.locale = {
setPreferredLocale,
getLocale,
getLocaleURL,
loadLocale,
setLocale,
expireLocale: () => {
localStorage.removeItem(`locale-${getLocale()}`)
localStorage.removeItem(`locale-${getLocale()}-data`)
setLocale()
}
}
window.locale.setLocale();
// expiry management
// check if locale is older than EXPIRY_TIME then fetch again
function checkExpiry() {
const cacheDate = localStorage.getItem(`locale-${getLocale()}`)
if (cacheDate) {
if (Date.now() - cacheDate > 1000 * 60 * 60 * 24) { // 1 day
window.locale.expireLocale()
}
}
}
setInterval(checkExpiry, 1000 * 60 * 60); // 1 hour
checkExpiry()
})()

66
public/res/locale/en.json Normal file
View file

@ -0,0 +1,66 @@
{
"$": {
"name": "Nebulosus",
"kvk": 93409583,
"mail": "info@nebulosus.nl",
"motto": "Focused on innovation."
},
"about": {
"title": "About",
"text": "Nebulosus is a Dutch company focused on intuition, <span style='letter-spacing: 1px;'>simplicity</span>, <b style='color: darkgoldenrod;'>redundancy</b>, <span style='color: darkcyan; text-decoration: underline;'>reliability</span>, and <i style='color: green'>friendliness</i>. <br /> We believe software should be intuitive and aware of its environment. This is the standard we aim for at Nebulosus.<br />Looking to develop an app with intuitive design and robust infrastructure? Get in touch!<br />Need a company website? Lets discuss how we can help."
},
"offer": {
"title": "Offer",
"it-consultancy": {
"title": "IT Consultancy",
"tagline": "IT consultancy services for your business.",
"description": "Nebulosus offers IT consultancy services for your business. Giving you a clear understanding of the technology you need to move forward.",
"solutions": [
"IT Strategy",
"Infrastructure",
"Security",
"Compliance",
"Training"
]
},
"managed-hosting": {
"title": "Managed Hosting",
"tagline": "Managed hosting services for your website.",
"description": "Nebulosus offers managed hosting services for your website. Taking care of the technical stuff so you can focus on your business.",
"solutions": [
"Application Hosting",
"DNS Management (Domain and Subdomains)",
"SSL Certificates",
"Email Hosting"
]
},
"tech-support": {
"title": "Tech Support",
"tagline": "Professional support for your technical issues.",
"description": "Having an issue with your website, computer, or network? Nebulosus offers professional support for all your technical issues.",
"solutions": [
"Android/iOS Support",
"Windows/Mac/Linux Support",
"Network Support",
"Installation and Configuration",
"Advice and Guidance"
]
},
"development": {
"title": "Development",
"tagline": "Development services for your business.",
"description": "Nebulosus offers development services for your application. Whether you need a website, custom integration, or want to automate your business, Nebulosus can help.",
"solutions": [
"(Web)applications",
"Integration development",
"Automation",
"API Development",
"Database Development"
]
}
},
"dict": {
"kvk": "Chamber of Commerce",
"mail": "Email"
}
}

66
public/res/locale/nl.json Normal file
View file

@ -0,0 +1,66 @@
{
"$": {
"name": "Nebulosus",
"kvk": 93409583,
"mail": "info@nebulosus.nl",
"motto": "Gericht op innovatie."
},
"about": {
"title": "Over",
"text": "Nebulosus is een Nederlands bedrijf dat streeft naar intuïtieve, eenvoudige en betrouwbare software, met redundantie en gebruiksvriendelijkheid als kernwaarden. <br /> Software moet intuïtief en omgevingsbewust zijn. Daar zetten wij ons voor in.<br />Wil je een app met intuïtief design en een robuuste infrastructuur? Neem contact op!<br />Op zoek naar een bedrijfssite? Laten we het bespreken!"
},
"offer": {
"title": "Aanbod",
"it-consultancy": {
"title": "IT Consultancy",
"tagline": "IT-consultancydiensten voor uw bedrijf.",
"description": "Technologie moet je vooruithelpen, niet tegenwerken. Strategisch advies waarmee uw bedrijf wendbaar blijft in een snel veranderend digitaal landschap.",
"solutions": [
"IT-strategie",
"Infrastructuur",
"Beveiliging",
"Compliance",
"Training"
]
},
"managed-hosting": {
"title": "Beheerde Hosting",
"tagline": "Beheerde hostingdiensten voor uw website.",
"description": "Nebulosus biedt beheerde hostingdiensten voor uw website. Terwijl de technische zaken worden geregeld, kunt u zich richten op uw bedrijf.",
"solutions": [
"Applicatie Hosting",
"DNS-beheer (Domeinnaam en subdomeinen)",
"SSL-certificaten",
"E-mailhosting"
]
},
"tech-support": {
"title": "Technische Ondersteuning",
"tagline": "Professionele ondersteuning bij uw technische problemen.",
"description": "Een probleem met uw website, computer of netwerk? Nebulosus biedt professionele ondersteuning voor al uw technische problemen.",
"solutions": [
"Android/iOS-ondersteuning",
"Windows/Mac/Linux-ondersteuning",
"Netwerkondersteuning",
"Installatie en configuratie",
"Advies en begeleiding"
]
},
"development": {
"title": "Ontwikkeling",
"tagline": "Ontwikkelingsdiensten voor uw bedrijf.",
"description": "Nebulosus biedt ontwikkelingsdiensten voor uw applicatie. Of u nu een website, mobiele app of aangepaste software nodig heeft, Nebulosus kan helpen.",
"solutions": [
"(Web)applicaties",
"Integratie ontwikkeling",
"Automatisering",
"API's",
"Databaseontwikkeling"
]
}
},
"dict": {
"kvk": "Kamer van Koophandel",
"mail": "E-mail"
}
}

View file

@ -20,10 +20,11 @@ header {
top: 0%;
width: 100vw;
height: fit-content;
background-color: var(--theme-color, gray);
color: #fff;
box-shadow: 0 0 20px var(--theme-color-lowlight);
background-color: #fff;
border-bottom: 4px solid var(--theme-color);
color: #000;
align-content: center;
z-index: 100;
}
header div.logo {
@ -40,8 +41,8 @@ header div.logo span {
main {
display: flex;
flex-direction: column;
gap: 1em;
width: 100vw;
margin-bottom: 4rem;
}
main section {
@ -57,17 +58,19 @@ main section {
section#intro {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 0;
width: 100vw;
background-color: var(--theme-color);
background: linear-gradient(120deg, var(--theme-color-highlight-2), var(--theme-color) 60%);
color: #fff;
font-size: 2em;
border-bottom: 3px solid gray;
h1 {
margin: 0;
}
}
div section {
@ -76,6 +79,20 @@ div section {
/* --- */
footer {
display: flex;
flex-direction: column;
position: fixed;
bottom: 0;
width: calc(100vw - 5em);
height: 2rem;
padding-left: 2.5em;
background-color: #fff;
justify-content: center;
}
/* --- */
/* for anchors.js */
h2:hover {
cursor: pointer;
@ -144,13 +161,13 @@ button {
cursor: pointer;
&:hover {
background-color: var(--theme-color-highlight-2);
border: 1px solid var(--theme-color-highlight);
}
transition: background-color .2s ease-in-out;
}
div.columns {
.columns {
display: flex;
@media (max-width: 600px) {
@ -158,7 +175,7 @@ div.columns {
}
}
div.rows {
.rows {
display: flex;
flex-direction: column;
}