Redesign the landscape orientation for kiosk readability at 3-10m distance: - Add dark kiosk background (#1a1a2e) with high-contrast light text - Replace 2-column grid with 5-row full-width stacking layout - Add compact weather bar (temp + sunrise/sunset) replacing full widget - Enlarge countdown to 2em hero size in landscape - Replace time ranges with next 2-3 absolute departure times - Add 3-tier urgency colors: Nu (green), 1-2min (red), 3-5min (orange) - Make site headers full-width blue gradient bars in landscape - Tighten card spacing (65px min-height, 8px gap) for 4-stop visibility - Add scrolling news ticker with /api/ticker fallback messages - Fix daylight bar from position:fixed to relative in landscape grid - Hide background overlay in landscape for maximum contrast - Fix weather-section HTML missing closing div tags All changes scoped behind body.landscape CSS selectors; other orientations unaffected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
233 lines
11 KiB
HTML
233 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>SL Transport Departures - Ambassaderna (1411)</title>
|
|
<!-- Global configuration - will be set by Constants.js, kept for backward compatibility -->
|
|
<script>
|
|
// Global variables (fallback if Constants not loaded)
|
|
window.API_URL = window.API_URL || 'http://localhost:3002/api/departures';
|
|
window.REFRESH_INTERVAL = window.REFRESH_INTERVAL || 30000;
|
|
</script>
|
|
|
|
<!-- Leaflet.js for map functionality -->
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
|
|
<!-- External CSS -->
|
|
<link rel="stylesheet" href="public/css/main.css">
|
|
<link rel="stylesheet" href="public/css/components.css">
|
|
|
|
<!-- Main application script (ES module - imports all dependencies) -->
|
|
<script type="module" src="public/js/main.js"></script>
|
|
|
|
<!-- Inline styles removed - now in external CSS files -->
|
|
</head>
|
|
<body>
|
|
<!-- Content wrapper for vertical orientation -->
|
|
<div id="content-wrapper">
|
|
<!-- Clock element -->
|
|
<div id="clock"></div>
|
|
|
|
<!-- Compact weather bar (landscape only) -->
|
|
<div id="compact-weather-bar"></div>
|
|
|
|
<!-- Main content grid for landscape layout -->
|
|
<div class="main-content-grid">
|
|
<!-- Left side: Departures -->
|
|
<div class="departures-section">
|
|
<div class="status" id="status">Loading departures...</div>
|
|
|
|
<div class="departure-container" id="departures">
|
|
<!-- Departures will be inserted here by JavaScript -->
|
|
</div>
|
|
</div>
|
|
|
|
</div> <!-- End of main-content-grid -->
|
|
|
|
<!-- Weather widget - fixed at bottom -->
|
|
<div class="weather-section">
|
|
<div class="weather-container">
|
|
<!-- Custom weather display with hourly forecast -->
|
|
<div id="custom-weather">
|
|
<div class="current-weather">
|
|
<div class="location-info">
|
|
<h3>Stockholm</h3>
|
|
<div class="weather-icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/day/113.png" alt="Clear" />
|
|
<div>Clear</div>
|
|
</div>
|
|
</div>
|
|
<div class="temperature">7.1 °C</div>
|
|
<div class="sun-times">
|
|
☀️ Sunrise: 06:45 AM | 🌙 Sunset: 05:32 PM
|
|
</div>
|
|
</div>
|
|
<div class="forecast">
|
|
<div class="forecast-hour">
|
|
<div class="time">Nu</div>
|
|
<div class="icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/day/113.png" alt="Clear" width="40" />
|
|
</div>
|
|
<div class="temp">7.1 °C</div>
|
|
</div>
|
|
<div class="forecast-hour">
|
|
<div class="time">19:00</div>
|
|
<div class="icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/night/113.png" alt="Clear" width="40" />
|
|
</div>
|
|
<div class="temp">6.8 °C</div>
|
|
</div>
|
|
<div class="forecast-hour">
|
|
<div class="time">20:00</div>
|
|
<div class="icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/night/113.png" alt="Clear" width="40" />
|
|
</div>
|
|
<div class="temp">6.5 °C</div>
|
|
</div>
|
|
<div class="forecast-hour">
|
|
<div class="time">21:00</div>
|
|
<div class="icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/night/116.png" alt="Partly cloudy" width="40" />
|
|
</div>
|
|
<div class="temp">6.2 °C</div>
|
|
</div>
|
|
<div class="forecast-hour">
|
|
<div class="time">22:00</div>
|
|
<div class="icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/night/116.png" alt="Partly cloudy" width="40" />
|
|
</div>
|
|
<div class="temp">6.0 °C</div>
|
|
</div>
|
|
<div class="forecast-hour">
|
|
<div class="time">23:00</div>
|
|
<div class="icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/night/116.png" alt="Partly cloudy" width="40" />
|
|
</div>
|
|
<div class="temp">5.8 °C</div>
|
|
</div>
|
|
<div class="forecast-hour">
|
|
<div class="time">00:00</div>
|
|
<div class="icon">
|
|
<img src="https://cdn.weatherapi.com/weather/64x64/night/116.png" alt="Partly cloudy" width="40" />
|
|
</div>
|
|
<div class="temp">5.5 °C</div>
|
|
</div>
|
|
</div>
|
|
</div> <!-- End of custom-weather -->
|
|
</div> <!-- End of weather-container -->
|
|
</div> <!-- End of weather-section -->
|
|
|
|
<!-- News ticker (landscape only) -->
|
|
<div id="news-ticker"><div class="ticker-content"></div></div>
|
|
|
|
<!-- Daylight Hours Bar -->
|
|
<div id="daylight-hours-bar">
|
|
<div class="daylight-bar-background"></div>
|
|
<div class="daylight-bar-indicator">
|
|
<span class="sun-icon">☀️</span>
|
|
</div>
|
|
</div>
|
|
</div> <!-- End of content-wrapper -->
|
|
|
|
<!-- Last updated - positioned next to gear icon -->
|
|
<div class="last-updated" id="last-updated"></div>
|
|
|
|
<!-- Config Modal Template -->
|
|
<template id="config-modal-template">
|
|
<div class="config-modal-content">
|
|
<div class="config-modal-header">
|
|
<h2>Settings</h2>
|
|
<span class="config-modal-close" role="button" tabindex="0" aria-label="Close settings">×</span>
|
|
</div>
|
|
<div class="config-tabs">
|
|
<button class="config-tab active" data-tab="display">Display</button>
|
|
<button class="config-tab" data-tab="appearance">Appearance</button>
|
|
<button class="config-tab" data-tab="content">Content</button>
|
|
<button class="config-tab" data-tab="options">Options</button>
|
|
</div>
|
|
<div class="config-modal-body">
|
|
<!-- Display Tab -->
|
|
<div class="config-tab-content active" id="tab-display">
|
|
<div class="config-option">
|
|
<label for="orientation-select">Screen Orientation:</label>
|
|
<select id="orientation-select">
|
|
<option value="normal">Normal (0°)</option>
|
|
<option value="vertical">Vertical (90°)</option>
|
|
<option value="upsidedown">Upside Down (180°)</option>
|
|
<option value="vertical-reverse">Vertical Reverse (270°)</option>
|
|
<option value="landscape">Landscape (2-column)</option>
|
|
</select>
|
|
</div>
|
|
<div class="config-option">
|
|
<label for="dark-mode-select">Dark Mode:</label>
|
|
<select id="dark-mode-select">
|
|
<option value="auto">Automatic (Sunset/Sunrise)</option>
|
|
<option value="on">Always On</option>
|
|
<option value="off">Always Off</option>
|
|
</select>
|
|
<div class="sun-times" id="sun-times">
|
|
<small>Sunrise: <span id="sunrise-time">--:--</span> | Sunset: <span id="sunset-time">--:--</span></small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Appearance Tab -->
|
|
<div class="config-tab-content" id="tab-appearance">
|
|
<div class="config-option">
|
|
<label for="background-image-url">Background Image:</label>
|
|
<input type="text" id="background-image-url" placeholder="Enter image URL">
|
|
<div class="config-flex-row">
|
|
<button id="test-image-button" class="config-btn-sm">Use Test Image</button>
|
|
<label for="local-image-input" class="config-file-label">Select Local Image</label>
|
|
<input type="file" id="local-image-input" accept="image/*" class="config-file-input-hidden">
|
|
</div>
|
|
<div class="background-preview" id="background-preview">
|
|
<div class="no-image">No image selected</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-option">
|
|
<label for="background-opacity">Background Opacity: <span id="opacity-value">30%</span></label>
|
|
<input type="range" id="background-opacity" min="0" max="1" step="0.05" value="0.3">
|
|
</div>
|
|
</div>
|
|
<!-- Content Tab -->
|
|
<div class="config-tab-content" id="tab-content">
|
|
<div class="config-option">
|
|
<label>Transit Sites:</label>
|
|
<div style="margin-bottom: 15px;">
|
|
<div class="config-flex-row-mb">
|
|
<input type="text" id="site-search-input" placeholder="Search for transit stop..." class="config-search-input">
|
|
<button id="search-site-button">Search</button>
|
|
<button id="select-from-map-button">Select from Map</button>
|
|
</div>
|
|
<div id="site-search-results" class="config-search-results"></div>
|
|
</div>
|
|
<div id="sites-container"></div>
|
|
<div class="config-sites-add">
|
|
<button id="add-site-button" class="config-btn-sm">Add Site Manually</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Options Tab -->
|
|
<div class="config-tab-content" id="tab-options">
|
|
<div class="config-option">
|
|
<label for="combine-directions">
|
|
<input type="checkbox" id="combine-directions">
|
|
Combine departures going in the same direction
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-modal-footer">
|
|
<button id="config-save-button">Save</button>
|
|
<button id="config-cancel-button">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|