From 50a920e650ff18de1a13d6db3b495cfca52a4414 Mon Sep 17 00:00:00 2001 From: Rolando Santamaria Maso Date: Sun, 8 Mar 2026 12:13:13 +0100 Subject: [PATCH 1/5] feat: upgrade landing page to premium dark mode --- docs/index.html | 14 ++++++++------ docs/styles.css | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/index.html b/docs/index.html index 40980f9..1bd0731 100644 --- a/docs/index.html +++ b/docs/index.html @@ -48,7 +48,7 @@ @@ -298,7 +298,9 @@

Everything You Need

-
โšก
+
+ +

Near-Zero Alloc Hot Path

~141k req/sec โ€” 55% faster than Bun. Built on fasthttp with direct ctx.SetBody() and pre-formatted headers โ€” no formatting allocations on cache hits.

@@ -319,7 +321,7 @@

TLS 1.2 / 1.3

-
๐Ÿ›ก๏ธ
+

Security Hardened

Path traversal prevention, dotfile blocking, CSP, HSTS, Referrer-Policy, Permissions-Policy โ€” set on @@ -523,7 +525,7 @@

HTTP Request

-
๐Ÿ›ก๏ธ
+

Recovery Middleware

Panic โ†’ 500, log stack trace

@@ -714,7 +716,7 @@

Configuration Reference

- ๐Ÿ›ก๏ธ security + security
@@ -1030,7 +1032,7 @@

Security Model

๐Ÿ“‹ Headers
-
๐Ÿ—œ๏ธ
+

gzip + Brotli

On-the-fly gzip via pooled writers, plus pre-compressed .gz/.br sidecar file @@ -313,7 +313,7 @@

gzip + Brotli

-
๐Ÿ”’
+

TLS 1.2 / 1.3

Modern cipher suites, automatic HTTPโ†’HTTPS redirects, HSTS, and HTTP/2 via ALPN negotiation โ€” just set @@ -329,12 +329,12 @@

Security Hardened

-
๐Ÿ“ฆ
+

Smart Caching

Byte-accurate LRU cache with startup preloading, configurable max size, per-file size cap, optional TTL expiry, ETag, and live flush via SIGHUP without downtime.

-
๐Ÿ”„
+

HTTP/2 & Range Requests

Full HTTP/2 support, byte-range serving for video / large files, conditional requests (ETag, @@ -342,7 +342,7 @@

HTTP/2 & Range Requests

-
๐ŸŒ
+

CORS Built-In

Wildcard or per-origin CORS. Preflight returns 204 with proper headers. Wildcard emits literal @@ -350,7 +350,7 @@

CORS Built-In

-
๐Ÿณ
+

Container Ready

Most settings overridable via environment variables. Graceful shutdown on SIGTERM/SIGINT with @@ -358,7 +358,7 @@

Container Ready

-
๐Ÿ“‚
+

Directory Listing

Optional HTML directory index with breadcrumb nav, sorted entries, human-readable sizes, and automatic @@ -513,7 +513,7 @@

Request Pipeline

-
๐ŸŒ
+

HTTP Request

Incoming GET / HEAD / OPTIONS

@@ -537,7 +537,7 @@

Recovery Middleware

-
๐Ÿ“
+

Logging Middleware

Pooled status writer, method / path / status / bytes / duration

@@ -549,7 +549,7 @@

Logging Middleware

-
๐Ÿ”
+

Security Middleware

Method whitelist ยท security headers ยท path safety (cached) ยท dotfile block ยท CORS

@@ -561,7 +561,7 @@

Security Middleware

-
๐Ÿ—œ๏ธ
+

Compress Middleware

Post-processing gzip via pooled writers ยท content-type / size gating

@@ -573,7 +573,7 @@

Compress Middleware

-
โšก
+

File Handler

@@ -605,19 +605,19 @@

Performance Benchmarks

- โšก static-web (fasthttp) + static-web (fasthttp) ~141,000 619 µs 2.46 ms - ๐Ÿฅˆ Bun (native static) + Bun (native static) ~90,000 1.05 ms 2.33 ms - ๐Ÿ“ฆ static-web (old net/http) + static-web (old net/http) ~76,000 1.25 ms 3.15 ms @@ -629,21 +629,21 @@

Performance Benchmarks

-
๐Ÿง 
+

fasthttp + Preload

Built on fasthttp with zero per-request allocations. --preload loads all files into RAM at startup. Cache hits use direct ctx.SetBody() with pre-formatted headers.

-
๐Ÿ”ค
+

55% Faster Than Bun

With fasthttp + preload, static-web reaches ~141k req/sec โ€” 55% faster than Bun at ~90k req/sec, while offering full security headers, TLS, and compression out of the box.

-
โ™ป๏ธ
+

GC tuned

gc_percent = 400 reduces GC frequency by 4x. The hot path is allocation-free โ€” fasthttp reuses per-connection buffers, eliminating the per-request allocations of net/http. @@ -671,7 +671,7 @@

Configuration Reference

- ๐Ÿ–ฅ๏ธ server + server
@@ -1305,7 +1305,7 @@

Legal

diff --git a/docs/script.js b/docs/script.js index c6649bf..d04fd57 100644 --- a/docs/script.js +++ b/docs/script.js @@ -332,7 +332,7 @@ document.querySelectorAll('a[href^="#"]').forEach(function (link) { โ€” Groups elements by parent section for incremental delays =========================== */ (function initReveal() { - var selectors = '.feature-card, .pipeline-step, .perf-card'; + var selectors = ".feature-card, .pipeline-step, .perf-card, .section-title, .section-description, .cta-card"; var targets = document.querySelectorAll(selectors); if (!targets.length) return; diff --git a/docs/styles.css b/docs/styles.css index 6b3d026..09ca51d 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -73,6 +73,20 @@ a { color: inherit; text-decoration: none; } top: 16px; } +/* =========================== + Scroll-Reveal (injected by JS but base defined here for no-FOUC) + =========================== */ +.reveal { + opacity: 0; + transform: translateY(24px); + transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1), transform 0.6s cubic-bezier(0.4, 0, 0.2, 1); +} + +.reveal.visible { + opacity: 1; + transform: translateY(0); +} + /* =========================== Navigation =========================== */ @@ -336,13 +350,17 @@ a { color: inherit; text-decoration: none; } border-radius: var(--radius-md); font-weight: 600; font-size: 0.9rem; - transition: all 0.3s ease; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); border: none; cursor: pointer; font-family: var(--font-sans); + position: relative; + overflow: hidden; } -.btn-icon { width: 18px; height: 18px; } +.btn-icon { width: 18px; height: 18px; transition: transform 0.3s ease; } + +.btn:hover .btn-icon { transform: scale(1.1); } .btn-primary { background: var(--gradient-primary); @@ -351,8 +369,8 @@ a { color: inherit; text-decoration: none; } } .btn-primary:hover { - transform: translateY(-2px); - box-shadow: 0 6px 32px rgba(255,255,255,0.3); + transform: translateY(-2px) scale(1.02); + box-shadow: 0 8px 32px rgba(255,255,255,0.4); } .btn-secondary { @@ -362,8 +380,10 @@ a { color: inherit; text-decoration: none; } } .btn-secondary:hover { - background: var(--color-border); - border-color: var(--color-border-light); + background: var(--color-bg-secondary); + border-color: var(--color-primary-light); + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(255,255,255,0.1); } /* Install bar (hero + CTA shared) */ @@ -511,9 +531,9 @@ a { color: inherit; text-decoration: none; } } .feature-card:hover { - border-color: var(--color-primary); - transform: translateY(-3px); - box-shadow: 0 8px 30px rgba(255,255,255,0.15); + border-color: var(--color-secondary); + transform: translateY(-4px); + box-shadow: 0 12px 40px rgba(139, 92, 246, 0.15), 0 0 20px rgba(139, 92, 246, 0.1); } .feature-icon { font-size: 1.8rem; margin-bottom: 10px; } @@ -761,10 +781,14 @@ a { color: inherit; text-decoration: none; } border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 20px; - transition: all 0.25s; + transition: all 0.3s ease; } -.perf-card:hover { border-color: var(--color-border-light); } +.perf-card:hover { + border-color: var(--color-accent); + transform: translateY(-4px); + box-shadow: 0 12px 40px rgba(34, 211, 238, 0.15), 0 0 20px rgba(34, 211, 238, 0.1); +} .perf-card-icon { font-size: 1.6rem; margin-bottom: 8px; } @@ -1122,28 +1146,16 @@ a { color: inherit; text-decoration: none; } .footer-bottom a:hover { color: var(--color-primary); } -/* =========================== - Scroll-Reveal (injected by JS but base defined here for no-FOUC) - =========================== */ -.reveal { - opacity: 0; - transform: translateY(24px); - transition: opacity 0.5s ease, transform 0.5s ease; -} - -.reveal.visible { - opacity: 1; - transform: none; -} - /* =========================== Responsive =========================== */ @media (max-width: 768px) { - .nav { padding: 16px 20px; } + .nav { padding: 12px 16px; gap: 16px; } + .nav-logo { gap: 8px; } + .logo-text { font-size: 1.1rem; } .nav-links { display: none; } .nav-cta { display: none; } - .nav-hamburger { display: flex; } + .nav-hamburger { display: flex; width: 36px; height: 36px; } /* Mobile nav overlay */ .nav-open .nav-links { @@ -1152,7 +1164,7 @@ a { color: inherit; text-decoration: none; } position: fixed; inset: 0; z-index: 100; - background: rgba(10, 10, 15, 0.97); + background: rgba(10, 10, 15, 0.98); backdrop-filter: blur(12px); align-items: center; justify-content: center; @@ -1167,41 +1179,47 @@ a { color: inherit; text-decoration: none; } } .hero { min-height: auto; } - .hero-content { padding: 20px 16px 40px; } - .hero-logo-svg { width: 72px; height: 72px; } + .hero-content { padding: 16px 12px 32px; } + .hero-logo-svg { width: 64px; height: 64px; } + .hero-title { font-size: 2.2rem; } + .hero-subtitle { font-size: 1rem; } .hero-stats { grid-template-columns: repeat(2, auto); - padding: 16px; - gap: 8px; - row-gap: 12px; + padding: 12px; + gap: 12px; + row-gap: 16px; + width: 100%; + margin-bottom: 20px; } /* Hide dividers on mobile 2ร—2 grid */ .stat-divider { display: none; } - .stat { padding: 0 12px; } + .stat { padding: 0 8px; } .stat-value { font-size: 1.05rem; } .hero-install, .cta-install { - padding: 12px 12px 12px 16px; + padding: 8px 8px 8px 16px; + width: 100%; } - .install-code { font-size: 0.75rem; } + .install-code { font-size: 0.75rem; overflow-x: auto; flex: 1; } - .section-inner { padding: 44px 16px; } + .section-inner { padding: 48px 16px; } - .features-grid { grid-template-columns: 1fr; } + .features-grid { grid-template-columns: 1fr; gap: 12px; } - .pipeline { padding: 0 4px; } - .pipeline-step { padding: 14px 16px; } - .pipeline-info p { font-size: 0.78rem; } + .pipeline { padding: 0; } + .pipeline-step { padding: 14px 16px; flex-direction: column; text-align: center; gap: 10px; } + .pipeline-icon { width: auto; } + .pipeline-info p { font-size: 0.8rem; } - .perf-cards { grid-template-columns: 1fr; } + .perf-cards { grid-template-columns: 1fr; gap: 12px; } .cta-card { padding: 32px 16px; } - .cta-install { padding: 10px 12px; } + .cta-install { padding: 8px 12px; } .footer-content { flex-direction: column; gap: 32px; } .footer-links-group { gap: 28px; } From 32f00bcd34a13d813e6759510986e361af21bcc3 Mon Sep 17 00:00:00 2001 From: Rolando Santamaria Maso Date: Sun, 8 Mar 2026 12:41:18 +0100 Subject: [PATCH 4/5] docs: clarify near-zero allocations on fasthttp hot path --- USER_GUIDE.md | 2 +- docs/index.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 3304ae9..fb5c728 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -638,7 +638,7 @@ STATIC_CACHE_PRELOAD=true STATIC_CACHE_GC_PERCENT=400 ./bin/static-web ### GC tuning -`gc_percent` sets the Go runtime `GOGC` target. A higher value means the GC runs less often, trading memory for throughput. The handler's hot path is allocation-free, and fasthttp reuses per-connection buffers (unlike net/http which allocates per-request). Recommended values: +`gc_percent` sets the Go runtime `GOGC` target. A higher value means the GC runs less often, trading memory for throughput. The handler's hot path has near-zero allocations, and fasthttp reuses per-connection buffers (unlike net/http which allocates per-request). Recommended values: | `gc_percent` | Behaviour | |---|---| diff --git a/docs/index.html b/docs/index.html index 717e0b5..82addb0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -632,7 +632,7 @@

Performance Benchmarks

fasthttp + Preload

- Built on fasthttp with zero per-request allocations. --preload loads all files into RAM at startup. Cache hits use direct ctx.SetBody() with pre-formatted headers. + Built on fasthttp with near-zero per-request allocations. --preload loads all files into RAM at startup. Cache hits use direct ctx.SetBody() with pre-formatted headers.

@@ -646,7 +646,7 @@

55% Faster Than Bun

GC tuned

- gc_percent = 400 reduces GC frequency by 4x. The hot path is allocation-free โ€” fasthttp reuses per-connection buffers, eliminating the per-request allocations of net/http. + gc_percent = 400 reduces GC frequency by 4x. The hot path has near-zero allocations โ€” fasthttp reuses per-connection buffers, eliminating the per-request allocations of net/http.

From f4ada4f2d13f766a4a84420092c97ccab03c2b23 Mon Sep 17 00:00:00 2001 From: Rolando Santamaria Maso Date: Sun, 8 Mar 2026 12:43:25 +0100 Subject: [PATCH 5/5] style(ui): reduce vertical spacing in hero section --- docs/styles.css | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/styles.css b/docs/styles.css index 09ca51d..4dce2dd 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -216,7 +216,7 @@ a { color: inherit; text-decoration: none; } position: relative; display: flex; flex-direction: column; - min-height: 85vh; + min-height: 65vh; overflow: hidden; background: var(--color-bg); } @@ -238,13 +238,13 @@ a { color: inherit; text-decoration: none; } align-items: center; justify-content: center; text-align: center; - padding: 20px 20px 32px; + padding: 16px 16px 24px; position: relative; z-index: 2; } .hero-logo { - margin-bottom: 16px; + margin-bottom: 12px; animation: float 6s ease-in-out infinite; } @@ -266,7 +266,7 @@ a { color: inherit; text-decoration: none; } -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; - margin-bottom: 8px; + margin-bottom: 4px; letter-spacing: -0.03em; } @@ -274,14 +274,14 @@ a { color: inherit; text-decoration: none; } font-size: clamp(1rem, 2.5vw, 1.3rem); color: var(--color-text-secondary); font-weight: 500; - margin-bottom: 12px; + margin-bottom: 8px; } .hero-description { font-size: 1rem; color: var(--color-text-muted); max-width: 620px; - margin-bottom: 20px; + margin-bottom: 16px; line-height: 1.6; } @@ -293,7 +293,7 @@ a { color: inherit; text-decoration: none; } grid-template-columns: repeat(4, auto); align-items: center; column-gap: 0; - margin-bottom: 24px; + margin-bottom: 16px; background: var(--color-bg-tertiary); border: 1px solid var(--color-border); border-radius: var(--radius-lg); @@ -337,7 +337,7 @@ a { color: inherit; text-decoration: none; } .hero-actions { display: flex; gap: 12px; - margin-bottom: 20px; + margin-bottom: 16px; flex-wrap: wrap; justify-content: center; } @@ -1179,7 +1179,7 @@ a { color: inherit; text-decoration: none; } } .hero { min-height: auto; } - .hero-content { padding: 16px 12px 32px; } + .hero-content { padding: 12px 12px 24px; } .hero-logo-svg { width: 64px; height: 64px; } .hero-title { font-size: 2.2rem; } .hero-subtitle { font-size: 1rem; } @@ -1190,7 +1190,7 @@ a { color: inherit; text-decoration: none; } gap: 12px; row-gap: 16px; width: 100%; - margin-bottom: 20px; + margin-bottom: 16px; } /* Hide dividers on mobile 2ร—2 grid */