/* ============================================================================
   Forecast Flakes — the locked frame viewer.

   Forecast Eagle keeps a "legacy" viewer beside every interactive explorer and
   this is the winter one. It is not a nostalgia exercise. The interactive page
   needs a WebGL context, a vector basemap, a sprite sheet and eight modules; on
   an old laptop, a locked-down work desktop, or a browser that refuses WebGL,
   it renders nothing at all. This page is four stacked <img> tags in a fixed
   frame, every control is a button, and the whole run is preloaded before it
   plays — so the loop is instant, the camera cannot be dragged off the map, and
   the thing works anywhere.

   Dark chrome, light map. The same choice Forecast Eagle makes: model imagery
   sits in a dark inset so the eye goes to the data, while the document around
   it — every other page on this site — stays paper.
   ========================================================================== */
.lab { --bg:#0e1218; --panel:#161c25; --edge:#2a3441; --tx:#ccd6e2; --dim:#7e8b9b;
       --hot:#2f57bf; --hot2:#4d78e0; }

body.lab { margin:0; background:var(--bg); color:var(--tx);
  font-family:'Overpass',Helvetica,Arial,sans-serif; }
body.lab a { color:var(--hot2); }

.lbar { display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  background:#080b0f; border-bottom:2px solid var(--hot); padding:6px 12px;
  font:700 11px 'Overpass Mono',ui-monospace,monospace; letter-spacing:.07em; }
.lbar .brand { font-weight:900; letter-spacing:.14em; color:#fff; }
.lbar .brand span { color:var(--hot2); }
.lbar .tagx { color:var(--dim); }
.lbar .sp { flex:1; }
.lbar a { color:var(--dim); text-decoration:none; padding:3px 6px; }
.lbar a:hover, .lbar a[aria-current] { color:#fff; }

.lwrap { display:grid; grid-template-columns:236px minmax(0,1fr); gap:0;
  min-height:calc(100vh - 34px); }
@media (max-width:900px){ .lwrap{ grid-template-columns:1fr; } }

.lside { background:var(--panel); border-right:1px solid var(--edge);
  padding:10px; overflow:auto; max-height:calc(100vh - 34px); }
@media (max-width:900px){ .lside{ max-height:none; border-right:0;
  border-bottom:1px solid var(--edge); } }
.lgrp { margin-bottom:14px; }
.lgrp > h4 { margin:0 0 5px; font:800 9.5px 'Overpass Mono',monospace;
  letter-spacing:.16em; text-transform:uppercase; color:var(--dim); }
.lbtns { display:flex; flex-wrap:wrap; gap:3px; }
.lb { background:#1e2733; color:var(--tx); border:1px solid var(--edge);
  border-radius:2px; font:700 10.5px 'Overpass Mono',monospace; letter-spacing:.04em;
  padding:5px 7px; cursor:pointer; text-transform:uppercase; }
.lb:hover { border-color:var(--hot2); color:#fff; }
.lb.on { background:var(--hot); border-color:var(--hot2); color:#fff; }
.lb.wide { width:100%; text-align:left; }
.lb[disabled] { opacity:.35; cursor:default; }
.lb.link { display:block; text-decoration:none; text-align:center; margin-top:4px; }

.lmain { display:flex; flex-direction:column; min-width:0; }
.lhead { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;
  padding:8px 12px; border-bottom:1px solid var(--edge); }
.lhead h1 { margin:0; font-size:16px; font-weight:900; color:#fff; }
.lhead .sub { font:700 11px 'Overpass Mono',monospace; color:var(--dim); }

/* The stage. `.crop` is the window; `.frame` is the whole raster, scaled and
   shifted behind it. Every layer is inside `.frame`, so they are cropped by the
   same transform and cannot drift apart. */
.lstage { flex:1; display:flex; align-items:center; justify-content:center;
  padding:12px; min-height:0; }
.crop { position:relative; overflow:hidden; background:#dfe7ee;
  border:1px solid var(--edge); box-shadow:0 10px 34px rgba(0,0,0,.5); }
.frame { position:absolute; }
.frame img { position:absolute; inset:0; width:100%; height:100%; display:block;
  image-rendering:auto; }
.frame img.px { image-rendering:pixelated; }

.lplate { position:absolute; left:0; top:0; background:rgba(8,11,15,.82);
  color:#fff; padding:6px 10px; font:800 12px 'Overpass Mono',monospace;
  letter-spacing:.05em; border-bottom-right-radius:4px; z-index:5; }
.lplate small, .lstamp small { display:block; font-weight:700; font-size:10px;
  color:#9fb0c4; letter-spacing:.08em; margin-top:2px; }
.lstamp { position:absolute; right:0; top:0; background:rgba(8,11,15,.82);
  color:#fff; padding:6px 10px; font:800 12px 'Overpass Mono',monospace;
  border-bottom-left-radius:4px; z-index:5; text-align:right; }
.lprog { position:absolute; left:0; right:0; bottom:0; height:3px;
  background:rgba(255,255,255,.12); z-index:6; }
.lprog i { display:block; height:100%; background:var(--hot2); width:0; }

.lfoot { border-top:1px solid var(--edge); padding:8px 12px; }
.lrow { display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-bottom:6px; }
.lframes { display:flex; gap:2px; flex-wrap:wrap; }
.lframes .lb { padding:4px 6px; font-size:10px; }
.lleg { display:flex; flex-wrap:wrap; gap:0; margin-top:4px;
  border:1px solid var(--edge); border-radius:3px; overflow:hidden; }
.lleg .c { flex:1 1 0; min-width:26px; text-align:center;
  font:700 9px 'Overpass Mono',monospace; color:#0e1218; padding:3px 1px; }
.lleg .c.dk { color:#fff; }
.lnote { font:600 11px/1.5 'Overpass',sans-serif; color:var(--dim); margin:6px 0 0;
  max-width:105ch; }
.lnote b { color:var(--tx); }

/* City labels are DOM, not a baked overlay.
   A rasterised label sheet is magnified by whatever the crop's zoom happens to be — on
   the Northeast box that is 2.1x, and Burlington ends up in 27-point type sitting on top
   of Portland. These are spans instead: positioned by the same mercator fractions the
   crop uses, so they ride with it exactly, but drawn at a constant size and thinned by
   rank as the box tightens. Still no map engine. */
.clab { position:absolute; transform:translate(6px,-50%); white-space:nowrap;
  font:800 11.5px 'Overpass',sans-serif; color:#141a21; pointer-events:none;
  text-shadow:0 0 3px #fff, 0 0 3px #fff, 0 0 2px #fff, 1px 1px 0 #fff, -1px -1px 0 #fff; }
.cdot { position:absolute; width:5px; height:5px; margin:-2.5px 0 0 -2.5px;
  border-radius:50%; background:#141a21; box-shadow:0 0 0 1.2px rgba(255,255,255,.9);
  pointer-events:none; }
.clayer { position:absolute; inset:0; overflow:hidden; pointer-events:none; }
