deepseek-v4-pro-0812 @ high · api

apihigh
config
deepseek-v4-pro-0812-eff-high--api--official--dev
batch
2026-07-19--unified
transport
deepseek-official-api
protocol
api · metered
served model
deepseek-v4-pro
captured
Jul 18, 2026, 11:54 AM · N=4
variant
live
slot 0 · P-q · sandboxed iframe
deepseek-v4-pro-0812 @high · api P-q slot 0 screenshot

delivered in a markdown fence — the model wrapped its HTML in a code fence; extraction stripped it. Recorded here for traceability.

content never populated — at capture time this card was still in its placeholder state and the real content never arrived. The screenshot is exactly what the page showed; its own code is in Source below.

The screenshot is the exact frozen pixels the similarity channels measured. Run live re-executes the raw output in a sandboxed iframe; its rendering depends on your browser and fonts and is not guaranteed to match the measured pixels.

similarity neighborsNo similarity data for this session — this batch has no computed pairs.

Fidelity — does the card show the right data?

  • namematch
  • conditionmatch
  • datematch
  • max tempnot-foundno-temperature-candidate
  • min tempnot-foundno-temperature-candidate
  • hourlynot-foundcoverage · 0 match · 0 mismatch · 24 not shown
  • request sidematch0 violation(s)

extractor fidelity-extractor-v1+Berlin-2026-07-15

Source — raw model output, one byte unchanged

download card.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Weather Card</title>
    <style>
        :root {
            --card-bg: rgba(255, 255, 255, 0.92);
            --card-border: rgba(255, 255, 255, 0.5);
            --text-primary: #1a1a2e;
            --text-secondary: #55556b;
            --text-muted: #8888a0;
            --accent: #3a7bd5;
            --shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
            --bar-bg: rgba(0, 0, 0, 0.06);
            --hover-glow: rgba(58, 123, 213, 0.4);
            --font-stack: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            --bg-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            --card-accent-gradient: linear-gradient(90deg, #3a7bd5, #5c9ce6);
        }

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

        body {
            width: 100vw;
            height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            font-family: var(--font-stack);
            background: var(--bg-gradient);
            transition: background 0.7s ease;
            overflow: hidden;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }

        /* Weather-based background themes */
        body.weather-clear {
            --bg-gradient: linear-gradient(150deg, #4facfe 0%, #00c6fb 40%, #1e3c72 100%);
            --card-accent-gradient: linear-gradient(90deg, #ffb347, #ff8c42);
            --accent: #f58220;
        }
        body.weather-partly {
            --bg-gradient: linear-gradient(150deg, #5b8def 0%, #87c7f3 50%, #b6d8e8 100%);
            --card-accent-gradient: linear-gradient(90deg, #5b8def, #7db8e8);
            --accent: #4a7fc1;
        }
        body.weather-cloudy {
            --bg-gradient: linear-gradient(150deg, #8e9eab 0%, #b0bec5 40%, #607d8b 100%);
            --card-accent-gradient: linear-gradient(90deg, #78909c, #90a4ae);
            --accent: #607d8b;
        }
        body.weather-rain {
            --bg-gradient: linear-gradient(150deg, #3a4a5a 0%, #2c3e50 45%, #1a252f 100%);
            --card-accent-gradient: linear-gradient(90deg, #4a6fa5, #6b8db5);
            --accent: #4a6fa5;
        }
        body.weather-snow {
            --bg-gradient: linear-gradient(150deg, #e8f0f8 0%, #c5d8e8 45%, #9bb8d4 100%);
            --card-accent-gradient: linear-gradient(90deg, #7fa8c9, #a8c8e8);
            --accent: #5a8ab5;
        }
        body.weather-thunder {
            --bg-gradient: linear-gradient(150deg, #2d1b3d 0%, #3d2a54 35%, #1a1025 100%);
            --card-accent-gradient: linear-gradient(90deg, #7c5cbf, #a87cc0);
            --accent: #8a6cc0;
        }
        body.weather-fog {
            --bg-gradient: linear-gradient(150deg, #b8c6d0 0%, #d5dde5 45%, #a0aeb8 100%);
            --card-accent-gradient: linear-gradient(90deg, #8fa5b5, #b0c0cc);
            --accent: #7a8f9f;
        }
        body.weather-drizzle {
            --bg-gradient: linear-gradient(150deg, #5a7a8f 0%, #7a9fb5 45%, #4a6a80 100%);
            --card-accent-gradient: linear-gradient(90deg, #5b8eab, #7aa8c0);
            --accent: #4a7f9a;
        }

        .scene {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 40px;
        }

        .weather-card {
            width: 860px;
            max-width: 95%;
            background: var(--card-bg);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border: 1px solid var(--card-border);
            border-radius: 20px;
            box-shadow: var(--shadow);
            overflow: hidden;
            transition: all 0.5s ease;
            animation: cardAppear 0.5s ease-out forwards;
        }

        @keyframes cardAppear {
            from {
                opacity: 0;
                transform: translateY(24px) scale(0.96);
            }
            to {
                opacity: 1;
                transform: translateY(0) scale(1);
            }
        }

        .card-accent {
            height: 5px;
            background: var(--card-accent-gradient);
            transition: background 0.5s ease;
        }

        .card-content {
            padding: 32px 36px 30px;
        }

        /* Header */
        .card-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 28px;
        }
        .location-group {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .location-icon {
            width: 18px;
            height: 18px;
            color: var(--accent);
            transition: color 0.5s ease;
            flex-shrink: 0;
        }
        .location-name {
            font-size: 28px;
            font-weight: 700;
            color: var(--text-primary);
            letter-spacing: -0.3px;
            line-height: 1.2;
        }
        .date-display {
            font-size: 15px;
            font-weight: 500;
            color: var(--text-secondary);
            letter-spacing: 0.3px;
            text-align: right;
        }

        /* Main weather section */
        .weather-main {
            display: flex;
            align-items: center;
            gap: 28px;
            padding: 16px 4px 24px;
            border-bottom: 1px solid rgba(0, 0, 0, 0.07);
            margin-bottom: 24px;
        }
        .icon-wrap {
            width: 96px;
            height: 96px;
            flex-shrink: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            background: rgba(0, 0, 0, 0.04);
            transition: background 0.5s ease;
        }
        .icon-wrap svg {
            width: 68px;
            height: 68px;
            transition: transform 0.3s ease;
        }
        .icon-wrap:hover svg {
            transform: scale(1.08);
        }
        .temp-block {
            flex: 1;
        }
        .temp-row {
            display: flex;
            align-items: baseline;
            gap: 20px;
            flex-wrap: wrap;
        }
        .temp-max {
            font-size: 56px;
            font-weight: 800;
            color: var(--text-primary);
            letter-spacing: -2px;
            line-height: 1;
        }
        .temp-max .deg {
            font-size: 36px;
            font-weight: 600;
            letter-spacing: -1px;
            vertical-align: top;
            margin-left: 2px;
        }
        .temp-min {
            font-size: 20px;
            font-weight: 500;
            color: var(--text-secondary);
        }
        .temp-min .deg {
            font-size: 14px;
            vertical-align: super;
        }
        .condition-label {
            display: inline-block;
            margin-top: 8px;
            font-size: 16px;
            font-weight: 500;
            color: var(--text-secondary);
            background: rgba(0, 0, 0, 0.05);
            padding: 6px 14px;
            border-radius: 20px;
            letter-spacing: 0.2px;
            transition: background 0.5s ease;
        }

        /* Hourly section */
        .hourly-section {
            margin-top: 4px;
        }
        .hourly-title {
            font-size: 13px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 1.2px;
            color: var(--text-muted);
            margin-bottom: 16px;
        }
        .hourly-chart-wrap {
            position: relative;
            height: 150px;
            display: flex;
            align-items: flex-end;
            gap: 6px;
            padding: 8px 4px 0;
            background: var(--bar-bg);
            border-radius: 12px;
            transition: background 0.5s ease;
        }
        .hourly-bar {
            flex: 1;
            min-width: 14px;
            max-width: 24px;
            border-radius: 6px 6px 3px 3px;
            cursor: pointer;
            position: relative;
            transform-origin: bottom;
            animation: barGrow 0.7s cubic-bezier(0.25, 0.8, 0.35, 1) forwards;
            opacity: 0;
            transition: filter 0.2s ease, box-shadow 0.2s ease;
        }
        .hourly-bar:hover {
            filter: brightness(1.15);
            box-shadow: 0 0 12px var(--hover-glow);
        }
        @keyframes barGrow {
            from {
                transform: scaleY(0);
                opacity: 0;
            }
            to {
                transform: scaleY(1);
                opacity: 1;
            }
        }

        .bar-tooltip {
            position: absolute;
            top: -32px;
            left: 50%;
            transform: translateX(-50%) translateY(4px);
            background: #1a1a2e;
            color: #fff;
            font-size: 11px;
            font-weight: 600;
            padding: 4px 8px;
            border-radius: 6px;
            white-space: nowrap;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.2s ease, transform 0.2s ease;
            z-index: 10;
        }
        .bar-tooltip::after {
            content: '';
            position: absolute;
            top: 100%;
            left: 50%;
            transform: translateX(-50%);
            border: 5px solid transparent;
            border-top-color: #1a1a2e;
        }
        .hourly-bar:hover .bar-tooltip {
            opacity: 1;
            transform: translateX(-50%) translateY(0);
        }

        .hourly-labels {
            display: flex;
            justify-content: space-between;
            padding: 10px 6px 0;
            font-size: 11px;
            font-weight: 500;
            color: var(--text-muted);
            letter-spacing: 0.3px;
        }

        .zero-line {
            position: absolute;
            left: 0;
            right: 0;
            border-top: 1.5px dashed rgba(0, 0, 0, 0.2);
            pointer-events: none;
            z-index: 1;
            transition: border-color 0.5s ease;
        }

        /* Error state */
        .error-state {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            text-align: center;
            padding: 50px 30px;
            min-height: 300px;
        }
        .error-icon {
            font-size: 56px;
            margin-bottom: 16px;
            opacity: 0.7;
        }
        .error-title {
            font-size: 22px;
            font-weight: 700;
            color: var(--text-primary);
            margin-bottom: 8px;
        }
        .error-desc {
            font-size: 15px;
            color: var(--text-secondary);
            max-width: 400px;
            line-height: 1.5;
        }
        .error-retry {
            margin-top: 20px;
            padding: 10px 24px;
            font-size: 14px;
            font-weight: 600;
            color: #fff;
            background: var(--accent);
            border: none;
            border-radius: 8px;
            cursor: pointer;
            transition: background 0.3s ease, transform 0.2s ease;
            font-family: var(--font-stack);
        }
        .error-retry:hover {
            background: color-mix(in srgb, var(--accent) 85%, black);
            transform: translateY(-1px);
        }
        .error-retry:active {
            transform: translateY(0);
        }

        /* Loading state */
        .loading-state {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            text-align: center;
            padding: 50px 30px;
            min-height: 300px;
        }
        .loading-spinner {
            width: 48px;
            height: 48px;
            border: 4px solid rgba(0, 0, 0, 0.1);
            border-top-color: var(--accent);
            border-radius: 50%;
            animation: spin 0.8s linear infinite;
            margin-bottom: 16px;
            transition: border-top-color 0.5s ease;
        }
        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }
        .loading-text {
            font-size: 16px;
            font-weight: 500;
            color: var(--text-secondary);
        }
    </style>
</head>
<body>
    <div class="scene" id="scene">
        <div class="weather-card" id="weatherCard">
            <div class="card-accent" id="cardAccent"></div>
            <div class="card-content" id="cardContent">
                <div class="loading-state" id="loadingState">
                    <div class="loading-spinner"></div>
                    <div class="loading-text">Loading weather data&hellip;</div>
                </div>
            </div>
        </div>
    </div>

    <script>
        (function() {
            'use strict';

            // ---------- Weather code mappings ----------
            const weatherInfo = {
                0: { label: 'Clear sky', icon: 'clear', bgClass: 'weather-clear' },
                1: { label: 'Mainly clear', icon: 'clear', bgClass: 'weather-clear' },
                2: { label: 'Partly cloudy', icon: 'partly', bgClass: 'weather-partly' },
                3: { label: 'Overcast', icon: 'cloudy', bgClass: 'weather-cloudy' },
                45: { label: 'Foggy', icon: 'fog', bgClass: 'weather-fog' },
                48: { label: 'Icy fog', icon: 'fog', bgClass: 'weather-fog' },
                51: { label: 'Light drizzle', icon: 'drizzle', bgClass: 'weather-drizzle' },
                53: { label: 'Moderate drizzle', icon: 'drizzle', bgClass: 'weather-drizzle' },
                55: { label: 'Heavy drizzle', icon: 'drizzle', bgClass: 'weather-drizzle' },
                56: { label: 'Freezing drizzle', icon: 'drizzle', bgClass: 'weather-drizzle' },
                57: { label: 'Heavy freezing drizzle', icon: 'drizzle', bgClass: 'weather-drizzle' },
                61: { label: 'Light rain', icon: 'rain', bgClass: 'weather-rain' },
                63: { label: 'Moderate rain', icon: 'rain', bgClass: 'weather-rain' },
                65: { label: 'Heavy rain', icon: 'rain', bgClass: 'weather-rain' },
                66: { label: 'Freezing rain', icon: 'rain', bgClass: 'weather-rain' },
                67: { label: 'Heavy freezing rain', icon: 'rain', bgClass: 'weather-rain' },
                71: { label: 'Light snow', icon: 'snow', bgClass: 'weather-snow' },
                73: { label: 'Moderate snow', icon: 'snow', bgClass: 'weather-snow' },
                75: { label: 'Heavy snow', icon: 'snow', bgClass: 'weather-snow' },
                77: { label: 'Snow grains', icon: 'snow', bgClass: 'weather-snow' },
                80: { label: 'Light showers', icon: 'rain', bgClass: 'weather-rain' },
                81: { label: 'Moderate showers', icon: 'rain', bgClass: 'weather-rain' },
                82: { label: 'Heavy showers', icon: 'rain', bgClass: 'weather-rain' },
                85: { label: 'Light snow showers', icon: 'snow', bgClass: 'weather-snow' },
                86: { label: 'Heavy snow showers', icon: 'snow', bgClass: 'weather-snow' },
                95: { label: 'Thunderstorm', icon: 'thunder', bgClass: 'weather-thunder' },
                96: { label: 'Thunderstorm with hail', icon: 'thunder', bgClass: 'weather-thunder' },
                99: { label: 'Thunderstorm with heavy hail', icon: 'thunder', bgClass: 'weather-thunder' },
            };

            // ---------- SVG Icon Generators ----------
            function cloudShape(color, xOffset = 0, yOffset = 0, scale = 1) {
                return `
              <g fill="${color}" transform="translate(${xOffset},${yOffset}) scale(${scale})">
                <circle cx="22" cy="36" r="13" />
                <circle cx="38" cy="29" r="17" />
                <circle cx="53" cy="38" r="12" />
                <rect x="15" y="36" width="48" height="14" rx="7" />
              </g>
            `;
            }

            function sunRays(cx, cy, innerR, outerR, color, strokeWidth = 2.5) {
                let rays = '';
                for (let i = 0; i < 8; i++) {
                    const angle = (i * Math.PI * 2) / 8;
                    const x1 = cx + Math.cos(angle) * innerR;
                    const y1 = cy + Math.sin(angle) * innerR;
                    const x2 = cx + Math.cos(angle) * outerR;
                    const y2 = cy + Math.sin(angle) * outerR;
                    rays += `<line x1="${x1.toFixed(1)}" y1="${y1.toFixed(1)}" x2="${x2.toFixed(1)}" y2="${y2.toFixed(1)}" stroke="${color}" stroke-width="${strokeWidth}" stroke-linecap="round"/>`;
                }
                return rays;
            }

            const svgIcons = {
                clear: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="32" cy="32" r="11" fill="#FFB300"/>
                ${sunRays(32, 32, 15, 24, '#FFB300', 3)}
              </svg>
            `,
                partly: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="30" cy="26" r="9" fill="#FFB300"/>
                ${sunRays(30, 26, 12, 19, '#FFB300', 2.5)}
                ${cloudShape('#B0BEC5', 4, 10, 1)}
              </svg>
            `,
                cloudy: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                ${cloudShape('#90A4AE', 0, 4, 1.1)}
              </svg>
            `,
                rain: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                ${cloudShape('#78909C', 0, -2, 1)}
                <line x1="22" y1="48" x2="18" y2="56" stroke="#42A5F5" stroke-width="3" stroke-linecap="round"/>
                <line x1="34" y1="48" x2="30" y2="56" stroke="#42A5F5" stroke-width="3" stroke-linecap="round"/>
                <line x1="46" y1="48" x2="42" y2="56" stroke="#42A5F5" stroke-width="3" stroke-linecap="round"/>
              </svg>
            `,
                drizzle: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                ${cloudShape('#90A4AE', 0, -2, 1)}
                <line x1="28" y1="50" x2="26" y2="55" stroke="#64B5F6" stroke-width="2.5" stroke-linecap="round"/>
                <line x1="40" y1="50" x2="38" y2="55" stroke="#64B5F6" stroke-width="2.5" stroke-linecap="round"/>
              </svg>
            `,
                snow: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                ${cloudShape('#B0BEC5', 0, -2, 1)}
                <text x="24" y="56" font-size="12" fill="#E3F2FD" font-weight="bold">&#10022;</text>
                <text x="36" y="56" font-size="12" fill="#E3F2FD" font-weight="bold">&#10022;</text>
                <text x="48" y="52" font-size="10" fill="#E3F2FD" font-weight="bold">&#10022;</text>
              </svg>
            `,
                thunder: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                ${cloudShape('#546E7A', 0, 0, 1)}
                <polygon points="37,38 28,52 34,52 31,62 44,46 37,46 40,38" fill="#FFC107"/>
              </svg>
            `,
                fog: `
              <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
                <line x1="12" y1="28" x2="52" y2="28" stroke="#90A4AE" stroke-width="3" stroke-linecap="round"/>
                <line x1="8" y1="37" x2="56" y2="37" stroke="#90A4AE" stroke-width="3" stroke-linecap="round"/>
                <line x1="16" y1="46" x2="48" y2="46" stroke="#90A4AE" stroke-width="3" stroke-linecap="round"/>
                <line x1="20" y1="55" x2="44" y2="55" stroke="#90A4AE" stroke-width="2.5" stroke-linecap="round"/>
              </svg>
            `,
            };

            // ---------- Helpers ----------
            function getTodayUTC() {
                const d = new Date();
                return d.toISOString().slice(0, 10);
            }

            function formatDateDisplay(dateStr) {
                const date = new Date(dateStr + 'T00:00:00Z');
                return date.toLocaleDateString('en-US', {
                    weekday: 'long',
                    year: 'numeric',
                    month: 'long',
                    day: 'numeric',
                    timeZone: 'UTC',
                });
            }

            function formatHour(hour) {
                return String(hour).padStart(2, '0') + ':00';
            }

            function tempColor(temp) {
                const stops = [
                    { temp: -15, hue: 230 },
                    { temp: -5, hue: 210 },
                    { temp: 0, hue: 190 },
                    { temp: 10, hue: 140 },
                    { temp: 20, hue: 50 },
                    { temp: 28, hue: 20 },
                    { temp: 35, hue: 0 },
                ];
                const t = Math.max(-15, Math.min(35, temp));
                let lower = stops[0];
                let upper = stops[stops.length - 1];
                for (let i = 0; i < stops.length - 1; i++) {
                    if (t >= stops[i].temp && t <= stops[i + 1].temp) {
                        lower = stops[i];
                        upper = stops[i + 1];
                        break;
                    }
                }
                const ratio = (t - lower.temp) / (upper.temp - lower.temp);
                const hue = lower.hue + ratio * (upper.hue - lower.hue);
                return `hsl(${Math.round(hue)}, 72%, 52%)`;
            }

            function getIconForCode(code) {
                const info = weatherInfo[code] || weatherInfo[3];
                return svgIcons[info.icon] || svgIcons.cloudy;
            }

            function getLabelForCode(code) {
                const info = weatherInfo[code] || weatherInfo[3];
                return info.label;
            }

            function getBgClassForCode(code) {
                const info = weatherInfo[code] || weatherInfo[3];
                return info.bgClass;
            }

            // ---------- Query Parameters ----------
            const params = new URLSearchParams(window.location.search);
            const lat = params.get('lat') || '52.52';
            const lon = params.get('lon') || '13.405';
            const locationName = params.get('name') || 'Berlin';
            const dateStr = params.get('date') || getTodayUTC();

            // ---------- DOM Elements ----------
            const scene = document.getElementById('scene');
            const cardContent = document.getElementById('cardContent');
            const weatherCard = document.getElementById('weatherCard');
            const cardAccent = document.getElementById('cardAccent');

            // ---------- Fetch & Render ----------
            function buildApiUrl(dateStr) {
                const today = getTodayUTC();
                const isPast = dateStr < today;
                const basePath = isPast ? '/api/om/archive' : '/api/om/forecast';
                const queryParams = new URLSearchParams({
                    latitude: lat,
                    longitude: lon,
                    daily: 'temperature_2m_max,temperature_2m_min,weather_code',
                    hourly: 'temperature_2m',
                    timezone: 'UTC',
                    temperature_unit: 'celsius',
                    start_date: dateStr,
                    end_date: dateStr,
                });
                return `${basePath}?${queryParams.toString()}`;
            }

            function renderError(message) {
                document.body.className = '';
                cardContent.innerHTML = `
              <div class="error-state">
                <div class="error-icon">&#9888;&#65039;</div>
                <div class="error-title">Unable to load weather</div>
                <div class="error-desc">${message}</div>
                <button class="error-retry" onclick="window.location.reload()">Try Again</button>
              </div>
            `;
                weatherCard.style.animation = 'cardAppear 0.4s ease-out forwards';
            }

            function renderLoading() {
                document.body.className = '';
                cardContent.innerHTML = `
              <div class="loading-state">
                <div class="loading-spinner"></div>
                <div class="loading-text">Loading weather data&hellip;</div>
              </div>
            `;
            }

            function renderWeatherCard(data) {
                const daily = data.daily || {};
                const hourly = data.hourly || {};
                const maxTemps = daily.temperature_2m_max || [];
                const minTemps = daily.temperature_2m_min || [];
                const codes = daily.weather_code || [];
                const hourlyTemps = hourly.temperature_2m || [];
                const hourlyTimes = hourly.time || [];

                if (maxTemps.length === 0 || minTemps.length === 0 || codes.length === 0) {
                    renderError('No weather data available for the requested date.');
                    return;
                }

                const maxTemp = maxTemps[0];
                const minTemp = minTemps[0];
                const code = codes[0];
                const info = weatherInfo[code] || weatherInfo[3];
                const iconSvg = getIconForCode(code);
                const label = getLabelForCode(code);
                const bgClass = getBgClassForCode(code);
                const dateDisplay = formatDateDisplay(dateStr);

                // Update body background class
                document.body.className = bgClass;
                // Update accent color
                cardAccent.style.background = 'var(--card-accent-gradient)';

                // Extract hours from time strings
                const hours = hourlyTimes.map(t => {
                    const match = t.match(/T(\d{2}):/);
                    return match ? parseInt(match[1], 10) : null;
                }).filter(h => h !== null);

                // If no hours found but we have 24 temps, assume 0-23
                const effectiveHours = hours.length === hourlyTemps.length ? hours :
                    Array.from({ length: hourlyTemps.length }, (_, i) => i);

                // Build hourly bars HTML
                const tempMinBar = Math.min(...hourlyTemps);
                const tempMaxBar = Math.max(...hourlyTemps);
                const tempRange = tempMaxBar - tempMinBar || 1;
                const chartHeight = 140;
                const minBarHeight = 8;
                const maxBarHeight = chartHeight - 8;

                let barsHtml = '';
                for (let i = 0; i < hourlyTemps.length; i++) {
                    const t = hourlyTemps[i];
                    const norm = (t - tempMinBar) / tempRange;
                    const barHeight = minBarHeight + norm * (maxBarHeight - minBarHeight);
                    const color = tempColor(t);
                    const hourLabel = formatHour(effectiveHours[i] ?? i);
                    const delay = i * 20;
                    barsHtml += `
                <div class="hourly-bar" 
                     style="height:${barHeight.toFixed(1)}px; background:${color}; animation-delay:${delay}ms;"
                     title="${hourLabel} &mdash; ${t.toFixed(1)}&deg;C">
                  <span class="bar-tooltip">${t.toFixed(1)}&deg;C &middot; ${hourLabel}</span>
                </div>
              `;
                }

                // Build time labels every 3 hours
                const labelHours = [0, 3, 6, 9, 12, 15, 18, 21];
                const labelsHtml = labelHours.map(h => `<span>${formatHour(h)}</span>`).join('');

                // Zero line if any temp is below 0°C
                const hasSubZero = hourlyTemps.some(t => t < 0);
                const zeroLineHtml = hasSubZero ? `
              <div class="zero-line" style="bottom:${(minBarHeight + ((0 - tempMinBar) / tempRange) * (maxBarHeight - minBarHeight)).toFixed(1)}px;"></div>
            ` : '';

                // Build the full card HTML
                const cardHtml = `
              <div class="card-header">
                <div class="location-group">
                  <svg class="location-icon" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                    <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>
                  </svg>
                  <h1 class="location-name">${escapeHtml(locationName)}</h1>
                </div>
                <span class="date-display">${escapeHtml(dateDisplay)}</span>
              </div>
              <div class="weather-main">
                <div class="icon-wrap">
                  ${iconSvg}
                </div>
                <div class="temp-block">
                  <div class="temp-row">
                    <span class="temp-max">${maxTemp.toFixed(1)}<span class="deg">&deg;C</span></span>
                    <span class="temp-min">Low: ${minTemp.toFixed(1)}<span class="deg">&deg;C</span></span>
                  </div>
                  <span class="condition-label">${escapeHtml(label)}</span>
                </div>
              </div>
              <div class="hourly-section">
                <div class="hourly-title">Hourly Temperatures</div>
                <div class="hourly-chart-wrap">
                  ${zeroLineHtml}
                  ${barsHtml}
                </div>
                <div class="hourly-labels">${labelsHtml}</div>
              </div>
            `;

                cardContent.innerHTML = cardHtml;
                weatherCard.style.animation = 'none';
                void weatherCard.offsetHeight;
                weatherCard.style.animation = 'cardAppear 0.4s ease-out forwards';
            }

            function escapeHtml(str) {
                const div = document.createElement('div');
                div.textContent = str;
                return div.innerHTML;
            }

            async function loadWeather() {
                renderLoading();
                try {
                    const apiUrl = buildApiUrl(dateStr);
                    const response = await fetch(apiUrl, {
                        method: 'GET',
                        headers: { 'Accept': 'application/json' },
                    });
                    if (!response.ok) {
                        throw new Error(`API responded with status ${response.status}`);
                    }
                    const data = await response.json();
                    if (!data || !data.daily || !data.hourly) {
                        throw new Error('Unexpected response format from API');
                    }
                    renderWeatherCard(data);
                } catch (err) {
                    console.error('Weather fetch error:', err);
                    renderError(
                        'We couldn\'t retrieve the weather data for the requested date and location. Please check your connection or try again later.'
                    );
                }
            }

            // ---------- Start ----------
            loadWeather();
        })();
    </script>
</body>
</html>

L1 — cheap deterministic descriptors

bytes total31,906html / css / js717 / 12,520 / 18,669
dom nodes15dom depth7
css rules59js presentyes
brightness172.4contrast52.9
colorfulness50.7whitespace46.0%

This slot's telemetry

prompt tokens400completion tokens19,710
total tokens20,110wall225.4 s
costrequest id
config.json592 B
{
  "N": 4,
  "auth": {
    "credential_ref": "WCB_DEEPSEEK_KEY",
    "method": "api-key"
  },
  "billing": "metered",
  "config_id": "deepseek-v4-pro-0812-eff-high--api--official--dev",
  "effort": "high",
  "family": "deepseek",
  "m": {
    "min": 4,
    "q": 4
  },
  "model_id": "deepseek-v4-pro-0812",
  "protocol": "api",
  "served_model": "deepseek-v4-pro",
  "telemetry": {
    "completion_tokens": 126136,
    "cost_usd": null,
    "prompt_tokens": 3168,
    "total_tokens": 129304,
    "wall_ms": 1545026
  },
  "transport": "deepseek-official-api",
  "vendor_sanction_ref": null
}
send-log4.7 KB
{
  "N": 4,
  "batch_id": "2026-08-13--ds-pro-ga",
  "config_id": "deepseek-v4-pro-0812-eff-high--api--official--dev",
  "positions": [
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T05:43:49.214464+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T05:40:03.816948+00:00"
        }
      ],
      "block_index": 0,
      "model_reaching_attempt_index": 0,
      "slot_index": 0,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T05:46:26.422073+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T05:43:53.093969+00:00"
        }
      ],
      "block_index": 0,
      "model_reaching_attempt_index": 0,
      "slot_index": 0,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T05:48:30.151113+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T05:46:29.602055+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T05:51:27.060788+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T05:48:33.259179+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T05:54:55.390490+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T05:51:30.457950+00:00"
        }
      ],
      "block_index": 2,
      "model_reaching_attempt_index": 0,
      "slot_index": 2,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T05:58:02.474051+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T05:54:58.656398+00:00"
        }
      ],
      "block_index": 2,
      "model_reaching_attempt_index": 0,
      "slot_index": 2,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T06:00:10.337303+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T05:58:05.782322+00:00"
        }
      ],
      "block_index": 3,
      "model_reaching_attempt_index": 0,
      "slot_index": 3,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-13T06:06:12.413570+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-13T06:00:13.702082+00:00"
        }
      ],
      "block_index": 3,
      "model_reaching_attempt_index": 0,
      "slot_index": 3,
      "terminal_state": "valid",
      "variant": "P-q"
    }
  ],
  "retry_policy": {
    "max_unreachable_retries": 5,
    "rate_limit_backoff": {
      "max_attempts": 4,
      "max_total_ms": 60000
    }
  }
}