From 0e8b2a4547f6de3161a4e6fa43f04f9caa5a8a8e Mon Sep 17 00:00:00 2001 From: Jasper Middendorp Date: Sun, 22 Feb 2026 18:30:57 +0100 Subject: [PATCH] Rebuild website with Eleventy + Nunjucks and new hero system Migrate from static HTML/CSS/JS to Eleventy 3.x with Nunjucks templates, design tokens, scroll reveals, and 10 interactive hero variants with a live selector. Preserves all content, contact form, and GitHub Pages setup. Co-Authored-By: Claude Opus 4.6 --- .eleventy.js | 16 + .gitignore | 3 + _includes/base.njk | 34 + _includes/footer.njk | 28 + _includes/nav.njk | 16 + about.njk | 59 ++ contact.njk | 69 ++ css/styles.css | 1112 ----------------------------- index.html | 366 ---------- index.njk | 292 ++++++++ js/script.js | 145 ---- main.js | 872 +++++++++++++++++++++++ package-lock.json | 1580 ++++++++++++++++++++++++++++++++++++++++++ package.json | 16 + privacy.html | 292 -------- privacy.njk | 156 +++++ styles.css | 1461 ++++++++++++++++++++++++++++++++++++++ terms.html | 271 -------- terms.njk | 135 ++++ 19 files changed, 4737 insertions(+), 2186 deletions(-) create mode 100644 .eleventy.js create mode 100644 .gitignore create mode 100644 _includes/base.njk create mode 100644 _includes/footer.njk create mode 100644 _includes/nav.njk create mode 100644 about.njk create mode 100644 contact.njk delete mode 100644 css/styles.css delete mode 100644 index.html create mode 100644 index.njk delete mode 100644 js/script.js create mode 100644 main.js create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 privacy.html create mode 100644 privacy.njk create mode 100644 styles.css delete mode 100644 terms.html create mode 100644 terms.njk diff --git a/.eleventy.js b/.eleventy.js new file mode 100644 index 0000000..e3352f1 --- /dev/null +++ b/.eleventy.js @@ -0,0 +1,16 @@ +module.exports = function (eleventyConfig) { + eleventyConfig.addPassthroughCopy("styles.css"); + eleventyConfig.addPassthroughCopy("main.js"); + eleventyConfig.addPassthroughCopy("assets"); + eleventyConfig.addPassthroughCopy("CNAME"); + + return { + dir: { + input: ".", + output: "_site", + includes: "_includes", + }, + templateFormats: ["njk"], + htmlTemplateEngine: false, + }; +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..628cb86 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +_site/ +node_modules/ +.DS_Store diff --git a/_includes/base.njk b/_includes/base.njk new file mode 100644 index 0000000..70ba947 --- /dev/null +++ b/_includes/base.njk @@ -0,0 +1,34 @@ + + + + + + + + {{ title }} + + + + + + + + + + + + + + + + + + {{ headExtra | safe }} + + + {% include "nav.njk" %} + {{ content | safe }} + {% include "footer.njk" %} + + + diff --git a/_includes/footer.njk b/_includes/footer.njk new file mode 100644 index 0000000..9670b95 --- /dev/null +++ b/_includes/footer.njk @@ -0,0 +1,28 @@ + diff --git a/_includes/nav.njk b/_includes/nav.njk new file mode 100644 index 0000000..693c7d1 --- /dev/null +++ b/_includes/nav.njk @@ -0,0 +1,16 @@ + + diff --git a/about.njk b/about.njk new file mode 100644 index 0000000..8574fa7 --- /dev/null +++ b/about.njk @@ -0,0 +1,59 @@ +--- +layout: base.njk +title: "About — No Box Dev" +description: "We build web and mobile applications shaped by psychology and enhanced by AI." +canonical: "https://noboxdev.com/about" +permalink: "/about/index.html" +--- + + +
+
+
+
+ +

Human-centered. Psychology-driven.

+

We combine technical expertise with an understanding of human behavior to build digital products that truly work for the people using them.

+
+
+ + +
+
+
+
+ +

Building products that make sense

+

At No Box Dev, we believe great digital products aren't just about clean code or pretty screens. They're about understanding how people think, decide, and act — and designing technology that supports those behaviors.

+

With a psychologist on our team, we go beyond surface-level UX. We design for motivation, reduce friction, and shape behavior with intention. The result: applications that don't just function, but feel intuitive and drive real adoption.

+

Whether you're a founder with an idea or a team looking to improve an existing product, we bring structure, clarity, and shared ownership to every collaboration.

+
+
+ No Box Dev team working +
+
+
+
+ + +
+
+
+ +

Who We Are

+
+
+

Meet the team

+

We're a small, dedicated team of developers, designers, and a psychologist. More details coming soon.

+
+
+
+ + +
+
+

Ready to build something together?

+

We'd love to hear about your project and explore how we can help.

+ Get in touch +
+
diff --git a/contact.njk b/contact.njk new file mode 100644 index 0000000..11b2342 --- /dev/null +++ b/contact.njk @@ -0,0 +1,69 @@ +--- +layout: base.njk +title: "Contact — No Box Dev" +description: "Get in touch with No Box Dev. Tell us about your project and we'll get back to you." +canonical: "https://noboxdev.com/contact" +permalink: "/contact/index.html" +--- + + +
+
+
+
+ +

Let's get started.

+

Tell us about your project and we'll get back to you within 24 hours.

+ +
+
+
+ + + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ +
+

Message sent!

+

We'll get back to you within 24 hours.

+
+
+ +
+

Or reach us directly.

+
+
Email
+ hello@noboxdev.com +
+
+
Location
+

Available Worldwide

+
+
+
Response Time
+

Usually within 24 hours

+
+
+
+
+
diff --git a/css/styles.css b/css/styles.css deleted file mode 100644 index a527a0d..0000000 --- a/css/styles.css +++ /dev/null @@ -1,1112 +0,0 @@ -/** - * NoBoxDev Website Styles - */ - -/* Font Faces */ -@font-face { - font-family: 'Aeonik'; - src: url('../assets/fonts/Aeonik-regular.ttf') format('truetype'); - font-weight: 400; - font-style: normal; -} - -@font-face { - font-family: 'Aeonik'; - src: url('../assets/fonts/Aeonik bold italic.ttf') format('truetype'); - font-weight: 700; - font-style: italic; -} - -@font-face { - font-family: 'Arbeit'; - src: url('../assets/fonts/Arbeit-Regular.otf') format('opentype'); - font-weight: 400; - font-style: normal; -} - -@font-face { - font-family: 'Arbeit'; - src: url('../assets/fonts/Arbeit-Bold.otf') format('opentype'); - font-weight: 700; - font-style: normal; -} - -@font-face { - font-family: 'Arbeit'; - src: url('../assets/fonts/Arbeit-LightItalic.otf') format('opentype'); - font-weight: 300; - font-style: italic; -} - -/* Reset */ -*, *::before, *::after { - box-sizing: border-box; - margin: 0; - padding: 0; -} - -/* CSS Variables */ -:root { - --color-primary: #FE795D; - --color-primary-dark: #e56a50; - --color-secondary: #9B78F4; - --color-dark: #201E1D; - --color-charcoal: #333333; - --color-light-grey: #F5F5F5; - --color-white: #FFFFFF; - --color-text: #201E1D; - --color-text-light: #666666; - - --font-display: 'Aeonik', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - --font-body: 'Arbeit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - - --spacing-xs: 0.5rem; - --spacing-sm: 1rem; - --spacing-md: 1.5rem; - --spacing-lg: 2rem; - --spacing-xl: 3rem; - --spacing-xxl: 5rem; - - --container-max: 1200px; - --container-padding: 1.5rem; - - --radius-sm: 4px; - --radius-md: 8px; - --radius-lg: 16px; - --radius-full: 9999px; - - --transition-fast: 150ms ease; - --transition-base: 250ms ease; - --transition-slow: 400ms ease; - - --shadow-sm: 0 1px 2px rgba(32, 30, 29, 0.05); - --shadow-md: 0 4px 6px rgba(32, 30, 29, 0.07); - --shadow-lg: 0 10px 25px rgba(32, 30, 29, 0.1); - --shadow-xl: 0 20px 50px rgba(32, 30, 29, 0.15); -} - -/* Base */ -html { - font-size: 16px; - scroll-behavior: smooth; - -webkit-font-smoothing: antialiased; -} - -body { - font-family: var(--font-body); - font-size: 1rem; - line-height: 1.7; - color: var(--color-text); - background-color: var(--color-white); -} - -/* Typography */ -h1, h2, h3, h4, h5, h6 { - font-family: var(--font-display); - font-weight: 400; - line-height: 1.1; - color: var(--color-dark); -} - -h1 { font-size: 56px; } -h2 { font-size: 40px; } -h3 { font-size: 20px; } -h4 { font-size: 18px; } - -p { - margin-bottom: var(--spacing-sm); -} - -a { - color: var(--color-primary); - text-decoration: none; - transition: color var(--transition-fast); -} - -a:hover { - color: var(--color-primary-dark); -} - -img { - max-width: 100%; - height: auto; -} - -/* Container */ -.container { - width: 100%; - max-width: var(--container-max); - margin: 0 auto; - padding: 0 var(--spacing-md); -} - -/* Buttons */ -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: var(--spacing-xs); - padding: 10px 28px; - font-family: var(--font-body); - font-size: 16px; - font-weight: 400; - text-decoration: none; - border: none; - border-radius: var(--radius-sm); - cursor: pointer; - transition: all var(--transition-fast); -} - -.btn-coral { - background-color: var(--color-primary); - color: var(--color-white); -} - -.btn-coral:hover { - background-color: var(--color-primary-dark); - color: var(--color-white); - transform: translateY(-2px); -} - -.btn-outline-white { - background-color: transparent; - color: var(--color-white); - border: 2px solid var(--color-white); -} - -.btn-outline-white:hover { - background-color: var(--color-white); - color: var(--color-secondary); -} - -.btn-full { - width: 100%; -} - -/* Header */ -.header { - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 100; - background-color: rgba(254, 121, 93, 0.5); - transition: background-color var(--transition-base); -} - -.header-bar { - display: none; -} - -.header.scrolled { - background-color: rgba(254, 121, 93, 0.5); -} - -.header.scrolled .header-bar { - height: 4px; -} - -.header-inner { - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--spacing-sm) 0; -} - -.logo { - display: flex; - align-items: center; - gap: var(--spacing-sm); - text-decoration: none; -} - -.logo-img { - height: 40px; - width: auto; -} - -.logo-text { - font-family: var(--font-display); - font-weight: 400; - font-size: 1.25rem; - color: var(--color-white); - letter-spacing: 0.15em; - transition: color var(--transition-fast); - display: inline-flex; - align-items: center; -} - -.header.scrolled .logo-text { - color: var(--color-white); -} - -.logo-box { - position: relative; - display: inline-flex; - flex-direction: column; - align-items: center; - margin: 0 2px; -} - -.built-upon { - position: absolute; - top: -12px; - left: 50%; - transform: translateX(-50%); - font-size: 0.45rem; - font-weight: 400; - letter-spacing: 0.02em; - white-space: nowrap; - opacity: 0.9; -} - -.logo-hexagon { - width: 14px; - height: 14px; - vertical-align: middle; -} - -.nav { - display: flex; - align-items: center; - gap: var(--spacing-lg); -} - -.nav-link { - font-family: var(--font-body); - font-size: 16px; - font-weight: 400; - color: var(--color-white); - text-decoration: none; - transition: color var(--transition-fast); - background: transparent; -} - -.header.scrolled .nav-link { - color: var(--color-white); -} - -.nav-link:hover { - color: rgba(255, 255, 255, 0.8); -} - -/* Header Contact Button - Outlined */ -.header .btn-coral { - background-color: transparent; - border: 1.5px solid var(--color-white); - color: var(--color-white); - padding: 10px 28px; -} - -.header .btn-coral:hover { - background-color: var(--color-white); - color: var(--color-primary); -} - -/* Mobile Menu Button */ -.mobile-menu-btn { - display: none; - flex-direction: column; - justify-content: center; - gap: 5px; - width: 30px; - height: 30px; - background: none; - border: none; - cursor: pointer; - padding: 0; -} - -.mobile-menu-btn span { - display: block; - width: 100%; - height: 2px; - background-color: var(--color-white); - transition: all var(--transition-fast); -} - -.header.scrolled .mobile-menu-btn span { - background-color: var(--color-dark); -} - -/* Mobile Navigation */ -.mobile-nav { - display: none; - position: fixed; - top: 60px; - left: 0; - right: 0; - background-color: var(--color-white); - padding: var(--spacing-lg); - flex-direction: column; - gap: var(--spacing-md); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); - z-index: 99; -} - -.mobile-nav.active { - display: flex; -} - -.mobile-nav-link { - font-size: 1rem; - color: var(--color-dark); - padding: var(--spacing-xs) 0; -} - -/* Hero Section */ -.hero { - position: relative; - min-height: 100vh; - display: flex; - align-items: center; - padding: calc(var(--spacing-xxl) + 60px) 0 var(--spacing-xxl); - overflow: hidden; -} - -.hero-background { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: -1; -} - -.hero-bg-image { - width: 100%; - height: 100%; - object-fit: cover; -} - -.hero-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); -} - -.hero-content { - max-width: 700px; - color: var(--color-white); -} - -.hero-intro { - font-family: var(--font-display); - font-size: 32px; - margin-bottom: var(--spacing-xs); - color: rgba(255, 255, 255, 0.9); -} - -.hero-intro .highlight { - color: #FE795D; - font-weight: 700; -} - -.hero-title { - font-family: var(--font-display); - font-size: 56px; - font-weight: 400; - margin-bottom: var(--spacing-md); - color: var(--color-white); - line-height: 1.1; -} - -.hero-tagline { - font-family: var(--font-display); - font-size: 28px; - margin-bottom: var(--spacing-lg); - color: rgba(255, 255, 255, 0.9); - font-style: italic; - font-weight: 300; -} - -.hero-tagline .highlight { - color: var(--color-white); - font-style: italic; -} - -.hero-decoration { - position: absolute; - pointer-events: none; - opacity: 0.15; -} - -.hero-decoration-left { - left: 0; - bottom: 0; - width: 300px; -} - -.hero-decoration-right { - right: 0; - top: 50%; - transform: translateY(-50%); - width: 300px; -} - -.hero-decoration img { - width: 100%; - height: auto; -} - -/* Section */ -.section { - padding: var(--spacing-xxl) 0; -} - -.section-header { - margin-bottom: 48px; -} - -.section-label { - display: block; - font-size: 0.75rem; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.1em; - color: var(--color-primary); - margin-bottom: var(--spacing-xs); -} - -.section-label-light { - color: rgba(255, 255, 255, 0.7); -} - -.section-title { - font-family: var(--font-display); - font-size: 40px; - color: var(--color-primary); -} - -.section-title-light { - color: var(--color-white); -} - -/* Services Section */ -.services { - background-color: var(--color-white); -} - -.section-header-row { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: var(--spacing-lg); -} - -.section-header-row .section-title { - margin-bottom: 0; -} - -.services-intro { - max-width: 900px; - margin-bottom: var(--spacing-xxl); -} - -.services-intro p { - font-family: var(--font-body); - font-size: 16px; - color: var(--color-text-light); - margin-bottom: var(--spacing-md); - line-height: 1.8; -} - -.services-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: var(--spacing-md); -} - -.service-card { - background-color: #F0F0F0; - border-radius: 16px; - padding: 32px; - font-family: var(--font-body); - font-size: 16px; -} - -.service-card:hover { - background-color: #E8E8E8; -} - -.service-icon { - width: 48px; - height: 48px; - margin-bottom: var(--spacing-md); -} - -.service-icon img, -.service-icon svg { - width: 100%; - height: 100%; -} - -.service-title { - font-family: var(--font-body); - font-size: 18px; - font-weight: 700; - margin-bottom: var(--spacing-sm); - color: var(--color-dark); -} - -.service-description { - font-family: var(--font-body); - font-size: 14px; - color: var(--color-text-light); - line-height: 1.7; -} - -/* Case Studies Section */ -.case-studies { - background-color: var(--color-light-grey); -} - -.case-studies-intro { - max-width: 900px; - margin-bottom: var(--spacing-xxl); -} - -.case-studies-intro p { - font-family: var(--font-body); - font-size: 16px; - color: var(--color-text-light); - margin-bottom: var(--spacing-md); - line-height: 1.8; -} - -.case-studies-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: var(--spacing-lg); -} - -.case-study-card { - background-color: var(--color-white); - border-radius: var(--radius-md); - overflow: hidden; - display: flex; - flex-direction: column; - transition: transform var(--transition-base), box-shadow var(--transition-base); -} - -.case-study-card:hover { - transform: translateY(-4px); - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); -} - -.case-study-image { - position: relative; - width: 100%; - height: 220px; - overflow: hidden; - background-color: var(--color-dark); -} - -.case-study-image img { - width: 100%; - height: 100%; - object-fit: cover; -} - -.case-study-tag { - position: absolute; - top: var(--spacing-sm); - left: var(--spacing-sm); - padding: 0.25rem 0.75rem; - font-size: 0.7rem; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.05em; - border-radius: var(--radius-sm); - background-color: var(--color-white); - color: var(--color-dark); -} - -/* Coming Soon Overlay */ -.case-study-link-wrapper { - position: relative; - margin-top: auto; -} - -.coming-soon-overlay { - position: absolute; - bottom: 0; - left: 0; - right: 0; - transform: translateY(100%); - opacity: 0; - transition: transform var(--transition-base), opacity var(--transition-base); - z-index: 10; -} - -.case-study-card.show-coming-soon .coming-soon-overlay { - transform: translateY(0); - opacity: 1; -} - -.coming-soon-btn { - display: block; - padding: 0.75rem 1.5rem; - background-color: #9B78F4; - color: var(--color-white); - font-family: var(--font-body); - font-size: 14px; - font-weight: 500; - border-radius: var(--radius-sm); - text-align: center; - cursor: pointer; -} - -.case-study-content { - padding: 24px; - display: flex; - flex-direction: column; - flex: 1; -} - -.case-study-title { - font-family: var(--font-display); - font-size: 18px; - font-weight: 400; - margin-bottom: var(--spacing-xs); -} - -.case-study-description { - font-family: var(--font-body); - font-size: 14px; - color: var(--color-text-light); - margin-bottom: var(--spacing-sm); - line-height: 1.6; - flex: 1; -} - -.case-study-link { - display: inline-flex; - align-items: center; - gap: var(--spacing-xs); - font-family: var(--font-body); - font-size: 14px; - font-weight: 500; - color: var(--color-primary); -} - -.case-study-link:hover { - color: var(--color-primary-dark); -} - -/* Collaboration CTA */ -.collaboration-cta { - background-color: #9B78F8; - padding: 80px 0; - text-align: center; -} - -.collaboration-title { - font-family: var(--font-display); - font-size: 40px; - color: var(--color-white); - margin-bottom: var(--spacing-sm); -} - -.collaboration-text { - font-family: var(--font-body); - color: rgba(255, 255, 255, 0.9); - font-size: 16px; - margin-bottom: var(--spacing-lg); - max-width: 600px; - margin-left: auto; - margin-right: auto; -} - -.collaboration-cta .btn-outline-white { - padding: 10px 38px; -} - -/* How We Work Section */ -.how-we-work { - background-color: var(--color-white); -} - -.steps-list { - max-width: 1010px; -} - -.step-item { - display: flex; - gap: var(--spacing-lg); - padding: var(--spacing-sm) var(--spacing-md); - margin: 0 calc(-1 * var(--spacing-md)); - border-radius: 25px; - transition: background-color var(--transition-base); -} - -.step-item.active { - background-color: var(--color-primary); -} - -.step-number { - font-family: var(--font-display); - font-size: 32px; - font-weight: 400; - color: var(--color-primary); - min-width: 60px; - transition: color var(--transition-base); -} - -.step-item.active .step-number { - color: var(--color-white); -} - -.step-content { - flex: 1; -} - -.step-title { - font-family: var(--font-body); - font-size: 20px; - font-weight: 700; - margin-bottom: var(--spacing-xs); - color: #FE795D; - transition: color var(--transition-base); -} - -.step-item.active .step-title { - color: var(--color-white); -} - -.step-description { - font-family: var(--font-body); - font-size: 16px; - color: #FE795D; - line-height: 1.7; - transition: color var(--transition-base); -} - -.step-item.active .step-description { - color: rgba(255, 255, 255, 0.9); -} - -/* Contact Section */ -.contact { - position: relative; - padding: var(--spacing-xxl) 0; - overflow: hidden; -} - -.contact-background { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: -1; -} - -.contact-bg-image { - width: 100%; - height: 100%; - object-fit: cover; -} - -.contact-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.4); -} - -.contact .section-header { - text-align: center; - margin-bottom: var(--spacing-xxl); -} - -.contact-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: var(--spacing-xxl); - max-width: 1000px; - margin: 0 auto; -} - -.contact-info { - color: var(--color-dark); - background-color: rgba(255, 255, 255, 0.95); - border-radius: var(--radius-md); - padding: var(--spacing-lg); -} - -.contact-info-title { - font-size: 1.5rem; - color: var(--color-dark); - margin-bottom: var(--spacing-sm); -} - -.contact-info-text { - color: var(--color-dark); - margin-bottom: var(--spacing-lg); -} - -.contact-details { - display: flex; - flex-direction: column; - gap: var(--spacing-md); -} - -.contact-detail { - display: flex; - flex-direction: column; -} - -.contact-detail-label { - font-size: 0.75rem; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.1em; - color: var(--color-dark); - margin-bottom: 4px; -} - -.contact-detail-value { - font-size: 1rem; - color: var(--color-dark); -} - -.contact-form { - background-color: rgba(255, 255, 255, 0.8); - border-radius: var(--radius-md); - padding: var(--spacing-lg); -} - -.form-group { - margin-bottom: var(--spacing-md); -} - -.form-label { - display: block; - font-size: 1rem; - font-weight: 500; - color: var(--color-dark); - margin-bottom: var(--spacing-xs); -} - -.form-input, -.form-textarea { - width: 100%; - padding: 0.875rem 1rem; - font-family: var(--font-body); - font-size: 1rem; - color: var(--color-dark); - background-color: rgba(255, 255, 255, 0.5); - border: 2px solid transparent; - border-radius: var(--radius-sm); - transition: border-color var(--transition-fast); -} - -.form-input:focus, -.form-textarea:focus { - outline: none; - border-color: var(--color-primary); - background-color: rgba(255, 255, 255, 0.7); -} - -.form-textarea { - min-height: 120px; - resize: vertical; -} - -/* Footer */ -.footer { - position: relative; - background-color: var(--color-primary); - color: var(--color-white); - padding: var(--spacing-xxl) 0 var(--spacing-lg); - overflow: hidden; -} - -.footer-grid { - display: grid; - grid-template-columns: 2fr 1fr 1fr; - gap: var(--spacing-lg); - margin-bottom: var(--spacing-xxl); - max-width: 700px; -} - -.footer-brand .logo-text { - color: var(--color-white); - font-size: 1.5rem; -} - -.footer-logo-img { - height: 40px; - width: auto; -} - -.footer-nav-title { - font-size: 0.75rem; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.1em; - color: rgba(255, 255, 255, 0.7); - margin-bottom: var(--spacing-md); -} - -.footer-nav-list { - list-style: none; -} - -.footer-nav-list li { - margin-bottom: var(--spacing-xs); -} - -.footer-nav-list a { - color: var(--color-white); - font-size: 0.9rem; - transition: opacity var(--transition-fast); -} - -.footer-nav-list a:hover { - opacity: 0.8; - color: var(--color-white); -} - -.footer-bottom { - display: flex; - align-items: center; - gap: var(--spacing-lg); - padding-top: var(--spacing-lg); - border-top: 1px solid rgba(255, 255, 255, 0.2); - max-width: 700px; -} - -.footer-copyright { - font-size: 0.8rem; - color: rgba(255, 255, 255, 0.8); - padding-right: var(--spacing-lg); - border-right: 1px solid rgba(255, 255, 255, 0.2); -} - -.footer-legal { - display: flex; - gap: var(--spacing-md); -} - -.footer-legal a { - font-size: 0.8rem; - color: rgba(255, 255, 255, 0.8); -} - -.footer-legal a:hover { - color: var(--color-white); -} - -.footer-decoration { - position: absolute; - right: -50px; - top: 0; - bottom: 0; - width: 600px; - pointer-events: none; -} - -.footer-decoration img { - width: 100%; - height: 100%; - object-fit: cover; - object-position: left center; -} - -/* Responsive */ -@media (max-width: 1024px) { - .services-grid { - grid-template-columns: repeat(2, 1fr); - } - - .case-studies-grid { - grid-template-columns: repeat(2, 1fr); - } - - .footer-grid { - grid-template-columns: 1fr 1fr; - } -} - -@media (max-width: 768px) { - h1, .hero-title { - font-size: 2.5rem; - } - - h2, .section-title { - font-size: 2rem; - } - - .nav { - display: none; - } - - .mobile-menu-btn { - display: flex; - } - - .hero { - padding-top: 100px; - } - - .services-grid { - grid-template-columns: 1fr; - } - - .case-studies-grid { - grid-template-columns: 1fr; - } - - .contact-grid { - grid-template-columns: 1fr; - } - - .contact-info { - text-align: center; - } - - .contact-details { - align-items: center; - } - - .footer-grid { - grid-template-columns: 1fr; - text-align: center; - } - - .footer-bottom { - flex-direction: column; - gap: var(--spacing-sm); - text-align: center; - } - - .step-item { - flex-direction: column; - gap: var(--spacing-sm); - } - - .step-number { - min-width: auto; - } -} - -@media (max-width: 480px) { - .hero-title { - font-size: 2rem; - } - - .section-title { - font-size: 1.75rem; - } - - .collaboration-title { - font-size: 1.75rem; - } -} diff --git a/index.html b/index.html deleted file mode 100644 index bcbff67..0000000 --- a/index.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - - No Box Dev - We build web and mobile applications - - - - - - - - - - - -
-
- -
-
-
-
-

At No Box Dev,

-

We build web and mobile applications

-

- Shaped by psychology,
- Enhanced by AI. -

- Contact us now -
-
- -
- -
-
- -
-
- - -
-
-
-

Our Services

- Contact us -
-
-

We design and build digital products that help founders move forward with focus and confidence. With years of experience across technology, entrepreneurship, and product development. We know what it takes to turn an idea into a working, scalable application.

-

What sets us apart is how we combine technical expertise with psychology. With a psychologist on board, we look beyond screens and features. We focus on how people think, decide, hesitate, and act. We design for motivation, reduce friction, and shape behavior with intention.

-

This leads to applications that don't just function, but make sense to the people using them. Products that feel intuitive, lower cognitive load, and support real adoption.

-

Whether you're building an MVP, improving an existing product, or developing an application end to end, we support the full journey from idea to launch: with structure, clarity, and shared ownership throughout.

-
- -
-
-
- App Design -
-

App Design & Prototyping

-

We design clear, modern interfaces that are easy to use. We create layouts and components that make your product feel natural, strengthen your brand, and help users understand what to do without thinking.

-
- -
-
- MVP Development -
-

Web & Mobile MVP Development

-

Launch a functional MVP that's ready for real users. We build fast, scalable web and mobile applications using no-code/low-code technology. The result: quick delivery without compromising on quality.

-
- -
-
- Full-Stack Development -
-

Full-Stack Development

-

We build the systems that make the product work. From APIs to databases, workflows and integrations, we create reliable back-end systems that scale as your product grows.

-
- -
-
- AI Integration -
-

AI Integration

-

We build applications where AI supports the purpose of the product. We combine psychology and AI so that users get what they need to do more easily, making the product smarter without making it complicated.

-
-
-
-
- - -
-
-
-

Case studies

-
-
-

Working together is a partnership, and choosing the right partner matters. The best way to see if we're the right fit is by looking at the work we've built together with our clients.

-

Each project shows how we collaborate: hands-on, committed, and closely involved. We take the time to understand the challenge, think alongside you, and stay present throughout the entire process. No layers, no distance, just clear communication and shared responsibility.

-

The projects below show not only what we deliver, but how we work: structured, transparent, and always in partnership.

-

If this way of working aligns with how you like to build, we'd be glad to explore what we can create together.

-
- -
-
-
- Playnist app screens - Community Application -
-
-

Playnist

-

Playnist set out to create a retro-inspired gaming platform that feels both nostalgic and modern — intuitive for players, visually rooted in classic game design, and technically efficient.

- -
-
- -
-
- Baseline dashboard - Mobile App -
-
-

Baseline

-

Baseline set out to create a science-based application that helps people de-stress through grounding, guided moments of reflection and breathing.

- -
-
- -
-
- Read with Robin app - Givtech -
-
-

Read with Robin

-

Robins' entrepreneur who understands the importance of reading with children—and the short attention spans they often have—set out to create an app that makes shared reading more engaging and fun.

- -
-
- -
-
- Klachtenbureau dashboard - SAAS Platform -
-
-

Klachtenbureau

-

Klachtenbureau set out to create a transparent and accessible platform for managing and resolving complaints.

- -
-
-
-
-
- - -
-
-

We bring collaboration back

-

We collaborate with founders and teams to build clear, human-centered digital products.
Get in touch to explore working together.

- Contact us -
-
- - -
-
-
- -

How We Work

-
- -
-
-
01
-
-

Understand

-

Every project begins with getting clear on what you're building and why. We take time to understand the product, the users, and the behavior you want to support. This is also where you get to know how we work and whether the collaboration feels right on both sides.

-
-
- -
-
02
-
-

Plan

-

Once there's clarity, we agree on scope, timeline, and priorities. No open-ended builds. No vague promises. You'll know what we're delivering when, and what decisions still need to be made along the way. We build in focused iterations.

-
-
- -
-
03
-
-

Build

-

We work in short, focused cycles and meet regularly to review progress. You're closely involved throughout the process, so there are no surprises and no distance between idea and execution.

-
-
- -
-
04
-
-

Track

-

You can follow progress in your dashboard and share feedback as we go. This keeps communication clear, decisions fast, and the product aligned with your goals.

-
-
- -
-
05
-
-

Launch

-

We don't build endlessly, and we don't ship half-finished work. What we deliver is a product that works, is structured, and is ready to be used and built upon.

-
-
-
-
-
- - -
-
- -
-
-
-
- -

Let's Build Something Great Together

-
- -
-
-

Let's get in touch

-

We'd love to hear about your project.
Fill out the form and we'll get back to you soon.

- -
-
- Location - Available Worldwide -
-
- Response Time - Usually within 24 hours -
-
-
- -
- - - - - -
- - -
- -
- - -
- -
- - -
- - -
-
-
-
- - - - - - - diff --git a/index.njk b/index.njk new file mode 100644 index 0000000..923ae40 --- /dev/null +++ b/index.njk @@ -0,0 +1,292 @@ +--- +layout: base.njk +title: "No Box Dev — We build web and mobile applications" +description: "No Box Dev builds web and mobile applications shaped by psychology and enhanced by AI. We collaborate with founders and teams to build clear, human-centered digital products." +ogTitle: "No Box Dev — Web & Mobile Applications" +ogDescription: "We build web and mobile applications shaped by psychology and enhanced by AI." +canonical: "https://noboxdev.com/" +permalink: "/index.html" +--- + + +
+ +
+
+
+
+
+

We build digital
productsexperiencesplatformssolutions

+

Shaped by psychology, enhanced by AI.
We partner with founders to turn ideas into applications people actually love using.

+ +
+
+ +
+ + + + + + + + + + +
+
+ + +
+
+
+ +

Our Services

+
+
+

We design and build digital products that help founders move forward with focus and confidence. With years of experience across technology, entrepreneurship, and product development, we know what it takes to turn an idea into a working, scalable application.

+

What sets us apart is how we combine technical expertise with psychology. With a psychologist on board, we look beyond screens and features. We focus on how people think, decide, hesitate, and act.

+
+ +
+
+
+ +
+

App Design & Prototyping

+

We design clear, modern interfaces that are easy to use. We create layouts and components that make your product feel natural, strengthen your brand, and help users understand what to do without thinking.

+
+ +
+
+ +
+

Web & Mobile MVP Development

+

Launch a functional MVP that's ready for real users. We build fast, scalable web and mobile applications using no-code/low-code technology. The result: quick delivery without compromising on quality.

+
+ +
+
+ +
+

Full-Stack Development

+

We build the systems that make the product work. From APIs to databases, workflows and integrations, we create reliable back-end systems that scale as your product grows.

+
+ +
+
+ +
+

AI Integration

+

We build applications where AI supports the purpose of the product. We combine psychology and AI so that users get what they need more easily, making the product smarter without making it complicated.

+
+
+
+
+ + +
+
+
+ +

Case Studies

+
+
+

Working together is a partnership, and choosing the right partner matters. The best way to see if we're the right fit is by looking at the work we've built together with our clients.

+

Each project shows how we collaborate: hands-on, committed, and closely involved.

+
+ +
+
+
+ Playnist app screens + Community Application +
+
+

Playnist

+

Playnist set out to create a retro-inspired gaming platform that feels both nostalgic and modern — intuitive for players, visually rooted in classic game design, and technically efficient.

+ +
+
+ +
+
+ Baseline dashboard + Mobile App +
+
+

Baseline

+

Baseline set out to create a science-based application that helps people de-stress through grounding, guided moments of reflection and breathing.

+ +
+
+ +
+
+ Read with Robin app + Givtech +
+
+

Read with Robin

+

Robin's entrepreneur who understands the importance of reading with children — and the short attention spans they often have — set out to create an app that makes shared reading more engaging and fun.

+ +
+
+ +
+
+ Klachtenbureau dashboard + SAAS Platform +
+
+

Klachtenbureau

+

Klachtenbureau set out to create a transparent and accessible platform for managing and resolving complaints.

+ +
+
+
+
+
+ + +
+
+

We bring collaboration back

+

We collaborate with founders and teams to build clear, human-centered digital products. Get in touch to explore working together.

+ Contact us +
+
+ + +
+
+
+ +

How We Work

+
+ +
+
+
01
+
+

Understand

+

Every project begins with getting clear on what you're building and why. We take time to understand the product, the users, and the behavior you want to support. This is also where you get to know how we work and whether the collaboration feels right on both sides.

+
+
+ +
+
02
+
+

Plan

+

Once there's clarity, we agree on scope, timeline, and priorities. No open-ended builds. No vague promises. You'll know what we're delivering when, and what decisions still need to be made along the way.

+
+
+ +
+
03
+
+

Build

+

We work in short, focused cycles and meet regularly to review progress. You're closely involved throughout the process, so there are no surprises and no distance between idea and execution.

+
+
+ +
+
04
+
+

Track

+

You can follow progress in your dashboard and share feedback as we go. This keeps communication clear, decisions fast, and the product aligned with your goals.

+
+
+ +
+
05
+
+

Launch

+

We don't build endlessly, and we don't ship half-finished work. What we deliver is a product that works, is structured, and is ready to be used and built upon.

+
+
+
+
+
+ + +
+
+
+ +

Let's Build Something Great Together

+
+ +
+
+

Let's get in touch

+

We'd love to hear about your project. Fill out the form and we'll get back to you soon.

+ +
+
Location
+

Available Worldwide

+
+
+
Response Time
+

Usually within 24 hours

+
+
+ +
+
+ + + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ +
+

Message sent!

+

We'll get back to you soon.

+
+
+
+
+
diff --git a/js/script.js b/js/script.js deleted file mode 100644 index a1018d6..0000000 --- a/js/script.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * NoBoxDev Website JavaScript - */ - -// Header scroll effect -const header = document.getElementById('header'); - -window.addEventListener('scroll', () => { - if (window.scrollY > 50) { - header.classList.add('scrolled'); - } else { - header.classList.remove('scrolled'); - } -}); - -// Mobile menu toggle -const mobileMenuBtn = document.getElementById('mobile-menu-btn'); -const mobileNav = document.getElementById('mobile-nav'); - -if (mobileMenuBtn && mobileNav) { - mobileMenuBtn.addEventListener('click', () => { - mobileNav.classList.toggle('active'); - mobileMenuBtn.classList.toggle('active'); - }); - - // Close mobile menu when clicking a link - mobileNav.querySelectorAll('a').forEach(link => { - link.addEventListener('click', () => { - mobileNav.classList.remove('active'); - mobileMenuBtn.classList.remove('active'); - }); - }); -} - -// Smooth scroll for anchor links -document.querySelectorAll('a[href^="#"]').forEach(anchor => { - anchor.addEventListener('click', function (e) { - const href = this.getAttribute('href'); - - // Skip if it's just "#" - if (href === '#') return; - - e.preventDefault(); - - const target = document.querySelector(href); - if (target) { - const headerOffset = 80; - const elementPosition = target.getBoundingClientRect().top; - const offsetPosition = elementPosition + window.pageYOffset - headerOffset; - - window.scrollTo({ - top: offsetPosition, - behavior: 'smooth' - }); - } - }); -}); - -// Coming Soon overlay for case study cards -const caseStudyCards = document.querySelectorAll('.case-study-card[data-coming-soon]'); - -caseStudyCards.forEach(card => { - const linkWrapper = card.querySelector('.case-study-link-wrapper'); - const link = card.querySelector('.case-study-link'); - const overlay = card.querySelector('.coming-soon-overlay'); - - if (link && overlay && linkWrapper) { - // Show overlay when clicking the case study link - link.addEventListener('click', (e) => { - e.preventDefault(); - card.classList.add('show-coming-soon'); - }); - - // Hide overlay when clicking on it - overlay.addEventListener('click', (e) => { - e.stopPropagation(); - card.classList.remove('show-coming-soon'); - }); - } -}); - -// How We Work - Scroll-based step highlighting -const stepItems = document.querySelectorAll('.step-item'); -const howWeWorkSection = document.getElementById('how-we-work'); - -function updateActiveStep() { - if (!howWeWorkSection || stepItems.length === 0) return; - - const sectionRect = howWeWorkSection.getBoundingClientRect(); - const sectionTop = sectionRect.top; - const sectionHeight = sectionRect.height; - const windowHeight = window.innerHeight; - - // Only activate when section is in view - if (sectionTop > windowHeight || sectionTop + sectionHeight < 0) { - return; - } - - // Calculate which step should be active based on scroll position within the section - const scrollProgress = Math.max(0, Math.min(1, (windowHeight / 2 - sectionTop) / sectionHeight)); - const activeIndex = Math.min(Math.floor(scrollProgress * stepItems.length), stepItems.length - 1); - - // Update active class - stepItems.forEach((step, index) => { - if (index === activeIndex) { - step.classList.add('active'); - } else { - step.classList.remove('active'); - } - }); -} - -// Run on scroll and load -window.addEventListener('scroll', updateActiveStep); -window.addEventListener('load', updateActiveStep); - -// Form submission feedback -const contactForm = document.querySelector('.contact-form'); -if (contactForm) { - contactForm.addEventListener('submit', function() { - const submitBtn = this.querySelector('button[type="submit"]'); - submitBtn.textContent = 'Sending...'; - submitBtn.disabled = true; - }); -} - -// Intersection Observer for animations -const observerOptions = { - root: null, - rootMargin: '0px', - threshold: 0.1 -}; - -const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - entry.target.classList.add('animate-in'); - } - }); -}, observerOptions); - -// Observe elements for animation -document.querySelectorAll('.service-card, .case-study-card').forEach(el => { - observer.observe(el); -}); diff --git a/main.js b/main.js new file mode 100644 index 0000000..8108302 --- /dev/null +++ b/main.js @@ -0,0 +1,872 @@ +/* ============================================ + No Box Dev + Nav, scroll reveals, hero variants, form + ============================================ */ + +document.addEventListener('DOMContentLoaded', () => { + + const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + const isTouch = window.matchMedia('(pointer: coarse)').matches; + + // --- Sticky Nav --- + const nav = document.querySelector('.nav'); + if (nav) { + const onScroll = () => nav.classList.toggle('scrolled', window.scrollY > 40); + window.addEventListener('scroll', onScroll, { passive: true }); + onScroll(); + } + + // --- Mobile Nav Toggle --- + const toggle = document.querySelector('.nav-toggle'); + const navLinks = document.querySelector('.nav-links'); + const backdrop = document.querySelector('.nav-backdrop'); + + function closeNav() { + if (!toggle || !navLinks) return; + toggle.classList.remove('open'); + navLinks.classList.remove('open'); + document.body.classList.remove('nav-open'); + if (nav) nav.classList.remove('nav-open'); + if (backdrop) backdrop.classList.remove('active'); + } + + function openNav() { + if (!toggle || !navLinks) return; + toggle.classList.add('open'); + navLinks.classList.add('open'); + document.body.classList.add('nav-open'); + if (nav) nav.classList.add('nav-open'); + if (backdrop) backdrop.classList.add('active'); + } + + if (toggle && navLinks) { + toggle.addEventListener('click', () => { + navLinks.classList.contains('open') ? closeNav() : openNav(); + }); + navLinks.querySelectorAll('a').forEach(a => a.addEventListener('click', closeNav)); + if (backdrop) backdrop.addEventListener('click', closeNav); + document.addEventListener('keydown', e => { + if (e.key === 'Escape' && navLinks.classList.contains('open')) closeNav(); + }); + } + + // --- Active Nav Link --- + const path = location.pathname.replace(/\/+$/, '') || '/'; + document.querySelectorAll('.nav-links a:not(.btn)').forEach(a => { + const href = a.getAttribute('href'); + if (href === path || (path === '' && href === '/')) a.classList.add('active'); + }); + + // --- Scroll Reveal --- + const reveals = document.querySelectorAll('.reveal, .reveal-stagger'); + if (reveals.length) { + const obs = new IntersectionObserver(entries => { + entries.forEach(e => { + if (e.isIntersecting) { e.target.classList.add('visible'); obs.unobserve(e.target); } + }); + }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' }); + reveals.forEach(el => obs.observe(el)); + } + + // --- Step Highlighting --- + const steps = document.querySelectorAll('.step-item'); + if (steps.length) { + function hlSteps() { + const mid = window.innerHeight * 0.6; + steps.forEach(s => { + const r = s.getBoundingClientRect(); + s.classList.toggle('active', r.top < mid && r.bottom > mid * 0.3); + }); + } + window.addEventListener('scroll', hlSteps, { passive: true }); + hlSteps(); + } + + // --- Contact Form --- + const form = document.querySelector('#contact-form'); + const formOk = document.querySelector('.form-success'); + if (form) { + form.addEventListener('submit', () => { + const btn = form.querySelector('button[type="submit"]'); + btn.textContent = 'Sending...'; + btn.disabled = true; + if (formOk) setTimeout(() => { form.style.display = 'none'; formOk.classList.add('show'); }, 1000); + }); + } + + // ============================================ + // HERO SYSTEM — 10 Variants + Selector + // ============================================ + const hero = document.querySelector('.hero'); + if (!hero) return; + + // --- Word Rotation (shared across all variants) --- + const rotator = document.getElementById('hero-rotate'); + if (rotator && !reducedMotion) { + const words = rotator.querySelectorAll('.hero-rotate-word'); + let cur = 0; + setInterval(() => { + const prev = words[cur]; + cur = (cur + 1) % words.length; + const next = words[cur]; + prev.classList.add('exit'); + prev.classList.remove('active'); + next.classList.add('active'); + next.classList.remove('exit'); + setTimeout(() => prev.classList.remove('exit'), 600); + }, 3000); + } + + // --- Canvas setup --- + const canvas = document.getElementById('hero-canvas'); + if (!canvas) return; + const ctx = canvas.getContext('2d'); + const dpr = window.devicePixelRatio || 1; + + function resize() { + canvas.width = hero.offsetWidth * dpr; + canvas.height = hero.offsetHeight * dpr; + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + } + resize(); + window.addEventListener('resize', resize); + + const W = () => hero.offsetWidth; + const H = () => hero.offsetHeight; + + let mouseX = W() / 2, mouseY = H() / 2, mouseIn = false; + if (!isTouch) { + hero.addEventListener('mousemove', e => { + const r = hero.getBoundingClientRect(); + mouseX = e.clientX - r.left; + mouseY = e.clientY - r.top; + mouseIn = true; + }); + hero.addEventListener('mouseleave', () => { mouseIn = false; }); + } + + // Colors + const CORAL = '254,121,93'; + const PURPLE = '155,120,244'; + + // Animation state + let animId = null; + let variantState = {}; + + function stopAnim() { + if (animId) cancelAnimationFrame(animId); + animId = null; + variantState = {}; + } + + // --- Variant Selector --- + const selBtns = document.querySelectorAll('.hero-sel-btn'); + let activeVariant = 'particles'; + + selBtns.forEach(btn => { + btn.addEventListener('click', () => { + const v = btn.dataset.variant; + if (v === activeVariant) return; + selBtns.forEach(b => b.classList.remove('active')); + btn.classList.add('active'); + switchVariant(v); + }); + }); + + function switchVariant(v) { + stopAnim(); + activeVariant = v; + hero.dataset.variant = v; + ctx.clearRect(0, 0, W(), H()); + if (!reducedMotion) initVariant(v); + } + + function initVariant(v) { + switch (v) { + case 'particles': initParticles(); break; + case 'flow': initFlowField(); break; + case 'waves': initWaves(); break; + case 'constellation': initConstellation(); break; + case 'aurora': initAurora(); break; + case 'bubbles': initBubbles(); break; + case 'rings': initRings(); break; + case 'morph': initMorph(); break; + case 'grid': initGridWarp(); break; + case 'comet': initComets(); break; + } + } + + // ============================================= + // 1. PARTICLES — Magnetic connected dots + // ============================================= + function initParticles() { + const COUNT = isTouch ? 35 : 60; + const pts = []; + for (let i = 0; i < COUNT; i++) { + pts.push({ + x: Math.random() * W(), y: Math.random() * H(), + vx: (Math.random() - 0.5) * 0.3, vy: (Math.random() - 0.5) * 0.3, + r: Math.random() * 2 + 1.5, + color: Math.random() > 0.5 ? CORAL : PURPLE + }); + } + variantState.pts = pts; + + function draw() { + ctx.clearRect(0, 0, W(), H()); + const { pts } = variantState; + + pts.forEach(p => { + p.x += p.vx; p.y += p.vy; + if (p.x < -10) p.x = W() + 10; + if (p.x > W() + 10) p.x = -10; + if (p.y < -10) p.y = H() + 10; + if (p.y > H() + 10) p.y = -10; + + if (mouseIn) { + const dx = mouseX - p.x, dy = mouseY - p.y; + const d = Math.sqrt(dx * dx + dy * dy); + if (d < 200 && d > 1) { + const f = (1 - d / 200) * 0.02; + p.vx += dx / d * f; + p.vy += dy / d * f; + } + } + p.vx *= 0.995; p.vy *= 0.995; + }); + + for (let i = 0; i < pts.length; i++) { + for (let j = i + 1; j < pts.length; j++) { + const dx = pts[i].x - pts[j].x, dy = pts[i].y - pts[j].y; + const d = Math.sqrt(dx * dx + dy * dy); + if (d < 140) { + ctx.strokeStyle = `rgba(${pts[i].color},${(1 - d / 140) * 0.12})`; + ctx.lineWidth = 0.8; + ctx.beginPath(); + ctx.moveTo(pts[i].x, pts[i].y); + ctx.lineTo(pts[j].x, pts[j].y); + ctx.stroke(); + } + } + } + + pts.forEach(p => { + ctx.fillStyle = `rgba(${p.color},0.06)`; + ctx.beginPath(); ctx.arc(p.x, p.y, p.r * 5, 0, Math.PI * 2); ctx.fill(); + ctx.fillStyle = `rgba(${p.color},0.5)`; + ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2); ctx.fill(); + }); + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 2. FLOW FIELD — Particles following noise + // ============================================= + function initFlowField() { + // Simple noise via sine combinations + function noise(x, y, t) { + return Math.sin(x * 0.01 + t) * Math.cos(y * 0.012 - t * 0.7) + + Math.sin((x + y) * 0.008 + t * 0.5) * 0.5; + } + + const COUNT = isTouch ? 200 : 400; + const pts = []; + for (let i = 0; i < COUNT; i++) { + pts.push({ + x: Math.random() * W(), y: Math.random() * H(), + prevX: 0, prevY: 0, + speed: Math.random() * 1.5 + 0.5, + color: Math.random() > 0.5 ? CORAL : PURPLE, + alpha: Math.random() * 0.3 + 0.1, + life: Math.random() * 200 + }); + } + variantState = { pts, time: 0 }; + + function draw() { + // Fade trail + ctx.fillStyle = 'rgba(250,250,248,0.06)'; + ctx.fillRect(0, 0, W(), H()); + variantState.time += 0.008; + const t = variantState.time; + + variantState.pts.forEach(p => { + p.prevX = p.x; p.prevY = p.y; + const angle = noise(p.x, p.y, t) * Math.PI * 2; + p.x += Math.cos(angle) * p.speed; + p.y += Math.sin(angle) * p.speed; + p.life++; + + if (p.x < 0 || p.x > W() || p.y < 0 || p.y > H() || p.life > 300) { + p.x = Math.random() * W(); + p.y = Math.random() * H(); + p.prevX = p.x; p.prevY = p.y; + p.life = 0; + } + + ctx.strokeStyle = `rgba(${p.color},${p.alpha})`; + ctx.lineWidth = 1.2; + ctx.beginPath(); + ctx.moveTo(p.prevX, p.prevY); + ctx.lineTo(p.x, p.y); + ctx.stroke(); + }); + + animId = requestAnimationFrame(draw); + } + + // Clear first + ctx.fillStyle = 'rgba(250,250,248,1)'; + ctx.fillRect(0, 0, W(), H()); + draw(); + } + + // ============================================= + // 3. WAVES — Layered flowing sine waves + // ============================================= + function initWaves() { + variantState.time = 0; + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 0.015; + const t = variantState.time; + const w = W(), h = H(); + const mid = h * 0.55; + + const layers = [ + { color: CORAL, alpha: 0.08, amp: 60, freq: 0.003, speed: 1, yOff: 0 }, + { color: PURPLE, alpha: 0.06, amp: 45, freq: 0.004, speed: -0.7, yOff: 30 }, + { color: CORAL, alpha: 0.05, amp: 35, freq: 0.005, speed: 1.3, yOff: 60 }, + { color: PURPLE, alpha: 0.04, amp: 50, freq: 0.002, speed: -0.5, yOff: -20 }, + { color: CORAL, alpha: 0.07, amp: 25, freq: 0.006, speed: 0.9, yOff: 90 }, + ]; + + layers.forEach(l => { + ctx.fillStyle = `rgba(${l.color},${l.alpha})`; + ctx.beginPath(); + ctx.moveTo(0, h); + + for (let x = 0; x <= w; x += 3) { + const y = mid + l.yOff + + Math.sin(x * l.freq + t * l.speed) * l.amp + + Math.sin(x * l.freq * 2.3 + t * l.speed * 0.7) * l.amp * 0.3; + ctx.lineTo(x, y); + } + + ctx.lineTo(w, h); + ctx.closePath(); + ctx.fill(); + }); + + // Mouse ripple + if (mouseIn) { + ctx.strokeStyle = `rgba(${CORAL},0.15)`; + ctx.lineWidth = 2; + ctx.beginPath(); + for (let x = 0; x <= w; x += 3) { + const dx = x - mouseX; + const dist = Math.abs(dx); + const influence = Math.max(0, 1 - dist / 200); + const y = mid + Math.sin(x * 0.005 + t) * 40 - influence * 50 * Math.sin(t * 3); + x === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y); + } + ctx.stroke(); + } + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 4. CONSTELLATION — Interactive star mesh + // ============================================= + function initConstellation() { + const COUNT = isTouch ? 60 : 100; + const stars = []; + for (let i = 0; i < COUNT; i++) { + stars.push({ + x: Math.random() * W(), y: Math.random() * H(), + vx: (Math.random() - 0.5) * 0.15, vy: (Math.random() - 0.5) * 0.15, + r: Math.random() * 1.5 + 0.5, + brightness: Math.random(), + twinkleSpeed: Math.random() * 0.02 + 0.005 + }); + } + variantState = { stars, time: 0 }; + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 1; + const { stars, time } = variantState; + + stars.forEach(s => { + s.x += s.vx; s.y += s.vy; + if (s.x < 0) s.x = W(); if (s.x > W()) s.x = 0; + if (s.y < 0) s.y = H(); if (s.y > H()) s.y = 0; + }); + + // Connections — brighter near mouse + const connDist = 120; + for (let i = 0; i < stars.length; i++) { + for (let j = i + 1; j < stars.length; j++) { + const dx = stars[i].x - stars[j].x, dy = stars[i].y - stars[j].y; + const d = Math.sqrt(dx * dx + dy * dy); + if (d < connDist) { + let alpha = (1 - d / connDist) * 0.08; + // Boost near mouse + if (mouseIn) { + const mx = (stars[i].x + stars[j].x) / 2; + const my = (stars[i].y + stars[j].y) / 2; + const md = Math.sqrt((mx - mouseX) ** 2 + (my - mouseY) ** 2); + if (md < 200) alpha += (1 - md / 200) * 0.15; + } + ctx.strokeStyle = `rgba(255,255,255,${alpha})`; + ctx.lineWidth = 0.6; + ctx.beginPath(); + ctx.moveTo(stars[i].x, stars[i].y); + ctx.lineTo(stars[j].x, stars[j].y); + ctx.stroke(); + } + } + } + + // Draw stars + stars.forEach(s => { + const twinkle = (Math.sin(time * s.twinkleSpeed) + 1) / 2; + let alpha = 0.3 + twinkle * 0.5; + let glow = 0; + + // Brighten near mouse + if (mouseIn) { + const md = Math.sqrt((s.x - mouseX) ** 2 + (s.y - mouseY) ** 2); + if (md < 180) { + const boost = (1 - md / 180); + alpha = Math.min(1, alpha + boost * 0.5); + glow = boost * 15; + } + } + + if (glow > 0) { + ctx.fillStyle = `rgba(${CORAL},${alpha * 0.15})`; + ctx.beginPath(); ctx.arc(s.x, s.y, s.r + glow, 0, Math.PI * 2); ctx.fill(); + } + + ctx.fillStyle = `rgba(255,255,255,${alpha})`; + ctx.beginPath(); ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2); ctx.fill(); + }); + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 5. AURORA — Flowing gradient bands + // ============================================= + function initAurora() { + variantState.time = 0; + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 0.005; + const t = variantState.time; + const w = W(), h = H(); + + const bands = [ + { color1: [254, 121, 93], color2: [155, 120, 244], y: 0.3, width: 0.25, speed: 1 }, + { color1: [155, 120, 244], color2: [100, 180, 255], y: 0.45, width: 0.2, speed: -0.7 }, + { color1: [254, 121, 93], color2: [255, 180, 100], y: 0.55, width: 0.15, speed: 1.2 }, + { color1: [155, 120, 244], color2: [254, 121, 93], y: 0.65, width: 0.2, speed: -0.5 }, + ]; + + bands.forEach(band => { + const baseY = h * band.y; + const bw = h * band.width; + + for (let x = 0; x < w; x += 2) { + const wave = Math.sin(x * 0.003 + t * band.speed) * 40 + + Math.sin(x * 0.007 + t * band.speed * 1.5) * 20; + const y = baseY + wave; + const intensity = Math.sin(x * 0.002 + t * 0.3) * 0.5 + 0.5; + + const r = band.color1[0] + (band.color2[0] - band.color1[0]) * intensity; + const g = band.color1[1] + (band.color2[1] - band.color1[1]) * intensity; + const b = band.color1[2] + (band.color2[2] - band.color1[2]) * intensity; + + const grad = ctx.createLinearGradient(x, y - bw / 2, x, y + bw / 2); + grad.addColorStop(0, `rgba(${r},${g},${b},0)`); + grad.addColorStop(0.5, `rgba(${r},${g},${b},0.12)`); + grad.addColorStop(1, `rgba(${r},${g},${b},0)`); + + ctx.fillStyle = grad; + ctx.fillRect(x, y - bw / 2, 3, bw); + } + }); + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 6. BUBBLES — Soft floating circles + // ============================================= + function initBubbles() { + const COUNT = isTouch ? 12 : 20; + const bubbles = []; + for (let i = 0; i < COUNT; i++) { + bubbles.push({ + x: Math.random() * W(), y: Math.random() * H(), + r: Math.random() * 80 + 30, + vx: (Math.random() - 0.5) * 0.3, + vy: (Math.random() - 0.5) * 0.3 - 0.1, + color: Math.random() > 0.5 ? CORAL : PURPLE, + alpha: Math.random() * 0.08 + 0.03, + phase: Math.random() * Math.PI * 2 + }); + } + variantState = { bubbles, time: 0 }; + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 0.01; + const t = variantState.time; + + variantState.bubbles.forEach(b => { + b.x += b.vx + Math.sin(t + b.phase) * 0.3; + b.y += b.vy + Math.cos(t * 0.7 + b.phase) * 0.2; + + // Wrap + if (b.y < -b.r * 2) { b.y = H() + b.r; b.x = Math.random() * W(); } + if (b.x < -b.r * 2) b.x = W() + b.r; + if (b.x > W() + b.r * 2) b.x = -b.r; + + // Mouse push + if (mouseIn) { + const dx = b.x - mouseX, dy = b.y - mouseY; + const d = Math.sqrt(dx * dx + dy * dy); + if (d < 150 + b.r && d > 1) { + b.vx += dx / d * 0.08; + b.vy += dy / d * 0.08; + } + } + + b.vx *= 0.99; b.vy *= 0.99; + + const pulse = 1 + Math.sin(t * 2 + b.phase) * 0.05; + const r = b.r * pulse; + + // Gradient fill + const grad = ctx.createRadialGradient(b.x, b.y, 0, b.x, b.y, r); + grad.addColorStop(0, `rgba(${b.color},${b.alpha * 2})`); + grad.addColorStop(0.6, `rgba(${b.color},${b.alpha})`); + grad.addColorStop(1, `rgba(${b.color},0)`); + + ctx.fillStyle = grad; + ctx.beginPath(); + ctx.arc(b.x, b.y, r, 0, Math.PI * 2); + ctx.fill(); + + // Rim + ctx.strokeStyle = `rgba(${b.color},${b.alpha * 1.5})`; + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.arc(b.x, b.y, r * 0.85, 0, Math.PI * 2); + ctx.stroke(); + }); + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 7. RINGS — Concentric pulsing rings + // ============================================= + function initRings() { + variantState.time = 0; + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 0.008; + const t = variantState.time; + const cx = W() / 2, cy = H() / 2; + const maxR = Math.max(W(), H()) * 0.6; + const ringCount = 12; + + // Mouse offset + let ox = 0, oy = 0; + if (mouseIn) { + ox = (mouseX - cx) * 0.05; + oy = (mouseY - cy) * 0.05; + } + + for (let i = 0; i < ringCount; i++) { + const progress = i / ringCount; + const r = progress * maxR + Math.sin(t + i * 0.5) * 15; + const wobble = Math.sin(t * 2 + i) * 3; + + const color = i % 2 === 0 ? CORAL : PURPLE; + const alpha = (1 - progress) * 0.12 + Math.sin(t + i * 0.8) * 0.03; + + ctx.strokeStyle = `rgba(${color},${Math.max(0, alpha)})`; + ctx.lineWidth = 1.5 - progress * 0.8; + ctx.beginPath(); + ctx.ellipse( + cx + ox + wobble, + cy + oy + wobble * 0.5, + r, + r * (0.85 + Math.sin(t + i) * 0.05), + Math.sin(t * 0.3 + i * 0.2) * 0.1, + 0, Math.PI * 2 + ); + ctx.stroke(); + } + + // Center glow + const grad = ctx.createRadialGradient(cx + ox, cy + oy, 0, cx + ox, cy + oy, 120); + grad.addColorStop(0, `rgba(${CORAL},0.08)`); + grad.addColorStop(0.5, `rgba(${PURPLE},0.04)`); + grad.addColorStop(1, `rgba(${PURPLE},0)`); + ctx.fillStyle = grad; + ctx.fillRect(0, 0, W(), H()); + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 8. MORPH — Organic morphing blob shapes + // ============================================= + function initMorph() { + variantState.time = 0; + + function blobPath(cx, cy, r, points, t, speed, wobble) { + ctx.beginPath(); + for (let i = 0; i <= points; i++) { + const angle = (i / points) * Math.PI * 2; + const offset = Math.sin(angle * 3 + t * speed) * wobble + + Math.cos(angle * 2 - t * speed * 0.7) * wobble * 0.6; + const pr = r + offset; + const x = cx + Math.cos(angle) * pr; + const y = cy + Math.sin(angle) * pr; + i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y); + } + ctx.closePath(); + } + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 0.008; + const t = variantState.time; + const w = W(), h = H(); + + const blobs = [ + { cx: w * 0.7, cy: h * 0.35, r: 200, color: CORAL, alpha: 0.12, pts: 80, speed: 0.8, wobble: 40 }, + { cx: w * 0.3, cy: h * 0.6, r: 180, color: PURPLE, alpha: 0.10, pts: 80, speed: -0.6, wobble: 35 }, + { cx: w * 0.5, cy: h * 0.4, r: 140, color: CORAL, alpha: 0.06, pts: 80, speed: 1.1, wobble: 30 }, + ]; + + // Mouse influence + if (mouseIn) { + blobs[0].cx += (mouseX - w * 0.7) * 0.08; + blobs[0].cy += (mouseY - h * 0.35) * 0.08; + blobs[1].cx += (mouseX - w * 0.3) * -0.05; + blobs[1].cy += (mouseY - h * 0.6) * -0.05; + } + + blobs.forEach(b => { + // Blur effect via multiple layers + for (let layer = 3; layer >= 0; layer--) { + const lr = b.r + layer * 20; + const la = b.alpha * (1 - layer * 0.25); + ctx.fillStyle = `rgba(${b.color},${la})`; + blobPath(b.cx, b.cy, lr, b.pts, t, b.speed, b.wobble + layer * 8); + ctx.fill(); + } + }); + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 9. GRID WARP — Dot grid that distorts + // ============================================= + function initGridWarp() { + const spacing = isTouch ? 40 : 30; + variantState.time = 0; + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 0.01; + const t = variantState.time; + const w = W(), h = H(); + const cols = Math.ceil(w / spacing) + 2; + const rows = Math.ceil(h / spacing) + 2; + + for (let row = 0; row < rows; row++) { + for (let col = 0; col < cols; col++) { + let x = col * spacing; + let y = row * spacing; + + // Ambient wave + x += Math.sin(y * 0.02 + t) * 5; + y += Math.cos(x * 0.02 + t * 0.7) * 5; + + // Mouse warp + let warpStrength = 0; + if (mouseIn) { + const dx = x - mouseX, dy = y - mouseY; + const d = Math.sqrt(dx * dx + dy * dy); + if (d < 200 && d > 1) { + const push = (1 - d / 200) * 25; + x += dx / d * push; + y += dy / d * push; + warpStrength = 1 - d / 200; + } + } + + const baseAlpha = 0.1 + Math.sin(col * 0.3 + row * 0.3 + t) * 0.04; + const alpha = baseAlpha + warpStrength * 0.4; + const r = 1.5 + warpStrength * 2.5; + const color = (col + row) % 3 === 0 ? CORAL : PURPLE; + + ctx.fillStyle = `rgba(${color},${alpha})`; + ctx.beginPath(); + ctx.arc(x, y, r, 0, Math.PI * 2); + ctx.fill(); + } + } + + // Draw some connecting lines near mouse + if (mouseIn) { + for (let row = 0; row < rows - 1; row++) { + for (let col = 0; col < cols - 1; col++) { + let x1 = col * spacing + Math.sin(row * spacing * 0.02 + t) * 5; + let y1 = row * spacing + Math.cos(col * spacing * 0.02 + t * 0.7) * 5; + const dx1 = x1 - mouseX, dy1 = y1 - mouseY; + const d1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); + + if (d1 < 120) { + let x2 = (col + 1) * spacing + Math.sin((row) * spacing * 0.02 + t) * 5; + let y2 = row * spacing + Math.cos((col + 1) * spacing * 0.02 + t * 0.7) * 5; + let x3 = col * spacing + Math.sin((row + 1) * spacing * 0.02 + t) * 5; + let y3 = (row + 1) * spacing + Math.cos(col * spacing * 0.02 + t * 0.7) * 5; + + const a = (1 - d1 / 120) * 0.1; + ctx.strokeStyle = `rgba(${CORAL},${a})`; + ctx.lineWidth = 0.5; + ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); + ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x3, y3); ctx.stroke(); + } + } + } + } + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // ============================================= + // 10. COMETS — Particles with trailing tails + // ============================================= + function initComets() { + const COUNT = isTouch ? 8 : 15; + const comets = []; + for (let i = 0; i < COUNT; i++) { + comets.push(makeComet()); + } + variantState = { comets, time: 0 }; + + function makeComet() { + const angle = Math.random() * Math.PI * 2; + const speed = Math.random() * 2 + 0.8; + return { + x: Math.random() * W(), y: Math.random() * H(), + vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed, + trail: [], + maxTrail: Math.floor(Math.random() * 25) + 15, + r: Math.random() * 3 + 2, + color: Math.random() > 0.5 ? CORAL : PURPLE, + curve: (Math.random() - 0.5) * 0.01 + }; + } + + function draw() { + ctx.clearRect(0, 0, W(), H()); + variantState.time += 0.01; + + variantState.comets.forEach(c => { + // Slight curve + const angle = Math.atan2(c.vy, c.vx) + c.curve; + const speed = Math.sqrt(c.vx * c.vx + c.vy * c.vy); + c.vx = Math.cos(angle) * speed; + c.vy = Math.sin(angle) * speed; + + // Mouse attraction + if (mouseIn) { + const dx = mouseX - c.x, dy = mouseY - c.y; + const d = Math.sqrt(dx * dx + dy * dy); + if (d < 250 && d > 1) { + c.vx += dx / d * 0.05; + c.vy += dy / d * 0.05; + } + } + + c.x += c.vx; + c.y += c.vy; + + c.trail.unshift({ x: c.x, y: c.y }); + if (c.trail.length > c.maxTrail) c.trail.pop(); + + // Reset if off screen + if (c.x < -50 || c.x > W() + 50 || c.y < -50 || c.y > H() + 50) { + Object.assign(c, makeComet()); + // Enter from edge + const side = Math.floor(Math.random() * 4); + if (side === 0) { c.x = -10; c.y = Math.random() * H(); } + else if (side === 1) { c.x = W() + 10; c.y = Math.random() * H(); } + else if (side === 2) { c.y = -10; c.x = Math.random() * W(); } + else { c.y = H() + 10; c.x = Math.random() * W(); } + c.trail = []; + } + + // Draw trail + for (let i = 1; i < c.trail.length; i++) { + const alpha = (1 - i / c.trail.length) * 0.4; + const width = (1 - i / c.trail.length) * c.r; + ctx.strokeStyle = `rgba(${c.color},${alpha})`; + ctx.lineWidth = width; + ctx.beginPath(); + ctx.moveTo(c.trail[i - 1].x, c.trail[i - 1].y); + ctx.lineTo(c.trail[i].x, c.trail[i].y); + ctx.stroke(); + } + + // Head glow + ctx.fillStyle = `rgba(${c.color},0.15)`; + ctx.beginPath(); ctx.arc(c.x, c.y, c.r * 4, 0, Math.PI * 2); ctx.fill(); + + // Head + ctx.fillStyle = `rgba(${c.color},0.8)`; + ctx.beginPath(); ctx.arc(c.x, c.y, c.r, 0, Math.PI * 2); ctx.fill(); + }); + + animId = requestAnimationFrame(draw); + } + draw(); + } + + // --- Initialize default --- + if (!reducedMotion) initVariant(activeVariant); + +}); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7a30d5b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1580 @@ +{ + "name": "noboxdev-website", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "noboxdev-website", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@11ty/eleventy": "3.1.2" + } + }, + "node_modules/@11ty/dependency-tree": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-4.0.2.tgz", + "integrity": "sha512-RTF6VTZHatYf7fSZBUN3RKwiUeJh5dhWV61gDPrHhQF2/gzruAkYz8yXuvGLx3w3ZBKreGrR+MfYpSVkdbdbLA==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1" + } + }, + "node_modules/@11ty/dependency-tree-esm": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree-esm/-/dependency-tree-esm-2.0.4.tgz", + "integrity": "sha512-MYKC0Ac77ILr1HnRJalzKDlb9Z8To3kXQCltx299pUXXUFtJ1RIONtULlknknqW8cLe19DLVgmxVCtjEFm7h0A==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.7", + "acorn": "^8.15.0", + "dependency-graph": "^1.0.0", + "normalize-path": "^3.0.0" + } + }, + "node_modules/@11ty/eleventy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.1.2.tgz", + "integrity": "sha512-IcsDlbXnBf8cHzbM1YBv3JcTyLB35EK88QexmVyFdVJVgUU6bh9g687rpxryJirHzo06PuwnYaEEdVZQfIgRGg==", + "license": "MIT", + "dependencies": { + "@11ty/dependency-tree": "^4.0.0", + "@11ty/dependency-tree-esm": "^2.0.0", + "@11ty/eleventy-dev-server": "^2.0.8", + "@11ty/eleventy-plugin-bundle": "^3.0.6", + "@11ty/eleventy-utils": "^2.0.7", + "@11ty/lodash-custom": "^4.17.21", + "@11ty/posthtml-urls": "^1.0.1", + "@11ty/recursive-copy": "^4.0.2", + "@sindresorhus/slugify": "^2.2.1", + "bcp-47-normalize": "^2.3.0", + "chokidar": "^3.6.0", + "debug": "^4.4.1", + "dependency-graph": "^1.0.0", + "entities": "^6.0.1", + "filesize": "^10.1.6", + "gray-matter": "^4.0.3", + "iso-639-1": "^3.1.5", + "js-yaml": "^4.1.0", + "kleur": "^4.1.5", + "liquidjs": "^10.21.1", + "luxon": "^3.6.1", + "markdown-it": "^14.1.0", + "minimist": "^1.2.8", + "moo": "^0.5.2", + "node-retrieve-globals": "^6.0.1", + "nunjucks": "^3.2.4", + "picomatch": "^4.0.2", + "please-upgrade-node": "^3.2.0", + "posthtml": "^0.16.6", + "posthtml-match-helper": "^2.0.3", + "semver": "^7.7.2", + "slugify": "^1.6.6", + "tinyglobby": "^0.2.14" + }, + "bin": { + "eleventy": "cmd.cjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-dev-server": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-2.0.8.tgz", + "integrity": "sha512-15oC5M1DQlCaOMUq4limKRYmWiGecDaGwryr7fTE/oM9Ix8siqMvWi+I8VjsfrGr+iViDvWcH/TVI6D12d93mA==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1", + "chokidar": "^3.6.0", + "debug": "^4.4.0", + "finalhandler": "^1.3.1", + "mime": "^3.0.0", + "minimist": "^1.2.8", + "morphdom": "^2.7.4", + "please-upgrade-node": "^3.2.0", + "send": "^1.1.0", + "ssri": "^11.0.0", + "urlpattern-polyfill": "^10.0.0", + "ws": "^8.18.1" + }, + "bin": { + "eleventy-dev-server": "cmd.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-plugin-bundle": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.7.tgz", + "integrity": "sha512-QK1tRFBhQdZASnYU8GMzpTdsMMFLVAkuU0gVVILqNyp09xJJZb81kAS3AFrNrwBCsgLxTdWHJ8N64+OTTsoKkA==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.2", + "debug": "^4.4.0", + "posthtml-match-helper": "^2.0.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-utils": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-2.0.7.tgz", + "integrity": "sha512-6QE+duqSQ0GY9rENXYb4iPR4AYGdrFpqnmi59tFp9VrleOl0QSh8VlBr2yd6dlhkdtj7904poZW5PvGr9cMiJQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/lodash-custom": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@11ty/lodash-custom/-/lodash-custom-4.17.21.tgz", + "integrity": "sha512-Mqt6im1xpb1Ykn3nbcCovWXK3ggywRJa+IXIdoz4wIIK+cvozADH63lexcuPpGS/gJ6/m2JxyyXDyupkMr5DHw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/posthtml-urls": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@11ty/posthtml-urls/-/posthtml-urls-1.0.2.tgz", + "integrity": "sha512-0vaV3Wt0surZ+oS1VdKKe0axeeupuM+l7W/Z866WFQwF+dGg2Tc/nmhk/5l74/Y55P8KyImnLN9CdygNw2huHg==", + "license": "MIT", + "dependencies": { + "evaluate-value": "^2.0.0", + "http-equiv-refresh": "^2.0.1", + "list-to-array": "^1.1.0", + "parse-srcset": "^1.0.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@11ty/recursive-copy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.3.tgz", + "integrity": "sha512-SX48BTLEGX8T/OsKWORsHAAeiDsbFl79Oa/0Wg/mv/d27b7trCVZs7fMHvpSgDvZz/fZqx5rDk8+nx5oyT7xBw==", + "license": "ISC", + "dependencies": { + "errno": "^1.0.0", + "junk": "^3.1.0", + "maximatch": "^0.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sindresorhus/slugify": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", + "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/transliterate": "^1.0.0", + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sindresorhus/transliterate": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz", + "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-normalize": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz", + "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==", + "license": "MIT", + "dependencies": { + "bcp-47": "^2.0.0", + "bcp-47-match": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/errno/-/errno-1.0.0.tgz", + "integrity": "sha512-3zV5mFS1E8/1bPxt/B0xxzI1snsg3uSCIh6Zo1qKg6iMw93hzPANk9oBFzSFBFrwuVoQuE3rLoouAUfwOAj1wQ==", + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esm-import-transformer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.5.tgz", + "integrity": "sha512-1GKLvfuMnnpI75l8c6sHoz0L3Z872xL5akGuBudgqTDPv4Vy6f2Ec7jEMKTxlqWl/3kSvNbHELeimJtnqgYniw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/evaluate-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/evaluate-value/-/evaluate-value-2.0.0.tgz", + "integrity": "sha512-VonfiuDJc0z4sOO7W0Pd130VLsXN6vmBWZlrog1mCb/o7o/Nl5Lr25+Kj/nkCCAhG+zqeeGjxhkK9oHpkgTHhQ==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-equiv-refresh": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-equiv-refresh/-/http-equiv-refresh-2.0.1.tgz", + "integrity": "sha512-XJpDL/MLkV3dKwLzHwr2dY05dYNfBNlyPu4STQ8WvKCFdc6vC5tPXuq28of663+gHVg03C+16pHHs/+FmmDjcw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", + "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", + "license": "ISC" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/iso-639-1": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.5.tgz", + "integrity": "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/liquidjs": { + "version": "10.24.0", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.24.0.tgz", + "integrity": "sha512-TAUNAdgwaAXjjcUFuYVJm9kOVH7zc0mTKxsG9t9Lu4qdWjB2BEblyVIYpjWcmJLMGgiYqnGNJjpNMHx0gp/46A==", + "license": "MIT", + "dependencies": { + "commander": "^10.0.0" + }, + "bin": { + "liquid": "bin/liquid.js", + "liquidjs": "bin/liquid.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/liquidjs" + } + }, + "node_modules/list-to-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/list-to-array/-/list-to-array-1.1.0.tgz", + "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==", + "license": "MIT" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/maximatch": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz", + "integrity": "sha512-9ORVtDUFk4u/NFfo0vG/ND/z7UQCVZBL539YW0+U1I7H1BkZwizcPx5foFv7LCPcBnm2U6RjFnQOsIvN4/Vm2A==", + "license": "MIT", + "dependencies": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "license": "BSD-3-Clause" + }, + "node_modules/morphdom": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz", + "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/node-retrieve-globals": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/node-retrieve-globals/-/node-retrieve-globals-6.0.1.tgz", + "integrity": "sha512-j0DeFuZ/Wg3VlklfbxUgZF/mdHMTEiEipBb3q0SpMMbHaV3AVfoUQF8UGxh1s/yjqO0TgRZd4Pi/x2yRqoQ4Eg==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "acorn-walk": "^8.3.4", + "esm-import-transformer": "^3.0.3" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", + "license": "MIT" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "license": "MIT", + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/posthtml": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.7.tgz", + "integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==", + "license": "MIT", + "peer": true, + "dependencies": { + "posthtml-parser": "^0.11.0", + "posthtml-render": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/posthtml-match-helper": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/posthtml-match-helper/-/posthtml-match-helper-2.0.3.tgz", + "integrity": "sha512-p9oJgTdMF2dyd7WE54QI1LvpBIkNkbSiiECKezNnDVYhGhD1AaOnAkw0Uh0y5TW+OHO8iBdSqnd8Wkpb6iUqmw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "posthtml": "^0.16.6" + } + }, + "node_modules/posthtml-parser": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", + "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", + "license": "MIT", + "dependencies": { + "htmlparser2": "^7.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/posthtml-render": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", + "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", + "license": "MIT", + "dependencies": { + "is-json": "^2.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "license": "MIT" + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz", + "integrity": "sha512-aZpUoMN/Jj2MqA4vMCeiKGnc/8SuSyHbGSBdgFbZxP8OJGF/lFkIuElzPxsN0q8TQQ+prw3P4EDfB3TBHHgfXw==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2819ded --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "noboxdev-website", + "version": "1.0.0", + "description": "No Box Dev marketing website", + "main": "main.js", + "scripts": { + "build": "npx @11ty/eleventy", + "serve": "npx @11ty/eleventy --serve" + }, + "author": "No Box Dev", + "license": "ISC", + "type": "commonjs", + "dependencies": { + "@11ty/eleventy": "3.1.2" + } +} diff --git a/privacy.html b/privacy.html deleted file mode 100644 index 33ddc0e..0000000 --- a/privacy.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - Privacy Policy - No Box Dev - - - - - - - - - - - - -
-
- Go Back -

Privacy Policy

-

(Development & Design Services)

-

Last updated: December 2025

- -

At NoBoxDev ("we", "us", "our"), we respect your privacy and are committed to protecting your personal data. This Privacy Policy explains how we collect, use, and safeguard your information when you work with us or visit our website.

- -
-

1. Information We Collect

-

We may collect the following types of information:

-

1.1. Information you provide directly:

-
    -
  • Name and contact details (email, phone number)
  • -
  • Company name and job title
  • -
  • Project requirements and specifications
  • -
  • Payment and billing information
  • -
  • Communication history (emails, messages, call notes)
  • -
-

1.2. Information collected automatically:

-
    -
  • IP address and browser type
  • -
  • Device information
  • -
  • Pages visited and time spent on our website
  • -
  • Referral source
  • -
-
- -
-

2. How We Use Your Information

-

We use your information to:

-
    -
  • Communicate with you about projects and services
  • -
  • Provide, maintain, and improve our services
  • -
  • Process payments and send invoices
  • -
  • Send project updates and relevant information
  • -
  • Respond to inquiries and support requests
  • -
  • Comply with legal obligations
  • -
  • Improve our website and user experience
  • -
-
- -
-

3. Legal Basis for Processing

-

We process your personal data based on:

-
    -
  • Contract: To fulfill our contractual obligations to you
  • -
  • Legitimate interest: To operate and improve our business
  • -
  • Consent: When you have given explicit consent
  • -
  • Legal obligation: To comply with applicable laws
  • -
-
- -
-

4. Data Sharing

-

We do not sell your personal data. We may share your information with:

-
    -
  • Service providers: Tools we use to deliver our services (e.g., project management, hosting, payment processing)
  • -
  • Professional advisors: Accountants, lawyers, or consultants when necessary
  • -
  • Legal authorities: When required by law or to protect our rights
  • -
-

All third parties are required to respect the security of your data and treat it in accordance with the law.

-
- -
-

5. Data Security

-

We implement appropriate technical and organizational measures to protect your personal data, including:

-
    -
  • Secure, encrypted connections (SSL/TLS)
  • -
  • Access controls and authentication
  • -
  • Regular security assessments
  • -
  • Secure storage of sensitive information
  • -
-

While we strive to protect your data, no method of transmission over the internet is 100% secure.

-
- -
-

6. Data Retention

-

We retain your personal data only for as long as necessary to:

-
    -
  • Fulfill the purposes for which it was collected
  • -
  • Comply with legal, accounting, or reporting requirements
  • -
  • Resolve disputes and enforce agreements
  • -
-

Project-related data is typically retained for 7 years after project completion for legal and accounting purposes.

-
- -
-

7. Your Rights

-

Under applicable data protection laws, you have the right to:

-
    -
  • Access: Request a copy of your personal data
  • -
  • Rectification: Request correction of inaccurate data
  • -
  • Erasure: Request deletion of your data (subject to legal obligations)
  • -
  • Restriction: Request limited processing of your data
  • -
  • Portability: Receive your data in a structured, machine-readable format
  • -
  • Objection: Object to processing based on legitimate interests
  • -
  • Withdraw consent: Where processing is based on consent
  • -
-

To exercise any of these rights, please contact us at hello@noboxdev.com.

-
- -
-

8. Cookies

-

Our website may use cookies and similar technologies to:

-
    -
  • Remember your preferences
  • -
  • Understand how you use our website
  • -
  • Improve your browsing experience
  • -
-

You can control cookies through your browser settings. Disabling cookies may affect website functionality.

-
- -
-

9. Third-Party Links

-

Our website may contain links to third-party websites. We are not responsible for the privacy practices of these external sites. We encourage you to read their privacy policies.

-
- -
-

10. International Transfers

-

Your data may be transferred to and processed in countries outside the European Economic Area (EEA). When this occurs, we ensure appropriate safeguards are in place to protect your data.

-
- -
-

11. Changes to This Policy

-

We may update this Privacy Policy from time to time. Changes will be posted on this page with an updated revision date. We encourage you to review this policy periodically.

-
- -
-

12. Contact Us

-

If you have any questions about this Privacy Policy or how we handle your data, please contact us:

-

NoBoxDev
- Email: hello@noboxdev.com

-
-
-
- - - - - - - diff --git a/privacy.njk b/privacy.njk new file mode 100644 index 0000000..6103e56 --- /dev/null +++ b/privacy.njk @@ -0,0 +1,156 @@ +--- +layout: base.njk +title: "Privacy Policy — No Box Dev" +description: "Privacy Policy for NoBoxDev Development & Design Services." +canonical: "https://noboxdev.com/privacy" +permalink: "/privacy/index.html" +--- + + + + + +
+
+ +
+
diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..c67971c --- /dev/null +++ b/styles.css @@ -0,0 +1,1461 @@ +/* ============================================ + No Box Dev + Design system adapted from n1.care patterns + ============================================ */ + +/* --- Design Tokens --- */ +:root { + --bg: #FAFAF8; + --bg-alt: #F0EFEB; + --text: #201E1D; + --text-muted: #6B6462; + --coral: #FE795D; + --coral-dark: #e56a50; + --purple: #9B78F4; + --purple-dark: #8560e0; + --white: #FFFFFF; + --black: #1A1A1A; + --border: #E0DEDA; + --radius: 6px; + --transition: 0.3s ease; + --max-width: 1200px; +} + +/* --- Font Faces --- */ +@font-face { + font-family: 'Aeonik'; + src: url('/assets/fonts/Aeonik-regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Aeonik'; + src: url('/assets/fonts/Aeonik bold italic.ttf') format('truetype'); + font-weight: 700; + font-style: italic; + font-display: swap; +} + +@font-face { + font-family: 'Arbeit'; + src: url('/assets/fonts/Arbeit-Regular.otf') format('opentype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Arbeit'; + src: url('/assets/fonts/Arbeit-Bold.otf') format('opentype'); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Arbeit'; + src: url('/assets/fonts/Arbeit-LightItalic.otf') format('opentype'); + font-weight: 300; + font-style: italic; + font-display: swap; +} + +/* --- Reset --- */ +*, *::before, *::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + font-family: 'Arbeit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + font-weight: 400; + color: var(--text); + background: var(--bg); + line-height: 1.7; + font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem); + animation: pageIn 0.5s ease both; +} + +@keyframes pageIn { + from { opacity: 0; } + to { opacity: 1; } +} + +img { max-width: 100%; display: block; } +a { color: inherit; text-decoration: none; } +ul, ol { list-style: none; } +button, input, textarea, select { + font: inherit; + color: inherit; + border: none; + background: none; + outline: none; +} + +/* --- Typography (Fluid) --- */ +h1, h2, h3, h4 { + font-family: 'Aeonik', sans-serif; +} + +h1 { + font-size: clamp(2.75rem, 2.2rem + 2.75vw, 4rem); + font-weight: 700; + line-height: 1.08; + letter-spacing: -0.025em; +} + +h2 { + font-size: clamp(1.75rem, 1.4rem + 1.75vw, 2.75rem); + font-weight: 700; + line-height: 1.15; + letter-spacing: -0.02em; +} + +h3 { + font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.5rem); + font-weight: 700; + line-height: 1.3; +} + +h4 { + font-size: clamp(1rem, 0.95rem + 0.3vw, 1.2rem); + font-weight: 700; + line-height: 1.4; +} + +p { + max-width: 640px; + overflow-wrap: break-word; +} + +.text-muted { + color: var(--text-muted); +} + +.text-lg { + font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem); + line-height: 1.6; +} + +/* --- Layout --- */ +.container { + width: 100%; + max-width: var(--max-width); + margin: 0 auto; + padding: 0 clamp(1.25rem, 1rem + 2vw, 3rem); +} + +section { + padding: clamp(4rem, 3rem + 5vw, 9rem) 0; +} + +/* --- Section Labels --- */ +.section-label { + display: inline-block; + font-family: 'Arbeit', sans-serif; + font-size: 0.7rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--coral); + background: rgba(254, 121, 93, 0.08); + padding: 0.35rem 0.9rem; + border-radius: 20px; + margin-bottom: 1.5rem; +} + +/* --- Navigation --- */ +.nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 100; + background: var(--bg); + transition: background var(--transition), box-shadow var(--transition); +} + +.nav.scrolled { + background: rgba(250, 250, 248, 0.95); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + box-shadow: 0 1px 0 var(--border); +} + +.nav.nav-transparent { + background: transparent; +} + +.nav.nav-transparent .nav-logo, +.nav.nav-transparent .nav-links a:not(.btn) { + color: var(--text-muted); +} + +.nav.nav-transparent .nav-links a:not(.btn):hover { + color: var(--text); +} + +.nav.nav-transparent .nav-toggle span { + background: var(--text); +} + +.nav.nav-transparent.scrolled { + background: rgba(250, 250, 248, 0.95); +} + +.nav-inner { + display: flex; + align-items: center; + justify-content: space-between; + height: clamp(3.5rem, 3rem + 2vw, 4.5rem); +} + +.nav-logo { + display: flex; + align-items: center; +} + +.nav-logo img { + height: 28px; + width: auto; +} + +.nav-links { + display: flex; + align-items: center; + gap: clamp(1.5rem, 1rem + 2vw, 2.5rem); +} + +.nav-links a:not(.btn) { + font-size: 0.9rem; + font-weight: 500; + color: var(--text-muted); + transition: color var(--transition); +} + +.nav-links a:not(.btn):hover { + color: var(--text); +} + +.nav-links a.active:not(.btn) { + color: var(--text); + position: relative; +} + +.nav-links a.active:not(.btn)::after { + content: ''; + position: absolute; + bottom: -4px; + left: 0; + right: 0; + height: 2px; + background: var(--coral); + border-radius: 1px; +} + +/* Mobile nav toggle */ +.nav-toggle { + display: none; + flex-direction: column; + gap: 5px; + cursor: pointer; + padding: 10px; + min-width: 44px; + min-height: 44px; + align-items: center; + justify-content: center; +} + +.nav-toggle span { + display: block; + width: 22px; + height: 2px; + background: var(--text); + transition: transform var(--transition), opacity var(--transition); +} + +.nav-toggle.open span:nth-child(1) { + transform: translateY(7px) rotate(45deg); +} + +.nav-toggle.open span:nth-child(2) { + opacity: 0; +} + +.nav-toggle.open span:nth-child(3) { + transform: translateY(-7px) rotate(-45deg); +} + +/* Mobile nav overlay backdrop */ +.nav-backdrop { + display: none; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.4); + z-index: 99; + opacity: 0; + transition: opacity 0.3s ease; +} + +.nav-backdrop.active { + display: block; + opacity: 1; +} + +body.nav-open { + overflow: hidden; +} + +/* --- Buttons --- */ +.btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + font-family: 'Arbeit', sans-serif; + font-size: 0.9rem; + font-weight: 700; + padding: 0.8rem 2rem; + border-radius: 28px; + cursor: pointer; + transition: all var(--transition); + min-height: 44px; +} + +.btn-primary { + background: var(--coral); + color: var(--white); +} + +.btn-primary:hover { + background: var(--coral-dark); + transform: translateY(-1px); + box-shadow: 0 4px 16px rgba(254, 121, 93, 0.3); +} + +.btn-outline { + border: 1.5px solid var(--text); + color: var(--text); +} + +.btn-outline:hover { + background: var(--text); + color: var(--bg); +} + +.btn-outline-white { + border: 1.5px solid var(--white); + color: var(--white); +} + +.btn-outline-white:hover { + background: var(--white); + color: var(--purple); +} + +.btn-ghost { + color: var(--coral); + padding: 0.5rem 0; + font-weight: 600; + position: relative; +} + +.btn-ghost::before { + content: ''; + position: absolute; + bottom: 0.35rem; + left: 0; + width: 0; + height: 1.5px; + background: var(--coral); + transition: width 0.3s ease; +} + +.btn-ghost:hover::before { + width: calc(100% - 1.5rem); +} + +.btn-ghost::after { + content: '\2192'; + transition: transform var(--transition); +} + +.btn-ghost:hover::after { + transform: translateX(4px); +} + +/* --- Hero --- */ +.hero { + position: relative; + min-height: 100vh; + display: flex; + align-items: center; + overflow: hidden; + background: var(--bg); +} + +.hero .container { + position: relative; + z-index: 2; +} + +#hero-canvas { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + z-index: 1; + pointer-events: none; +} + +/* Gradient mesh glows */ +.hero-glow { + position: absolute; + border-radius: 50%; + filter: blur(100px); + opacity: 0.35; + will-change: transform; + pointer-events: none; +} + +.hero-glow--1 { + width: 600px; + height: 600px; + background: var(--coral); + top: -15%; + right: -8%; + animation: glowDrift1 18s ease-in-out infinite; +} + +.hero-glow--2 { + width: 500px; + height: 500px; + background: var(--purple); + bottom: -20%; + left: -8%; + animation: glowDrift2 22s ease-in-out infinite; +} + +.hero-glow--3 { + width: 400px; + height: 400px; + background: linear-gradient(135deg, var(--coral), var(--purple)); + top: 30%; + left: 35%; + opacity: 0.2; + animation: glowDrift3 16s ease-in-out infinite; +} + +@keyframes glowDrift1 { + 0%, 100% { transform: translate(0, 0) scale(1); } + 33% { transform: translate(-40px, 30px) scale(1.05); } + 66% { transform: translate(30px, -20px) scale(0.95); } +} + +@keyframes glowDrift2 { + 0%, 100% { transform: translate(0, 0) scale(1); } + 33% { transform: translate(50px, -20px) scale(1.08); } + 66% { transform: translate(-30px, 40px) scale(0.92); } +} + +@keyframes glowDrift3 { + 0%, 100% { transform: translate(0, 0) scale(1); } + 50% { transform: translate(-50px, -30px) scale(1.12); } +} + +/* Hero text */ +.hero-text { + text-align: center; + max-width: 820px; + margin: 0 auto; +} + +.hero h1 { + margin-bottom: 1.5rem; + color: var(--text); +} + +.hero .hero-tagline { + font-size: clamp(1.05rem, 1rem + 0.4vw, 1.25rem); + color: var(--text-muted); + margin-bottom: 2.5rem; + max-width: 520px; + margin-left: auto; + margin-right: auto; + line-height: 1.7; +} + +.hero-actions { + display: flex; + align-items: center; + justify-content: center; + gap: 1.5rem; + flex-wrap: wrap; +} + +.hero .btn-ghost { + color: var(--text-muted); +} + +.hero .btn-ghost:hover { + color: var(--text); +} + +/* Rotating word */ +.hero-rotate { + display: inline-block; + position: relative; + overflow: hidden; + vertical-align: bottom; + height: 1.15em; +} + +.hero-rotate-word { + display: block; + position: absolute; + left: 0; + right: 0; + background: linear-gradient(135deg, var(--coral) 0%, var(--purple) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + transform: translateY(110%); + opacity: 0; + transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.4s ease; +} + +.hero-rotate-word.active { + position: relative; + transform: translateY(0); + opacity: 1; +} + +.hero-rotate-word.exit { + transform: translateY(-110%); + opacity: 0; +} + +/* Dark variant overrides */ +.hero[data-variant="aurora"], +.hero[data-variant="constellation"] { + background: var(--black); +} + +.hero[data-variant="aurora"] .hero-text h1, +.hero[data-variant="constellation"] .hero-text h1 { + color: var(--white); +} + +.hero[data-variant="aurora"] .hero-tagline, +.hero[data-variant="constellation"] .hero-tagline { + color: rgba(255,255,255,0.6); +} + +.hero[data-variant="aurora"] .btn-ghost, +.hero[data-variant="constellation"] .btn-ghost { + color: rgba(255,255,255,0.5); +} + +.hero[data-variant="aurora"] .btn-ghost:hover, +.hero[data-variant="constellation"] .btn-ghost:hover { + color: var(--white); +} + +.hero[data-variant="aurora"] .hero-glow, +.hero[data-variant="constellation"] .hero-glow { + opacity: 0.15; +} + +/* Hide glows on morph variant (it has its own) */ +.hero[data-variant="morph"] .hero-glow { + display: none; +} + +/* --- Hero Selector --- */ +.hero-selector { + position: absolute; + right: 1.5rem; + top: 50%; + transform: translateY(-50%); + z-index: 10; + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.hero-sel-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.35rem 0.75rem; + border-radius: 20px; + cursor: pointer; + transition: all 0.25s ease; + background: rgba(255,255,255,0.6); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + border: 1px solid rgba(0,0,0,0.06); + white-space: nowrap; +} + +.hero-sel-btn:hover { + background: rgba(255,255,255,0.85); + transform: translateX(-4px); +} + +.hero-sel-btn.active { + background: var(--coral); + color: var(--white); + border-color: transparent; +} + +.sel-num { + font-size: 0.65rem; + font-weight: 700; + letter-spacing: 0.04em; + opacity: 0.6; +} + +.hero-sel-btn.active .sel-num { + opacity: 1; +} + +.sel-label { + font-size: 0.7rem; + font-weight: 600; + letter-spacing: 0.02em; +} + +/* Dark variant selector */ +.hero[data-variant="aurora"] .hero-sel-btn, +.hero[data-variant="constellation"] .hero-sel-btn { + background: rgba(255,255,255,0.08); + border-color: rgba(255,255,255,0.1); + color: rgba(255,255,255,0.7); +} + +.hero[data-variant="aurora"] .hero-sel-btn:hover, +.hero[data-variant="constellation"] .hero-sel-btn:hover { + background: rgba(255,255,255,0.15); + color: var(--white); +} + +.hero[data-variant="aurora"] .hero-sel-btn.active, +.hero[data-variant="constellation"] .hero-sel-btn.active { + background: var(--coral); + color: var(--white); +} + +/* --- Services Section --- */ +.services { + background: var(--bg-alt); +} + +.section-header { + margin-bottom: clamp(2rem, 1.5rem + 2vw, 3.5rem); +} + +.section-header h2 { + margin-top: 0.5rem; +} + +.services-intro { + max-width: 720px; + margin-bottom: clamp(2rem, 1.5rem + 2vw, 3rem); +} + +.services-intro p { + color: var(--text-muted); + margin-bottom: 1rem; + max-width: 720px; +} + +.services-intro p:last-child { + margin-bottom: 0; +} + +.services-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: clamp(1rem, 0.75rem + 1.5vw, 2rem); +} + +.service-card { + background: var(--white); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: clamp(1.5rem, 1.25rem + 1vw, 2rem); + transition: transform var(--transition), box-shadow var(--transition); +} + +.service-card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06); +} + +.service-icon { + width: 48px; + height: 48px; + margin-bottom: 1.25rem; +} + +.service-icon img { + width: 100%; + height: 100%; + object-fit: contain; +} + +.service-card h3 { + margin-bottom: 0.75rem; + font-size: clamp(1.1rem, 1rem + 0.3vw, 1.25rem); +} + +.service-card p { + color: var(--text-muted); + font-size: 0.9rem; + line-height: 1.6; +} + +/* --- Case Studies Section --- */ +.case-studies-intro { + max-width: 720px; + margin-bottom: clamp(2rem, 1.5rem + 2vw, 3rem); +} + +.case-studies-intro p { + color: var(--text-muted); + margin-bottom: 1rem; +} + +.case-studies-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: clamp(1.25rem, 1rem + 1vw, 2rem); +} + +.case-study-card { + background: var(--white); + border: 1px solid var(--border); + border-radius: var(--radius); + overflow: hidden; + transition: transform var(--transition), box-shadow var(--transition); + position: relative; +} + +.case-study-card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06); +} + +.case-study-image { + position: relative; + height: 200px; + overflow: hidden; +} + +.case-study-image img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.case-study-tag { + position: absolute; + top: 0.75rem; + left: 0.75rem; + font-size: 0.7rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + padding: 0.3rem 0.75rem; + border-radius: 20px; + background: var(--white); + color: var(--text); +} + +.case-study-content { + padding: clamp(1.25rem, 1rem + 0.5vw, 1.75rem); +} + +.case-study-content h3 { + margin-bottom: 0.5rem; + font-size: 1.2rem; +} + +.case-study-content p { + color: var(--text-muted); + font-size: 0.9rem; + line-height: 1.6; + margin-bottom: 1rem; +} + +.case-study-link { + font-size: 0.875rem; + font-weight: 600; + color: var(--coral); + display: inline-flex; + align-items: center; + gap: 0.35rem; + transition: gap var(--transition); +} + +.case-study-link:hover { + gap: 0.6rem; +} + +.case-study-link-wrapper { + position: relative; +} + +.coming-soon-overlay { + position: absolute; + inset: 0; + display: flex; + align-items: center; +} + +.coming-soon-btn { + font-size: 0.8rem; + font-weight: 600; + color: var(--text-muted); + background: var(--bg-alt); + padding: 0.3rem 0.85rem; + border-radius: 20px; +} + +/* --- Collaboration CTA --- */ +.collab-cta { + background: var(--purple); + text-align: center; + padding: clamp(3rem, 2.5rem + 3vw, 6rem) 0; +} + +.collab-cta h2 { + color: var(--white); + margin-bottom: 1rem; +} + +.collab-cta p { + color: rgba(255, 255, 255, 0.85); + font-size: clamp(1.05rem, 1rem + 0.3vw, 1.25rem); + max-width: 600px; + margin: 0 auto 2rem; +} + +/* --- How We Work --- */ +.how-we-work { + background: var(--bg-alt); +} + +.steps-list { + max-width: 720px; +} + +.step-item { + display: grid; + grid-template-columns: 64px 1fr; + gap: 1.5rem; + padding: clamp(1.5rem, 1.25rem + 1vw, 2.5rem) 0; + border-bottom: 1px solid var(--border); + opacity: 0.5; + transition: opacity var(--transition); +} + +.step-item.active, +.step-item:hover { + opacity: 1; +} + +.step-item:last-child { + border-bottom: none; +} + +.step-number { + font-family: 'Aeonik', sans-serif; + font-size: clamp(1.5rem, 1.25rem + 1vw, 2rem); + color: var(--coral); + font-weight: 400; + letter-spacing: -0.02em; +} + +.step-content h3 { + margin-bottom: 0.5rem; +} + +.step-content p { + color: var(--text-muted); + font-size: 0.95rem; + line-height: 1.6; +} + +/* --- Contact Section --- */ +.contact-section { + position: relative; +} + +.contact-grid { + display: grid; + grid-template-columns: 1fr 1.2fr; + gap: clamp(2rem, 1.5rem + 3vw, 4rem); + align-items: start; +} + +.contact-info h3 { + margin-bottom: 1rem; +} + +.contact-info p { + color: var(--text-muted); + margin-bottom: 2rem; +} + +.contact-detail { + margin-bottom: 1.25rem; +} + +.contact-detail .label { + font-size: 0.75rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--text-muted); + margin-bottom: 0.25rem; +} + +.contact-detail a, +.contact-detail p { + font-size: 0.95rem; + color: var(--text); +} + +/* --- Forms --- */ +.form-group { + margin-bottom: 1.25rem; +} + +.form-group label { + display: block; + font-size: 0.85rem; + font-weight: 700; + margin-bottom: 0.4rem; + color: var(--text); +} + +.form-group input, +.form-group textarea, +.form-group select { + width: 100%; + padding: 0.75rem 1rem; + border: 1px solid var(--border); + border-radius: var(--radius); + background: var(--white); + font-size: 0.95rem; + transition: border-color var(--transition), box-shadow var(--transition); +} + +.form-group input:focus, +.form-group textarea:focus, +.form-group select:focus { + border-color: var(--coral); + box-shadow: 0 0 0 3px rgba(254, 121, 93, 0.1); +} + +.form-group textarea { + resize: vertical; + min-height: 120px; +} + +.form-honeypot { + position: absolute; + left: -9999px; +} + +.form-success { + display: none; + text-align: center; + padding: 3rem 2rem; + background: var(--white); + border: 1px solid var(--coral); + border-radius: var(--radius); +} + +.form-success.show { + display: block; +} + +.form-success h3 { + color: var(--coral); + margin-bottom: 0.5rem; +} + +/* --- Subpage Headers --- */ +.subpage-header { + background: var(--bg); + min-height: 60vh; + display: flex; + flex-direction: column; + justify-content: center; + padding-top: clamp(5rem, 4rem + 3vw, 7rem); + padding-bottom: clamp(4rem, 3rem + 4vw, 7rem); + position: relative; + overflow: hidden; +} + +.subpage-header::before { + content: ''; + position: absolute; + top: -40%; + right: -10%; + width: 50%; + height: 180%; + background: radial-gradient(ellipse, rgba(254, 121, 93, 0.08) 0%, transparent 70%); + pointer-events: none; +} + +.subpage-wave { + position: absolute; + width: 200%; + height: 40%; + left: -50%; + border-radius: 45%; + will-change: transform; + pointer-events: none; +} + +.subpage-wave--1 { + bottom: -20%; + animation: tide-1 14s ease-in-out infinite; +} + +.subpage-wave--2 { + bottom: -28%; + animation: tide-2 18s ease-in-out infinite; +} + +/* About — purple tint */ +.subpage-header--about .subpage-wave--1 { background: rgba(155, 120, 244, 0.06); bottom: -24%; } +.subpage-header--about .subpage-wave--2 { background: rgba(140, 105, 230, 0.04); bottom: -34%; } +.subpage-header--about::before { background: radial-gradient(ellipse, rgba(155, 120, 244, 0.08) 0%, transparent 70%); top: -30%; left: -10%; right: auto; } + +/* Contact — coral tint */ +.subpage-header--contact .subpage-wave--1 { background: rgba(254, 121, 93, 0.06); left: -55%; } +.subpage-header--contact .subpage-wave--2 { background: rgba(240, 107, 80, 0.04); left: -48%; } +.subpage-header--contact::before { background: radial-gradient(ellipse, rgba(254, 121, 93, 0.08) 0%, transparent 70%); top: -50%; right: -15%; } + +/* Legal — very subtle neutral */ +.subpage-header--legal .subpage-wave--1 { background: rgba(180, 170, 160, 0.04); bottom: -26%; } +.subpage-header--legal .subpage-wave--2 { background: rgba(165, 155, 145, 0.03); bottom: -34%; } +.subpage-header--legal::before { background: radial-gradient(ellipse, rgba(180, 170, 160, 0.06) 0%, transparent 70%); } + +/* Staggered reveal for subpage header children */ +.subpage-header .reveal:nth-child(1) { transition-delay: 0s; } +.subpage-header .reveal:nth-child(2) { transition-delay: 0.15s; } +.subpage-header .reveal:nth-child(3) { transition-delay: 0.3s; } + +.subpage-header .container { + text-align: center; +} + +.subpage-header .section-label { + color: var(--coral); + background: rgba(254, 121, 93, 0.08); +} + +.subpage-header h1 { + color: var(--text); + margin-bottom: 1.25rem; + max-width: 700px; + margin-left: auto; + margin-right: auto; +} + +.subpage-header p { + color: var(--text-muted); + font-size: clamp(1.05rem, 1rem + 0.3vw, 1.25rem); + max-width: 560px; + margin-left: auto; + margin-right: auto; +} + +/* Contact form in subpage header */ +.subpage-header--contact .contact-grid { + margin-top: clamp(2.5rem, 2rem + 3vw, 4rem); + text-align: left; +} + +.subpage-header--contact .form-group input, +.subpage-header--contact .form-group textarea, +.subpage-header--contact .form-group select { + background: rgba(255, 255, 255, 0.85); + backdrop-filter: blur(4px); + border-color: rgba(0, 0, 0, 0.08); +} + +.subpage-header--contact .form-group input:focus, +.subpage-header--contact .form-group textarea:focus, +.subpage-header--contact .form-group select:focus { + background: var(--white); + border-color: var(--coral); +} + +/* --- About Page --- */ +.mission-section { + background: var(--bg-alt); +} + +.mission-split { + display: grid; + grid-template-columns: 1fr 1fr; + gap: clamp(2rem, 1.5rem + 3vw, 4rem); + align-items: center; +} + +.mission-text p { + color: var(--text-muted); + margin-bottom: 1rem; +} + +.team-section { + padding: clamp(4rem, 3rem + 5vw, 9rem) 0; +} + +.team-placeholder { + background: var(--bg-alt); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: clamp(2rem, 1.5rem + 2vw, 4rem); + text-align: center; + max-width: 600px; + margin: 0 auto; +} + +.team-placeholder p { + color: var(--text-muted); + margin: 0 auto; +} + +/* --- Legal Pages --- */ +.legal-content { + max-width: 800px; + margin: 0 auto; + padding: clamp(3rem, 2.5rem + 3vw, 6rem) 0; +} + +.legal-content h1 { + font-size: clamp(2rem, 1.6rem + 2vw, 3rem); + margin-bottom: 0.5rem; +} + +.legal-subtitle { + font-size: 1.1rem; + color: var(--text-muted); + margin-bottom: 0.25rem; +} + +.legal-updated { + font-size: 0.85rem; + color: var(--text-muted); + opacity: 0.8; + margin-bottom: clamp(2rem, 1.5rem + 1vw, 3rem); +} + +.legal-intro { + font-size: 1rem; + color: var(--text-muted); + line-height: 1.8; + margin-bottom: clamp(2rem, 1.5rem + 1vw, 3rem); +} + +.legal-section { + margin-bottom: 2rem; +} + +.legal-section h2 { + font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem); + margin-bottom: 0.75rem; +} + +.legal-section p { + color: var(--text-muted); + font-size: 0.95rem; + line-height: 1.8; + margin-bottom: 0.75rem; +} + +.legal-section ul { + padding-left: 1.5rem; + margin-bottom: 0.75rem; +} + +.legal-section ul li { + color: var(--text-muted); + font-size: 0.95rem; + line-height: 1.8; + position: relative; + padding-left: 1rem; +} + +.legal-section ul li::before { + content: "\2022"; + position: absolute; + left: 0; +} + +/* --- Footer --- */ +.footer { + border-top: 1px solid var(--border); + padding: clamp(2.5rem, 2rem + 2vw, 4rem) 0; +} + +.footer-inner { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 2rem; + flex-wrap: wrap; +} + +.footer-brand { + max-width: 320px; +} + +.footer-brand .nav-logo { + margin-bottom: 0.75rem; +} + +.footer-brand .nav-logo img { + height: 24px; +} + +.footer-brand p { + font-size: 0.85rem; + color: var(--text-muted); + line-height: 1.6; +} + +.footer-links { + display: flex; + gap: clamp(3rem, 2rem + 3vw, 5rem); +} + +.footer-col h4 { + font-size: 0.8rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--text-muted); + margin-bottom: 1rem; +} + +.footer-col a { + display: block; + width: fit-content; + font-size: 0.875rem; + color: var(--text-muted); + padding: 0.25rem 0; + transition: color var(--transition); + position: relative; +} + +.footer-col a::after { + content: ''; + position: absolute; + bottom: 0.2rem; + left: 0; + width: 0; + height: 1px; + background: var(--text); + transition: width 0.3s ease; +} + +.footer-col a:hover { + color: var(--text); +} + +.footer-col a:hover::after { + width: 100%; +} + +.footer-bottom { + margin-top: clamp(2rem, 1.5rem + 1vw, 3rem); + padding-top: 1.5rem; + border-top: 1px solid var(--border); + font-size: 0.8rem; + color: var(--text-muted); +} + +/* --- Reveal Animations --- */ +.reveal { + opacity: 0; + transform: translateY(30px); + transition: opacity 0.8s ease, transform 0.8s ease; +} + +.reveal.visible { + opacity: 1; + transform: translateY(0); +} + +.reveal-stagger > * { + opacity: 0; + transform: translateY(20px); + transition: opacity 0.6s ease, transform 0.6s ease; +} + +.reveal-stagger.visible > *:nth-child(1) { transition-delay: 0s; } +.reveal-stagger.visible > *:nth-child(2) { transition-delay: 0.1s; } +.reveal-stagger.visible > *:nth-child(3) { transition-delay: 0.2s; } +.reveal-stagger.visible > *:nth-child(4) { transition-delay: 0.3s; } +.reveal-stagger.visible > *:nth-child(5) { transition-delay: 0.4s; } +.reveal-stagger.visible > *:nth-child(6) { transition-delay: 0.5s; } +.reveal-stagger.visible > *:nth-child(7) { transition-delay: 0.6s; } +.reveal-stagger.visible > *:nth-child(8) { transition-delay: 0.7s; } +.reveal-stagger.visible > *:nth-child(9) { transition-delay: 0.8s; } + +.reveal-stagger.visible > * { + opacity: 1; + transform: translateY(0); +} + +/* --- Responsive --- */ +@media (max-width: 900px) { + /* Mobile nav full-screen overlay */ + .nav.nav-open, + .nav.nav-open.nav-transparent, + .nav.nav-open.nav-transparent.scrolled { + bottom: 0; + background: var(--bg); + backdrop-filter: none; + -webkit-backdrop-filter: none; + } + + .nav.nav-open .nav-inner { + height: 100%; + flex-wrap: wrap; + align-content: flex-start; + } + + .nav-links { + display: none; + flex-direction: column; + padding: 2rem; + gap: 0.5rem; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + order: 1; + } + + .nav-links.open { + display: flex; + width: 100%; + flex: 1 1 100%; + } + + .nav-links a:not(.btn) { + font-size: 1.1rem; + padding: 0.75rem 0; + min-height: 44px; + display: flex; + align-items: center; + } + + .nav-links .btn { + margin-top: 1rem; + width: 100%; + justify-content: center; + min-height: 44px; + } + + .nav-toggle { + display: flex; + position: relative; + z-index: 1; + } + + .hero-selector { + right: 0.5rem; + } + + .sel-label { display: none; } + + .hero-sel-btn { + padding: 0.3rem 0.5rem; + } + + .services-grid { + grid-template-columns: repeat(2, 1fr); + } + + .case-studies-grid { + grid-template-columns: 1fr; + } + + .contact-grid, + .mission-split { + grid-template-columns: 1fr; + } +} + +@media (max-width: 600px) { + .hero { + min-height: auto; + padding-top: clamp(5rem, 4rem + 3vw, 7rem); + padding-bottom: 3rem; + } + + .services-grid { + grid-template-columns: 1fr; + } + + .step-item { + grid-template-columns: 48px 1fr; + gap: 1rem; + } + + .footer-inner { + flex-direction: column; + } + + #contact-form .btn { + width: 100%; + justify-content: center; + } +} + +/* --- Reduced Motion --- */ +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } + + .tide-wave, + .subpage-wave { + animation: none !important; + } + + .reveal { + opacity: 1; + transform: none; + } + + .reveal-stagger > * { + opacity: 1; + transform: none; + } + + html { + scroll-behavior: auto; + } +} diff --git a/terms.html b/terms.html deleted file mode 100644 index 02fdd84..0000000 --- a/terms.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - Terms & Conditions - No Box Dev - - - - - - - - - - - - -
-
- Go Back -

Terms & Conditions

-

(Development & Design Services)

-

Last updated: December 2025

- -

These Terms & Conditions apply to all services provided by NoBoxDev ("we", "us", "our") to the client ("you", "your"). By entering into a project, proposal, or agreement with us, you agree to the following terms.

- -
-

1. Scope of Work

-

1.1. All work will be performed according to the agreed proposal, statement of work, or project summary.

-

1.2. Any changes to scope—such as new features, additional screens, integrations, or workflows—must be approved in writing and may affect timelines and pricing.

-

1.3. We work in iterative cycles. Deliverables are shared through design tools, development environments, or demo links.

-
- -
-

2. Client Responsibilities

-

2.1. You agree to provide timely access to all information, materials, and decisions required for the project.

-

2.2. Delays in feedback or approvals may result in adjusted timelines.

-

2.3. You are responsible for ensuring that any content, images, data, or third-party material you provide does not infringe on intellectual property rights.

-
- -
-

3. Collaboration & Communication

-

3.1. Communication takes place via email, Slack, shared project boards (e.g., ClickUp), or scheduled calls.

-

3.2. Feedback rounds and revision cycles follow the structure outlined in the proposal.

-

3.3. Any urgent requests outside the agreed workflow may require additional fees.

-
- -
-

4. Payments & Invoicing

-

4.1. Project fees, retainers, or fixed pricing are outlined in your proposal.

-

4.2. Invoices are issued according to the agreed schedule (e.g., upfront deposit, milestone-based, or monthly).

-

4.3. Payment terms are 14 days unless otherwise stated.

-

4.4. Late payments may pause the project until resolved.

-

4.5. Fees for third-party tools (e.g., Bubble plans, APIs, plugins, hosting) are not included unless explicitly stated.

-
- -
-

5. Timelines

-

5.1. Project timelines are estimates based on the information available at the start of the project.

-

5.2. Timelines may shift due to:

-
    -
  • Client delays
  • -
  • Changes in scope
  • -
  • External dependencies (e.g., third-party APIs)
  • -
-

5.3. We communicate timeline adjustments promptly and transparently.

-
- -
-

6. Intellectual Property

-

6.1. All design files, developed applications, workflows, and documentation become your property after full payment for the corresponding phase or project.

-

6.2. Until payment is complete, all work remains the property of NoBoxDev.

-

6.3. We may showcase non-confidential, finalised work in our portfolio or marketing materials unless agreed otherwise.

-
- -
-

7. Confidentiality

-

7.1. Both parties agree to keep all non-public information confidential.

-

7.2. This includes business information, user data, financials, and technical architecture.

-

7.3. Confidentiality obligations remain in effect after the project ends.

-
- -
-

8. Revisions & Maintenance

-

8.1. Revisions are included as specified in the proposal. Additional revisions or redesigns may incur fees.

-

8.2. Post-launch maintenance, bug fixes, or feature updates are not included unless agreed through a maintenance contract or support plan.

-
- -
-

9. Testing & Acceptance

-

9.1. We conduct internal testing before delivering any feature or milestone.

-

9.2. You are responsible for reviewing, testing, and approving deliverables within a reasonable timeframe.

-

9.3. Approval of deliverables signifies acceptance and allows us to proceed to the next stage.

-
- -
-

10. Third-Party Services

-

10.1. We may integrate external APIs, plugins, libraries, or software when needed.

-

10.2. We cannot guarantee the long-term performance, pricing, or availability of third-party services.

-

10.3. Any costs associated with third-party services are your responsibility.

-
- -
-

11. Liability

-

11.1. We deliver development and design services to the best of our expertise, but we cannot guarantee uninterrupted uptime or error-free operation.

-

11.2. We are not liable for:

-
    -
  • Indirect losses
  • -
  • Lost profits
  • -
  • Damages caused by third-party tools
  • -
  • Misuse of the application
  • -
-

11.3. Our total liability is limited to the amount paid for the project phase in question.

-
- -
-

12. Termination

-

12.1. Either party may terminate the agreement with 30 days' written notice.

-

12.2. Work completed up to the termination date must be paid in full.

-

12.3. Upon termination, all access and licenses provided to the client may be suspended until payment is settled.

-
- -
-

13. Governing Law

-

These terms are governed by the laws of the Netherlands.

-
- -
-

14. Acceptance

-

By continuing the project, paying invoices, or approving deliverables, you confirm acceptance of these Terms & Conditions.

-
-
-
- - - - - - - diff --git a/terms.njk b/terms.njk new file mode 100644 index 0000000..47e1127 --- /dev/null +++ b/terms.njk @@ -0,0 +1,135 @@ +--- +layout: base.njk +title: "Terms & Conditions — No Box Dev" +description: "Terms & Conditions for NoBoxDev Development & Design Services." +canonical: "https://noboxdev.com/terms" +permalink: "/terms/index.html" +--- + + + + + +
+
+ +
+