Initial upload of bennys production files

This commit is contained in:
2025-11-18 19:44:37 +00:00
parent 77b206e795
commit 3a9ce0821a
9749 changed files with 1677047 additions and 0 deletions

45
templates/about.html Normal file
View File

@@ -0,0 +1,45 @@
{% extends "base.html" %}
{% block content %}
<section class="py-16 md:py-24">
<div class="max-w-4xl mx-auto px-6 space-y-8">
<header>
<h1 class="font-bebas text-5xl">About Bennys House</h1>
<p class="mt-4 text-white/80 max-w-prose">Bennys House is an Amarillohomed IT & Web services studio serving the Texas Panhandle and the greater Texas area. We build and run practical systems for small businesses and individuals, and we can operate at enterprise scale when needed.</p>
</header>
<section class="glass rounded-2xl p-6 space-y-4">
<h2 class="text-xl font-semibold">What we believe</h2>
<ul class="card-list !pl-0 list-none space-y-2">
<li class="dot">Localfirst when it makes sense, cloud when it earns the right.</li>
<li class="dot">Simple, reliable stacks beat flashy complexity.</li>
<li class="dot">Own your infra where possible; avoid lockin.</li>
</ul>
</section>
<section class="grid md:grid-cols-2 gap-6">
<article class="card">
<h3 class="card-title">Service Area</h3>
<p class="card-body">Based in Amarillo, we happily travel anywhere in the Texas Panhandle — and consult across the greater Texas region. Remote support available.</p>
</article>
<article class="card">
<h3 class="card-title">Stack & Focus</h3>
<p class="card-body">Proxmox • Windows Server/AD • Linux • Flask/Node • Tailwind • MariaDB • WireGuard • Nginx. We ship secure, maintainable, nononsense solutions.</p>
</article>
</section>
<section class="glass rounded-2xl p-6">
<h2 class="text-xl font-semibold">Who we help</h2>
<p class="card-body">Local shops, offices, and individuals who need dependable systems and clean websites. Need enterprise rigor? We can engage via BrookHaven for larger programs.</p>
</section>
<div class="pt-2">
<a href="/contact" class="btn-primary">Start a project</a>
<a href="/services" class="btn-ghost ml-2">Explore services</a>
</div>
</div>
</section>
{% endblock %}

98
templates/base.html Normal file
View File

@@ -0,0 +1,98 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{{ brand }} — {{ tagline }}</title>
<meta name="description" content="Bennys House — local IT infrastructure, web hosting, and creative services." />
<link rel="icon" href="{{ url_for('static', filename='favicon.svg') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}">
</head>
<body class="bg-zinc-950 text-zinc-100 antialiased">
<!-- NAV -->
<header class="sticky top-0 z-50 border-b border-white/10 bg-black/60 backdrop-blur">
<div class="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between">
<a href="/" class="flex items-center gap-3">
<div class="size-8 rounded-lg bg-white text-black grid place-items-center font-bold">BH</div>
<span class="font-bebas tracking-wider text-2xl">Bennys House</span>
</a>
<!-- Desktop nav -->
<nav class="hidden md:flex items-center gap-6 text-sm">
<a href="/" class="hover:underline underline-offset-4">Home</a>
<a href="/about" class="hover:underline underline-offset-4">About</a>
<a href="/services" class="hover:underline underline-offset-4">Services</a>
<a href="/contact" class="hover:underline underline-offset-4">Contact</a>
<a href="/benjamin.vcf" class="ml-2 inline-flex items-center gap-2 px-4 py-2 rounded-xl glass hover:bg-white/10 transition">Download vCard</a>
</nav>
<!-- Mobile toggle -->
<button
id="menuBtn"
class="md:hidden p-2 rounded hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white/30"
aria-label="Toggle menu"
aria-controls="mobileNav"
aria-expanded="false">
<!-- hamburger -->
<svg id="iconOpen" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M4 7h16M4 12h16M4 17h16"/>
</svg>
<!-- close -->
<svg id="iconClose" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" class="hidden" aria-hidden="true">
<path d="M6 6l12 12M18 6L6 18"/>
</svg>
</button>
</div>
<!-- Mobile panel -->
<div id="mobileNav" class="md:hidden hidden border-t border-white/10 bg-black/90 backdrop-blur">
<nav class="px-6 py-4 grid gap-2 text-sm">
<a class="py-2 hover:underline underline-offset-4" href="/">Home</a>
<a class="py-2 hover:underline underline-offset-4" href="/about">About</a>
<a class="py-2 hover:underline underline-offset-4" href="/services">Services</a>
<a class="py-2 hover:underline underline-offset-4" href="/contact">Contact</a>
<a class="mt-2 inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl glass hover:bg-white/10 transition" href="/benjamin.vcf">Download vCard</a>
</nav>
</div>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer class="border-t border-white/10 py-10">
<div class="max-w-7xl mx-auto px-6 flex flex-col md:flex-row items-center justify-between gap-4 text-sm text-white/60">
<div> {{ year or 2025 }} Bennys House.</div>
<div class="flex items-center gap-6">
<a class="hover:underline underline-offset-4" href="https://brookhaven.bennyshouse.net">Enterprise</a>
<a class="hover:underline underline-offset-4" href="{{ contact.link }}">LinkedIn</a>
<a class="hover:underline underline-offset-4" href="{{ contact.cal }}">Book a call</a>
</div>
</div>
</footer>
<script>
// mobile nav toggle (vanilla JS)
const btn = document.getElementById('menuBtn');
const nav = document.getElementById('mobileNav');
const icoOpen = document.getElementById('iconOpen');
const icoClose = document.getElementById('iconClose');
function toggleNav(force) {
const willOpen = force !== undefined ? force : nav.classList.contains('hidden');
nav.classList.toggle('hidden', !willOpen);
icoOpen.classList.toggle('hidden', willOpen);
icoClose.classList.toggle('hidden', !willOpen);
btn.setAttribute('aria-expanded', String(willOpen));
document.body.classList.toggle('overflow-hidden', willOpen); // lock scroll when open
}
btn?.addEventListener('click', () => toggleNav());
window.addEventListener('keydown', (e) => { if (e.key === 'Escape') toggleNav(false); });
document.addEventListener('click', (e) => {
if (!nav.contains(e.target) && !btn.contains(e.target)) toggleNav(false);
});
</script>
</body>
</html>

146
templates/contact.html Normal file
View File

@@ -0,0 +1,146 @@
{% extends "base.html" %}
{% block content %}
<section class="py-16 md:py-24">
<div class="max-w-5xl mx-auto px-6">
<div class="grid md:grid-cols-2 gap-10 items-start">
<!-- Left column: Contact card -->
<div
class="relative rounded-2xl border border-white/10 bg-black/50 backdrop-blur p-6 sm:p-8 shadow-xl">
<!-- Accent top border -->
<div class="absolute inset-x-0 -top-px h-px bg-gradient-to-r from-transparent via-white/30 to-transparent"></div>
<header class="flex items-start gap-4">
<div class="h-12 w-12 rounded-xl bg-white/10 grid place-items-center shrink-0">
<!-- Simple user icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 opacity-80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 7.5a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.5 20.25a8.25 8.25 0 0115 0"/>
</svg>
</div>
<div>
<h1 class="font-bebas text-5xl leading-none tracking-wide">{{ contact.name }}</h1>
<p class="mt-1 text-white/80">{{ contact.title }}</p>
<p class="mt-0.5 text-white/60">{{ contact.city }}</p>
<p class="mt-0.5 text-white/60"><span class="font-medium text-white/70">Hours:</span> {{ contact.hours }}</p>
</div>
</header>
<!-- Divider -->
<div class="mt-6 h-px w-full bg-gradient-to-r from-transparent via-white/10 to-transparent"></div>
<!-- Contact methods -->
<ul class="mt-6 space-y-2 text-sm">
{% if contact.email %}
<li class="group">
<a href="mailto:{{ contact.email }}" class="flex items-center gap-3 rounded-lg px-3 py-2 hover:bg-white/5 transition">
<span class="inline-flex h-8 w-8 items-center justify-center rounded-md border border-white/10 bg-white/5">
<!-- Mail icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 opacity-80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 7.5v9a2.25 2.25 0 01-2.25 2.25h-15A2.25 2.25 0 012.25 16.5v-9m19.5 0A2.25 2.25 0 0019.5 5.25h-15A2.25 2.25 0 002.25 7.5m19.5 0l-9.75 6.75L2.25 7.5"/>
</svg>
</span>
<span class="truncate text-white/80 group-hover:text-white">{{ contact.email }}</span>
</a>
</li>
{% endif %}
{% if contact.phone %}
<li class="group">
<a href="tel:{{ contact.phone }}" class="flex items-center gap-3 rounded-lg px-3 py-2 hover:bg-white/5 transition">
<span class="inline-flex h-8 w-8 items-center justify-center rounded-md border border-white/10 bg-white/5">
<!-- Phone icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 opacity-80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h1.5a1.5 1.5 0 001.5-1.5v-2.318a1.5 1.5 0 00-1.265-1.482l-3.03-.505a1.5 1.5 0 00-1.38.43l-.97.97a12.036 12.036 0 01-5.36-5.36l.97-.97a1.5 1.5 0 00.43-1.38l-.505-3.03A1.5 1.5 0 006.568 3H4.25A2 2 0 002.25 5v1.75z"/>
</svg>
</span>
<span class="truncate text-white/80 group-hover:text-white">{{ contact.phone }}</span>
</a>
</li>
{% endif %}
{% if contact.cal %}
<li class="group">
<a href="{{ contact.cal }}" class="flex items-center gap-3 rounded-lg px-3 py-2 hover:bg-white/5 transition" target="_blank" rel="noopener">
<span class="inline-flex h-8 w-8 items-center justify-center rounded-md border border-white/10 bg-white/5">
<!-- Calendar icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 opacity-80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v3M17.25 3v3M3.75 8.25h16.5M5.25 21h13.5A2.25 2.25 0 0021 18.75V8.25H3v10.5A2.25 2.25 0 005.25 21z"/>
</svg>
</span>
<span class="truncate text-white/80 group-hover:text-white">Book a call</span>
</a>
</li>
{% endif %}
<li class="group">
<a href="/benjamin.vcf" class="flex items-center gap-3 rounded-lg px-3 py-2 hover:bg-white/5 transition">
<span class="inline-flex h-8 w-8 items-center justify-center rounded-md border border-white/10 bg-white/5">
<!-- vCard icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 opacity-80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6.75h2.25A2.25 2.25 0 0120.25 9v6A2.25 2.25 0 0118 17.25H6A2.25 2.25 0 013.75 15V9A2.25 2.25 0 016 6.75h2.25"/>
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 12a2.25 2.25 0 104.5 0 2.25 2.25 0 00-4.5 0zM12.75 15.75c-1.5-1.125-3.75-1.125-5.25 0"/>
</svg>
</span>
<span class="truncate text-white/80 group-hover:text-white">Download vCard</span>
</a>
</li>
{% if contact.link %}
<li class="group">
<a href="{{ contact.link }}" class="flex items-center gap-3 rounded-lg px-3 py-2 hover:bg-white/5 transition" target="_blank" rel="noopener">
<span class="inline-flex h-8 w-8 items-center justify-center rounded-md border border-white/10 bg-white/5">
<!-- LinkedIn icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 opacity-80" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M4.98 3.5C4.98 4.88 3.86 6 2.5 6S0 4.88 0 3.5 1.12 1 2.5 1s2.48 1.12 2.48 2.5zM.5 8h4V24h-4V8zm7.5 0h3.8v2.2h.1c.5-1 1.9-2.2 3.9-2.2 4.1 0 4.9 2.7 4.9 6.2V24h-4v-7.1c0-1.7 0-3.9-2.4-3.9s-2.8 1.9-2.8 3.8V24h-4V8z"/>
</svg>
</span>
<span class="truncate text-white/80 group-hover:text-white">LinkedIn</span>
</a>
</li>
{% endif %}
</ul>
<!-- CTA -->
<div class="mt-8">
<a href="https://netdeploy.net"
class="inline-flex w-full items-center justify-center gap-2 rounded-xl px-5 py-3 font-semibold text-black shadow-lg transition
bg-gradient-to-b from-emerald-400 to-emerald-300 hover:from-emerald-300 hover:to-emerald-200 active:from-emerald-400 active:to-emerald-300">
<span>Get a Quote</span>
<!-- Arrow icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M13.5 4.5l6 6-6 6v-3.75H4.5v-4.5h9V4.5z"/>
</svg>
</a>
<p class="mt-3 text-xs text-white/50 text-center">No commitment—just a quick estimate.</p>
</div>
</div>
<!-- Right column -->
<div class="rounded-2xl border border-white/10 bg-black/30 p-6 sm:p-8">
<h2 class="text-xl font-semibold">How I can help</h2>
<p class="mt-2 text-white/70">
Need local IT, web hosting, or a custom app? Send a quick note or book a time that works for you.
I typically respond the same day.
</p>
<!-- Non-responsive map (fixed size) -->
<div class="mt-6 overflow-x-auto">
<iframe
class="block mx-auto rounded-xl border border-white/10 shadow-md"
width="600"
height="450"
style="border:0; max-width:100%;"
loading="lazy"
allowfullscreen
referrerpolicy="no-referrer-when-downgrade"
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d10563.745987097742!2d-101.84526106399407!3d35.2219850311224!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x870ac125c3ca1575%3A0x87f3e3d0ff616d5d!2sDowntown%20Amarillo%2C%20Amarillo%2C%20TX!5e0!3m2!1sen!2sus!4v1707800000000!5m2!1sen!2sus">
</iframe>
<p class="mt-2 text-xs text-white/50 text-center">Downtown Amarillo</p>
</div>
</div>
</div>
</div>
</section>
{% endblock %}

69
templates/index.html Normal file
View File

@@ -0,0 +1,69 @@
{% extends "base.html" %}
{% block content %}
<section class="relative overflow-hidden">
<div class="absolute inset-0 bg-grid mask-fade"></div>
<div class="max-w-7xl mx-auto px-6 py-16 md:py-24 grid md:grid-cols-2 gap-12 items-center">
<div>
<h1 class="font-bebas text-5xl md:text-7xl leading-none">No<span class="text-white/70"> House</span><br><span class="text-white/90">Quite Like It</span></h1>
<p class="mt-6 text-white/80 max-w-prose">Localfirst infrastructure, modern web hosting, and pragmatic creative. We refurbish and recycle hardware to cut costs, then deploy reliable systems you actually own.</p>
<div class="mt-8 flex flex-wrap gap-3">
<a href="{{ contact.cal }}" class="btn-primary">Book a 30min call</a>
<a href="/contact" class="btn-ghost">Get a quote</a>
</div>
<ul class="mt-6 flex flex-wrap gap-6 text-xs text-white/60">
<li class="dot">Onsite infrastructure</li>
<li class="dot">Flask/Node hosting</li>
<li class="dot">SSL + backups</li>
<li class="dot">Refurb discount option</li>
</ul>
</div>
<div class="space-y-4">
<div class="glass rounded-2xl p-2 shadow-2xl">
<img class="rounded-xl object-cover w-full h-64" src="{{ hero_imgs[0] }}" alt="Local area photo 1">
</div>
<div class="grid grid-cols-2 gap-4">
<div class="glass rounded-2xl p-2"><img class="rounded-xl object-cover w-full h-40" src="{{ hero_imgs[1] }}" alt="Local area photo 2"></div>
<div class="glass rounded-2xl p-2"><img class="rounded-xl object-cover w-full h-40" src="{{ hero_imgs[2] }}" alt="Local area photo 3"></div>
</div>
</div>
</div>
</section>
<section class="py-16 md:py-24">
<div class="max-w-7xl mx-auto px-6">
<h2 class="font-bebas text-4xl md:text-5xl">Services</h2>
<div class="mt-8 grid md:grid-cols-3 gap-6">
<article class="card">
<h3 class="card-title">Local IT Infrastructure</h3>
<p class="card-body">Proxmox clusters, VLANs, DNS, VPN, backups—made for small businesses that need reliability without red tape.</p>
<ul class="card-list">
<li>Windows Server/AD & Linux</li>
<li>Secure file servers (Samba/NFS)</li>
<li>Monitoring & on-call</li>
</ul>
</article>
<article class="card">
<h3 class="card-title">Web & App Hosting</h3>
<p class="card-body">Flask, Node, or static. SSL, backups, staging, and wildcard subdomains for rapid prototyping & launch.</p>
<ul class="card-list">
<li>Stripe + domain upsells</li>
<li>Fast Tailwind frontends</li>
<li>Observability baked in</li>
</ul>
</article>
<article class="card">
<h3 class="card-title">Refurb & Recycle Discount</h3>
<p class="card-body">Lower your quote by letting us refurbish quality used hardware into dependable local servers.</p>
<ul class="card-list">
<li>Costeffective nodes</li>
<li>Warranty & burnin tests</li>
<li>Green + budgetfriendly</li>
</ul>
</article>
</div>
</div>
</section>
{% endblock %}

67
templates/services.html Normal file
View File

@@ -0,0 +1,67 @@
{% extends "base.html" %}
{% block content %}
<section class="py-16 md:py-24">
<div class="max-w-6xl mx-auto px-6">
<header class="max-w-3xl">
<h1 class="font-bebas text-5xl">Services</h1>
<p class="mt-4 text-white/80">From local sysadmin to modern web, we tailor the stack to your constraints and budget — including refurbpowered discounts to keep costs sensible.</p>
</header>
<div class="mt-10 grid md:grid-cols-2 gap-6">
<article class="card">
<h3 class="card-title">Local System Administration</h3>
<p class="card-body">Onsite/remote support for small businesses and individuals. Proxmox clusters, Windows Server/Active Directory, Linux, backups, VLANs, DNS, VPN, and monitoring.</p>
<ul class="card-list">
<li>User & identity management (AD)</li>
<li>Secure file servers (Samba/NFS)</li>
<li>Automated backups & recovery drills</li>
</ul>
</article>
<article class="card">
<h3 class="card-title">Web Development & Hosting</h3>
<p class="card-body">Flask/Node apps or static sites with Tailwind frontends. SSL, backups, staging, wildcard subdomains — and Stripe/domain upsells when youre ready.</p>
<ul class="card-list">
<li>New builds or refactors</li>
<li>Observability baked in</li>
<li>Fast, accessible UI</li>
</ul>
</article>
<article class="card">
<h3 class="card-title">App Deployment & Integrations</h3>
<p class="card-body">Want a custom Obsidian server for your office? Need a selfhosted wiki, dashboard, or existing tool stood up securely? We handle the infra, auth, and logistics.</p>
<ul class="card-list">
<li>Install, configure, and harden</li>
<li>Singlesignon options</li>
<li>Backups & updates scheduled</li>
</ul>
</article>
<article class="card">
<h3 class="card-title">Refurb & Recycle Discounts</h3>
<p class="card-body">Lower your quote by letting us refurb quality used hardware into dependable local servers. Burnin tests and warranty options included.</p>
<ul class="card-list">
<li>Costeffective nodes</li>
<li>Green and budgetfriendly</li>
<li>Onsite support options</li>
</ul>
</article>
<article class="card md:col-span-2">
<h3 class="card-title">Enterprise via BrookHaven</h3>
<p class="card-body">If you need largerscale rollouts, compliance, or crosssite coordination, we can deliver through our enterprise channel (BrookHaven) while keeping execution pragmatic.</p>
<div class="mt-4">
<a href="/contact" class="btn-primary">Tell us what you need</a>
<a href="/about" class="btn-ghost ml-2">Learn about us</a>
</div>
</article>
</div>
</div>
</section>
{% endblock %}