{story_emoji} {selected_story_title}
{scene_text}
Scene {current_scene_index + 1} of {total_scenes}
# app.py from flask import Flask, request, redirect, url_for, session, jsonify from datetime import datetime app = Flask(__name__) # IMPORTANT: Change this to a strong, random key for production! # You can generate one with: import os; os.urandom(24) app.secret_key = b'your_strong_secret_key_here_please_change_me' # --- Story Content (Updated with The Greening of Sector 12) --- stories = { "🏗 The Greening of Sector 12": { "emoji": "🏗", "scenes": [ "Anand Joshi, a retired civil engineer, had two calendars that governed his life in Sector 12. There was the official one on his wall, and then there was the water calendar, etched into his mind. From March until the monsoon, the municipal taps would hiss and run dry by 8 a.m. This was the season of the water tanker—its rumbling engine a sound of both relief and failure—and the metallic clang of empty buckets.", "Then came July. The monsoon would arrive not as a gentle relief, but as a deluge. The same concrete lanes that had shimmered with heat now became channels of churning brown water. The small park in the center of their sector would flood, drowning the new saplings the residents' association planted every year. It was the irony that gnawed at Mr. Joshi. For four months, they begged for water. For the next four, they cursed it for having nowhere to go.", "One sweltering afternoon in May, he watched his wife carefully portion out a single bucket of water for her prized hibiscus plants. That evening, he sat down with a notepad and a calculator. He measured his roof: 100 square meters. He looked up the average rainfall for his city: about 800 millimeters per year. The numbers that stared back at him were staggering. His own roof could potentially harvest nearly 80,000 liters of water annually—enough to see his family through the dry season with ease.", "His first project was his own home. He wasn't a young man anymore, but his hands still remembered their purpose. He spent a week installing PVC gutters along his eaves, routing them to a filtration system made of sand, gravel, and charcoal. He then connected this to his home's long-forgotten underground water sump. He also installed a simple T-junction with a valve—a 'first-flush' diverter.", "\"The first ten minutes of rain just washes the roof clean,\" he explained to his skeptical neighbor, Mrs. Verma, who was watching him from her balcony. \"We let that dirty water run off. Then, we turn the valve and collect the clean water that follows.\" The first monsoon shower that year was a quiet vindication. While the rest of the street's runoff turned into a muddy torrent, a steady, clear stream gurgled into Mr. Joshi's sump.", "The real test came the following April. The tankers were late, the municipal supply was cut to every other day, but the Joshi household had water. His garden was a defiant patch of green in a sector of brown, thirsty lawns. He washed his car with a bucket and hose, and Mrs. Joshi could water her hibiscus without rationing. That's when the questions started. Mrs. Verma was the first. \"Anand-ji, you have no water problems. What is your secret?\"", "Mr. Joshi didn't just tell her; he showed her. He opened the lid of his sump to reveal the clear water. He demonstrated the first-flush valve. He shared his calculations. Her main concern was practical. \"But the cost? And won't it become a breeding ground for mosquitoes?\" He had answers. He showed her how his system was fully sealed, preventing any mosquito access. He broke down the cost—a modest one-time investment that, he calculated, would pay for itself in three years by eliminating the need for expensive tanker water.", "His success became a local pilot project. He helped Mr. Singh next door, a bank manager who was good with spreadsheets and saw the clear financial benefit. Then, two younger families on the lane, tired of their children's school uniforms not being washed on time, pitched in to get their own systems installed. The real change came when they tackled the park.", "Mr. Joshi called a meeting of the Residents' Welfare Association. He didn't just talk about saving water; he talked about the flooding. He proposed digging two large recharge wells at the lowest point of the park—essentially deep pits filled with gravel and stone that would act like a sponge. \"Instead of letting the storm water flood our roads and overwhelm the city drains,\" he argued, holding up a simple hand-drawn diagram, \"we channel it into these wells. We send it back into the ground, where it belongs. We recharge our groundwater.\"", "This time, people listened. They pooled their resources. The project became a community effort. On weekends, residents came out to help, digging, carrying stones, and sharing tea and snacks. They weren't just building a water system; they were rebuilding a sense of neighborhood. The next monsoon was different. The rain fell with its usual intensity, but the park didn't turn into a lake. The water flowed through the newly laid channels and disappeared silently into the recharge wells. The roads were clear within an hour of the downpour.", "The most telling sign came a year later. The old community borewell, which had been running dry by February, now had water until late April. The water tankers became a rare sight in Sector 12. The children played in a park that was green and thriving. One evening, Mr. Joshi stood on his balcony, looking out at the neighborhood. He could hear the faint hum of a neighbor's water pump—a sound that was no longer a prelude to a sputtering, dry cough. It was the sound of a steady, reliable flow. He hadn't brought a river to Sector 12. He had simply shown his neighbors how to catch a cloud." ] }, "☁ The Rain Whisperer": { "emoji": "☁", "scenes": [ "Ravi liked to walk along the old riverbed at dawn when the world was still assembling itself. Once a river ran there — he had heard stories from his grandmother about frogs and fish and a willow that hummed in the wind. Now the river was a shallow ribbon of memory, and Ravi's shoes made soft, lonely sounds in the dust.", "One foggy morning, a single drop of rain fell from nowhere and made a tiny pool at his feet. It shimmered, and in the shimmer Ravi heard something like a voice, thin as static and kind as a lullaby. \"Send me back to the earth,\" it whispered. Ravi laughed, then listened again. The voice — a cloud's voice — urged him to find places where water could be welcomed instead of sent away.", "The cloud appeared at the edge of the sky, small and earnest, and it guided Ravi gently through choices. \"Not the paved plaza,\" it said; \"the garden, the bare patch, the pit.\" Together they walked the neighborhood, choosing places where rain could soak into the ground instead of racing to the drains.", "Ravi's first attempt was a simple recharge pit behind the community library. He dug with neighbors, layered sand and gravel, and planted grass around its rim. When the next rain came, they funneled roof runoff into the pit; the water disappeared into the soil like a secret returning home. A few weeks later the elderly well behind the temple had water again, enough for the old women to wash their sarees and for the children to play.", "The cloud taught Ravi about first-flush systems, too. \"The first flow carries what the roofs have collected — dust, leaves, bird droppings,\" it explained. They installed a small diversion so the first few liters bypassed the recharge pit and went straight to a drain, while the cleaner flow was channeled into the pit and the garden beds. It was not magic; it was attention.", "As the neighborhood's soil drank and softened, roots found new pockets to hold moisture. The willow by the school, once a mere stick, began to look hopeful again. Ravi realized that the voice he had heard was not only the cloud's: it was the earth telling him what it needed, and the work they did was listening.", "The cloud hung over the neighborhood less often as the wells rose and the trees greened, and when it drifted away for good, Ravi felt no sadness. The whisper remained in everyone's mouths like a recipe: leave space for water, let it sink, protect the first flush, and share what you catch. There was, he thought, a simple poetry to caring for the ground you stand on." ] }, "🌈 Little Cloud's Mission": { "emoji": "🌈", "scenes": [ "Little Cloud woke up on a Wednesday feeling very excited. \"Today is a collecting day!\" it bubbled, and rain had barely begun to fall when it floated down over Maya's roof.", "Maya, who was seven and loved stickers and jumping puddles, opened her window. \"Hello, Little Cloud!\" she shouted. Little Cloud bounced and shook, and drops fell like glitter into a shiny barrel Mr. Kumar had set under the gutter.", "\"Catch the clean drops, and don't forget the screen!\" sang Little Cloud. Maya peered at the top of the barrel where a fine mesh kept out leaves and sleepy beetles. Together they counted the drops that went into the barrel: one, two, three!", "Maya learned fast. She tapped the little valve at the bottom and watched a trickle of water come out into a mug. \"This is for the plants,\" said Little Cloud, puffing proudly. \"But first — the first drops that wash the roof are dirty. We let the first flush go away, and then we save the rest.\"", "They played a game: when Little Cloud shook, colorful drop-shapes fell. Green drops were clean and went in the barrel; red drops were yucky (oil, leaves) and had to be blocked with the screen. Maya clapped when she caught three green drops in a row.", "That afternoon Maya took a watering can to the potted basil and the marigolds. She watered carefully, saying, \"Thank you, Little Cloud,\" because she felt the water was a gift. Her mother promised to use the barrel water for cleaning the bicycle and the balcony floor, but not for drinking. Little Cloud beamed.", "At school the next day, Maya told her friends how to set up a barrel and explained the first-flush with a picture she drew: a painted roof, an arrow to a barrel, and a smiley plant. Her teacher made a chart of all the safe uses: watering plants, washing garden tools, cleaning the porch. Everyone got a sticker: \"Little Rain Helper.\"", "As the rains came and went, Maya and Little Cloud collected and saved many buckets. It was fun, and it made the neighborhood greener. Most important, Maya learned that a small, careful act — a barrel, a screen, remembering the first flush — could become a big, kind thing for the world." ] } } # --- Flask Routes --- @app.before_request def initialize_session_state(): """Initializes session variables for story navigation if they don't exist.""" if 'current_scene' not in session: session['current_scene'] = 0 if 'selected_story' not in session: session['selected_story'] = list(stories.keys())[0] # Default to the first story @app.route('/', methods=['GET', 'POST']) def index(): """Main route to display stories and handle navigation, with embedded HTML.""" # Handle story selection from the sidebar dropdown if request.method == 'POST' and 'select_story' in request.form: new_story_title = request.form['select_story'] if new_story_title in stories: session['selected_story'] = new_story_title session['current_scene'] = 0 # Reset scene when changing story return redirect(url_for('index')) # Redirect to GET request to show new story # Handle scene navigation (Next/Previous buttons) if request.method == 'POST' and ('navigate_prev' in request.form or 'navigate_next' in request.form): if 'navigate_prev' in request.form and session['current_scene'] > 0: session['current_scene'] -= 1 elif 'navigate_next' in request.form: current_story_scenes = stories[session['selected_story']]['scenes'] if session['current_scene'] < len(current_story_scenes) - 1: session['current_scene'] += 1 return redirect(url_for('index')) # Prepare data for rendering the template selected_story_title = session['selected_story'] current_scene_index = session['current_scene'] story_data = stories.get(selected_story_title, {}) scene_text = story_data['scenes'][current_scene_index] if story_data and 'scenes' else "Story content not found." total_scenes = len(story_data['scenes']) if story_data and 'scenes' else 1 progress_percentage = ((current_scene_index + 1) / total_scenes) * 100 story_emoji = story_data.get('emoji', '💧') # Generate options for the story selection dropdown story_options_html = "" for story_key, story_info in stories.items(): selected_attr = "selected" if story_key == selected_story_title else "" story_options_html += f"" # HTML structure embedded directly html_content = f"""
{scene_text}
Scene {current_scene_index + 1} of {total_scenes}