Pismo has 10 offices across 8 time zones. Pismo Zones tells you what time it is for the whole team, in under a second, at 137KB, with zero API calls. This is the anatomy of how it was built.
🇺🇸Austin
UTC-6DST
🇬🇧Bristol
UTC+0BST
🇮🇳Bangalore
SourceUTC+5:30
The Why
Ten offices. One question. Under a second.
Pismo ships code from São Paulo, Austin, Bristol, Bangalore, Singapore, Warsaw, Mexico City, Buenos Aires, Bogotá, and Sydney. Standups, deploys, incident bridges: they all start with the same question: “what time is it there?” Pismo Zones makes that question disappear. The whole thing runs in your browser tab, answers instantly, and forgets you were ever there.
10
Global Offices
São Paulo to Sydney. Each user picks their own set of cities, and the entire interface adapts: layout, gradients, meeting overlap scores.
0
External API Calls
Luxon bundles the IANA timezone database. Works offline, on airplane mode, behind Visa’s corporate firewall. Everything stays in your browser tab.
137KB
Total Bundle (gzip)
Three runtime dependencies: React, Framer Motion, Luxon. The rest is 4,300 lines of hand-written CSS and custom hooks.
8.5K
Lines of Source
11 components and 4 hooks spread across 19 files, held together by a single CSS file with 930+ custom properties. Every line answers one question.
70
Holidays Tracked
Covers five countries. Cards go dim on holidays and show “Outside Hours,” so nobody sends the 3am Slack asking why someone isn’t responding.
48
Meeting Slots Scored
Every 30-minute slot scored by overlap across all active cities. Finds the best meeting time in under 10ms, entirely in the browser.
Layer 1
The Sky is the Data
You don’t read the time to know it’s night in Austin. You see deep indigo. Nine RGB stops, hand-tuned to match real skies, interpolated across 1,440 minutes. When the gradient gets too bright for white text, a dark overlay fades in proportionally. The correction is continuous, scaling with brightness. Drag the slider and watch the math work.
12:00NOONoverlay: 0%
12:00
f(x)
Linear Interpolation in sRGB
Each RGB channel blended between stops. sRGB lerp desaturates midpoints slightly, which accidentally simulates atmospheric haze. A bug that became a feature.
Aa
WCAG Contrast Auto-Correction
When luminance exceeds 0.42, a dark overlay fades in up to 22%. Uses the actual sRGB-to-linear gamma formula. White text stays readable at every hour.
24h
Seamless 24-Hour Cycle
Hour 0 and hour 24 share identical RGB. Dawn and dusk get dedicated stops because those 20-minute transitions are what humans actually notice.
Layer 2
Why Does it Feel Like Glass?
Seven CSS layers, each contributing one physical property: a gradient base, a 50px blur, a warm sheen, a refractive border, a shimmer entrance, a day-boundary horizon, and a cursor spotlight. Remove any one and the card still holds. Stack all seven and it feels tangible. Click to pull them apart.
L1: Time-of-day gradient
L2: backdrop-filter blur(50px) saturate(180%)
L3: Static sheen (warm + cool radial)
L4: Gradient border (mask-composite)
L5: Shimmer reveal (one-shot sweep)
L6: Day boundary horizon
L7: Cursor-tracking spotlight
Click to collapse layers
Gradient (data = decoration)
Blur + Saturate (glass physics)
Static sheen (light source)
Gradient border (edge refraction)
Shimmer (entrance reveal)
Day sweep (semantic indicator)
Cursor sheen (interactive spotlight)
/* The critical glass recipe */
.card {
background: rgba(44, 44, 46, 0.35);
backdrop-filter: blur(50px) saturate(180%);
/* 50px blur: background becomes pure color wash */
/* 180% saturate: compensates for blur-induced desaturation */
/* Without saturate, glass looks like dirty plastic */
}
Layer 3
Why Does it Feel Alive Without Feeling Bouncy?
Two curves, used everywhere, never mixed. The ease-out decelerates like something with mass, and cards use it for every entrance. The spring overshoots by 56% before settling, like a door that bounces once, and badges use it for their pop. Scroll down and watch them side by side.
Premium Ease-Out
cubic-bezier(0.2, 0.8, 0.2, 1)
Reaches ~80% in the first ~20% of duration, then gently settles. The element arrives with mass.
Spring Overshoot
cubic-bezier(0.34, 1.56, 0.64, 1)
Overshoots target by ~56%, then settles. Creates elasticity and "pop." Used for badges.
Snap-Settle
cubic-bezier(0.25, 1, 0.5, 1)
Arrives almost instantly, microsettles. Used for toggle pills and dropdown snaps.
Linear (Anti-Pattern)
linear
Constant velocity. Feels mechanical. Only used for ambient particle drift where constant speed reads as natural.
Layer 4
How Do You Show Live Without Showing a Number?
The seconds tick at 42% opacity. Below WCAG readability. You can’t read “:42” but your peripheral vision catches the change. Your brain registers “this is live” without your eyes ever leaving the hours. Drag the slider. Find the exact point where “readable” becomes “felt.”
09:31:42
Seconds opacity: 42%
~3.5:1 contrast (below AA)
42% = felt more than read (liveness signal) 65% = tertiary text (readable but secondary) 85% = secondary text (clearly readable) 100% = primary text (demands attention)
Synthesis
15 principles. Steal all of them.
Each maps to a specific line of code. Any one of them makes an app “nice.” All fifteen together produce the feeling of encountering something built by someone who understands both the pixels and the people staring at them.
Responsive
The Same Soul. Entirely Different Bones.
Mobile is not a scaled-down desktop. The layout transforms completely: settings move to a top bar, actions drop to the thumb zone, panels become full-viewport modals, and backdrop-filter stacking is replaced with solid backgrounds for performance. The app feels native on both surfaces because it was designed for both from the start.
Pismo Zones
ENPT12h24h
🇧🇷São PauloUTC-3
OUTSIDE HOURS3
🇺🇸AustinUTC-5
11:02:52PM-1dFri, Apr 3
🇬🇧BristolUTC+1
05:02:52AMSat, Apr 4
🇮🇳BangaloreSOURCEUTC+5:30
09:32:52AMSat, Apr 4
Install app for quick accessInstall×
🇮🇳BangaloreSOURCE∨
Now
Apr 409:32 AM
TimeMeet
Top Settings Bar
Globe brand + segmented EN/PT, 12h/24h toggles, and theme icon. Glass backdrop. Always pinned. Desktop puts these in the InputBar — mobile promotes them because they change the entire view.
Cards: Full Fidelity
Every card shows flag, city name, UTC offset badge, large time, seconds, AM/PM period, date, and day-offset badge (-1d). The SOURCE badge marks the reference city. Gradients encode time-of-day. Same data density as desktop, different layout.
Two-Row Bottom Dock
Row 1: source selector (flag + city + chevron), Now button with live pulse dot, share button. Row 2: date/time pickers (native showPicker()), Time/Meet segmented toggle, holiday calendar. Everything reachable with one thumb.
Performance: No Stacked Blur
Desktop stacks 7 backdrop-filter layers per card. Mobile replaces them with solid rgba backgrounds. Same visual feel, 3x fewer compositing passes. Full-viewport modals replace dropdown panels.
PWA: Install on Any Device
Full Progressive Web App with manifest, service worker, and offline support. On iOS, the install banner detects standalone mode and walks users through Add to Home Screen. On Android and desktop, the native beforeinstallprompt event triggers the install flow directly. Once installed, it runs in its own window with no browser chrome. Offline fallback serves a branded page when the network drops.
Social
42 Characters. Every City. Every Minute.
A share URL encodes source city, exact time, date, and every selected destination into 8 to 10 base36 characters. Path-based URLs (/s/abc123) instead of hash fragments, because social crawlers ignore fragments. An edge function serves dynamic OG meta for crawlers and meta-refresh redirects humans to the SPA.
Hash
Click cities to build a hash
Generated URL
pismozones.app/s/---
Binary Breakdown
Source-1 char
Time-3 chars
Date-3 chars
Cities-1-2 chars
b36
Base36 Encoding
source(1) + time(3) + date(3) + cities bitfield(1-2) = 8-10 chars total. Compact enough for any messaging platform, readable in URLs, no special characters to escape.
/s/
Path-Based URLs
Social crawlers (Twitter, Slack, iMessage) ignore hash fragments. Path-based /s/abc123 routes are visible to every crawler. Edge functions serve the right OG tags before the SPA loads.
OG
Dynamic OG Images
@vercel/og generates preview images on the edge showing the source city, shared time, gradient colors matching the time of day, and all destination cities. Every share link gets a unique card.
Trust
What You Can’t Do Matters More.
The strongest security property is structural impossibility. Zero external API calls means zero attack surface for data exfiltration. All decoded values come from a static CITIES array, never from user input. There is nothing to steal, nothing to inject, nothing to track.
Pismo Zones was built entirely through conversations with Claude Opus 4.6, starting from a blank file. Every gradient stop was tuned in dialogue. Every animation curve was tested against real human perception, rejected twice, and then accepted once. The AI wrote the code. The human held the bar and decided when “good enough” wasn’t. Taste was the bottleneck. Speed was never the constraint. That’s the only way AI-assisted craft produces something worth showing.