gpt-5.2 @ high · cursor
cursorhigh
- config
- gpt-5.2-eff-high--cli--cursor--dev
- batch
- 2026-07-19--unified
- transport
- cursor-agent-cli-isolated-home
- protocol
- cli · plan
- served model
- gpt-5.2-high
- captured
- Jul 18, 2026, 11:54 AM · N=2
variant
live
slot 0 · P-q · sandboxed iframe

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 tempmismatchshown: 16
- min tempmismatchshown: 25
- hourlymismatchcoverage 0/24 · 0 match · 4 mismatch · 20 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" />
<meta name="color-scheme" content="dark" />
<title>Weather Card</title>
<style>
:root{
--bg0:#070A14;
--bg1:#0B1230;
--card: rgba(255,255,255,.06);
--card2: rgba(255,255,255,.085);
--stroke: rgba(255,255,255,.12);
--stroke2: rgba(255,255,255,.18);
--text: rgba(255,255,255,.92);
--muted: rgba(255,255,255,.68);
--muted2: rgba(255,255,255,.52);
--shadow: 0 30px 80px rgba(0,0,0,.55);
--shadow2: 0 12px 36px rgba(0,0,0,.40);
--accent:#7C5CFF;
--accent2:#22D3EE;
--good:#34D399;
--warn:#FBBF24;
--bad:#FB7185;
--radius: 22px;
--radius2: 16px;
--mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--sans: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji","Segoe UI Emoji";
}
*{box-sizing:border-box}
html,body{height:100%}
body{
margin:0;
font-family:var(--sans);
color:var(--text);
background:
radial-gradient(1100px 600px at 18% 15%, rgba(124,92,255,.28), transparent 55%),
radial-gradient(900px 520px at 78% 18%, rgba(34,211,238,.22), transparent 52%),
radial-gradient(800px 700px at 50% 90%, rgba(251,113,133,.18), transparent 55%),
linear-gradient(180deg, var(--bg0), var(--bg1));
overflow:hidden;
}
/* Subtle grain without images */
body:before{
content:"";
position:fixed; inset:0;
pointer-events:none;
background-image:
repeating-linear-gradient(0deg, rgba(255,255,255,.03), rgba(255,255,255,.03) 1px, transparent 1px, transparent 3px),
repeating-linear-gradient(90deg, rgba(255,255,255,.018), rgba(255,255,255,.018) 1px, transparent 1px, transparent 4px);
mix-blend-mode:overlay;
opacity:.35;
filter: blur(.2px);
}
.stage{
width:1280px;
height:800px;
margin:0 auto;
display:flex;
align-items:center;
justify-content:center;
padding:36px;
position:relative;
}
.wrap{
width:100%;
height:100%;
display:grid;
grid-template-rows: auto 1fr;
gap:18px;
}
header{
display:flex;
align-items:flex-end;
justify-content:space-between;
padding: 6px 6px 0;
}
.brand{
display:flex;
flex-direction:column;
gap:6px;
line-height:1.1;
}
.brand .title{
font-weight:700;
letter-spacing:-.02em;
font-size:18px;
color:rgba(255,255,255,.86);
}
.brand .sub{
display:flex;
gap:10px;
align-items:center;
font-family:var(--mono);
font-size:12px;
color:var(--muted2);
}
.dot{
width:6px; height:6px;
border-radius:99px;
background: linear-gradient(135deg, var(--accent), var(--accent2));
box-shadow: 0 0 0 4px rgba(124,92,255,.12);
}
.pillrow{
display:flex;
gap:10px;
align-items:center;
flex-wrap:wrap;
justify-content:flex-end;
}
.pill{
border:1px solid var(--stroke);
background: rgba(255,255,255,.04);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
padding:10px 12px;
border-radius: 999px;
box-shadow: var(--shadow2);
display:flex;
gap:10px;
align-items:center;
min-height:40px;
}
.pill .k{
color:var(--muted2);
font-family:var(--mono);
font-size:11px;
letter-spacing:.02em;
text-transform:uppercase;
}
.pill .v{
color:rgba(255,255,255,.86);
font-size:13px;
font-weight:600;
letter-spacing:-.01em;
white-space:nowrap;
}
main{
display:grid;
grid-template-columns: 1.15fr .85fr;
gap:18px;
height:100%;
min-height:0;
}
.card{
border-radius: var(--radius);
border:1px solid var(--stroke);
background: linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,.04));
box-shadow: var(--shadow);
position:relative;
overflow:hidden;
min-height:0;
}
.card:before{
content:"";
position:absolute; inset:-2px;
pointer-events:none;
background:
radial-gradient(600px 260px at 15% 12%, rgba(124,92,255,.22), transparent 60%),
radial-gradient(560px 260px at 90% 15%, rgba(34,211,238,.18), transparent 62%),
radial-gradient(700px 340px at 50% 120%, rgba(251,113,133,.14), transparent 58%);
opacity:.9;
filter:saturate(1.2);
}
.left{
padding:24px;
display:grid;
grid-template-rows: auto auto 1fr;
gap:16px;
height:100%;
position:relative;
z-index:1;
}
.topline{
display:flex;
justify-content:space-between;
gap:16px;
align-items:flex-start;
}
.place{
display:flex;
flex-direction:column;
gap:10px;
min-width:0;
}
.place .name{
font-size:30px;
font-weight:760;
letter-spacing:-.03em;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
max-width: 520px;
}
.place .meta{
display:flex;
gap:14px;
align-items:center;
flex-wrap:wrap;
color:var(--muted);
font-size:13px;
}
.meta .tag{
border:1px solid var(--stroke);
background: rgba(255,255,255,.04);
padding:7px 10px;
border-radius:999px;
display:inline-flex;
align-items:center;
gap:8px;
}
.meta .tag b{
font-family:var(--mono);
font-size:12px;
color:rgba(255,255,255,.80);
font-weight:700;
}
.condbox{
display:flex;
flex-direction:column;
align-items:flex-end;
gap:10px;
min-width:220px;
}
.icon{
width:78px;
height:78px;
filter: drop-shadow(0 10px 24px rgba(0,0,0,.45));
}
.condtext{
text-align:right;
display:flex;
flex-direction:column;
gap:6px;
}
.condtext .main{
font-weight:740;
letter-spacing:-.02em;
font-size:16px;
color:rgba(255,255,255,.90);
}
.condtext .sub{
font-size:12px;
color:var(--muted2);
font-family:var(--mono);
}
.temps{
display:grid;
grid-template-columns: 1.2fr .8fr;
gap:16px;
align-items:end;
}
.hiLo{
display:flex;
flex-direction:column;
gap:12px;
}
.range{
display:flex;
align-items:baseline;
gap:14px;
flex-wrap:wrap;
}
.big{
font-size:56px;
font-weight:860;
letter-spacing:-.05em;
line-height:1;
background: linear-gradient(135deg, rgba(255,255,255,.92), rgba(255,255,255,.70));
-webkit-background-clip:text;
background-clip:text;
color:transparent;
}
.small{
font-size:22px;
font-weight:780;
letter-spacing:-.03em;
color:rgba(255,255,255,.84);
}
.unit{
font-size:14px;
font-weight:700;
letter-spacing:.02em;
color:var(--muted2);
margin-left:6px;
font-family:var(--mono);
}
.chips{
display:flex;
gap:10px;
flex-wrap:wrap;
}
.chip{
border:1px solid var(--stroke);
background: rgba(255,255,255,.04);
border-radius: 999px;
padding:10px 12px;
display:flex;
gap:10px;
align-items:center;
min-height:40px;
}
.chip .lbl{
font-family:var(--mono);
font-size:11px;
color:var(--muted2);
text-transform:uppercase;
letter-spacing:.03em;
}
.chip .val{
font-weight:750;
letter-spacing:-.01em;
color:rgba(255,255,255,.86);
font-size:14px;
white-space:nowrap;
}
.chartWrap{
border:1px solid rgba(255,255,255,.10);
background: rgba(0,0,0,.18);
border-radius: var(--radius2);
padding:14px 14px 10px;
overflow:hidden;
position:relative;
}
.chartHead{
display:flex;
align-items:baseline;
justify-content:space-between;
gap:12px;
padding:0 2px 10px;
}
.chartHead .h{
font-weight:760;
letter-spacing:-.02em;
font-size:14px;
color:rgba(255,255,255,.88);
}
.chartHead .s{
font-family:var(--mono);
font-size:11px;
color:var(--muted2);
}
canvas{
width:100%;
height:220px;
display:block;
border-radius: 12px;
}
.right{
padding:20px;
display:grid;
grid-template-rows: auto 1fr auto;
gap:14px;
height:100%;
position:relative;
z-index:1;
}
.panelTitle{
display:flex;
justify-content:space-between;
align-items:baseline;
gap:12px;
padding:4px 2px 0;
}
.panelTitle .h{
font-weight:780;
letter-spacing:-.02em;
font-size:14px;
color:rgba(255,255,255,.88);
}
.panelTitle .hint{
font-family:var(--mono);
font-size:11px;
color:var(--muted2);
}
.hourly{
border:1px solid rgba(255,255,255,.10);
background: rgba(0,0,0,.16);
border-radius: var(--radius2);
overflow:hidden;
min-height:0;
display:grid;
grid-template-rows: auto 1fr;
}
.hourly .gridHead{
display:flex;
justify-content:space-between;
padding:12px 14px;
border-bottom:1px solid rgba(255,255,255,.08);
color:var(--muted2);
font-family:var(--mono);
font-size:11px;
letter-spacing:.02em;
text-transform:uppercase;
}
.scroller{
overflow:auto;
padding:8px;
scrollbar-width:thin;
scrollbar-color: rgba(255,255,255,.22) transparent;
}
.scroller::-webkit-scrollbar{ width:10px }
.scroller::-webkit-scrollbar-thumb{ background: rgba(255,255,255,.16); border-radius:999px; border:3px solid transparent; background-clip: content-box;}
.scroller::-webkit-scrollbar-track{ background: transparent }
.hgrid{
display:grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap:10px;
padding:6px;
}
.hrow{
border:1px solid rgba(255,255,255,.10);
background: rgba(255,255,255,.03);
border-radius: 14px;
padding:10px 12px;
display:flex;
justify-content:space-between;
align-items:baseline;
gap:12px;
}
.hrow .t{
font-family:var(--mono);
font-size:12px;
color:rgba(255,255,255,.78);
letter-spacing:.02em;
}
.hrow .p{
font-weight:820;
letter-spacing:-.02em;
font-size:14px;
color:rgba(255,255,255,.90);
}
.hrow .p span{
color:var(--muted2);
font-weight:700;
font-family:var(--mono);
font-size:12px;
margin-left:6px;
letter-spacing:.02em;
}
.footer{
display:flex;
justify-content:space-between;
align-items:center;
gap:12px;
padding:4px 2px 0;
color:var(--muted2);
font-family:var(--mono);
font-size:11px;
}
.status{
display:flex;
align-items:center;
gap:10px;
padding:10px 12px;
border:1px solid rgba(255,255,255,.10);
background: rgba(0,0,0,.16);
border-radius: 999px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
max-width: 100%;
}
.spinner{
width:14px; height:14px;
border-radius:999px;
border:2px solid rgba(255,255,255,.18);
border-top-color: rgba(255,255,255,.72);
animation: spin .9s linear infinite;
flex:0 0 auto;
}
@keyframes spin{to{transform:rotate(360deg)}}
.err{
border-color: rgba(251,113,133,.26);
background: rgba(251,113,133,.08);
}
.ok{
border-color: rgba(52,211,153,.22);
background: rgba(52,211,153,.07);
}
.skeleton{
position:relative;
overflow:hidden;
}
.skeleton:after{
content:"";
position:absolute; inset:-40px;
background: linear-gradient(90deg, transparent, rgba(255,255,255,.10), transparent);
transform: translateX(-50%);
animation: shimmer 1.2s ease-in-out infinite;
}
@keyframes shimmer{
0%{transform: translateX(-60%)}
100%{transform: translateX(60%)}
}
.mute{ color: var(--muted2) }
.hidden{ display:none !important }
@media (prefers-reduced-motion: reduce){
.spinner{ animation:none }
.skeleton:after{ animation:none }
}
</style>
</head>
<body>
<div class="stage">
<div class="wrap">
<header>
<div class="brand">
<div class="title">Weather Card</div>
<div class="sub"><span class="dot"></span><span id="subtitle">Open‑Meteo compatible • UTC</span></div>
</div>
<div class="pillrow">
<div class="pill" title="Location parameters">
<div class="k">LAT/LON</div>
<div class="v" id="pillCoords" class="skeleton">—</div>
</div>
<div class="pill" title="Requested date">
<div class="k">DATE</div>
<div class="v" id="pillDate" class="skeleton">—</div>
</div>
</div>
</header>
<main>
<section class="card left" aria-label="Daily summary">
<div class="topline">
<div class="place">
<div id="locName" class="name skeleton" style="width: min(520px, 100%);">Loading…</div>
<div class="meta">
<span class="tag" title="Date (UTC)"><b id="dateLabel" class="skeleton">—</b></span>
<span class="tag" title="Coordinates"><b id="coordLabel" class="skeleton">—</b></span>
</div>
</div>
<div class="condbox">
<svg class="icon" viewBox="0 0 120 120" fill="none" aria-hidden="true">
<defs>
<linearGradient id="gSun" x1="20" y1="16" x2="92" y2="96" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFD166" stop-opacity=".95"/>
<stop offset="1" stop-color="#FF4D6D" stop-opacity=".85"/>
</linearGradient>
<linearGradient id="gSky" x1="18" y1="26" x2="104" y2="106" gradientUnits="userSpaceOnUse">
<stop stop-color="#7C5CFF" stop-opacity=".95"/>
<stop offset="1" stop-color="#22D3EE" stop-opacity=".70"/>
</linearGradient>
</defs>
<g id="iconGroup"></g>
</svg>
<div class="condtext">
<div id="condMain" class="main skeleton" style="width: 180px;">—</div>
<div id="condSub" class="sub skeleton" style="width: 220px;">—</div>
</div>
</div>
</div>
<div class="temps">
<div class="hiLo">
<div class="range">
<div class="big"><span id="tMax" class="skeleton">—</span><span class="unit">°C</span></div>
<div class="small">/ <span id="tMin" class="skeleton">—</span><span class="unit">°C</span></div>
</div>
<div class="chips">
<div class="chip">
<div class="lbl">High</div>
<div class="val"><span id="chipHigh" class="skeleton">—</span><span class="unit">°C</span></div>
</div>
<div class="chip">
<div class="lbl">Low</div>
<div class="val"><span id="chipLow" class="skeleton">—</span><span class="unit">°C</span></div>
</div>
<div class="chip">
<div class="lbl">Code</div>
<div class="val"><span id="chipCode" class="skeleton">—</span></div>
</div>
</div>
</div>
<div class="chartWrap" aria-label="Hourly temperature chart">
<div class="chartHead">
<div class="h">Hourly temperature</div>
<div class="s" id="chartRange" class="skeleton">—</div>
</div>
<canvas id="chart" width="980" height="220"></canvas>
</div>
</div>
</section>
<aside class="card right" aria-label="Hourly temperatures list">
<div class="panelTitle">
<div class="h">Hourly details</div>
<div class="hint" id="hourlyHint" class="skeleton">—</div>
</div>
<div class="hourly">
<div class="gridHead">
<div>Time (UTC)</div>
<div>Temp (°C)</div>
</div>
<div class="scroller" id="hourlyScroll">
<div class="hgrid" id="hourlyGrid" aria-live="polite"></div>
</div>
</div>
<div class="footer">
<div class="status" id="statusPill" aria-live="polite">
<span class="spinner" id="spin"></span>
<span id="statusText">Loading weather data…</span>
</div>
<div id="sourceText">Source: <span class="mute">same‑origin Open‑Meteo API</span></div>
</div>
</aside>
</main>
</div>
</div>
<script>
(function(){
const $ = (id)=>document.getElementById(id);
const els = {
pillCoords: $("pillCoords"),
pillDate: $("pillDate"),
locName: $("locName"),
dateLabel: $("dateLabel"),
coordLabel: $("coordLabel"),
condMain: $("condMain"),
condSub: $("condSub"),
tMax: $("tMax"),
tMin: $("tMin"),
chipHigh: $("chipHigh"),
chipLow: $("chipLow"),
chipCode: $("chipCode"),
hourlyHint: $("hourlyHint"),
hourlyGrid: $("hourlyGrid"),
statusPill: $("statusPill"),
statusText: $("statusText"),
spin: $("spin"),
chart: $("chart"),
chartRange: $("chartRange"),
iconGroup: $("iconGroup"),
};
function todayUTC(){
return new Date().toISOString().slice(0,10);
}
function validDate(s){
return typeof s === "string" && /^\d{4}-\d{2}-\d{2}$/.test(s);
}
function parseNum(v, fallback){
const n = Number(v);
return Number.isFinite(n) ? n : fallback;
}
function fmtDateLong(yyyyMmDd){
const d = new Date(yyyyMmDd + "T00:00:00Z");
try{
return new Intl.DateTimeFormat(undefined, {
weekday:"short", year:"numeric", month:"short", day:"2-digit", timeZone:"UTC"
}).format(d) + " (UTC)";
}catch{
return yyyyMmDd + " (UTC)";
}
}
function fmtTemp(t){
if (!Number.isFinite(t)) return "—";
const r = Math.round(t * 10) / 10;
return (Math.abs(r) >= 10 ? r.toFixed(0) : r.toFixed(1)).replace(/\.0$/,"");
}
function setLoading(on){
const sk = document.querySelectorAll(".skeleton");
sk.forEach(el=>{
if (on) el.classList.add("skeleton");
else el.classList.remove("skeleton");
});
els.spin.classList.toggle("hidden", !on);
}
function status(kind, text){
els.statusText.textContent = text;
els.statusPill.classList.remove("err","ok");
if (kind === "error") els.statusPill.classList.add("err");
if (kind === "ok") els.statusPill.classList.add("ok");
}
function weatherInfo(code){
const c = Number(code);
const map = [
{ codes:[0], label:"Clear sky", detail:"Best visibility • crisp and bright", icon:"clear" },
{ codes:[1], label:"Mainly clear", detail:"Light clouds • mostly sunny", icon:"partly" },
{ codes:[2], label:"Partly cloudy", detail:"Sun and clouds • variable cover", icon:"partly" },
{ codes:[3], label:"Overcast", detail:"Cloudy skies • muted light", icon:"cloud" },
{ codes:[45,48], label:"Fog", detail:"Low visibility • haze and mist", icon:"fog" },
{ codes:[51,53,55], label:"Drizzle", detail:"Light rain • intermittent drops", icon:"drizzle" },
{ codes:[56,57], label:"Freezing drizzle", detail:"Icy drizzle • slippery surfaces", icon:"drizzle" },
{ codes:[61,63,65], label:"Rain", detail:"Steady rain • carry an umbrella", icon:"rain" },
{ codes:[66,67], label:"Freezing rain", detail:"Icy rain • hazardous conditions", icon:"rain" },
{ codes:[71,73,75], label:"Snow", detail:"Snowfall • cold and quiet", icon:"snow" },
{ codes:[77], label:"Snow grains", detail:"Fine snow • reduced visibility", icon:"snow" },
{ codes:[80,81,82], label:"Rain showers", detail:"Showers • bursts of rain", icon:"rain" },
{ codes:[85,86], label:"Snow showers", detail:"Snow showers • on and off", icon:"snow" },
{ codes:[95], label:"Thunderstorm", detail:"Thunder • keep safe outdoors", icon:"thunder" },
{ codes:[96,99], label:"Thunderstorm (hail)", detail:"Storm + hail • seek shelter", icon:"thunder" },
];
for (const g of map){
if (g.codes.includes(c)) return { code:c, label:g.label, detail:g.detail, icon:g.icon };
}
return { code:c, label:"Unknown conditions", detail:"Weather code not recognized", icon:"cloud" };
}
function drawIcon(kind){
const g = els.iconGroup;
g.innerHTML = "";
const svg = {
clear: `
<circle cx="60" cy="58" r="22" fill="url(#gSun)" opacity=".95"/>
<g opacity=".78" stroke="url(#gSun)" stroke-width="5" stroke-linecap="round">
<line x1="60" y1="18" x2="60" y2="6"/>
<line x1="60" y1="110" x2="60" y2="98"/>
<line x1="20" y1="58" x2="8" y2="58"/>
<line x1="112" y1="58" x2="100" y2="58"/>
<line x1="33" y1="31" x2="24" y2="22"/>
<line x1="96" y1="94" x2="87" y2="85"/>
<line x1="33" y1="85" x2="24" y2="94"/>
<line x1="96" y1="22" x2="87" y2="31"/>
</g>
`,
partly: `
<circle cx="46" cy="50" r="18" fill="url(#gSun)" opacity=".92"/>
<g opacity=".72" stroke="url(#gSun)" stroke-width="4" stroke-linecap="round">
<line x1="46" y1="22" x2="46" y2="12"/>
<line x1="46" y1="88" x2="46" y2="78"/>
<line x1="18" y1="50" x2="8" y2="50"/>
<line x1="84" y1="50" x2="74" y2="50"/>
<line x1="27" y1="31" x2="20" y2="24"/>
<line x1="72" y1="76" x2="65" y2="69"/>
<line x1="27" y1="69" x2="20" y2="76"/>
<line x1="72" y1="24" x2="65" y2="31"/>
</g>
<path d="M36 84c0-10 8-18 18-18 7 0 13 3 16 8 2-1 5-2 8-2 9 0 16 7 16 16 0 9-7 16-16 16H54c-10 0-18-8-18-18z"
fill="url(#gSky)" opacity=".85"/>
`,
cloud: `
<path d="M30 82c0-12 10-22 22-22 9 0 17 5 20 13 3-2 7-3 11-3 12 0 22 10 22 22s-10 22-22 22H52c-12 0-22-10-22-22z"
fill="url(#gSky)" opacity=".88"/>
<path d="M42 80c0-8 6-14 14-14 6 0 11 3 13 8 2-1 4-1 6-1 8 0 14 6 14 14s-6 14-14 14H56c-8 0-14-6-14-14z"
fill="rgba(255,255,255,.12)"/>
`,
fog: `
<path d="M30 78c0-12 10-22 22-22 9 0 17 5 20 13 3-2 7-3 11-3 12 0 22 10 22 22s-10 22-22 22H52c-12 0-22-10-22-22z"
fill="url(#gSky)" opacity=".72"/>
<g stroke="rgba(255,255,255,.38)" stroke-width="5" stroke-linecap="round" opacity=".85">
<line x1="26" y1="98" x2="94" y2="98"/>
<line x1="18" y1="110" x2="102" y2="110"/>
</g>
`,
drizzle: `
<path d="M30 76c0-12 10-22 22-22 9 0 17 5 20 13 3-2 7-3 11-3 12 0 22 10 22 22s-10 22-22 22H52c-12 0-22-10-22-22z"
fill="url(#gSky)" opacity=".82"/>
<g stroke="rgba(34,211,238,.95)" stroke-width="5" stroke-linecap="round" opacity=".9">
<line x1="44" y1="100" x2="40" y2="110"/>
<line x1="64" y1="100" x2="60" y2="110"/>
<line x1="84" y1="100" x2="80" y2="110"/>
</g>
`,
rain: `
<path d="M30 74c0-12 10-22 22-22 9 0 17 5 20 13 3-2 7-3 11-3 12 0 22 10 22 22s-10 22-22 22H52c-12 0-22-10-22-22z"
fill="url(#gSky)" opacity=".84"/>
<g stroke="rgba(34,211,238,.95)" stroke-width="5" stroke-linecap="round" opacity=".95">
<line x1="40" y1="98" x2="34" y2="114"/>
<line x1="58" y1="98" x2="52" y2="114"/>
<line x1="76" y1="98" x2="70" y2="114"/>
<line x1="94" y1="98" x2="88" y2="114"/>
</g>
`,
snow: `
<path d="M30 74c0-12 10-22 22-22 9 0 17 5 20 13 3-2 7-3 11-3 12 0 22 10 22 22s-10 22-22 22H52c-12 0-22-10-22-22z"
fill="url(#gSky)" opacity=".82"/>
<g stroke="rgba(255,255,255,.85)" stroke-width="4" stroke-linecap="round" opacity=".95">
<line x1="44" y1="102" x2="44" y2="116"/>
<line x1="38" y1="109" x2="50" y2="109"/>
<line x1="40" y1="105" x2="48" y2="113"/>
<line x1="48" y1="105" x2="40" y2="113"/>
<line x1="76" y1="102" x2="76" y2="116"/>
<line x1="70" y1="109" x2="82" y2="109"/>
<line x1="72" y1="105" x2="80" y2="113"/>
<line x1="80" y1="105" x2="72" y2="113"/>
</g>
`,
thunder: `
<path d="M30 74c0-12 10-22 22-22 9 0 17 5 20 13 3-2 7-3 11-3 12 0 22 10 22 22s-10 22-22 22H52c-12 0-22-10-22-22z"
fill="url(#gSky)" opacity=".80"/>
<path d="M62 90l-10 18h10l-6 14 20-24H66l8-8H62z"
fill="#FBBF24" opacity=".95"/>
<g stroke="rgba(34,211,238,.92)" stroke-width="5" stroke-linecap="round" opacity=".9">
<line x1="38" y1="98" x2="32" y2="114"/>
<line x1="94" y1="98" x2="88" y2="114"/>
</g>
`
};
g.innerHTML = svg[kind] || svg.cloud;
}
function buildHourlyGrid(items){
els.hourlyGrid.innerHTML = "";
for (const it of items){
const row = document.createElement("div");
row.className = "hrow";
const t = document.createElement("div");
t.className = "t";
t.textContent = it.hhmm;
const p = document.createElement("div");
p.className = "p";
p.innerHTML = `${fmtTemp(it.temp)}<span>°C</span>`;
row.appendChild(t);
row.appendChild(p);
els.hourlyGrid.appendChild(row);
}
}
function drawChart(items){
const canvas = els.chart;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const dpr = Math.max(1, Math.min(2.5, window.devicePixelRatio || 1));
const cssW = canvas.clientWidth || 980;
const cssH = canvas.clientHeight || 220;
canvas.width = Math.round(cssW * dpr);
canvas.height = Math.round(cssH * dpr);
ctx.setTransform(dpr,0,0,dpr,0,0);
const W = cssW, H = cssH;
const pad = {l: 10, r: 10, t: 10, b: 18};
const innerW = W - pad.l - pad.r;
const innerH = H - pad.t - pad.b;
ctx.clearRect(0,0,W,H);
// background grid
ctx.globalAlpha = 1;
ctx.strokeStyle = "rgba(255,255,255,.08)";
ctx.lineWidth = 1;
for (let i=0;i<=4;i++){
const y = pad.t + innerH * (i/4);
ctx.beginPath();
ctx.moveTo(pad.l, y);
ctx.lineTo(W - pad.r, y);
ctx.stroke();
}
for (let i=0;i<=6;i++){
const x = pad.l + innerW * (i/6);
ctx.beginPath();
ctx.moveTo(x, pad.t);
ctx.lineTo(x, pad.t + innerH);
ctx.stroke();
}
const temps = items.map(x=>x.temp).filter(Number.isFinite);
if (!temps.length) return;
let tMin = Math.min(...temps);
let tMax = Math.max(...temps);
const span = Math.max(1, tMax - tMin);
const margin = span < 6 ? 2 : Math.min(4, span * 0.18);
tMin -= margin;
tMax += margin;
els.chartRange.textContent = `${fmtTemp(Math.min(...temps))}°C → ${fmtTemp(Math.max(...temps))}°C`;
const xAt = (i)=> pad.l + (innerW * (i/(items.length-1 || 1)));
const yAt = (temp)=> pad.t + innerH * (1 - ((temp - tMin) / (tMax - tMin)));
// area fill
ctx.beginPath();
items.forEach((it, i)=>{
const x = xAt(i);
const y = yAt(it.temp);
if (i===0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
});
ctx.lineTo(pad.l + innerW, pad.t + innerH);
ctx.lineTo(pad.l, pad.t + innerH);
ctx.closePath();
const grad = ctx.createLinearGradient(0, pad.t, 0, pad.t + innerH);
grad.addColorStop(0, "rgba(124,92,255,.28)");
grad.addColorStop(.6, "rgba(34,211,238,.10)");
grad.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = grad;
ctx.fill();
// line
ctx.beginPath();
items.forEach((it, i)=>{
const x = xAt(i);
const y = yAt(it.temp);
if (i===0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
});
ctx.lineWidth = 3;
ctx.strokeStyle = "rgba(255,255,255,.82)";
ctx.shadowColor = "rgba(0,0,0,.35)";
ctx.shadowBlur = 10;
ctx.stroke();
ctx.shadowBlur = 0;
// points + labels every 3 hours
ctx.fillStyle = "rgba(34,211,238,.95)";
ctx.strokeStyle = "rgba(255,255,255,.55)";
ctx.lineWidth = 2;
const step = Math.max(1, Math.round(items.length / 8));
for (let i=0;i<items.length;i++){
if (i % step !== 0 && i !== items.length-1) continue;
const x = xAt(i);
const y = yAt(items[i].temp);
ctx.beginPath();
ctx.arc(x, y, 4.2, 0, Math.PI*2);
ctx.fill();
ctx.beginPath();
ctx.arc(x, y, 7.4, 0, Math.PI*2);
ctx.stroke();
ctx.font = "11px " + getComputedStyle(document.body).fontFamily;
ctx.fillStyle = "rgba(255,255,255,.78)";
ctx.textAlign = "center";
ctx.fillText(items[i].hhmm.slice(0,2), x, pad.t + innerH + 14);
ctx.fillStyle = "rgba(255,255,255,.88)";
ctx.fillText(fmtTemp(items[i].temp), x, Math.max(14, y - 10));
ctx.fillStyle = "rgba(34,211,238,.95)";
}
}
function stripSkeleton(){
document.querySelectorAll(".skeleton").forEach(el=>el.classList.remove("skeleton"));
}
async function run(){
setLoading(true);
const qs = new URLSearchParams(location.search);
const lat = parseNum(qs.get("lat"), 52.52);
const lon = parseNum(qs.get("lon"), 13.405);
const name = (qs.get("name") || "Berlin").trim() || "Berlin";
const dateRaw = qs.get("date");
const date = validDate(dateRaw) ? dateRaw : todayUTC();
const today = todayUTC();
const isPast = date < today;
els.pillCoords.textContent = `${lat.toFixed(3)}, ${lon.toFixed(3)}`;
els.pillDate.textContent = date;
els.locName.textContent = name;
els.dateLabel.textContent = fmtDateLong(date);
els.coordLabel.textContent = `${lat.toFixed(3)}°, ${lon.toFixed(3)}°`;
els.hourlyHint.textContent = `${date} • UTC`;
drawIcon("cloud");
const endpoint = isPast ? "/api/om/archive" : "/api/om/forecast";
const params = new URLSearchParams({
latitude: String(lat),
longitude: String(lon),
daily: "temperature_2m_max,temperature_2m_min,weather_code",
hourly: "temperature_2m",
timezone: "UTC",
temperature_unit: "celsius",
start_date: date,
end_date: date
});
const url = `${endpoint}?${params.toString()}`;
try{
const res = await fetch(url, { headers: { "Accept": "application/json" } });
if (!res.ok){
throw new Error(`HTTP ${res.status}`);
}
const data = await res.json();
const daily = data && data.daily;
const hourly = data && data.hourly;
if (!daily || !hourly || !Array.isArray(daily.time) || !Array.isArray(hourly.time)){
throw new Error("Malformed response");
}
const di = daily.time.indexOf(date);
if (di < 0){
throw new Error("Requested date not found in daily data");
}
const tmax = Number(daily.temperature_2m_max?.[di]);
const tmin = Number(daily.temperature_2m_min?.[di]);
const wcode = Number(daily.weather_code?.[di]);
if (!Number.isFinite(tmax) || !Number.isFinite(tmin) || !Number.isFinite(wcode)){
throw new Error("Missing daily values");
}
const wi = weatherInfo(wcode);
els.condMain.textContent = wi.label;
els.condSub.textContent = wi.detail;
els.chipCode.textContent = String(wi.code);
drawIcon(wi.icon);
els.tMax.textContent = fmtTemp(tmax);
els.tMin.textContent = fmtTemp(tmin);
els.chipHigh.textContent = fmtTemp(tmax);
els.chipLow.textContent = fmtTemp(tmin);
const times = hourly.time;
const temps = hourly.temperature_2m;
if (!Array.isArray(temps) || times.length !== temps.length){
throw new Error("Hourly arrays mismatch");
}
const items = [];
for (let i=0;i<times.length;i++){
const ts = String(times[i]);
if (ts.startsWith(date)){
const hhmm = ts.slice(11,16) || "??:??";
items.push({ hhmm, temp: Number(temps[i]) });
}
}
if (!items.length){
throw new Error("No hourly data for requested date");
}
const tempsOnly = items.map(x=>x.temp).filter(Number.isFinite);
const lo = Math.min(...tempsOnly);
const hi = Math.max(...tempsOnly);
els.hourlyHint.textContent = `${items.length} points • ${fmtTemp(lo)}°C → ${fmtTemp(hi)}°C`;
buildHourlyGrid(items);
drawChart(items);
stripSkeleton();
status("ok", "Loaded.");
setLoading(false);
}catch(err){
stripSkeleton();
setLoading(false);
status("error", "Weather data could not be loaded.");
els.condMain.textContent = "Unavailable";
els.condSub.textContent = "Weather data could not be loaded.";
els.tMax.textContent = "—";
els.tMin.textContent = "—";
els.chipHigh.textContent = "—";
els.chipLow.textContent = "—";
els.chipCode.textContent = "—";
els.hourlyHint.textContent = date + " • UTC";
els.chartRange.textContent = "—";
els.hourlyGrid.innerHTML = "";
const msg = document.createElement("div");
msg.style.padding = "14px";
msg.style.color = "rgba(255,255,255,.78)";
msg.style.fontFamily = getComputedStyle(document.body).fontFamily;
msg.innerHTML = `<div style="font-weight:780; letter-spacing:-.02em; margin-bottom:6px;">Weather data could not be loaded.</div>
<div style="color: rgba(255,255,255,.55); font-family: ${getComputedStyle(document.body).fontFamily};">Check parameters or try again later.</div>`;
els.hourlyGrid.appendChild(msg);
try{
const ctx = els.chart.getContext("2d");
if (ctx){
ctx.clearRect(0,0,els.chart.width,els.chart.height);
ctx.setTransform(1,0,0,1,0,0);
}
}catch{}
}
}
// Ensure initial skeleton styles are visible even if text is set quickly
requestAnimationFrame(run);
window.addEventListener("resize", ()=> {
// redraw chart if data exists
try{
const rows = els.hourlyGrid.querySelectorAll(".hrow");
if (rows && rows.length){
// Reconstruct items from DOM if needed (best-effort)
const items = [];
rows.forEach(r=>{
const t = r.querySelector(".t")?.textContent || "";
const p = r.querySelector(".p")?.textContent || "";
const n = Number(String(p).replace(/[^\d\.\-]/g,""));
if (t && Number.isFinite(n)) items.push({hhmm:t, temp:n});
});
if (items.length >= 2) drawChart(items);
}
}catch{}
});
})();
</script>
</body>
</html>L1 — cheap deterministic descriptors
| bytes total | 37,097 | html / css / js | 5,004 / 12,514 / 19,579 |
|---|---|---|---|
| dom nodes | 92 | dom depth | 12 |
| css rules | 78 | js present | yes |
| brightness | 39.6 | contrast | 18.9 |
| colorfulness | 24.9 | whitespace | 64.6% |
This slot's telemetry
| prompt tokens | 17,654 | completion tokens | 12,397 |
|---|---|---|---|
| total tokens | 30,051 | wall | 165.7 s |
| cost | — | request id | — |
config.json556 B
{
"N": 2,
"auth": {
"credential_ref": "WCB_NONE",
"method": "oauth-login"
},
"billing": "plan",
"config_id": "gpt-5.2-eff-high--cli--cursor--dev",
"effort": "high",
"family": "gpt",
"m": {
"min": 2,
"q": 2
},
"model_id": "gpt-5.2",
"protocol": "cli",
"served_model": "gpt-5.2-high",
"telemetry": {
"completion_tokens": 41303,
"cost_usd": null,
"prompt_tokens": 35406,
"total_tokens": 76709,
"wall_ms": 511570
},
"transport": "cursor-agent-cli-isolated-home",
"vendor_sanction_ref": null
}send-log2.5 KB
{
"N": 2,
"batch_id": "2026-08-13--cursor-s0",
"config_id": "gpt-5.2-eff-high--cli--cursor--dev",
"positions": [
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-08-13T01:09:31.396551+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:08:06.383778+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-13T01:12:20.448476+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:09:34.700028+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-13T01:14:59.939021+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:12:24.617364+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-13T01:16:49.826891+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:15:04.340792+00:00"
}
],
"block_index": 1,
"model_reaching_attempt_index": 0,
"slot_index": 1,
"terminal_state": "valid",
"variant": "P-min"
}
],
"retry_policy": {
"max_unreachable_retries": 5,
"rate_limit_backoff": {
"max_attempts": 4,
"max_total_ms": 60000
}
}
}