Staub Real Estate

Buying, Selling, Investing. Welcome to the Treasure Valley

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ada County Real Estate Market: October 2025</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap" rel="stylesheet">
    <style>
        body { font-family: 'Lato', sans-serif; background-color: #f4f7f7; margin:0; }
        .chart-container { position: relative; width: 100%; max-width: 600px; margin: 0 auto; height: 300px; max-height: 400px; }
        @media (min-width: 768px) { .chart-container { height: 350px; } }
        .stat-card { background-color: white; border-radius: 0.75rem; padding: 1.5rem; text-align: center; box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); }
        .stat-number { font-size: 3rem; font-weight: 900; color: #5F909C; line-height: 1; }
        .stat-label { margin-top: 0.5rem; color: #4A5568; font-weight: 700; }
        .gemini-button { background-color: #5F909C; color: white; padding: 0.75rem 1.5rem; border-radius: 0.5rem; font-weight: 700; transition: background-color 0.3s; }
        .gemini-button:hover { background-color: #4A7A85; }
        .gemini-button:disabled { background-color: #99C3C3; cursor: not-allowed; }
        .gemini-output { background-color: #f4f7f7; border-left: 4px solid #5F909C; padding: 1rem; margin-top: 1rem; min-height: 100px; border-radius: 0.25rem; }
        .loader { border: 4px solid #D2E7E7; border-top: 4px solid #5F909C; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 20px auto; }
        @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
    </style>
</head>
<body>

    <header class="bg-[#5F909C] text-white text-center py-12 px-4">
        <h1 class="text-4xl md:text-5xl font-bold">Ada County Real Estate Market</h1>
        <p class="text-xl mt-2 text-[#D2E7E7]">An October 2025 Snapshot</p>
    </header>

    <main class="container mx-auto p-4 md:p-8">
        <!-- Market Overview -->
        <section class="mb-12 text-center">
            <h2 class="text-3xl font-bold text-[#5F909C] mb-2">The Big Picture: A Resilient Market</h2>
            <p class="text-lg text-gray-600 max-w-3xl mx-auto mb-8">The Ada County housing market remains resilient, showing modest price gains and a quicker sales pace as we enter the fall season. Despite higher borrowing costs, buyer demand is keeping pace with supply.</p>
            <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
                <div class="stat-card"><div class="stat-number">$558K</div><div class="stat-label">Median Sale Price</div></div>
                <div class="stat-card"><div class="stat-number">26</div><div class="stat-label">Average Days on Market</div></div>
                <div class="stat-card"><div class="stat-number">2.9</div><div class="stat-label">Months of Inventory</div></div>
            </div>
        </section>

        <!-- AI Insights -->
        <section class="mb-12 bg-white p-6 rounded-lg shadow-md text-center">
            <h2 class="text-3xl font-bold text-[#5F909C] mb-4">✨ AI Market Insights</h2>
            <p class="text-lg text-gray-600 max-w-3xl mx-auto mb-6">Get a personalized summary of what the current market data means for you, powered by the Gemini API.</p>
            <div class="flex justify-center gap-4 mb-4">
                <button id="buyerSummaryBtn" class="gemini-button">Generate Buyer Summary</button>
                <button id="sellerSummaryBtn" class="gemini-button">Generate Seller Summary</button>
            </div>
            <div id="summaryOutput" class="gemini-output"><p class="text-gray-500">Your AI-generated summary will appear here...</p></div>
        </section>

        <!-- Charts Example -->
        <section class="mb-12 grid grid-cols-1 md:grid-cols-2 gap-8">
            <div class="bg-white p-6 rounded-lg shadow-md">
                <h3 class="text-xl font-bold text-center mb-4 text-[#5F909C]">Sale Price vs. List Price</h3>
                <div class="chart-container h-64"><canvas id="salesRatioChart"></canvas></div>
            </div>
            <div class="bg-white p-6 rounded-lg shadow-md">
                <h3 class="text-xl font-bold text-center mb-4 text-[#5F909C]">Median Home Prices</h3>
                <div class="chart-container h-64"><canvas id="valueChart"></canvas></div>
            </div>
        </section>

    </main>

    <footer class="text-center py-6 bg-[#5F909C] text-[#D2E7E7]">
        <p>Data sourced from market reports as of October 2025.</p>
    </footer>

    <!-- Charts JS -->
    <script>
        const tealPalette = ['#5F909C', '#7CAAAA', '#99C3C3', '#B5DDDD', '#D2E7E7'];
        const tooltipTitleCallback = (tooltipItems) => tooltipItems[0].chart.data.labels[tooltipItems[0].dataIndex];
        const defaultChartOptions = { responsive:true, maintainAspectRatio:false, plugins:{legend:{position:'top'}, tooltip:{callbacks:{title: tooltipTitleCallback}}} };
        new Chart(document.getElementById('salesRatioChart'), { type:'doughnut', data:{ labels:['Sold Below List Price','Sold At/Above List Price'], datasets:[{ data:[80,20], backgroundColor:[tealPalette[2],tealPalette[0]], borderColor:'#fff', borderWidth:2 }] }, options:{ ...defaultChartOptions, plugins:{legend:{position:'bottom'}} } });
        new Chart(document.getElementById('valueChart'), { type:'bar', data:{ labels:['Boise','Salt Lake City','Portland','Seattle','San Jose'], datasets:[{ label:'Median Home Price', data:[540000,575000,610000,860000,1460000], backgroundColor:tealPalette[1], borderColor:tealPalette[0], borderWidth:1 }] }, options:defaultChartOptions });
    </script>

    <!-- Gemini API JS -->
    <script>
        const apiKey = "AIzaSyDsmwAZkxbTY83004u7NbdRvH0uK-nRsS8"; // Your Gemini API Key
        const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`;
        const buyerSummaryBtn = document.getElementById('buyerSummaryBtn');
        const sellerSummaryBtn = document.getElementById('sellerSummaryBtn');
        const summaryOutput = document.getElementById('summaryOutput');
        const marketData = "Median Sale Price is $558K, Average Days on Market is 26, and there are 2.9 months of housing inventory.";

        const simpleMarkdownToHtml = (text) => text.replace(/\*\*(.*?)\*\*/g,'<strong>$1</strong>').replace(/\*(.*?)\*/g,'<li>$1</li>').replace(/\n/g,'<br>');

        const callGeminiApi = async (prompt) => {
            summaryOutput.innerHTML = '<div class="loader"></div>';
            buyerSummaryBtn.disabled = sellerSummaryBtn.disabled = true;
            try {
                const response = await fetch(apiUrl,{ method:'POST', headers:{ 'Content-Type':'application/json' }, body:JSON.stringify({ contents:[{ parts:[{ text: prompt }] }] }) });
                const result = await response.json();
                const text = result.candidates?.[0]?.content?.parts?.[0]?.text || 'No response from API.';
                summaryOutput.innerHTML = simpleMarkdownToHtml(text);
            } catch(e) {
                summaryOutput.innerHTML = `<p class="text-red-500">Error: ${e.message}</p>`;
            }
            buyerSummaryBtn.disabled = sellerSummaryBtn.disabled = false;
        };

        buyerSummaryBtn.addEventListener('click', () => callGeminiApi(`You are a helpful real estate advisor. Based on data: ${marketData}. Write 2-3 concise sentences for a potential home buyer.`));
        sellerSummaryBtn.addEventListener('click', () => callGeminiApi(`You are a helpful real estate advisor. Based on data: ${marketData}. Write 2-3 concise sentences for a potential home seller.`));
    </script>

    <!-- Auto-resize for iframe -->
    <script>
        function resizeIframe() {
            if (window.parent) {
                const height = document.documentElement.scrollHeight;
                window.parent.postMessage({ type: 'resize-iframe', height }, '*');
            }
        }
        window.addEventListener('load', resizeIframe);
        window.addEventListener('resize', resizeIframe);
    </script>

</body>
</html>

Discover more from Staub Real Estate

Subscribe now to keep reading and get access to the full archive.

Continue reading