From 880a7f4a3b855b75af780f0dc43857d5f72a349a Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 13 May 2025 21:04:01 -0600 Subject: [PATCH] Hello World --- docker-compose.yml | 23 + site/404.html | 92 ++++ site/css/responsive.css | 193 +++++++++ site/css/styles.css | 898 +++++++++++++++++++++++++++++++++++++++ site/img/bunker-logo.svg | 1 + site/index.html | 247 +++++++++++ site/js/main.js | 189 ++++++++ site/nginx.conf | 25 ++ site/robots.txt | 4 + site/sitemap.html | 123 ++++++ 10 files changed, 1795 insertions(+) create mode 100644 docker-compose.yml create mode 100644 site/404.html create mode 100644 site/css/responsive.css create mode 100644 site/css/styles.css create mode 100644 site/img/bunker-logo.svg create mode 100644 site/index.html create mode 100644 site/js/main.js create mode 100644 site/nginx.conf create mode 100644 site/robots.txt create mode 100644 site/sitemap.html diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ee75bdf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ + + + version: '3' + + services: + bnkops.landing.server: + image: lscr.io/linuxserver/nginx:latest + container_name: bnkops.landing.server + environment: + - PUID=${USER_ID:-1000} # Uses USER_ID from your .env file, defaults to 1000 + - PGID=${GROUP_ID:-1000} # Uses GROUP_ID from your .env file, defaults to 1000 + - TZ=Etc/UTC + volumes: + - ./site:/config/www # Mounts your static site to Nginx's web root + ports: + - "4007:80" # Exposes Nginx's port 80 to host port 4001 + restart: unless-stopped + networks: + - changemaker + + networks: + changemaker: + driver: bridge \ No newline at end of file diff --git a/site/404.html b/site/404.html new file mode 100644 index 0000000..92debdb --- /dev/null +++ b/site/404.html @@ -0,0 +1,92 @@ + + + + + + The Bunker Operations - Page Not Found + + + + + + +
+ +
+ +
+
+
+
404
+

Page Not Found

+

We're sorry, but the page you are looking for doesn't exist or has been moved.

+ +
+
+ +
+
+ + +
🔍
+
🏳️‍⚧️
+
💻
+
+ + + + + + diff --git a/site/css/responsive.css b/site/css/responsive.css new file mode 100644 index 0000000..d744ae7 --- /dev/null +++ b/site/css/responsive.css @@ -0,0 +1,193 @@ +/* + * Responsive Stylesheet for BNKOps Website + * Version: 2.0.0 + * Date: May 2025 + * Theme: Dark Purple with Trans Pride Colors + */ + +/* ==================== + Responsive Design + ==================== */ + +/* Extra large devices (large desktops, 1200px and up) */ +@media (max-width: 1200px) { + .container { + max-width: 960px; + } + + .emoji-sticker { + font-size: 2.5rem; + } +} + +/* Large devices (desktops, 992px and up) */ +@media (max-width: 992px) { + .container { + max-width: 720px; + } + + section { + padding: 60px 0; + } + + .section-header h2 { + font-size: 2rem; + } + + .about-content, + .contact-content, + .error-container .container { + grid-template-columns: 1fr; + gap: 30px; + } + + .about-stats { + margin-top: 30px; + } + + .error-illustration { + display: none; + } + + .post-it { + transform: rotate(0deg) !important; + } + + .post-it:hover { + transform: scale(1.03) !important; + } +} + +/* Medium devices (tablets, 768px and up) */ +@media (max-width: 768px) { + .container { + max-width: 540px; + } + + .menu-toggle { + display: block; + } + + .nav-menu { + position: fixed; + top: 70px; + left: -100%; + background-color: rgba(16, 0, 43, 0.95); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + width: 100%; + height: calc(100vh - 70px); + flex-direction: column; + align-items: center; + justify-content: flex-start; + padding-top: 50px; + transition: var(--transition); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3); + z-index: 100; + } + + .nav-menu.active { + left: 0; + } + + .nav-menu li { + margin: 0 0 20px 0; + } + + .nav-menu a { + font-size: 1.2rem; + } + + .hero h1 { + font-size: 2.5rem; + } + + .services-grid { + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 20px; + } + + .about-stats { + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + } + + .emoji-sticker { + font-size: 2rem; + } + + .footer-content { + grid-template-columns: 1fr; + text-align: center; + } + + .footer-links h3::after, + .footer-social h3::after { + left: 50%; + transform: translateX(-50%); + } + + .social-icons { + justify-content: center; + } + + .error-actions { + flex-direction: column; + } +} + +/* Small devices (landscape phones, 576px and up) */ +@media (max-width: 576px) { + .container { + width: 95%; + padding: 0 10px; + } + + section { + padding: 50px 0; + } + + .section-header { + margin-bottom: 30px; + } + + .section-header h2 { + font-size: 1.8rem; + } + + .section-header p { + font-size: 1rem; + } + + .hero h1 { + font-size: 2rem; + } + + .hero p { + font-size: 1rem; + } + + .btn { + padding: 10px 20px; + font-size: 0.9rem; + } + + .service-card { + padding: 20px; + } + + .error-code { + font-size: 6rem; + } + + .error-content h1 { + font-size: 2rem; + } + + .sitemap-content { + grid-template-columns: 1fr; + } + + .emoji-sticker { + font-size: 1.5rem; + } +} diff --git a/site/css/styles.css b/site/css/styles.css new file mode 100644 index 0000000..0f35a14 --- /dev/null +++ b/site/css/styles.css @@ -0,0 +1,898 @@ +/* + * Main Stylesheet for BNKOps Website + * Version: 2.0.0 + * Date: May 2025 + */ + +/* ==================== + Base Styling + ==================== */ +:root { + /* Trans Pride Theme Colors */ + --trans-blue: #5BCEFA; + --trans-pink: #F5A9B8; + --trans-white: #FFFFFF; + + /* Primary dark purple theme */ + --primary-color: #7B2CBF; + --secondary-color: #9D4EDD; + --accent-color: #C77DFF; + + /* Additional theme colors */ + --dark-purple: #3C096C; + --light-purple: #E0AAFF; + + /* UI Colors */ + --light-color: #F8F9FA; + --dark-color: #240046; + --text-color: #F8F9FA; + --body-bg: #10002B; + --footer-bg: #240046; + --card-bg: #3C096C; + + /* Utility */ + --border-radius: 8px; + --box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25); + --transition: all 0.3s ease; + + /* Post-it note colors */ + --postit-blue: var(--trans-blue); + --postit-pink: var(--trans-pink); + --postit-white: var(--trans-white); + --postit-purple: var(--primary-color); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + line-height: 1.6; + color: var(--text-color); + background-color: var(--body-bg); + background-image: linear-gradient(to bottom, var(--dark-purple), var(--body-bg)); + min-height: 100vh; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: 600; + line-height: 1.3; + margin-bottom: 1rem; +} + +p { + margin-bottom: 1rem; +} + +a { + color: var(--trans-blue); + text-decoration: none; + transition: var(--transition); +} + +a:hover { + color: var(--trans-pink); +} + +ul { + list-style: none; +} + +img { + max-width: 100%; + height: auto; +} + +.container { + width: 90%; + max-width: 1200px; + margin: 0 auto; + padding: 0 15px; +} + +section { + padding: 80px 0; +} + +.section-header { + text-align: center; + margin-bottom: 50px; + position: relative; +} + +.section-header h2 { + font-size: 2.5rem; + color: var(--trans-pink); + margin-bottom: 0.5rem; + position: relative; + display: inline-block; +} + +.section-header h2::after { + content: ''; + position: absolute; + width: 80px; + height: 4px; + background: linear-gradient(to right, var(--trans-blue), var(--trans-pink), var(--trans-white), var(--trans-pink), var(--trans-blue)); + bottom: -10px; + left: 50%; + transform: translateX(-50%); + border-radius: 2px; +} + +.section-header p { + color: var(--light-purple); + font-size: 1.1rem; + margin-top: 20px; +} + +/* ==================== + Post-it Notes Styling + ==================== */ +.post-it { + background-color: var(--card-bg); + border-radius: var(--border-radius); + padding: 30px; + box-shadow: var(--box-shadow); + transition: var(--transition); + position: relative; + margin-bottom: 20px; + transform: rotate(0deg); +} + +.post-it-blue { + background-color: var(--postit-blue); + border-top: 8px solid #4AADDF; + color: #444; +} + +.post-it-pink { + background-color: var(--postit-pink); + border-top: 8px solid #E797A7; + color: #444; +} + +.post-it-white { + background-color: var(--postit-white); + border-top: 8px solid #E7E7E7; + color: #444; +} + +/* Add text shadow to post-its for better readability */ +.hero .post-it p { + text-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + line-height: 1.5; +} + +.post-it-purple { + background-color: var(--primary-color); + border-top: 8px solid var(--accent-color); + color: white; +} + +.tilt-left-sm { + transform: rotate(-2deg); +} + +.tilt-right-sm { + transform: rotate(2deg); +} + +.tilt-left-md { + transform: rotate(-4deg); +} + +.tilt-right-md { + transform: rotate(4deg); +} + +.post-it:hover { + transform: scale(1.03) rotate(0deg); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); + z-index: 10; +} + +/* ==================== + Buttons + ==================== */ +.btn { + display: inline-block; + padding: 12px 28px; + font-size: 1rem; + font-weight: 600; + text-align: center; + border-radius: var(--border-radius); + transition: all 0.3s ease; + border: none; + cursor: pointer; + position: relative; + overflow: hidden; + z-index: 1; +} + +.btn::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(90deg, var(--trans-blue), var(--trans-pink), var(--trans-white), var(--trans-pink), var(--trans-blue)); + z-index: -1; + transition: transform 0.5s; + transform: translateX(-100%); +} + +.btn:hover::before { + transform: translateX(0); +} + +.btn:hover { + color: var(--dark-purple); + text-shadow: 0 0 3px rgba(255, 255, 255, 0.7); + font-weight: 700; +} + +.btn-primary { + background-color: var(--primary-color); + color: white; +} + +.btn-secondary { + background-color: var(--secondary-color); + color: white; +} + +.btn-primary:hover, .btn-secondary:hover { + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); + transform: translateY(-3px); +} + +/* ==================== + Navigation + ==================== */ +.navbar { + position: fixed; + top: 0; + left: 0; + width: 100%; + background-color: rgba(16, 0, 43, 0.9); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + z-index: 1000; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); + padding: 15px 0; + border-bottom: 1px solid rgba(123, 44, 191, 0.3); +} + +.navbar .container { + display: flex; + justify-content: space-between; + align-items: center; +} + +.logo a { + font-size: 1.8rem; + font-weight: 700; + color: var(--trans-white); + text-shadow: 0 0 10px rgba(91, 206, 250, 0.5), 0 0 20px rgba(245, 169, 184, 0.3); + position: relative; +} + +.logo a::after { + content: ''; + position: absolute; + width: 100%; + height: 3px; + bottom: -5px; + left: 0; + background: linear-gradient(to right, var(--trans-blue), var(--trans-pink), var(--trans-white)); + border-radius: 3px; +} + +.nav-menu { + display: flex; +} + +.nav-menu li { + margin-left: 30px; +} + +.nav-menu a { + color: var(--light-color); + font-weight: 500; + position: relative; + padding-bottom: 5px; +} + +.nav-menu a:after { + content: ''; + position: absolute; + width: 0; + height: 2px; + background: linear-gradient(to right, var(--trans-blue), var(--trans-pink)); + bottom: 0; + left: 0; + transition: var(--transition); +} + +.nav-menu a:hover:after, +.nav-menu a.active:after { + width: 100%; +} + +.nav-menu a.active { + color: var(--trans-pink); +} + +.menu-toggle { + display: none; + cursor: pointer; +} + +.menu-toggle .bar { + width: 25px; + height: 3px; + background-color: var(--light-color); + margin: 5px 0; + transition: var(--transition); + display: block; +} + +/* ==================== + Hero Section + ==================== */ +.hero { + min-height: 100vh; + display: flex; + align-items: center; + background: linear-gradient(rgba(16, 0, 43, 0.8), rgba(36, 0, 70, 0.9)), url('../img/hero-bg.jpg') center/cover no-repeat; + color: white; + text-align: center; + padding-top: 80px; + position: relative; + overflow: hidden; +} + +.hero::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 10px; + background: linear-gradient(90deg, var(--trans-blue) 0%, var(--trans-pink) 50%, var(--trans-white) 100%); +} + +.hero h1 { + font-size: 3.5rem; + margin-bottom: 20px; + color: var(--trans-white); + text-shadow: 0 0 15px rgba(123, 44, 191, 0.8); + position: relative; +} + +.hero h1::after { + content: ''; + position: absolute; + width: 120px; + height: 4px; + background: linear-gradient(to right, var(--trans-blue), var(--trans-pink), var(--trans-white)); + bottom: -10px; + left: 50%; + transform: translateX(-50%); + border-radius: 2px; +} + +.hero p { + font-size: 1.2rem; + margin-bottom: 30px; + max-width: 700px; + margin-left: auto; + margin-right: auto; + color: var(--trans-white); + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); +} + +.emoji-sticker { + position: absolute; + font-size: 3rem; + z-index: 0; + animation: float 5s ease-in-out infinite; + filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.3)); + pointer-events: none; /* So they don't interfere with clicks */ + opacity: 0.8; +} + +@keyframes float { + 0% { + transform: translateY(0px); + } + 50% { + transform: translateY(-15px); + } + 100% { + transform: translateY(0px); + } +} + +/* ==================== + Services Section + ==================== */ +.services { + background-color: var(--body-bg); + position: relative; + z-index: 5; +} + +.services::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: radial-gradient(circle at 10% 20%, rgba(123, 44, 191, 0.1) 0%, transparent 60%), + radial-gradient(circle at 80% 70%, rgba(245, 169, 184, 0.1) 0%, transparent 60%); + z-index: -1; +} + +.services-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 30px; +} + +.service-card { + background-color: var(--card-bg); + padding: 30px; + border-radius: var(--border-radius); + box-shadow: var(--box-shadow); + text-align: center; + transition: var(--transition); + color: var(--text-color); + position: relative; + overflow: hidden; + border-top: 4px solid transparent; +} + +.service-card:nth-child(3n+1) { + border-color: var(--trans-blue); +} + +.service-card:nth-child(3n+2) { + border-color: var(--trans-pink); +} + +.service-card:nth-child(3n+3) { + border-color: var(--trans-white); +} + +.service-card:hover { + transform: translateY(-10px); + box-shadow: 0 15px 30px rgba(0, 0, 0, 0.4); +} + +.service-card::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 5px; + background: linear-gradient(90deg, var(--trans-blue), var(--trans-pink), var(--trans-white)); + opacity: 0; + transition: opacity 0.3s ease; +} + +.service-card:hover::after { + opacity: 1; +} + +.service-card i { + font-size: 2.5rem; + color: var(--accent-color); + margin-bottom: 20px; + display: inline-block; + transition: transform 0.3s ease; +} + +.service-card:hover i { + transform: scale(1.2); +} + +.service-card h3 { + font-size: 1.5rem; + margin-bottom: 15px; + color: var(--trans-white); +} + +/* ==================== + About Section + ==================== */ +.about { + background-color: var(--dark-purple); + position: relative; +} + +.about-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 50px; + align-items: center; +} + +.about-text { + color: var(--text-color); +} + +.about-text p:last-child { + margin-bottom: 0; +} + +.about-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; +} + +.stat-item { + background-color: var(--card-bg); + padding: 20px; + border-radius: var(--border-radius); + box-shadow: var(--box-shadow); + text-align: center; + color: var(--text-color); + transition: var(--transition); +} + +.stat-item:hover { + transform: translateY(-5px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); +} + +.stat-item h3 { + font-size: 2.5rem; + background: linear-gradient(90deg, var(--trans-blue), var(--trans-pink)); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + margin-bottom: 10px; +} + +/* ==================== + Contact Section + ==================== */ +.contact { + background-color: var(--body-bg); + position: relative; +} + +.contact::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: radial-gradient(circle at 90% 10%, rgba(123, 44, 191, 0.2) 0%, transparent 60%), + radial-gradient(circle at 20% 90%, rgba(245, 169, 184, 0.2) 0%, transparent 60%); + z-index: 0; +} + +.contact-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 50px; + position: relative; + z-index: 1; +} + +.contact-item { + display: flex; + margin-bottom: 30px; +} + +.contact-item i { + font-size: 1.5rem; + color: var(--trans-pink); + margin-right: 20px; + width: 40px; + height: 40px; + background-color: rgba(123, 44, 191, 0.2); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: var(--transition); +} + +.contact-item:hover i { + background-color: var(--primary-color); + color: var(--trans-white); + transform: scale(1.1); +} + +.contact-item h3 { + font-size: 1.2rem; + margin-bottom: 5px; + color: var(--trans-blue); +} + +.contact-item p { + color: var(--text-color); +} + +.form-group { + margin-bottom: 20px; +} + +.form-group input, +.form-group textarea { + width: 100%; + padding: 12px 15px; + background-color: rgba(60, 9, 108, 0.5); + border: 1px solid var(--primary-color); + border-radius: var(--border-radius); + font-size: 1rem; + transition: var(--transition); + color: var(--text-color); + box-shadow: 0 0 10px rgba(123, 44, 191, 0.1) inset; +} + +.form-group input::placeholder, +.form-group textarea::placeholder { + color: rgba(248, 249, 250, 0.5); +} + +.form-group input:focus, +.form-group textarea:focus { + border-color: var(--trans-pink); + outline: none; + box-shadow: 0 0 15px rgba(245, 169, 184, 0.3); +} + +.form-group textarea { + height: 150px; + resize: vertical; +} + +/* ==================== + Footer + ==================== */ +footer { + background-color: var(--footer-bg); + color: var(--text-color); + padding: 70px 0 20px; + position: relative; +} + +footer::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 5px; + background: linear-gradient(90deg, var(--trans-blue), var(--trans-pink), var(--trans-white), var(--trans-pink), var(--trans-blue)); +} + +.footer-content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 30px; + margin-bottom: 50px; +} + +.footer-logo h2 { + font-size: 2rem; + margin-bottom: 10px; + background: linear-gradient(90deg, var(--trans-blue), var(--trans-pink)); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} + +.footer-links h3, +.footer-social h3 { + font-size: 1.2rem; + margin-bottom: 20px; + position: relative; + padding-bottom: 10px; + color: var(--trans-white); +} + +.footer-links h3::after, +.footer-social h3::after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + width: 50px; + height: 2px; + background: linear-gradient(to right, var(--trans-blue), var(--trans-pink)); +} + +.footer-links ul li { + margin-bottom: 10px; +} + +.footer-links ul li a { + color: var(--light-purple); + transition: var(--transition); + display: inline-block; +} + +.footer-links ul li a:hover { + color: var(--trans-pink); + padding-left: 5px; +} + +.social-icons { + display: flex; + gap: 15px; +} + +.social-icons a { + width: 40px; + height: 40px; + background-color: rgba(60, 9, 108, 0.6); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-color); + transition: var(--transition); + position: relative; + overflow: hidden; +} + +.social-icons a::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(45deg, var(--trans-blue), var(--trans-pink)); + opacity: 0; + transition: opacity 0.3s ease; + z-index: -1; +} + +.social-icons a:hover::before { + opacity: 1; +} + +.social-icons a:hover { + transform: translateY(-5px); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); +} + +.footer-bottom { + text-align: center; + padding-top: 20px; + border-top: 1px solid rgba(245, 169, 184, 0.2); + color: var(--light-purple); +} + +/* ==================== + Sitemap Page + ==================== */ +.sitemap-section { + padding-top: 150px; + min-height: calc(100vh - 300px); +} + +.sitemap-content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 30px; +} + +.sitemap-group { + background-color: var(--card-bg); + padding: 30px; + border-radius: var(--border-radius); + box-shadow: var(--box-shadow); +} + +.sitemap-group h2 { + color: var(--trans-pink); + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 2px solid var(--primary-color); +} + +.sitemap-list li { + margin-bottom: 10px; + padding-left: 20px; + position: relative; +} + +.sitemap-list li::before { + content: '→'; + position: absolute; + left: 0; + color: var(--trans-blue); +} + +.sitemap-list li a { + color: var(--text-color); + transition: var(--transition); +} + +.sitemap-list li a:hover { + color: var(--trans-pink); +} + +.sitemap-list ul { + margin-top: 10px; + margin-left: 20px; +} + +/* ==================== + Error Page (404) + ==================== */ +.error-page { + background-color: var(--body-bg); +} + +.error-container { + padding-top: 150px; + min-height: calc(100vh - 300px); + display: flex; + align-items: center; +} + +.error-container .container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 50px; + align-items: center; +} + +.error-code { + font-size: 8rem; + font-weight: 700; + background: linear-gradient(90deg, var(--trans-blue), var(--trans-pink)); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + line-height: 1; + margin-bottom: 20px; + text-shadow: 0 5px 30px rgba(0, 0, 0, 0.2); +} + +.error-content h1 { + font-size: 2.5rem; + margin-bottom: 20px; + color: var(--trans-white); +} + +.error-content p { + color: var(--light-purple); +} + +.error-actions { + margin-top: 30px; + display: flex; + gap: 15px; +} + +.error-illustration { + text-align: center; +} + +.error-illustration i { + font-size: 15rem; + color: var(--primary-color); + opacity: 0.3; +} diff --git a/site/img/bunker-logo.svg b/site/img/bunker-logo.svg new file mode 100644 index 0000000..a388854 --- /dev/null +++ b/site/img/bunker-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/index.html b/site/index.html new file mode 100644 index 0000000..0dc46aa --- /dev/null +++ b/site/index.html @@ -0,0 +1,247 @@ + + + + + + The Bunker Operations + + + + + + +
+ +
+ +
+
+

The Bunker Operations

+

Community Strategy, Tactics, and Technology

+
+
+ 🌱 💪 +

A co-operative network full of care, knowledge, and skill on how to build local community capacity in current times.

+
+
+ 🔓 ⚡ +

Open-source, self-hosted, low-cost, and corporation-free technology for community focused organizations.

+
+
+
+ Work with us + Learn more +
+
+ + +
+ +
+
+
+

Our Solutions

+

Tools and infrastructure built for community organizations

+
+
+
+ +

Strategy & Tactics

+

We provide consulting with a focus on community building, ethical technology, scalable campaigns, and grassroots fundraising.

+
    +
  • Community organizing strategy
  • +
  • Tech infrastructure planning
  • +
  • Campaign development
  • +
  • Ethics-first approach
  • +
+ +
+
+ +

BnkOps Repository

+

A peer-to-peer generated knowledge base. Like MySpace meets social work, our repository grows organically through community contributions.

+
    +
  • Open-source documentation
  • +
  • Community-driven content
  • +
  • Experience-based knowledge
  • +
  • Corporation-free infrastructure
  • +
+ +
+
+ +

Change Maker

+

Professional-grade documentation tools with revolutionary simplicity. Build and manage your digital political campaign or community website.

+
    +
  • Local build control
  • +
  • Remote accessibility
  • +
  • Built-in security
  • +
  • Save thousands in yearly bills
  • +
+ +
+
+
+
+

Build your power, don't pay for it ✊

+
+
+
+
+ +
+
+
+

Who We Are

+

The Bunker Operations

+
+
+
+

BNKOps is a collective with a central administrative team. We operate as a co-operative of skilled individuals passionate about building community capacity through ethical technology and organizing strategies.

+

Our group comprises trusted collaborators, comrades, and co-conspirators sharing goals in community growth. Based in amiskwaciy-waskahikan (Edmonton), we are grateful for the land's provisions and strive to honor it through our work.

+
+
+
+ +

Co-operative Based

+

Creating resources that are open-source, low-cost, easy to operate, and corporation-free.

+
+
+ +

Community Focused

+

Our group comprises trusted collaborators, comrades, and co-conspirators sharing goals in community growth.

+
+
+ +

Open Source

+

All our tools and resources are open-source, ensuring accessibility and transparency.

+
+
+
+
+ Visit our repository +
+
+
+ +
+
+
+

Work With Us

+

Looking to collaborate? Reach out, let's chat.

+
+
+
+

Contact Us

+ + +
+

Administration

+
+

Reed Larsen 💅

+

The Bunker Admin

+ reed@bnkops.ca +
+
+

Shayla Breen 🤔

+

The Bunker Strategist

+ shayla@bnkops.ca +
+
+
+ + +
+

Stay Updated

+
+
+ +
+
+ +
+
+ + +
+ +
+
+
+
+ +
+ + + + + + diff --git a/site/js/main.js b/site/js/main.js new file mode 100644 index 0000000..762391d --- /dev/null +++ b/site/js/main.js @@ -0,0 +1,189 @@ +/* + * Main JavaScript for BNKOps Website + * Version: 2.0.0 + * Date: May 2025 + * Theme: Dark Purple with Trans Pride Colors + */ + +document.addEventListener('DOMContentLoaded', () => { + // Mobile menu toggle + const mobileMenu = document.getElementById('mobile-menu'); + const navMenu = document.querySelector('.nav-menu'); + + if (mobileMenu) { + mobileMenu.addEventListener('click', () => { + mobileMenu.classList.toggle('active'); + navMenu.classList.toggle('active'); + }); + } + + // Close mobile menu when clicking on a nav link + const navLinks = document.querySelectorAll('.nav-menu a'); + + navLinks.forEach(link => { + link.addEventListener('click', () => { + mobileMenu.classList.remove('active'); + navMenu.classList.remove('active'); + }); + }); + + // Smooth scrolling for anchor links + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function(e) { + if (this.getAttribute('href') !== '#') { + e.preventDefault(); + + const targetId = this.getAttribute('href'); + const targetElement = document.querySelector(targetId); + + if (targetElement) { + window.scrollTo({ + top: targetElement.offsetTop - 70, + behavior: 'smooth' + }); + } + } + }); + }); + + // Sticky navigation on scroll with color change + const navbar = document.querySelector('.navbar'); + const navbarHeight = navbar.getBoundingClientRect().height; + + window.addEventListener('scroll', () => { + if (window.scrollY > navbarHeight) { + navbar.classList.add('sticky'); + navbar.style.backgroundColor = 'rgba(60, 9, 108, 0.95)'; + } else { + navbar.classList.remove('sticky'); + navbar.style.backgroundColor = 'rgba(16, 0, 43, 0.9)'; + } + }); + + // Form submission (prevent default for demo) + const contactForm = document.querySelector('.contact-form'); + + if (contactForm) { + contactForm.addEventListener('submit', (e) => { + e.preventDefault(); + alert('Form submission successful! This is a demo message.'); + contactForm.reset(); + }); + } + + // Create emoji stickers dynamically + const createEmojiStickers = () => { + const heroSection = document.querySelector('.hero'); + const servicesSection = document.querySelector('.services'); + const aboutSection = document.querySelector('.about'); + const contactSection = document.querySelector('.contact'); + + const emojis = ['💻', '📚', '🌱', '⚡', '🔓', '💪', '✨', '🌈', '🏳️‍⚧️', '🏳️‍🌈']; + + const sections = [heroSection, servicesSection, aboutSection, contactSection]; + + // Safe zones for emoji placement (percentage from edges) + const safeZones = { + hero: { top: 35, bottom: 25, left: 10, right: 10 }, + services: { top: 15, bottom: 15, left: 5, right: 5 }, + about: { top: 20, bottom: 20, left: 5, right: 5 }, + contact: { top: 20, bottom: 15, left: 5, right: 5 } + }; + + // Get section name from class + const getSectionName = (section) => { + if (section.classList.contains('hero')) return 'hero'; + if (section.classList.contains('services')) return 'services'; + if (section.classList.contains('about')) return 'about'; + if (section.classList.contains('contact')) return 'contact'; + return 'default'; + }; + + sections.forEach((section) => { + if (section) { + const sectionName = getSectionName(section); + const zone = safeZones[sectionName] || { top: 20, bottom: 20, left: 5, right: 5 }; + + // Add 3-4 emoji stickers per section + const emojiCount = Math.floor(Math.random() * 2) + 2; // 2-3 emojis per section + const placedPositions = []; + + for (let i = 0; i < emojiCount; i++) { + const emoji = document.createElement('div'); + emoji.className = 'emoji-sticker'; + emoji.textContent = emojis[Math.floor(Math.random() * emojis.length)]; + + // Calculate safe position that doesn't overlap with content + let attempts = 0; + let position; + + // Try to find a non-overlapping position + do { + position = { + top: Math.random() * (100 - zone.top - zone.bottom) + zone.top, + left: Math.random() * (100 - zone.left - zone.right) + zone.left + }; + + // Check if this position is far enough from other emojis + const isFarEnough = placedPositions.every(pos => { + const distance = Math.sqrt( + Math.pow(position.top - pos.top, 2) + + Math.pow(position.left - pos.left, 2) + ); + return distance > 20; // Minimum distance between emojis + }); + + attempts++; + if (isFarEnough || attempts > 10) break; + } while (attempts < 10); + + // Apply position + emoji.style.top = `${position.top}%`; + emoji.style.left = `${position.left}%`; + placedPositions.push(position); + + // Set z-index to be below content + emoji.style.zIndex = "1"; + + // Random animation delay + emoji.style.animationDelay = `${Math.random() * 2}s`; + + section.appendChild(emoji); + } + } + }); + }; + + // Create post-it notes effect + const createPostItEffect = () => { + const postIts = document.querySelectorAll('.post-it, .service-card'); + + postIts.forEach((postIt, index) => { + // Add subtle rotation to every other card + if (index % 2 === 0) { + postIt.classList.add('tilt-left-sm'); + } else { + postIt.classList.add('tilt-right-sm'); + } + + // Create shadow effect on hover + postIt.addEventListener('mouseover', () => { + postIt.style.transform = 'scale(1.03) rotate(0deg)'; + postIt.style.boxShadow = '0 15px 30px rgba(0, 0, 0, 0.3)'; + postIt.style.zIndex = '10'; + }); + + postIt.addEventListener('mouseout', () => { + postIt.style.transform = ''; + postIt.style.boxShadow = ''; + postIt.style.zIndex = ''; + }); + }); + }; + + // Initialize effects + setTimeout(() => { + createEmojiStickers(); + createPostItEffect(); + }, 100); +}); diff --git a/site/nginx.conf b/site/nginx.conf new file mode 100644 index 0000000..c1f938d --- /dev/null +++ b/site/nginx.conf @@ -0,0 +1,25 @@ +server { + listen 80; + listen [::]:80; + + root /config/www; + index index.html; + + location / { + try_files $uri $uri/ =404; + } + + # Custom error pages + error_page 404 /404.html; + + # Enable gzip compression + gzip on; + gzip_types text/plain text/css application/javascript application/json image/svg+xml; + gzip_min_length 1000; + + # Set cache headers for static assets + location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { + expires 30d; + add_header Cache-Control "public, no-transform"; + } +} diff --git a/site/robots.txt b/site/robots.txt new file mode 100644 index 0000000..f68b70f --- /dev/null +++ b/site/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://bnkops.com/sitemap.xml diff --git a/site/sitemap.html b/site/sitemap.html new file mode 100644 index 0000000..c1239bf --- /dev/null +++ b/site/sitemap.html @@ -0,0 +1,123 @@ + + + + + + The Bunker Operations - Sitemap + + + + + + +
+ +
+ +
+
+
+

Sitemap

+

Find your way around our website

+
+ +
+
+

Main Pages

+ +
+ +
+

Services

+ +
+ +
+

External Resources

+ +
+
+ +
+ Back to Home +
+
+ + +
🏳️‍⚧️
+
🌈
+
+ + + + + +