The station, not the surf brand
The Swell Bureau avoids tropical escapism. Its concept is a working coastal forecasting room before sunrise: slate walls, paper charts, fluorescent buoy data, one warm strip at the horizon. The page moves from live instrument to dispatch, teaching diagram, tide desk, break dossiers, and finally a departure board. That sequence makes the visitor act like a forecaster before it asks them to act like a surfer.
A forecast you can feel
The signature sea is a dependency-free 2D canvas in main.js. The function waveSet() converts the four controls into a primary wave, two harmonics, and a variable set of short cross-waves. sampleWater() sums trochoidal, or Gerstner-style, displacement in all three axes: sine raises the surface while cosine pushes each sample along the travel direction. Period controls wavelength, height controls amplitude, direction rotates the wave vector, and chop adds short, scattered components.
project() applies a perspective camera to the displaced grid. Logarithmically spaced depth rows keep detail near the viewer without wasting hundreds of lines at the horizon. The yellow buoy samples the same water function. A damped spring follows the local height and the calculated slope adds lean, so it responds to the model rather than floating on a separate animation. updateModel() scores the settings and writes the operational call in plain surf language.
Pass 3 adds the crest-clock instrument. setCrestClock() opens a stripped-back temporal scope over the same live ocean; updateCrestClock() derives its countdown and travelling coral pulse directly from simulation time modulo the selected period. Seven seconds therefore feels impatient while nineteen leaves an uncanny stretch of empty water. The main animation stops when the document is hidden; reduced-motion mode keeps the scope readable as a still instrument.
01INPUTSheight · period · bearing · chop02waveSet()physical components03sampleWater()xyz displacement + slope04ONE TRUTHsea · buoy · language
Charts, tapes, and field marks
The supporting graphics are inline SVG and CSS. drawTapes() writes two wave paths that compare seven-second wind sea with fourteen-second groundswell. The tide desk uses one cubic Bézier curve, a translucent area fill, a now pin, and a coral reef-window bracket. Break diagrams reduce reef, point, and beach bathymetry to three layers: water, dashed bottom, and a coral breaking mark. Repeating 32-pixel rules turn the light sections into chart paper; restrained grain stops the large color fields from feeling digitally flat.
#2C3540
PRE-DAWN
#3E7D8C
SWELL
#EEF1EB
FOAM
#F2C84B
BUOY
#EF7B6C
SUNRISE
Sora carries compressed, tightly tracked headlines and clear operational copy. Chivo Mono handles coordinates, times, labels, inputs, and small measurements. The scale deliberately jumps from enormous display words to compact telemetry, with almost no middle-weight decoration.
Reproduce this
Give an AI agent a place, an instrument, and a physical relationship to teach. Ask for one genuine interaction whose parameters drive both the visual and the language. Require code-native graphics, local fonts, several distinct editorial section structures, responsive screenshots, and a written critique after visual inspection.
Build a dawn-patrol surf forecast station in pure HTML, CSS, and JavaScript. Use a perspective canvas mesh whose summed Gerstner waves respond visibly to swell height, period, direction, and chop. Make a buoy sample that exact surface. Pair the simulator with tide-chart editorial layouts, break-specific bathymetry diagrams, real forecast copy, and an interactive checklist. Use slate, teal, foam, yellow, and coral; Sora plus Chivo Mono; no external assets. Verify at phone, tablet, and desktop widths and refine from screenshots.