tailwind v4 update

This commit is contained in:
Kismet Hasanaj
2026-05-02 19:48:50 +02:00
parent bad0d2a29a
commit ce8672e283
7 changed files with 734 additions and 322 deletions
+89
View File
@@ -0,0 +1,89 @@
# Editing The Website
This site is designed so most updates happen in one file:
- `public/index.html`
The design system lives separately in:
- `src/styles.css`
The generated stylesheet served by Nginx is:
- `public/styles.css`
## Common Updates
### Change The Main Headline
Open `public/index.html` and find:
```html
<h1>Novarix Networks</h1>
```
Keep this short. The supporting paragraph underneath should explain the offer.
### Change The Services
Open `public/index.html` and find:
```html
<section class="content-section" id="services">
```
Each service is an `<article class="service-card reveal">`.
You can safely edit:
- the `<h3>` title
- the `<p>` description
- the bullet points inside `<li>`
### Change Contact Details
Open `public/index.html` and search for:
```html
contact@novarixnet.com
```
Replace it with the real public inbox when ready.
## When To Run The Tailwind Build
If you only change words in `public/index.html`, the deploy script will still rebuild CSS for you.
On the server, run:
```bash
cd /var/www/novarixnet.com
./deploy.sh
```
That pulls the newest code, rebuilds Tailwind, tests Nginx and reloads the site.
## Local Preview
Install dependencies:
```bash
npm install --no-package-lock
```
Build the CSS:
```bash
npm run build
```
Preview the `public/` folder with any static server you prefer.
## Server Update
On the Nginx VM:
```bash
cd /var/www/novarixnet.com
./deploy.sh
```
+142 -84
View File
@@ -1,115 +1,173 @@
# Novarix Networks Website # Novarix Networks Website
Static marketing site for `Novarix Networks`, prepared for this deployment model: Static Tailwind CSS website for `Novarix Networks`.
- `Gitea` as the source of truth for the code The site is designed for this workflow:
- `Ubuntu 24.04` VM running `Nginx` as the private web server
- `Nginx Proxy Manager` exposing the site publicly and handling SSL - edit locally
- push changes to your internal `Gitea` repo
- run one deploy command on the Ubuntu Nginx VM
- serve the site from `/var/www/novarixnet.com/public`
- expose it publicly through `Nginx Proxy Manager`
## Project Structure ## Project Structure
- `public/` static files that should be deployed to the web root - `public/index.html` main website content
- `public/assets/logo/` brand assets used by the site - `public/styles.css` generated CSS served by Nginx after `npm run build`
- `public/assets/favicon/` favicon files - `public/script.js` small navigation and reveal animation script
- `ops/nginx/novarixnet.com.conf.example` example Nginx server block - `public/assets/` logo and favicon assets
- `src/styles.css` Tailwind source file
- `EDITING.md` simple guide for changing content
- `deploy.sh` server-side update script
- `ops/nginx/novarixnet.com.conf.example` example Nginx config
## Current Recommended Architecture ## Important Tailwind Note
1. Keep this project in your internal `Gitea` repo. This project uses the current Tailwind CSS v4 CLI setup:
2. Use the `Ubuntu 24.04` VM as the dedicated private web server.
3. Install `nginx` on that VM.
4. Deploy the contents of `public/` to something like `/var/www/novarixnet.com`.
5. Use `Nginx Proxy Manager` to proxy the public domain to the VM's private IP and Nginx port.
6. Let `Nginx Proxy Manager` handle the public certificate and HTTPS redirect.
## Recommended Workflow
This is the cleanest way to handle changes:
1. Edit the site locally.
2. Commit and push to `Gitea`.
3. On the `Ubuntu 24.04` web VM, pull the latest repo changes.
4. Sync the contents of `public/` into `/var/www/novarixnet.com`.
5. Reload `nginx` if needed.
This keeps:
- your repo as the source of truth
- the web VM as a deployment target
- live web files separate from the Git working tree
## Important Deployment Note
Do not point `nginx` directly at the Git repository directory if you can avoid it.
Better approach:
- keep the repo in a path such as `/opt/novarix-website`
- serve the live site from `/var/www/novarixnet.com`
- copy or sync `public/` into `/var/www/novarixnet.com` during deployment
That gives you a cleaner separation between:
- source code
- deployment files
- web server content
## Example Web VM Layout
- Repo checkout: `/opt/novarix-website`
- Live site root: `/var/www/novarixnet.com`
- Nginx site config: `/etc/nginx/sites-available/novarixnet.com`
## Example Deployment Flow On The Web VM
Clone the repo once:
```bash ```bash
git clone <your-gitea-repo-url> /opt/novarix-website npm install tailwindcss @tailwindcss/cli
``` ```
Deploy updated files: Tailwind builds `src/styles.css` into this generated file:
```bash ```text
sudo mkdir -p /var/www/novarixnet.com public/styles.css
sudo rsync -av --delete /opt/novarix-website/public/ /var/www/novarixnet.com/
``` ```
Reload Nginx: Nginx serves the compiled `public/styles.css` file. It does not understand Tailwind directly, so the build step must run after the repo is pulled.
## Ubuntu 24.04 Nginx Server Setup
Install Nginx and Git:
```bash ```bash
sudo apt update
sudo apt install -y nginx git
sudo systemctl enable nginx
sudo systemctl start nginx
```
Install Node.js 20 or newer. NodeSource currently supports Ubuntu 24.04 with Node 22, which is a good choice for this server:
```bash
sudo apt install -y curl
curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt install -y nodejs
```
After installing, confirm:
```bash
node --version
npm --version
```
Create the web directory and make your normal sudo user the owner:
```bash
sudo mkdir -p /var/www
sudo chown -R $USER:$USER /var/www
```
Clone the Gitea repo:
```bash
git clone http://10.10.10.11:3000/kismet.hasanaj/novarix-networks-homepage.git /var/www/novarixnet.com
```
Install the website dependencies and build the CSS:
```bash
cd /var/www/novarixnet.com
npm install --no-package-lock
npm run build
```
Use the Nginx config in:
```text
ops/nginx/novarixnet.com.conf.example
```
The important Nginx root is:
```nginx
root /var/www/novarixnet.com/public;
```
Enable the site:
```bash
sudo ln -s /etc/nginx/sites-available/novarixnet.com /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx sudo systemctl reload nginx
``` ```
## Nginx Proxy Manager Flow ## Updating The Live Website
- Public DNS record points to your public IP After pushing changes to Gitea from your local machine, SSH into the Nginx VM and run:
- Router forwards `80` and `443` to the host running `Nginx Proxy Manager`
- `Nginx Proxy Manager` receives the public request
- `Nginx Proxy Manager` proxies traffic to the private `Ubuntu 24.04` web VM
- Private `nginx` serves the static files
## Canonical Domain Suggestion ```bash
cd /var/www/novarixnet.com
./deploy.sh
```
Your strongest current options are: The deploy script does this:
- `novarixnet.com` for broad and international branding ```bash
- `novarix.co.uk` for a stronger UK-local trust signal git pull origin main
npm install --no-package-lock
npm run build
sudo nginx -t
sudo systemctl reload nginx
```
Pick one as the canonical domain and redirect the others to it. If the script is not executable yet, run this once:
## Notes For This Site ```bash
chmod +x /var/www/novarixnet.com/deploy.sh
```
- Replace the placeholder `contact@novarixnet.com` link in `public/index.html` ## Editing The Site
- Add real company contact details before launch
- Add legal pages such as privacy and terms
- Add deeper service pages once the ISP, MSP, and transit offers are finalized
- Add a contact form or CRM integration later if needed
## Included Nginx Example For simple content changes, edit:
Use the example config here as a starting point: ```text
public/index.html
```
- `ops/nginx/novarixnet.com.conf.example` For visual styling changes, edit:
Review the domain names, root path, and cache rules before using it in production. ```text
src/styles.css
```
The quick editing guide is:
```text
EDITING.md
```
## Nginx Proxy Manager
Create a proxy host:
- Domain: `novarixnet.com`
- Scheme: `http`
- Forward hostname/IP: private IP of the Ubuntu Nginx VM
- Forward port: `80`
- SSL: request certificate and force SSL
- Enable `Block Common Exploits`
## Canonical Domain
Recommended primary domain:
```text
novarixnet.com
```
Redirect the other Novarix domains to the primary domain once DNS and Nginx Proxy Manager are ready.
Executable
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
cd /var/www/novarixnet.com
git pull origin main
npm install --no-package-lock
npm run build
sudo nginx -t
sudo systemctl reload nginx
echo "Novarix Networks website deployed."
+1 -1
View File
@@ -2,7 +2,7 @@ server {
listen 80; listen 80;
server_name novarixnet.com www.novarixnet.com; server_name novarixnet.com www.novarixnet.com;
root /var/www/novarixnet.com; root /var/www/novarixnet.com/public;
index index.html; index index.html;
location / { location / {
+15
View File
@@ -0,0 +1,15 @@
{
"name": "novarix-networks-homepage",
"version": "1.0.0",
"private": true,
"description": "Static Tailwind CSS website for Novarix Networks.",
"scripts": {
"build": "tailwindcss -i ./src/styles.css -o ./public/styles.css --minify",
"watch": "tailwindcss -i ./src/styles.css -o ./public/styles.css --watch",
"serve": "npx serve public"
},
"devDependencies": {
"@tailwindcss/cli": "latest",
"tailwindcss": "latest"
}
}
+128 -168
View File
@@ -3,24 +3,23 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Novarix Networks | Agile Connectivity, Managed Services, and Transit</title> <title>Novarix Networks | ISP, MSP and Transit Provider</title>
<meta <meta
name="description" name="description"
content="Novarix Networks delivers agile connectivity, managed infrastructure, and transit services for businesses, operators, and demanding environments." content="Novarix Networks provides agile business connectivity, managed network services and transit for organisations that need practical engineering and dependable infrastructure."
/> />
<meta <meta
name="keywords" name="keywords"
content="Novarix Networks, ISP, MSP, transit provider, managed networking, business connectivity, network infrastructure" content="Novarix Networks, ISP, MSP, transit provider, business internet, managed network services, IP transit"
/> />
<meta name="theme-color" content="#04111f" /> <meta name="theme-color" content="#071014" />
<link rel="icon" type="image/png" href="/assets/favicon/favicon8.png" /> <link rel="icon" type="image/png" href="/assets/favicon/favicon8.png" />
<link rel="apple-touch-icon" href="/assets/favicon/favicon9.png" /> <link rel="apple-touch-icon" href="/assets/favicon/favicon9.png" />
<link rel="stylesheet" href="/styles.css" /> <link rel="stylesheet" href="/styles.css" />
</head> </head>
<body> <body>
<div class="site-shell">
<header class="site-header"> <header class="site-header">
<a class="brand" href="#top" aria-label="Novarix Networks home"> <a class="brand-link" href="#top" aria-label="Novarix Networks home">
<img src="/assets/logo/novarix_networks-white.svg" alt="Novarix Networks" /> <img src="/assets/logo/novarix_networks-white.svg" alt="Novarix Networks" />
</a> </a>
<button <button
@@ -33,225 +32,186 @@
<span></span> <span></span>
<span></span> <span></span>
</button> </button>
<nav class="site-nav" id="primary-nav"> <nav class="site-nav" id="primary-nav" aria-label="Primary navigation">
<a href="#services">Services</a> <a href="#services">Services</a>
<a href="#approach">Approach</a> <a href="#network">Network</a>
<a href="#infrastructure">Infrastructure</a> <a href="#customers">Customers</a>
<a href="#contact">Contact</a> <a href="#contact">Contact</a>
</nav> </nav>
</header> </header>
<main id="top"> <main id="top">
<section class="hero"> <!-- Edit the hero wording here. Keep the headline short and direct. -->
<div class="hero-copy reveal"> <section class="hero-section">
<p class="eyebrow">Connectivity without the drag</p> <div class="hero-bg" aria-hidden="true">
<h1>Network infrastructure built to move as fast as the environment around it.</h1> <img src="/assets/logo/animated_logo_intro.svg" alt="" />
<p class="hero-text"> </div>
Novarix Networks is being shaped to serve as an agile ISP, MSP, and <div class="hero-content reveal">
transit provider for organisations that need dependable connectivity, <p class="eyebrow">Independent network operator in buildout</p>
practical engineering, and infrastructure that can keep evolving. <h1>Novarix Networks</h1>
<p class="hero-lede">
Agile ISP, MSP and transit services for businesses, operators and projects that need
networking handled with pace, clarity and engineering discipline.
</p> </p>
<div class="hero-actions"> <div class="hero-actions">
<a class="button button-primary" href="#contact">Start the conversation</a> <a class="button-primary" href="#contact">Discuss connectivity</a>
<a class="button button-secondary" href="#services">Explore services</a> <a class="button-secondary" href="#services">View services</a>
</div> </div>
<ul class="hero-points">
<li>Business connectivity and routed access</li>
<li>Managed network and edge services</li>
<li>Transit, interconnect, and custom builds</li>
</ul>
</div> </div>
<div class="hero-status reveal">
<div class="hero-visual reveal"> <div>
<div class="hero-orbit"> <span>Focus</span>
<div class="signal-grid"></div>
<img
class="animated-mark"
src="/assets/logo/animated_logo_intro.svg"
alt="Animated Novarix Networks logo"
/>
<div class="status-card status-card-left">
<span class="status-kicker">Positioning</span>
<strong>ISP / MSP / Transit</strong> <strong>ISP / MSP / Transit</strong>
<p>Built for flexible projects, modern routing, and growth-ready delivery.</p>
</div> </div>
<div class="status-card status-card-right"> <div>
<span class="status-kicker">Operating model</span> <span>Built for</span>
<strong>Lean, technical, responsive</strong> <strong>Fast-moving network requirements</strong>
<p>A brand direction designed to feel more engineering-led than corporate.</p>
</div> </div>
<div>
<span>Primary domain</span>
<strong>novarixnet.com</strong>
</div> </div>
</div> </div>
</section> </section>
<section class="proof-strip reveal"> <section class="intro-band reveal" aria-label="Company introduction">
<div> <p>
<span>For businesses</span> Novarix Networks is being built for organisations that want a networking partner with a
<p>Connectivity and managed networking designed around uptime, reach, and clarity.</p> direct technical conversation, a practical operating model and the flexibility to shape
</div> connectivity around the real environment.
<div> </p>
<span>For operators</span>
<p>Transit and interconnect conversations grounded in routing, performance, and fit.</p>
</div>
<div>
<span>For projects</span>
<p>Flexible enough for bespoke deployments, migrations, and edge-focused solutions.</p>
</div>
</section> </section>
<section class="section" id="services"> <!-- Service cards: edit titles, descriptions and bullets as your offer becomes more specific. -->
<section class="content-section" id="services">
<div class="section-heading reveal"> <div class="section-heading reveal">
<p class="eyebrow">Services</p> <p class="eyebrow">Services</p>
<h2>Three service pillars, one consistent operating mindset.</h2> <h2>Connectivity, managed networking and transit under one engineering-led brand.</h2>
<p>
The first version of the site should make the offer easy to understand at a glance.
This layout keeps the positioning clear while leaving room to deepen each service page later.
</p>
</div> </div>
<div class="card-grid"> <div class="service-grid">
<article class="service-card reveal"> <article class="service-card reveal">
<span class="card-index">01</span> <span class="service-number">01</span>
<h3>ISP</h3> <h3>Business Connectivity</h3>
<p> <p>
Business internet, routed connectivity, and infrastructure built for organisations Internet access and routed connectivity for businesses that need static addressing,
that need more than a generic off-the-shelf link. clear support routes and a provider able to work close to the network.
</p> </p>
<ul> <ul>
<li>Dedicated access</li> <li>Business internet access</li>
<li>Static addressing</li> <li>Static IP addressing</li>
<li>Custom network design</li> <li>Custom routed handoff options</li>
</ul> </ul>
</article> </article>
<article class="service-card reveal"> <article class="service-card reveal">
<span class="card-index">02</span> <span class="service-number">02</span>
<h3>MSP</h3> <h3>Managed Network Services</h3>
<p> <p>
Managed network services for teams that want stronger visibility, better change Managed edge, routing and operational support for teams that want reliable network
control, and a partner that can operate close to the infrastructure. ownership without carrying every change, incident and upgrade alone.
</p> </p>
<ul> <ul>
<li>Managed edge and routing</li> <li>Managed edge infrastructure</li>
<li>Operational support</li> <li>Change and migration support</li>
<li>Network evolution planning</li> <li>Network health and visibility</li>
</ul> </ul>
</article> </article>
<article class="service-card reveal"> <article class="service-card reveal">
<span class="card-index">03</span> <span class="service-number">03</span>
<h3>Transit</h3> <h3>Transit and Interconnect</h3>
<p> <p>
Transit and interconnect positioning for carriers, platforms, and demanding environments Transit-focused services for operators, platforms and technical environments that care
that care about path quality, flexibility, and engineering credibility. about routing posture, interconnection options and scalable delivery.
</p> </p>
<ul> <ul>
<li>IP transit</li> <li>IP transit planning</li>
<li>Peering and interconnect</li> <li>Peering and interconnect readiness</li>
<li>Scalable routing posture</li> <li>Carrier and operator engagement</li>
</ul> </ul>
</article> </article>
</div> </div>
</section> </section>
<section class="section section-split" id="approach"> <section class="network-section" id="network">
<div class="section-heading reveal"> <div class="network-copy reveal">
<p class="eyebrow">Approach</p> <p class="eyebrow">Operating model</p>
<h2>Designed to feel modern, direct, and technically credible.</h2> <h2>Built to stay sharp as networking conditions change.</h2>
</div>
<div class="split-panel reveal">
<div class="approach-list">
<article>
<h3>Agile by default</h3>
<p> <p>
The tone and structure lean into speed, clarity, and practical execution rather than The Novarix site should feel like the company it represents: direct, technically capable
generic telecom language. and quick to adapt. The layout keeps the offer visible while leaving room for future pages
such as looking glass tools, network status, peering policy and customer portals.
</p> </p>
</article>
<article>
<h3>Engineering-led presentation</h3>
<p>
Visual direction is based on the geometry and colour depth of your logo, helping the
brand feel network-native without looking dated.
</p>
</article>
<article>
<h3>Launch small, scale cleanly</h3>
<p>
This base site is intentionally static and fast so you can get online quickly, then add
service detail, portals, status pages, and forms as the company grows.
</p>
</article>
</div> </div>
<div class="approach-panel"> <div class="network-panel reveal">
<div class="approach-graphic"> <div class="network-row">
<span class="pulse pulse-one"></span> <span>01</span>
<span class="pulse pulse-two"></span>
<span class="pulse pulse-three"></span>
<div class="approach-core">
<strong>Novarix</strong>
<span>Networks</span>
</div>
</div>
</div>
</div>
</section>
<section class="section" id="infrastructure">
<div class="section-heading reveal">
<p class="eyebrow">Deployment</p>
<h2>Built to drop straight into your Proxmox and NPM workflow.</h2>
</div>
<div class="deployment-grid">
<article class="deployment-card reveal">
<h3>1. Host the site privately</h3>
<p>
Run Nginx on a private VM or container in Proxmox and serve this static site locally on your LAN.
</p>
</article>
<article class="deployment-card reveal">
<h3>2. Publish through NPM</h3>
<p>
Add a proxy host in Nginx Proxy Manager pointing the public domain to the private web server.
</p>
</article>
<article class="deployment-card reveal">
<h3>3. Add SSL and redirects</h3>
<p>
Let NPM issue the certificate, force HTTPS, and redirect every secondary domain to the canonical one.
</p>
</article>
<article class="deployment-card reveal">
<h3>4. Expand later</h3>
<p>
Keep the website separate from future customer portals, looking glass tools, monitoring pages, or APIs.
</p>
</article>
</div>
</section>
<section class="section cta-section reveal" id="contact">
<div class="cta-panel">
<div> <div>
<p class="eyebrow">Next step</p> <h3>Lean delivery</h3>
<h2>Launch the brand, then sharpen the details.</h2> <p>Shorter paths from requirement to answer, with practical engineering at the centre.</p>
</div>
</div>
<div class="network-row">
<span>02</span>
<div>
<h3>Clear ownership</h3>
<p>Service boundaries, routing decisions and support expectations explained plainly.</p>
</div>
</div>
<div class="network-row">
<span>03</span>
<div>
<h3>Room to grow</h3>
<p>A static marketing site today, with clean paths for portals and network tools later.</p>
</div>
</div>
</div>
</section>
<section class="content-section" id="customers">
<div class="section-heading reveal">
<p class="eyebrow">Who it serves</p>
<h2>A clearer first impression for the customers you want to attract.</h2>
</div>
<div class="customer-grid">
<article class="customer-card reveal">
<h3>Businesses</h3>
<p>Connectivity that can be discussed with someone who understands the technical detail.</p>
</article>
<article class="customer-card reveal">
<h3>IT teams</h3>
<p>Managed network support for teams that need capacity without losing visibility.</p>
</article>
<article class="customer-card reveal">
<h3>Operators</h3>
<p>Transit and interconnect conversations that start from routing reality, not sales theatre.</p>
</article>
<article class="customer-card reveal">
<h3>Projects</h3>
<p>Bespoke networking support for migrations, edge deployments and unusual requirements.</p>
</article>
</div>
</section>
<!-- Contact details: replace the email and wording when your public inbox is final. -->
<section class="contact-section reveal" id="contact">
<div>
<p class="eyebrow">Start here</p>
<h2>Bring us the network problem. We will help shape the route forward.</h2>
<p> <p>
This base design is ready for real content, domain decisions, and production hosting. This contact point is ready to be replaced with your production inbox, quote form or CRM
Once you choose your final contact route, we can wire in live enquiry handling, deeper service pages, endpoint when you decide how you want enquiries handled.
and any customer-facing systems you want to expose later.
</p> </p>
</div> </div>
<div class="cta-actions"> <div class="contact-actions">
<a class="button button-primary" href="mailto:contact@novarixnet.com">Use placeholder contact</a> <a class="button-primary" href="mailto:contact@novarixnet.com">contact@novarixnet.com</a>
<a class="button button-secondary" href="/assets/logo/novarix_networks-coloured.svg">View brand asset</a> <a class="button-secondary" href="https://novarixnet.com">novarixnet.com</a>
</div>
</div> </div>
</section> </section>
</main> </main>
<footer class="site-footer"> <footer class="site-footer">
<img src="/assets/logo/novarix_networks-white.svg" alt="Novarix Networks" /> <img src="/assets/logo/novarix_networks-white.svg" alt="Novarix Networks" />
<p>Agile connectivity, managed services, and transit positioning for modern networks.</p> <p>ISP, MSP and transit services for modern network environments.</p>
<small>Base website concept prepared for private hosting behind Nginx Proxy Manager.</small>
</footer> </footer>
</div>
<script src="/script.js"></script> <script src="/script.js"></script>
</body> </body>
+278
View File
@@ -0,0 +1,278 @@
@import "tailwindcss";
@source "../public";
@theme {
--font-sans: "Aptos", "Satoshi", "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
--color-ink: #071014;
--color-graphite: #11181d;
--color-panel: #f5f8f8;
--color-line: #d9e5e5;
--color-cyan: #38d1d4;
--color-teal: #147d89;
--color-blueprint: #205c8c;
--color-lime: #c8f05a;
}
@layer base {
html {
scroll-behavior: smooth;
}
body {
@apply m-0 min-w-80 bg-panel font-sans text-ink antialiased;
}
img {
@apply block max-w-full;
}
a {
@apply text-inherit no-underline;
}
}
@layer components {
.site-header {
@apply fixed left-1/2 top-4 z-50 flex w-[calc(100%_-_1rem)] max-w-[74rem] -translate-x-1/2 items-center justify-between gap-4 border border-white/10 bg-ink/86 px-4 py-3 text-white shadow-2xl shadow-ink/25 backdrop-blur-xl md:top-6 md:w-[calc(100%_-_3rem)] md:px-5;
}
.brand-link {
@apply w-48 shrink-0 md:w-60;
}
.site-nav {
@apply hidden items-center gap-7 text-sm font-medium text-white/72 md:flex;
}
.site-nav a {
@apply transition hover:text-white focus-visible:text-white focus-visible:outline-none;
}
.nav-toggle {
@apply grid h-11 w-11 place-items-center border border-white/12 bg-white/8 md:hidden;
}
.nav-toggle span {
@apply block h-0.5 w-5 bg-white transition;
}
.nav-toggle span + span {
@apply mt-1.5;
}
.site-header.nav-open .site-nav {
@apply absolute left-0 right-0 top-[calc(100%+0.5rem)] flex flex-col items-stretch gap-0 border border-white/10 bg-ink p-2 text-white shadow-xl md:static md:flex-row md:items-center md:gap-7 md:border-0 md:bg-transparent md:p-0 md:shadow-none;
}
.site-header.nav-open .site-nav a {
@apply px-3 py-3;
}
.site-header.nav-open .nav-toggle span:first-child {
@apply translate-y-1 rotate-45;
}
.site-header.nav-open .nav-toggle span:last-child {
@apply -translate-y-1 -rotate-45;
}
.hero-section {
@apply relative grid min-h-[92svh] overflow-hidden bg-ink px-4 pb-10 pt-28 text-white md:px-8 md:pb-12 md:pt-32;
}
.hero-section::before {
content: "";
@apply absolute inset-0 opacity-50;
background-image:
linear-gradient(rgba(255, 255, 255, 0.08) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.08) 1px, transparent 1px);
background-size: 42px 42px;
mask-image: linear-gradient(180deg, transparent, black 20%, black 78%, transparent);
}
.hero-section::after {
content: "";
@apply absolute inset-x-0 bottom-0 h-40 bg-linear-to-t from-panel to-transparent;
}
.hero-bg {
@apply pointer-events-none absolute inset-0 overflow-hidden;
}
.hero-bg img {
@apply absolute left-1/2 top-1/2 w-[74rem] max-w-none -translate-x-1/2 -translate-y-1/2 opacity-20 blur-[1px] saturate-150;
}
.hero-content {
@apply relative z-10 mx-auto grid w-full max-w-6xl content-center;
}
.eyebrow {
@apply mb-4 text-xs font-bold uppercase text-cyan;
}
.hero-content h1 {
@apply max-w-5xl text-6xl font-black leading-[0.9] text-white text-shadow-lg/35 md:text-8xl lg:text-9xl;
}
.hero-lede {
@apply mt-7 max-w-3xl text-lg leading-8 text-white/76 md:text-xl;
}
.hero-actions,
.contact-actions {
@apply mt-8 flex flex-wrap gap-3;
}
.button-primary,
.button-secondary {
@apply inline-flex min-h-12 items-center justify-center px-5 text-sm font-bold transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-cyan;
}
.button-primary {
@apply bg-lime text-ink shadow-lg shadow-lime/20 hover:-translate-y-0.5;
}
.button-secondary {
@apply border border-current bg-transparent text-current hover:-translate-y-0.5 hover:bg-white/8;
}
.hero-status {
@apply relative z-10 mx-auto mt-10 grid w-full max-w-6xl gap-px border border-white/12 bg-white/12 md:grid-cols-3;
}
.hero-status div {
@apply bg-ink/70 p-5 backdrop-blur;
}
.hero-status span {
@apply mb-2 block text-xs font-bold uppercase text-white/52;
}
.hero-status strong {
@apply block text-lg text-white;
}
.intro-band {
@apply mx-auto -mt-2 w-[calc(100%_-_2rem)] max-w-[74rem] border-x border-line bg-panel px-0 py-14 md:py-20;
}
.intro-band p {
@apply max-w-5xl text-3xl font-semibold leading-tight md:text-5xl;
}
.content-section {
@apply mx-auto w-[calc(100%_-_2rem)] max-w-[74rem] py-16 md:py-24;
}
.section-heading {
@apply max-w-4xl;
}
.section-heading h2,
.network-copy h2,
.contact-section h2 {
@apply text-4xl font-black leading-tight md:text-6xl;
}
.service-grid {
@apply mt-10 grid gap-4 md:grid-cols-3;
}
.service-card,
.customer-card {
@apply border border-line bg-white p-6 shadow-sm transition hover:-translate-y-1 hover:shadow-xl hover:shadow-ink/8;
}
.service-number {
@apply mb-12 block text-sm font-black text-teal;
}
.service-card h3,
.customer-card h3,
.network-row h3 {
@apply text-2xl font-black leading-tight;
}
.service-card p,
.customer-card p,
.network-copy p,
.network-row p,
.contact-section p {
@apply mt-4 leading-7 text-graphite/72;
}
.service-card ul {
@apply mt-6 space-y-2 border-t border-line pt-5 text-sm font-semibold text-graphite/74;
}
.service-card li {
@apply flex gap-2;
}
.service-card li::before {
content: "";
@apply mt-2 h-1.5 w-1.5 shrink-0 bg-cyan;
}
.network-section {
@apply grid gap-0 bg-graphite text-white md:grid-cols-2;
}
.network-copy {
@apply mx-auto w-full max-w-[37rem] px-4 py-16 md:ml-auto md:px-8 md:py-24;
}
.network-copy p {
@apply text-white/70;
}
.network-panel {
@apply grid border-t border-white/10 md:border-l md:border-t-0;
}
.network-row {
@apply grid grid-cols-[4rem_1fr] gap-4 border-b border-white/10 px-4 py-10 md:px-8;
}
.network-row span {
@apply text-sm font-black text-cyan;
}
.network-row p {
@apply text-white/68;
}
.customer-grid {
@apply mt-10 grid gap-4 md:grid-cols-2;
}
.customer-card {
@apply min-h-48;
}
.contact-section {
@apply mx-auto mb-8 grid w-[calc(100%_-_2rem)] max-w-[74rem] gap-8 bg-ink p-6 text-white md:grid-cols-[1fr_auto] md:p-10;
}
.contact-section p {
@apply max-w-3xl text-white/72;
}
.site-footer {
@apply mx-auto flex w-[calc(100%_-_2rem)] max-w-[74rem] flex-col gap-4 border-t border-line py-10 text-sm text-graphite/70 md:flex-row md:items-center md:justify-between;
}
.site-footer img {
@apply w-52 invert;
}
.reveal {
@apply translate-y-5 opacity-0 transition duration-700 ease-out;
}
.reveal.is-visible {
@apply translate-y-0 opacity-100;
}
}