← Back to web work
Web Development · Case Study

VisitSPI
South Padre Island

A student tourism website rebuilt to production standards — every animation preserved, every structural flaw fixed.

8Pages
10Animations
5CSS bugs fixed
0Charm lost

Overview

A student project done with real care — and what that meant for the rebuild.

VisitSPI is a personal tourism guide to South Padre Island, Texas, built as a semester capstone for an Internet Studio course. The original site had something most student web projects don't: genuine personality. A hand-coded animated wave intro. A bouncing beach ball that was, as the designer's own statement explains, "a complete accident that I chose to then utilize." A sidebar on the dining page labeled "Wyatt's favorite dish." Personal vacation photos with captions like "celebrating my birthday at Coco's — that's a mango smoothie and I was turning 27."

That voice is rare. It's also fragile — the kind of thing that gets accidentally sanded off during a technical revision. The rebuild challenge was to apply production-level standards across HTML semantics, accessibility, SEO, form handling, and CSS correctness while leaving the site's soul completely intact.

"The ball and the bird movement were a complete accident that I chose to then utilize."

The result is a site that passes the same technical audits applied to a professional medical practice website — and still has a beach ball bouncing across the screen.


The Original

What was there — and why it worked despite the bugs.

The original VisitSPI site was a single-stylesheet, seven-page static build. It used five self-hosted fonts (Boldonse, Berkshire Swash, Changa One, Amiko, Biryani) and a 498-line CSS file to create something that looked genuinely distinctive: a teal-and-coral palette inspired by the coastal waters and sunsets of South Padre Island, a logo that dropped in from above on page load, and a fixed animated background of palm tree tiles that scrolled perpetually sideways.

The site had a clear aesthetic point of view. The Boldonse logo text was bold and italic and gold-on-navy. The nav buttons were coral pills with seafoam borders. The page content sat in a centered card with a teal box-shadow that made it feel like it was floating above the animated background. Every design choice had a reason behind it, documented in a dedicated Design Statement page that explained the color palette, typography decisions, and animation philosophy in the designer's own words.

The palette

#006D77
#83C5BE
#EDF6F9
#E29578
#FFDDD2
#FFD166
#004E89
#102A31

All nine original colors were retained without modification. The palette was already correct.

What the original did well

Strong, committed aesthetic direction — teal, coral, seafoam, and sand applied consistently throughout
Distinctive font stack: Boldonse for the logo, Berkshire Swash for headings, Changa One for H1 banners, Amiko for body — all self-hosted in woff2 format
Animated wave intro that plays once on load, followed by perpetual ambient animation — a genuinely sophisticated choreography
Personal voice throughout — "Wyatt's favorite dish" sidebar cards, captions on personal photos, honest recommendations
lang="en" on every page and responsive viewport meta tag present
Design Statement page documenting every design decision — unusual and valuable for a student project

What was broken

!Three CSS animation bugs. The bottleFly, planeFly, and birdFly keyframes used transform: translate X(0) — a space inside the function name that browsers ignore entirely. Those three elements were never animating. The animations the designer described in the Design Statement weren't running.
!Missing pixel units. The #wave and #wave2 elements had bottom: -170 and bottom: -190 with no unit. CSS interprets unitless positional values as zero — the waves were starting from the wrong position on every page load.
!Invalid font-weight. The H1 declaration used font-weight: strong. The word "strong" is an HTML element, not a CSS keyword. The browser fell back to the default font weight.
!Forms with no labels. Every form field on contact.html and booknow.html used an H3 heading above the input instead of a <label for="">. There was no programmatic connection between the label text and the input. Screen readers couldn't associate them. Clicking the label text didn't focus the field.
!Absolute image paths. Every image was referenced as /images/filename.jpg — a path that only resolves when served from a web server root. The site couldn't be previewed by opening HTML files directly in a browser.
!Multiple H1s per page. The Activities page had three H1 elements — Nightlife, Fishing, and Beaches — each styled as a section header. A page should have one H1 as its primary topic declaration.
!No skip links, no ARIA landmarks. No mechanism for keyboard or screen reader users to skip the navigation on any page. No <main>, <header>, or <nav> landmarks. The decorative animation divs were announced to screen readers as empty elements.
!No meta descriptions or OG tags. Zero pages had a meta description. Any link shared to social media would display nothing. Search engine result snippets would be generated from whatever text the crawler happened to find first.
!No transition on nav hover. The nav links had transform: translateY(-2px) on hover, but no transition property — the movement snapped instantly rather than animating.

The Rebuild

Production standards applied without touching the personality.

The rebuild philosophy was simple: fix what's broken, add what's missing, leave everything else alone. Every animation element, every font, every color, every "Wyatt's favorite dish" card is in the final build. The test for every change was whether a visitor looking at the two versions side-by-side could tell the difference. For most of the improvements, they couldn't.

8
Pages (added Thank You)
10
Keyframe animations
636
Lines of CSS
8
Skip links (all pages)
7
Active nav indicators
12
Proper form labels

The animation fixes

Three keyframe animations were silently broken by a space inside the CSS function name. The fix was removing the space. The animations now run exactly as the designer intended and described — the bottle spins as it flies across the screen, the plane flies straight, the bird rotates as it moves. The wave positioning was corrected from unitless to -170px and -190px.

Before — silently broken
@keyframes bottleFly { from { transform: translate X(0) rotate(0deg); } }
After — works correctly
@keyframes bottleFly { from { transform: translateX(0) rotate(0deg); } }

Form labels — the right way

Every form field was given a proper <label for="id"> element paired with a matching id attribute on the input. Phone fields now use type="tel" (which gives mobile users the numeric keyboard) and email fields use type="email" (which enables browser validation and the correct mobile keyboard). The forms were connected to Netlify's form handling with data-netlify="true" and a honeypot spam field, making them actually functional on deployment. A Thank You page was added as the form success destination so users get confirmation rather than a blank page.

Before — no association
<h3>Email Address?</h3> <p> <input type="text" name="guest-email" placeholder="Enter email"> </p>
After — properly paired
<label for="guest-email"> Email Address </label> <input type="email" id="guest-email" name="guest-email" autocomplete="email" required>

Semantic structure

The logo and nav were wrapped in a <header> element. Page content moved into <main id="main-content">. The navigation became a proper <nav aria-label="Main navigation"> with a <ul> of items. Each page marks its own nav link with aria-current="page", which changes the button to ocean blue with gold text — a visible active state that didn't exist in the original. Every decorative animation element received aria-hidden="true" so screen readers don't announce empty divs flying across the page.

What was added without changing the look

+Skip-to-main-content link on every page — invisible until focused, then appears in the top-left corner using the teal brand color
+Meta description on every page, written specifically for each page's content and purpose
+Open Graph tags on every page so link previews on social media show the page title and description
+CSS custom properties for the full nine-color palette — every color in one place, one edit to change anything
+transition on all interactive elements — the nav hover now animates smoothly instead of snapping
+prefers-reduced-motion media query — the animations stop for users who have requested reduced motion in their OS accessibility settings
+netlify.toml with X-Frame-Options DENY, X-Content-Type-Options nosniff, and Referrer-Policy headers
+robots.txt and sitemap.xml covering all seven content pages
+Phone numbers converted to tel: links — tapping them on mobile now opens the dialer
+All external links in Works Cited have rel="noopener noreferrer"
+Photo gallery rebuilt as a semantic CSS Grid with figure/figcaption instead of a stack of img + h2
+Fun facts styled with CSS counters — coral numbered circles without a numbered list in HTML
+Mobile breakpoint at 600px — sidebar floats collapse to full-width, font sizes scale, nav wraps gracefully

Preservation

Everything that makes this site itself.

The hardest part of a rebuild like this is knowing what not to touch. The following elements were preserved exactly as they were in the original:

All ten animation elements — wave intro, second wave, palm tile background, beach girls rising and sinking, umbrella flying offscreen, bottle spinning across the page, plane flying through, bird flapping in reverse, beach ball bouncing, logo dropping in from above
All five self-hosted fonts — Boldonse, Berkshire Swash, Changa One, Amiko, Biryani
All nine colors of the original palette, unchanged to the hex digit
"Wyatt's favorite dish" sidebar cards on the dining page — Happy Eggs Benedict and a milkshake, chicken tenders and a Turbo, black paella and a crab roll
All personal photos on the gallery page and every caption written by Wyatt, including the birthday smoothie at Coco's and the fish caught with his dad
The Design Statement page in full — every word of the color palette explanation, typography rationale, and animation philosophy, plus the complete 32-item Works Cited list
The voice — casual, confident, first-person, specific. "My favorite way to end the night is a pitcher at The Coral Reef listening to some karaoke."

Takeaways

What this project illustrates about the gap between working and correct.

The original VisitSPI site looked right. In a browser, at a normal zoom level, on a laptop, with no assistive technology, it appeared to work. The animations played — three of the ten were silently not playing, but you'd have to know what to look for to notice. The forms appeared submittable — they posted to #, meaning they did nothing. The wave positioning was slightly off — but only a pixel-precise comparison would reveal it.

This is the most common category of web development problem: things that appear to work but don't. The bottle was supposed to spin as it flew across the screen. It didn't. The form was supposed to send a message. It didn't. The nav hover was supposed to ease smoothly. It snapped. None of these are visible in a screenshot. All of them are visible in experience.

Production standards aren't about making things look different. They're about making things work the way they appear to work.

The accessibility improvements follow the same logic. A form label looks like a heading next to an input. It behaves like a label — but only if the browser knows they're connected. Without the for/id pairing, a screen reader user hears "text input" with no context, and clicking the label text does nothing. The fix is invisible to sighted users and essential to everyone else.

The broader lesson is that personality and correctness aren't in tension. The beach ball can bounce across the screen and still have aria-hidden="true". The "Wyatt's favorite dish" sidebar can stay exactly where it is and still be inside a properly structured content flow. The wave animation can play exactly as designed — in fact, more exactly, now that the keyframe bug is fixed. The charm of this site was never in the broken parts. It was in the choices: the fonts, the colors, the animations, the voice. Those are all still there.

VISITSPI — SOUTH PADRE ISLAND STUDENT PROJECT · WEB DEVELOPMENT CASE STUDY