gpt-5.4-mini @ xhigh · cursor
cursorxhigh
- config
- gpt-5.4-mini-eff-xhigh--cli--cursor--dev
- batch
- 2026-07-19--unified
- transport
- cursor-agent-cli-isolated-home
- protocol
- cli · plan
- served model
- gpt-5.4-mini-xhigh
- 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 neighbors
nearest
gpt-5.4-mini @high · api0.73gpt-5.4-mini @medium · api0.72gpt-5.6-sol @high · cursor0.72gpt-5.4-mini @high · codex-oauth0.72gpt-5.4-mini @high · cursor0.72farthest
north-mini-code-free · api0.48claude-haiku-4-5 @max · CC0.49claude-sonnet-4 · cursor0.49claude-sonnet-4 · kiro0.49claude-sonnet-4-5-thinking · cursor-xl0.50within session 2026-07-19--unified
similarity measures convergence within this session — not quality.
Fidelity — does the card show the right data?
- namematch
- conditionmatch
- datematch
- max tempambiguousinsufficient-distinct-temperature-nodes
- min tempambiguousinsufficient-distinct-temperature-nodes
- hourlyambiguouscoverage · 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">
<meta name="color-scheme" content="dark">
<title>Weather Card</title>
<style>
:root {
color-scheme: dark;
--accent-rgb: 106, 191, 255;
--accent-2-rgb: 88, 118, 255;
--text: #f5f8ff;
--muted: rgba(232, 241, 255, 0.66);
--muted-strong: rgba(232, 241, 255, 0.86);
--line: rgba(255, 255, 255, 0.10);
}
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
body {
min-height: 100%;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: var(--text);
position: relative;
overflow: hidden;
background:
radial-gradient(circle at 15% 12%, rgba(var(--accent-rgb), 0.22), transparent 26%),
radial-gradient(circle at 86% 14%, rgba(var(--accent-2-rgb), 0.18), transparent 24%),
radial-gradient(circle at 55% 86%, rgba(255, 255, 255, 0.06), transparent 28%),
linear-gradient(140deg, #050913 0%, #0b1325 48%, #08111c 100%);
}
body::before,
body::after {
content: "";
position: fixed;
pointer-events: none;
z-index: 0;
filter: blur(42px);
opacity: 0.8;
}
body::before {
width: 34vw;
height: 34vw;
left: -10vw;
top: -9vw;
background: radial-gradient(circle, rgba(var(--accent-rgb), 0.20), transparent 72%);
}
body::after {
width: 36vw;
height: 36vw;
right: -12vw;
bottom: -14vw;
background: radial-gradient(circle, rgba(var(--accent-2-rgb), 0.12), transparent 72%);
}
.shell {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: grid;
place-items: center;
padding: 24px;
}
.card {
position: relative;
width: min(1192px, calc(100vw - 48px));
height: min(744px, calc(100vh - 48px));
padding: 28px;
border-radius: 38px;
overflow: hidden;
isolation: isolate;
background: linear-gradient(180deg, rgba(14, 20, 36, 0.92), rgba(8, 12, 22, 0.96));
border: 1px solid rgba(255, 255, 255, 0.10);
box-shadow:
0 30px 80px rgba(0, 0, 0, 0.50),
inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.card::before,
.card::after {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
}
.card::before {
background:
radial-gradient(circle at 18% 0%, rgba(var(--accent-rgb), 0.18), transparent 42%),
radial-gradient(circle at 86% 14%, rgba(var(--accent-2-rgb), 0.12), transparent 38%),
linear-gradient(180deg, rgba(255, 255, 255, 0.05), transparent 22%);
}
.card::after {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.04), transparent 30%, rgba(255, 255, 255, 0.02));
mix-blend-mode: screen;
opacity: 0.4;
}
#content {
position: relative;
z-index: 1;
height: 100%;
display: flex;
flex-direction: column;
gap: 18px;
min-height: 0;
}
.top {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 20px;
}
.eyebrow {
font-size: 11px;
letter-spacing: 0.24em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 10px;
}
h1 {
margin: 0;
max-width: 760px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: clamp(40px, 4.6vw, 58px);
line-height: 0.94;
letter-spacing: -0.06em;
font-weight: 700;
}
.subline {
margin-top: 12px;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px;
color: var(--muted);
font-size: 14px;
}
.subline .dot {
width: 4px;
height: 4px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.35);
}
.status {
display: inline-flex;
align-items: center;
gap: 10px;
flex: 0 0 auto;
padding: 12px 16px;
border-radius: 999px;
background: rgba(var(--accent-rgb), 0.12);
border: 1px solid rgba(var(--accent-rgb), 0.28);
color: #eef8ff;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.01em;
white-space: nowrap;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.status::before {
content: "";
width: 8px;
height: 8px;
border-radius: 999px;
background: #fff;
box-shadow: 0 0 0 6px rgba(var(--accent-rgb), 0.10);
}
.hero {
display: grid;
grid-template-columns: minmax(0, 1.1fr) 320px;
gap: 20px;
align-items: stretch;
min-height: 0;
}
.summary {
padding-top: 6px;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 0;
}
.range {
display: flex;
align-items: flex-end;
gap: 12px;
font-variant-numeric: tabular-nums;
}
.max {
font-size: clamp(72px, 7.8vw, 92px);
line-height: 0.9;
letter-spacing: -0.09em;
font-weight: 700;
}
.slash {
padding-bottom: 12px;
font-size: 56px;
line-height: 1;
color: rgba(255, 255, 255, 0.24);
}
.min {
padding-bottom: 10px;
font-size: clamp(42px, 5vw, 56px);
line-height: 0.95;
letter-spacing: -0.06em;
color: rgba(255, 255, 255, 0.74);
}
.range-caption {
margin-top: 8px;
font-size: 12px;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--muted-strong);
}
.condition {
margin-top: 14px;
font-size: 28px;
line-height: 1.06;
font-weight: 600;
letter-spacing: -0.03em;
}
.support {
margin-top: 8px;
max-width: 620px;
color: var(--muted);
font-size: 15px;
line-height: 1.45;
}
.chips {
margin-top: 18px;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.chip {
padding: 9px 12px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.08);
color: var(--muted-strong);
font-size: 13px;
white-space: nowrap;
}
.visual {
position: relative;
overflow: hidden;
border-radius: 28px;
padding: 18px 18px 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
min-height: 170px;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.035));
border: 1px solid rgba(255, 255, 255, 0.09);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.visual::before {
content: "";
position: absolute;
inset: 0;
background:
radial-gradient(circle at 50% 18%, rgba(var(--accent-rgb), 0.18), transparent 56%),
radial-gradient(circle at 50% 80%, rgba(var(--accent-2-rgb), 0.14), transparent 62%);
pointer-events: none;
}
.visual > * {
position: relative;
z-index: 1;
}
.visual-art {
width: 220px;
max-width: 100%;
height: 128px;
display: grid;
place-items: center;
}
.visual-art svg {
width: 100%;
height: 100%;
overflow: visible;
filter: drop-shadow(0 14px 26px rgba(0, 0, 0, 0.30));
}
.visual-kicker {
margin-top: 4px;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.24em;
color: var(--muted);
}
.visual-title {
margin-top: 5px;
font-size: 24px;
font-weight: 700;
line-height: 1.08;
letter-spacing: -0.03em;
}
.visual-sub {
margin-top: 6px;
font-size: 13px;
color: var(--muted);
}
.hourly-section {
display: flex;
flex-direction: column;
gap: 14px;
min-height: 0;
}
.section-head {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 20px;
}
.section-head h2 {
margin: 0;
font-size: 18px;
line-height: 1.12;
letter-spacing: -0.02em;
}
.section-head p {
margin: 5px 0 0;
font-size: 13px;
color: var(--muted);
}
.range-note {
font-size: 13px;
color: var(--muted);
text-align: right;
}
.chart-card {
position: relative;
height: 130px;
border-radius: 24px;
overflow: hidden;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.025));
border: 1px solid rgba(255, 255, 255, 0.08);
padding: 12px 14px 10px;
}
.chart-card::before {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
background:
radial-gradient(circle at 50% 0%, rgba(var(--accent-rgb), 0.14), transparent 55%),
linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 50%);
}
.chart-card svg {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: block;
}
.chart-card line {
stroke: rgba(255, 255, 255, 0.08);
stroke-width: 1;
shape-rendering: geometricPrecision;
}
.chart-card path.area {
opacity: 0.94;
}
.chart-card path.line {
fill: none;
stroke-width: 4.5;
stroke-linecap: round;
stroke-linejoin: round;
}
.chart-card circle {
fill: #fff;
fill-opacity: 0.92;
stroke: rgba(var(--accent-rgb), 0.7);
stroke-width: 1.5;
}
.hourly-grid {
display: grid;
grid-template-columns: repeat(8, minmax(0, 1fr));
gap: 10px;
min-height: 0;
}
.hour {
position: relative;
aspect-ratio: 1.92 / 1;
min-height: 66px;
padding: 10px 11px 11px;
border-radius: 18px;
overflow: hidden;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.035));
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
.hour::before {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
background: radial-gradient(circle at 20% 0%, rgba(var(--accent-rgb), 0.08), transparent 60%);
}
.hour .time {
position: relative;
z-index: 1;
font-size: 12px;
color: var(--muted);
}
.hour .temp {
position: absolute;
right: 11px;
top: 10px;
z-index: 1;
font-size: 16px;
font-weight: 700;
letter-spacing: -0.03em;
font-variant-numeric: tabular-nums;
}
.hour .track {
position: absolute;
left: 11px;
right: 11px;
bottom: 11px;
height: 5px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.08);
}
.hour .fill {
position: absolute;
left: 11px;
bottom: 11px;
height: 5px;
border-radius: 999px;
background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.65), rgba(var(--accent-2-rgb), 0.95));
box-shadow: 0 0 16px rgba(var(--accent-rgb), 0.22);
}
#errorState {
position: absolute;
inset: 0;
z-index: 2;
display: grid;
place-items: center;
padding: 28px;
}
#errorState[hidden] {
display: none;
}
.error-card {
width: min(520px, 100%);
padding: 32px 28px;
border-radius: 28px;
text-align: center;
background: linear-gradient(180deg, rgba(19, 24, 40, 0.92), rgba(10, 14, 24, 0.94));
border: 1px solid rgba(255, 255, 255, 0.10);
box-shadow:
0 28px 60px rgba(0, 0, 0, 0.35),
inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.error-title {
font-size: 28px;
line-height: 1.08;
font-weight: 700;
letter-spacing: -0.04em;
margin: 0 0 12px;
}
.error-card p {
margin: 0;
color: var(--muted);
font-size: 15px;
line-height: 1.6;
}
@media (max-width: 1160px) {
.hero {
grid-template-columns: 1fr;
}
.hourly-grid {
grid-template-columns: repeat(6, minmax(0, 1fr));
}
.visual {
min-height: 150px;
}
}
</style>
</head>
<body>
<main class="shell">
<section class="card" aria-live="polite">
<div id="content">
<header class="top">
<div class="headline">
<div class="eyebrow">Weather card</div>
<h1 id="location" title="Berlin">Berlin</h1>
<div class="subline">
<span id="dateLabel">Loading date...</span>
<span class="dot" aria-hidden="true"></span>
<span id="coordsLabel">52.52° N · 13.41° E</span>
</div>
</div>
<div class="status" id="statusPill">Loading weather...</div>
</header>
<section class="hero">
<div class="summary">
<div>
<div class="range" aria-label="daily high and low">
<span id="maxTemp" class="max">--</span>
<span class="slash">/</span>
<span id="minTemp" class="min">--</span>
</div>
<div class="range-caption">High / Low °C</div>
<div class="condition" id="conditionText">Fetching weather data...</div>
<div class="support" id="supportText">The selected day is evaluated in UTC.</div>
</div>
<div class="chips">
<div class="chip" id="endpointChip">Source: auto</div>
<div class="chip" id="rangeChip">Hourly readings: pending</div>
<div class="chip">Timezone: UTC</div>
</div>
</div>
<div class="visual" id="visualPanel">
<div class="visual-art" id="iconWrap" style="color: rgb(106, 191, 255);">
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<g fill="#ffffff" opacity="0.96">
<circle cx="84" cy="84" r="20"></circle>
<circle cx="116" cy="72" r="28"></circle>
<circle cx="148" cy="84" r="21"></circle>
<rect x="68" y="84" width="104" height="28" rx="14"></rect>
</g>
</svg>
</div>
<div class="visual-copy">
<div class="visual-kicker">Condition</div>
<div class="visual-title" id="conditionPillText">Loading weather...</div>
<div class="visual-sub" id="codeLabel">Weather code --</div>
</div>
</div>
</section>
<section class="hourly-section">
<div class="section-head">
<div>
<h2>Hourly temperatures</h2>
<p id="chartHint">Loading hourly temperatures...</p>
</div>
<div class="range-note" id="rangeNote">--</div>
</div>
<div class="chart-card">
<svg id="chart" viewBox="0 0 1000 160" preserveAspectRatio="none" aria-hidden="true"></svg>
</div>
<div class="hourly-grid" id="hourlyGrid" aria-label="Hourly temperatures"></div>
</section>
</div>
<div id="errorState" hidden>
<div class="error-card" role="alert">
<div class="error-title">Unable to load weather data.</div>
<p id="errorDetail">The weather API request failed.</p>
</div>
</div>
</section>
</main>
<script>
(() => {
const qs = new URLSearchParams(location.search);
const defaultDate = new Date().toISOString().slice(0, 10);
function parseDate(value) {
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return defaultDate;
const parsed = new Date(`${value}T00:00:00Z`);
return Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== value ? defaultDate : value;
}
function parseNumber(value, fallback, min, max) {
const n = Number.parseFloat(value);
return Number.isFinite(n) && n >= min && n <= max ? n : fallback;
}
const state = {
lat: parseNumber(qs.get("lat"), 52.52, -90, 90),
lon: parseNumber(qs.get("lon"), 13.405, -180, 180),
name: (qs.get("name") || "Berlin").trim() || "Berlin",
date: parseDate(qs.get("date")),
today: defaultDate
};
const selectedDate = new Date(`${state.date}T00:00:00Z`);
const selectedDateLabel = new Intl.DateTimeFormat("en-GB", {
weekday: "long",
day: "numeric",
month: "long",
year: "numeric",
timeZone: "UTC"
}).format(selectedDate);
const dom = {
content: document.getElementById("content"),
errorState: document.getElementById("errorState"),
errorDetail: document.getElementById("errorDetail"),
location: document.getElementById("location"),
dateLabel: document.getElementById("dateLabel"),
coordsLabel: document.getElementById("coordsLabel"),
statusPill: document.getElementById("statusPill"),
maxTemp: document.getElementById("maxTemp"),
minTemp: document.getElementById("minTemp"),
conditionText: document.getElementById("conditionText"),
supportText: document.getElementById("supportText"),
endpointChip: document.getElementById("endpointChip"),
rangeChip: document.getElementById("rangeChip"),
chartHint: document.getElementById("chartHint"),
rangeNote: document.getElementById("rangeNote"),
chart: document.getElementById("chart"),
hourlyGrid: document.getElementById("hourlyGrid"),
visualPanel: document.getElementById("visualPanel"),
iconWrap: document.getElementById("iconWrap"),
conditionPillText: document.getElementById("conditionPillText"),
codeLabel: document.getElementById("codeLabel")
};
const numberFormatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 0,
maximumFractionDigits: 1
});
let currentTheme = {
accent: "106, 191, 255",
accent2: "88, 118, 255",
accentCss: "rgb(106, 191, 255)",
accent2Css: "rgb(88, 118, 255)"
};
const themes = {
clear: { accent: "255, 196, 84", accent2: "96, 187, 255" },
partly: { accent: "255, 183, 74", accent2: "98, 150, 255" },
cloudy: { accent: "159, 176, 194", accent2: "94, 117, 143" },
fog: { accent: "190, 203, 214", accent2: "133, 148, 162" },
rain: { accent: "88, 180, 255", accent2: "79, 111, 255" },
snow: { accent: "182, 240, 255", accent2: "148, 205, 255" },
storm: { accent: "194, 112, 255", accent2: "86, 108, 255" }
};
function setPalette(accent, accent2) {
currentTheme = {
accent,
accent2,
accentCss: `rgb(${accent})`,
accent2Css: `rgb(${accent2})`
};
document.documentElement.style.setProperty("--accent-rgb", accent);
document.documentElement.style.setProperty("--accent-2-rgb", accent2);
}
function setTheme(category) {
const base = themes[category] || themes.cloudy;
setPalette(base.accent, base.accent2);
}
function setErrorTheme() {
setPalette("255, 120, 117", "255, 178, 95");
}
function formatTemp(value) {
const n = Number.isFinite(value) ? value : NaN;
if (!Number.isFinite(n)) return "--";
const safe = Math.abs(n) < 0.05 ? 0 : n;
return `${numberFormatter.format(safe)}\u00B0`;
}
function formatCoord(value, positive, negative) {
return `${Math.abs(value).toFixed(2)}\u00B0 ${value >= 0 ? positive : negative}`;
}
function weatherMeta(code) {
const c = Number(code);
if (c === 0) return { label: "Clear sky", category: "clear" };
if (c === 1) return { label: "Mainly clear", category: "partly" };
if (c === 2) return { label: "Partly cloudy", category: "partly" };
if (c === 3) return { label: "Overcast", category: "cloudy" };
if (c === 45 || c === 48) return { label: "Fog", category: "fog" };
if (c === 51) return { label: "Light drizzle", category: "rain" };
if (c === 53) return { label: "Moderate drizzle", category: "rain" };
if (c === 55) return { label: "Dense drizzle", category: "rain" };
if (c === 56) return { label: "Freezing drizzle", category: "rain" };
if (c === 57) return { label: "Heavy freezing drizzle", category: "rain" };
if (c === 61) return { label: "Slight rain", category: "rain" };
if (c === 63) return { label: "Moderate rain", category: "rain" };
if (c === 65) return { label: "Heavy rain", category: "rain" };
if (c === 66) return { label: "Freezing rain", category: "rain" };
if (c === 67) return { label: "Heavy freezing rain", category: "rain" };
if (c === 71) return { label: "Slight snow", category: "snow" };
if (c === 73) return { label: "Moderate snow", category: "snow" };
if (c === 75) return { label: "Heavy snow", category: "snow" };
if (c === 77) return { label: "Snow grains", category: "snow" };
if (c === 80) return { label: "Slight rain showers", category: "rain" };
if (c === 81) return { label: "Moderate rain showers", category: "rain" };
if (c === 82) return { label: "Violent rain showers", category: "rain" };
if (c === 85) return { label: "Slight snow showers", category: "snow" };
if (c === 86) return { label: "Heavy snow showers", category: "snow" };
if (c === 95) return { label: "Thunderstorm", category: "storm" };
if (c === 96) return { label: "Thunderstorm with hail", category: "storm" };
if (c === 99) return { label: "Thunderstorm with heavy hail", category: "storm" };
return { label: `Weather code ${c}`, category: "cloudy" };
}
function weatherIcon(category) {
if (category === "clear") {
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<circle cx="120" cy="64" r="28" fill="currentColor" opacity="0.98"></circle>
<g stroke="currentColor" stroke-width="6" stroke-linecap="round" opacity="0.95">
<line x1="120" y1="14" x2="120" y2="32"></line>
<line x1="120" y1="96" x2="120" y2="114"></line>
<line x1="70" y1="64" x2="88" y2="64"></line>
<line x1="152" y1="64" x2="170" y2="64"></line>
<line x1="87" y1="31" x2="100" y2="44"></line>
<line x1="140" y1="84" x2="153" y2="97"></line>
<line x1="87" y1="97" x2="100" y2="84"></line>
<line x1="140" y1="44" x2="153" y2="31"></line>
</g>
</svg>`;
}
if (category === "partly") {
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<circle cx="156" cy="46" r="23" fill="currentColor" opacity="0.95"></circle>
<g stroke="currentColor" stroke-width="6" stroke-linecap="round" opacity="0.9">
<line x1="156" y1="8" x2="156" y2="22"></line>
<line x1="156" y1="68" x2="156" y2="82"></line>
<line x1="119" y1="46" x2="133" y2="46"></line>
<line x1="179" y1="46" x2="193" y2="46"></line>
<line x1="131" y1="22" x2="141" y2="32"></line>
<line x1="171" y1="60" x2="181" y2="70"></line>
<line x1="131" y1="70" x2="141" y2="60"></line>
<line x1="171" y1="32" x2="181" y2="22"></line>
</g>
<g fill="#ffffff" opacity="0.98">
<circle cx="88" cy="98" r="24"></circle>
<circle cx="120" cy="86" r="31"></circle>
<circle cx="152" cy="98" r="23"></circle>
<rect x="72" y="98" width="108" height="30" rx="15"></rect>
</g>
</svg>`;
}
if (category === "cloudy") {
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<g fill="#ffffff" opacity="0.96">
<circle cx="84" cy="84" r="20"></circle>
<circle cx="116" cy="72" r="28"></circle>
<circle cx="148" cy="84" r="21"></circle>
<rect x="68" y="84" width="104" height="28" rx="14"></rect>
</g>
</svg>`;
}
if (category === "fog") {
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<g fill="#ffffff" opacity="0.95">
<circle cx="82" cy="82" r="20"></circle>
<circle cx="113" cy="72" r="28"></circle>
<circle cx="144" cy="82" r="21"></circle>
<rect x="66" y="82" width="102" height="28" rx="14"></rect>
</g>
<g stroke="currentColor" stroke-width="6" stroke-linecap="round" opacity="0.9">
<line x1="54" y1="118" x2="186" y2="118"></line>
<line x1="66" y1="132" x2="174" y2="132"></line>
<line x1="82" y1="145" x2="158" y2="145"></line>
</g>
</svg>`;
}
if (category === "rain") {
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<g fill="#ffffff" opacity="0.96">
<circle cx="84" cy="84" r="20"></circle>
<circle cx="116" cy="72" r="28"></circle>
<circle cx="148" cy="84" r="21"></circle>
<rect x="68" y="84" width="104" height="28" rx="14"></rect>
</g>
<g stroke="currentColor" stroke-width="6" stroke-linecap="round" opacity="0.95">
<line x1="88" y1="118" x2="82" y2="136"></line>
<line x1="120" y1="118" x2="114" y2="136"></line>
<line x1="152" y1="118" x2="146" y2="136"></line>
</g>
</svg>`;
}
if (category === "snow") {
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<g fill="#ffffff" opacity="0.96">
<circle cx="84" cy="84" r="20"></circle>
<circle cx="116" cy="72" r="28"></circle>
<circle cx="148" cy="84" r="21"></circle>
<rect x="68" y="84" width="104" height="28" rx="14"></rect>
</g>
<g stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.95">
<line x1="88" y1="118" x2="88" y2="138"></line>
<line x1="78" y1="128" x2="98" y2="128"></line>
<line x1="124" y1="118" x2="124" y2="138"></line>
<line x1="114" y1="128" x2="134" y2="128"></line>
<line x1="160" y1="118" x2="160" y2="138"></line>
<line x1="150" y1="128" x2="170" y2="128"></line>
</g>
</svg>`;
}
if (category === "storm") {
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<g fill="#ffffff" opacity="0.96">
<circle cx="84" cy="84" r="20"></circle>
<circle cx="116" cy="72" r="28"></circle>
<circle cx="148" cy="84" r="21"></circle>
<rect x="68" y="84" width="104" height="28" rx="14"></rect>
</g>
<path d="M132 104 L115 129 H129 L120 145 L151 118 H138 L146 104 Z" fill="currentColor"></path>
</svg>`;
}
return `
<svg viewBox="0 0 240 150" aria-hidden="true" focusable="false">
<g fill="#ffffff" opacity="0.96">
<circle cx="84" cy="84" r="20"></circle>
<circle cx="116" cy="72" r="28"></circle>
<circle cx="148" cy="84" r="21"></circle>
<rect x="68" y="84" width="104" height="28" rx="14"></rect>
</g>
</svg>`;
}
function renderChart(values) {
if (!values.length) return;
const width = 1000;
const height = 160;
const padX = 18;
const padY = 18;
const min = Math.min(...values);
const max = Math.max(...values);
const range = Math.max(1, max - min);
const usableW = width - padX * 2;
const usableH = height - padY * 2;
const denom = Math.max(1, values.length - 1);
const xs = values.map((_, i) => padX + (usableW * i) / denom);
const ys = values.map((v) => padY + (1 - (v - min) / range) * usableH);
const line = xs.map((x, i) => `${i === 0 ? "M" : "L"} ${x.toFixed(1)} ${ys[i].toFixed(1)}`).join(" ");
const area = `${line} L ${xs[xs.length - 1].toFixed(1)} ${height - padY} L ${xs[0].toFixed(1)} ${height - padY} Z`;
const grid = [0.25, 0.5, 0.75].map((fraction) => {
const y = padY + usableH * fraction;
return `<line x1="${padX}" y1="${y.toFixed(1)}" x2="${(width - padX).toFixed(1)}" y2="${y.toFixed(1)}"></line>`;
}).join("");
const points = xs.map((x, i) => {
const r = i === 0 || i === values.length - 1 ? 4 : 3;
return `<circle cx="${x.toFixed(1)}" cy="${ys[i].toFixed(1)}" r="${r}"></circle>`;
}).join("");
dom.chart.innerHTML = `
<defs>
<linearGradient id="areaGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="${currentTheme.accentCss}" stop-opacity="0.28"></stop>
<stop offset="65%" stop-color="${currentTheme.accent2Css}" stop-opacity="0.10"></stop>
<stop offset="100%" stop-color="${currentTheme.accent2Css}" stop-opacity="0.00"></stop>
</linearGradient>
<linearGradient id="lineGradient" x1="0" y1="0" x2="100%" y2="0">
<stop offset="0%" stop-color="${currentTheme.accentCss}"></stop>
<stop offset="100%" stop-color="${currentTheme.accent2Css}"></stop>
</linearGradient>
</defs>
${grid}
<path class="area" d="${area}" fill="url(#areaGradient)"></path>
<path class="line" d="${line}" stroke="url(#lineGradient)"></path>
${points}
`;
}
function showError(detail) {
dom.content.hidden = true;
dom.errorState.hidden = false;
dom.errorDetail.textContent = detail;
dom.statusPill.textContent = "Unable to load data";
setErrorTheme();
document.title = `${state.name} - Weather data unavailable`;
}
function createHourTile(time, temp, width) {
const tile = document.createElement("div");
tile.className = "hour";
tile.title = `${time} - ${formatTemp(temp)}`;
const timeEl = document.createElement("div");
timeEl.className = "time";
timeEl.textContent = time;
const tempEl = document.createElement("div");
tempEl.className = "temp";
tempEl.textContent = formatTemp(temp);
const track = document.createElement("div");
track.className = "track";
const fill = document.createElement("div");
fill.className = "fill";
fill.style.width = `${width.toFixed(1)}%`;
tile.append(timeEl, tempEl, track, fill);
return tile;
}
async function loadWeather() {
const endpoint = state.date < state.today ? "/api/om/archive" : "/api/om/forecast";
const params = new URLSearchParams({
latitude: String(state.lat),
longitude: String(state.lon),
daily: "temperature_2m_max,temperature_2m_min,weather_code",
hourly: "temperature_2m",
timezone: "UTC",
temperature_unit: "celsius",
start_date: state.date,
end_date: state.date
});
dom.location.textContent = state.name;
dom.location.title = state.name;
dom.dateLabel.textContent = selectedDateLabel;
dom.dateLabel.title = state.date;
dom.coordsLabel.textContent = `${formatCoord(state.lat, "N", "S")} \u00B7 ${formatCoord(state.lon, "E", "W")}`;
dom.coordsLabel.title = `${state.lat}, ${state.lon}`;
dom.chartHint.textContent = "Loading hourly temperatures...";
dom.supportText.textContent = "The selected day is evaluated in UTC.";
dom.endpointChip.textContent = endpoint.includes("archive") ? "Source: archive" : "Source: forecast";
dom.rangeChip.textContent = "Hourly readings: pending";
dom.conditionText.textContent = "Fetching weather data...";
dom.conditionPillText.textContent = "Loading weather...";
dom.codeLabel.textContent = "Weather code --";
dom.statusPill.textContent = "Loading weather...";
dom.iconWrap.style.color = currentTheme.accentCss;
dom.iconWrap.innerHTML = weatherIcon("cloudy");
dom.hourlyGrid.innerHTML = "";
dom.rangeNote.textContent = "--";
dom.maxTemp.textContent = "--";
dom.minTemp.textContent = "--";
document.title = `${state.name} - ${selectedDateLabel}`;
dom.content.hidden = false;
dom.errorState.hidden = true;
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 12000);
try {
const response = await fetch(`${endpoint}?${params.toString()}`, {
signal: controller.signal,
cache: "no-store",
credentials: "same-origin"
});
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
const data = await response.json();
const daily = data && data.daily;
const hourly = data && data.hourly;
const dailyTimes = Array.isArray(daily && daily.time) ? daily.time : [];
let dayIndex = dailyTimes.findIndex((value) => String(value).slice(0, 10) === state.date);
if (dayIndex < 0 && dailyTimes.length === 1) dayIndex = 0;
if (dayIndex < 0) {
throw new Error("Requested date was not returned by the API");
}
const dailyMaxRaw = daily.temperature_2m_max && daily.temperature_2m_max[dayIndex];
const dailyMinRaw = daily.temperature_2m_min && daily.temperature_2m_min[dayIndex];
const weatherCodeRaw = daily.weather_code && daily.weather_code[dayIndex];
const dailyMax = Number.parseFloat(dailyMaxRaw);
const dailyMin = Number.parseFloat(dailyMinRaw);
const weatherCode = Number.parseInt(weatherCodeRaw, 10);
if (!Number.isFinite(dailyMax) || !Number.isFinite(dailyMin) || !Number.isFinite(weatherCode)) {
throw new Error("Daily weather values were incomplete");
}
const meta = weatherMeta(weatherCode);
setTheme(meta.category);
dom.iconWrap.style.color = currentTheme.accentCss;
dom.iconWrap.innerHTML = weatherIcon(meta.category);
const hourlyTimes = Array.isArray(hourly && hourly.time) ? hourly.time : [];
const hourlyTempsRaw = Array.isArray(hourly && hourly.temperature_2m) ? hourly.temperature_2m : [];
const pairs = [];
for (let i = 0; i < hourlyTimes.length; i += 1) {
const time = String(hourlyTimes[i]);
if (!time.startsWith(`${state.date}T`)) continue;
const temp = Number.parseFloat(hourlyTempsRaw[i]);
if (!Number.isFinite(temp)) continue;
pairs.push({ time, temp });
}
if (!pairs.length) {
throw new Error("Hourly temperatures were not returned for the selected date");
}
const hourlyValues = pairs.map((pair) => pair.temp);
const hourlyMin = Math.min(...hourlyValues);
const hourlyMax = Math.max(...hourlyValues);
const hourlySpan = Math.max(1, hourlyMax - hourlyMin);
dom.maxTemp.textContent = formatTemp(dailyMax);
dom.minTemp.textContent = formatTemp(dailyMin);
dom.conditionText.textContent = meta.label;
dom.conditionPillText.textContent = meta.label;
dom.codeLabel.textContent = `Weather code ${weatherCode}`;
dom.endpointChip.textContent = endpoint.includes("archive") ? "Source: archive" : "Source: forecast";
dom.rangeChip.textContent = `${pairs.length} hourly readings`;
dom.chartHint.textContent = `${pairs.length} hourly readings for ${selectedDateLabel}`;
dom.rangeNote.textContent = `Hourly span ${formatTemp(hourlyMin)} to ${formatTemp(hourlyMax)}`;
dom.statusPill.textContent = endpoint.includes("archive") ? "Archive loaded" : "Forecast loaded";
document.title = `${state.name} - ${selectedDateLabel}`;
dom.hourlyGrid.innerHTML = "";
pairs.forEach(({ time, temp }) => {
const normalized = 8 + ((temp - hourlyMin) / hourlySpan) * 84;
dom.hourlyGrid.appendChild(createHourTile(time.slice(11, 16), temp, Math.max(8, Math.min(92, normalized))));
});
renderChart(hourlyValues);
dom.content.hidden = false;
dom.errorState.hidden = true;
} catch (err) {
const reason = err && err.name === "AbortError"
? "The weather request timed out"
: (err && err.message) ? err.message : "The weather request could not be completed";
showError(`Could not load weather data for ${state.name} on ${selectedDateLabel}. ${reason.replace(/\.$/, "")}.`);
} finally {
clearTimeout(timeout);
}
}
loadWeather();
})();
</script>
</body>
</html>L1 — cheap deterministic descriptors
| bytes total | 34,343 | html / css / js | 3,355 / 10,355 / 20,633 |
|---|---|---|---|
| dom nodes | 60 | dom depth | 11 |
| css rules | 67 | js present | yes |
| brightness | 36.6 | contrast | 30.0 |
| colorfulness | 17.6 | whitespace | 74.7% |
This slot's telemetry
| prompt tokens | 16,123 | completion tokens | 87,886 |
|---|---|---|---|
| total tokens | 104,009 | wall | 469.5 s |
| cost | — | request id | — |
config.json577 B
{
"N": 2,
"auth": {
"credential_ref": "WCB_NONE",
"method": "oauth-login"
},
"billing": "plan",
"config_id": "gpt-5.4-mini-eff-xhigh--cli--cursor--dev",
"effort": "xhigh",
"family": "gpt",
"m": {
"min": 2,
"q": 2
},
"model_id": "gpt-5.4-mini",
"protocol": "cli",
"served_model": "gpt-5.4-mini-xhigh",
"telemetry": {
"completion_tokens": 350502,
"cost_usd": null,
"prompt_tokens": 64461,
"total_tokens": 414963,
"wall_ms": 2342352
},
"transport": "cursor-agent-cli-isolated-home",
"vendor_sanction_ref": null
}send-log2.5 KB
{
"N": 2,
"batch_id": "2026-08-13--cursor-s1",
"config_id": "gpt-5.4-mini-eff-xhigh--cli--cursor--dev",
"positions": [
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-08-13T01:31:02.937083+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:21:59.785238+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:38:56.184530+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:31:06.651628+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:54:33.219580+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:39:00.412102+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-13T02:01:57.422150+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T01:55:20.468465+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
}
}
}