diff --git a/.gitignore b/.gitignore index 8e24341..e758bf9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ node_modules **/debug.log server/scripts/custom.js -cache/ #music folder server/music/* diff --git a/README.md b/README.md index fbb2128..579d905 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,34 @@ ![Weatherstar 4000+ Current Conditions](https://github.com/netbymatt/ws4kp/blob/main/server/images/social/1200x600.png) -# ws4kp-linhanced +# WeatherStar 4000+ -`ws4kp-linhanced` is a Linux-focused fork of [`netbymatt/ws4kp`](https://github.com/netbymatt/ws4kp) by `markmental`. +A live version of this project is available at https://weatherstar.netbymatt.com ## About -This fork keeps the classic WeatherStar-style experience and stable base architecture from the original `ws4kp` project, while selectively integrating international weather support and other practical improvements. It is not intended to be a perfect hardware emulation of the WeatherStar 4000. If you want a more exact recreation of the original hardware behavior, see the [WS4000 Simulator](http://www.taiganet.com/). - -This fork also explicitly adopts Slackware Linux `weatherstar4k` branding as part of its mission. The goal is not broad platform neutrality. The goal is a lean, self-hostable, Linux-oriented weatherstar fork with a strong visual identity and a codebase that stays practical to maintain. - -## About This Fork - -This project is based on: - -* [`netbymatt/ws4kp`](https://github.com/netbymatt/ws4kp) for the core WeatherStar implementation and the more stable upstream foundation. -* [`mwood77/ws4kp-international`](https://github.com/mwood77/ws4kp-international) for the Open-Meteo international weather direction and some global map ideas. - -This fork intentionally diverges from `ws4kp-international`. That project proved out the international weather concept, but this fork aims to keep a narrower scope and avoid the feature creep that can make ongoing work harder. The original `ws4kp` codebase provided a better base for that approach, so this fork builds from there and pulls in only the parts that fit. - -## Current Direction - -This fork is focused on: - -* preserving the classic WeatherStar feel while staying maintainable -* Linux-first identity and presentation -* Open-Meteo-based international weather support for the core forecast screens -* global radar and global regional observations on the newer map stack -* pragmatic feature additions instead of broad platform expansion +This project aims to bring back the feel of the 90s with a weather forecast that has the look and feel of The Weather Channel at that time but available in a modern way. This is by no means intended to be a perfect emulation of the WeatherStar 4000, the hardware that produced those wonderful blue and orange graphics you saw during the local forecast on The Weather Channel. If you would like a much more accurate project please see the [WS4000 Simulator](http://www.taiganet.com/). Instead, this project intends to create a simple to use interface with minimal configuration fuss. Some changes have been made to the screens available because either more or less forecast information is available today than was in the 90s. Most of these changes are captured in sections below. ## What's your motivation -Nostalgia, Linux affinity, and an interest in keeping a practical retro weather display alive without turning it into a sprawling platform. +Nostalgia. And I enjoy following the weather, especially severe storms. + +It's also a creative outlet for me and keeps my programming skills honed for when I need them for my day job. ### Included technology -This fork still keeps the original project's straightforward architecture and relatively low dependency surface so it stays approachable to modify. +I've kept this open source, well commented, and made it as library-free as possible to help others interested in programming be able to jump right in and start working with the code. -From a learning standpoint, this codebase makes use of a lot of different methods and technologies common on the internet including: +From a learning standpoint, this codebase make use of a lot of different methods and technologies common on the internet including: -* The [Open-Meteo API](https://open-meteo.com/) for core forecast data. -* NOAA APIs and products where legacy US-only displays still require them. +* The https://api.weather.gov REST API. ([documentation](https://www.weather.gov/documentation/services-web-api)). * ES 6 functionality * Arrow functions * Promises - * Async/await and parallel loading of forecast resources + * Async/await and parallel loading of all forecast resources * Classes and extensions * Javascript modules * Separation between API code and user interface code * Use of a modern date parsing library [luxon](https://moment.github.io/luxon/) -* Server-side proxy caching plus browser/static asset caching +* Practical API rates and static asset caching * Very straight-forward hand written HTML * Build system integration (Gulp, Webpack) to reduce the number of scripts that need to be loaded * Hand written CSS made easier to mange with SASS @@ -58,33 +38,33 @@ From a learning standpoint, this codebase makes use of a lot of different method Ensure you have Node installed. ```bash -git clone -cd ws4kp-linhanced +git clone https://github.com/netbymatt/ws4kp.git +cd ws4kp npm install npm start ``` Open your browser and navigate to https://localhost:8080 -## Does ws4kp-linhanced work outside of the USA? +## Does WeatherStar 4000+ work outside of the USA? -Yes for the core forecast screens, and more than that. - -The main weather flow now uses Open-Meteo, so search, current conditions, hourly, local forecast, extended forecast, almanac, travel forecast, radar, and regional observations all work internationally. +Yes for the core forecast screens. The main weather flow now uses Open-Meteo so search, current conditions, hourly, local forecast, extended forecast, and almanac work internationally. Some legacy displays still rely on [NOAA's Weather API](https://www.weather.gov/documentation/services-web-api) and remain available only for United States locations for now: * Hazards +* Latest Observations +* Regional Forecast +* Travel Forecast * SPC Outlook - -This fork no longer treats `ws4kp-international` as a drop-in upstream. Instead, it selectively incorporates the Open-Meteo international weather work while keeping a leaner feature set and a more stable base. +* Local Radar Earlier international work on this idea was explored in a fork created by [@mwood77](https://github.com/mwood77): - [`ws4kp-international`](https://github.com/mwood77/ws4kp-international) ## Deployment Modes -`ws4kp-linhanced` supports two deployment modes: +WeatherStar 4000+ supports two deployment modes: ### Server Deployment (Recommended) @@ -100,7 +80,7 @@ Earlier international work on this idea was explored in a fork created by [@mwoo * Browser-based caching * Used by: static file hosting and default `Dockerfile` -## Other methods to run ws4kp-linhanced +## Other methods to run Ws4kp ### Development Mode (individual JS files, easier debugging) ```bash @@ -124,7 +104,7 @@ npm run build STATIC=1 DIST=1 npm start ``` -For all modes, access `ws4kp-linhanced` by going to: http://localhost:8080/ +For all modes, access WeatherStar by going to: http://localhost:8080/ ### Key Differences @@ -205,15 +185,16 @@ STATIC=1 DIST=1 npm start # Use Express to serve (minimized) production files ## What's different -This fork has diverged significantly from upstream in a few important ways: +I've made several changes to this Weather Star 4000 simulation compared to the original hardware unit and the code that this was forked from. -* Core weather and forecast screens now use Open-Meteo instead of being tied entirely to weather.gov. -* Travel Forecast has been rebuilt on region buckets with a global fallback instead of remaining a US-only NOAA-driven screen. -* Local Radar now uses global RainViewer radar imagery on top of a cached world basemap instead of the older US-only radar path. -* Regional Forecast has been temporarily replaced by a global `Regional Observations` map display using nearby city observations on the new map stack. -* Latest Observations has been removed. -* Some NOAA-based displays are still retained where there is no equivalent replacement yet, especially Hazards and SPC Outlook. -* This fork explicitly embraces Linux and Slackware-flavored `weatherstar4k` branding instead of aiming for broad neutral presentation. +* Radar displays the timestamp of the image. +* A new hour-by-hour graph of the temperature, cloud cover and precipitation chances for the next 24 hours. +* A new hourly forecast display for the next 24 hours is available, and is shown in the style of the travel cities forecast. (off by default because it duplicates the hourly graph) +* The SPC Outlook is shown in the style of the old air quality screen. This shows the probability of severe weather over the next 3 days at your location. SPC outlook only displays if you're within one of the highlight areas over the next 3 day. You can view the [maps](https://www.weather.gov/crh/outlooks) and pick a location within one of the risk categories to see if the screen is working for you. +* The "Local Forecast" and "Extended Forecast" provide several additional days of information compared to the original format in the 90s. +* The original music has been replaced. More info in [Music](#music). +* Marine forecast (tides) is not available as it is not reliably part of the new API. +* "Flavors" are not present in this simulation. Flavors refer to the order of the weather information that was shown on the original units. Instead, the order of the displays has been fixed and a checkboxes can be used to turn on and off individual displays. The travel forecast has been defaulted to off so only local information shows for new users. ## Sharing a permalink (bookmarking) Selected displays, the forecast city and widescreen setting are sticky from one session to the next. However if you would like to share your exact configuration or bookmark it, click the "Copy Permalink" (or get "Get Permalink") near the bottom of the page. A URL will be copied to your clipboard with all of you selected displays and location (or copy it from the page if your browser doesn't support clipboard transfers directly). You can then share this link or add it to your bookmarks. diff --git a/gulp/publish-frontend.mjs b/gulp/publish-frontend.mjs index e558393..e00a868 100644 --- a/gulp/publish-frontend.mjs +++ b/gulp/publish-frontend.mjs @@ -79,6 +79,7 @@ const mjsSources = [ 'server/scripts/modules/extendedforecast.mjs', 'server/scripts/modules/hourly.mjs', 'server/scripts/modules/hourly-graph.mjs', + 'server/scripts/modules/latestobservations.mjs', 'server/scripts/modules/localforecast.mjs', 'server/scripts/modules/radar.mjs', 'server/scripts/modules/regionalforecast.mjs', diff --git a/index.mjs b/index.mjs index f8e090b..a74cd28 100644 --- a/index.mjs +++ b/index.mjs @@ -5,15 +5,7 @@ import { readFile } from 'fs/promises'; import { exec } from 'child_process'; import { promisify } from 'util'; import { - weatherProxy, - radarProxy, - outlookProxy, - mesonetProxy, - forecastProxy, - openMeteoProxy, - rainViewerProxy, - arcGisServerProxy, - arcGisServicesProxy, + weatherProxy, radarProxy, outlookProxy, mesonetProxy, forecastProxy, openMeteoProxy, rainViewerProxy, } from './proxy/handlers.mjs'; import playlist from './src/playlist.mjs'; import OVERRIDES from './src/overrides.mjs'; @@ -264,8 +256,6 @@ if (!process.env?.STATIC) { app.use('/forecast/', forecastProxy); app.use('/open-meteo/', openMeteoProxy); app.use('/rainviewer/', rainViewerProxy); - app.use('/arcgis-server/', arcGisServerProxy); - app.use('/arcgis-services/', arcGisServicesProxy); // Playlist route is available in server mode (not in static mode) app.get('/playlist.json', playlist); diff --git a/proxy/cache.mjs b/proxy/cache.mjs index 549c616..8786645 100644 --- a/proxy/cache.mjs +++ b/proxy/cache.mjs @@ -19,164 +19,18 @@ */ import https from 'https'; -import { createHash } from 'crypto'; -import { - mkdir, readdir, readFile, rm, unlink, writeFile, -} from 'fs/promises'; -import path from 'path'; // Default timeout for upstream requests (matches client-side default) const DEFAULT_REQUEST_TIMEOUT = 15000; -const CACHE_DIR = path.resolve('./cache'); -const STALE_TIME_LIMIT_MS = 3 * 60 * 60 * 1000; -const PERSISTED_HOSTS = new Set([ - 'api.open-meteo.com', - 'api.rainviewer.com', - 'server.arcgisonline.com', - 'services.arcgisonline.com', -]); -const BINARY_PERSISTED_HOSTS = new Set([ - 'server.arcgisonline.com', - 'services.arcgisonline.com', -]); -const HOST_FALLBACK_TTLS = { - 'api.open-meteo.com': 10 * 60, - 'api.rainviewer.com': 2 * 60, - 'server.arcgisonline.com': 7 * 24 * 60 * 60, - 'services.arcgisonline.com': 7 * 24 * 60 * 60, -}; class HttpCache { constructor() { this.cache = new Map(); this.inFlight = new Map(); this.cleanupInterval = null; - this.hydrationPromise = this.loadPersistedEntries(); this.startCleanup(); } - static hashKey(key) { - return createHash('sha256').update(key).digest('hex'); - } - - static getCacheFilePath(key) { - return path.join(CACHE_DIR, `${HttpCache.hashKey(key)}.json`); - } - - static getCacheBodyFilePath(key) { - return path.join(CACHE_DIR, `${HttpCache.hashKey(key)}.bin`); - } - - static getPersistedHost(url) { - try { - const parsedUrl = new URL(url); - return parsedUrl.hostname; - } catch { - return null; - } - } - - static shouldPersist(url, options, response) { - const host = HttpCache.getPersistedHost(url); - if (!host || !PERSISTED_HOSTS.has(host)) { - return false; - } - - if (options?.encoding === 'binary') { - return BINARY_PERSISTED_HOSTS.has(host) && Buffer.isBuffer(response?.data); - } - - return typeof response?.data === 'string'; - } - - static getHostFallbackTtl(url) { - try { - const parsedUrl = new URL(url); - return HOST_FALLBACK_TTLS[parsedUrl.hostname] ?? 0; - } catch { - return 0; - } - } - - async ensureHydrated() { - await this.hydrationPromise; - } - - async loadPersistedEntries() { - try { - await mkdir(CACHE_DIR, { recursive: true }); - const files = await readdir(CACHE_DIR); - const now = Date.now(); - - await Promise.allSettled(files.filter((file) => file.endsWith('.json')).map(async (file) => { - const filePath = path.join(CACHE_DIR, file); - const raw = await readFile(filePath, 'utf8'); - const parsed = JSON.parse(raw); - if (!parsed?.key || !parsed?.entry) { - await unlink(filePath); - return; - } - - if (now > parsed.entry.expiry + STALE_TIME_LIMIT_MS) { - if (parsed.entry.binaryBody === true) { - await unlink(HttpCache.getCacheBodyFilePath(parsed.key)).catch(() => null); - } - await unlink(filePath); - return; - } - - if (parsed.entry.binaryBody === true) { - parsed.entry.data = await readFile(HttpCache.getCacheBodyFilePath(parsed.key)); - } - - this.cache.set(parsed.key, parsed.entry); - })); - } catch (error) { - console.warn(`⚠️ Cache load | Failed to hydrate disk cache: ${error.message}`); - } - } - - static async persistEntry(key, entry) { - try { - await mkdir(CACHE_DIR, { recursive: true }); - - if (Buffer.isBuffer(entry.data)) { - const metadata = { - ...entry, - data: undefined, - binaryBody: true, - }; - await writeFile(HttpCache.getCacheBodyFilePath(key), entry.data); - await writeFile(HttpCache.getCacheFilePath(key), JSON.stringify({ key, entry: metadata })); - return; - } - - await writeFile(HttpCache.getCacheFilePath(key), JSON.stringify({ key, entry })); - } catch (error) { - console.warn(`⚠️ Cache save | Failed to persist cache entry ${key}: ${error.message}`); - } - } - - static async deletePersistedEntry(key) { - try { - await unlink(HttpCache.getCacheBodyFilePath(key)).catch(() => null); - await unlink(HttpCache.getCacheFilePath(key)); - } catch (error) { - if (error.code !== 'ENOENT') { - console.warn(`⚠️ Cache del | Failed to delete cache entry ${key}: ${error.message}`); - } - } - } - - static async clearPersistedEntries() { - try { - await rm(CACHE_DIR, { recursive: true, force: true }); - await mkdir(CACHE_DIR, { recursive: true }); - } catch (error) { - console.warn(`⚠️ Cache clear| Failed to clear disk cache: ${error.message}`); - } - } - // Parse cache-control header to extract s-maxage or max-age static parseCacheControl(cacheControlHeader) { if (!cacheControlHeader) return 0; @@ -212,17 +66,15 @@ class HttpCache { // Generate cache key from request static generateKey(req) { - const requestPath = req.path || req.url || '/'; + const path = req.path || req.url || '/'; const url = req.url || req.path || '/'; // Since this cache is intended only by the frontend, we can use a simple URL-based key - return `${requestPath}${url.includes('?') ? url.substring(url.indexOf('?')) : ''}`; + return `${path}${url.includes('?') ? url.substring(url.indexOf('?')) : ''}`; } // High-level method to handle caching for HTTP proxies async handleRequest(req, res, upstreamUrl, options = {}) { - await this.ensureHydrated(); - // Check cache status const cacheResult = this.getCachedRequest(req); @@ -410,7 +262,7 @@ class HttpCache { } // Store in cache (pass original headers for cache logic, but store filtered headers) - this.storeCachedResponse(req, response, fullUrl, getRes.headers, options); + this.storeCachedResponse(req, response, fullUrl, getRes.headers); // Send response to client res.status(statusCode); @@ -506,7 +358,7 @@ class HttpCache { return { status: 'stale', data: cached }; } - storeCachedResponse(req, response, url, originalHeaders, options = {}) { + storeCachedResponse(req, response, url, originalHeaders) { const key = HttpCache.generateKey(req); const cacheControl = (originalHeaders || {})['cache-control']; @@ -524,13 +376,6 @@ class HttpCache { cacheType = 'explicit'; } - if (maxAge <= 0) { - maxAge = HttpCache.getHostFallbackTtl(url); - if (maxAge > 0) { - cacheType = 'override'; - } - } - // Don't cache if still no valid max-age if (maxAge <= 0) { console.log(`📤 Sent | ${url} (no cache directives; not cached)`); @@ -551,9 +396,6 @@ class HttpCache { }; this.cache.set(key, cached); - if (HttpCache.shouldPersist(url, options, response)) { - HttpCache.persistEntry(key, cached); - } console.log(`🌐 Add | ${url} (${cacheType} ${maxAge}s TTL, expires: ${new Date(cached.expiry).toISOString()})`); } @@ -584,25 +426,20 @@ class HttpCache { startCleanup() { if (this.cleanupInterval) return; - this.cleanupInterval = setInterval(async () => { + this.cleanupInterval = setInterval(() => { const now = Date.now(); let removedCount = 0; - const deletePromises = []; Array.from(this.cache.entries()).forEach(([key, cached]) => { // Allow stale entries to persist for up to 3 hours before cleanup // This gives us time to make conditional requests and potentially refresh them - if (now > cached.expiry + STALE_TIME_LIMIT_MS) { + const staleTimeLimit = 3 * 60 * 60 * 1000; + if (now > cached.expiry + staleTimeLimit) { this.cache.delete(key); - deletePromises.push(HttpCache.deletePersistedEntry(key)); removedCount += 1; } }); - if (deletePromises.length > 0) { - await Promise.allSettled(deletePromises); - } - if (removedCount > 0) { console.log(`🧹 Clean | Removed ${removedCount} stale entries (${this.cache.size} remaining)`); } @@ -634,17 +471,15 @@ class HttpCache { // Clear all cache entries clear() { this.cache.clear(); - HttpCache.clearPersistedEntries(); console.log('🗑️ Clear | Cache cleared'); } // Clear a specific cache entry by path - clearEntry(cachePath) { - const key = cachePath; + clearEntry(path) { + const key = path; const deleted = this.cache.delete(key); if (deleted) { - HttpCache.deletePersistedEntry(key); - console.log(`🗑️ Clear | ${cachePath} removed from cache`); + console.log(`🗑️ Clear | ${path} removed from cache`); return true; } return false; diff --git a/proxy/handlers.mjs b/proxy/handlers.mjs index a845b61..4255d95 100644 --- a/proxy/handlers.mjs +++ b/proxy/handlers.mjs @@ -64,19 +64,3 @@ export const rainViewerProxy = async (req, res) => { skipParams: ['u'], }); }; - -export const arcGisServerProxy = async (req, res) => { - await cache.handleRequest(req, res, 'https://server.arcgisonline.com', { - serviceName: 'ArcGIS Server', - skipParams: ['u'], - encoding: 'binary', - }); -}; - -export const arcGisServicesProxy = async (req, res) => { - await cache.handleRequest(req, res, 'https://services.arcgisonline.com', { - serviceName: 'ArcGIS Services', - skipParams: ['u'], - encoding: 'binary', - }); -}; diff --git a/server/scripts/modules/latestobservations.mjs b/server/scripts/modules/latestobservations.mjs new file mode 100644 index 0000000..9e05a28 --- /dev/null +++ b/server/scripts/modules/latestobservations.mjs @@ -0,0 +1,215 @@ +// current weather conditions display +import { distance as calcDistance, directionToNSEW } from './utils/calc.mjs'; +import { safeJson, safePromiseAll } from './utils/fetch.mjs'; +import STATUS from './status.mjs'; +import { locationCleanup } from './utils/string.mjs'; +import { temperature, windSpeed } from './utils/units.mjs'; +import WeatherDisplay from './weatherdisplay.mjs'; +import { registerDisplay } from './navigation.mjs'; +import augmentObservationWithMetar from './utils/metar.mjs'; +import settings from './settings.mjs'; +import { debugFlag } from './utils/debug.mjs'; +import { enhanceObservationWithMapClick } from './utils/mapclick.mjs'; + +class LatestObservations extends WeatherDisplay { + constructor(navId, elemId) { + super(navId, elemId, 'Latest Observations', true); + + // constants + this.MaximumRegionalStations = 7; + } + + async getData(weatherParameters, refresh) { + if (!super.getData(weatherParameters, refresh)) return; + if (!this.weatherParameters?.supportsNoaaDisplays) { + this.data = []; + this.timing.totalScreens = 0; + this.setStatus(STATUS.loaded); + return; + } + this.timing.totalScreens = 1; + // latest observations does a silent refresh but will not fall back to previously fetched data + // this is intentional because up to 30 stations are available to pull data from + + // calculate distance to each station + const stationsByDistance = Object.values(StationInfo).map((station) => { + const distance = calcDistance(station.lat, station.lon, this.weatherParameters.latitude, this.weatherParameters.longitude); + return { ...station, distance }; + }); + + // sort the stations by distance + const sortedStations = stationsByDistance.sort((a, b) => a.distance - b.distance); + // try up to 30 regional stations + const regionalStations = sortedStations.slice(0, 30); + + // Fetch stations sequentially in batches to avoid unnecessary API calls. + // We start with the 7 closest stations and only fetch more if some fail, + // stopping as soon as we have 7 valid stations with data. + const actualConditions = []; + let lastStation = Math.min(regionalStations.length, 7); + let firstStation = 0; + while (actualConditions.length < 7 && (lastStation) <= regionalStations.length) { + // Sequential fetching is intentional here - we want to try closest stations first + // and only fetch additional batches if needed, rather than hitting all 30 stations at once + // eslint-disable-next-line no-await-in-loop + const someStations = await this.getStations(regionalStations.slice(firstStation, lastStation)); + + actualConditions.push(...someStations); + // update counters + firstStation += lastStation; + lastStation = Math.min(regionalStations.length + 1, firstStation + 7 - actualConditions.length); + } + + // cut down to the maximum of 7 + this.data = actualConditions.slice(0, this.MaximumRegionalStations); + + // test for at least one station + if (this.data.length === 0) { + this.setStatus(STATUS.noData); + return; + } + this.setStatus(STATUS.loaded); + } + + // This is a class method because it needs access to the instance's `stillWaiting` method + async getStations(stations) { + // Use centralized safe Promise handling to avoid unhandled AbortError rejections + const stationData = await safePromiseAll(stations.map(async (station) => { + try { + const data = await safeJson(`https://api.weather.gov/stations/${station.id}/observations/latest`, { + retryCount: 1, + stillWaiting: () => this.stillWaiting(), + }); + + if (!data) { + if (debugFlag('verbose-failures')) { + console.log(`Failed to get Latest Observations for station ${station.id}`); + } + return false; + } + + // Enhance observation data with METAR parsing for missing fields + const originalData = { ...data.properties }; + data.properties = augmentObservationWithMetar(data.properties); + const metarFields = [ + { name: 'temperature', check: (orig, metar) => orig.temperature.value === null && metar.temperature.value !== null }, + { name: 'windSpeed', check: (orig, metar) => orig.windSpeed.value === null && metar.windSpeed.value !== null }, + { name: 'windDirection', check: (orig, metar) => orig.windDirection.value === null && metar.windDirection.value !== null }, + ]; + const augmentedData = data.properties; + const metarReplacements = metarFields.filter((field) => field.check(originalData, augmentedData)).map((field) => field.name); + if (debugFlag('latestobservations') && metarReplacements.length > 0) { + console.log(`Latest Observations for station ${station.id} were augmented with METAR data for ${metarReplacements.join(', ')}`); + } + + // test data quality + const requiredFields = [ + { name: 'temperature', check: (props) => props.temperature?.value === null }, + { name: 'windSpeed', check: (props) => props.windSpeed?.value === null }, + { name: 'windDirection', check: (props) => props.windDirection?.value === null }, + { name: 'textDescription', check: (props) => props.textDescription === null || props.textDescription === '' }, + ]; + + // Use enhanced observation with MapClick fallback + const enhancedResult = await enhanceObservationWithMapClick(data.properties, { + requiredFields, + stationId: station.id, + stillWaiting: () => this.stillWaiting(), + debugContext: 'latestobservations', + }); + + data.properties = enhancedResult.data; + const { missingFields } = enhancedResult; + + // Check final data quality + if (missingFields.length > 0) { + if (debugFlag('latestobservations')) { + console.log(`Latest Observations for station ${station.id} is missing fields: ${missingFields.join(', ')}`); + } + return false; + } + + // format the return values + return { + ...data.properties, + StationId: station.id, + city: station.city, + }; + } catch (error) { + console.error(`Unexpected error getting latest observations for station ${station.id}: ${error.message}`); + return false; + } + })); + // filter false (no data or other error) + return stationData.filter((d) => d); + } + + async drawCanvas() { + super.drawCanvas(); + const conditions = this.data; + + // sort array by station name + const sortedConditions = conditions.sort((a, b) => ((a.Name < b.Name) ? -1 : 1)); + + if (settings.units.value === 'us') { + this.elem.querySelector('.column-headers .temp.english').classList.add('show'); + this.elem.querySelector('.column-headers .temp.metric').classList.remove('show'); + } else { + this.elem.querySelector('.column-headers .temp.english').classList.remove('show'); + this.elem.querySelector('.column-headers .temp.metric').classList.add('show'); + } + // get unit converters + const windConverter = windSpeed(); + const temperatureConverter = temperature(); + + const lines = sortedConditions.map((condition) => { + const windDirection = directionToNSEW(condition.windDirection.value); + + const Temperature = temperatureConverter(condition.temperature.value); + const WindSpeed = windConverter(condition.windSpeed.value); + + const fill = { + location: locationCleanup(condition.city).substr(0, 14), + temp: Temperature, + weather: shortenCurrentConditions(condition.textDescription).substr(0, 9), + }; + + if (WindSpeed > 0) { + fill.wind = windDirection + (Array(6 - windDirection.length - WindSpeed.toString().length).join(' ')) + WindSpeed.toString(); + } else if (WindSpeed === 'NA') { + fill.wind = 'NA'; + } else { + fill.wind = 'Calm'; + } + + return this.fillTemplate('observation-row', fill); + }); + + const linesContainer = this.elem.querySelector('.observation-lines'); + linesContainer.innerHTML = ''; + linesContainer.append(...lines); + + this.finishDraw(); + } +} + +const shortenCurrentConditions = (_condition) => { + let condition = _condition; + condition = condition.replace(/Light/, 'L'); + condition = condition.replace(/Heavy/, 'H'); + condition = condition.replace(/Partly/, 'P'); + condition = condition.replace(/Mostly/, 'M'); + condition = condition.replace(/Few/, 'F'); + condition = condition.replace(/Thunderstorm/, 'T\'storm'); + condition = condition.replace(/ in /, ''); + condition = condition.replace(/Vicinity/, ''); + condition = condition.replace(/ and /, ' '); + condition = condition.replace(/Freezing Rain/, 'Frz Rn'); + condition = condition.replace(/Freezing/, 'Frz'); + condition = condition.replace(/Unknown Precip/, ''); + condition = condition.replace(/L Snow Fog/, 'L Snw/Fog'); + condition = condition.replace(/ with /, '/'); + return condition; +}; +// register display +registerDisplay(new LatestObservations(2, 'latest-observations')); diff --git a/server/scripts/modules/radar.mjs b/server/scripts/modules/radar.mjs index 5c58dcd..f22eaf7 100644 --- a/server/scripts/modules/radar.mjs +++ b/server/scripts/modules/radar.mjs @@ -11,44 +11,9 @@ import { clearMarkers, } from './utils/leaflet-weather-map.mjs'; -const RADAR_METADATA_URL = 'https://api.rainviewer.com/public/weather-maps.json'; -const RADAR_METADATA_CACHE_TTL_MS = 2 * 60 * 1000; -let radarMetadataCache = null; - -const getRadarMetadataCached = async (stillWaiting) => { - const now = Date.now(); - if (radarMetadataCache && (now - radarMetadataCache.fetchedAt) < RADAR_METADATA_CACHE_TTL_MS) { - return radarMetadataCache.data; - } - - const radarMetadata = await safeJson(RADAR_METADATA_URL, { - retryCount: 2, - stillWaiting, - }); - - if (radarMetadata?.host && radarMetadata?.radar?.past?.length) { - radarMetadataCache = { - data: radarMetadata, - fetchedAt: now, - }; - return radarMetadata; - } - - if (radarMetadataCache) { - return radarMetadataCache.data; - } - - return null; -}; - -const haveRadarFramesChanged = (currentHost, currentFrames, nextHost, nextFrames) => { - if (currentHost !== nextHost) return true; - if (currentFrames.length !== nextFrames.length) return true; - - return currentFrames.some((frame, index) => frame?.path !== nextFrames[index]?.path || frame?.time !== nextFrames[index]?.time); -}; - class Radar extends WeatherDisplay { + static metadataUrl = 'https://api.rainviewer.com/public/weather-maps.json'; + constructor(navId, elemId) { super(navId, elemId, 'Local Radar'); @@ -83,7 +48,10 @@ class Radar extends WeatherDisplay { this.updateLocationMarker(); await this.updateNearbyMarkers(); - const radarMetadata = await getRadarMetadataCached(() => this.stillWaiting()); + const radarMetadata = await safeJson(Radar.metadataUrl, { + retryCount: 2, + stillWaiting: () => this.stillWaiting(), + }); const frames = radarMetadata?.radar?.past?.slice(-this.maxFrames) ?? []; if (!frames.length || !radarMetadata?.host) { @@ -93,25 +61,11 @@ class Radar extends WeatherDisplay { return; } - const currentFrameIndex = Math.max(0, Math.min(this.screenIndex < 0 ? this.mapFrames.length - 1 : this.screenIndex, frames.length - 1)); - const framesChanged = haveRadarFramesChanged(this.radarHost, this.mapFrames, radarMetadata.host, frames); this.radarHost = radarMetadata.host; this.mapFrames = frames; + this.resetRadarLayers(); this.timing.delay = this.buildTiming(); this.calcNavTiming(); - - if (framesChanged) { - this.resetRadarLayers(); - } - - if (refresh) { - if (framesChanged && this.active) { - this.showFrame(currentFrameIndex); - } - this.setStatus(STATUS.loaded); - return; - } - this.resetNavBaseCount(); this.showFrame(this.mapFrames.length - 1); this.setStatus(STATUS.loaded); diff --git a/server/scripts/modules/travelforecast.mjs b/server/scripts/modules/travelforecast.mjs index 676e875..1a77b9b 100644 --- a/server/scripts/modules/travelforecast.mjs +++ b/server/scripts/modules/travelforecast.mjs @@ -8,15 +8,16 @@ import { registerDisplay } from './navigation.mjs'; import calculateScrollTiming from './utils/scroll-timing.mjs'; import { debugFlag } from './utils/debug.mjs'; import { temperature } from './utils/units.mjs'; -import { getCachedAggregatedOpenMeteoForecast } from './utils/weather.mjs'; - -const MIN_TRAVEL_CITIES = 5; +import { getAggregatedOpenMeteoForecast } from './utils/weather.mjs'; class TravelForecast extends WeatherDisplay { constructor(navId, elemId, defaultActive) { // special height and width for scrolling super(navId, elemId, 'Travel Forecast', defaultActive); + // add previous data cache + this.previousData = []; + // cache for scroll calculations // This cache is essential because baseCountChange() is called 25 times per second (every 40ms) // during scrolling. Travel forecast scroll duration varies based on the number of cities configured. @@ -44,13 +45,30 @@ class TravelForecast extends WeatherDisplay { // super checks for enabled if (!super.getData(weatherParameters, refresh)) return; + // clear stored data if not refresh + if (!refresh) { + this.previousData = []; + } + const temperatureConverter = temperature(); const selectedTravelCities = getTravelCitiesForLocation(this.weatherParameters); - const forecastPromises = selectedTravelCities.map(async (city) => { + const forecastPromises = selectedTravelCities.map(async (city, index) => { try { - const forecast = await getCachedAggregatedOpenMeteoForecast(city.Latitude, city.Longitude); - if (!forecast) { + let forecast; + forecast = await getAggregatedOpenMeteoForecast(city.Latitude, city.Longitude); + + if (forecast) { + // store for the next run + this.previousData[index] = forecast; + } else if (this.previousData?.[index]) { + // if there's previous data use it + if (debugFlag('travelforecast')) { + console.warn(`Using previous forecast data for ${city.Name} travel forecast`); + } + forecast = this.previousData?.[index]; + } else { + // no current data and no previous data available if (debugFlag('verbose-failures')) { console.warn(`No travel forecast for ${city.Name} available`); } @@ -82,11 +100,7 @@ class TravelForecast extends WeatherDisplay { // wait for all forecasts using centralized safe Promise handling const forecasts = await safePromiseAll(forecastPromises); - const validForecasts = forecasts.filter((forecast) => forecast && !forecast.error && forecast.high !== undefined); - const invalidForecasts = forecasts.filter((forecast) => forecast && forecast.error); - this.data = validForecasts.length >= MIN_TRAVEL_CITIES - ? validForecasts - : [...validForecasts, ...invalidForecasts].slice(0, Math.max(validForecasts.length, MIN_TRAVEL_CITIES)); + this.data = forecasts; // test for some data available in at least one forecast const hasData = this.data.some((forecast) => forecast.high); diff --git a/server/scripts/modules/utils/leaflet-weather-map.mjs b/server/scripts/modules/utils/leaflet-weather-map.mjs index cd8ec39..4918210 100644 --- a/server/scripts/modules/utils/leaflet-weather-map.mjs +++ b/server/scripts/modules/utils/leaflet-weather-map.mjs @@ -2,14 +2,9 @@ import { safePromiseAll } from './fetch.mjs'; import { loadData } from './data-loader.mjs'; import { getSmallIconFromWmoCode } from '../icons.mjs'; import { getOpenMeteoObservationSnapshot } from './weather.mjs'; -import { temperature } from './units.mjs'; -const getBaseMapUrl = () => (window.WS4KP_SERVER_AVAILABLE - ? '/arcgis-server/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}' - : 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}'); -const getBoundaryMapUrl = () => (window.WS4KP_SERVER_AVAILABLE - ? '/arcgis-services/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}' - : 'https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}'); +const BASE_MAP_URL = 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}'; +const BOUNDARY_MAP_URL = 'https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}'; const DEFAULT_MAX_NEARBY_MARKERS = 7; const MIN_CITY_DISTANCE_METERS = 25000; const MIN_MARKER_PIXEL_DISTANCE = 85; @@ -30,14 +25,14 @@ const createMap = (mapElement) => window.L.map(mapElement, { }); const addBaseLayers = (map) => { - const baseLayer = window.L.tileLayer(getBaseMapUrl(), { + const baseLayer = window.L.tileLayer(BASE_MAP_URL, { maxZoom: 10, minZoom: 1, crossOrigin: true, className: 'radar-base-layer', }).addTo(map); - const boundaryLayer = window.L.tileLayer(getBoundaryMapUrl(), { + const boundaryLayer = window.L.tileLayer(BOUNDARY_MAP_URL, { maxZoom: 10, minZoom: 1, opacity: 0.6, @@ -105,13 +100,12 @@ const selectNearbyCities = (map, sourceLocation, cities, options = {}) => { }; const buildNearbyWeatherMarker = (city, observation) => { - const temperatureConverter = temperature(); const icon = getSmallIconFromWmoCode(observation.weatherCode, observation.isDay); const markerHtml = `
${city.name}
-
${temperatureConverter(observation.temperature)}
+
${Math.round(observation.temperature)}
${city.name} weather
`; diff --git a/server/scripts/modules/utils/url-rewrite.mjs b/server/scripts/modules/utils/url-rewrite.mjs index cc4267f..c815f0b 100644 --- a/server/scripts/modules/utils/url-rewrite.mjs +++ b/server/scripts/modules/utils/url-rewrite.mjs @@ -50,14 +50,6 @@ const rewriteUrl = (_url) => { url.protocol = window.location.protocol; url.host = window.location.host; url.pathname = `/rainviewer${url.pathname}`; - } else if (url.origin === 'https://server.arcgisonline.com') { - url.protocol = window.location.protocol; - url.host = window.location.host; - url.pathname = `/arcgis-server${url.pathname}`; - } else if (url.origin === 'https://services.arcgisonline.com') { - url.protocol = window.location.protocol; - url.host = window.location.host; - url.pathname = `/arcgis-services${url.pathname}`; } else if (typeof OVERRIDES !== 'undefined' && OVERRIDES?.RADAR_HOST && url.origin === `https://${OVERRIDES.RADAR_HOST}`) { // Handle override radar host url.protocol = window.location.protocol; diff --git a/server/scripts/modules/utils/weather.mjs b/server/scripts/modules/utils/weather.mjs index 8ddd837..5a67a4f 100644 --- a/server/scripts/modules/utils/weather.mjs +++ b/server/scripts/modules/utils/weather.mjs @@ -15,11 +15,6 @@ const OPEN_METEO_RADAR_OBSERVATION_PARAMETERS = [ 'models=best_match', ].join('&'); -const OPEN_METEO_OBSERVATION_CACHE_TTL_MS = 10 * 60 * 1000; -const OPEN_METEO_TRAVEL_FORECAST_CACHE_TTL_MS = 30 * 60 * 1000; -const openMeteoObservationCache = new Map(); -const openMeteoTravelForecastCache = new Map(); - const getPoint = async (lat, lon) => { const point = await safeJson(`https://api.weather.gov/points/${lat.toFixed(4)},${lon.toFixed(4)}`); if (!point) { @@ -60,49 +55,16 @@ const getAggregatedOpenMeteoForecast = async (lat, lon) => { }; }; -const getCachedAggregatedOpenMeteoForecast = async (lat, lon) => { - const cacheKey = `${lat.toFixed(4)},${lon.toFixed(4)}`; - const cachedEntry = openMeteoTravelForecastCache.get(cacheKey); - const now = Date.now(); - if (cachedEntry && (now - cachedEntry.fetchedAt) < OPEN_METEO_TRAVEL_FORECAST_CACHE_TTL_MS) { - return cachedEntry.data; - } - - const forecast = await getAggregatedOpenMeteoForecast(lat, lon); - if (forecast) { - openMeteoTravelForecastCache.set(cacheKey, { - data: forecast, - fetchedAt: now, - }); - return forecast; - } - - if (cachedEntry) { - return cachedEntry.data; - } - - return false; -}; - const getOpenMeteoObservationSnapshot = async (lat, lon) => { - const cacheKey = `${lat.toFixed(4)},${lon.toFixed(4)}`; - const cachedEntry = openMeteoObservationCache.get(cacheKey); - const now = Date.now(); - if (cachedEntry && (now - cachedEntry.fetchedAt) < OPEN_METEO_OBSERVATION_CACHE_TTL_MS) { - return cachedEntry.data; - } - const forecast = await safeJson(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&${OPEN_METEO_RADAR_OBSERVATION_PARAMETERS}`); if (!forecast?.hourly?.time?.length) { if (debugFlag('verbose-failures')) { console.warn(`Unable to get Open-Meteo radar observation snapshot for ${lat},${lon}`); } - if (cachedEntry) { - return cachedEntry.data; - } return false; } + const now = Date.now(); let nearestIndex = 0; let nearestDelta = Number.POSITIVE_INFINITY; @@ -114,20 +76,13 @@ const getOpenMeteoObservationSnapshot = async (lat, lon) => { } }); - const snapshot = { + return { time: forecast.hourly.time[nearestIndex], temperature: forecast.hourly.temperature_2m?.[nearestIndex] ?? null, weatherCode: forecast.hourly.weather_code?.[nearestIndex] ?? 0, isDay: Boolean(forecast.hourly.is_day?.[nearestIndex] ?? 1), timezone: forecast.timezone, }; - - openMeteoObservationCache.set(cacheKey, { - data: snapshot, - fetchedAt: now, - }); - - return snapshot; }; const weatherConditions = [ @@ -225,7 +180,6 @@ export { getPoint, getOpenMeteoForecast, getAggregatedOpenMeteoForecast, - getCachedAggregatedOpenMeteoForecast, getOpenMeteoObservationSnapshot, aggregateWeatherForecastData, getConditionText, diff --git a/server/styles/scss/_hourly.scss b/server/styles/scss/_hourly.scss index e2c46ed..44d1572 100644 --- a/server/styles/scss/_hourly.scss +++ b/server/styles/scss/_hourly.scss @@ -44,7 +44,12 @@ .hourly-lines { min-height: 338px; padding-top: 10px; - background: #0b0b39; + + background: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px, + c.$gradient-main-background-1 136px, + c.$gradient-main-background-1 202px, + c.$gradient-main-background-2 338px, + ); .hourly-row { font-family: 'Star4000 Large'; @@ -95,4 +100,4 @@ } } } -} +} \ No newline at end of file diff --git a/server/styles/scss/_latest-observations.scss b/server/styles/scss/_latest-observations.scss new file mode 100644 index 0000000..2910548 --- /dev/null +++ b/server/styles/scss/_latest-observations.scss @@ -0,0 +1,72 @@ +@use 'shared/_colors'as c; +@use 'shared/_utils'as u; + +.weather-display .latest-observations { + + &.main { + overflow-y: hidden; + + .column-headers { + height: 20px; + position: absolute; + width: 100%; + } + + .column-headers { + top: 0px; + + div { + display: inline-block; + font-family: 'Star4000 Small'; + font-size: 24pt; + position: absolute; + top: -14px; + @include u.text-shadow(); + } + + .temp { + // hidden initially for english/metric switching + display: none; + + &.show { + display: inline-block; + } + } + } + + .temp { + left: 230px; + } + + .weather { + left: 280px; + } + + .wind { + left: 430px; + } + + .observation-lines { + min-height: 338px; + padding-top: 10px; + + .observation-row { + font-family: 'Star4000'; + font-size: 24pt; + @include u.text-shadow(); + position: relative; + height: 40px; + + >div { + position: absolute; + top: 8px; + } + + .wind { + white-space: pre; + text-align: right; + } + } + } + } +} \ No newline at end of file diff --git a/server/styles/scss/_radar.scss b/server/styles/scss/_radar.scss index d0722a7..1600e17 100644 --- a/server/styles/scss/_radar.scss +++ b/server/styles/scss/_radar.scss @@ -37,7 +37,7 @@ .scale-table { display: flex; justify-content: center; - gap: 4px; + gap: 7px; .item { display: flex; diff --git a/server/styles/scss/_travel.scss b/server/styles/scss/_travel.scss index ac8778f..add8642 100644 --- a/server/styles/scss/_travel.scss +++ b/server/styles/scss/_travel.scss @@ -44,7 +44,12 @@ .travel-lines { min-height: 338px; padding-top: 10px; - background: #0b0b39; + + background: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px, + c.$gradient-main-background-1 136px, + c.$gradient-main-background-1 202px, + c.$gradient-main-background-2 338px, + ); .travel-row { font-family: 'Star4000 Large'; diff --git a/server/styles/scss/_weather-display.scss b/server/styles/scss/_weather-display.scss index f476ed0..6c79637 100644 --- a/server/styles/scss/_weather-display.scss +++ b/server/styles/scss/_weather-display.scss @@ -97,7 +97,7 @@ &.has-scroll { width: 640px; margin-top: 0; - height: 320px; + height: 310px; overflow: hidden; &.no-header { diff --git a/server/styles/scss/ws.scss b/server/styles/scss/ws.scss index 786e148..2644340 100644 --- a/server/styles/scss/ws.scss +++ b/server/styles/scss/ws.scss @@ -5,6 +5,7 @@ @use 'hourly'; @use 'hourly-graph'; @use 'travel'; +@use 'latest-observations'; @use 'local-forecast'; @use 'progress'; @use 'radar'; diff --git a/server/styles/ws.min.css b/server/styles/ws.min.css index 0298f5f..f56aa5c 100644 --- a/server/styles/ws.min.css +++ b/server/styles/ws.min.css @@ -1,2 +1,2 @@ -@font-face{font-family:"Star4000";src:url("../fonts/Star4000.woff") format("woff");font-display:swap}body{font-family:"Star4000";margin:0}@media(prefers-color-scheme: dark){body{background-color:#000;color:#fff}}@media(prefers-color-scheme: dark){body a{color:#add8e6}}body.kiosk{margin:0px;padding:0px;overflow:hidden;width:100vw;background-color:#000 !important}#divQuery{max-width:640px;padding:8px}#divQuery .buttons{display:inline-block;width:150px;text-align:right}#divQuery .buttons #imgGetGps{height:13px;vertical-align:middle}#divQuery .buttons button{font-size:16pt;border:1px solid #a9a9a9}@media(prefers-color-scheme: dark){#divQuery .buttons button{background-color:#000;color:#fff}}#divQuery .buttons #btnGetGps img.dark{display:none}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.dark{display:inline-block}}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.light{display:none}}#divQuery .buttons #btnGetGps.active{background-color:#000}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps.active{background-color:#fff}}#divQuery .buttons #btnGetGps.active img{filter:invert(1)}#divQuery input,#divQuery button{font-family:"Star4000"}#divQuery #txtLocation{width:calc(100% - 170px);max-width:490px;font-size:16pt;min-width:200px;display:inline-block;background-color:#fff;color:#000;border:2px inset gray}@media(prefers-color-scheme: dark){#divQuery #txtLocation{background-color:#000;color:#fff;border:2px inset gray}}.autocomplete-suggestions{background-color:#fff;border:1px solid #000;position:absolute;z-index:9999}@media(prefers-color-scheme: dark){.autocomplete-suggestions{background-color:#000}}.autocomplete-suggestions div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16pt}.autocomplete-suggestions div.selected{background-color:blue;color:#fff}#divTwc{display:block;background-color:#000;color:#fff;width:100%;max-width:640px;margin:0}#divTwc.wide{max-width:854px}.content-wrapper{padding:8px}#divTwcMain{width:640px;height:480px;position:relative}.wide #divTwcMain{width:854px}.kiosk #divTwc{max-width:unset}#divTwcLeft{display:none;text-align:right;flex-direction:column;vertical-align:middle}#divTwcLeft>div{flex:1;padding-right:12px;display:flex;flex-direction:column;justify-content:center}#divTwcRight{text-align:left;display:none;flex-direction:column;vertical-align:middle}#divTwcRight>div{flex:1;padding-left:12px;display:flex;flex-direction:column;justify-content:center}#divTwcBottom{display:flex;flex-direction:row;background-color:#000;color:#fff;width:640px}.wide #divTwcBottom{width:854px}@media(prefers-color-scheme: dark){#divTwcBottom{background-color:#303030}}#divTwcBottom>div{padding-left:6px;padding-right:6px}@media(max-width: 550px){#divTwcBottom>div{font-size:.9em}}@media(max-width: 500px){#divTwcBottom>div{font-size:.8em}}@media(max-width: 450px){#divTwcBottom>div{font-size:.7em}}@media(max-width: 400px){#divTwcBottom>div{font-size:.6em}}@media(max-width: 350px){#divTwcBottom>div{font-size:.5em}}#divTwcBottomLeft{flex:1;text-align:left}#divTwcBottomMiddle{flex:0;text-align:center}#divTwcBottomRight{flex:1;text-align:right}#divTwcNavContainer{display:none}#divTwcNav{width:100%;display:flex;flex-direction:row;background-color:#000;color:#fff;max-width:640px}#divTwcNav>div{padding-left:6px;padding-right:6px}#divTwcNavLeft{flex:1;text-align:left}#divTwcNavMiddle{flex:0;text-align:center}#divTwcNavRight{flex:1;text-align:right}#imgPause1x{visibility:hidden;position:absolute}.HideCursor{cursor:none !important}#txtScrollText{width:475px}@font-face{font-family:"Star4000 Extended";src:url("../fonts/Star4000 Extended.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Large";src:url("../fonts/Star4000 Large.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Small";src:url("../fonts/Star4000 Small.woff") format("woff");font-display:swap}#display{font-family:"Star4000";margin:0 0 0 0;width:100%}#container{position:relative;width:640px;height:480px;background-image:url(../images/backgrounds/1.png);transform-origin:0 0;background-repeat:no-repeat}.wide #container{padding-left:107px;padding-right:107px;background:url(../images/backgrounds/1-wide.png);background-repeat:no-repeat}#divTwc:fullscreen #container,.kiosk #divTwc #container{width:unset;height:unset}#loading{width:640px;height:480px;max-width:100%;text-shadow:4px 4px #000;display:flex;align-items:center;text-align:center;justify-content:center}#loading .title{font-family:Star4000 Large;font-size:36px;color:#ff0;margin-bottom:0px}#loading .version{margin-bottom:35px}#loading .instructions{font-size:18pt}.heading{font-weight:bold;margin-top:15px}#settings{margin-bottom:15px}#enabledDisplays,#settings{margin-bottom:15px}#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#ff0}#enabledDisplays .press-here,#settings .press-here{color:lime;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:red}#enabledDisplays .no-data,#settings .no-data{color:silver}#enabledDisplays .disabled,#settings .disabled{color:silver}#enabledDisplays .press-here,#settings .press-here{color:#fff}@media(prefers-color-scheme: light){#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#990}#enabledDisplays .press-here,#settings .press-here{color:#000;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:#900}#enabledDisplays .no-data,#settings .no-data{color:hsl(0,0%,30%)}#enabledDisplays .disabled,#settings .disabled{color:hsl(0,0%,30%)}}#enabledDisplays label,#settings label{display:block;max-width:fit-content;cursor:pointer}#enabledDisplays label .alert,#settings label .alert{display:none}#enabledDisplays label .alert.show,#settings label .alert.show{display:inline;color:red}#divTwcBottom img{transform:scale(0.75)}@media(max-width: 550px){.wide #divTwcBottom img{transform:scale(1)}}#divTwc:fullscreen,.kiosk #divTwc{display:flex;align-items:center;justify-content:center;align-content:center}#divTwc:fullscreen.no-cursor,.kiosk #divTwc.no-cursor{cursor:none}#divTwc:fullscreen #display,.kiosk #divTwc #display{position:relative}#divTwc:fullscreen #divTwcBottom,.kiosk #divTwc #divTwcBottom{display:flex;flex-direction:row;background-color:rgba(0,0,0,.5);color:#fff;width:100%;position:absolute;bottom:0px}.kiosk #divTwc #divTwcBottom{display:none}.navButton{cursor:pointer}#ToggleScanlines{display:inline-block}#ToggleScanlines .on{display:none}#ToggleScanlines .off{display:inline-block}#ToggleScanlines.on .on{display:inline-block}#ToggleScanlines.on .off{display:none}.visible{visibility:visible;opacity:1;transition:opacity .1s linear}#divTwc:fullscreen .hidden{visibility:hidden;opacity:0;transition:visibility 0s 1s,opacity 1s linear}.github-links{width:610px;max-width:calc(100vw - 30px);display:flex;justify-content:space-evenly;flex-wrap:wrap}.github-links span a{text-decoration:none;outline:0}.github-links span .widget{display:inline-block;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:0;line-height:0;white-space:nowrap}.github-links span .btn,.github-links span .social-count{position:relative;display:inline-block;display:inline-flex;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid}.github-links span .btn{border-radius:.25em}.github-links span .btn:not(:last-child){border-radius:.25em 0 0 .25em}.github-links span .social-count{border-left:0;border-radius:0 .25em .25em 0}.github-links span .widget-lg .btn,.github-links span .widget-lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.github-links span .octicon{display:inline-block;vertical-align:text-top;fill:currentColor;overflow:visible}.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}@media(prefers-color-scheme: light){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}}@media(prefers-color-scheme: dark){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #58a6ff;outline-offset:-2px}.github-links span .btn{color:#c9d1d9;background-color:#1a1e23;border-color:#2f3439;border-color:rgba(240,246,252,.1);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #21262d, #1a1e23 90%);background-image:linear-gradient(180deg, #21262d, #1a1e23 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#292e33;background-position:0 -0.5em;border-color:#8b949e;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #30363d, #292e33 90%);background-image:linear-gradient(180deg, #30363d, #292e33 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#161719;border-color:#8b949e;box-shadow:inset 0 .15em .3em rgba(1,4,9,.15);background-image:none;filter:none}.github-links span .social-count{color:#c9d1d9;background-color:#0d1117;border-color:#24282e;border-color:rgba(240,246,252,.1)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#58a6ff}.github-links span .octicon-heart{color:#db61a2}}#share-link-copied{color:#990;display:none}#share-link-instructions{display:none}body.kiosk #loading .instructions{display:none !important}.kiosk>*:not(#divTwc){display:none !important}#divInfo{display:grid;grid-template-columns:1fr 1fr;max-width:250px}.weather-display{width:640px;height:480px;overflow:hidden;position:relative;background-image:url(../images/backgrounds/1.png);height:0px}.weather-display.show{height:480px}.weather-display .template{display:none}.weather-display .header{width:640px;height:60px;padding-top:30px;position:relative;z-index:20}.weather-display .header .title{color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000";font-size:24pt;position:absolute;width:250px}.weather-display .header .title.single{left:170px;top:25px}.weather-display .header .title.dual{left:170px}.weather-display .header .title.dual>div{position:absolute}.weather-display .header .title.dual .top{top:-3px}.weather-display .header .title.dual .bottom{top:26px}.weather-display .header .logo{top:30px;left:50px;position:absolute;z-index:10}.weather-display .header .noaa-logo{position:absolute;top:39px;left:356px}.weather-display .header .title.single{top:40px}.weather-display .header .date-time{white-space:pre;color:#fff;font-family:"Star4000 Small";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;left:415px;width:170px;text-align:right;position:absolute}.weather-display .header .date-time.date{padding-top:22px}.weather-display .main{position:relative}.weather-display .main.has-scroll{width:640px;margin-top:0;height:320px;overflow:hidden}.weather-display .main.has-scroll.no-header{height:400px;margin-top:0}.weather-display .main.has-box{margin-left:64px;margin-right:64px;width:calc(100% - 128px)}#container>.scroll{display:none;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;width:640px;height:77px;overflow:hidden;margin-top:3px;position:absolute;bottom:0px;z-index:1}#container>.scroll.hazard{background-color:#702323}#container>.scroll .scroll-container{width:640px}#container>.scroll .scroll-container .fixed,#container>.scroll .scroll-container .scroll-header{margin-left:55px;margin-right:55px;overflow:hidden;white-space:nowrap}#container>.scroll .scroll-container .scroll-header{height:26px;font-family:"Star4000 Small";font-size:20pt;margin-top:-10px}#container>.scroll .scroll-container .fixed{font-family:"Star4000";font-size:24pt}#container>.scroll .scroll-container .fixed .scroll-area{text-wrap:nowrap;position:relative}.wide #container>.scroll{width:854px;margin-left:-107px}.wide #container>.scroll .scroll-container{margin-left:107px}.weather-display .main.current-weather.main .col{height:50px;width:255px;display:inline-block;margin-top:10px;padding-top:10px;position:absolute;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.current-weather.main .col.left{font-family:"Star4000 Extended";font-size:24pt}.weather-display .main.current-weather.main .col.right{right:0px;font-family:"Star4000 Large";font-size:20px;font-weight:bold;line-height:24px}.weather-display .main.current-weather.main .col.right .row{margin-bottom:12px}.weather-display .main.current-weather.main .col.right .row .label,.weather-display .main.current-weather.main .col.right .row .value{display:inline-block}.weather-display .main.current-weather.main .col.right .row .label{margin-left:20px}.weather-display .main.current-weather.main .col.right .row .value{float:right;margin-right:10px}.weather-display .main.current-weather.main .center{text-align:center}.weather-display .main.current-weather.main .temp{font-family:"Star4000 Large";font-size:24pt}.weather-display .main.current-weather.main .icon img{margin:0 auto;display:block}.weather-display .main.current-weather.main .wind-container{margin-left:10px;display:flex}.weather-display .main.current-weather.main .wind-container>div{width:50%}.weather-display .main.current-weather.main .wind-container .wind{text-align:right}.weather-display .main.current-weather.main .wind-gusts{text-align:right;font-size:28px}.weather-display .main.current-weather.main .location{color:#ff0;max-height:32px;margin-bottom:10px;padding-top:4px;overflow:hidden;text-wrap:nowrap}#extended-forecast-html.weather-display{background-image:url("../images/backgrounds/2.png")}.weather-display .main.extended-forecast .day-container{margin-top:16px;margin-left:27px}.weather-display .main.extended-forecast .day{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding:5px;height:285px;width:155px;display:inline-block;margin:0px 15px;font-family:"Star4000";font-size:24pt}.weather-display .main.extended-forecast .day .date{text-transform:uppercase;text-align:center;color:#ff0}.weather-display .main.extended-forecast .day .condition{text-align:center;height:74px;margin-top:5px}.weather-display .main.extended-forecast .day .icon{text-align:center;height:75px}.weather-display .main.extended-forecast .day .icon img{max-height:75px}.weather-display .main.extended-forecast .day .temperatures{width:100%}.weather-display .main.extended-forecast .day .temperatures .temperature-block{display:inline-block;width:44%;vertical-align:top}.weather-display .main.extended-forecast .day .temperatures .temperature-block>div{text-align:center}.weather-display .main.extended-forecast .day .temperatures .temperature-block .value{font-family:"Star4000 Large";margin-top:4px}.weather-display .main.extended-forecast .day .temperatures .temperature-block.lo .label{color:#8080ff}.weather-display .main.extended-forecast .day .temperatures .temperature-block.hi .label{color:#ff0}.weather-display .main.hourly.main{overflow-y:hidden}.weather-display .main.hourly.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.hourly.main .column-headers .temp{left:355px}.weather-display .main.hourly.main .column-headers .like{left:435px}.weather-display .main.hourly.main .column-headers .wind{left:535px}.weather-display .main.hourly.main .hourly-lines{min-height:338px;padding-top:10px;background:#0b0b39}.weather-display .main.hourly.main .hourly-lines .hourly-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.hourly.main .hourly-lines .hourly-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.hourly.main .hourly-lines .hourly-row .hour{left:25px}.weather-display .main.hourly.main .hourly-lines .hourly-row .icon{left:255px;width:70px;text-align:center;top:unset}.weather-display .main.hourly.main .hourly-lines .hourly-row .temp{left:355px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like{left:425px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.heat-index{color:#e00}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.wind-chill{color:#8080ff}.weather-display .main.hourly.main .hourly-lines .hourly-row .wind{left:505px;width:100px;text-align:right}#hourly-graph-html{background-image:url(../images/backgrounds/1-chart.png)}#hourly-graph-html .header .right{position:absolute;top:35px;right:60px;width:360px;font-family:"Star4000 Small";font-size:28px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:right}#hourly-graph-html .header .right div{margin-top:-18px}#hourly-graph-html .header .right .temperature{color:red}#hourly-graph-html .header .right .dewpoint{color:green}#hourly-graph-html .header .right .cloud{color:#d3d3d3}#hourly-graph-html .header .right .rain{color:aqua}.weather-display .main.hourly-graph.main>div{position:absolute}.weather-display .main.hourly-graph.main .label{font-family:"Star4000 Small";font-size:24pt;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;margin-top:-15px;position:absolute}.weather-display .main.hourly-graph.main .x-axis{bottom:0px;left:54px;width:532px;height:20px}.weather-display .main.hourly-graph.main .x-axis .label{text-align:center;transform:translateX(-50%);white-space:nowrap}.weather-display .main.hourly-graph.main .x-axis .label.l-1{left:0px}.weather-display .main.hourly-graph.main .x-axis .label.l-2{left:133px}.weather-display .main.hourly-graph.main .x-axis .label.l-3{left:266px}.weather-display .main.hourly-graph.main .x-axis .label.l-4{left:399px}.weather-display .main.hourly-graph.main .x-axis .label.l-5{left:532px}.weather-display .main.hourly-graph.main .chart{top:0px;left:50px}.weather-display .main.hourly-graph.main .chart img{width:532px;height:285px}.weather-display .main.hourly-graph.main .y-axis{top:0px;left:0px;width:50px;height:285px}.weather-display .main.hourly-graph.main .y-axis .label{text-align:right;right:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-1{top:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-2{top:93.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-3{bottom:82.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-4{bottom:0px}.weather-display .main.hourly-graph.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly-graph.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly-graph.main .column-headers .temp{left:355px}.weather-display .main.hourly-graph.main .column-headers .like{left:435px}.weather-display .main.hourly-graph.main .column-headers .wind{left:535px}.weather-display .main.travel.main{overflow-y:hidden}.weather-display .main.travel.main .column-headers{background-color:#200057;height:20px;position:sticky;top:0px;width:100%;z-index:5;overflow:hidden}.weather-display .main.travel.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.travel.main .column-headers .temp{width:50px;text-align:center}.weather-display .main.travel.main .column-headers .temp.low{left:455px}.weather-display .main.travel.main .column-headers .temp.high{left:510px;width:60px}.weather-display .main.travel.main .travel-lines{min-height:338px;padding-top:10px;background:#0b0b39}.weather-display .main.travel.main .travel-lines .travel-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.travel.main .travel-lines .travel-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.travel.main .travel-lines .travel-row .city{left:80px}.weather-display .main.travel.main .travel-lines .travel-row .icon{left:330px;width:70px;text-align:center;top:unset}.weather-display .main.travel.main .travel-lines .travel-row .icon img{max-width:47px}.weather-display .main.travel.main .travel-lines .travel-row .temp{width:50px;text-align:center}.weather-display .main.travel.main .travel-lines .travel-row .temp.low{left:455px}.weather-display .main.travel.main .travel-lines .travel-row .temp.high{left:510px;width:60px}.weather-display .local-forecast .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:280px;overflow:hidden}.weather-display .local-forecast .forecasts{position:relative}.weather-display .local-forecast .forecast{font-family:"Star4000";font-size:24pt;text-transform:uppercase;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;min-height:280px;line-height:40px}.weather-display .progress{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000 Extended";font-size:18pt}.weather-display .progress .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:310px;overflow:hidden;line-height:26px}.weather-display .progress .container .item{position:relative}.weather-display .progress .container .item .name{white-space:nowrap}.weather-display .progress .container .item .name::after{content:"........................................................................"}.weather-display .progress .container .item .links{position:absolute;text-align:right;right:0px;top:0px}.weather-display .progress .container .item .links>div{background-color:#26235a;display:none;padding-left:4px}.weather-display .progress .container .item .links .loading,.weather-display .progress .container .item .links .retrying{color:#ff0}.weather-display .progress .container .item .links .press-here{color:lime;cursor:pointer}.weather-display .progress .container .item .links .failed{color:red}.weather-display .progress .container .item .links .no-data{color:silver}.weather-display .progress .container .item .links .disabled{color:silver}.weather-display .progress .container .item .links.loading .loading,.weather-display .progress .container .item .links.press-here .press-here,.weather-display .progress .container .item .links.failed .failed,.weather-display .progress .container .item .links.no-data .no-data,.weather-display .progress .container .item .links.disabled .disabled,.weather-display .progress .container .item .links.retrying .retrying{display:block}@keyframes progress-scroll{0%{background-position:-40px 0}100%{background-position:40px 0}}#progress-html.weather-display .scroll .progress-bar-container{border:2px solid #000;background-color:#fff;margin:20px auto;width:524px;position:relative;display:none}#progress-html.weather-display .scroll .progress-bar-container.show{display:block}#progress-html.weather-display .scroll .progress-bar-container .progress-bar{height:20px;margin:2px;width:520px;background:repeating-linear-gradient(90deg, #09246f 0px, #09246f 5px, #364ac0 5px, #364ac0 10px, #4f99f9 10px, #4f99f9 15px, #8ffdfa 15px, #8ffdfa 20px, #4f99f9 20px, #4f99f9 25px, #364ac0 25px, #364ac0 30px, #09246f 30px, #09246f 40px);animation-duration:2s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:progress-scroll;animation-timing-function:steps(8, end)}#progress-html.weather-display .scroll .progress-bar-container .cover{position:absolute;top:0px;right:0px;background-color:#fff;width:100%;height:24px;transition:width 1s steps(6)}#radar-html.weather-display{background-image:url("../images/backgrounds/4.png")}#radar-html.weather-display .header{height:83px}#radar-html.weather-display .header .title.dual{color:#fff;font-family:"Arial",sans-serif;font-weight:bold;font-size:28pt;left:155px}#radar-html.weather-display .header .title.dual .top{top:-4px}#radar-html.weather-display .header .title.dual .bottom{top:31px}#radar-html.weather-display .header .right{position:absolute;right:0px;width:360px;margin-top:2px;font-family:"Star4000";font-size:18pt;font-weight:bold;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:center}#radar-html.weather-display .header .right .scale-table{display:flex;justify-content:center;gap:4px}#radar-html.weather-display .header .right .scale-table .item{display:flex;flex-direction:column;align-items:center;width:25px;gap:2px}#radar-html.weather-display .header .right .scale-table .box{display:block;border:2px solid #000;width:100%;height:22px;padding:0}#radar-html.weather-display .header .right .scale-table .box-1{background-color:#49bef6}#radar-html.weather-display .header .right .scale-table .box-2{background-color:#31d216}#radar-html.weather-display .header .right .scale-table .box-3{background-color:#f1e458}#radar-html.weather-display .header .right .scale-table .box-4{background-color:#e08e2f}#radar-html.weather-display .header .right .scale-table .box-5{background-color:#c42a2a}#radar-html.weather-display .header .right .scale-table .box-6{background-color:#913bb8}#radar-html.weather-display .header .right .scale-table .label{font-family:"Star4000 Small";font-size:10pt;line-height:1;white-space:nowrap}#radar-html.weather-display .header .right .scale{margin-top:-2px}#radar-html.weather-display .header .right .time{position:relative;font-weight:normal;top:-20px;font-family:"Star4000 Small";font-size:18pt;left:130px}.weather-display .main.radar{overflow:hidden;height:367px}.weather-display .main.radar .container{position:relative;height:100%}.weather-display .main.radar .container .scroll-area{position:relative;height:100%}.weather-display .main.radar .container .frame{height:100%}.weather-display .main.radar .container .map{height:100%;width:100%}.weather-display .main.radar .container .leaflet-map{height:100%;width:100%;background:#061f3e}.weather-display .main.radar .container .leaflet-container{background:#061f3e;font-family:inherit}.weather-display .main.radar .container .radar-base-layer,.weather-display .main.radar .container .radar-base-layer .leaflet-tile{filter:grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2)}.weather-display .main.radar .container .radar-boundary-layer,.weather-display .main.radar .container .radar-boundary-layer .leaflet-tile{filter:grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1)}.weather-display .main.radar .container .leaflet-control-container,.weather-display .main.radar .container .leaflet-control-attribution,.weather-display .main.radar .container .leaflet-control-zoom{display:none}.weather-display .main.radar .container .location-marker{background:#ff0;border:2px solid #000;border-radius:50%}.weather-display .main.radar .container .nearby-weather-marker{background:rgba(0,0,0,0);border:0}.weather-display .main.radar .container .nearby-weather-marker .nearby-weather-marker-inner{display:flex;flex-direction:column;align-items:center;min-width:72px;padding:2px 4px;background:rgba(18,34,61,.88);border:1px solid #000;box-shadow:1px 1px 0 #000;color:#fff;text-align:center}.weather-display .main.radar .container .nearby-weather-marker .city{font-family:"Star4000 Small";font-size:11pt;line-height:1;white-space:nowrap;margin-bottom:1px;text-shadow:1px 1px 0 #000}.weather-display .main.radar .container .nearby-weather-marker .details{display:flex;align-items:center;gap:2px}.weather-display .main.radar .container .nearby-weather-marker .temp{font-family:"Star4000";font-size:18pt;line-height:1;color:#ff0;text-shadow:1px 1px 0 #000}.weather-display .main.radar .container .nearby-weather-marker img{width:auto;height:20px}.wide.radar #container{background:url(../images/backgrounds/4-wide.png)}#regional-forecast-html.weather-display{background-image:url("../images/backgrounds/5.png")}.weather-display .main.regional-forecast{position:relative;overflow:hidden;z-index:0}.weather-display .main.regional-forecast .map{position:absolute;inset:0}.weather-display .main.regional-forecast .leaflet-map{height:100%;width:100%;background:#061f3e}.weather-display .main.regional-forecast .leaflet-container{background:#061f3e;font-family:inherit}.weather-display .main.regional-forecast .radar-base-layer,.weather-display .main.regional-forecast .radar-base-layer .leaflet-tile{filter:grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2)}.weather-display .main.regional-forecast .radar-boundary-layer,.weather-display .main.regional-forecast .radar-boundary-layer .leaflet-tile{filter:grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1)}.weather-display .main.regional-forecast .leaflet-control-container,.weather-display .main.regional-forecast .leaflet-control-attribution,.weather-display .main.regional-forecast .leaflet-control-zoom{display:none}.weather-display .main.regional-forecast .location-marker{background:#ff0;border:2px solid #000;border-radius:50%}.weather-display .main.regional-forecast .nearby-weather-marker{background:rgba(0,0,0,0);border:0}.weather-display .main.regional-forecast .nearby-weather-marker .nearby-weather-marker-inner{display:flex;flex-direction:column;align-items:center;min-width:72px;padding:2px 4px;background:rgba(18,34,61,.88);border:1px solid #000;box-shadow:1px 1px 0 #000;color:#fff;text-align:center}.weather-display .main.regional-forecast .nearby-weather-marker .city{font-family:"Star4000 Small";font-size:11pt;line-height:1;white-space:nowrap;margin-bottom:1px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.regional-forecast .nearby-weather-marker .details{display:flex;align-items:center;gap:2px}.weather-display .main.regional-forecast .nearby-weather-marker .temp{font-family:"Star4000";font-size:18pt;line-height:1;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.regional-forecast .nearby-weather-marker img{width:auto;height:20px}#almanac-html.weather-display{background-image:url("../images/backgrounds/3.png")}.weather-display .main.almanac{font-family:"Star4000";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.almanac .sun{display:grid;grid-template-columns:auto auto auto;grid-template-rows:auto auto auto;gap:0px 90px;margin:3px auto 5px auto;width:fit-content;line-height:30px}.weather-display .main.almanac .sun .grid-item{width:auto;height:auto;padding:0;margin:0;position:relative}.weather-display .main.almanac .sun .grid-item.header{color:#ff0;text-align:center}.weather-display .main.almanac .sun .grid-item.row-label{text-align:right}.weather-display .main.almanac .sun .grid-item.time{text-align:center}.weather-display .main.almanac .moon{position:relative;padding:7px 50px;line-height:36px}.weather-display .main.almanac .moon .title{color:#ff0;padding-left:13px}.weather-display .main.almanac .moon .day{display:inline-block;text-align:center;width:132px}.weather-display .main.almanac .moon .day .icon{padding-left:10px}.weather-display .main.almanac .moon .day .date{position:relative;top:-10px}#hazards-html.weather-display{background-image:url("../images/backgrounds/7.png")}.weather-display .main.hazards.main{overflow-y:hidden;height:480px;background-color:#702323}.weather-display .main.hazards.main .hazard-lines{min-height:400px;padding-top:10px}.weather-display .main.hazards.main .hazard-lines .hazard{font-family:"Star4000";font-size:24pt;color:#fff;text-shadow:0px 0px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative;text-transform:uppercase;margin-top:10px;margin-left:80px;margin-right:80px;padding-bottom:10px}.wide.hazards #container{background:url(../images/backgrounds/7-wide.png)}.media{display:none}#ToggleMediaContainer{display:none;position:relative}#ToggleMediaContainer.available{display:inline-block}#ToggleMediaContainer.available img.on{display:none}#ToggleMediaContainer.available img.off{display:block}#ToggleMediaContainer.available.playing img.on{display:block}#ToggleMediaContainer.available.playing img.off{display:none}#ToggleMediaContainer .volume-slider{display:none;position:absolute;top:0px;transform:translateY(-100%);width:100%;background-color:#000;text-align:center;z-index:100}@media(prefers-color-scheme: dark){#ToggleMediaContainer .volume-slider{background-color:#303030}}#ToggleMediaContainer .volume-slider input[type=range]{writing-mode:vertical-lr;direction:rtl;margin-top:20px;margin-bottom:20px}#ToggleMediaContainer .volume-slider.show{display:block}#spc-outlook-html.weather-display{background-image:url("../images/backgrounds/6.png")}.weather-display .spc-outlook .container{position:relative;top:0px;margin:0px 10px;box-sizing:border-box;height:300px;overflow:hidden}.weather-display .spc-outlook .risk-levels{position:absolute;left:206px;font-family:"Star4000 Small";font-size:32px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .spc-outlook .risk-levels .risk-level{position:relative;top:-14px;height:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(1){left:100px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(2){left:80px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(3){left:60px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(4){left:40px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(5){left:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(6){left:0px}.weather-display .spc-outlook .days{position:absolute;top:120px}.weather-display .spc-outlook .days .day{height:60px}.weather-display .spc-outlook .days .day .day-name{position:absolute;font-family:"Star4000";font-size:24pt;width:200px;text-align:right;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding-top:20px}.weather-display .spc-outlook .days .day .risk-bar{position:absolute;width:150px;height:40px;left:210px;margin-top:20px;border:3px outset hsl(0,0%,70%);background:linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%)}#server-observations-html.weather-display .header .title.single{font-size:20pt}.weather-display .server-observations.main{height:auto !important;min-height:250px}.weather-display .server-observations .container{position:relative;top:15px;box-sizing:border-box;height:250px;overflow:hidden}.weather-display .server-observations .server-output{position:relative;font-family:"Star4000";font-size:20pt;line-height:32px;color:#fff;text-transform:uppercase;text-align:center;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .server-observations .server-output .server-page{height:250px;padding:0 8px;box-sizing:border-box}.weather-display .server-observations .server-output .server-line{white-space:normal;overflow-wrap:anywhere;word-break:break-word;margin-bottom:6px}.weather-display .linux-news.main{height:auto !important;min-height:250px}.weather-display .linux-news .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:250px;overflow:hidden}.weather-display .linux-news .news-output{position:relative}.weather-display .linux-news .news-output .news-page{height:250px;box-sizing:border-box;padding:0 8px;display:flex;flex-direction:column;justify-content:space-between}.weather-display .linux-news .news-output .story{height:116px;overflow:hidden}.weather-display .linux-news .news-output .headline{font-family:"Star4000";font-size:17pt;line-height:22px;color:#ff0;text-transform:uppercase;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;margin-bottom:4px}.weather-display .linux-news .news-output .blurb{font-family:"Star4000";font-size:14pt;line-height:16px;color:#fff;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;overflow:hidden}.scanlines{position:relative;overflow:hidden;isolation:isolate}.scanlines #container{position:relative;z-index:1;transform:translateZ(0);will-change:filter;filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98)}.scanlines #container::before,.scanlines #container::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:3}.scanlines #container::before{background:linear-gradient(to right, rgba(255, 0, 0, 0.04) 0%, rgba(255, 0, 0, 0.01) 15%, rgba(255, 0, 0, 0) 50%, rgba(255, 0, 0, 0.01) 85%, rgba(255, 0, 0, 0.04) 100%);transform:translateX(-0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines #container::after{background:linear-gradient(to right, rgba(0, 140, 255, 0.04) 0%, rgba(0, 140, 255, 0.01) 15%, rgba(0, 140, 255, 0) 50%, rgba(0, 140, 255, 0.01) 85%, rgba(0, 140, 255, 0.04) 100%);transform:translateX(0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines:before,.scanlines:after{display:block;pointer-events:none;content:"";position:absolute;left:0;right:0}.scanlines:before{height:var(--scanline-thickness, 1px);z-index:2147483650;background:rgba(0,0,0,.3);opacity:.75;animation:scanline 6s linear infinite}.scanlines:after{top:0;bottom:0;z-index:2147483648;background:repeating-linear-gradient(to bottom, transparent 0, transparent var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) calc(var(--scanline-thickness, 1px) * 2));animation:none}.scanlines{box-shadow:inset 0 0 80px rgba(0,0,0,.16),inset 0 0 18px hsla(0,0%,100%,.05)}.scanlines.crt-panels-only #container{filter:none}.scanlines.crt-panels-only .weather-display{filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98);transform:translateZ(0)}.scanlines .header,.scanlines .main,.scanlines .scroll,.scanlines .date-time,.scanlines .city,.scanlines .temp,.scanlines .condition,.scanlines .location,.scanlines .label,.scanlines .value,.scanlines .title{text-shadow:0 0 1px hsla(0,0%,100%,.18),0 0 2px hsla(0,0%,100%,.06)}@keyframes scanline{0%{transform:translate3d(0, 200000%, 0)}}@keyframes scanlines{0%{background-position:0 50%}} +@font-face{font-family:"Star4000";src:url("../fonts/Star4000.woff") format("woff");font-display:swap}body{font-family:"Star4000";margin:0}@media(prefers-color-scheme: dark){body{background-color:#000;color:#fff}}@media(prefers-color-scheme: dark){body a{color:#add8e6}}body.kiosk{margin:0px;padding:0px;overflow:hidden;width:100vw;background-color:#000 !important}#divQuery{max-width:640px;padding:8px}#divQuery .buttons{display:inline-block;width:150px;text-align:right}#divQuery .buttons #imgGetGps{height:13px;vertical-align:middle}#divQuery .buttons button{font-size:16pt;border:1px solid #a9a9a9}@media(prefers-color-scheme: dark){#divQuery .buttons button{background-color:#000;color:#fff}}#divQuery .buttons #btnGetGps img.dark{display:none}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.dark{display:inline-block}}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps img.light{display:none}}#divQuery .buttons #btnGetGps.active{background-color:#000}@media(prefers-color-scheme: dark){#divQuery .buttons #btnGetGps.active{background-color:#fff}}#divQuery .buttons #btnGetGps.active img{filter:invert(1)}#divQuery input,#divQuery button{font-family:"Star4000"}#divQuery #txtLocation{width:calc(100% - 170px);max-width:490px;font-size:16pt;min-width:200px;display:inline-block;background-color:#fff;color:#000;border:2px inset gray}@media(prefers-color-scheme: dark){#divQuery #txtLocation{background-color:#000;color:#fff;border:2px inset gray}}.autocomplete-suggestions{background-color:#fff;border:1px solid #000;position:absolute;z-index:9999}@media(prefers-color-scheme: dark){.autocomplete-suggestions{background-color:#000}}.autocomplete-suggestions div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16pt}.autocomplete-suggestions div.selected{background-color:blue;color:#fff}#divTwc{display:block;background-color:#000;color:#fff;width:100%;max-width:640px;margin:0}#divTwc.wide{max-width:854px}.content-wrapper{padding:8px}#divTwcMain{width:640px;height:480px;position:relative}.wide #divTwcMain{width:854px}.kiosk #divTwc{max-width:unset}#divTwcLeft{display:none;text-align:right;flex-direction:column;vertical-align:middle}#divTwcLeft>div{flex:1;padding-right:12px;display:flex;flex-direction:column;justify-content:center}#divTwcRight{text-align:left;display:none;flex-direction:column;vertical-align:middle}#divTwcRight>div{flex:1;padding-left:12px;display:flex;flex-direction:column;justify-content:center}#divTwcBottom{display:flex;flex-direction:row;background-color:#000;color:#fff;width:640px}.wide #divTwcBottom{width:854px}@media(prefers-color-scheme: dark){#divTwcBottom{background-color:#303030}}#divTwcBottom>div{padding-left:6px;padding-right:6px}@media(max-width: 550px){#divTwcBottom>div{font-size:.9em}}@media(max-width: 500px){#divTwcBottom>div{font-size:.8em}}@media(max-width: 450px){#divTwcBottom>div{font-size:.7em}}@media(max-width: 400px){#divTwcBottom>div{font-size:.6em}}@media(max-width: 350px){#divTwcBottom>div{font-size:.5em}}#divTwcBottomLeft{flex:1;text-align:left}#divTwcBottomMiddle{flex:0;text-align:center}#divTwcBottomRight{flex:1;text-align:right}#divTwcNavContainer{display:none}#divTwcNav{width:100%;display:flex;flex-direction:row;background-color:#000;color:#fff;max-width:640px}#divTwcNav>div{padding-left:6px;padding-right:6px}#divTwcNavLeft{flex:1;text-align:left}#divTwcNavMiddle{flex:0;text-align:center}#divTwcNavRight{flex:1;text-align:right}#imgPause1x{visibility:hidden;position:absolute}.HideCursor{cursor:none !important}#txtScrollText{width:475px}@font-face{font-family:"Star4000 Extended";src:url("../fonts/Star4000 Extended.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Large";src:url("../fonts/Star4000 Large.woff") format("woff");font-display:swap}@font-face{font-family:"Star4000 Small";src:url("../fonts/Star4000 Small.woff") format("woff");font-display:swap}#display{font-family:"Star4000";margin:0 0 0 0;width:100%}#container{position:relative;width:640px;height:480px;background-image:url(../images/backgrounds/1.png);transform-origin:0 0;background-repeat:no-repeat}.wide #container{padding-left:107px;padding-right:107px;background:url(../images/backgrounds/1-wide.png);background-repeat:no-repeat}#divTwc:fullscreen #container,.kiosk #divTwc #container{width:unset;height:unset}#loading{width:640px;height:480px;max-width:100%;text-shadow:4px 4px #000;display:flex;align-items:center;text-align:center;justify-content:center}#loading .title{font-family:Star4000 Large;font-size:36px;color:#ff0;margin-bottom:0px}#loading .version{margin-bottom:35px}#loading .instructions{font-size:18pt}.heading{font-weight:bold;margin-top:15px}#settings{margin-bottom:15px}#enabledDisplays,#settings{margin-bottom:15px}#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#ff0}#enabledDisplays .press-here,#settings .press-here{color:lime;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:red}#enabledDisplays .no-data,#settings .no-data{color:silver}#enabledDisplays .disabled,#settings .disabled{color:silver}#enabledDisplays .press-here,#settings .press-here{color:#fff}@media(prefers-color-scheme: light){#enabledDisplays .loading,#enabledDisplays .retrying,#settings .loading,#settings .retrying{color:#990}#enabledDisplays .press-here,#settings .press-here{color:#000;cursor:pointer}#enabledDisplays .failed,#settings .failed{color:#900}#enabledDisplays .no-data,#settings .no-data{color:hsl(0,0%,30%)}#enabledDisplays .disabled,#settings .disabled{color:hsl(0,0%,30%)}}#enabledDisplays label,#settings label{display:block;max-width:fit-content;cursor:pointer}#enabledDisplays label .alert,#settings label .alert{display:none}#enabledDisplays label .alert.show,#settings label .alert.show{display:inline;color:red}#divTwcBottom img{transform:scale(0.75)}@media(max-width: 550px){.wide #divTwcBottom img{transform:scale(1)}}#divTwc:fullscreen,.kiosk #divTwc{display:flex;align-items:center;justify-content:center;align-content:center}#divTwc:fullscreen.no-cursor,.kiosk #divTwc.no-cursor{cursor:none}#divTwc:fullscreen #display,.kiosk #divTwc #display{position:relative}#divTwc:fullscreen #divTwcBottom,.kiosk #divTwc #divTwcBottom{display:flex;flex-direction:row;background-color:rgba(0,0,0,.5);color:#fff;width:100%;position:absolute;bottom:0px}.kiosk #divTwc #divTwcBottom{display:none}.navButton{cursor:pointer}#ToggleScanlines{display:inline-block}#ToggleScanlines .on{display:none}#ToggleScanlines .off{display:inline-block}#ToggleScanlines.on .on{display:inline-block}#ToggleScanlines.on .off{display:none}.visible{visibility:visible;opacity:1;transition:opacity .1s linear}#divTwc:fullscreen .hidden{visibility:hidden;opacity:0;transition:visibility 0s 1s,opacity 1s linear}.github-links{width:610px;max-width:calc(100vw - 30px);display:flex;justify-content:space-evenly;flex-wrap:wrap}.github-links span a{text-decoration:none;outline:0}.github-links span .widget{display:inline-block;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:0;line-height:0;white-space:nowrap}.github-links span .btn,.github-links span .social-count{position:relative;display:inline-block;display:inline-flex;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid}.github-links span .btn{border-radius:.25em}.github-links span .btn:not(:last-child){border-radius:.25em 0 0 .25em}.github-links span .social-count{border-left:0;border-radius:0 .25em .25em 0}.github-links span .widget-lg .btn,.github-links span .widget-lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.github-links span .octicon{display:inline-block;vertical-align:text-top;fill:currentColor;overflow:visible}.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}@media(prefers-color-scheme: light){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #0969da;outline-offset:-2px}.github-links span .btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.github-links span .social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#0969da}.github-links span .octicon-heart{color:#bf3989}}@media(prefers-color-scheme: dark){.github-links span .btn:focus-visible,.github-links span .social-count:focus-visible{outline:2px solid #58a6ff;outline-offset:-2px}.github-links span .btn{color:#c9d1d9;background-color:#1a1e23;border-color:#2f3439;border-color:rgba(240,246,252,.1);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #21262d, #1a1e23 90%);background-image:linear-gradient(180deg, #21262d, #1a1e23 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')}.github-links span :root .btn{filter:none}.github-links span .btn:hover,.github-links span .btn:focus{background-color:#292e33;background-position:0 -0.5em;border-color:#8b949e;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e");background-image:-moz-linear-gradient(top, #30363d, #292e33 90%);background-image:linear-gradient(180deg, #30363d, #292e33 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')}.github-links span :root .btn:hover,.github-links span :root .btn:focus{filter:none}.github-links span .btn:active{background-color:#161719;border-color:#8b949e;box-shadow:inset 0 .15em .3em rgba(1,4,9,.15);background-image:none;filter:none}.github-links span .social-count{color:#c9d1d9;background-color:#0d1117;border-color:#24282e;border-color:rgba(240,246,252,.1)}.github-links span .social-count:hover,.github-links span .social-count:focus{color:#58a6ff}.github-links span .octicon-heart{color:#db61a2}}#share-link-copied{color:#990;display:none}#share-link-instructions{display:none}body.kiosk #loading .instructions{display:none !important}.kiosk>*:not(#divTwc){display:none !important}#divInfo{display:grid;grid-template-columns:1fr 1fr;max-width:250px}.weather-display{width:640px;height:480px;overflow:hidden;position:relative;background-image:url(../images/backgrounds/1.png);height:0px}.weather-display.show{height:480px}.weather-display .template{display:none}.weather-display .header{width:640px;height:60px;padding-top:30px;position:relative;z-index:20}.weather-display .header .title{color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000";font-size:24pt;position:absolute;width:250px}.weather-display .header .title.single{left:170px;top:25px}.weather-display .header .title.dual{left:170px}.weather-display .header .title.dual>div{position:absolute}.weather-display .header .title.dual .top{top:-3px}.weather-display .header .title.dual .bottom{top:26px}.weather-display .header .logo{top:30px;left:50px;position:absolute;z-index:10}.weather-display .header .noaa-logo{position:absolute;top:39px;left:356px}.weather-display .header .title.single{top:40px}.weather-display .header .date-time{white-space:pre;color:#fff;font-family:"Star4000 Small";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;left:415px;width:170px;text-align:right;position:absolute}.weather-display .header .date-time.date{padding-top:22px}.weather-display .main{position:relative}.weather-display .main.has-scroll{width:640px;margin-top:0;height:310px;overflow:hidden}.weather-display .main.has-scroll.no-header{height:400px;margin-top:0}.weather-display .main.has-box{margin-left:64px;margin-right:64px;width:calc(100% - 128px)}#container>.scroll{display:none;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;width:640px;height:77px;overflow:hidden;margin-top:3px;position:absolute;bottom:0px;z-index:1}#container>.scroll.hazard{background-color:#702323}#container>.scroll .scroll-container{width:640px}#container>.scroll .scroll-container .fixed,#container>.scroll .scroll-container .scroll-header{margin-left:55px;margin-right:55px;overflow:hidden;white-space:nowrap}#container>.scroll .scroll-container .scroll-header{height:26px;font-family:"Star4000 Small";font-size:20pt;margin-top:-10px}#container>.scroll .scroll-container .fixed{font-family:"Star4000";font-size:24pt}#container>.scroll .scroll-container .fixed .scroll-area{text-wrap:nowrap;position:relative}.wide #container>.scroll{width:854px;margin-left:-107px}.wide #container>.scroll .scroll-container{margin-left:107px}.weather-display .main.current-weather.main .col{height:50px;width:255px;display:inline-block;margin-top:10px;padding-top:10px;position:absolute;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.current-weather.main .col.left{font-family:"Star4000 Extended";font-size:24pt}.weather-display .main.current-weather.main .col.right{right:0px;font-family:"Star4000 Large";font-size:20px;font-weight:bold;line-height:24px}.weather-display .main.current-weather.main .col.right .row{margin-bottom:12px}.weather-display .main.current-weather.main .col.right .row .label,.weather-display .main.current-weather.main .col.right .row .value{display:inline-block}.weather-display .main.current-weather.main .col.right .row .label{margin-left:20px}.weather-display .main.current-weather.main .col.right .row .value{float:right;margin-right:10px}.weather-display .main.current-weather.main .center{text-align:center}.weather-display .main.current-weather.main .temp{font-family:"Star4000 Large";font-size:24pt}.weather-display .main.current-weather.main .icon img{margin:0 auto;display:block}.weather-display .main.current-weather.main .wind-container{margin-left:10px;display:flex}.weather-display .main.current-weather.main .wind-container>div{width:50%}.weather-display .main.current-weather.main .wind-container .wind{text-align:right}.weather-display .main.current-weather.main .wind-gusts{text-align:right;font-size:28px}.weather-display .main.current-weather.main .location{color:#ff0;max-height:32px;margin-bottom:10px;padding-top:4px;overflow:hidden;text-wrap:nowrap}#extended-forecast-html.weather-display{background-image:url("../images/backgrounds/2.png")}.weather-display .main.extended-forecast .day-container{margin-top:16px;margin-left:27px}.weather-display .main.extended-forecast .day{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding:5px;height:285px;width:155px;display:inline-block;margin:0px 15px;font-family:"Star4000";font-size:24pt}.weather-display .main.extended-forecast .day .date{text-transform:uppercase;text-align:center;color:#ff0}.weather-display .main.extended-forecast .day .condition{text-align:center;height:74px;margin-top:5px}.weather-display .main.extended-forecast .day .icon{text-align:center;height:75px}.weather-display .main.extended-forecast .day .icon img{max-height:75px}.weather-display .main.extended-forecast .day .temperatures{width:100%}.weather-display .main.extended-forecast .day .temperatures .temperature-block{display:inline-block;width:44%;vertical-align:top}.weather-display .main.extended-forecast .day .temperatures .temperature-block>div{text-align:center}.weather-display .main.extended-forecast .day .temperatures .temperature-block .value{font-family:"Star4000 Large";margin-top:4px}.weather-display .main.extended-forecast .day .temperatures .temperature-block.lo .label{color:#8080ff}.weather-display .main.extended-forecast .day .temperatures .temperature-block.hi .label{color:#ff0}.weather-display .main.hourly.main{overflow-y:hidden}.weather-display .main.hourly.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.hourly.main .column-headers .temp{left:355px}.weather-display .main.hourly.main .column-headers .like{left:435px}.weather-display .main.hourly.main .column-headers .wind{left:535px}.weather-display .main.hourly.main .hourly-lines{min-height:338px;padding-top:10px;background:repeating-linear-gradient(0deg, #001040 0px, #102080 136px, #102080 202px, #001040 338px)}.weather-display .main.hourly.main .hourly-lines .hourly-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.hourly.main .hourly-lines .hourly-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.hourly.main .hourly-lines .hourly-row .hour{left:25px}.weather-display .main.hourly.main .hourly-lines .hourly-row .icon{left:255px;width:70px;text-align:center;top:unset}.weather-display .main.hourly.main .hourly-lines .hourly-row .temp{left:355px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like{left:425px}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.heat-index{color:#e00}.weather-display .main.hourly.main .hourly-lines .hourly-row .like.wind-chill{color:#8080ff}.weather-display .main.hourly.main .hourly-lines .hourly-row .wind{left:505px;width:100px;text-align:right}#hourly-graph-html{background-image:url(../images/backgrounds/1-chart.png)}#hourly-graph-html .header .right{position:absolute;top:35px;right:60px;width:360px;font-family:"Star4000 Small";font-size:28px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:right}#hourly-graph-html .header .right div{margin-top:-18px}#hourly-graph-html .header .right .temperature{color:red}#hourly-graph-html .header .right .dewpoint{color:green}#hourly-graph-html .header .right .cloud{color:#d3d3d3}#hourly-graph-html .header .right .rain{color:aqua}.weather-display .main.hourly-graph.main>div{position:absolute}.weather-display .main.hourly-graph.main .label{font-family:"Star4000 Small";font-size:24pt;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;margin-top:-15px;position:absolute}.weather-display .main.hourly-graph.main .x-axis{bottom:0px;left:54px;width:532px;height:20px}.weather-display .main.hourly-graph.main .x-axis .label{text-align:center;transform:translateX(-50%);white-space:nowrap}.weather-display .main.hourly-graph.main .x-axis .label.l-1{left:0px}.weather-display .main.hourly-graph.main .x-axis .label.l-2{left:133px}.weather-display .main.hourly-graph.main .x-axis .label.l-3{left:266px}.weather-display .main.hourly-graph.main .x-axis .label.l-4{left:399px}.weather-display .main.hourly-graph.main .x-axis .label.l-5{left:532px}.weather-display .main.hourly-graph.main .chart{top:0px;left:50px}.weather-display .main.hourly-graph.main .chart img{width:532px;height:285px}.weather-display .main.hourly-graph.main .y-axis{top:0px;left:0px;width:50px;height:285px}.weather-display .main.hourly-graph.main .y-axis .label{text-align:right;right:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-1{top:0px}.weather-display .main.hourly-graph.main .y-axis .label.l-2{top:93.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-3{bottom:82.3333333333px}.weather-display .main.hourly-graph.main .y-axis .label.l-4{bottom:0px}.weather-display .main.hourly-graph.main .column-headers{background-color:#200057;height:20px;position:absolute;width:100%}.weather-display .main.hourly-graph.main .column-headers{position:sticky;top:0px;z-index:5}.weather-display .main.hourly-graph.main .column-headers .temp{left:355px}.weather-display .main.hourly-graph.main .column-headers .like{left:435px}.weather-display .main.hourly-graph.main .column-headers .wind{left:535px}.weather-display .main.travel.main{overflow-y:hidden}.weather-display .main.travel.main .column-headers{background-color:#200057;height:20px;position:sticky;top:0px;width:100%;z-index:5;overflow:hidden}.weather-display .main.travel.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;color:#ff0;position:absolute;top:-14px;z-index:5;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.travel.main .column-headers .temp{width:50px;text-align:center}.weather-display .main.travel.main .column-headers .temp.low{left:455px}.weather-display .main.travel.main .column-headers .temp.high{left:510px;width:60px}.weather-display .main.travel.main .travel-lines{min-height:338px;padding-top:10px;background:repeating-linear-gradient(0deg, #001040 0px, #102080 136px, #102080 202px, #001040 338px)}.weather-display .main.travel.main .travel-lines .travel-row{font-family:"Star4000 Large";font-size:24pt;height:72px;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative}.weather-display .main.travel.main .travel-lines .travel-row>div{position:absolute;white-space:pre;top:8px}.weather-display .main.travel.main .travel-lines .travel-row .city{left:80px}.weather-display .main.travel.main .travel-lines .travel-row .icon{left:330px;width:70px;text-align:center;top:unset}.weather-display .main.travel.main .travel-lines .travel-row .icon img{max-width:47px}.weather-display .main.travel.main .travel-lines .travel-row .temp{width:50px;text-align:center}.weather-display .main.travel.main .travel-lines .travel-row .temp.low{left:455px}.weather-display .main.travel.main .travel-lines .travel-row .temp.high{left:510px;width:60px}.weather-display .latest-observations.main{overflow-y:hidden}.weather-display .latest-observations.main .column-headers{height:20px;position:absolute;width:100%}.weather-display .latest-observations.main .column-headers{top:0px}.weather-display .latest-observations.main .column-headers div{display:inline-block;font-family:"Star4000 Small";font-size:24pt;position:absolute;top:-14px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .latest-observations.main .column-headers .temp{display:none}.weather-display .latest-observations.main .column-headers .temp.show{display:inline-block}.weather-display .latest-observations.main .temp{left:230px}.weather-display .latest-observations.main .weather{left:280px}.weather-display .latest-observations.main .wind{left:430px}.weather-display .latest-observations.main .observation-lines{min-height:338px;padding-top:10px}.weather-display .latest-observations.main .observation-lines .observation-row{font-family:"Star4000";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative;height:40px}.weather-display .latest-observations.main .observation-lines .observation-row>div{position:absolute;top:8px}.weather-display .latest-observations.main .observation-lines .observation-row .wind{white-space:pre;text-align:right}.weather-display .local-forecast .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:280px;overflow:hidden}.weather-display .local-forecast .forecasts{position:relative}.weather-display .local-forecast .forecast{font-family:"Star4000";font-size:24pt;text-transform:uppercase;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;min-height:280px;line-height:40px}.weather-display .progress{text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;font-family:"Star4000 Extended";font-size:18pt}.weather-display .progress .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:310px;overflow:hidden;line-height:26px}.weather-display .progress .container .item{position:relative}.weather-display .progress .container .item .name{white-space:nowrap}.weather-display .progress .container .item .name::after{content:"........................................................................"}.weather-display .progress .container .item .links{position:absolute;text-align:right;right:0px;top:0px}.weather-display .progress .container .item .links>div{background-color:#26235a;display:none;padding-left:4px}.weather-display .progress .container .item .links .loading,.weather-display .progress .container .item .links .retrying{color:#ff0}.weather-display .progress .container .item .links .press-here{color:lime;cursor:pointer}.weather-display .progress .container .item .links .failed{color:red}.weather-display .progress .container .item .links .no-data{color:silver}.weather-display .progress .container .item .links .disabled{color:silver}.weather-display .progress .container .item .links.loading .loading,.weather-display .progress .container .item .links.press-here .press-here,.weather-display .progress .container .item .links.failed .failed,.weather-display .progress .container .item .links.no-data .no-data,.weather-display .progress .container .item .links.disabled .disabled,.weather-display .progress .container .item .links.retrying .retrying{display:block}@keyframes progress-scroll{0%{background-position:-40px 0}100%{background-position:40px 0}}#progress-html.weather-display .scroll .progress-bar-container{border:2px solid #000;background-color:#fff;margin:20px auto;width:524px;position:relative;display:none}#progress-html.weather-display .scroll .progress-bar-container.show{display:block}#progress-html.weather-display .scroll .progress-bar-container .progress-bar{height:20px;margin:2px;width:520px;background:repeating-linear-gradient(90deg, #09246f 0px, #09246f 5px, #364ac0 5px, #364ac0 10px, #4f99f9 10px, #4f99f9 15px, #8ffdfa 15px, #8ffdfa 20px, #4f99f9 20px, #4f99f9 25px, #364ac0 25px, #364ac0 30px, #09246f 30px, #09246f 40px);animation-duration:2s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:progress-scroll;animation-timing-function:steps(8, end)}#progress-html.weather-display .scroll .progress-bar-container .cover{position:absolute;top:0px;right:0px;background-color:#fff;width:100%;height:24px;transition:width 1s steps(6)}#radar-html.weather-display{background-image:url("../images/backgrounds/4.png")}#radar-html.weather-display .header{height:83px}#radar-html.weather-display .header .title.dual{color:#fff;font-family:"Arial",sans-serif;font-weight:bold;font-size:28pt;left:155px}#radar-html.weather-display .header .title.dual .top{top:-4px}#radar-html.weather-display .header .title.dual .bottom{top:31px}#radar-html.weather-display .header .right{position:absolute;right:0px;width:360px;margin-top:2px;font-family:"Star4000";font-size:18pt;font-weight:bold;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;text-align:center}#radar-html.weather-display .header .right .scale-table{display:flex;justify-content:center;gap:7px}#radar-html.weather-display .header .right .scale-table .item{display:flex;flex-direction:column;align-items:center;width:25px;gap:2px}#radar-html.weather-display .header .right .scale-table .box{display:block;border:2px solid #000;width:100%;height:22px;padding:0}#radar-html.weather-display .header .right .scale-table .box-1{background-color:#49bef6}#radar-html.weather-display .header .right .scale-table .box-2{background-color:#31d216}#radar-html.weather-display .header .right .scale-table .box-3{background-color:#f1e458}#radar-html.weather-display .header .right .scale-table .box-4{background-color:#e08e2f}#radar-html.weather-display .header .right .scale-table .box-5{background-color:#c42a2a}#radar-html.weather-display .header .right .scale-table .box-6{background-color:#913bb8}#radar-html.weather-display .header .right .scale-table .label{font-family:"Star4000 Small";font-size:10pt;line-height:1;white-space:nowrap}#radar-html.weather-display .header .right .scale{margin-top:-2px}#radar-html.weather-display .header .right .time{position:relative;font-weight:normal;top:-20px;font-family:"Star4000 Small";font-size:18pt;left:130px}.weather-display .main.radar{overflow:hidden;height:367px}.weather-display .main.radar .container{position:relative;height:100%}.weather-display .main.radar .container .scroll-area{position:relative;height:100%}.weather-display .main.radar .container .frame{height:100%}.weather-display .main.radar .container .map{height:100%;width:100%}.weather-display .main.radar .container .leaflet-map{height:100%;width:100%;background:#061f3e}.weather-display .main.radar .container .leaflet-container{background:#061f3e;font-family:inherit}.weather-display .main.radar .container .radar-base-layer,.weather-display .main.radar .container .radar-base-layer .leaflet-tile{filter:grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2)}.weather-display .main.radar .container .radar-boundary-layer,.weather-display .main.radar .container .radar-boundary-layer .leaflet-tile{filter:grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1)}.weather-display .main.radar .container .leaflet-control-container,.weather-display .main.radar .container .leaflet-control-attribution,.weather-display .main.radar .container .leaflet-control-zoom{display:none}.weather-display .main.radar .container .location-marker{background:#ff0;border:2px solid #000;border-radius:50%}.weather-display .main.radar .container .nearby-weather-marker{background:rgba(0,0,0,0);border:0}.weather-display .main.radar .container .nearby-weather-marker .nearby-weather-marker-inner{display:flex;flex-direction:column;align-items:center;min-width:72px;padding:2px 4px;background:rgba(18,34,61,.88);border:1px solid #000;box-shadow:1px 1px 0 #000;color:#fff;text-align:center}.weather-display .main.radar .container .nearby-weather-marker .city{font-family:"Star4000 Small";font-size:11pt;line-height:1;white-space:nowrap;margin-bottom:1px;text-shadow:1px 1px 0 #000}.weather-display .main.radar .container .nearby-weather-marker .details{display:flex;align-items:center;gap:2px}.weather-display .main.radar .container .nearby-weather-marker .temp{font-family:"Star4000";font-size:18pt;line-height:1;color:#ff0;text-shadow:1px 1px 0 #000}.weather-display .main.radar .container .nearby-weather-marker img{width:auto;height:20px}.wide.radar #container{background:url(../images/backgrounds/4-wide.png)}#regional-forecast-html.weather-display{background-image:url("../images/backgrounds/5.png")}.weather-display .main.regional-forecast{position:relative;overflow:hidden;z-index:0}.weather-display .main.regional-forecast .map{position:absolute;inset:0}.weather-display .main.regional-forecast .leaflet-map{height:100%;width:100%;background:#061f3e}.weather-display .main.regional-forecast .leaflet-container{background:#061f3e;font-family:inherit}.weather-display .main.regional-forecast .radar-base-layer,.weather-display .main.regional-forecast .radar-base-layer .leaflet-tile{filter:grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2)}.weather-display .main.regional-forecast .radar-boundary-layer,.weather-display .main.regional-forecast .radar-boundary-layer .leaflet-tile{filter:grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1)}.weather-display .main.regional-forecast .leaflet-control-container,.weather-display .main.regional-forecast .leaflet-control-attribution,.weather-display .main.regional-forecast .leaflet-control-zoom{display:none}.weather-display .main.regional-forecast .location-marker{background:#ff0;border:2px solid #000;border-radius:50%}.weather-display .main.regional-forecast .nearby-weather-marker{background:rgba(0,0,0,0);border:0}.weather-display .main.regional-forecast .nearby-weather-marker .nearby-weather-marker-inner{display:flex;flex-direction:column;align-items:center;min-width:72px;padding:2px 4px;background:rgba(18,34,61,.88);border:1px solid #000;box-shadow:1px 1px 0 #000;color:#fff;text-align:center}.weather-display .main.regional-forecast .nearby-weather-marker .city{font-family:"Star4000 Small";font-size:11pt;line-height:1;white-space:nowrap;margin-bottom:1px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.regional-forecast .nearby-weather-marker .details{display:flex;align-items:center;gap:2px}.weather-display .main.regional-forecast .nearby-weather-marker .temp{font-family:"Star4000";font-size:18pt;line-height:1;color:#ff0;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.regional-forecast .nearby-weather-marker img{width:auto;height:20px}#almanac-html.weather-display{background-image:url("../images/backgrounds/3.png")}.weather-display .main.almanac{font-family:"Star4000";font-size:24pt;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .main.almanac .sun{display:grid;grid-template-columns:auto auto auto;grid-template-rows:auto auto auto;gap:0px 90px;margin:3px auto 5px auto;width:fit-content;line-height:30px}.weather-display .main.almanac .sun .grid-item{width:auto;height:auto;padding:0;margin:0;position:relative}.weather-display .main.almanac .sun .grid-item.header{color:#ff0;text-align:center}.weather-display .main.almanac .sun .grid-item.row-label{text-align:right}.weather-display .main.almanac .sun .grid-item.time{text-align:center}.weather-display .main.almanac .moon{position:relative;padding:7px 50px;line-height:36px}.weather-display .main.almanac .moon .title{color:#ff0;padding-left:13px}.weather-display .main.almanac .moon .day{display:inline-block;text-align:center;width:132px}.weather-display .main.almanac .moon .day .icon{padding-left:10px}.weather-display .main.almanac .moon .day .date{position:relative;top:-10px}#hazards-html.weather-display{background-image:url("../images/backgrounds/7.png")}.weather-display .main.hazards.main{overflow-y:hidden;height:480px;background-color:#702323}.weather-display .main.hazards.main .hazard-lines{min-height:400px;padding-top:10px}.weather-display .main.hazards.main .hazard-lines .hazard{font-family:"Star4000";font-size:24pt;color:#fff;text-shadow:0px 0px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;position:relative;text-transform:uppercase;margin-top:10px;margin-left:80px;margin-right:80px;padding-bottom:10px}.wide.hazards #container{background:url(../images/backgrounds/7-wide.png)}.media{display:none}#ToggleMediaContainer{display:none;position:relative}#ToggleMediaContainer.available{display:inline-block}#ToggleMediaContainer.available img.on{display:none}#ToggleMediaContainer.available img.off{display:block}#ToggleMediaContainer.available.playing img.on{display:block}#ToggleMediaContainer.available.playing img.off{display:none}#ToggleMediaContainer .volume-slider{display:none;position:absolute;top:0px;transform:translateY(-100%);width:100%;background-color:#000;text-align:center;z-index:100}@media(prefers-color-scheme: dark){#ToggleMediaContainer .volume-slider{background-color:#303030}}#ToggleMediaContainer .volume-slider input[type=range]{writing-mode:vertical-lr;direction:rtl;margin-top:20px;margin-bottom:20px}#ToggleMediaContainer .volume-slider.show{display:block}#spc-outlook-html.weather-display{background-image:url("../images/backgrounds/6.png")}.weather-display .spc-outlook .container{position:relative;top:0px;margin:0px 10px;box-sizing:border-box;height:300px;overflow:hidden}.weather-display .spc-outlook .risk-levels{position:absolute;left:206px;font-family:"Star4000 Small";font-size:32px;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .spc-outlook .risk-levels .risk-level{position:relative;top:-14px;height:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(1){left:100px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(2){left:80px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(3){left:60px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(4){left:40px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(5){left:20px}.weather-display .spc-outlook .risk-levels .risk-level:nth-child(6){left:0px}.weather-display .spc-outlook .days{position:absolute;top:120px}.weather-display .spc-outlook .days .day{height:60px}.weather-display .spc-outlook .days .day .day-name{position:absolute;font-family:"Star4000";font-size:24pt;width:200px;text-align:right;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;padding-top:20px}.weather-display .spc-outlook .days .day .risk-bar{position:absolute;width:150px;height:40px;left:210px;margin-top:20px;border:3px outset hsl(0,0%,70%);background:linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%)}#server-observations-html.weather-display .header .title.single{font-size:20pt}.weather-display .server-observations.main{height:auto !important;min-height:250px}.weather-display .server-observations .container{position:relative;top:15px;box-sizing:border-box;height:250px;overflow:hidden}.weather-display .server-observations .server-output{position:relative;font-family:"Star4000";font-size:20pt;line-height:32px;color:#fff;text-transform:uppercase;text-align:center;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000}.weather-display .server-observations .server-output .server-page{height:250px;padding:0 8px;box-sizing:border-box}.weather-display .server-observations .server-output .server-line{white-space:normal;overflow-wrap:anywhere;word-break:break-word;margin-bottom:6px}.weather-display .linux-news.main{height:auto !important;min-height:250px}.weather-display .linux-news .container{position:relative;top:15px;margin:0px 10px;box-sizing:border-box;height:250px;overflow:hidden}.weather-display .linux-news .news-output{position:relative}.weather-display .linux-news .news-output .news-page{height:250px;box-sizing:border-box;padding:0 8px;display:flex;flex-direction:column;justify-content:space-between}.weather-display .linux-news .news-output .story{height:116px;overflow:hidden}.weather-display .linux-news .news-output .headline{font-family:"Star4000";font-size:17pt;line-height:22px;color:#ff0;text-transform:uppercase;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;margin-bottom:4px}.weather-display .linux-news .news-output .blurb{font-family:"Star4000";font-size:14pt;line-height:16px;color:#fff;text-shadow:3px 3px 0 #000,-1.5px -1.5px 0 #000,0 -1.5px 0 #000,1.5px -1.5px 0 #000,1.5px 0 0 #000,1.5px 1.5px 0 #000,0 1.5px 0 #000,-1.5px 1.5px 0 #000,-1.5px 0 0 #000;overflow:hidden}.scanlines{position:relative;overflow:hidden;isolation:isolate}.scanlines #container{position:relative;z-index:1;transform:translateZ(0);will-change:filter;filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98)}.scanlines #container::before,.scanlines #container::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:3}.scanlines #container::before{background:linear-gradient(to right, rgba(255, 0, 0, 0.04) 0%, rgba(255, 0, 0, 0.01) 15%, rgba(255, 0, 0, 0) 50%, rgba(255, 0, 0, 0.01) 85%, rgba(255, 0, 0, 0.04) 100%);transform:translateX(-0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines #container::after{background:linear-gradient(to right, rgba(0, 140, 255, 0.04) 0%, rgba(0, 140, 255, 0.01) 15%, rgba(0, 140, 255, 0) 50%, rgba(0, 140, 255, 0.01) 85%, rgba(0, 140, 255, 0.04) 100%);transform:translateX(0.7px);filter:blur(1.2px);mix-blend-mode:screen}.scanlines:before,.scanlines:after{display:block;pointer-events:none;content:"";position:absolute;left:0;right:0}.scanlines:before{height:var(--scanline-thickness, 1px);z-index:2147483650;background:rgba(0,0,0,.3);opacity:.75;animation:scanline 6s linear infinite}.scanlines:after{top:0;bottom:0;z-index:2147483648;background:repeating-linear-gradient(to bottom, transparent 0, transparent var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) var(--scanline-thickness, 1px), rgba(0, 0, 0, 0.3) calc(var(--scanline-thickness, 1px) * 2));animation:none}.scanlines{box-shadow:inset 0 0 80px rgba(0,0,0,.16),inset 0 0 18px hsla(0,0%,100%,.05)}.scanlines.crt-panels-only #container{filter:none}.scanlines.crt-panels-only .weather-display{filter:blur(0.45px) saturate(1.08) contrast(1.04) brightness(0.98);transform:translateZ(0)}.scanlines .header,.scanlines .main,.scanlines .scroll,.scanlines .date-time,.scanlines .city,.scanlines .temp,.scanlines .condition,.scanlines .location,.scanlines .label,.scanlines .value,.scanlines .title{text-shadow:0 0 1px hsla(0,0%,100%,.18),0 0 2px hsla(0,0%,100%,.06)}@keyframes scanline{0%{transform:translate3d(0, 200000%, 0)}}@keyframes scanlines{0%{background-position:0 50%}} /*# sourceMappingURL=ws.min.css.map */ diff --git a/server/styles/ws.min.css.map b/server/styles/ws.min.css.map index a001dd7..4d53c5e 100644 --- a/server/styles/ws.min.css.map +++ b/server/styles/ws.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_page.scss","shared/_utils.scss","_weather-display.scss","shared/_colors.scss","_current-weather.scss","_extended-forecast.scss","_hourly.scss","_hourly-graph.scss","_travel.scss","_local-forecast.scss","_progress.scss","_radar.scss","_regional-forecast.scss","_almanac.scss","_hazards.scss","_media.scss","_spc-outlook.scss","_server-observations.scss","_linux-news.scss","shared/_scanlines.scss"],"names":[],"mappings":"AAGA,WACC,uBACA,iDACA,kBAGD,KACC,uBACA,SAEA,mCAJD,KAKE,sBACA,YAIA,mCADD,OAEE,eAIF,WACC,WACA,YACA,gBACA,YAEA,iCAIF,UACC,gBACA,YAEA,mBACC,qBACA,YACA,iBAEA,8BACC,YACA,sBAGD,0BACC,eACA,yBAEA,mCAJD,0BAKE,sBACA,YAQA,uCACC,aAEA,mCAHD,uCAIE,sBAKD,mCADD,wCAEE,cAKH,qCACC,sBAEA,mCAHD,qCAIE,uBAGD,yCACC,iBAMJ,iCAEC,uBAGD,uBACC,yBACA,gBACA,eACA,gBACA,qBAGA,sBACA,WACA,sBAEA,mCAZD,uBAaE,sBACA,WACA,uBAOH,0BACC,sBACA,sBACA,kBACA,aAEA,mCAND,0BAOE,uBAGD,8BAEC,mBACA,gBACA,uBACA,eAEA,uCACC,sBACA,WAMH,QACC,cACA,sBACA,WACA,WACA,gBACA,SAEA,aACC,gBAIF,iBACC,YAGD,YACC,YACA,aACA,kBAEA,kBACC,YAIF,eACC,gBAGD,YACC,aACA,iBACA,sBACA,sBAGD,gBACC,OACA,mBACA,aACA,sBACA,uBAGD,aACC,gBACA,aACA,sBACA,sBAGD,iBACC,OACA,kBACA,aACA,sBACA,uBAGD,cAEC,aACA,mBACA,sBAEA,WACA,YAEA,oBACC,YAGD,mCAbD,cAcE,0BAKF,kBACC,iBACA,kBAIA,yBAND,kBAOE,gBAGD,yBAVD,kBAWE,gBAGD,yBAdD,kBAeE,gBAGD,yBAlBD,kBAmBE,gBAGD,yBAtBD,kBAuBE,gBAIF,kBACC,OACA,gBAID,oBACC,OACA,kBAGD,mBACC,OACA,iBAGD,oBACC,aAGD,WACC,WACA,aACA,mBACA,sBACA,WACA,gBAGD,eACC,iBACA,kBAGD,eACC,OACA,gBAGD,iBACC,OACA,kBAGD,gBACC,OACA,iBAGD,YACC,kBACA,kBAGD,YACC,uBAGD,eACC,YAGD,WACC,gCACA,0DACA,kBAGD,WACC,6BACA,uDACA,kBAGD,WACC,6BACA,uDACA,kBAGD,SACC,uBACA,eACA,WAGD,WACC,kBACA,YACA,aAEA,kDACA,qBACA,4BAGD,iBACC,mBACA,oBACA,iDACA,4BAGD,wDAGC,YACA,aAGD,SACC,YACA,aACA,eACA,yBACA,aACA,mBACA,kBACA,uBAEA,gBACC,2BACA,eACA,WACA,kBAGD,kBACC,mBAGD,uBACC,eAIF,SACC,iBACA,gBAGD,UACC,mBAGD,2BAEC,mBCzXA,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,UAGD,6CACC,aAGD,+CACC,aDyWD,mDACC,WAGD,oCAEC,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,WAGD,6CACC,oBAGD,+CACC,qBAIF,uCACC,cACA,sBACA,eAEA,qDACC,aAEA,+DACC,eACA,UAMJ,kBACC,sBAGA,yBACC,wBACC,oBAKH,kCAEC,aACA,mBACA,uBACA,qBAEA,sDACC,YAIF,oDAEC,kBAGD,8DAEC,aACA,mBACA,gCACA,WACA,WACA,kBACA,WAIA,6BACC,aAIF,WACC,eAGD,iBACC,qBAEA,qBACC,aAGD,sBACC,qBAKA,wBACC,qBAGD,yBACC,aAMH,SACC,mBACA,UACA,8BAGD,2BACC,kBACA,UACA,8CAGD,cACC,YACA,6BACA,aACA,6BACA,eAGC,qBACC,qBACA,UAGD,2BACC,qBACA,gBACA,iFACA,YACA,cACA,mBAGD,yDAEC,kBACA,qBACA,oBACA,YACA,gBACA,eACA,gBACA,iBACA,sBACA,eACA,yBACA,sBACA,qBACA,iBACA,2BACA,8BACA,0BACA,iBAGD,wBACC,oBAGD,yCACC,8BAGD,iCACC,cACA,8BAGD,+EAEC,YACA,iBACA,eACA,iBAGD,4BACC,qBACA,wBACA,kBACA,iBAGD,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,cAGD,oCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,eAIF,mCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,kCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,8CACA,sBACA,YAGD,iCACC,cACA,yBACA,qBACA,kCAGD,8EAEC,cAGD,kCACC,eAMJ,mBACC,WACA,aAGD,yBACC,aAID,kCACC,wBAMA,sBACC,wBAIF,SACC,aACA,8BACA,gBEnzBD,iBACC,YACA,aACA,gBACA,kBACA,kDAGA,WAEA,sBACC,aAGD,2BACC,aAGD,yBACC,YACA,YACA,iBACA,kBACA,WAEA,gCACC,MC7BW,KFMb,YACC,6JCwBC,uBACA,eACA,kBACA,YAEA,uCACC,WACA,SAGD,qCACC,WAEA,yCACC,kBAGD,0CACC,SAGD,6CACC,SAMH,+BACC,SACA,UACA,kBACA,WAGD,oCACC,kBACA,SACA,WAGD,uCACC,SAGD,oCACC,gBACA,MC7ES,KD8ET,6BACA,eD1EF,YACC,6JC2EC,WACA,YACA,iBACA,kBAEA,yCACC,iBAKH,uBACC,kBAEA,kCACC,YACA,aACA,aACA,gBAEA,4CACC,aACA,aAIF,+BACC,iBACA,kBACA,yBAOH,mBACC,aDjHA,YACC,6JCkHD,YACA,YACA,gBACA,eACA,kBACA,WACA,UAEA,0BACC,yBAGD,qCACC,YAEA,gGAEC,iBACA,kBACA,gBACA,mBAGD,oDACC,YACA,6BACA,eACA,iBAGD,4CACC,uBACA,eAEA,yDACC,iBACA,kBAYJ,yBACC,YACA,mBAEA,2CACC,kBExKA,iDACC,YACA,YACA,qBACA,gBACA,iBACA,kBHNF,YACC,6JGSC,sDACC,gCACA,eAID,uDACC,UACA,6BACA,eACA,iBACA,iBAEA,4DACC,mBAEA,sIAEC,qBAGD,mEACC,iBAGD,mEACC,YACA,kBAQJ,oDACC,kBAGD,kDACC,6BACA,eAIA,sDACC,cACA,cAIF,4DACC,iBACA,aAEA,gEACC,UAGD,kEACC,iBAIF,wDACC,iBACA,eAGD,sDACC,MDtFW,KCuFX,gBACA,mBACA,gBACA,gBACA,iBCxFH,wCACC,oDAIA,wDACC,gBACA,iBAGD,8CJPA,YACC,6JIQA,YACA,aACA,YACA,qBACA,gBACA,uBACA,eAEA,oDACC,yBACA,kBACA,MF1BW,KE6BZ,yDACC,kBACA,YACA,eAGD,oDACC,kBACA,YAEA,wDACC,gBAIF,4DACC,WAEA,+EACC,qBACA,UACA,mBAEA,mFACC,kBAGD,sFACC,6BACA,eAGD,yFACC,MFhDU,QEmDX,yFACC,MFlES,KGIb,mCACC,kBAEA,mDACC,iBHJa,QGKb,YACA,kBACA,WAGD,mDACC,gBACA,QACA,UAEA,uDACC,qBACA,6BACA,eACA,MHpBiB,KGqBjB,kBACA,UACA,ULpBH,YACC,6JKuBC,yDACC,WAGD,yDACC,WAGD,yDACC,WAIF,iDACC,iBACA,iBACA,mBAEA,6DACC,6BACA,eACA,YACA,MHpDU,KFMb,YACC,6JK+CE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAGD,mEACC,WAGD,mEACC,WAEA,8EACC,WAGD,8EACC,MHvES,QG2EX,mEACC,WACA,YACA,iBCzFL,mBACC,wDAGC,kCACC,kBACA,SACA,WACA,YACA,6BACA,eNPF,YACC,6JMQC,iBAEA,sCACC,iBAGD,+CACC,UAGD,4CACC,YAGD,yCACC,cAGD,wCACC,WASF,6CACC,kBAGD,gDACC,6BACA,eACA,MJ/CkB,KFGpB,YACC,6JM6CC,iBACA,kBAGD,iDACC,WACA,UACA,YACA,YAEA,wDACC,kBACA,2BACA,mBAEA,4DACC,SAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAQH,gDACC,QACA,UAEA,oDACC,YACA,aAIF,iDACC,QACA,SACA,WACA,aAEA,wDACC,iBACA,UAEA,4DACC,QAGD,4DACC,oBAGD,4DACC,uBAGD,4DACC,WAKH,yDACC,iBJ/Ha,QIgIb,YACA,kBACA,WAGD,yDACC,gBACA,QACA,UAGA,+DACC,WAGD,+DACC,WAGD,+DACC,WCpJH,mCACC,kBAEA,mDACC,iBLJa,QKKb,YACA,gBACA,QACA,WACA,UACA,gBAEA,uDACC,qBACA,6BACA,eACA,MLjBiB,KKkBjB,kBACA,UACA,UPjBH,YACC,6JOoBC,yDACC,WACA,kBAEA,6DACC,WAID,8DACC,WACA,WAKH,iDACC,iBACA,iBACA,mBAEA,6DACC,6BACA,eACA,YACA,MLpDU,KFMb,YACC,6JO+CE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAEA,uEACC,eAIF,mEACC,WACA,kBAEA,uEACC,WAGD,wEACC,WACA,WCnFL,4CACC,kBACA,SACA,gBACA,sBACA,aACA,gBAGD,4CACC,kBAGD,2CACC,uBACA,eACA,yBRdD,YACC,6JQeA,iBACA,iBCpBF,2BTGC,YACC,6JSFD,gCACA,eAEA,sCACC,kBACA,SACA,gBACA,sBACA,aACA,gBACA,iBAEA,4CACC,kBAEA,kDACC,mBAEA,yDACC,mFAIF,mDACC,kBACA,iBACA,UACA,QAEA,uDACC,iBPnBM,QOoBN,aACA,iBTjBJ,yHAEC,WAGD,+DACC,WACA,eAGD,2DACC,UAGD,4DACC,aAGD,6DACC,aSGE,gaAMC,cAYJ,2BACC,GACC,4BAGD,KACC,4BAIF,+DACC,sBACA,sBACA,iBACA,YACA,kBACA,aAEA,oEACC,cAGD,6EACC,YACA,WACA,YACA,6OAiBA,sBACA,6BACA,mCACA,+BACA,wCAGD,sEACC,kBACA,QACA,UACA,sBACA,WACA,YACA,6BClHH,4BACC,oDAEA,oCACC,YAEA,gDACC,WACA,+BACA,iBACA,eACA,WAEA,qDACC,SAGD,wDACC,SAIF,2CACC,kBACA,UACA,YACA,eACA,uBACA,eACA,iBV1BF,YACC,6JU2BC,kBAEA,wDACC,aACA,uBACA,QAEA,8DACC,aACA,sBACA,mBACA,WACA,QAGD,6DACC,cACA,sBACA,WACA,YACA,UAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,6BACA,eACA,cACA,mBAIF,kDACC,gBAGD,iDACC,kBACA,mBACA,UACA,6BACA,eACA,WAMJ,6BACC,gBACA,aAEA,wCACC,kBACA,YAEA,qDACC,kBACA,YAGD,+CACC,YAGD,6CACC,YACA,WAGD,qDACC,YACA,WACA,mBAGD,2DACC,mBACA,oBAGD,kIAEC,oEAGD,0IAEC,kEAGD,sMAGC,aAGD,yDACC,gBACA,sBACA,kBAGD,+DACC,yBACA,SAEA,4FACC,aACA,sBACA,mBACA,eACA,gBACA,8BACA,sBACA,0BACA,WACA,kBAGD,qEACC,6BACA,eACA,cACA,mBACA,kBACA,2BAGD,wEACC,aACA,mBACA,QAGD,qEACC,uBACA,eACA,cACA,WACA,2BAGD,mEACC,WACA,YAMJ,uBACC,iDC9MD,wCACC,oDAGD,yCACC,kBACA,gBACA,UAEA,8CACC,kBACA,QAGD,sDACC,YACA,WACA,mBAGD,4DACC,mBACA,oBAGD,oIAEC,oEAGD,4IAEC,kEAGD,yMAGC,aAGD,0DACC,gBACA,sBACA,kBAGD,gEACC,yBACA,SAEA,6FACC,aACA,sBACA,mBACA,eACA,gBACA,8BACA,sBACA,0BACA,WACA,kBAGD,sEACC,6BACA,eACA,cACA,mBACA,kBXlEF,YACC,6JWqEA,yEACC,aACA,mBACA,QAGD,sEACC,uBACA,eACA,cACA,MTtFW,KFMb,YACC,6JWmFA,oEACC,WACA,YCzFH,8BACC,oDAGD,+BACC,uBACA,eZHA,YACC,6JYKD,oCAGC,aACA,qCACA,kCACA,aACA,yBACA,kBACA,iBAEA,+CAEC,WACA,YACA,UACA,SACA,kBAGA,sDACC,MV9BiB,KU+BjB,kBAID,yDAEC,iBAID,oDACC,kBAKH,qCACC,kBACA,iBACA,iBAEA,4CACC,MVrDkB,KUsDlB,kBAGD,0CACC,qBACA,kBACA,YAEA,gDAEC,kBAGD,gDACC,kBACA,UCrEJ,8BACC,oDAIA,oCACC,kBACA,aACA,yBAGA,kDACC,iBACA,iBAEA,0DACC,uBACA,eACA,WbfH,YACC,6JagBE,kBACA,yBACA,gBACA,iBACA,kBACA,oBAMJ,yBACC,iDCnCD,OACC,aAGD,sBACC,aACA,kBAEA,gCACC,qBAEA,uCACC,aAGD,wCACC,cAKA,+CACC,cAGD,gDACC,aAQH,qCACC,aACA,kBACA,QACA,4BACA,WACA,sBACA,kBACA,YAEA,mCAVD,qCAWE,0BAGD,uDACC,yBACA,cACA,gBACA,mBAGD,0CACC,cCrDH,kCACC,oDAKA,yCACC,kBACA,QACA,gBACA,sBACA,aACA,gBAGD,2CACC,kBACA,WACA,6BACA,efhBD,YACC,6JemBA,uDACC,kBACA,UACA,YAEA,oEACC,WAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,SAKH,oCACC,kBACA,UAEA,yCACC,YAEA,mDACC,kBACA,uBACA,eACA,YACA,iBf/DH,YACC,6JegEE,iBAGD,mDACC,kBACA,YACA,YACA,WACA,gBACA,gCACA,gGC7EH,gEACC,eAMD,2CACC,uBACA,iBAGD,iDACC,kBACA,SACA,sBACA,aACA,gBAGD,qDACC,kBACA,uBACA,eACA,iBACA,WACA,yBACA,kBhBzBD,YACC,6JgB2BA,kEACC,aACA,cACA,sBAGD,kEACC,mBACA,uBACA,sBACA,kBCzCF,kCACC,uBACA,iBAGD,wCACC,kBACA,SACA,gBACA,sBACA,aACA,gBAGD,0CACC,kBAEA,qDACC,aACA,sBACA,cACA,aACA,sBACA,8BAGD,iDACC,aACA,gBAGD,oDACC,uBACA,eACA,iBACA,WACA,yBjBjCF,YACC,6JiBkCC,kBAGD,iDACC,uBACA,eACA,iBACA,WjB1CF,YACC,6JiB2CC,gBCiBH,WACE,kBACA,gBACA,kBAMA,sBACE,kBACA,UACA,wBACA,mBAEA,OACE,4DASJ,2DAEE,WACA,kBACA,QACA,oBACA,UAGF,8BACE,WACE,8JAQF,6BACA,mBACA,sBAMF,6BACE,WACE,wKAQF,4BACA,mBACA,sBAMF,mCAEE,cACA,oBACA,WACA,kBACA,OACA,QAGF,kBACE,sCACA,mBACA,WA/IS,eAgJT,QA5IW,IAwCX,sCA2GF,iBACE,MACA,SACA,QAzJW,WA0JX,2NArHA,eAsBJ,WA6GE,WACE,kEAaF,sCACE,YAGF,4CACE,OACE,4DAKF,wBASF,gNAWE,YACE,wDASN,oBACE,GACE,sCAIJ,qBACE,GACE","sourcesContent":["@use 'shared/_utils'as u;\n@use 'shared/_colors'as c;\n\n@font-face {\n\tfont-family: \"Star4000\";\n\tsrc: url('../fonts/Star4000.woff') format('woff');\n\tfont-display: swap;\n}\n\nbody {\n\tfont-family: \"Star4000\";\n\tmargin: 0;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t\tcolor: white;\n\t}\n\n\ta {\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tcolor: lightblue;\n\t\t}\n\t}\n\n\t&.kiosk {\n\t\tmargin: 0px;\n\t\tpadding: 0px;\n\t\toverflow: hidden;\n\t\twidth: 100vw;\n\t\t// Always use black background in kiosk mode, regardless of light/dark preference\n\t\tbackground-color: #000000 !important;\n\t}\n}\n\n#divQuery {\n\tmax-width: 640px;\n\tpadding: 8px;\n\n\t.buttons {\n\t\tdisplay: inline-block;\n\t\twidth: 150px;\n\t\ttext-align: right;\n\n\t\t#imgGetGps {\n\t\t\theight: 13px;\n\t\t\tvertical-align: middle;\n\t\t}\n\n\t\tbutton {\n\t\t\tfont-size: 16pt;\n\t\t\tborder: 1px solid darkgray;\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbackground-color: #000000;\n\t\t\t\tcolor: white;\n\t\t\t}\n\n\t\t}\n\n\t\t#btnGetGps {\n\t\t\timg {\n\n\t\t\t\t&.dark {\n\t\t\t\t\tdisplay: none;\n\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t&.light {\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t&.active {\n\t\t\t\tbackground-color: black;\n\n\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\tbackground-color: white;\n\t\t\t\t}\n\n\t\t\t\timg {\n\t\t\t\t\tfilter: invert(1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinput,\n\tbutton {\n\t\tfont-family: \"Star4000\";\n\t}\n\n\t#txtLocation {\n\t\twidth: calc(100% - 170px);\n\t\tmax-width: 490px;\n\t\tfont-size: 16pt;\n\t\tmin-width: 200px;\n\t\tdisplay: inline-block;\n\n\t\t// Ensure consistent styling across light and dark modes\n\t\tbackground-color: white;\n\t\tcolor: black;\n\t\tborder: 2px inset #808080;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #000000;\n\t\t\tcolor: white;\n\t\t\tborder: 2px inset #808080;\n\t\t}\n\t}\n\n\n}\n\n.autocomplete-suggestions {\n\tbackground-color: #ffffff;\n\tborder: 1px solid #000000;\n\tposition: absolute;\n\tz-index: 9999;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t}\n\n\tdiv {\n\t\t/*padding: 2px 5px;*/\n\t\twhite-space: nowrap;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\tfont-size: 16pt;\n\n\t\t&.selected {\n\t\t\tbackground-color: #0000ff;\n\t\t\tcolor: #ffffff;\n\t\t}\n\t}\n\n}\n\n#divTwc {\n\tdisplay: block;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\twidth: 100%;\n\tmax-width: 640px;\n\tmargin: 0; // Ensure edge-to-edge display\n\n\t&.wide {\n\t\tmax-width: 854px;\n\t}\n}\n\n.content-wrapper {\n\tpadding: 8px;\n}\n\n#divTwcMain {\n\twidth: 640px;\n\theight: 480px;\n\tposition: relative;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n}\n\n.kiosk #divTwc {\n\tmax-width: unset;\n}\n\n#divTwcLeft {\n\tdisplay: none;\n\ttext-align: right;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcLeft>div {\n\tflex: 1;\n\tpadding-right: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcRight {\n\ttext-align: left;\n\tdisplay: none;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcRight>div {\n\tflex: 1;\n\tpadding-left: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcBottom {\n\t/* visibility: hidden; */\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\n\tcolor: #ffffff;\n\twidth: 640px;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: rgb(48, 48, 48);\n\t}\n\n}\n\n#divTwcBottom>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n\n\t// Use font-size scaling instead of zoom/transform to avoid layout gaps and preserve icon tap targets.\n\t// While not semantically ideal, it works well for our fixed-layout design.\n\t@media (max-width: 550px) {\n\t\tfont-size: 0.90em;\n\t}\n\n\t@media (max-width: 500px) {\n\t\tfont-size: 0.80em;\n\t}\n\n\t@media (max-width: 450px) {\n\t\tfont-size: 0.70em;\n\t}\n\n\t@media (max-width: 400px) {\n\t\tfont-size: 0.60em;\n\t}\n\n\t@media (max-width: 350px) {\n\t\tfont-size: 0.50em;\n\t}\n}\n\n#divTwcBottomLeft {\n\tflex: 1;\n\ttext-align: left;\n\n}\n\n#divTwcBottomMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcBottomRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#divTwcNavContainer {\n\tdisplay: none;\n}\n\n#divTwcNav {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\tmax-width: 640px;\n}\n\n#divTwcNav>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n}\n\n#divTwcNavLeft {\n\tflex: 1;\n\ttext-align: left;\n}\n\n#divTwcNavMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcNavRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#imgPause1x {\n\tvisibility: hidden;\n\tposition: absolute;\n}\n\n.HideCursor {\n\tcursor: none !important;\n}\n\n#txtScrollText {\n\twidth: 475px;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Extended';\n\tsrc: url('../fonts/Star4000 Extended.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Large';\n\tsrc: url('../fonts/Star4000 Large.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Small';\n\tsrc: url('../fonts/Star4000 Small.woff') format('woff');\n\tfont-display: swap;\n}\n\n#display {\n\tfont-family: \"Star4000\";\n\tmargin: 0 0 0 0;\n\twidth: 100%;\n}\n\n#container {\n\tposition: relative;\n\twidth: 640px;\n\theight: 480px;\n\t// overflow: hidden;\n\tbackground-image: url(../images/backgrounds/1.png);\n\ttransform-origin: 0 0;\n\tbackground-repeat: no-repeat;\n}\n\n.wide #container {\n\tpadding-left: 107px;\n\tpadding-right: 107px;\n\tbackground: url(../images/backgrounds/1-wide.png);\n\tbackground-repeat: no-repeat;\n}\n\n#divTwc:fullscreen #container,\n.kiosk #divTwc #container {\n\t// background-image: none;\n\twidth: unset;\n\theight: unset;\n}\n\n#loading {\n\twidth: 640px;\n\theight: 480px;\n\tmax-width: 100%;\n\ttext-shadow: 4px 4px black;\n\tdisplay: flex;\n\talign-items: center;\n\ttext-align: center;\n\tjustify-content: center;\n\n\t.title {\n\t\tfont-family: Star4000 Large;\n\t\tfont-size: 36px;\n\t\tcolor: yellow;\n\t\tmargin-bottom: 0px;\n\t}\n\n\t.version {\n\t\tmargin-bottom: 35px;\n\t}\n\n\t.instructions {\n\t\tfont-size: 18pt;\n\t}\n}\n\n.heading {\n\tfont-weight: bold;\n\tmargin-top: 15px;\n}\n\n#settings {\n\tmargin-bottom: 15px;\n}\n\n#enabledDisplays,\n#settings {\n\tmargin-bottom: 15px;\n\t@include u.status-colors();\n\n\t.press-here {\n\t\tcolor: white;\n\t}\n\n\t@media (prefers-color-scheme: light) {\n\n\t\t.loading,\n\t\t.retrying {\n\t\t\tcolor: hsl(60, 100%, 30%);\n\t\t}\n\n\t\t.press-here {\n\t\t\tcolor: black;\n\t\t\tcursor: pointer;\n\t\t}\n\n\t\t.failed {\n\t\t\tcolor: hsl(0, 100%, 30%);\n\t\t}\n\n\t\t.no-data {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\n\t\t.disabled {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\t}\n\n\tlabel {\n\t\tdisplay: block;\n\t\tmax-width: fit-content;\n\t\tcursor: pointer;\n\n\t\t.alert {\n\t\t\tdisplay: none;\n\n\t\t\t&.show {\n\t\t\t\tdisplay: inline;\n\t\t\t\tcolor: red;\n\t\t\t}\n\t\t}\n\t}\n}\n\n#divTwcBottom img {\n\ttransform: scale(0.75);\n\n\t// Make icons larger in widescreen mode on mobile\n\t@media (max-width: 550px) {\n\t\t.wide & {\n\t\t\ttransform: scale(1.0); // Larger icons in widescreen\n\t\t}\n\t}\n}\n\n#divTwc:fullscreen,\n.kiosk #divTwc {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\talign-content: center;\n\n\t&.no-cursor {\n\t\tcursor: none;\n\t}\n}\n\n#divTwc:fullscreen #display,\n.kiosk #divTwc #display {\n\tposition: relative;\n}\n\n#divTwc:fullscreen #divTwcBottom,\n.kiosk #divTwc #divTwcBottom {\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: rgb(0 0 0 / 0.5);\n\tcolor: #ffffff;\n\twidth: 100%;\n\tposition: absolute;\n\tbottom: 0px;\n}\n\n.kiosk {\n\t#divTwc #divTwcBottom {\n\t\tdisplay: none;\n\t}\n}\n\n.navButton {\n\tcursor: pointer;\n}\n\n#ToggleScanlines {\n\tdisplay: inline-block;\n\n\t.on {\n\t\tdisplay: none;\n\t}\n\n\t.off {\n\t\tdisplay: inline-block;\n\t}\n\n\n\t&.on {\n\t\t.on {\n\t\t\tdisplay: inline-block;\n\t\t}\n\n\t\t.off {\n\t\t\tdisplay: none;\n\t\t}\n\n\t}\n}\n\n.visible {\n\tvisibility: visible;\n\topacity: 1;\n\ttransition: opacity 0.1s linear;\n}\n\n#divTwc:fullscreen .hidden {\n\tvisibility: hidden;\n\topacity: 0;\n\ttransition: visibility 0s 1s, opacity 1s linear\n}\n\n.github-links {\n\twidth: 610px;\n\tmax-width: calc(100vw - 30px);\n\tdisplay: flex;\n\tjustify-content: space-evenly;\n\tflex-wrap: wrap;\n\n\tspan {\n\t\ta {\n\t\t\ttext-decoration: none;\n\t\t\toutline: 0\n\t\t}\n\n\t\t.widget {\n\t\t\tdisplay: inline-block;\n\t\t\toverflow: hidden;\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;\n\t\t\tfont-size: 0;\n\t\t\tline-height: 0;\n\t\t\twhite-space: nowrap\n\t\t}\n\n\t\t.btn,\n\t\t.social-count {\n\t\t\tposition: relative;\n\t\t\tdisplay: inline-block;\n\t\t\tdisplay: inline-flex;\n\t\t\theight: 14px;\n\t\t\tpadding: 2px 5px;\n\t\t\tfont-size: 11px;\n\t\t\tfont-weight: 600;\n\t\t\tline-height: 14px;\n\t\t\tvertical-align: bottom;\n\t\t\tcursor: pointer;\n\t\t\t-webkit-user-select: none;\n\t\t\t-moz-user-select: none;\n\t\t\t-ms-user-select: none;\n\t\t\tuser-select: none;\n\t\t\tbackground-repeat: repeat-x;\n\t\t\tbackground-position: -1px -1px;\n\t\t\tbackground-size: 110% 110%;\n\t\t\tborder: 1px solid\n\t\t}\n\n\t\t.btn {\n\t\t\tborder-radius: .25em\n\t\t}\n\n\t\t.btn:not(:last-child) {\n\t\t\tborder-radius: .25em 0 0 .25em\n\t\t}\n\n\t\t.social-count {\n\t\t\tborder-left: 0;\n\t\t\tborder-radius: 0 .25em .25em 0\n\t\t}\n\n\t\t.widget-lg .btn,\n\t\t.widget-lg .social-count {\n\t\t\theight: 16px;\n\t\t\tpadding: 5px 10px;\n\t\t\tfont-size: 12px;\n\t\t\tline-height: 16px\n\t\t}\n\n\t\t.octicon {\n\t\t\tdisplay: inline-block;\n\t\t\tvertical-align: text-top;\n\t\t\tfill: currentColor;\n\t\t\toverflow: visible\n\t\t}\n\n\t\t.btn:focus-visible,\n\t\t.social-count:focus-visible {\n\t\t\toutline: 2px solid #0969da;\n\t\t\toutline-offset: -2px\n\t\t}\n\n\t\t.btn {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #ebf0f4;\n\t\t\tborder-color: #ccd1d5;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t}\n\n\t\t:root .btn {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:hover,\n\t\t.btn:focus {\n\t\t\tbackground-color: #e9ebef;\n\t\t\tbackground-position: 0 -0.5em;\n\t\t\tborder-color: #caccd1;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t}\n\n\t\t:root .btn:hover,\n\t\t:root .btn:focus {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:active {\n\t\t\tbackground-color: #e5e9ed;\n\t\t\tborder-color: #c7cbcf;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\tbackground-image: none;\n\t\t\tfilter: none\n\t\t}\n\n\t\t.social-count {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #fff;\n\t\t\tborder-color: #ddddde;\n\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t}\n\n\t\t.social-count:hover,\n\t\t.social-count:focus {\n\t\t\tcolor: #0969da\n\t\t}\n\n\t\t.octicon-heart {\n\t\t\tcolor: #bf3989\n\t\t}\n\n\t\t@media(prefers-color-scheme:light) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #0969da;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #ebf0f4;\n\t\t\t\tborder-color: #ccd1d5;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #e9ebef;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #caccd1;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #e5e9ed;\n\t\t\t\tborder-color: #c7cbcf;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #fff;\n\t\t\t\tborder-color: #ddddde;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #0969da\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #bf3989\n\t\t\t}\n\t\t}\n\n\t\t@media(prefers-color-scheme:dark) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #58a6ff;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #1a1e23;\n\t\t\t\tborder-color: #2f3439;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #21262d, #1a1e23 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #21262d, #1a1e23 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #292e33;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #30363d, #292e33 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #30363d, #292e33 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #161719;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(1, 4, 9, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #0d1117;\n\t\t\t\tborder-color: #24282e;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #58a6ff\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #db61a2\n\t\t\t}\n\t\t}\n\t}\n}\n\n#share-link-copied {\n\tcolor: hsl(60, 100%, 30%);\n\tdisplay: none;\n}\n\n#share-link-instructions {\n\tdisplay: none;\n}\n\n// Hide instructions in kiosk mode (higher specificity than the show rule)\nbody.kiosk #loading .instructions {\n\tdisplay: none !important;\n}\n\n.kiosk {\n\n\t// In kiosk mode, hide everything except the main weather display\n\t>*:not(#divTwc) {\n\t\tdisplay: none !important;\n\t}\n}\n\n#divInfo {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr;\n\tmax-width: 250px;\n}","@use 'colors'as c;\n\n@mixin text-shadow($offset: 3px, $outline: 1.5px) {\n\t/* eventually, when chrome supports paint-order for html elements */\n\t/* -webkit-text-stroke: 2px black; */\n\t/* paint-order: stroke fill; */\n\ttext-shadow:\n\t\t$offset $offset 0 c.$text-shadow,\n\t\t(-$outline) (-$outline) 0 c.$text-shadow,\n\t\t0 (-$outline) 0 c.$text-shadow,\n\t\t$outline (-$outline) 0 c.$text-shadow,\n\t\t$outline 0 0 c.$text-shadow,\n\t\t$outline $outline 0 c.$text-shadow,\n\t\t0 $outline 0 c.$text-shadow,\n\t\t(-$outline) $outline 0 c.$text-shadow,\n\t\t(-$outline) 0 0 c.$text-shadow;\n}\n\n@mixin status-colors() {\n\n\t.loading,\n\t.retrying {\n\t\tcolor: #ffff00;\n\t}\n\n\t.press-here {\n\t\tcolor: #00ff00;\n\t\tcursor: pointer;\n\t}\n\n\t.failed {\n\t\tcolor: #ff0000;\n\t}\n\n\t.no-data {\n\t\tcolor: #C0C0C0;\n\t}\n\n\t.disabled {\n\t\tcolor: #C0C0C0;\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display {\n\twidth: 640px;\n\theight: 480px;\n\toverflow: hidden;\n\tposition: relative;\n\tbackground-image: url(../images/backgrounds/1.png);\n\n\t/* this method is required to hide blocks so they can be measured while off screen */\n\theight: 0px;\n\n\t&.show {\n\t\theight: 480px;\n\t}\n\n\t.template {\n\t\tdisplay: none;\n\t}\n\n\t.header {\n\t\twidth: 640px;\n\t\theight: 60px;\n\t\tpadding-top: 30px;\n\t\tposition: relative;\n\t\tz-index: 20;\n\n\t\t.title {\n\t\t\tcolor: c.$title-color;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\t\t\tposition: absolute;\n\t\t\twidth: 250px;\n\n\t\t\t&.single {\n\t\t\t\tleft: 170px;\n\t\t\t\ttop: 25px;\n\t\t\t}\n\n\t\t\t&.dual {\n\t\t\t\tleft: 170px;\n\n\t\t\t\t&>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t}\n\n\t\t\t\t.top {\n\t\t\t\t\ttop: -3px;\n\t\t\t\t}\n\n\t\t\t\t.bottom {\n\t\t\t\t\ttop: 26px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t.logo {\n\t\t\ttop: 30px;\n\t\t\tleft: 50px;\n\t\t\tposition: absolute;\n\t\t\tz-index: 10;\n\t\t}\n\n\t\t.noaa-logo {\n\t\t\tposition: absolute;\n\t\t\ttop: 39px;\n\t\t\tleft: 356px;\n\t\t}\n\n\t\t.title.single {\n\t\t\ttop: 40px;\n\t\t}\n\n\t\t.date-time {\n\t\t\twhite-space: pre;\n\t\t\tcolor: c.$date-time;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tleft: 415px;\n\t\t\twidth: 170px;\n\t\t\ttext-align: right;\n\t\t\tposition: absolute;\n\n\t\t\t&.date {\n\t\t\t\tpadding-top: 22px;\n\t\t\t}\n\t\t}\n\t}\n\n\t.main {\n\t\tposition: relative;\n\n\t\t&.has-scroll {\n\t\t\twidth: 640px;\n\t\t\tmargin-top: 0;\n\t\t\theight: 320px;\n\t\t\toverflow: hidden;\n\n\t\t\t&.no-header {\n\t\t\t\theight: 400px;\n\t\t\t\tmargin-top: 0; // Reset for no-header case since the gap issue is header-related\n\t\t\t}\n\t\t}\n\n\t\t&.has-box {\n\t\t\tmargin-left: 64px;\n\t\t\tmargin-right: 64px;\n\t\t\twidth: calc(100% - 128px);\n\t\t}\n\n\t}\n\n}\n\n#container>.scroll {\n\tdisplay: none;\n\t@include u.text-shadow(3px, 1.5px);\n\twidth: 640px;\n\theight: 77px;\n\toverflow: hidden;\n\tmargin-top: 3px;\n\tposition: absolute;\n\tbottom: 0px;\n\tz-index: 1;\n\n\t&.hazard {\n\t\tbackground-color: rgb(112, 35, 35);\n\t}\n\n\t.scroll-container {\n\t\twidth: 640px;\n\n\t\t.fixed,\n\t\t.scroll-header {\n\t\t\tmargin-left: 55px;\n\t\t\tmargin-right: 55px;\n\t\t\toverflow: hidden;\n\t\t\twhite-space: nowrap;\n\t\t}\n\n\t\t.scroll-header {\n\t\t\theight: 26px;\n\t\t\tfont-family: \"Star4000 Small\";\n\t\t\tfont-size: 20pt;\n\t\t\tmargin-top: -10px;\n\t\t}\n\n\t\t.fixed {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\n\t\t\t.scroll-area {\n\t\t\t\ttext-wrap: nowrap;\n\t\t\t\tposition: relative;\n\t\t\t\t// the following added by js code as it is dependent on the content of the element\n\t\t\t\t// transition: left (x)s;\n\t\t\t\t// left: calc((elem width) - 640px);\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n\n.wide #container>.scroll {\n\twidth: 854px;\n\tmargin-left: -107px;\n\n\t.scroll-container {\n\t\tmargin-left: 107px;\n\t}\n}\n","$title-color: yellow;\n$date-time: white;\n$text-shadow: black;\n$column-header-text: yellow;\n$column-header: rgb(32, 0, 87);\n\n$gradient-main-background-1: #102080;\n$gradient-main-background-2: #001040;\n\n$gradient-loading-1: #09246f;\n$gradient-loading-2: #364ac0;\n$gradient-loading-3: #4f99f9;\n$gradient-loading-4: #8ffdfa;\n\n$extended-low: #8080FF;\n\n$blue-box: #26235a;","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.current-weather {\n\t&.main {\n\n\t\t.col {\n\t\t\theight: 50px;\n\t\t\twidth: 255px;\n\t\t\tdisplay: inline-block;\n\t\t\tmargin-top: 10px;\n\t\t\tpadding-top: 10px;\n\t\t\tposition: absolute;\n\n\t\t\t@include u.text-shadow();\n\n\t\t\t&.left {\n\t\t\t\tfont-family: 'Star4000 Extended';\n\t\t\t\tfont-size: 24pt;\n\n\t\t\t}\n\n\t\t\t&.right {\n\t\t\t\tright: 0px;\n\t\t\t\tfont-family: \"Star4000 Large\";\n\t\t\t\tfont-size: 20px;\n\t\t\t\tfont-weight: bold;\n\t\t\t\tline-height: 24px;\n\n\t\t\t\t.row {\n\t\t\t\t\tmargin-bottom: 12px;\n\n\t\t\t\t\t.label,\n\t\t\t\t\t.value {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\n\t\t\t\t\t.label {\n\t\t\t\t\t\tmargin-left: 20px;\n\t\t\t\t\t}\n\n\t\t\t\t\t.value {\n\t\t\t\t\t\tfloat: right;\n\t\t\t\t\t\tmargin-right: 10px;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\t.center {\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000 Large';\n\t\t\tfont-size: 24pt;\n\t\t}\n\n\t\t.icon {\n\t\t\timg {\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tdisplay: block;\n\t\t\t}\n\t\t}\n\n\t\t.wind-container {\n\t\t\tmargin-left: 10px;\n\t\t\tdisplay: flex;\n\n\t\t\t&>div {\n\t\t\t\twidth: 50%;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\ttext-align: right;\n\t\t\t}\n\t\t}\n\n\t\t.wind-gusts {\n\t\t\ttext-align: right;\n\t\t\tfont-size: 28px;\n\t\t}\n\n\t\t.location {\n\t\t\tcolor: c.$title-color;\n\t\t\tmax-height: 32px;\n\t\t\tmargin-bottom: 10px;\n\t\t\tpadding-top: 4px;\n\t\t\toverflow: hidden;\n\t\t\ttext-wrap: nowrap;\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#extended-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/2.png');\n}\n\n.weather-display .main.extended-forecast {\n\t.day-container {\n\t\tmargin-top: 16px;\n\t\tmargin-left: 27px;\n\t}\n\n\t.day {\n\t\t@include u.text-shadow();\n\t\tpadding: 5px;\n\t\theight: 285px;\n\t\twidth: 155px;\n\t\tdisplay: inline-block;\n\t\tmargin: 0px 15px;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\n\t\t.date {\n\t\t\ttext-transform: uppercase;\n\t\t\ttext-align: center;\n\t\t\tcolor: c.$title-color;\n\t\t}\n\n\t\t.condition {\n\t\t\ttext-align: center;\n\t\t\theight: 74px;\n\t\t\tmargin-top: 5px;\n\t\t}\n\n\t\t.icon {\n\t\t\ttext-align: center;\n\t\t\theight: 75px;\n\n\t\t\timg {\n\t\t\t\tmax-height: 75px;\n\t\t\t}\n\t\t}\n\n\t\t.temperatures {\n\t\t\twidth: 100%;\n\n\t\t\t.temperature-block {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 44%;\n\t\t\t\tvertical-align: top;\n\n\t\t\t\t>div {\n\t\t\t\t\ttext-align: center;\n\t\t\t\t}\n\n\t\t\t\t.value {\n\t\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\t\tmargin-top: 4px;\n\t\t\t\t}\n\n\t\t\t\t&.lo .label {\n\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t}\n\n\t\t\t\t&.hi .label {\n\t\t\t\t\tcolor: c.$title-color;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .main.hourly {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\t\t.hourly-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\t\t\tbackground: #0b0b39;\n\n\t\t\t.hourly-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.hour {\n\t\t\t\t\tleft: 25px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 255px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\tleft: 355px;\n\t\t\t\t}\n\n\t\t\t\t.like {\n\t\t\t\t\tleft: 425px;\n\n\t\t\t\t\t&.heat-index {\n\t\t\t\t\t\tcolor: #e00;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.wind-chill {\n\t\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.wind {\n\t\t\t\t\tleft: 505px;\n\t\t\t\t\twidth: 100px;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hourly-graph-html {\n\tbackground-image: url(../images/backgrounds/1-chart.png);\n\n\t.header {\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\ttop: 35px;\n\t\t\tright: 60px;\n\t\t\twidth: 360px;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 28px;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: right;\n\n\t\t\tdiv {\n\t\t\t\tmargin-top: -18px;\n\t\t\t}\n\n\t\t\t.temperature {\n\t\t\t\tcolor: red;\n\t\t\t}\n\n\t\t\t.dewpoint {\n\t\t\t\tcolor: green;\n\t\t\t}\n\n\t\t\t.cloud {\n\t\t\t\tcolor: lightgrey;\n\t\t\t}\n\n\t\t\t.rain {\n\t\t\t\tcolor: aqua;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.hourly-graph {\n\n\t&.main {\n\t\t>div {\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.label {\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\tcolor: c.$column-header-text;\n\t\t\t@include u.text-shadow();\n\t\t\tmargin-top: -15px;\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.x-axis {\n\t\t\tbottom: 0px;\n\t\t\tleft: 54px;\n\t\t\twidth: 532px;\n\t\t\theight: 20px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: center;\n\t\t\t\ttransform: translateX(-50%);\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\tleft: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\tleft: calc(532px / 4 * 1);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tleft: calc(532px / 4 * 2);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tleft: calc(532px / 4 * 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-5 {\n\t\t\t\t\tleft: calc(532px / 4 * 4);\n\t\t\t\t}\n\t\t\t}\n\n\n\n\t\t}\n\n\t\t.chart {\n\t\t\ttop: 0px;\n\t\t\tleft: 50px;\n\n\t\t\timg {\n\t\t\t\twidth: 532px;\n\t\t\t\theight: 285px;\n\t\t\t}\n\t\t}\n\n\t\t.y-axis {\n\t\t\ttop: 0px;\n\t\t\tleft: 0px;\n\t\t\twidth: 50px;\n\t\t\theight: 285px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\ttop: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\ttop: calc(280px / 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tbottom: calc(280px / 3 - 11px);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tbottom: 0px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.travel {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\twidth: 100%;\n\t\t\tz-index: 5;\n\t\t\toverflow: hidden; // prevent thin gaps between header and content\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\twidth: 50px;\n\t\t\t\ttext-align: center;\n\n\t\t\t\t&.low {\n\t\t\t\t\tleft: 455px;\n\n\t\t\t\t}\n\n\t\t\t\t&.high {\n\t\t\t\t\tleft: 510px;\n\t\t\t\t\twidth: 60px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.travel-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\t\t\tbackground: #0b0b39;\n\n\t\t\t.travel-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.city {\n\t\t\t\t\tleft: 80px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 330px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\n\t\t\t\t\timg {\n\t\t\t\t\t\tmax-width: 47px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\twidth: 50px;\n\t\t\t\t\ttext-align: center;\n\n\t\t\t\t\t&.low {\n\t\t\t\t\t\tleft: 455px;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.high {\n\t\t\t\t\t\tleft: 510px;\n\t\t\t\t\t\twidth: 60px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .local-forecast {\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 280px;\n\t\toverflow: hidden;\n\t}\n\n\t.forecasts {\n\t\tposition: relative;\n\t}\n\n\t.forecast {\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\t\ttext-transform: uppercase;\n\t\t@include u.text-shadow();\n\t\tmin-height: 280px;\n\t\tline-height: 40px;\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .progress {\n\t@include u.text-shadow();\n\tfont-family: 'Star4000 Extended';\n\tfont-size: 18pt;\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 310px;\n\t\toverflow: hidden;\n\t\tline-height: 26px;\n\n\t\t.item {\n\t\t\tposition: relative;\n\n\t\t\t.name {\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&::after {\n\t\t\t\t\tcontent: '........................................................................';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.links {\n\t\t\t\tposition: absolute;\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\t\t\t\ttop: 0px;\n\n\t\t\t\t>div {\n\t\t\t\t\tbackground-color: c.$blue-box;\n\t\t\t\t\tdisplay: none;\n\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t}\n\n\t\t\t\t@include u.status-colors();\n\n\t\t\t\t&.loading .loading,\n\t\t\t\t&.press-here .press-here,\n\t\t\t\t&.failed .failed,\n\t\t\t\t&.no-data .no-data,\n\t\t\t\t&.disabled .disabled,\n\t\t\t\t&.retrying .retrying {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\n}\n\n#progress-html.weather-display .scroll {\n\n\t@keyframes progress-scroll {\n\t\t0% {\n\t\t\tbackground-position: -40px 0;\n\t\t}\n\n\t\t100% {\n\t\t\tbackground-position: 40px 0;\n\t\t}\n\t}\n\n\t.progress-bar-container {\n\t\tborder: 2px solid black;\n\t\tbackground-color: white;\n\t\tmargin: 20px auto;\n\t\twidth: 524px;\n\t\tposition: relative;\n\t\tdisplay: none;\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t.progress-bar {\n\t\t\theight: 20px;\n\t\t\tmargin: 2px;\n\t\t\twidth: 520px;\n\t\t\tbackground: repeating-linear-gradient(90deg,\n\t\t\t\t\tc.$gradient-loading-1 0px,\n\t\t\t\t\tc.$gradient-loading-1 5px,\n\t\t\t\t\tc.$gradient-loading-2 5px,\n\t\t\t\t\tc.$gradient-loading-2 10px,\n\t\t\t\t\tc.$gradient-loading-3 10px,\n\t\t\t\t\tc.$gradient-loading-3 15px,\n\t\t\t\t\tc.$gradient-loading-4 15px,\n\t\t\t\t\tc.$gradient-loading-4 20px,\n\t\t\t\t\tc.$gradient-loading-3 20px,\n\t\t\t\t\tc.$gradient-loading-3 25px,\n\t\t\t\t\tc.$gradient-loading-2 25px,\n\t\t\t\t\tc.$gradient-loading-2 30px,\n\t\t\t\t\tc.$gradient-loading-1 30px,\n\t\t\t\t\tc.$gradient-loading-1 40px,\n\t\t\t\t);\n\t\t\t// animation\n\t\t\tanimation-duration: 2s;\n\t\t\tanimation-fill-mode: forwards;\n\t\t\tanimation-iteration-count: infinite;\n\t\t\tanimation-name: progress-scroll;\n\t\t\tanimation-timing-function: steps(8, end);\n\t\t}\n\n\t\t.cover {\n\t\t\tposition: absolute;\n\t\t\ttop: 0px;\n\t\t\tright: 0px;\n\t\t\tbackground-color: white;\n\t\t\twidth: 100%;\n\t\t\theight: 24px;\n\t\t\ttransition: width 1s steps(6);\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#radar-html.weather-display {\n\tbackground-image: url('../images/backgrounds/4.png');\n\n\t.header {\n\t\theight: 83px;\n\n\t\t.title.dual {\n\t\t\tcolor: white;\n\t\t\tfont-family: 'Arial', sans-serif;\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 28pt;\n\t\t\tleft: 155px;\n\n\t\t\t.top {\n\t\t\t\ttop: -4px;\n\t\t\t}\n\n\t\t\t.bottom {\n\t\t\t\ttop: 31px;\n\t\t\t}\n\t\t}\n\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\tright: 0px;\n\t\t\twidth: 360px;\n\t\t\tmargin-top: 2px;\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 18pt;\n\t\t\tfont-weight: bold;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: center;\n\n\t\t\t.scale-table {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: center;\n\t\t\t\tgap: 4px;\n\n\t\t\t\t.item {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: column;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\twidth: 25px;\n\t\t\t\t\tgap: 2px;\n\t\t\t\t}\n\n\t\t\t\t.box {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t\tborder: 2px solid black;\n\t\t\t\t\twidth: 100%;\n\t\t\t\t\theight: 22px;\n\t\t\t\t\tpadding: 0;\n\t\t\t\t}\n\n\t\t\t\t.box-1 {\n\t\t\t\t\tbackground-color: rgb(73, 190, 246);\n\t\t\t\t}\n\n\t\t\t\t.box-2 {\n\t\t\t\t\tbackground-color: rgb(49, 210, 22);\n\t\t\t\t}\n\n\t\t\t\t.box-3 {\n\t\t\t\t\tbackground-color: rgb(241, 228, 88);\n\t\t\t\t}\n\n\t\t\t\t.box-4 {\n\t\t\t\t\tbackground-color: rgb(224, 142, 47);\n\t\t\t\t}\n\n\t\t\t\t.box-5 {\n\t\t\t\t\tbackground-color: rgb(196, 42, 42);\n\t\t\t\t}\n\n\t\t\t\t.box-6 {\n\t\t\t\t\tbackground-color: rgb(145, 59, 184);\n\t\t\t\t}\n\n\t\t\t\t.label {\n\t\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\t\tfont-size: 10pt;\n\t\t\t\t\tline-height: 1;\n\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.scale {\n\t\t\t\tmargin-top: -2px;\n\t\t\t}\n\n\t\t\t.time {\n\t\t\t\tposition: relative;\n\t\t\t\tfont-weight: normal;\n\t\t\t\ttop: -20px;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 18pt;\n\t\t\t\tleft: 130px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.radar {\n\toverflow: hidden;\n\theight: 367px;\n\n\t.container {\n\t\tposition: relative;\n\t\theight: 100%;\n\n\t\t.scroll-area {\n\t\t\tposition: relative;\n\t\t\theight: 100%;\n\t\t}\n\n\t\t.frame {\n\t\t\theight: 100%;\n\t\t}\n\n\t\t.map {\n\t\t\theight: 100%;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.leaflet-map {\n\t\t\theight: 100%;\n\t\t\twidth: 100%;\n\t\t\tbackground: #061f3e;\n\t\t}\n\n\t\t.leaflet-container {\n\t\t\tbackground: #061f3e;\n\t\t\tfont-family: inherit;\n\t\t}\n\n\t\t.radar-base-layer,\n\t\t.radar-base-layer .leaflet-tile {\n\t\t\tfilter: grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2);\n\t\t}\n\n\t\t.radar-boundary-layer,\n\t\t.radar-boundary-layer .leaflet-tile {\n\t\t\tfilter: grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1);\n\t\t}\n\n\t\t.leaflet-control-container,\n\t\t.leaflet-control-attribution,\n\t\t.leaflet-control-zoom {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\t.location-marker {\n\t\t\tbackground: #ff0;\n\t\t\tborder: 2px solid #000;\n\t\t\tborder-radius: 50%;\n\t\t}\n\n\t\t.nearby-weather-marker {\n\t\t\tbackground: transparent;\n\t\t\tborder: 0;\n\n\t\t\t.nearby-weather-marker-inner {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: center;\n\t\t\t\tmin-width: 72px;\n\t\t\t\tpadding: 2px 4px;\n\t\t\t\tbackground: rgba(18, 34, 61, 0.88);\n\t\t\t\tborder: 1px solid #000;\n\t\t\t\tbox-shadow: 1px 1px 0 #000;\n\t\t\t\tcolor: #fff;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t.city {\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 11pt;\n\t\t\t\tline-height: 1;\n\t\t\t\twhite-space: nowrap;\n\t\t\t\tmargin-bottom: 1px;\n\t\t\t\ttext-shadow: 1px 1px 0 #000;\n\t\t\t}\n\n\t\t\t.details {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tgap: 2px;\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 18pt;\n\t\t\t\tline-height: 1;\n\t\t\t\tcolor: #ff0;\n\t\t\t\ttext-shadow: 1px 1px 0 #000;\n\t\t\t}\n\n\t\t\timg {\n\t\t\t\twidth: auto;\n\t\t\t\theight: 20px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.wide.radar #container {\n\tbackground: url(../images/backgrounds/4-wide.png);\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#regional-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/5.png');\n}\n\n.weather-display .main.regional-forecast {\n\tposition: relative;\n\toverflow: hidden;\n\tz-index: 0;\n\n\t.map {\n\t\tposition: absolute;\n\t\tinset: 0;\n\t}\n\n\t.leaflet-map {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\tbackground: #061f3e;\n\t}\n\n\t.leaflet-container {\n\t\tbackground: #061f3e;\n\t\tfont-family: inherit;\n\t}\n\n\t.radar-base-layer,\n\t.radar-base-layer .leaflet-tile {\n\t\tfilter: grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2);\n\t}\n\n\t.radar-boundary-layer,\n\t.radar-boundary-layer .leaflet-tile {\n\t\tfilter: grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1);\n\t}\n\n\t.leaflet-control-container,\n\t.leaflet-control-attribution,\n\t.leaflet-control-zoom {\n\t\tdisplay: none;\n\t}\n\n\t.location-marker {\n\t\tbackground: #ff0;\n\t\tborder: 2px solid #000;\n\t\tborder-radius: 50%;\n\t}\n\n\t.nearby-weather-marker {\n\t\tbackground: transparent;\n\t\tborder: 0;\n\n\t\t.nearby-weather-marker-inner {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\talign-items: center;\n\t\t\tmin-width: 72px;\n\t\t\tpadding: 2px 4px;\n\t\t\tbackground: rgba(18, 34, 61, 0.88);\n\t\t\tborder: 1px solid #000;\n\t\t\tbox-shadow: 1px 1px 0 #000;\n\t\t\tcolor: #fff;\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.city {\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 11pt;\n\t\t\tline-height: 1;\n\t\t\twhite-space: nowrap;\n\t\t\tmargin-bottom: 1px;\n\t\t\t@include u.text-shadow();\n\t\t}\n\n\t\t.details {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tgap: 2px;\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 18pt;\n\t\t\tline-height: 1;\n\t\t\tcolor: c.$title-color;\n\t\t\t@include u.text-shadow();\n\t\t}\n\n\t\timg {\n\t\t\twidth: auto;\n\t\t\theight: 20px;\n\t\t}\n\t}\n}\n","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n#almanac-html.weather-display {\n\tbackground-image: url('../images/backgrounds/3.png');\n}\n\n.weather-display .main.almanac {\n\tfont-family: 'Star4000';\n\tfont-size: 24pt;\n\t@include u.text-shadow();\n\n\t.sun {\n\t\t// Use CSS Grid for cross-browser consistency\n\t\t// Grid is populated in reading order (left-to-right, top-to-bottom):\n\t\tdisplay: grid;\n\t\tgrid-template-columns: auto auto auto;\n\t\tgrid-template-rows: auto auto auto;\n\t\tgap: 0px 90px;\n\t\tmargin: 3px auto 5px auto; // align the bottom of the div with the background\n\t\twidth: fit-content;\n\t\tline-height: 30px;\n\n\t\t.grid-item {\n\t\t\t// Reset inherited styles that interfere with grid layout\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tpadding: 0;\n\t\t\tmargin: 0;\n\t\t\tposition: relative;\n\n\t\t\t// Column headers (day names)\n\t\t\t&.header {\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t// Row labels (Sunrise:, Sunset:)\n\t\t\t&.row-label {\n\t\t\t\t// color: c.$column-header-text; // screenshots show labels were white\n\t\t\t\ttext-align: right;\n\t\t\t}\n\n\t\t\t// Time values (sunrise/sunset)\n\t\t\t&.time {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t}\n\t}\n\n\t.moon {\n\t\tposition: relative;\n\t\tpadding: 7px 50px;\n\t\tline-height: 36px;\n\n\t\t.title {\n\t\t\tcolor: c.$column-header-text;\n\t\t\tpadding-left: 13px;\n\t\t}\n\n\t\t.day {\n\t\t\tdisplay: inline-block;\n\t\t\ttext-align: center;\n\t\t\twidth: 132px;\n\n\t\t\t.icon {\n\t\t\t\t// shadow in image make it look off center\n\t\t\t\tpadding-left: 10px;\n\t\t\t}\n\n\t\t\t.date {\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -10px;\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hazards-html.weather-display {\n\tbackground-image: url('../images/backgrounds/7.png');\n}\n\n.weather-display .main.hazards {\n\t&.main {\n\t\toverflow-y: hidden;\n\t\theight: 480px;\n\t\tbackground-color: rgb(112, 35, 35);\n\n\n\t\t.hazard-lines {\n\t\t\tmin-height: 400px;\n\t\t\tpadding-top: 10px;\n\n\t\t\t.hazard {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: white;\n\t\t\t\t@include u.text-shadow(0px);\n\t\t\t\tposition: relative;\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tmargin-top: 10px;\n\t\t\t\tmargin-left: 80px;\n\t\t\t\tmargin-right: 80px;\n\t\t\t\tpadding-bottom: 10px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.wide.hazards #container {\n\tbackground: url(../images/backgrounds/7-wide.png);\n}",".media {\n\tdisplay: none;\n}\n\n#ToggleMediaContainer {\n\tdisplay: none;\n\tposition: relative;\n\n\t&.available {\n\t\tdisplay: inline-block;\n\n\t\timg.on {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\timg.off {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t// icon switch is handled by adding/removing the .playing class\n\t\t&.playing {\n\t\t\timg.on {\n\t\t\t\tdisplay: block;\n\t\t\t}\n\n\t\t\timg.off {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\n\t\t}\n\n\n\t}\n\n\t.volume-slider {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\ttop: 0px;\n\t\ttransform: translateY(-100%);\n\t\twidth: 100%;\n\t\tbackground-color: #000;\n\t\ttext-align: center;\n\t\tz-index: 100;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #303030;\n\t\t}\n\n\t\tinput[type=\"range\"] {\n\t\t\twriting-mode: vertical-lr;\n\t\t\tdirection: rtl;\n\t\t\tmargin-top: 20px;\n\t\t\tmargin-bottom: 20px;\n\t\t}\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\t}\n\n\n\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#spc-outlook-html.weather-display {\n\tbackground-image: url('../images/backgrounds/6.png');\n}\n\n.weather-display .spc-outlook {\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 0px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 300px;\n\t\toverflow: hidden;\n\t}\n\n\t.risk-levels {\n\t\tposition: absolute;\n\t\tleft: 206px;\n\t\tfont-family: 'Star4000 Small';\n\t\tfont-size: 32px;\n\t\t@include u.text-shadow();\n\n\n\t\t.risk-level {\n\t\t\tposition: relative;\n\t\t\ttop: -14px;\n\t\t\theight: 20px;\n\n\t\t\t&:nth-child(1) {\n\t\t\t\tleft: calc(20px * 5);\n\t\t\t}\n\n\t\t\t&:nth-child(2) {\n\t\t\t\tleft: calc(20px * 4);\n\t\t\t}\n\n\t\t\t&:nth-child(3) {\n\t\t\t\tleft: calc(20px * 3);\n\t\t\t}\n\n\t\t\t&:nth-child(4) {\n\t\t\t\tleft: calc(20px * 2);\n\t\t\t}\n\n\t\t\t&:nth-child(5) {\n\t\t\t\tleft: calc(20px * 1);\n\t\t\t}\n\n\t\t\t&:nth-child(6) {\n\t\t\t\tleft: calc(20px * 0);\n\t\t\t}\n\t\t}\n\t}\n\n\t.days {\n\t\tposition: absolute;\n\t\ttop: 120px;\n\n\t\t.day {\n\t\t\theight: 60px;\n\n\t\t\t.day-name {\n\t\t\t\tposition: absolute;\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\twidth: 200px;\n\t\t\t\ttext-align: right;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tpadding-top: 20px;\n\t\t\t}\n\n\t\t\t.risk-bar {\n\t\t\t\tposition: absolute;\n\t\t\t\twidth: 150px;\n\t\t\t\theight: 40px;\n\t\t\t\tleft: 210px;\n\t\t\t\tmargin-top: 20px;\n\t\t\t\tborder: 3px outset hsl(0, 0%, 70%);\n\t\t\t\tbackground: linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%);\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#server-observations-html.weather-display {\n\t.header .title.single {\n\t\tfont-size: 20pt;\n\t}\n}\n\n.weather-display .server-observations {\n\t// Override the default has-scroll height to fit content properly\n\t&.main {\n\t\theight: auto !important;\n\t\tmin-height: 250px;\n\t}\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tbox-sizing: border-box;\n\t\theight: 250px;\n\t\toverflow: hidden;\n\t}\n\n\t.server-output {\n\t\tposition: relative;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 20pt;\n\t\tline-height: 32px;\n\t\tcolor: #fff;\n\t\ttext-transform: uppercase;\n\t\ttext-align: center;\n\t\t@include u.text-shadow();\n\n\t\t.server-page {\n\t\t\theight: 250px;\n\t\t\tpadding: 0 8px;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\n\t\t.server-line {\n\t\t\twhite-space: normal;\n\t\t\toverflow-wrap: anywhere;\n\t\t\tword-break: break-word;\n\t\t\tmargin-bottom: 6px;\n\t\t}\n\t}\n}\n","@use 'shared/_utils' as u;\n\n.weather-display .linux-news {\n\t&.main {\n\t\theight: auto !important;\n\t\tmin-height: 250px;\n\t}\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 250px;\n\t\toverflow: hidden;\n\t}\n\n\t.news-output {\n\t\tposition: relative;\n\n\t\t.news-page {\n\t\t\theight: 250px;\n\t\t\tbox-sizing: border-box;\n\t\t\tpadding: 0 8px;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tjustify-content: space-between;\n\t\t}\n\n\t\t.story {\n\t\t\theight: 116px;\n\t\t\toverflow: hidden;\n\t\t}\n\n\t\t.headline {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 17pt;\n\t\t\tline-height: 22px;\n\t\t\tcolor: #ff0;\n\t\t\ttext-transform: uppercase;\n\t\t\t@include u.text-shadow();\n\t\t\tmargin-bottom: 4px;\n\t\t}\n\n\t\t.blurb {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 14pt;\n\t\t\tline-height: 16px;\n\t\t\tcolor: #fff;\n\t\t\t@include u.text-shadow();\n\t\t\toverflow: hidden;\n\t\t}\n\t}\n}\n","/* =========================================================\n REGULAR SCANLINES SETTINGS\n ========================================================= */\n\n$scan-width: 1px;\n$scan-crt: false;\n$scan-fps: 20;\n$scan-color: rgba(#000, 0.30);\n$scan-z-index: 2147483648;\n\n$scan-moving-line: true;\n$scan-opacity: 0.75;\n\n/* =========================================================\n CRT / S-VIDEO EFFECT SETTINGS\n ========================================================= */\n\n// whole-screen softness\n$crt-soft-blur: 0.45px;\n\n// mild brightening / contrast to keep blur from looking muddy\n$crt-contrast: 1.04;\n$crt-saturation: 1.08;\n$crt-brightness: 0.98;\n\n// fake horizontal chroma bleed\n$crt-r-shift: -0.7px;\n$crt-b-shift: 0.7px;\n$crt-bleed-blur: 1.2px;\n$crt-rgb-opacity: 0.04;\n\n// subtle tube edge darkening\n$crt-vignette-opacity: 0.16;\n\n// optional tiny bloom\n$crt-glow-opacity: 0.05;\n\n/* =========================================================\n MIXINS\n ========================================================= */\n\n@mixin scan-crt($enabled) {\n @if $enabled == true {\n animation: scanlines 1s steps($scan-fps) infinite;\n } @else {\n animation: none;\n }\n}\n\n@mixin scan-moving($enabled) {\n @if $enabled == true {\n animation: scanline 6s linear infinite;\n } @else {\n animation: none;\n }\n}\n\n/* =========================================================\n APPLY TO THE REAL APP CONTAINER\n ========================================================= */\n\n/*\n You can add class=\"scanlines\" to #divTwcMain or #container.\n Example:\n
\n*/\n\n.scanlines {\n position: relative;\n overflow: hidden;\n isolation: isolate;\n\n /*\n This is the actual rendered weather area in your HTML.\n Applying the softness here affects the maps/text/icons themselves.\n */\n #container {\n position: relative;\n z-index: 1;\n transform: translateZ(0);\n will-change: filter;\n\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n }\n\n /*\n Red fringe overlay\n */\n #container::before,\n #container::after {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 3;\n }\n\n #container::before {\n background:\n linear-gradient(\n to right,\n rgba(255, 0, 0, $crt-rgb-opacity) 0%,\n rgba(255, 0, 0, 0.01) 15%,\n rgba(255, 0, 0, 0.00) 50%,\n rgba(255, 0, 0, 0.01) 85%,\n rgba(255, 0, 0, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-r-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Blue fringe overlay\n */\n #container::after {\n background:\n linear-gradient(\n to right,\n rgba(0, 140, 255, $crt-rgb-opacity) 0%,\n rgba(0, 140, 255, 0.01) 15%,\n rgba(0, 140, 255, 0.00) 50%,\n rgba(0, 140, 255, 0.01) 85%,\n rgba(0, 140, 255, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-b-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Moving scanline\n */\n &:before,\n &:after {\n display: block;\n pointer-events: none;\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n }\n\n &:before {\n height: var(--scanline-thickness, $scan-width);\n z-index: $scan-z-index + 2;\n background: $scan-color;\n opacity: $scan-opacity;\n @include scan-moving($scan-moving-line);\n }\n\n /*\n Regular scanline mask\n */\n &:after {\n top: 0;\n bottom: 0;\n z-index: $scan-z-index;\n background: repeating-linear-gradient(\n to bottom,\n transparent 0,\n transparent var(--scanline-thickness, $scan-width),\n $scan-color var(--scanline-thickness, $scan-width),\n $scan-color calc(var(--scanline-thickness, $scan-width) * 2)\n );\n @include scan-crt($scan-crt);\n }\n\n /*\n Vignette layer\n Added as an inset shadow so you don't need extra HTML\n */\n box-shadow:\n inset 0 0 80px rgba(0, 0, 0, $crt-vignette-opacity),\n inset 0 0 18px rgba(255, 255, 255, $crt-glow-opacity);\n}\n\n/* =========================================================\n OPTIONAL: only affect active weather panels, not menus\n ========================================================= */\n\n/*\n If the controls / bottom nav get too blurry, move the blur\n from #container to the weather slides only:\n*/\n.scanlines.crt-panels-only {\n #container {\n filter: none;\n }\n\n .weather-display {\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n\n transform: translateZ(0);\n }\n}\n\n/* =========================================================\n OPTIONAL: make text slightly glow like old TV phosphors\n ========================================================= */\n\n.scanlines {\n .header,\n .main,\n .scroll,\n .date-time,\n .city,\n .temp,\n .condition,\n .location,\n .label,\n .value,\n .title {\n text-shadow:\n 0 0 1px rgba(255, 255, 255, 0.18),\n 0 0 2px rgba(255, 255, 255, 0.06);\n }\n}\n\n/* =========================================================\n ANIMATIONS\n ========================================================= */\n\n@keyframes scanline {\n 0% {\n transform: translate3d(0, 200000%, 0);\n }\n}\n\n@keyframes scanlines {\n 0% {\n background-position: 0 50%;\n }\n}\n\n"],"file":"ws.min.css"} \ No newline at end of file +{"version":3,"sources":["_page.scss","shared/_utils.scss","_weather-display.scss","shared/_colors.scss","_current-weather.scss","_extended-forecast.scss","_hourly.scss","_hourly-graph.scss","_travel.scss","_latest-observations.scss","_local-forecast.scss","_progress.scss","_radar.scss","_regional-forecast.scss","_almanac.scss","_hazards.scss","_media.scss","_spc-outlook.scss","_server-observations.scss","_linux-news.scss","shared/_scanlines.scss"],"names":[],"mappings":"AAGA,WACC,uBACA,iDACA,kBAGD,KACC,uBACA,SAEA,mCAJD,KAKE,sBACA,YAIA,mCADD,OAEE,eAIF,WACC,WACA,YACA,gBACA,YAEA,iCAIF,UACC,gBACA,YAEA,mBACC,qBACA,YACA,iBAEA,8BACC,YACA,sBAGD,0BACC,eACA,yBAEA,mCAJD,0BAKE,sBACA,YAQA,uCACC,aAEA,mCAHD,uCAIE,sBAKD,mCADD,wCAEE,cAKH,qCACC,sBAEA,mCAHD,qCAIE,uBAGD,yCACC,iBAMJ,iCAEC,uBAGD,uBACC,yBACA,gBACA,eACA,gBACA,qBAGA,sBACA,WACA,sBAEA,mCAZD,uBAaE,sBACA,WACA,uBAOH,0BACC,sBACA,sBACA,kBACA,aAEA,mCAND,0BAOE,uBAGD,8BAEC,mBACA,gBACA,uBACA,eAEA,uCACC,sBACA,WAMH,QACC,cACA,sBACA,WACA,WACA,gBACA,SAEA,aACC,gBAIF,iBACC,YAGD,YACC,YACA,aACA,kBAEA,kBACC,YAIF,eACC,gBAGD,YACC,aACA,iBACA,sBACA,sBAGD,gBACC,OACA,mBACA,aACA,sBACA,uBAGD,aACC,gBACA,aACA,sBACA,sBAGD,iBACC,OACA,kBACA,aACA,sBACA,uBAGD,cAEC,aACA,mBACA,sBAEA,WACA,YAEA,oBACC,YAGD,mCAbD,cAcE,0BAKF,kBACC,iBACA,kBAIA,yBAND,kBAOE,gBAGD,yBAVD,kBAWE,gBAGD,yBAdD,kBAeE,gBAGD,yBAlBD,kBAmBE,gBAGD,yBAtBD,kBAuBE,gBAIF,kBACC,OACA,gBAID,oBACC,OACA,kBAGD,mBACC,OACA,iBAGD,oBACC,aAGD,WACC,WACA,aACA,mBACA,sBACA,WACA,gBAGD,eACC,iBACA,kBAGD,eACC,OACA,gBAGD,iBACC,OACA,kBAGD,gBACC,OACA,iBAGD,YACC,kBACA,kBAGD,YACC,uBAGD,eACC,YAGD,WACC,gCACA,0DACA,kBAGD,WACC,6BACA,uDACA,kBAGD,WACC,6BACA,uDACA,kBAGD,SACC,uBACA,eACA,WAGD,WACC,kBACA,YACA,aAEA,kDACA,qBACA,4BAGD,iBACC,mBACA,oBACA,iDACA,4BAGD,wDAGC,YACA,aAGD,SACC,YACA,aACA,eACA,yBACA,aACA,mBACA,kBACA,uBAEA,gBACC,2BACA,eACA,WACA,kBAGD,kBACC,mBAGD,uBACC,eAIF,SACC,iBACA,gBAGD,UACC,mBAGD,2BAEC,mBCzXA,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,UAGD,6CACC,aAGD,+CACC,aDyWD,mDACC,WAGD,oCAEC,4FAEC,WAGD,mDACC,WACA,eAGD,2CACC,WAGD,6CACC,oBAGD,+CACC,qBAIF,uCACC,cACA,sBACA,eAEA,qDACC,aAEA,+DACC,eACA,UAMJ,kBACC,sBAGA,yBACC,wBACC,oBAKH,kCAEC,aACA,mBACA,uBACA,qBAEA,sDACC,YAIF,oDAEC,kBAGD,8DAEC,aACA,mBACA,gCACA,WACA,WACA,kBACA,WAIA,6BACC,aAIF,WACC,eAGD,iBACC,qBAEA,qBACC,aAGD,sBACC,qBAKA,wBACC,qBAGD,yBACC,aAMH,SACC,mBACA,UACA,8BAGD,2BACC,kBACA,UACA,8CAGD,cACC,YACA,6BACA,aACA,6BACA,eAGC,qBACC,qBACA,UAGD,2BACC,qBACA,gBACA,iFACA,YACA,cACA,mBAGD,yDAEC,kBACA,qBACA,oBACA,YACA,gBACA,eACA,gBACA,iBACA,sBACA,eACA,yBACA,sBACA,qBACA,iBACA,2BACA,8BACA,0BACA,iBAGD,wBACC,oBAGD,yCACC,8BAGD,iCACC,cACA,8BAGD,+EAEC,YACA,iBACA,eACA,iBAGD,4BACC,qBACA,wBACA,kBACA,iBAGD,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,cAGD,oCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,gCACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,gCACA,iDACA,sBACA,YAGD,iCACC,cACA,sBACA,qBACA,gCAGD,8EAEC,cAGD,kCACC,eAIF,mCAEC,qFAEC,0BACA,oBAGD,wBACC,cACA,yBACA,qBACA,kCACA,8SACA,iEACA,+DACA,sGAGD,8BACC,YAGD,4DAEC,yBACA,6BACA,qBACA,8SACA,iEACA,+DACA,sGAGD,wEAEC,YAGD,+BACC,yBACA,qBACA,8CACA,sBACA,YAGD,iCACC,cACA,yBACA,qBACA,kCAGD,8EAEC,cAGD,kCACC,eAMJ,mBACC,WACA,aAGD,yBACC,aAID,kCACC,wBAMA,sBACC,wBAIF,SACC,aACA,8BACA,gBEnzBD,iBACC,YACA,aACA,gBACA,kBACA,kDAGA,WAEA,sBACC,aAGD,2BACC,aAGD,yBACC,YACA,YACA,iBACA,kBACA,WAEA,gCACC,MC7BW,KFMb,YACC,6JCwBC,uBACA,eACA,kBACA,YAEA,uCACC,WACA,SAGD,qCACC,WAEA,yCACC,kBAGD,0CACC,SAGD,6CACC,SAMH,+BACC,SACA,UACA,kBACA,WAGD,oCACC,kBACA,SACA,WAGD,uCACC,SAGD,oCACC,gBACA,MC7ES,KD8ET,6BACA,eD1EF,YACC,6JC2EC,WACA,YACA,iBACA,kBAEA,yCACC,iBAKH,uBACC,kBAEA,kCACC,YACA,aACA,aACA,gBAEA,4CACC,aACA,aAIF,+BACC,iBACA,kBACA,yBAOH,mBACC,aDjHA,YACC,6JCkHD,YACA,YACA,gBACA,eACA,kBACA,WACA,UAEA,0BACC,yBAGD,qCACC,YAEA,gGAEC,iBACA,kBACA,gBACA,mBAGD,oDACC,YACA,6BACA,eACA,iBAGD,4CACC,uBACA,eAEA,yDACC,iBACA,kBAYJ,yBACC,YACA,mBAEA,2CACC,kBExKA,iDACC,YACA,YACA,qBACA,gBACA,iBACA,kBHNF,YACC,6JGSC,sDACC,gCACA,eAID,uDACC,UACA,6BACA,eACA,iBACA,iBAEA,4DACC,mBAEA,sIAEC,qBAGD,mEACC,iBAGD,mEACC,YACA,kBAQJ,oDACC,kBAGD,kDACC,6BACA,eAIA,sDACC,cACA,cAIF,4DACC,iBACA,aAEA,gEACC,UAGD,kEACC,iBAIF,wDACC,iBACA,eAGD,sDACC,MDtFW,KCuFX,gBACA,mBACA,gBACA,gBACA,iBCxFH,wCACC,oDAIA,wDACC,gBACA,iBAGD,8CJPA,YACC,6JIQA,YACA,aACA,YACA,qBACA,gBACA,uBACA,eAEA,oDACC,yBACA,kBACA,MF1BW,KE6BZ,yDACC,kBACA,YACA,eAGD,oDACC,kBACA,YAEA,wDACC,gBAIF,4DACC,WAEA,+EACC,qBACA,UACA,mBAEA,mFACC,kBAGD,sFACC,6BACA,eAGD,yFACC,MFhDU,QEmDX,yFACC,MFlES,KGIb,mCACC,kBAEA,mDACC,iBHJa,QGKb,YACA,kBACA,WAGD,mDACC,gBACA,QACA,UAEA,uDACC,qBACA,6BACA,eACA,MHpBiB,KGqBjB,kBACA,UACA,ULpBH,YACC,6JKuBC,yDACC,WAGD,yDACC,WAGD,yDACC,WAIF,iDACC,iBACA,iBAEA,qGAMA,6DACC,6BACA,eACA,YACA,MHzDU,KFMb,YACC,6JKoDE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAGD,mEACC,WAGD,mEACC,WAEA,8EACC,WAGD,8EACC,MH5ES,QGgFX,mEACC,WACA,YACA,iBC9FL,mBACC,wDAGC,kCACC,kBACA,SACA,WACA,YACA,6BACA,eNPF,YACC,6JMQC,iBAEA,sCACC,iBAGD,+CACC,UAGD,4CACC,YAGD,yCACC,cAGD,wCACC,WASF,6CACC,kBAGD,gDACC,6BACA,eACA,MJ/CkB,KFGpB,YACC,6JM6CC,iBACA,kBAGD,iDACC,WACA,UACA,YACA,YAEA,wDACC,kBACA,2BACA,mBAEA,4DACC,SAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAGD,4DACC,WAQH,gDACC,QACA,UAEA,oDACC,YACA,aAIF,iDACC,QACA,SACA,WACA,aAEA,wDACC,iBACA,UAEA,4DACC,QAGD,4DACC,oBAGD,4DACC,uBAGD,4DACC,WAKH,yDACC,iBJ/Ha,QIgIb,YACA,kBACA,WAGD,yDACC,gBACA,QACA,UAGA,+DACC,WAGD,+DACC,WAGD,+DACC,WCpJH,mCACC,kBAEA,mDACC,iBLJa,QKKb,YACA,gBACA,QACA,WACA,UACA,gBAEA,uDACC,qBACA,6BACA,eACA,MLjBiB,KKkBjB,kBACA,UACA,UPjBH,YACC,6JOoBC,yDACC,WACA,kBAEA,6DACC,WAID,8DACC,WACA,WAKH,iDACC,iBACA,iBAEA,qGAMA,6DACC,6BACA,eACA,YACA,MLzDU,KFMb,YACC,6JOoDE,kBAEA,iEACC,kBACA,gBACA,QAGD,mEACC,UAGD,mEACC,WACA,WACA,kBACA,UAEA,uEACC,eAIF,mEACC,WACA,kBAEA,uEACC,WAGD,wEACC,WACA,WCvFL,2CACC,kBAEA,2DACC,YACA,kBACA,WAGD,2DACC,QAEA,+DACC,qBACA,6BACA,eACA,kBACA,URhBH,YACC,6JQmBC,iEAEC,aAEA,sEACC,qBAKH,iDACC,WAGD,oDACC,WAGD,iDACC,WAGD,8DACC,iBACA,iBAEA,+EACC,uBACA,eRhDH,YACC,6JQiDE,kBACA,YAEA,mFACC,kBACA,QAGD,qFACC,gBACA,iBC9DJ,4CACC,kBACA,SACA,gBACA,sBACA,aACA,gBAGD,4CACC,kBAGD,2CACC,uBACA,eACA,yBTdD,YACC,6JSeA,iBACA,iBCpBF,2BVGC,YACC,6JUFD,gCACA,eAEA,sCACC,kBACA,SACA,gBACA,sBACA,aACA,gBACA,iBAEA,4CACC,kBAEA,kDACC,mBAEA,yDACC,mFAIF,mDACC,kBACA,iBACA,UACA,QAEA,uDACC,iBRnBM,QQoBN,aACA,iBVjBJ,yHAEC,WAGD,+DACC,WACA,eAGD,2DACC,UAGD,4DACC,aAGD,6DACC,aUGE,gaAMC,cAYJ,2BACC,GACC,4BAGD,KACC,4BAIF,+DACC,sBACA,sBACA,iBACA,YACA,kBACA,aAEA,oEACC,cAGD,6EACC,YACA,WACA,YACA,6OAiBA,sBACA,6BACA,mCACA,+BACA,wCAGD,sEACC,kBACA,QACA,UACA,sBACA,WACA,YACA,6BClHH,4BACC,oDAEA,oCACC,YAEA,gDACC,WACA,+BACA,iBACA,eACA,WAEA,qDACC,SAGD,wDACC,SAIF,2CACC,kBACA,UACA,YACA,eACA,uBACA,eACA,iBX1BF,YACC,6JW2BC,kBAEA,wDACC,aACA,uBACA,QAEA,8DACC,aACA,sBACA,mBACA,WACA,QAGD,6DACC,cACA,sBACA,WACA,YACA,UAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,yBAGD,+DACC,6BACA,eACA,cACA,mBAIF,kDACC,gBAGD,iDACC,kBACA,mBACA,UACA,6BACA,eACA,WAMJ,6BACC,gBACA,aAEA,wCACC,kBACA,YAEA,qDACC,kBACA,YAGD,+CACC,YAGD,6CACC,YACA,WAGD,qDACC,YACA,WACA,mBAGD,2DACC,mBACA,oBAGD,kIAEC,oEAGD,0IAEC,kEAGD,sMAGC,aAGD,yDACC,gBACA,sBACA,kBAGD,+DACC,yBACA,SAEA,4FACC,aACA,sBACA,mBACA,eACA,gBACA,8BACA,sBACA,0BACA,WACA,kBAGD,qEACC,6BACA,eACA,cACA,mBACA,kBACA,2BAGD,wEACC,aACA,mBACA,QAGD,qEACC,uBACA,eACA,cACA,WACA,2BAGD,mEACC,WACA,YAMJ,uBACC,iDC9MD,wCACC,oDAGD,yCACC,kBACA,gBACA,UAEA,8CACC,kBACA,QAGD,sDACC,YACA,WACA,mBAGD,4DACC,mBACA,oBAGD,oIAEC,oEAGD,4IAEC,kEAGD,yMAGC,aAGD,0DACC,gBACA,sBACA,kBAGD,gEACC,yBACA,SAEA,6FACC,aACA,sBACA,mBACA,eACA,gBACA,8BACA,sBACA,0BACA,WACA,kBAGD,sEACC,6BACA,eACA,cACA,mBACA,kBZlEF,YACC,6JYqEA,yEACC,aACA,mBACA,QAGD,sEACC,uBACA,eACA,cACA,MVtFW,KFMb,YACC,6JYmFA,oEACC,WACA,YCzFH,8BACC,oDAGD,+BACC,uBACA,ebHA,YACC,6JaKD,oCAGC,aACA,qCACA,kCACA,aACA,yBACA,kBACA,iBAEA,+CAEC,WACA,YACA,UACA,SACA,kBAGA,sDACC,MX9BiB,KW+BjB,kBAID,yDAEC,iBAID,oDACC,kBAKH,qCACC,kBACA,iBACA,iBAEA,4CACC,MXrDkB,KWsDlB,kBAGD,0CACC,qBACA,kBACA,YAEA,gDAEC,kBAGD,gDACC,kBACA,UCrEJ,8BACC,oDAIA,oCACC,kBACA,aACA,yBAGA,kDACC,iBACA,iBAEA,0DACC,uBACA,eACA,WdfH,YACC,6JcgBE,kBACA,yBACA,gBACA,iBACA,kBACA,oBAMJ,yBACC,iDCnCD,OACC,aAGD,sBACC,aACA,kBAEA,gCACC,qBAEA,uCACC,aAGD,wCACC,cAKA,+CACC,cAGD,gDACC,aAQH,qCACC,aACA,kBACA,QACA,4BACA,WACA,sBACA,kBACA,YAEA,mCAVD,qCAWE,0BAGD,uDACC,yBACA,cACA,gBACA,mBAGD,0CACC,cCrDH,kCACC,oDAKA,yCACC,kBACA,QACA,gBACA,sBACA,aACA,gBAGD,2CACC,kBACA,WACA,6BACA,ehBhBD,YACC,6JgBmBA,uDACC,kBACA,UACA,YAEA,oEACC,WAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,UAGD,oEACC,SAKH,oCACC,kBACA,UAEA,yCACC,YAEA,mDACC,kBACA,uBACA,eACA,YACA,iBhB/DH,YACC,6JgBgEE,iBAGD,mDACC,kBACA,YACA,YACA,WACA,gBACA,gCACA,gGC7EH,gEACC,eAMD,2CACC,uBACA,iBAGD,iDACC,kBACA,SACA,sBACA,aACA,gBAGD,qDACC,kBACA,uBACA,eACA,iBACA,WACA,yBACA,kBjBzBD,YACC,6JiB2BA,kEACC,aACA,cACA,sBAGD,kEACC,mBACA,uBACA,sBACA,kBCzCF,kCACC,uBACA,iBAGD,wCACC,kBACA,SACA,gBACA,sBACA,aACA,gBAGD,0CACC,kBAEA,qDACC,aACA,sBACA,cACA,aACA,sBACA,8BAGD,iDACC,aACA,gBAGD,oDACC,uBACA,eACA,iBACA,WACA,yBlBjCF,YACC,6JkBkCC,kBAGD,iDACC,uBACA,eACA,iBACA,WlB1CF,YACC,6JkB2CC,gBCiBH,WACE,kBACA,gBACA,kBAMA,sBACE,kBACA,UACA,wBACA,mBAEA,OACE,4DASJ,2DAEE,WACA,kBACA,QACA,oBACA,UAGF,8BACE,WACE,8JAQF,6BACA,mBACA,sBAMF,6BACE,WACE,wKAQF,4BACA,mBACA,sBAMF,mCAEE,cACA,oBACA,WACA,kBACA,OACA,QAGF,kBACE,sCACA,mBACA,WA/IS,eAgJT,QA5IW,IAwCX,sCA2GF,iBACE,MACA,SACA,QAzJW,WA0JX,2NArHA,eAsBJ,WA6GE,WACE,kEAaF,sCACE,YAGF,4CACE,OACE,4DAKF,wBASF,gNAWE,YACE,wDASN,oBACE,GACE,sCAIJ,qBACE,GACE","sourcesContent":["@use 'shared/_utils'as u;\n@use 'shared/_colors'as c;\n\n@font-face {\n\tfont-family: \"Star4000\";\n\tsrc: url('../fonts/Star4000.woff') format('woff');\n\tfont-display: swap;\n}\n\nbody {\n\tfont-family: \"Star4000\";\n\tmargin: 0;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t\tcolor: white;\n\t}\n\n\ta {\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tcolor: lightblue;\n\t\t}\n\t}\n\n\t&.kiosk {\n\t\tmargin: 0px;\n\t\tpadding: 0px;\n\t\toverflow: hidden;\n\t\twidth: 100vw;\n\t\t// Always use black background in kiosk mode, regardless of light/dark preference\n\t\tbackground-color: #000000 !important;\n\t}\n}\n\n#divQuery {\n\tmax-width: 640px;\n\tpadding: 8px;\n\n\t.buttons {\n\t\tdisplay: inline-block;\n\t\twidth: 150px;\n\t\ttext-align: right;\n\n\t\t#imgGetGps {\n\t\t\theight: 13px;\n\t\t\tvertical-align: middle;\n\t\t}\n\n\t\tbutton {\n\t\t\tfont-size: 16pt;\n\t\t\tborder: 1px solid darkgray;\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbackground-color: #000000;\n\t\t\t\tcolor: white;\n\t\t\t}\n\n\t\t}\n\n\t\t#btnGetGps {\n\t\t\timg {\n\n\t\t\t\t&.dark {\n\t\t\t\t\tdisplay: none;\n\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t&.light {\n\t\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t&.active {\n\t\t\t\tbackground-color: black;\n\n\t\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\t\tbackground-color: white;\n\t\t\t\t}\n\n\t\t\t\timg {\n\t\t\t\t\tfilter: invert(1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinput,\n\tbutton {\n\t\tfont-family: \"Star4000\";\n\t}\n\n\t#txtLocation {\n\t\twidth: calc(100% - 170px);\n\t\tmax-width: 490px;\n\t\tfont-size: 16pt;\n\t\tmin-width: 200px;\n\t\tdisplay: inline-block;\n\n\t\t// Ensure consistent styling across light and dark modes\n\t\tbackground-color: white;\n\t\tcolor: black;\n\t\tborder: 2px inset #808080;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #000000;\n\t\t\tcolor: white;\n\t\t\tborder: 2px inset #808080;\n\t\t}\n\t}\n\n\n}\n\n.autocomplete-suggestions {\n\tbackground-color: #ffffff;\n\tborder: 1px solid #000000;\n\tposition: absolute;\n\tz-index: 9999;\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: #000000;\n\t}\n\n\tdiv {\n\t\t/*padding: 2px 5px;*/\n\t\twhite-space: nowrap;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\tfont-size: 16pt;\n\n\t\t&.selected {\n\t\t\tbackground-color: #0000ff;\n\t\t\tcolor: #ffffff;\n\t\t}\n\t}\n\n}\n\n#divTwc {\n\tdisplay: block;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\twidth: 100%;\n\tmax-width: 640px;\n\tmargin: 0; // Ensure edge-to-edge display\n\n\t&.wide {\n\t\tmax-width: 854px;\n\t}\n}\n\n.content-wrapper {\n\tpadding: 8px;\n}\n\n#divTwcMain {\n\twidth: 640px;\n\theight: 480px;\n\tposition: relative;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n}\n\n.kiosk #divTwc {\n\tmax-width: unset;\n}\n\n#divTwcLeft {\n\tdisplay: none;\n\ttext-align: right;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcLeft>div {\n\tflex: 1;\n\tpadding-right: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcRight {\n\ttext-align: left;\n\tdisplay: none;\n\tflex-direction: column;\n\tvertical-align: middle;\n}\n\n#divTwcRight>div {\n\tflex: 1;\n\tpadding-left: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n#divTwcBottom {\n\t/* visibility: hidden; */\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\n\tcolor: #ffffff;\n\twidth: 640px;\n\n\t.wide & {\n\t\twidth: 854px;\n\t}\n\n\t@media (prefers-color-scheme: dark) {\n\t\tbackground-color: rgb(48, 48, 48);\n\t}\n\n}\n\n#divTwcBottom>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n\n\t// Use font-size scaling instead of zoom/transform to avoid layout gaps and preserve icon tap targets.\n\t// While not semantically ideal, it works well for our fixed-layout design.\n\t@media (max-width: 550px) {\n\t\tfont-size: 0.90em;\n\t}\n\n\t@media (max-width: 500px) {\n\t\tfont-size: 0.80em;\n\t}\n\n\t@media (max-width: 450px) {\n\t\tfont-size: 0.70em;\n\t}\n\n\t@media (max-width: 400px) {\n\t\tfont-size: 0.60em;\n\t}\n\n\t@media (max-width: 350px) {\n\t\tfont-size: 0.50em;\n\t}\n}\n\n#divTwcBottomLeft {\n\tflex: 1;\n\ttext-align: left;\n\n}\n\n#divTwcBottomMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcBottomRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#divTwcNavContainer {\n\tdisplay: none;\n}\n\n#divTwcNav {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: #000000;\n\tcolor: #ffffff;\n\tmax-width: 640px;\n}\n\n#divTwcNav>div {\n\tpadding-left: 6px;\n\tpadding-right: 6px;\n}\n\n#divTwcNavLeft {\n\tflex: 1;\n\ttext-align: left;\n}\n\n#divTwcNavMiddle {\n\tflex: 0;\n\ttext-align: center;\n}\n\n#divTwcNavRight {\n\tflex: 1;\n\ttext-align: right;\n}\n\n#imgPause1x {\n\tvisibility: hidden;\n\tposition: absolute;\n}\n\n.HideCursor {\n\tcursor: none !important;\n}\n\n#txtScrollText {\n\twidth: 475px;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Extended';\n\tsrc: url('../fonts/Star4000 Extended.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Large';\n\tsrc: url('../fonts/Star4000 Large.woff') format('woff');\n\tfont-display: swap;\n}\n\n@font-face {\n\tfont-family: 'Star4000 Small';\n\tsrc: url('../fonts/Star4000 Small.woff') format('woff');\n\tfont-display: swap;\n}\n\n#display {\n\tfont-family: \"Star4000\";\n\tmargin: 0 0 0 0;\n\twidth: 100%;\n}\n\n#container {\n\tposition: relative;\n\twidth: 640px;\n\theight: 480px;\n\t// overflow: hidden;\n\tbackground-image: url(../images/backgrounds/1.png);\n\ttransform-origin: 0 0;\n\tbackground-repeat: no-repeat;\n}\n\n.wide #container {\n\tpadding-left: 107px;\n\tpadding-right: 107px;\n\tbackground: url(../images/backgrounds/1-wide.png);\n\tbackground-repeat: no-repeat;\n}\n\n#divTwc:fullscreen #container,\n.kiosk #divTwc #container {\n\t// background-image: none;\n\twidth: unset;\n\theight: unset;\n}\n\n#loading {\n\twidth: 640px;\n\theight: 480px;\n\tmax-width: 100%;\n\ttext-shadow: 4px 4px black;\n\tdisplay: flex;\n\talign-items: center;\n\ttext-align: center;\n\tjustify-content: center;\n\n\t.title {\n\t\tfont-family: Star4000 Large;\n\t\tfont-size: 36px;\n\t\tcolor: yellow;\n\t\tmargin-bottom: 0px;\n\t}\n\n\t.version {\n\t\tmargin-bottom: 35px;\n\t}\n\n\t.instructions {\n\t\tfont-size: 18pt;\n\t}\n}\n\n.heading {\n\tfont-weight: bold;\n\tmargin-top: 15px;\n}\n\n#settings {\n\tmargin-bottom: 15px;\n}\n\n#enabledDisplays,\n#settings {\n\tmargin-bottom: 15px;\n\t@include u.status-colors();\n\n\t.press-here {\n\t\tcolor: white;\n\t}\n\n\t@media (prefers-color-scheme: light) {\n\n\t\t.loading,\n\t\t.retrying {\n\t\t\tcolor: hsl(60, 100%, 30%);\n\t\t}\n\n\t\t.press-here {\n\t\t\tcolor: black;\n\t\t\tcursor: pointer;\n\t\t}\n\n\t\t.failed {\n\t\t\tcolor: hsl(0, 100%, 30%);\n\t\t}\n\n\t\t.no-data {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\n\t\t.disabled {\n\t\t\tcolor: hsl(0, 0%, 30%);\n\t\t}\n\t}\n\n\tlabel {\n\t\tdisplay: block;\n\t\tmax-width: fit-content;\n\t\tcursor: pointer;\n\n\t\t.alert {\n\t\t\tdisplay: none;\n\n\t\t\t&.show {\n\t\t\t\tdisplay: inline;\n\t\t\t\tcolor: red;\n\t\t\t}\n\t\t}\n\t}\n}\n\n#divTwcBottom img {\n\ttransform: scale(0.75);\n\n\t// Make icons larger in widescreen mode on mobile\n\t@media (max-width: 550px) {\n\t\t.wide & {\n\t\t\ttransform: scale(1.0); // Larger icons in widescreen\n\t\t}\n\t}\n}\n\n#divTwc:fullscreen,\n.kiosk #divTwc {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\talign-content: center;\n\n\t&.no-cursor {\n\t\tcursor: none;\n\t}\n}\n\n#divTwc:fullscreen #display,\n.kiosk #divTwc #display {\n\tposition: relative;\n}\n\n#divTwc:fullscreen #divTwcBottom,\n.kiosk #divTwc #divTwcBottom {\n\tdisplay: flex;\n\tflex-direction: row;\n\tbackground-color: rgb(0 0 0 / 0.5);\n\tcolor: #ffffff;\n\twidth: 100%;\n\tposition: absolute;\n\tbottom: 0px;\n}\n\n.kiosk {\n\t#divTwc #divTwcBottom {\n\t\tdisplay: none;\n\t}\n}\n\n.navButton {\n\tcursor: pointer;\n}\n\n#ToggleScanlines {\n\tdisplay: inline-block;\n\n\t.on {\n\t\tdisplay: none;\n\t}\n\n\t.off {\n\t\tdisplay: inline-block;\n\t}\n\n\n\t&.on {\n\t\t.on {\n\t\t\tdisplay: inline-block;\n\t\t}\n\n\t\t.off {\n\t\t\tdisplay: none;\n\t\t}\n\n\t}\n}\n\n.visible {\n\tvisibility: visible;\n\topacity: 1;\n\ttransition: opacity 0.1s linear;\n}\n\n#divTwc:fullscreen .hidden {\n\tvisibility: hidden;\n\topacity: 0;\n\ttransition: visibility 0s 1s, opacity 1s linear\n}\n\n.github-links {\n\twidth: 610px;\n\tmax-width: calc(100vw - 30px);\n\tdisplay: flex;\n\tjustify-content: space-evenly;\n\tflex-wrap: wrap;\n\n\tspan {\n\t\ta {\n\t\t\ttext-decoration: none;\n\t\t\toutline: 0\n\t\t}\n\n\t\t.widget {\n\t\t\tdisplay: inline-block;\n\t\t\toverflow: hidden;\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;\n\t\t\tfont-size: 0;\n\t\t\tline-height: 0;\n\t\t\twhite-space: nowrap\n\t\t}\n\n\t\t.btn,\n\t\t.social-count {\n\t\t\tposition: relative;\n\t\t\tdisplay: inline-block;\n\t\t\tdisplay: inline-flex;\n\t\t\theight: 14px;\n\t\t\tpadding: 2px 5px;\n\t\t\tfont-size: 11px;\n\t\t\tfont-weight: 600;\n\t\t\tline-height: 14px;\n\t\t\tvertical-align: bottom;\n\t\t\tcursor: pointer;\n\t\t\t-webkit-user-select: none;\n\t\t\t-moz-user-select: none;\n\t\t\t-ms-user-select: none;\n\t\t\tuser-select: none;\n\t\t\tbackground-repeat: repeat-x;\n\t\t\tbackground-position: -1px -1px;\n\t\t\tbackground-size: 110% 110%;\n\t\t\tborder: 1px solid\n\t\t}\n\n\t\t.btn {\n\t\t\tborder-radius: .25em\n\t\t}\n\n\t\t.btn:not(:last-child) {\n\t\t\tborder-radius: .25em 0 0 .25em\n\t\t}\n\n\t\t.social-count {\n\t\t\tborder-left: 0;\n\t\t\tborder-radius: 0 .25em .25em 0\n\t\t}\n\n\t\t.widget-lg .btn,\n\t\t.widget-lg .social-count {\n\t\t\theight: 16px;\n\t\t\tpadding: 5px 10px;\n\t\t\tfont-size: 12px;\n\t\t\tline-height: 16px\n\t\t}\n\n\t\t.octicon {\n\t\t\tdisplay: inline-block;\n\t\t\tvertical-align: text-top;\n\t\t\tfill: currentColor;\n\t\t\toverflow: visible\n\t\t}\n\n\t\t.btn:focus-visible,\n\t\t.social-count:focus-visible {\n\t\t\toutline: 2px solid #0969da;\n\t\t\toutline-offset: -2px\n\t\t}\n\n\t\t.btn {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #ebf0f4;\n\t\t\tborder-color: #ccd1d5;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t}\n\n\t\t:root .btn {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:hover,\n\t\t.btn:focus {\n\t\t\tbackground-color: #e9ebef;\n\t\t\tbackground-position: 0 -0.5em;\n\t\t\tborder-color: #caccd1;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t}\n\n\t\t:root .btn:hover,\n\t\t:root .btn:focus {\n\t\t\tfilter: none\n\t\t}\n\n\t\t.btn:active {\n\t\t\tbackground-color: #e5e9ed;\n\t\t\tborder-color: #c7cbcf;\n\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\tbackground-image: none;\n\t\t\tfilter: none\n\t\t}\n\n\t\t.social-count {\n\t\t\tcolor: #24292f;\n\t\t\tbackground-color: #fff;\n\t\t\tborder-color: #ddddde;\n\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t}\n\n\t\t.social-count:hover,\n\t\t.social-count:focus {\n\t\t\tcolor: #0969da\n\t\t}\n\n\t\t.octicon-heart {\n\t\t\tcolor: #bf3989\n\t\t}\n\n\t\t@media(prefers-color-scheme:light) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #0969da;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #ebf0f4;\n\t\t\t\tborder-color: #ccd1d5;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #e9ebef;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #caccd1;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #f3f4f6, #e9ebef 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #e5e9ed;\n\t\t\t\tborder-color: #c7cbcf;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15);\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(27, 31, 36, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #24292f;\n\t\t\t\tbackground-color: #fff;\n\t\t\t\tborder-color: #ddddde;\n\t\t\t\tborder-color: rgba(27, 31, 36, .15)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #0969da\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #bf3989\n\t\t\t}\n\t\t}\n\n\t\t@media(prefers-color-scheme:dark) {\n\n\t\t\t.btn:focus-visible,\n\t\t\t.social-count:focus-visible {\n\t\t\t\toutline: 2px solid #58a6ff;\n\t\t\t\toutline-offset: -2px\n\t\t\t}\n\n\t\t\t.btn {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #1a1e23;\n\t\t\t\tborder-color: #2f3439;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1);\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #21262d, #1a1e23 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #21262d, #1a1e23 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')\n\t\t\t}\n\n\t\t\t:root .btn {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:hover,\n\t\t\t.btn:focus {\n\t\t\t\tbackground-color: #292e33;\n\t\t\t\tbackground-position: 0 -0.5em;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbackground-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");\n\t\t\t\tbackground-image: -moz-linear-gradient(top, #30363d, #292e33 90%);\n\t\t\t\tbackground-image: linear-gradient(180deg, #30363d, #292e33 90%);\n\t\t\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')\n\t\t\t}\n\n\t\t\t:root .btn:hover,\n\t\t\t:root .btn:focus {\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.btn:active {\n\t\t\t\tbackground-color: #161719;\n\t\t\t\tborder-color: #8b949e;\n\t\t\t\tbox-shadow: inset 0 .15em .3em rgba(1, 4, 9, .15);\n\t\t\t\tbackground-image: none;\n\t\t\t\tfilter: none\n\t\t\t}\n\n\t\t\t.social-count {\n\t\t\t\tcolor: #c9d1d9;\n\t\t\t\tbackground-color: #0d1117;\n\t\t\t\tborder-color: #24282e;\n\t\t\t\tborder-color: rgba(240, 246, 252, .1)\n\t\t\t}\n\n\t\t\t.social-count:hover,\n\t\t\t.social-count:focus {\n\t\t\t\tcolor: #58a6ff\n\t\t\t}\n\n\t\t\t.octicon-heart {\n\t\t\t\tcolor: #db61a2\n\t\t\t}\n\t\t}\n\t}\n}\n\n#share-link-copied {\n\tcolor: hsl(60, 100%, 30%);\n\tdisplay: none;\n}\n\n#share-link-instructions {\n\tdisplay: none;\n}\n\n// Hide instructions in kiosk mode (higher specificity than the show rule)\nbody.kiosk #loading .instructions {\n\tdisplay: none !important;\n}\n\n.kiosk {\n\n\t// In kiosk mode, hide everything except the main weather display\n\t>*:not(#divTwc) {\n\t\tdisplay: none !important;\n\t}\n}\n\n#divInfo {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr;\n\tmax-width: 250px;\n}","@use 'colors'as c;\n\n@mixin text-shadow($offset: 3px, $outline: 1.5px) {\n\t/* eventually, when chrome supports paint-order for html elements */\n\t/* -webkit-text-stroke: 2px black; */\n\t/* paint-order: stroke fill; */\n\ttext-shadow:\n\t\t$offset $offset 0 c.$text-shadow,\n\t\t(-$outline) (-$outline) 0 c.$text-shadow,\n\t\t0 (-$outline) 0 c.$text-shadow,\n\t\t$outline (-$outline) 0 c.$text-shadow,\n\t\t$outline 0 0 c.$text-shadow,\n\t\t$outline $outline 0 c.$text-shadow,\n\t\t0 $outline 0 c.$text-shadow,\n\t\t(-$outline) $outline 0 c.$text-shadow,\n\t\t(-$outline) 0 0 c.$text-shadow;\n}\n\n@mixin status-colors() {\n\n\t.loading,\n\t.retrying {\n\t\tcolor: #ffff00;\n\t}\n\n\t.press-here {\n\t\tcolor: #00ff00;\n\t\tcursor: pointer;\n\t}\n\n\t.failed {\n\t\tcolor: #ff0000;\n\t}\n\n\t.no-data {\n\t\tcolor: #C0C0C0;\n\t}\n\n\t.disabled {\n\t\tcolor: #C0C0C0;\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display {\n\twidth: 640px;\n\theight: 480px;\n\toverflow: hidden;\n\tposition: relative;\n\tbackground-image: url(../images/backgrounds/1.png);\n\n\t/* this method is required to hide blocks so they can be measured while off screen */\n\theight: 0px;\n\n\t&.show {\n\t\theight: 480px;\n\t}\n\n\t.template {\n\t\tdisplay: none;\n\t}\n\n\t.header {\n\t\twidth: 640px;\n\t\theight: 60px;\n\t\tpadding-top: 30px;\n\t\tposition: relative;\n\t\tz-index: 20;\n\n\t\t.title {\n\t\t\tcolor: c.$title-color;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\t\t\tposition: absolute;\n\t\t\twidth: 250px;\n\n\t\t\t&.single {\n\t\t\t\tleft: 170px;\n\t\t\t\ttop: 25px;\n\t\t\t}\n\n\t\t\t&.dual {\n\t\t\t\tleft: 170px;\n\n\t\t\t\t&>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t}\n\n\t\t\t\t.top {\n\t\t\t\t\ttop: -3px;\n\t\t\t\t}\n\n\t\t\t\t.bottom {\n\t\t\t\t\ttop: 26px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t.logo {\n\t\t\ttop: 30px;\n\t\t\tleft: 50px;\n\t\t\tposition: absolute;\n\t\t\tz-index: 10;\n\t\t}\n\n\t\t.noaa-logo {\n\t\t\tposition: absolute;\n\t\t\ttop: 39px;\n\t\t\tleft: 356px;\n\t\t}\n\n\t\t.title.single {\n\t\t\ttop: 40px;\n\t\t}\n\n\t\t.date-time {\n\t\t\twhite-space: pre;\n\t\t\tcolor: c.$date-time;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\t@include u.text-shadow(3px, 1.5px);\n\t\t\tleft: 415px;\n\t\t\twidth: 170px;\n\t\t\ttext-align: right;\n\t\t\tposition: absolute;\n\n\t\t\t&.date {\n\t\t\t\tpadding-top: 22px;\n\t\t\t}\n\t\t}\n\t}\n\n\t.main {\n\t\tposition: relative;\n\n\t\t&.has-scroll {\n\t\t\twidth: 640px;\n\t\t\tmargin-top: 0;\n\t\t\theight: 310px;\n\t\t\toverflow: hidden;\n\n\t\t\t&.no-header {\n\t\t\t\theight: 400px;\n\t\t\t\tmargin-top: 0; // Reset for no-header case since the gap issue is header-related\n\t\t\t}\n\t\t}\n\n\t\t&.has-box {\n\t\t\tmargin-left: 64px;\n\t\t\tmargin-right: 64px;\n\t\t\twidth: calc(100% - 128px);\n\t\t}\n\n\t}\n\n}\n\n#container>.scroll {\n\tdisplay: none;\n\t@include u.text-shadow(3px, 1.5px);\n\twidth: 640px;\n\theight: 77px;\n\toverflow: hidden;\n\tmargin-top: 3px;\n\tposition: absolute;\n\tbottom: 0px;\n\tz-index: 1;\n\n\t&.hazard {\n\t\tbackground-color: rgb(112, 35, 35);\n\t}\n\n\t.scroll-container {\n\t\twidth: 640px;\n\n\t\t.fixed,\n\t\t.scroll-header {\n\t\t\tmargin-left: 55px;\n\t\t\tmargin-right: 55px;\n\t\t\toverflow: hidden;\n\t\t\twhite-space: nowrap;\n\t\t}\n\n\t\t.scroll-header {\n\t\t\theight: 26px;\n\t\t\tfont-family: \"Star4000 Small\";\n\t\t\tfont-size: 20pt;\n\t\t\tmargin-top: -10px;\n\t\t}\n\n\t\t.fixed {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 24pt;\n\n\t\t\t.scroll-area {\n\t\t\t\ttext-wrap: nowrap;\n\t\t\t\tposition: relative;\n\t\t\t\t// the following added by js code as it is dependent on the content of the element\n\t\t\t\t// transition: left (x)s;\n\t\t\t\t// left: calc((elem width) - 640px);\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n\n.wide #container>.scroll {\n\twidth: 854px;\n\tmargin-left: -107px;\n\n\t.scroll-container {\n\t\tmargin-left: 107px;\n\t}\n}\n","$title-color: yellow;\n$date-time: white;\n$text-shadow: black;\n$column-header-text: yellow;\n$column-header: rgb(32, 0, 87);\n\n$gradient-main-background-1: #102080;\n$gradient-main-background-2: #001040;\n\n$gradient-loading-1: #09246f;\n$gradient-loading-2: #364ac0;\n$gradient-loading-3: #4f99f9;\n$gradient-loading-4: #8ffdfa;\n\n$extended-low: #8080FF;\n\n$blue-box: #26235a;","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.current-weather {\n\t&.main {\n\n\t\t.col {\n\t\t\theight: 50px;\n\t\t\twidth: 255px;\n\t\t\tdisplay: inline-block;\n\t\t\tmargin-top: 10px;\n\t\t\tpadding-top: 10px;\n\t\t\tposition: absolute;\n\n\t\t\t@include u.text-shadow();\n\n\t\t\t&.left {\n\t\t\t\tfont-family: 'Star4000 Extended';\n\t\t\t\tfont-size: 24pt;\n\n\t\t\t}\n\n\t\t\t&.right {\n\t\t\t\tright: 0px;\n\t\t\t\tfont-family: \"Star4000 Large\";\n\t\t\t\tfont-size: 20px;\n\t\t\t\tfont-weight: bold;\n\t\t\t\tline-height: 24px;\n\n\t\t\t\t.row {\n\t\t\t\t\tmargin-bottom: 12px;\n\n\t\t\t\t\t.label,\n\t\t\t\t\t.value {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\n\t\t\t\t\t.label {\n\t\t\t\t\t\tmargin-left: 20px;\n\t\t\t\t\t}\n\n\t\t\t\t\t.value {\n\t\t\t\t\t\tfloat: right;\n\t\t\t\t\t\tmargin-right: 10px;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\t.center {\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000 Large';\n\t\t\tfont-size: 24pt;\n\t\t}\n\n\t\t.icon {\n\t\t\timg {\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tdisplay: block;\n\t\t\t}\n\t\t}\n\n\t\t.wind-container {\n\t\t\tmargin-left: 10px;\n\t\t\tdisplay: flex;\n\n\t\t\t&>div {\n\t\t\t\twidth: 50%;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\ttext-align: right;\n\t\t\t}\n\t\t}\n\n\t\t.wind-gusts {\n\t\t\ttext-align: right;\n\t\t\tfont-size: 28px;\n\t\t}\n\n\t\t.location {\n\t\t\tcolor: c.$title-color;\n\t\t\tmax-height: 32px;\n\t\t\tmargin-bottom: 10px;\n\t\t\tpadding-top: 4px;\n\t\t\toverflow: hidden;\n\t\t\ttext-wrap: nowrap;\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#extended-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/2.png');\n}\n\n.weather-display .main.extended-forecast {\n\t.day-container {\n\t\tmargin-top: 16px;\n\t\tmargin-left: 27px;\n\t}\n\n\t.day {\n\t\t@include u.text-shadow();\n\t\tpadding: 5px;\n\t\theight: 285px;\n\t\twidth: 155px;\n\t\tdisplay: inline-block;\n\t\tmargin: 0px 15px;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\n\t\t.date {\n\t\t\ttext-transform: uppercase;\n\t\t\ttext-align: center;\n\t\t\tcolor: c.$title-color;\n\t\t}\n\n\t\t.condition {\n\t\t\ttext-align: center;\n\t\t\theight: 74px;\n\t\t\tmargin-top: 5px;\n\t\t}\n\n\t\t.icon {\n\t\t\ttext-align: center;\n\t\t\theight: 75px;\n\n\t\t\timg {\n\t\t\t\tmax-height: 75px;\n\t\t\t}\n\t\t}\n\n\t\t.temperatures {\n\t\t\twidth: 100%;\n\n\t\t\t.temperature-block {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 44%;\n\t\t\t\tvertical-align: top;\n\n\t\t\t\t>div {\n\t\t\t\t\ttext-align: center;\n\t\t\t\t}\n\n\t\t\t\t.value {\n\t\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\t\tmargin-top: 4px;\n\t\t\t\t}\n\n\t\t\t\t&.lo .label {\n\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t}\n\n\t\t\t\t&.hi .label {\n\t\t\t\t\tcolor: c.$title-color;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .main.hourly {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\t\t.hourly-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\tbackground: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px,\n\t\t\t\t\tc.$gradient-main-background-1 136px,\n\t\t\t\t\tc.$gradient-main-background-1 202px,\n\t\t\t\t\tc.$gradient-main-background-2 338px,\n\t\t\t\t);\n\n\t\t\t.hourly-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.hour {\n\t\t\t\t\tleft: 25px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 255px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\tleft: 355px;\n\t\t\t\t}\n\n\t\t\t\t.like {\n\t\t\t\t\tleft: 425px;\n\n\t\t\t\t\t&.heat-index {\n\t\t\t\t\t\tcolor: #e00;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.wind-chill {\n\t\t\t\t\t\tcolor: c.$extended-low;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.wind {\n\t\t\t\t\tleft: 505px;\n\t\t\t\t\twidth: 100px;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hourly-graph-html {\n\tbackground-image: url(../images/backgrounds/1-chart.png);\n\n\t.header {\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\ttop: 35px;\n\t\t\tright: 60px;\n\t\t\twidth: 360px;\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 28px;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: right;\n\n\t\t\tdiv {\n\t\t\t\tmargin-top: -18px;\n\t\t\t}\n\n\t\t\t.temperature {\n\t\t\t\tcolor: red;\n\t\t\t}\n\n\t\t\t.dewpoint {\n\t\t\t\tcolor: green;\n\t\t\t}\n\n\t\t\t.cloud {\n\t\t\t\tcolor: lightgrey;\n\t\t\t}\n\n\t\t\t.rain {\n\t\t\t\tcolor: aqua;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.hourly-graph {\n\n\t&.main {\n\t\t>div {\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.label {\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 24pt;\n\t\t\tcolor: c.$column-header-text;\n\t\t\t@include u.text-shadow();\n\t\t\tmargin-top: -15px;\n\t\t\tposition: absolute;\n\t\t}\n\n\t\t.x-axis {\n\t\t\tbottom: 0px;\n\t\t\tleft: 54px;\n\t\t\twidth: 532px;\n\t\t\theight: 20px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: center;\n\t\t\t\ttransform: translateX(-50%);\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\tleft: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\tleft: calc(532px / 4 * 1);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tleft: calc(532px / 4 * 2);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tleft: calc(532px / 4 * 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-5 {\n\t\t\t\t\tleft: calc(532px / 4 * 4);\n\t\t\t\t}\n\t\t\t}\n\n\n\n\t\t}\n\n\t\t.chart {\n\t\t\ttop: 0px;\n\t\t\tleft: 50px;\n\n\t\t\timg {\n\t\t\t\twidth: 532px;\n\t\t\t\theight: 285px;\n\t\t\t}\n\t\t}\n\n\t\t.y-axis {\n\t\t\ttop: 0px;\n\t\t\tleft: 0px;\n\t\t\twidth: 50px;\n\t\t\theight: 285px;\n\n\t\t\t.label {\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\n\t\t\t\t&.l-1 {\n\t\t\t\t\ttop: 0px;\n\t\t\t\t}\n\n\t\t\t\t&.l-2 {\n\t\t\t\t\ttop: calc(280px / 3);\n\t\t\t\t}\n\n\t\t\t\t&.l-3 {\n\t\t\t\t\tbottom: calc(280px / 3 - 11px);\n\t\t\t\t}\n\n\t\t\t\t&.l-4 {\n\t\t\t\t\tbottom: 0px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\tz-index: 5;\n\n\n\t\t\t.temp {\n\t\t\t\tleft: 355px;\n\t\t\t}\n\n\t\t\t.like {\n\t\t\t\tleft: 435px;\n\t\t\t}\n\n\t\t\t.wind {\n\t\t\t\tleft: 535px;\n\t\t\t}\n\t\t}\n\n\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .main.travel {\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\tbackground-color: c.$column-header;\n\t\t\theight: 20px;\n\t\t\tposition: sticky;\n\t\t\ttop: 0px;\n\t\t\twidth: 100%;\n\t\t\tz-index: 5;\n\t\t\toverflow: hidden; // prevent thin gaps between header and content\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\tz-index: 5;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\twidth: 50px;\n\t\t\t\ttext-align: center;\n\n\t\t\t\t&.low {\n\t\t\t\t\tleft: 455px;\n\n\t\t\t\t}\n\n\t\t\t\t&.high {\n\t\t\t\t\tleft: 510px;\n\t\t\t\t\twidth: 60px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.travel-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\tbackground: repeating-linear-gradient(0deg, c.$gradient-main-background-2 0px,\n\t\t\t\t\tc.$gradient-main-background-1 136px,\n\t\t\t\t\tc.$gradient-main-background-1 202px,\n\t\t\t\t\tc.$gradient-main-background-2 338px,\n\t\t\t\t);\n\n\t\t\t.travel-row {\n\t\t\t\tfont-family: 'Star4000 Large';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\theight: 72px;\n\t\t\t\tcolor: c.$title-color;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.city {\n\t\t\t\t\tleft: 80px;\n\t\t\t\t}\n\n\t\t\t\t.icon {\n\t\t\t\t\tleft: 330px;\n\t\t\t\t\twidth: 70px;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\ttop: unset;\n\n\t\t\t\t\timg {\n\t\t\t\t\t\tmax-width: 47px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.temp {\n\t\t\t\t\twidth: 50px;\n\t\t\t\t\ttext-align: center;\n\n\t\t\t\t\t&.low {\n\t\t\t\t\t\tleft: 455px;\n\t\t\t\t\t}\n\n\t\t\t\t\t&.high {\n\t\t\t\t\t\tleft: 510px;\n\t\t\t\t\t\twidth: 60px;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .latest-observations {\n\n\t&.main {\n\t\toverflow-y: hidden;\n\n\t\t.column-headers {\n\t\t\theight: 20px;\n\t\t\tposition: absolute;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.column-headers {\n\t\t\ttop: 0px;\n\n\t\t\tdiv {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: -14px;\n\t\t\t\t@include u.text-shadow();\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\t// hidden initially for english/metric switching\n\t\t\t\tdisplay: none;\n\n\t\t\t\t&.show {\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.temp {\n\t\t\tleft: 230px;\n\t\t}\n\n\t\t.weather {\n\t\t\tleft: 280px;\n\t\t}\n\n\t\t.wind {\n\t\t\tleft: 430px;\n\t\t}\n\n\t\t.observation-lines {\n\t\t\tmin-height: 338px;\n\t\t\tpadding-top: 10px;\n\n\t\t\t.observation-row {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tposition: relative;\n\t\t\t\theight: 40px;\n\n\t\t\t\t>div {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\ttop: 8px;\n\t\t\t\t}\n\n\t\t\t\t.wind {\n\t\t\t\t\twhite-space: pre;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n.weather-display .local-forecast {\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 280px;\n\t\toverflow: hidden;\n\t}\n\n\t.forecasts {\n\t\tposition: relative;\n\t}\n\n\t.forecast {\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 24pt;\n\t\ttext-transform: uppercase;\n\t\t@include u.text-shadow();\n\t\tmin-height: 280px;\n\t\tline-height: 40px;\n\t}\n}","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n.weather-display .progress {\n\t@include u.text-shadow();\n\tfont-family: 'Star4000 Extended';\n\tfont-size: 18pt;\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 310px;\n\t\toverflow: hidden;\n\t\tline-height: 26px;\n\n\t\t.item {\n\t\t\tposition: relative;\n\n\t\t\t.name {\n\t\t\t\twhite-space: nowrap;\n\n\t\t\t\t&::after {\n\t\t\t\t\tcontent: '........................................................................';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.links {\n\t\t\t\tposition: absolute;\n\t\t\t\ttext-align: right;\n\t\t\t\tright: 0px;\n\t\t\t\ttop: 0px;\n\n\t\t\t\t>div {\n\t\t\t\t\tbackground-color: c.$blue-box;\n\t\t\t\t\tdisplay: none;\n\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t}\n\n\t\t\t\t@include u.status-colors();\n\n\t\t\t\t&.loading .loading,\n\t\t\t\t&.press-here .press-here,\n\t\t\t\t&.failed .failed,\n\t\t\t\t&.no-data .no-data,\n\t\t\t\t&.disabled .disabled,\n\t\t\t\t&.retrying .retrying {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\n}\n\n#progress-html.weather-display .scroll {\n\n\t@keyframes progress-scroll {\n\t\t0% {\n\t\t\tbackground-position: -40px 0;\n\t\t}\n\n\t\t100% {\n\t\t\tbackground-position: 40px 0;\n\t\t}\n\t}\n\n\t.progress-bar-container {\n\t\tborder: 2px solid black;\n\t\tbackground-color: white;\n\t\tmargin: 20px auto;\n\t\twidth: 524px;\n\t\tposition: relative;\n\t\tdisplay: none;\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t.progress-bar {\n\t\t\theight: 20px;\n\t\t\tmargin: 2px;\n\t\t\twidth: 520px;\n\t\t\tbackground: repeating-linear-gradient(90deg,\n\t\t\t\t\tc.$gradient-loading-1 0px,\n\t\t\t\t\tc.$gradient-loading-1 5px,\n\t\t\t\t\tc.$gradient-loading-2 5px,\n\t\t\t\t\tc.$gradient-loading-2 10px,\n\t\t\t\t\tc.$gradient-loading-3 10px,\n\t\t\t\t\tc.$gradient-loading-3 15px,\n\t\t\t\t\tc.$gradient-loading-4 15px,\n\t\t\t\t\tc.$gradient-loading-4 20px,\n\t\t\t\t\tc.$gradient-loading-3 20px,\n\t\t\t\t\tc.$gradient-loading-3 25px,\n\t\t\t\t\tc.$gradient-loading-2 25px,\n\t\t\t\t\tc.$gradient-loading-2 30px,\n\t\t\t\t\tc.$gradient-loading-1 30px,\n\t\t\t\t\tc.$gradient-loading-1 40px,\n\t\t\t\t);\n\t\t\t// animation\n\t\t\tanimation-duration: 2s;\n\t\t\tanimation-fill-mode: forwards;\n\t\t\tanimation-iteration-count: infinite;\n\t\t\tanimation-name: progress-scroll;\n\t\t\tanimation-timing-function: steps(8, end);\n\t\t}\n\n\t\t.cover {\n\t\t\tposition: absolute;\n\t\t\ttop: 0px;\n\t\t\tright: 0px;\n\t\t\tbackground-color: white;\n\t\t\twidth: 100%;\n\t\t\theight: 24px;\n\t\t\ttransition: width 1s steps(6);\n\t\t}\n\t}\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#radar-html.weather-display {\n\tbackground-image: url('../images/backgrounds/4.png');\n\n\t.header {\n\t\theight: 83px;\n\n\t\t.title.dual {\n\t\t\tcolor: white;\n\t\t\tfont-family: 'Arial', sans-serif;\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 28pt;\n\t\t\tleft: 155px;\n\n\t\t\t.top {\n\t\t\t\ttop: -4px;\n\t\t\t}\n\n\t\t\t.bottom {\n\t\t\t\ttop: 31px;\n\t\t\t}\n\t\t}\n\n\t\t.right {\n\t\t\tposition: absolute;\n\t\t\tright: 0px;\n\t\t\twidth: 360px;\n\t\t\tmargin-top: 2px;\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 18pt;\n\t\t\tfont-weight: bold;\n\t\t\t@include u.text-shadow();\n\t\t\ttext-align: center;\n\n\t\t\t.scale-table {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: center;\n\t\t\t\tgap: 7px;\n\n\t\t\t\t.item {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: column;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\twidth: 25px;\n\t\t\t\t\tgap: 2px;\n\t\t\t\t}\n\n\t\t\t\t.box {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t\tborder: 2px solid black;\n\t\t\t\t\twidth: 100%;\n\t\t\t\t\theight: 22px;\n\t\t\t\t\tpadding: 0;\n\t\t\t\t}\n\n\t\t\t\t.box-1 {\n\t\t\t\t\tbackground-color: rgb(73, 190, 246);\n\t\t\t\t}\n\n\t\t\t\t.box-2 {\n\t\t\t\t\tbackground-color: rgb(49, 210, 22);\n\t\t\t\t}\n\n\t\t\t\t.box-3 {\n\t\t\t\t\tbackground-color: rgb(241, 228, 88);\n\t\t\t\t}\n\n\t\t\t\t.box-4 {\n\t\t\t\t\tbackground-color: rgb(224, 142, 47);\n\t\t\t\t}\n\n\t\t\t\t.box-5 {\n\t\t\t\t\tbackground-color: rgb(196, 42, 42);\n\t\t\t\t}\n\n\t\t\t\t.box-6 {\n\t\t\t\t\tbackground-color: rgb(145, 59, 184);\n\t\t\t\t}\n\n\t\t\t\t.label {\n\t\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\t\tfont-size: 10pt;\n\t\t\t\t\tline-height: 1;\n\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.scale {\n\t\t\t\tmargin-top: -2px;\n\t\t\t}\n\n\t\t\t.time {\n\t\t\t\tposition: relative;\n\t\t\t\tfont-weight: normal;\n\t\t\t\ttop: -20px;\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 18pt;\n\t\t\t\tleft: 130px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.weather-display .main.radar {\n\toverflow: hidden;\n\theight: 367px;\n\n\t.container {\n\t\tposition: relative;\n\t\theight: 100%;\n\n\t\t.scroll-area {\n\t\t\tposition: relative;\n\t\t\theight: 100%;\n\t\t}\n\n\t\t.frame {\n\t\t\theight: 100%;\n\t\t}\n\n\t\t.map {\n\t\t\theight: 100%;\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.leaflet-map {\n\t\t\theight: 100%;\n\t\t\twidth: 100%;\n\t\t\tbackground: #061f3e;\n\t\t}\n\n\t\t.leaflet-container {\n\t\t\tbackground: #061f3e;\n\t\t\tfont-family: inherit;\n\t\t}\n\n\t\t.radar-base-layer,\n\t\t.radar-base-layer .leaflet-tile {\n\t\t\tfilter: grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2);\n\t\t}\n\n\t\t.radar-boundary-layer,\n\t\t.radar-boundary-layer .leaflet-tile {\n\t\t\tfilter: grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1);\n\t\t}\n\n\t\t.leaflet-control-container,\n\t\t.leaflet-control-attribution,\n\t\t.leaflet-control-zoom {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\t.location-marker {\n\t\t\tbackground: #ff0;\n\t\t\tborder: 2px solid #000;\n\t\t\tborder-radius: 50%;\n\t\t}\n\n\t\t.nearby-weather-marker {\n\t\t\tbackground: transparent;\n\t\t\tborder: 0;\n\n\t\t\t.nearby-weather-marker-inner {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: center;\n\t\t\t\tmin-width: 72px;\n\t\t\t\tpadding: 2px 4px;\n\t\t\t\tbackground: rgba(18, 34, 61, 0.88);\n\t\t\t\tborder: 1px solid #000;\n\t\t\t\tbox-shadow: 1px 1px 0 #000;\n\t\t\t\tcolor: #fff;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t.city {\n\t\t\t\tfont-family: 'Star4000 Small';\n\t\t\t\tfont-size: 11pt;\n\t\t\t\tline-height: 1;\n\t\t\t\twhite-space: nowrap;\n\t\t\t\tmargin-bottom: 1px;\n\t\t\t\ttext-shadow: 1px 1px 0 #000;\n\t\t\t}\n\n\t\t\t.details {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tgap: 2px;\n\t\t\t}\n\n\t\t\t.temp {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 18pt;\n\t\t\t\tline-height: 1;\n\t\t\t\tcolor: #ff0;\n\t\t\t\ttext-shadow: 1px 1px 0 #000;\n\t\t\t}\n\n\t\t\timg {\n\t\t\t\twidth: auto;\n\t\t\t\theight: 20px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.wide.radar #container {\n\tbackground: url(../images/backgrounds/4-wide.png);\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#regional-forecast-html.weather-display {\n\tbackground-image: url('../images/backgrounds/5.png');\n}\n\n.weather-display .main.regional-forecast {\n\tposition: relative;\n\toverflow: hidden;\n\tz-index: 0;\n\n\t.map {\n\t\tposition: absolute;\n\t\tinset: 0;\n\t}\n\n\t.leaflet-map {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\tbackground: #061f3e;\n\t}\n\n\t.leaflet-container {\n\t\tbackground: #061f3e;\n\t\tfont-family: inherit;\n\t}\n\n\t.radar-base-layer,\n\t.radar-base-layer .leaflet-tile {\n\t\tfilter: grayscale(0.35) brightness(0.58) contrast(1.1) saturate(0.2);\n\t}\n\n\t.radar-boundary-layer,\n\t.radar-boundary-layer .leaflet-tile {\n\t\tfilter: grayscale(0.8) brightness(0.7) contrast(1.3) saturate(0.1);\n\t}\n\n\t.leaflet-control-container,\n\t.leaflet-control-attribution,\n\t.leaflet-control-zoom {\n\t\tdisplay: none;\n\t}\n\n\t.location-marker {\n\t\tbackground: #ff0;\n\t\tborder: 2px solid #000;\n\t\tborder-radius: 50%;\n\t}\n\n\t.nearby-weather-marker {\n\t\tbackground: transparent;\n\t\tborder: 0;\n\n\t\t.nearby-weather-marker-inner {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\talign-items: center;\n\t\t\tmin-width: 72px;\n\t\t\tpadding: 2px 4px;\n\t\t\tbackground: rgba(18, 34, 61, 0.88);\n\t\t\tborder: 1px solid #000;\n\t\t\tbox-shadow: 1px 1px 0 #000;\n\t\t\tcolor: #fff;\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.city {\n\t\t\tfont-family: 'Star4000 Small';\n\t\t\tfont-size: 11pt;\n\t\t\tline-height: 1;\n\t\t\twhite-space: nowrap;\n\t\t\tmargin-bottom: 1px;\n\t\t\t@include u.text-shadow();\n\t\t}\n\n\t\t.details {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tgap: 2px;\n\t\t}\n\n\t\t.temp {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 18pt;\n\t\t\tline-height: 1;\n\t\t\tcolor: c.$title-color;\n\t\t\t@include u.text-shadow();\n\t\t}\n\n\t\timg {\n\t\t\twidth: auto;\n\t\t\theight: 20px;\n\t\t}\n\t}\n}\n","@use 'shared/_colors' as c;\n@use 'shared/_utils' as u;\n\n#almanac-html.weather-display {\n\tbackground-image: url('../images/backgrounds/3.png');\n}\n\n.weather-display .main.almanac {\n\tfont-family: 'Star4000';\n\tfont-size: 24pt;\n\t@include u.text-shadow();\n\n\t.sun {\n\t\t// Use CSS Grid for cross-browser consistency\n\t\t// Grid is populated in reading order (left-to-right, top-to-bottom):\n\t\tdisplay: grid;\n\t\tgrid-template-columns: auto auto auto;\n\t\tgrid-template-rows: auto auto auto;\n\t\tgap: 0px 90px;\n\t\tmargin: 3px auto 5px auto; // align the bottom of the div with the background\n\t\twidth: fit-content;\n\t\tline-height: 30px;\n\n\t\t.grid-item {\n\t\t\t// Reset inherited styles that interfere with grid layout\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tpadding: 0;\n\t\t\tmargin: 0;\n\t\t\tposition: relative;\n\n\t\t\t// Column headers (day names)\n\t\t\t&.header {\n\t\t\t\tcolor: c.$column-header-text;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t// Row labels (Sunrise:, Sunset:)\n\t\t\t&.row-label {\n\t\t\t\t// color: c.$column-header-text; // screenshots show labels were white\n\t\t\t\ttext-align: right;\n\t\t\t}\n\n\t\t\t// Time values (sunrise/sunset)\n\t\t\t&.time {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t}\n\t}\n\n\t.moon {\n\t\tposition: relative;\n\t\tpadding: 7px 50px;\n\t\tline-height: 36px;\n\n\t\t.title {\n\t\t\tcolor: c.$column-header-text;\n\t\t\tpadding-left: 13px;\n\t\t}\n\n\t\t.day {\n\t\t\tdisplay: inline-block;\n\t\t\ttext-align: center;\n\t\t\twidth: 132px;\n\n\t\t\t.icon {\n\t\t\t\t// shadow in image make it look off center\n\t\t\t\tpadding-left: 10px;\n\t\t\t}\n\n\t\t\t.date {\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -10px;\n\t\t\t}\n\t\t}\n\t}\n\n\n\n}\n","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#hazards-html.weather-display {\n\tbackground-image: url('../images/backgrounds/7.png');\n}\n\n.weather-display .main.hazards {\n\t&.main {\n\t\toverflow-y: hidden;\n\t\theight: 480px;\n\t\tbackground-color: rgb(112, 35, 35);\n\n\n\t\t.hazard-lines {\n\t\t\tmin-height: 400px;\n\t\t\tpadding-top: 10px;\n\n\t\t\t.hazard {\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\tcolor: white;\n\t\t\t\t@include u.text-shadow(0px);\n\t\t\t\tposition: relative;\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tmargin-top: 10px;\n\t\t\t\tmargin-left: 80px;\n\t\t\t\tmargin-right: 80px;\n\t\t\t\tpadding-bottom: 10px;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.wide.hazards #container {\n\tbackground: url(../images/backgrounds/7-wide.png);\n}",".media {\n\tdisplay: none;\n}\n\n#ToggleMediaContainer {\n\tdisplay: none;\n\tposition: relative;\n\n\t&.available {\n\t\tdisplay: inline-block;\n\n\t\timg.on {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\timg.off {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t// icon switch is handled by adding/removing the .playing class\n\t\t&.playing {\n\t\t\timg.on {\n\t\t\t\tdisplay: block;\n\t\t\t}\n\n\t\t\timg.off {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\n\t\t}\n\n\n\t}\n\n\t.volume-slider {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\ttop: 0px;\n\t\ttransform: translateY(-100%);\n\t\twidth: 100%;\n\t\tbackground-color: #000;\n\t\ttext-align: center;\n\t\tz-index: 100;\n\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\tbackground-color: #303030;\n\t\t}\n\n\t\tinput[type=\"range\"] {\n\t\t\twriting-mode: vertical-lr;\n\t\t\tdirection: rtl;\n\t\t\tmargin-top: 20px;\n\t\t\tmargin-bottom: 20px;\n\t\t}\n\n\t\t&.show {\n\t\t\tdisplay: block;\n\t\t}\n\t}\n\n\n\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#spc-outlook-html.weather-display {\n\tbackground-image: url('../images/backgrounds/6.png');\n}\n\n.weather-display .spc-outlook {\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 0px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 300px;\n\t\toverflow: hidden;\n\t}\n\n\t.risk-levels {\n\t\tposition: absolute;\n\t\tleft: 206px;\n\t\tfont-family: 'Star4000 Small';\n\t\tfont-size: 32px;\n\t\t@include u.text-shadow();\n\n\n\t\t.risk-level {\n\t\t\tposition: relative;\n\t\t\ttop: -14px;\n\t\t\theight: 20px;\n\n\t\t\t&:nth-child(1) {\n\t\t\t\tleft: calc(20px * 5);\n\t\t\t}\n\n\t\t\t&:nth-child(2) {\n\t\t\t\tleft: calc(20px * 4);\n\t\t\t}\n\n\t\t\t&:nth-child(3) {\n\t\t\t\tleft: calc(20px * 3);\n\t\t\t}\n\n\t\t\t&:nth-child(4) {\n\t\t\t\tleft: calc(20px * 2);\n\t\t\t}\n\n\t\t\t&:nth-child(5) {\n\t\t\t\tleft: calc(20px * 1);\n\t\t\t}\n\n\t\t\t&:nth-child(6) {\n\t\t\t\tleft: calc(20px * 0);\n\t\t\t}\n\t\t}\n\t}\n\n\t.days {\n\t\tposition: absolute;\n\t\ttop: 120px;\n\n\t\t.day {\n\t\t\theight: 60px;\n\n\t\t\t.day-name {\n\t\t\t\tposition: absolute;\n\t\t\t\tfont-family: 'Star4000';\n\t\t\t\tfont-size: 24pt;\n\t\t\t\twidth: 200px;\n\t\t\t\ttext-align: right;\n\t\t\t\t@include u.text-shadow();\n\t\t\t\tpadding-top: 20px;\n\t\t\t}\n\n\t\t\t.risk-bar {\n\t\t\t\tposition: absolute;\n\t\t\t\twidth: 150px;\n\t\t\t\theight: 40px;\n\t\t\t\tleft: 210px;\n\t\t\t\tmargin-top: 20px;\n\t\t\t\tborder: 3px outset hsl(0, 0%, 70%);\n\t\t\t\tbackground: linear-gradient(0deg, hsl(0, 0%, 40%) 0%, hsl(0, 0%, 60%) 50%, hsl(0, 0%, 40%) 100%);\n\t\t\t}\n\t\t}\n\t}\n}","@use 'shared/_colors'as c;\n@use 'shared/_utils'as u;\n\n#server-observations-html.weather-display {\n\t.header .title.single {\n\t\tfont-size: 20pt;\n\t}\n}\n\n.weather-display .server-observations {\n\t// Override the default has-scroll height to fit content properly\n\t&.main {\n\t\theight: auto !important;\n\t\tmin-height: 250px;\n\t}\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tbox-sizing: border-box;\n\t\theight: 250px;\n\t\toverflow: hidden;\n\t}\n\n\t.server-output {\n\t\tposition: relative;\n\t\tfont-family: 'Star4000';\n\t\tfont-size: 20pt;\n\t\tline-height: 32px;\n\t\tcolor: #fff;\n\t\ttext-transform: uppercase;\n\t\ttext-align: center;\n\t\t@include u.text-shadow();\n\n\t\t.server-page {\n\t\t\theight: 250px;\n\t\t\tpadding: 0 8px;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\n\t\t.server-line {\n\t\t\twhite-space: normal;\n\t\t\toverflow-wrap: anywhere;\n\t\t\tword-break: break-word;\n\t\t\tmargin-bottom: 6px;\n\t\t}\n\t}\n}\n","@use 'shared/_utils' as u;\n\n.weather-display .linux-news {\n\t&.main {\n\t\theight: auto !important;\n\t\tmin-height: 250px;\n\t}\n\n\t.container {\n\t\tposition: relative;\n\t\ttop: 15px;\n\t\tmargin: 0px 10px;\n\t\tbox-sizing: border-box;\n\t\theight: 250px;\n\t\toverflow: hidden;\n\t}\n\n\t.news-output {\n\t\tposition: relative;\n\n\t\t.news-page {\n\t\t\theight: 250px;\n\t\t\tbox-sizing: border-box;\n\t\t\tpadding: 0 8px;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tjustify-content: space-between;\n\t\t}\n\n\t\t.story {\n\t\t\theight: 116px;\n\t\t\toverflow: hidden;\n\t\t}\n\n\t\t.headline {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 17pt;\n\t\t\tline-height: 22px;\n\t\t\tcolor: #ff0;\n\t\t\ttext-transform: uppercase;\n\t\t\t@include u.text-shadow();\n\t\t\tmargin-bottom: 4px;\n\t\t}\n\n\t\t.blurb {\n\t\t\tfont-family: 'Star4000';\n\t\t\tfont-size: 14pt;\n\t\t\tline-height: 16px;\n\t\t\tcolor: #fff;\n\t\t\t@include u.text-shadow();\n\t\t\toverflow: hidden;\n\t\t}\n\t}\n}\n","/* =========================================================\n REGULAR SCANLINES SETTINGS\n ========================================================= */\n\n$scan-width: 1px;\n$scan-crt: false;\n$scan-fps: 20;\n$scan-color: rgba(#000, 0.30);\n$scan-z-index: 2147483648;\n\n$scan-moving-line: true;\n$scan-opacity: 0.75;\n\n/* =========================================================\n CRT / S-VIDEO EFFECT SETTINGS\n ========================================================= */\n\n// whole-screen softness\n$crt-soft-blur: 0.45px;\n\n// mild brightening / contrast to keep blur from looking muddy\n$crt-contrast: 1.04;\n$crt-saturation: 1.08;\n$crt-brightness: 0.98;\n\n// fake horizontal chroma bleed\n$crt-r-shift: -0.7px;\n$crt-b-shift: 0.7px;\n$crt-bleed-blur: 1.2px;\n$crt-rgb-opacity: 0.04;\n\n// subtle tube edge darkening\n$crt-vignette-opacity: 0.16;\n\n// optional tiny bloom\n$crt-glow-opacity: 0.05;\n\n/* =========================================================\n MIXINS\n ========================================================= */\n\n@mixin scan-crt($enabled) {\n @if $enabled == true {\n animation: scanlines 1s steps($scan-fps) infinite;\n } @else {\n animation: none;\n }\n}\n\n@mixin scan-moving($enabled) {\n @if $enabled == true {\n animation: scanline 6s linear infinite;\n } @else {\n animation: none;\n }\n}\n\n/* =========================================================\n APPLY TO THE REAL APP CONTAINER\n ========================================================= */\n\n/*\n You can add class=\"scanlines\" to #divTwcMain or #container.\n Example:\n
\n*/\n\n.scanlines {\n position: relative;\n overflow: hidden;\n isolation: isolate;\n\n /*\n This is the actual rendered weather area in your HTML.\n Applying the softness here affects the maps/text/icons themselves.\n */\n #container {\n position: relative;\n z-index: 1;\n transform: translateZ(0);\n will-change: filter;\n\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n }\n\n /*\n Red fringe overlay\n */\n #container::before,\n #container::after {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 3;\n }\n\n #container::before {\n background:\n linear-gradient(\n to right,\n rgba(255, 0, 0, $crt-rgb-opacity) 0%,\n rgba(255, 0, 0, 0.01) 15%,\n rgba(255, 0, 0, 0.00) 50%,\n rgba(255, 0, 0, 0.01) 85%,\n rgba(255, 0, 0, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-r-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Blue fringe overlay\n */\n #container::after {\n background:\n linear-gradient(\n to right,\n rgba(0, 140, 255, $crt-rgb-opacity) 0%,\n rgba(0, 140, 255, 0.01) 15%,\n rgba(0, 140, 255, 0.00) 50%,\n rgba(0, 140, 255, 0.01) 85%,\n rgba(0, 140, 255, $crt-rgb-opacity) 100%\n );\n transform: translateX($crt-b-shift);\n filter: blur($crt-bleed-blur);\n mix-blend-mode: screen;\n }\n\n /*\n Moving scanline\n */\n &:before,\n &:after {\n display: block;\n pointer-events: none;\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n }\n\n &:before {\n height: var(--scanline-thickness, $scan-width);\n z-index: $scan-z-index + 2;\n background: $scan-color;\n opacity: $scan-opacity;\n @include scan-moving($scan-moving-line);\n }\n\n /*\n Regular scanline mask\n */\n &:after {\n top: 0;\n bottom: 0;\n z-index: $scan-z-index;\n background: repeating-linear-gradient(\n to bottom,\n transparent 0,\n transparent var(--scanline-thickness, $scan-width),\n $scan-color var(--scanline-thickness, $scan-width),\n $scan-color calc(var(--scanline-thickness, $scan-width) * 2)\n );\n @include scan-crt($scan-crt);\n }\n\n /*\n Vignette layer\n Added as an inset shadow so you don't need extra HTML\n */\n box-shadow:\n inset 0 0 80px rgba(0, 0, 0, $crt-vignette-opacity),\n inset 0 0 18px rgba(255, 255, 255, $crt-glow-opacity);\n}\n\n/* =========================================================\n OPTIONAL: only affect active weather panels, not menus\n ========================================================= */\n\n/*\n If the controls / bottom nav get too blurry, move the blur\n from #container to the weather slides only:\n*/\n.scanlines.crt-panels-only {\n #container {\n filter: none;\n }\n\n .weather-display {\n filter:\n blur($crt-soft-blur)\n saturate($crt-saturation)\n contrast($crt-contrast)\n brightness($crt-brightness);\n\n transform: translateZ(0);\n }\n}\n\n/* =========================================================\n OPTIONAL: make text slightly glow like old TV phosphors\n ========================================================= */\n\n.scanlines {\n .header,\n .main,\n .scroll,\n .date-time,\n .city,\n .temp,\n .condition,\n .location,\n .label,\n .value,\n .title {\n text-shadow:\n 0 0 1px rgba(255, 255, 255, 0.18),\n 0 0 2px rgba(255, 255, 255, 0.06);\n }\n}\n\n/* =========================================================\n ANIMATIONS\n ========================================================= */\n\n@keyframes scanline {\n 0% {\n transform: translate3d(0, 200000%, 0);\n }\n}\n\n@keyframes scanlines {\n 0% {\n background-position: 0 50%;\n }\n}\n\n"],"file":"ws.min.css"} \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index 98025cc..05c7432 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -57,6 +57,7 @@ + @@ -117,6 +118,9 @@
<%- include('partials/local-forecast.ejs') %>
+
+ <%- include('partials/latest-observations.ejs') %> +
<%- include('partials/regional-forecast.ejs') %>
@@ -178,7 +182,7 @@
diff --git a/views/partials/latest-observations.ejs b/views/partials/latest-observations.ejs new file mode 100644 index 0000000..5af3684 --- /dev/null +++ b/views/partials/latest-observations.ejs @@ -0,0 +1,19 @@ +<%- include('header.ejs', {titleDual:{ top: 'Latest' , bottom: 'Observations' }, noaaLogo: true, hasTime: true }) %> +
+
+
+
°F
+
°C
+
Weather
+
Wind
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file