Build an Animated Storytelling Website

Build a scroll-animated mythology website and deploy it live on Vercel.

Introduction

30 Second Summary

You know those websites where the page transforms as you scroll? Text fades in, colors shift, and elements animate into view like a movie unfolding. These scroll-driven storytelling experiences are everywhere, from product launches to interactive articles.

In this project, you will build one from scratch. You will create an immersive, scroll-animated website that tells the story of Lord Shiva's Tandava (cosmic dance) from the Linga Purana, and deploy it live on the internet.

What You'll Build

A single-page storytelling website with scroll-driven animations built using HTML, CSS, JavaScript, and GSAP ScrollTrigger, deployed live on Vercel.

By the end of this project, you'll have:

  • A live website with scroll-driven animations including text reveals, pinned scenes, and background color transitions.
  • A video-ready hero section structured for future anime story content, using the standard HTML5 video element.
  • An authentic retelling of Shiva's Tandava from the Linga Purana (Chapter 106) with proper source attribution and a CSS Nataraja silhouette.
  • Secret Mission: Add a parallax cosmic background with animated stars and a glowing damaru drum that pulses with the scroll.

Do I need coding experience?

No prior web development experience is needed. This guide walks you through every line of code from the very beginning. You just need a computer with VS Code installed and a free GitHub account.

Build the Story Structure

Your project folder is ready with three empty files waiting to be filled. Every website starts with HTML. It defines the structure and content of your page.

In this step, you will build the full skeleton of your storytelling page. This includes a cinematic video area at the top, five story sections narrating the Tandava from the Linga Purana, and a source attribution footer.

In this step, get ready to:
  • Set up the HTML document head with GSAP and ScrollTrigger loaded from a CDN.
  • Create a video hero section with a "Coming Soon" overlay.
  • Write five story sections and a source attribution footer.
Set up the document head and page wrapper

The document head tells the browser how to render your page. It also loads external resources like your stylesheet and animation libraries.

  • In VS Code, click on index.html in the Explorer sidebar to open it.
  • Paste the following code at the top of the file to create the document head and opening body structure:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shiva's Tandava - The Cosmic Dance</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="page-wrapper">

    </div>

    <script src="https://cdn.jsdelivr.net/npm/gsap@3.15/dist/gsap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.15/dist/ScrollTrigger.min.js"></script>
    <script src="script.js"></script>
</body>
</html>

What does this code do?

  • The <head> sets the page title, links your stylesheet (style.css), and makes the page responsive on mobile devices.
  • The page-wrapper div wraps all visible content. You will add story sections inside it.
  • The two <script> tags at the bottom load GSAP and its ScrollTrigger plugin from a CDN (a public server that hosts libraries). The last script tag loads your own script.js file where you will write animations later.

Why load GSAP from a CDN instead of installing it?

Loading GSAP via CDN script tags means you do not need npm, build tools, or module bundlers. You add two <script> tags and the library is immediately available in your page.

  • Save index.html by pressing Cmd+S (macOS) or Ctrl+S (Windows).

You will not see anything in the browser yet. The page is empty between the wrapper tags. You will fill it in the next two chunks.

Create the video hero section

The top of your page features a cinematic video area. This section is designed to hold an anime story video in the future. For now, it displays a beautiful "Coming Soon" overlay with a play icon.

  • In index.html, place your cursor on the empty line inside the <div class="page-wrapper"> tags.
  • Paste the following code to create the video hero section:
        <section class="video-hero" id="video-section">
            <div class="video-container">
                <video id="story-video" poster="" playsinline controls preload="none">
                    <!-- Video source will be added when anime video is produced -->
                    <!-- <source src="tandava-story.mp4" type="video/mp4"> -->
                </video>
                <div class="video-overlay">
                    <h2 class="video-title">The Tandava</h2>
                    <p class="video-subtitle">Anime story video coming soon</p>
                    <div class="play-placeholder">
                        <svg viewBox="0 0 80 80" class="play-icon">
                            <circle cx="40" cy="40" r="38" fill="none" stroke="#d4a843" stroke-width="2"/>
                            <polygon points="32,24 60,40 32,56" fill="#d4a843"/>
                        </svg>
                    </div>
                </div>
            </div>
        </section>

What does this code do?

  • The <video> element uses standard HTML5 attributes: controls adds play/pause buttons, playsinline prevents fullscreen on mobile, and preload="none" avoids loading a video that does not exist yet.
  • The <source> tag is commented out. When you produce your anime video later, you uncomment it and add your file.
  • The video-overlay div sits on top of the video area, showing the title and a gold SVG play icon as a placeholder.
  • Save index.html.
  • Right-click on index.html in the Explorer sidebar and select Open with Live Server (or double-click the file in Finder/File Explorer to open it in a browser).
  • You should see the text "The Tandava" and "Anime story video coming soon" on a white background with no styling. This is expected because style.css is still empty.

See a completely blank page?

  • Make sure you pasted the video hero code inside the <div class="page-wrapper"> tags, not outside them.
  • Check for any red squiggly lines in VS Code indicating syntax errors (a missing closing tag or quote).

Why is my page showing a blank screen after adding the video hero section?

Build the story sections and footer

The core of your page is a scroll-driven reading experience. Each story section fills the full viewport and reveals a chapter from Linga Purana Chapter 106.

  • In index.html, place your cursor directly after the closing </section> tag of the video-hero section.
  • Paste the following code to create the introduction hero section:
        <section class="story-section hero-section" id="intro">
            <div class="section-content">
                <h1 class="main-title">The Tandava</h1>
                <p class="subtitle">The Cosmic Dance of Lord Shiva</p>
                <p class="source-tag">From the Linga Purana, Chapter 106</p>
                <div class="scroll-hint">Scroll to begin the story</div>
            </div>
        </section>

What does this code do?

This is the title screen the reader sees before scrolling. It displays the story name, a subtitle, the source reference (Linga Purana, Chapter 106), and a hint telling visitors to scroll. The hero-section class will center everything on screen when you add CSS later.

  • Directly below the intro section, paste the three narrative chapters of the story:
        <section class="story-section" id="affliction">
            <div class="section-content">
                <h2 class="section-heading">The Affliction of the Devas</h2>
                <p class="story-text">Daruka, born in the family of Asuras, attained great power through his penance. Like the fire at the end of a yuga, he tormented the Devas and brahmins alike.</p>
                <p class="story-text">The Devas, extremely afflicted and hurt by Daruka, sought refuge in Brahma, Vishnu, Yama, and Indra. But knowing the Asura could be slain only by a woman, even the gods disguised as women could not defeat him.</p>
                <p class="story-text">Accompanied by Brahma, they approached the lord of Uma. Bowing in diverse ways, Brahma spoke: "O lord, the demon Daruka is terrible. It behoves you to protect us by killing Daruka who is destined to be killed by a lady."</p>
            </div>
        </section>

        <section class="story-section" id="intervention">
            <div class="section-content">
                <h2 class="section-heading">The Divine Intervention</h2>
                <p class="story-text">On hearing Brahma's submission, the lord said laughingly to Parvati, the daughter of the mountain-lord: "O splendid lady, I request you for the welfare of the worlds to slay Daruka."</p>
                <p class="story-text">The goddess entered the body of the lord of Devas. From the poison in Shiva's neck, Parvati made her own body. On coming to know of this, Shiva created Kali, the blue-necked goddess with matted hair, from his third eye.</p>
                <p class="story-text">On seeing Kali who resembled fire, taking her origin, the Devas and Siddhas, including Vishnu, Brahma, and Indra, fled in fright.</p>
            </div>
        </section>

        <section class="story-section" id="victory">
            <div class="section-content">
                <h2 class="section-heading">The Victory</h2>
                <p class="story-text">At the behest of Parvati, the great goddess slew the demon Daruka who had attacked and killed the chiefs among Devas.</p>
                <p class="story-text">By virtue of her impetuosity and the fire of anger, the entire universe became agitated. Shiva, assuming the form of a boy through his power of Maya, stationed himself in the cremation ground and cried.</p>
                <p class="story-text">The goddess, deluded by his Maya, took the boy, kissed him, and suckled him at her breasts. Along with her breast-milk, the boy quaffed her wrath also, and her excessive anger was ceased.</p>
            </div>
        </section>

What does this code do?

These three sections tell the middle of the story. Each follows the same pattern: a section-heading for the chapter title and multiple story-text paragraphs for the narrative.

  • The Affliction: the demon Daruka terrorizes the Devas, and they beg Shiva for help.
  • The Divine Intervention: Parvati enters Shiva's body, and Kali is born from his third eye.
  • The Victory: Kali slays Daruka, and Shiva calms her wrath.
  • Finally, below the victory section, paste the Tandava climax section and the footer:
        <section class="story-section tandava-section" id="tandava">
            <div class="section-content">
                <h2 class="section-heading">The Tandava</h2>
                <p class="story-text">In order to propitiate her, the delighted trident-bearing lord of Devas performed the Tandava dance at dusk, along with the ghosts and leaders of goblins.</p>
                <p class="story-text">After quaffing the nectar-like dance of Shiva, Parameshvari danced in the midst of ghosts, happily along with Yoginis.</p>
                <p class="story-text">Devas all round, including Brahma, Indra, and Vishnu, bowed to and eulogised Kali and then prayed to the goddess Parvati.</p>
                <div class="nataraja-container">
                    <div class="fire-ring"></div>
                    <div class="nataraja-silhouette"></div>
                </div>
            </div>
        </section>

        <footer class="story-footer">
            <p class="attribution">Story source: <a href="https://www.wisdomlib.org/hinduism/book/the-linga-purana/d/doc1196086.html" target="_blank" rel="noopener">Linga Purana, Chapter 106</a> - English translation by J. L. Shastri</p>
            <p class="note">Others are of the opinion that the Tandava of the lord is due to the Bliss of yoga.</p>
        </footer>

What does this code do?

  • The tandava-section is the story climax. It contains the narrative text plus a nataraja-container div. This is where a CSS silhouette of the Nataraja (Shiva dancing) will appear, surrounded by a golden fire ring. Both are empty divs that CSS and JavaScript will bring to life.
  • The <footer> credits the source: Linga Purana, Chapter 106, English translation by J. L. Shastri. The closing note is a direct reference from the text about sages who believe the Tandava arises from the Bliss of yoga.
  • Save index.html and refresh your browser.
  • You should see all your story text displayed on the page. It looks like plain unstyled text on a white background. You can read through the full narrative from "The Tandava" heading down to the footer attribution.

Missing some sections?

  • Make sure all sections are placed inside the <div class="page-wrapper"> and before its closing </div> tag.
  • Check that every opening <section> tag has a matching </section>. A missing closing tag can hide everything below it.
  • Scroll all the way down in the browser. The page is long because you have five full-height sections.

Help me figure out why some of my HTML sections are not showing up in the browser.

✔️ Awesome, I've got everything!

Great. Double check you have saved index.html and can see all the story text in your browser.

ⓧ I'd like to double check the full code

Here is the complete index.html file. Make sure yours matches this exactly:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shiva's Tandava - The Cosmic Dance</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="page-wrapper">

        <section class="video-hero" id="video-section">
            <div class="video-container">
                <video id="story-video" poster="" playsinline controls preload="none">
                    <!-- Video source will be added when anime video is produced -->
                    <!-- <source src="tandava-story.mp4" type="video/mp4"> -->
                </video>
                <div class="video-overlay">
                    <h2 class="video-title">The Tandava</h2>
                    <p class="video-subtitle">Anime story video coming soon</p>
                    <div class="play-placeholder">
                        <svg viewBox="0 0 80 80" class="play-icon">
                            <circle cx="40" cy="40" r="38" fill="none" stroke="#d4a843" stroke-width="2"/>
                            <polygon points="32,24 60,40 32,56" fill="#d4a843"/>
                        </svg>
                    </div>
                </div>
            </div>
        </section>

        <section class="story-section hero-section" id="intro">
            <div class="section-content">
                <h1 class="main-title">The Tandava</h1>
                <p class="subtitle">The Cosmic Dance of Lord Shiva</p>
                <p class="source-tag">From the Linga Purana, Chapter 106</p>
                <div class="scroll-hint">Scroll to begin the story</div>
            </div>
        </section>

        <section class="story-section" id="affliction">
            <div class="section-content">
                <h2 class="section-heading">The Affliction of the Devas</h2>
                <p class="story-text">Daruka, born in the family of Asuras, attained great power through his penance. Like the fire at the end of a yuga, he tormented the Devas and brahmins alike.</p>
                <p class="story-text">The Devas, extremely afflicted and hurt by Daruka, sought refuge in Brahma, Vishnu, Yama, and Indra. But knowing the Asura could be slain only by a woman, even the gods disguised as women could not defeat him.</p>
                <p class="story-text">Accompanied by Brahma, they approached the lord of Uma. Bowing in diverse ways, Brahma spoke: "O lord, the demon Daruka is terrible. It behoves you to protect us by killing Daruka who is destined to be killed by a lady."</p>
            </div>
        </section>

        <section class="story-section" id="intervention">
            <div class="section-content">
                <h2 class="section-heading">The Divine Intervention</h2>
                <p class="story-text">On hearing Brahma's submission, the lord said laughingly to Parvati, the daughter of the mountain-lord: "O splendid lady, I request you for the welfare of the worlds to slay Daruka."</p>
                <p class="story-text">The goddess entered the body of the lord of Devas. From the poison in Shiva's neck, Parvati made her own body. On coming to know of this, Shiva created Kali, the blue-necked goddess with matted hair, from his third eye.</p>
                <p class="story-text">On seeing Kali who resembled fire, taking her origin, the Devas and Siddhas, including Vishnu, Brahma, and Indra, fled in fright.</p>
            </div>
        </section>

        <section class="story-section" id="victory">
            <div class="section-content">
                <h2 class="section-heading">The Victory</h2>
                <p class="story-text">At the behest of Parvati, the great goddess slew the demon Daruka who had attacked and killed the chiefs among Devas.</p>
                <p class="story-text">By virtue of her impetuosity and the fire of anger, the entire universe became agitated. Shiva, assuming the form of a boy through his power of Maya, stationed himself in the cremation ground and cried.</p>
                <p class="story-text">The goddess, deluded by his Maya, took the boy, kissed him, and suckled him at her breasts. Along with her breast-milk, the boy quaffed her wrath also, and her excessive anger was ceased.</p>
            </div>
        </section>

        <section class="story-section tandava-section" id="tandava">
            <div class="section-content">
                <h2 class="section-heading">The Tandava</h2>
                <p class="story-text">In order to propitiate her, the delighted trident-bearing lord of Devas performed the Tandava dance at dusk, along with the ghosts and leaders of goblins.</p>
                <p class="story-text">After quaffing the nectar-like dance of Shiva, Parameshvari danced in the midst of ghosts, happily along with Yoginis.</p>
                <p class="story-text">Devas all round, including Brahma, Indra, and Vishnu, bowed to and eulogised Kali and then prayed to the goddess Parvati.</p>
                <div class="nataraja-container">
                    <div class="fire-ring"></div>
                    <div class="nataraja-silhouette"></div>
                </div>
            </div>
        </section>

        <footer class="story-footer">
            <p class="attribution">Story source: <a href="https://www.wisdomlib.org/hinduism/book/the-linga-purana/d/doc1196086.html" target="_blank" rel="noopener">Linga Purana, Chapter 106</a> - English translation by J. L. Shastri</p>
            <p class="note">Others are of the opinion that the Tandava of the lord is due to the Bliss of yoga.</p>
        </footer>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/gsap@3.15/dist/gsap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.15/dist/ScrollTrigger.min.js"></script>
    <script src="script.js"></script>
</body>
</html>

Your HTML structure is complete. Right now it looks like a plain text document, but the bones are all in place. Next up, you will transform this page with divine-themed CSS styling that brings deep blues, gold, and saffron gradients to life.

Style the Divine Aesthetics

Your HTML structure is complete. You have a video hero section, five story sections, and a footer all ready to be transformed visually.

Right now, all that content renders as plain black-and-white text on a white background. In this step, you will write the CSS that creates a dark cosmic atmosphere with gold and saffron accents inspired by traditional depictions of Shiva's cosmic dance.

In this step, get ready to:
  • Set up base styles with a cosmic dark background, video hero layout, and full-screen story sections.
  • Style text elements with gold headings, readable body text, and background color transitions between sections.
  • Create the Nataraja silhouette and fire ring using pure CSS shapes and gradients.
Set up the base styles and video hero layout

Every element on the page needs a shared visual foundation. The base styles reset browser defaults, set the dark cosmic background, and establish the serif font that gives the story a classical feel.

  • In VS Code, open style.css from the shiva-tandava folder.
  • Add the base styles, video hero layout, and story section layout by pasting this code:
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: Georgia, 'Times New Roman', serif;
    background-color: #0a0a1a;
    color: #f0e6d3;
    overflow-x: hidden;
    line-height: 1.8;
}

.page-wrapper {
    position: relative;
}

/* Video hero - letterboxed cinematic container */
.video-hero {
    width: 100%;
    background-color: #000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
}

.video-container {
    position: relative;
    width: 100%;
    max-width: 900px;
    aspect-ratio: 16 / 9;
    background: linear-gradient(135deg, #0a0a1a 0%, #1a1040 50%, #0a0a1a 100%);
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid #2a2a4a;
    box-shadow: 0 0 40px rgba(212, 168, 67, 0.1);
}

.video-container video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: none;
}

/* Overlay shown until a real video source is added */
.video-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 20px;
}

.video-title {
    font-size: 2.5rem;
    color: #d4a843;
    letter-spacing: 3px;
    text-transform: uppercase;
    margin-bottom: 8px;
}

.video-subtitle {
    font-size: 1rem;
    color: #8a7a5a;
    margin-bottom: 30px;
    font-style: italic;
}

.play-placeholder {
    cursor: pointer;
    transition: transform 0.3s ease;
}

.play-placeholder:hover {
    transform: scale(1.1);
}

.play-icon {
    width: 80px;
    height: 80px;
    opacity: 0.7;
}

.play-icon:hover {
    opacity: 1;
}

/* Each story section fills the full viewport height */
.story-section {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 60px 20px;
    position: relative;
}

.section-content {
    max-width: 700px;
    width: 100%;
}

.hero-section {
    text-align: center;
    background: linear-gradient(180deg, #0a0a1a 0%, #1a1040 100%);
}

What does this code do?

The universal selector * resets all margins, padding, and switches to border-box sizing so elements behave predictably.

The body uses a deep navy background (#0a0a1a) with warm cream text (#f0e6d3) and the Georgia serif font for a classical feel. The video container is locked to a 16:9 aspect ratio with a maximum width of 900px, creating a cinematic letterboxed look.

Each .story-section fills the full viewport height so the reader sees one chapter at a time while scrolling.

  • Save style.css.
  • Open index.html in your browser (right-click the file in VS Code's Explorer sidebar and select Open with Live Server, or double-click the file in Finder/File Explorer).
  • You should see a dark page with the video container showing a gold-bordered play icon centered inside a dark gradient box at the top.

Still seeing a plain white page?

  • Confirm that style.css is in the same folder as index.html. The <link> tag in your HTML looks for the file in the same directory.
  • Check you saved the file. Unsaved changes in VS Code show a white dot on the file tab.
  • Hard-refresh your browser with Cmd+Shift+R (macOS) or Ctrl+Shift+R (Windows) to clear the cache.

Help me debug why my CSS isn't loading on the page.

Style the text elements and section backgrounds

The story needs dramatic gold headings, readable body text, and color-coded backgrounds that shift emotion as the reader scrolls from one chapter to the next.

  • In style.css, add the following code below the .hero-section block:
/* Title and hero text */
.main-title {
    font-size: 4rem;
    color: #d4a843;
    margin-bottom: 16px;
    letter-spacing: 4px;
    text-transform: uppercase;
}

.subtitle {
    font-size: 1.4rem;
    color: #c9a84c;
    margin-bottom: 24px;
    font-style: italic;
}

.source-tag {
    font-size: 0.9rem;
    color: #8a7a5a;
    margin-bottom: 60px;
}

/* Pulsing scroll hint to guide the reader */
.scroll-hint {
    font-size: 0.85rem;
    color: #5a5a7a;
    animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

/* Story section headings with gold border accent */
.section-heading {
    font-size: 2.2rem;
    color: #d4a843;
    margin-bottom: 32px;
    position: relative;
    padding-left: 20px;
    border-left: 3px solid #d4a843;
}

/* Story body text - warm white for readability */
.story-text {
    font-size: 1.1rem;
    margin-bottom: 24px;
    color: #e8dcc8;
    line-height: 2;
}

/* Extra height for the Tandava section (pinned animation needs space) */
.tandava-section {
    min-height: 150vh;
    flex-direction: column;
}

/* Each section shifts background color to match its mood */
#affliction {
    background: linear-gradient(180deg, #1a1040 0%, #2a1030 100%);
}

#intervention {
    background: linear-gradient(180deg, #2a1030 0%, #3a0a20 100%);
}

#victory {
    background: linear-gradient(180deg, #3a0a20 0%, #2a1a10 100%);
}

#tandava {
    background: linear-gradient(180deg, #2a1a10 0%, #1a1000 50%, #0a0a1a 100%);
}

/* Footer attribution */
.story-footer {
    text-align: center;
    padding: 60px 20px;
    background-color: #0a0a1a;
    border-top: 1px solid #2a2a3a;
}

.attribution {
    font-size: 0.9rem;
    color: #8a7a5a;
    margin-bottom: 12px;
}

.attribution a {
    color: #c9a84c;
    text-decoration: underline;
}

.attribution a:hover {
    color: #d4a843;
}

.note {
    font-size: 0.85rem;
    color: #5a5a6a;
    font-style: italic;
}

What does this code do?

The .main-title is sized at 4rem in gold (#d4a843) with wide letter-spacing for a dramatic, divine presence. The .section-heading uses a gold left border as a glowing accent that draws the eye to each chapter title.

The @keyframes pulse animation fades the scroll hint in and out to subtly guide readers downward. Each story section has its own background gradient shifting from deep purple through crimson to gold, tracking the emotional arc of the narrative.

  • Save style.css and refresh your browser.
  • You should see a large gold title reading "The Tandava" on a dark gradient background, with a pulsing "Scroll to begin the story" hint below it. Scrolling down reveals gold headings with a left border accent, cream-colored body text, and backgrounds that shift from purple to red to gold.

Text not showing in gold?

  • Make sure you pasted the new code below the closing brace of .hero-section, not inside it. Each CSS rule block needs its own set of curly braces.
  • Check that the class names match exactly. For example, .section-heading in CSS must match class="section-heading" in HTML.

Help me figure out why my CSS text styles aren't being applied.

Create the Nataraja silhouette and responsive styles

The Nataraja (Lord of Dance) is traditionally depicted inside a prabhamandala, a ring of cosmic fire. You will create this iconic image using pure CSS shapes. Both elements start invisible (opacity 0) because GSAP will animate them into view during the scroll.

What is prabhamandala?

In traditional Nataraja iconography, the prabhamandala is the circular ring of fire surrounding Shiva as he dances. It represents the cycle of creation and destruction. The CSS .fire-ring element recreates this using a golden circular border with glowing box-shadows.

  • In style.css, add this final section of code below the .note rule:
/* Nataraja container - holds the fire ring and silhouette */
.nataraja-container {
    position: relative;
    width: 300px;
    height: 300px;
    margin: 60px auto 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Prabhamandala - the cosmic ring of fire */
.fire-ring {
    position: absolute;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    border: 4px solid #d4a843;
    box-shadow: 0 0 30px #d4a843, 0 0 60px #b8860b, inset 0 0 30px rgba(212, 168, 67, 0.2);
    opacity: 0;
}

/* Shiva silhouette created with clip-path */
.nataraja-silhouette {
    width: 150px;
    height: 200px;
    background: radial-gradient(ellipse at center, #d4a843 0%, #8b6914 50%, transparent 70%);
    clip-path: polygon(50% 0%, 30% 25%, 10% 20%, 25% 45%, 15% 70%, 35% 60%, 50% 100%, 65% 60%, 85% 70%, 75% 45%, 90% 20%, 70% 25%);
    opacity: 0;
    filter: drop-shadow(0 0 20px #d4a843);
}

/* Responsive adjustments for mobile */
@media (max-width: 768px) {
    .main-title {
        font-size: 2.5rem;
    }

    .section-heading {
        font-size: 1.6rem;
    }

    .story-text {
        font-size: 1rem;
    }

    .video-title {
        font-size: 1.6rem;
    }

    .nataraja-container {
        width: 200px;
        height: 200px;
    }

    .fire-ring {
        width: 200px;
        height: 200px;
    }

    .nataraja-silhouette {
        width: 100px;
        height: 140px;
    }
}

What does this code do?

The .fire-ring is a 300px circle with a gold border and layered box-shadows that simulate a glowing ring of fire. The .nataraja-silhouette uses clip-path: polygon() to cut a multi-pointed dance figure shape from a gold radial gradient.

Both elements have opacity: 0 so they are invisible on page load. In the next step, GSAP ScrollTrigger will animate them into view as the reader reaches the Tandava section. The media query shrinks everything proportionally on screens under 768px.

  • Save style.css and refresh your browser.
  • Scroll down to the Tandava section. You will not see the Nataraja or fire ring yet (they start invisible). Confirm that the section headings, story text, and color gradients all display correctly throughout the page.

Seeing broken layout or overlapping elements?

  • Count your closing curly braces. Every opening { needs a matching }. A missing brace causes all rules below it to break.
  • Make sure the @media block is at the very end of your file. Rules after the media query closing brace would be treated as top-level styles.

Help me debug my broken CSS layout for the Nataraja section.

✔️ Awesome, I've got everything!

Great. Double check you have saved style.css before moving on.

ⓧ I'd like to double check the full code

Here is the complete style.css file at this point:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: Georgia, 'Times New Roman', serif;
    background-color: #0a0a1a;
    color: #f0e6d3;
    overflow-x: hidden;
    line-height: 1.8;
}

.page-wrapper {
    position: relative;
}

.video-hero {
    width: 100%;
    background-color: #000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
}

.video-container {
    position: relative;
    width: 100%;
    max-width: 900px;
    aspect-ratio: 16 / 9;
    background: linear-gradient(135deg, #0a0a1a 0%, #1a1040 50%, #0a0a1a 100%);
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid #2a2a4a;
    box-shadow: 0 0 40px rgba(212, 168, 67, 0.1);
}

.video-container video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: none;
}

.video-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 20px;
}

.video-title {
    font-size: 2.5rem;
    color: #d4a843;
    letter-spacing: 3px;
    text-transform: uppercase;
    margin-bottom: 8px;
}

.video-subtitle {
    font-size: 1rem;
    color: #8a7a5a;
    margin-bottom: 30px;
    font-style: italic;
}

.play-placeholder {
    cursor: pointer;
    transition: transform 0.3s ease;
}

.play-placeholder:hover {
    transform: scale(1.1);
}

.play-icon {
    width: 80px;
    height: 80px;
    opacity: 0.7;
}

.play-icon:hover {
    opacity: 1;
}

.story-section {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 60px 20px;
    position: relative;
}

.section-content {
    max-width: 700px;
    width: 100%;
}

.hero-section {
    text-align: center;
    background: linear-gradient(180deg, #0a0a1a 0%, #1a1040 100%);
}

.main-title {
    font-size: 4rem;
    color: #d4a843;
    margin-bottom: 16px;
    letter-spacing: 4px;
    text-transform: uppercase;
}

.subtitle {
    font-size: 1.4rem;
    color: #c9a84c;
    margin-bottom: 24px;
    font-style: italic;
}

.source-tag {
    font-size: 0.9rem;
    color: #8a7a5a;
    margin-bottom: 60px;
}

.scroll-hint {
    font-size: 0.85rem;
    color: #5a5a7a;
    animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

.section-heading {
    font-size: 2.2rem;
    color: #d4a843;
    margin-bottom: 32px;
    position: relative;
    padding-left: 20px;
    border-left: 3px solid #d4a843;
}

.story-text {
    font-size: 1.1rem;
    margin-bottom: 24px;
    color: #e8dcc8;
    line-height: 2;
}

.tandava-section {
    min-height: 150vh;
    flex-direction: column;
}

.nataraja-container {
    position: relative;
    width: 300px;
    height: 300px;
    margin: 60px auto 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fire-ring {
    position: absolute;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    border: 4px solid #d4a843;
    box-shadow: 0 0 30px #d4a843, 0 0 60px #b8860b, inset 0 0 30px rgba(212, 168, 67, 0.2);
    opacity: 0;
}

.nataraja-silhouette {
    width: 150px;
    height: 200px;
    background: radial-gradient(ellipse at center, #d4a843 0%, #8b6914 50%, transparent 70%);
    clip-path: polygon(50% 0%, 30% 25%, 10% 20%, 25% 45%, 15% 70%, 35% 60%, 50% 100%, 65% 60%, 85% 70%, 75% 45%, 90% 20%, 70% 25%);
    opacity: 0;
    filter: drop-shadow(0 0 20px #d4a843);
}

#affliction {
    background: linear-gradient(180deg, #1a1040 0%, #2a1030 100%);
}

#intervention {
    background: linear-gradient(180deg, #2a1030 0%, #3a0a20 100%);
}

#victory {
    background: linear-gradient(180deg, #3a0a20 0%, #2a1a10 100%);
}

#tandava {
    background: linear-gradient(180deg, #2a1a10 0%, #1a1000 50%, #0a0a1a 100%);
}

.story-footer {
    text-align: center;
    padding: 60px 20px;
    background-color: #0a0a1a;
    border-top: 1px solid #2a2a3a;
}

.attribution {
    font-size: 0.9rem;
    color: #8a7a5a;
    margin-bottom: 12px;
}

.attribution a {
    color: #c9a84c;
    text-decoration: underline;
}

.attribution a:hover {
    color: #d4a843;
}

.note {
    font-size: 0.85rem;
    color: #5a5a6a;
    font-style: italic;
}

@media (max-width: 768px) {
    .main-title {
        font-size: 2.5rem;
    }

    .section-heading {
        font-size: 1.6rem;
    }

    .story-text {
        font-size: 1rem;
    }

    .video-title {
        font-size: 1.6rem;
    }

    .nataraja-container {
        width: 200px;
        height: 200px;
    }

    .fire-ring {
        width: 200px;
        height: 200px;
    }

    .nataraja-silhouette {
        width: 100px;
        height: 140px;
    }
}

Your page now has a complete visual identity. The cosmic dark background, golden type, and color-shifting sections create an immersive atmosphere. Next up, you will bring this page to life with scroll-driven animations using GSAP ScrollTrigger.

Animate with GSAP ScrollTrigger

Your HTML structure and CSS styles are in place, but the page is completely static right now. Every heading, paragraph, and silhouette just sits there waiting.

GSAP ScrollTrigger transforms a static page into an immersive reading experience by tying animations directly to the user's scroll position. In this step, you'll bring the story to life with scroll-driven reveals, a pinned Nataraja scene, and dramatic entrance animations.

In this step, get ready to:
  • Register GSAP ScrollTrigger and create scroll-triggered text reveals.
  • Build a pinned timeline for the Nataraja scene with rotation and glow effects.
  • Add entrance animations for the hero section and wire up the video player.
Register ScrollTrigger and create reveal animations

ScrollTrigger is a GSAP plugin that watches the user's scroll position and fires animations when elements enter the viewport. You need to register it before using any scroll-based features.

  • Switch back to script.js in VS Code.
  • Register the ScrollTrigger plugin and create the heading reveal animations by pasting this code:
gsap.registerPlugin(ScrollTrigger);

// Animate each section heading as the user scrolls to it
document.querySelectorAll(".section-heading").forEach(function(heading) {
    gsap.from(heading, {
        y: 60,
        opacity: 0,
        duration: 1,
        ease: "power3.out",
        scrollTrigger: {
            trigger: heading,
            start: "top 80%",
            toggleActions: "play none none reverse"
        }
    });
});

What does this code do?

gsap.registerPlugin(ScrollTrigger) activates the plugin so GSAP can respond to scroll events.

gsap.from() animates FROM the values you specify back to the element's natural CSS state. Each heading starts 60px below and invisible, then slides up and fades in.

start: "top 80%" means the animation fires when the top of the heading reaches 80% down the viewport. toggleActions: "play none none reverse" reverses the animation when you scroll back up.

  • Now add the story paragraph reveals directly below the code you just pasted:
// Animate each story paragraph with a staggered delay
document.querySelectorAll(".story-text").forEach(function(text, index) {
    gsap.from(text, {
        y: 40,
        opacity: 0,
        duration: 0.8,
        delay: index * 0.1,
        ease: "power2.out",
        scrollTrigger: {
            trigger: text,
            start: "top 85%",
            toggleActions: "play none none reverse"
        }
    });
});

What does the delay do?

delay: index * 0.1 creates a staggered waterfall effect. The first paragraph in each section has no delay, the second waits 0.1 seconds, and the third waits 0.2 seconds. This makes the text feel like it's cascading in rather than appearing all at once.

  • Save script.js.
  • Open index.html in your browser by right-clicking the file in VS Code's Explorer sidebar and selecting Open with Live Server (if you have the extension) or by double-clicking the file in Finder/File Explorer.
  • Scroll down through the page. You should see each gold heading slide up and fade in as it enters view, followed by each story paragraph cascading in below it.

Text not animating on scroll?

  • Check that you saved script.js and refreshed the browser.
  • Open DevTools (press F12) and check the Console tab for red errors. A typo in the class name will cause a silent failure.
  • Confirm that your index.html loads the GSAP scripts before script.js. The three <script> tags must appear in order at the bottom of the <body>.

Help me debug why my GSAP scroll animations aren't playing.

Add the pinned Tandava scene

The Tandava section is the story's climax. Instead of scrolling past it like every other section, you'll pin it in place while the Nataraja silhouette and fire ring animate into view, controlled entirely by scroll progress.

  • In script.js, add the pinned timeline below your existing code:
// Pin the Tandava section and animate the Nataraja scene on scroll
var tandavaTimeline = gsap.timeline({
    scrollTrigger: {
        trigger: "#tandava",
        start: "top top",
        end: "+=800",
        scrub: 1,
        pin: true
    }
});

tandavaTimeline
    .to(".fire-ring", {
        opacity: 1,
        scale: 1.1,
        rotation: 360,
        duration: 2,
        ease: "none"
    })
    .to(".nataraja-silhouette", {
        opacity: 1,
        scale: 1.2,
        duration: 1.5,
        ease: "power2.out"
    }, "-=1.5")
    .to(".fire-ring", {
        boxShadow: "0 0 60px #d4a843, 0 0 120px #b8860b, inset 0 0 60px rgba(212, 168, 67, 0.4)",
        duration: 1
    });

What does this timeline do?

pin: true locks the Tandava section in place while the user scrolls through 800 pixels of scroll distance (end: "+=800"). scrub: 1 ties the animation progress directly to scroll position with a 1-second smoothing effect.

The timeline chains three animations: the fire ring fades in and completes a full 360-degree rotation, the Nataraja silhouette scales up (overlapping the ring animation by 1.5 seconds thanks to "-=1.5"), and the fire ring's glow intensifies with an enhanced box-shadow.

Why scrub instead of a normal animation?

A normal animation plays once at a fixed speed. With scrub, the user controls the pace. Scroll slowly and the ring rotates slowly. Scroll fast and it spins quickly. This creates an interactive feeling where the reader drives the cosmic dance forward.

  • Save script.js and refresh your browser.
  • Scroll all the way down to the Tandava section. The section should freeze in place, and as you continue scrolling, the golden fire ring should rotate into view while the Nataraja silhouette scales up inside it.

Tandava section not pinning?

  • Make sure the trigger selector is "#tandava" (with the hash). This matches the id="tandava" on your section element in the HTML.
  • If the ring appears but does not rotate, check that rotation: 360 has no quotes around the number.
  • If nothing appears at all, verify that your CSS has opacity: 0 on both .fire-ring and .nataraja-silhouette. GSAP animates TO opacity 1, so the starting state must be 0.

Help me debug my pinned GSAP ScrollTrigger timeline.

Add entrance animations and the video handler

The color progression from deep navy through purple, red, and gold is already built into your CSS gradients on each section. Now you'll add entrance animations for the hero section elements that play immediately on page load, plus a click handler that will play the video when one is added in the future.

  • In script.js, add the hero entrance animations below your tandavaTimeline code:
// Hero section entrance animations (play on page load)
gsap.from(".main-title", {
    scale: 0.8,
    opacity: 0,
    duration: 1.5,
    ease: "power4.out"
});

gsap.from(".subtitle", {
    y: 30,
    opacity: 0,
    duration: 1,
    delay: 0.5,
    ease: "power2.out"
});

gsap.from(".source-tag", {
    opacity: 0,
    duration: 1,
    delay: 1,
    ease: "power2.out"
});

gsap.from(".video-container", {
    scale: 0.95,
    opacity: 0,
    duration: 1.2,
    ease: "power3.out"
});

What does this code do?

These four animations have no scrollTrigger property, so they fire immediately when the page loads. The title scales up from 80% size, the subtitle slides up after a half-second delay, the source tag fades in after 1 second, and the video container gently scales in.

The staggered delays create a cinematic "opening credits" sequence that draws the reader in before they start scrolling.

  • Now add the video click handler at the bottom of script.js:
// Video overlay click handler (activates when a video source is added)
var videoOverlay = document.querySelector(".video-overlay");
var storyVideo = document.getElementById("story-video");

if (videoOverlay) {
    videoOverlay.addEventListener("click", function() {
        if (storyVideo.querySelector("source")) {
            videoOverlay.style.display = "none";
            storyVideo.style.display = "block";
            storyVideo.play();
            storyVideo.requestFullscreen();
        }
    });
}

Why check for a source element?

The if (storyVideo.querySelector("source")) check prevents the click handler from doing anything while the video source is commented out. When you produce your anime video in the future, you'll uncomment the <source> tag in your HTML and this handler will automatically work.

  • Save script.js and refresh your browser.
  • Watch the top of the page. The title "The Tandava" should scale in, followed by the subtitle sliding up, then the source tag fading in. The video container at the very top should gently scale into view.

Hero text appearing without animation?

  • These animations play once on page load. If you scroll down first and then scroll back up, you won't see them again. Refresh the page to replay them.
  • If the text never animates at all, check the Console for errors. A missing comma or quotation mark in the animation config will silently break all code below it.

Help me figure out why my GSAP entrance animations are not playing on page load.

✔️ Awesome, I've got everything!

Great. Double check you've saved script.js and your full scroll experience is working.

ⓧ I'd like to double check the full code

Here is the complete script.js file for comparison:

gsap.registerPlugin(ScrollTrigger);

document.querySelectorAll(".section-heading").forEach(function(heading) {
    gsap.from(heading, {
        y: 60,
        opacity: 0,
        duration: 1,
        ease: "power3.out",
        scrollTrigger: {
            trigger: heading,
            start: "top 80%",
            toggleActions: "play none none reverse"
        }
    });
});

document.querySelectorAll(".story-text").forEach(function(text, index) {
    gsap.from(text, {
        y: 40,
        opacity: 0,
        duration: 0.8,
        delay: index * 0.1,
        ease: "power2.out",
        scrollTrigger: {
            trigger: text,
            start: "top 85%",
            toggleActions: "play none none reverse"
        }
    });
});

gsap.from(".main-title", {
    scale: 0.8,
    opacity: 0,
    duration: 1.5,
    ease: "power4.out"
});

gsap.from(".subtitle", {
    y: 30,
    opacity: 0,
    duration: 1,
    delay: 0.5,
    ease: "power2.out"
});

gsap.from(".source-tag", {
    opacity: 0,
    duration: 1,
    delay: 1,
    ease: "power2.out"
});

gsap.from(".video-container", {
    scale: 0.95,
    opacity: 0,
    duration: 1.2,
    ease: "power3.out"
});

var tandavaTimeline = gsap.timeline({
    scrollTrigger: {
        trigger: "#tandava",
        start: "top top",
        end: "+=800",
        scrub: 1,
        pin: true
    }
});

tandavaTimeline
    .to(".fire-ring", {
        opacity: 1,
        scale: 1.1,
        rotation: 360,
        duration: 2,
        ease: "none"
    })
    .to(".nataraja-silhouette", {
        opacity: 1,
        scale: 1.2,
        duration: 1.5,
        ease: "power2.out"
    }, "-=1.5")
    .to(".fire-ring", {
        boxShadow: "0 0 60px #d4a843, 0 0 120px #b8860b, inset 0 0 60px rgba(212, 168, 67, 0.4)",
        duration: 1
    });

var videoOverlay = document.querySelector(".video-overlay");
var storyVideo = document.getElementById("story-video");

if (videoOverlay) {
    videoOverlay.addEventListener("click", function() {
        if (storyVideo.querySelector("source")) {
            videoOverlay.style.display = "none";
            storyVideo.style.display = "block";
            storyVideo.play();
            storyVideo.requestFullscreen();
        }
    });
}

Your storytelling page is now fully alive. Scroll reveals draw readers through the narrative, the pinned Tandava scene creates a dramatic climax, and the entrance sequence sets a cinematic tone. Next up, you'll deploy this to the web so anyone can experience it.

Deploy to Vercel

Your scroll-animated story is fully built and working locally. The HTML tells the narrative, the CSS paints it in divine golds and cosmic darks, and the JavaScript makes it dance as visitors scroll.

Now you will push your files to GitHub and deploy a live website on Vercel. Once deployed, anyone with the URL can experience the Tandava on their phone or computer.

In this step, get ready to:
  • Push your project files to GitHub.
  • Deploy your site on Vercel from the GitHub repository.
  • Verify the live site works on desktop and mobile.
Push your files to GitHub

Your GitHub repository from earlier needs the latest versions of all three files. There are two ways to get them there.

VS Code terminal

If you cloned the repository to your machine in Step 1, you can push directly from the terminal inside VS Code.

  • Open the integrated terminal in VS Code by pressing Ctrl+` (macOS and Windows).
  • Stage, commit, and push all your files by running these commands:
git add .
git commit -m "Add Shiva Tandava storytelling website"
git push origin main

What do these commands do?

  • git add . stages every file in the folder for the next commit.
  • git commit -m "..." saves a snapshot of your files with a description.
  • git push origin main uploads that snapshot to your GitHub repository on the main branch.
  • Confirm the push succeeded by checking your terminal output. You should see a message that includes the branch name main and a summary of files sent.

Push rejected or authentication error?

  • If Git asks for authentication, follow the prompts to sign in with your GitHub credentials or personal access token.
  • If you see a "rejected" error, run git pull origin main --rebase first (to pull the README), then try git push origin main again.
  • Make sure you are inside the shiva-tandava folder when running git commands.

Still stuck? Help me push my code to GitHub

GitHub web upload

If you did not clone the repository, you can upload files directly through github.com.

  • Open your browser and go to your shiva-tandava repository on github.com.
  • Click Add file near the top right, then select Upload files.
  • Drag your three files (index.html, style.css, script.js) from your shiva-tandava folder into the upload area.
  • Scroll down and click Commit changes.
  • Confirm you can see all three files listed in the repository alongside the README.md.

Don't see Add file?

Make sure you are signed in to the GitHub account that owns the repository. The Add file button only appears for repository owners.

Having trouble? Help me upload files to my GitHub repository

Import and deploy on Vercel

Vercel connects to your GitHub repository and automatically deploys your site every time you push new code. Since this project is plain HTML, CSS, and JavaScript with no build step, you will tell Vercel to skip building and serve your files directly.

  • Open your browser and go to vercel.com/new.
  • Under Import Git Repository, find your shiva-tandava repository and click Import.
  • On the configuration page, set the Framework Preset dropdown to Other.
  • Enable the Override toggle next to Build Command.
  • Leave the Build Command field empty. This tells Vercel there is nothing to build.
  • Click Deploy.

Why skip the build step?

Build tools like Webpack or Vite compile code before serving it. Your project uses plain HTML, CSS, and JavaScript files that browsers can read directly. Telling Vercel to skip the build step means it serves your files exactly as they are.

Vercel takes about 30 seconds to deploy. You will see a progress screen with a checkmark when it finishes.

Don't see your repository in the list?

  • Make sure you pushed your files to GitHub first (the previous substep).
  • Check that you signed in to Vercel with the same GitHub account that owns the repository.
  • If Vercel only shows some of your repos, click Adjust GitHub App Permissions at the bottom of the repository list and grant access to the shiva-tandava repository.

Need more help? Help me connect my GitHub repository to Vercel

Verify your live site

Once deployment completes, Vercel gives you a live URL ending in .vercel.app. This is your public website that anyone on the internet can visit.

  • Click the URL that Vercel shows you (it looks like shiva-tandava.vercel.app or similar).
  • Scroll through the entire story on your computer. Confirm the text fades in, background colors shift between sections, and the Nataraja scene pins in place while the fire ring and silhouette animate.
  • Open the same URL on your phone. Check that all text is readable, the video hero section displays at the top, and scroll animations still trigger.

What about future updates?

Every time you push new code to your main branch on GitHub, Vercel automatically picks it up and redeploys. No need to repeat the import process.

Site looks broken or animations don't play?

  • Open your browser's developer tools (F12 or Cmd+Option+I on macOS) and check the Console tab for red error messages. A typo in a filename or path causes a 404 for that resource.
  • Verify that style.css and script.js are in the same directory as index.html in your GitHub repository (not inside a subfolder).
  • If the page is completely blank, check that your Build Command override is enabled and the field is empty. A non-empty build command on a project without a package.json will fail silently.

Still stuck? Help me debug my Vercel deployment

Secret mission

Cosmic Parallax Background

Your story page looks incredible, but the background behind the text is static. Real cosmic scenes have depth. In this extension, you'll add a multi-layered starfield that drifts at different speeds as the user scrolls, plus Shiva's damaru drum that pulses with divine rhythm during the Tandava.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on free services. Your Vercel deployment stays live on the free Hobby plan at no cost, and your GitHub repository is free. There are no ongoing charges to worry about.

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • A Vercel deployment (free Hobby plan, no cost).
  • A GitHub repository (free).
  • A local shiva-tandava folder on your Desktop.

Keep everything running

No action needed. Choose this if you want your site to stay live and you plan to add more stories or produce the anime video in the future.

  • Your site stays live on Vercel indefinitely on the free Hobby plan.
  • Your GitHub repository remains available for future pushes, which automatically redeploy to Vercel.
  • Your local shiva-tandava folder stays on your Desktop for editing.

Pause - I'll come back to this later

Static sites on Vercel's free tier cost nothing whether they are live or not. There is nothing to pause.

  • Your Vercel deployment remains live at no cost. No pause action is needed.
  • Your GitHub repository stays available for free. No pause action is needed.
  • If you want to free up Desktop space, you can move the shiva-tandava folder to another location. Your work is safely backed up on GitHub.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow each step below to fully clean up.

Delete the Vercel project:

  • Open your Vercel dashboard and select the shiva-tandava project.
  • Click Settings in the sidebar.
  • Scroll to the bottom of the General page and click Delete in the Delete Project section.
  • Enter the project name to confirm, then click Continue.

Delete the GitHub repository:

  • On GitHub, navigate to your shiva-tandava repository.
  • Click Settings.
  • Scroll down to the Danger Zone section and click Delete this repository.
  • Click I want to delete this repository.
  • Click I have read and understand these effects.
  • Type the repository name to confirm, then click Delete this repository.

Delete local files (macOS/Linux):

cd ~/Desktop
rm -rf shiva-tandava

On Windows, run this in PowerShell instead:

cd ~\Desktop
Remove-Item -Recurse -Force shiva-tandava

That's a Wrap!

That's a Wrap!

Nice work! You just built and deployed a fully animated storytelling website that brings the Linga Purana's account of Shiva's Tandava to life through scroll-driven animations.

You've learned how to:

  • Build a complete HTML/CSS/JavaScript website from scratch with semantic sections, divine-themed styling, and a video-ready hero area.
  • Use GSAP ScrollTrigger to create professional scroll-driven animations including text reveals, pinned timelines, a rotating fire ring, and background color transitions.
  • Deploy a live website to Vercel connected to GitHub for automatic redeployments on every push.
  • Secret Mission: Added a multi-layer parallax starfield and an animated damaru drum SVG that pulses with scroll depth for cosmic parallax.

Ready to quiz yourself?