import gradio as gr from PIL import Image from datetime import datetime from dateutil import relativedelta import os # Hardcoded wedding date WEDDING_DATE = "2025-11-25" # Create placeholder images for the gallery def create_placeholder_images(): """Create placeholder images for the gallery when local images aren't available""" placeholder_images = [] for i in range(4): # Create 4 placeholder images # Create a simple colored image with text img = Image.new('RGB', (300, 300), color=(255, 182, 193)) # Light pink background placeholder_images.append(img) return placeholder_images # Try to load local images, fallback to placeholders try: # Local image paths (replace these with your own) # image_paths = ["/Users/shubhamsetia/Downloads/WhatsApp Image 2025-03-31 at 21.57.39.jpeg", "/Users/shubhamsetia/Downloads/WhatsApp Image 2025-03-31 at 21.52.21.jpeg"] # images = [Image.open(img) for img in image_paths if os.path.exists(img)] # if not images: # If no local images found, use placeholders images = create_placeholder_images() except Exception as e: print(f"Error loading images: {e}") images = create_placeholder_images() def calculate_time_remaining(): """ Calculates time until WEDDING_DATE (YYYY-MM-DD). Returns a formatted "X years, Y months, Z days..." or "The Wedding Day Has Arrived!" if the date is in the past. """ try: wedding_date = datetime.strptime(WEDDING_DATE, "%Y-%m-%d") now = datetime.now() if now > wedding_date: return "The Wedding Day Has Arrived! 🎊" diff = relativedelta.relativedelta(wedding_date, now) return ( f"{diff.years} years, {diff.months} months, {diff.days} days, " f"{diff.hours} hours, {diff.minutes} minutes, {diff.seconds} seconds" ) except Exception as e: return f"Error calculating time remaining: {e}" # ------------------------------------------------------------------------------ # THEME: Pale Pink Background -> White Card Container -> Pink Title Headers # ------------------------------------------------------------------------------ custom_css = """ /* Entire Gradio background: pale pink */ .gradio-container { background-color: #FFE6EE !important; font-family: 'Trebuchet MS', sans-serif; color: #000000 !important; /* Default text black for strong contrast */ } /* Main "card" container: white background, black text */ .wedding-container { display: flex; flex-direction: column; align-items: center; padding: 30px; background-color: #FFFFFF; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); margin: 20px auto; max-width: 900px; } /* HEADERS with a darker pink background + white text */ .wedding-title { display: inline-block; /* Let us style the background behind the text */ background-color: #d13078; /* Bold pink */ color: #FFFFFF !important; /* White text */ padding: 10px 20px; border-radius: 10px; font-size: 36px; font-weight: bold; margin-bottom: 20px; text-align: center; text-shadow: none; } .gallery-header { display: inline-block; background-color: #d13078; color: #FFFFFF !important; padding: 8px 16px; border-radius: 8px; font-size: 24px; font-weight: bold; margin: 20px 0; text-align: center; text-shadow: none; } /* Countdown container: bold pink (#E91E63) with white text inside */ .countdown-container { background-color: #E91E63; border-radius: 15px; padding: 20px; margin-bottom: 30px; width: 100%; text-align: center; box-shadow: 0 5px 15px rgba(0,0,0,0.15); color: #FFFFFF !important; } /* Title inside countdown box */ .countdown-title { font-size: 28px; margin-bottom: 10px; font-weight: bold; color: #FFFFFF !important; } /* Subtitle includes the countdown text */ .countdown-subtitle { font-size: 20px; margin-bottom: 20px; color: #FFFFFF !important; } /* Wedding date text inside countdown box */ .countdown-date { font-size: 20px; color: #FFFFFF !important; margin-top: 10px; } /* Refresh button: darker pink with white text */ .refresh-button { background-color: #C2185B !important; color: #FFFFFF !important; border: none !important; padding: 10px 20px !important; border-radius: 8px !important; font-size: 16px !important; cursor: pointer !important; transition: background-color 0.3s ease !important; box-shadow: 0 3px 10px rgba(0,0,0,0.1) !important; margin-top: 10px !important; } .refresh-button:hover { background-color: #A0134D !important; } /* Floating hearts animation */ .floating-hearts { position: relative; height: 50px; margin: 10px 0; } @keyframes float { 0% { transform: translateY(0) rotate(0deg); opacity: 1; } 100% { transform: translateY(-60px) rotate(20deg); opacity: 0; } } .heart { position: absolute; font-size: 24px; animation: float 4s infinite; } /* Heartbeat effect on the celebration icon */ @keyframes heartbeat { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } } .heartbeat { animation: heartbeat 1.5s infinite ease-in-out; display: inline-block; } /* Gallery container: white background + subtle shadow */ .gr-gallery { background-color: #ffffff; border-radius: 10px; padding: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1); } """ with gr.Blocks(css=custom_css) as app: with gr.Column(elem_classes=["wedding-container"]): # Title with darker pink background + white text gr.Markdown("# Wedding Countdown Gallery", elem_classes=["wedding-title"]) # Floating hearts gr.HTML("""