diff --git a/html/style.css b/html/style.css index d609b1b..db03474 100644 --- a/html/style.css +++ b/html/style.css @@ -1,445 +1,427 @@ +/* ─── Typeface ─────────────────────────────────────────────── */ @font-face { - font-family: FiraSans; - src: url("fonts/FiraSans-Medium.otf") format: ("opentype"); + font-family: FiraSans; + src: url("fonts/FiraSans-Light.otf") format("opentype"); } -* { - font-family: "FiraSans", sans-serif; - box-sizing: border-box; +/* ─── Design Tokens ─────────────────────────────────────────── */ +:root { + --bg: #101010; + --accent: #248bcc; + --text: #ffffff; + --muted: #888888; + + --glow-soft: 0 0 4px rgba(36,139,204,0.4), + 0 0 8px rgba(36,139,204,0.3), + 0 0 16px rgba(36,139,204,0.2); + --glow-mid: 0 0 4px rgba(36,139,204,0.7), + 0 0 8px rgba(36,139,204,0.6), + 0 0 16px rgba(36,139,204,0.5); + --text-glow: 0 0 2px #888, 0 0 4px #888, 0 0 8px #888; + --dark-glow: 0 0 2px #000, 0 0 4px #000, 0 0 8px #000; + + --r-lg: 25px; + --r-sm: 15px; + --r-xs: 9px; + + --footer-h: 4vh; } +/* ─── Reset ─────────────────────────────────────────────────── */ +*, *::before, *::after { + font-family: FiraSans, sans-serif; + box-sizing: border-box; + margin: 0; + padding: 0; +} + +/* ─── Page shell ────────────────────────────────────────────── */ +/* Two rows: content fills everything, footer claims fixed slice */ +html { height: 100%; } + body { - background-color: #101010; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-height: 100vh; - padding-bottom: 100px; - overflow-x: hidden; - overflow-y: hidden; -} - -/* Popup container */ -.popup { - position: relative; - display: inline-block; - cursor: pointer; -} - -/* Popup */ - -.popup h5 { - margin-top: 0px; - border: 1px solid #248bcc; - border-radius: 25px; - font-size: 15px; - color: white; - position: relative; - padding-left: 7px; - padding-right: 7px; - box-shadow: 0 0 4px rgba(36,139,204,0.4), 0 0 8px rgba(36,139,204,0.3), 0 0 16px rgba(36,139,204,0.2); - text-shadow: 0 0 2px #888, 0 0 4px #888, 0 0 8px #888; -} - -.popup h5:hover { - background-color: #248bcc; - box-shadow: 0 0 4px rgba(36,139,204,0.7), 0 0 8px rgba(36,139,204,0.6), 0 0 16px rgba(36,139,204,0.5); - text-shadow: 0 0 2px #fff, 0 0 4px #fff, 0 0 8px #fff; -} - -.popup { - display: block; - position: relative; - margin: auto; - text-align: center; -} - -.popup .popuptext { - background-color: #101010; - position: absolute; - z-index: 512; - visibility: hidden; - width: 100%; - color: #fff; - text-align: left; - top: 100%; - left: 50%; - margin-left: -50%; - border: 1px solid #248bcc; - border-radius: 25px; -} - -.popup .popuptext p { - color: white; - font-size: 15px; - margin: 0; -} - -.popup .popuptext .emo { - margin-top: 15px; - text-align: center; -} -.popup .popuptext .emo a { - padding-left: 15px; - padding-right: 15px; - font-size: 69px; - text-decoration: none; -} - -.popup .popuptext .text { - padding-left: 25px; -} - -.popup .popuptext .text p { - margin-bottom: 25px; - margin-top: 25px; -} - -.popup .popuptext .sources { - padding-left: 25px; -} -.popup .popuptext .sources a { - color: #248bcc; - padding-top: 0px; - margin-top: 0px; -} - -/* Hide and show the popup */ -.popup .show { - position: absolute; - z-index: 512; - visibility: visible; + background-color: var(--bg); + color: var(--text); + height: 100%; + height: 100vh; + height: 100dvh; + display: grid; + grid-template-rows: 1fr var(--footer-h); + overflow: hidden; + font-size: 16px; + align-content: start; } +/* ─── .main ─────────────────────────────────────────────────── */ +/* + * HTML structure inside .main: + * .conditions + * p.header > img.logo + * .popup (info button + popuptext) + * .current + * .cat × 4 + * .video > img + * + * PORTRAIT (default): .conditions on top, .video below + * LANDSCAPE: .conditions as left sidebar, .video fills right + */ .main { - border: 1px solid; - border-color: #248bcc; - border-radius: 25px 0 0 25px; - float: left; - width: 100%; - box-shadow: 0 0 4px rgba(36,139,204,0.4), 0 0 8px rgba(36,139,204,0.3), 0 0 16px rgba(36,139,204,0.2); -} - -.header { - display: block; - font-size: 13px; -} - -.logo { - margin-top: 7px; - width: 100%; - align: center; + display: grid; + grid-template-rows: auto 1fr; + grid-template-columns: 1fr; + grid-template-areas: + "conditions" + "video"; + min-height: 0; + overflow: hidden; + border: 1px solid var(--accent); + border-radius: var(--r-lg) var(--r-lg) 0 0; + box-shadow: var(--glow-soft); + max-height: calc(100dvh - var(--footer-h)); + overflow: hidden; } +/* ─── .conditions ───────────────────────────────────────────── */ +/* + * 3-column grid: + * col 1 (auto) — logo + popup button stacked + * col 2 (1fr) — current conditions, then cat 1 & 3 + * col 3 (1fr) — current conditions, then cat 2 & 4 + * + * Explicit placement: + * p.header → col 1 / row 1 + * .popup → col 1 / row 2 + * .current → col 2–3 / row 1–2 (spans all of right, same height as logo+popup) + * cat 1 → col 2 / auto row + * cat 2 → col 3 / auto row + * cat 3 → col 2 / auto row + * cat 4 → col 3 / auto row + * → produces a clean 2 × 2 data grid below the header band + */ .conditions { - padding-left: 20px; - padding-right: 20px; - width: 20%; - text-align: left; - overflow: hidden; - float: left; - color: grey; + grid-area: conditions; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1vh; + padding: 8px; + align-items: start; + overflow: hidden; } +p.header { margin-bottom: 1dvh; } +.popup { margin-bottom: 1dvh; } +.current { margin-bottom: 1dvh; } +.conditions { margin-bottom: 1dvh; } + +/* Logo wrapper
*/ +p.header { + grid-column: 1 / -1; + grid-row: 1; + display: flex; + align-items: center; + justify-content: center; +} + +img.logo { + max-height: 100px; + max-width: 100%; + width: auto; + display: block; + object-fit: contain; +} + +/* Info popup — sits below logo in col 1 */ +.popup { + grid-column: 1 / -1; + grid-row: 2; + display: block; + position: relative; + text-align: center; + cursor: pointer; + align-self: start; +} + +/* Current conditions — spans right two cols, rows 1–2 */ .current { - padding-bottom: 5px; - padding-top: 5px; - color: #101010; - text-align: center; - border: 1px solid #248bcc; - border-radius: 15px; - background-color: #101010; - background: linear-gradient(to top, rgba(10,10,10,0), rgba(36,139,204,1)); - box-shadow: 0 0 4px rgba(36,139,204,0.4), 0 0 8px rgba(36,139,204,0.3), 0 0 16px rgba(36,139,204,0.2); + grid-column: 1 / -1; + grid-row: 3; + align-self: stretch; + padding: 1vh 10px; + text-align: center; + border: 1px solid var(--accent); + border-radius: var(--r-sm); + background: linear-gradient(to top, rgba(10,10,10,0), var(--accent)); + box-shadow: var(--glow-soft); + display: flex; + flex-direction: column; + justify-content: center; + gap: 1vh; } -.current .update { - padding: 0px; - margin: 0px; - font-weight: normal; - color: white; - font-size: 15px; - text-shadow: 0 0 2px #000, 0 0 4px #000, 0 0 8px #000; -} - -.current .wttr { - margin: 0; - color: #fff; - font-size: 25px; - font-weight: bold; - text-shadow: 0 0 2px #000, 0 0 4px #000, 0 0 8px #000; -} - -.current .danger { - margin: 0; - text-align: center; - color: white; - font-size: 15px; - text-shadow: 0 0 2px #000, 0 0 4px #000, 0 0 8px #000; -} - -.current .level { - font-size: 25px; - font-weight: bold; - margin: 0px; -} - -.danger p { - color: #101010; - font-weight: normal; - margin: 0; - font-weight: none; - color: white; - font-size: 15px; -} +.current .update { font-size: 1rem; font-weight: normal; text-shadow: var(--dark-glow); } +.current .wttr { font-size: 1.5rem; font-weight: bold; text-shadow: var(--dark-glow); } +.current .danger { font-size: 1rem; font-weight: normal; text-shadow: var(--dark-glow); } +.current .level { font-size: 1.5rem; font-weight: bold; } +.danger p { font-size: 1rem; font-weight: normal; } +/* 4 data cats — auto-placed into cols 2 & 3, 2 per row → 2×2 grid */ .cat { - font-size: 15px; - position: relative; + position: relative; + overflow: hidden; + min-width: 0; } +.cat:nth-child(4) { grid-column: 1; } +.cat:nth-child(5) { grid-column: 2; } +.cat:nth-child(6) { grid-column: 1; } +.cat:nth-child(7) { grid-column: 2; } + +.cat p { padding-left: 24px; } + +/* Data value row */ .data { - margin-top: 5px; - font-weight: bold; - font-size: 25px; - padding-bottom: 5px; - padding-top: 5px; - color: white; - border-bottom: 1px solid #248bcc; - border-left: 1px solid #248bcc; - border-radius: 25px 0px 25px 25px; + margin-top: 5px; + font-weight: bold; + padding: 5px 0; + color: var(--text); + border-bottom: 1px solid var(--accent); + border-left: 1px solid var(--accent); + border-radius: var(--r-lg) 0 var(--r-lg) var(--r-lg); + position: relative; + overflow: hidden; } .data.plot { - text-shadow: 0 0 2px #248bcc, 0 0 4px #248bcc, 0 0 8px #248bcc; + text-shadow: 0 0 2px var(--accent), + 0 0 4px var(--accent), + 0 0 8px var(--accent); } .data::before { - content: ""; - position: absolute; - top: 0; left: 0; right: 0; bottom: 0; - border-bottom: 1px solid #248bcc; - border-radius: 25px 0 25px 25px; - filter: drop-shadow(0 0 2px #248bcc) - drop-shadow(0 0 4px #248bcc) - drop-shadow(0 0 8px #248bcc); - pointer-events: none; - z-index: -1; -} - -.plot { - background-repeat: no-repeat; - background-size: 102% 100%; - background-position: -2px 0px; - background-image: - linear-gradient(to right, rgba(0,0,0,0) 0%, #101010 39%); - linear-gradient(rgba(0,0,0,0), rgba(0,0,0,0)); -} - - -.cat p { - padding-left: 24px; + content: ""; + position: absolute; + inset: 0; + border-bottom: 1px solid var(--accent); + border-radius: var(--r-lg) 0 var(--r-lg) var(--r-lg); + filter: drop-shadow(0 0 2px var(--accent)) + drop-shadow(0 0 4px var(--accent)) + drop-shadow(0 0 8px var(--accent)); + pointer-events: none; + z-index: -1; } +/* Datapoint label */ .datapoint { - padding-top: 10px; - padding-bottom: 0; - padding-left: 10px; - margin-top: 30px; - margin-bottom: 0; - text-shadow: 0 0 2px #000, 0 0 4px #000, 0 0 8px #888; + padding: 10px 0 0 10px; + text-shadow: var(--dark-glow); + color: #888; } +/* Background sparkline */ +.plot { + background-repeat: no-repeat; + background-size: 102% 100%; + background-position: -2px 0; +} +/* ─── Popup widget ──────────────────────────────────────────── */ +.popup h5 { + border: 1px solid var(--accent); + border-radius: var(--r-lg); + font-size: 1rem; + color: var(--text); + padding: 0 9px; + box-shadow: var(--glow-soft); + text-shadow: var(--text-glow); + cursor: pointer; + display: inline-block; +} + +.popup h5:hover { + background-color: var(--accent); + box-shadow: var(--glow-mid); + text-shadow: 0 0 2px #fff, 0 0 4px #fff, 0 0 8px #fff; +} + +.popup .popuptext { + background-color: var(--bg); + position: absolute; + z-index: 512; + visibility: hidden; + width: 200px; /* fixed width so it doesn't collapse */ + color: var(--text); + text-align: left; + top: 100%; + left: 0; + border: 1px solid var(--accent); + border-radius: var(--r-sm); +} + +.popup .show { + visibility: visible; +} + +.popup .popuptext p { font-size: 1rem; } +.popup .popuptext .emo { margin-top: 1rem; text-align: center; } +.popup .popuptext .emo a { padding: 0 12px; font-size: 3rem; text-decoration: none; } +.popup .popuptext .text { padding-left: 20px; } +.popup .popuptext .text p { margin: 20px 0; } +.popup .popuptext .sources { padding-left: 20px; } +.popup .popuptext .sources p { padding-top: 4px; } +.popup .popuptext .sources a { color: var(--accent); font-size: 1rem; } + +/* ─── Video panel ───────────────────────────────────────────── */ .video { - position: relative; - z-index: -1; + grid-area: video; + height: 100%; + overflow: hidden; + min-height: 0; + position: relative; + z-index: 0; + min-height: 0; + overflow: hidden; } .video img { - width: 80%; - max-height: inherit; - max-width: inherit; - padding-top: 5px; - padding-right: 5px; + width: 100%; + height: 100%; + object-fit: contain; + display: block; + padding: 4px; + max-height: 100%; } +/* ─── Footer ────────────────────────────────────────────────── */ .footer { - flex-shrink: 0; - bottom: 0; - width: 100%; - text-align: center; + height: var(--footer-h); + width: 100%; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + grid-row: -1; + align-self: end; } -.footer p { - font-size: 13px; - color: #FFFFFF; +.footer p, .footer a { + font-size: 0.75rem; + color: var(--text); + text-decoration: none; +} +.footer a:hover { text-decoration: underline; } + + +/* ════════════════════════════════════════════════════════════════ + LANDSCAPE + Switch .main to two columns: sidebar | video + Switch .conditions to a single-column stacked list + ════════════════════════════════════════════════════════════════ */ +@media (orientation: landscape) { + body { + grid-template-rows: 1fr var(--footer-h); /* ← restore stretch in landscape */ + } + + .main { + grid-template-rows: 1fr; + grid-template-columns: minmax(180px, 1fr) auto; /* ← back to 2 columns */ + grid-template-areas: "conditions video"; + border-radius: var(--r-lg) 0 0 var(--r-lg); + justify-content: center; + } + + /* Single column — everything stacks top-to-bottom */ + .conditions { + grid-template-columns: 1fr; + grid-template-rows: auto auto auto repeat(4, auto); + overflow-y: auto; + overflow-x: hidden; + padding: 8px 6px; + gap: 1vh; + align-content: center; + justify-items: center; + max-width: 420px; + width: 100%; + margin: 0 auto; + } + + .current { + width: 100%; + } + + .cat { + width: 100%; + } + + .video { + display: block; + align-items: unset; + justify-content: unset; + height: 100%; + width: 100%; + aspect-ratio: 16 / 9; + } + + .video img { + width: 100%; + height: 100%; + object-fit: contain; + display: block; + } + + p.header { grid-column: 1; grid-row: 1; } + .popup { grid-column: 1; grid-row: 2; } + .current { grid-column: 1; grid-row: 3; } + + .cat:nth-child(4) { grid-column: 1; grid-row: 4; } + .cat:nth-child(5) { grid-column: 1; grid-row: 5; } + .cat:nth-child(6) { grid-column: 1; grid-row: 6; } + .cat:nth-child(7) { grid-column: 1; grid-row: 7; } + + img.logo { max-height: 70px; } + + .current .update { font-size: 1rem; } + .current .wttr { font-size: 1.5rem; } + .current .danger { font-size: 1rem; } + .current .level { font-size: 1rem; } + .danger p { font-size: 1rem; } + + .cat { font-size: 1rem; } + .cat p { padding-left: 14px; } + .data { font-size: 1.5rem; margin-top: 2px; padding: 2px 0; } + .datapoint { margin-top: 14px; padding: 5px 0 0 8px; font-size: 0.75rem; } + + .popup h5 { font-size: 1rem; } } -.footer a { - font-size: 13px; - color: #FFFFFF; - text-decoration: none; -} -.footer a:hover { - text-decoration: underline; -} +/* ════════════════════════════════════════════════════════════════ + PORTRAIT — small screens (narrow phones) + Tighten up spacing and font sizes + ════════════════════════════════════════════════════════════════ */ +@media (orientation: portrait) { -@media only screen and (max-width: 1100px) { - .popup .show { - position: absolute; - z-index: 512; - visibility: visible; - } - .main { - margin: 0; - padding: 0; - border-radius: 25px 25px 0px 0px; - } - .conditions, .video { - width: 100%; - } - .conditons { - font-size: 13px; - width: 100%; - } - .conditions .cat { - width: 50%; - display: inline; - float: left; - overflow: hidden; - padding-left: 5%; - padding-right: 5%; - } - .header { - margin-bottom: 0px; - margin-top: 5px; - } - .header img { - margin-top: 10px; - } - .logo { - max-height: 75px; - object-fit: contain; - } + .main { border-radius: var(--r-sm); } -.popup .popuptext { - top: 0%; - left: 50%; - margin-top: -15%; - margin-left: -50%; - border-radius: 15px; -} + img.logo { max-height: 56px; } -.popup .popuptext p { - font-size: 10px; - margin: 0; - padding: 0; -} + .current { border-radius: var(--r-xs); } + .current .update { font-size: 0.75rem; } + .current .wttr { font-size: 1.25rem; } + .current .danger { font-size: 0.75rem; } + .current .level { font-size: 1rem; } + .danger p { font-size: 0.75rem; } -.popup .popuptext .emo { - margin-top: 5px; - text-align: center; -} -.popup .popuptext .emo a { - padding-left: 15px; - padding-right: 15px; - font-size: 36px; -} + .cat { font-size: 0.75rem; } + .cat p { padding-left: 12px; } + .data { font-size: 1.25rem; margin-top: 0; padding: 2px 0; } + .datapoint { margin-top: 10px; padding: 4px 0 0 8px; font-size: 0.75rem; } -.popup .popuptext .text { - margin: 0; - padding: 0; - padding-left: 15px; -} + .popup h5 { padding: 0 6px; font-size: 0.75rem; } -.popup .popuptext .text p { - margin: 0; - padding: 0; - padding-bottom: 10px; - padding-top: 10px; + .popup .popuptext { font-size: 0.75rem; width: 180px; } + .popup .popuptext .emo a { font-size: 3rem; } + .popup .popuptext .text { padding-left: 10px; } + .popup .popuptext .text p { margin: 12px 0; } + .popup .popuptext .sources { padding-left: 10px; } + .popup .popuptext .sources a { font-size: 0.75px; } } - -.popup .popuptext .sources { - padding-left: 15px; -} -.popup .popuptext .sources p { - margin: 0; - padding: 0; - padding-top: 5px; -} -.popup .popuptext .sources a { - margin-top: 0; - padding-top: 0px; - font-size: 10px; -} - - .popup h5 { - margin-bottom: 5px; - margin-top: 0px; - } - .current { - border-radius: 9px; - } - .current .update { - padding: 0; - margin: 0; - font-size: 10px; - } - .current .wttr { - margin: 0; - padding: 0; - font-size: 15px; - } - .current .danger { - padding: 0; - margin: 0; - font-size: 10px; - } - .current .level { - padding: 0; - margin: 0; - font-size: 13px; - } - .danger p { - padding: 0; - margin: 0; - color: white; - font-size: 10px; - } - .cat p { - margin: 0; - padding-left: 12px; - } - .data { - margin-top: 0; - margin-bottom: 0; - padding-top: 0; - padding-bottom: 0px; - font-size: 13px; - position: relative; - } - .data::before { - content: ""; - position: absolute; - top: 0; left: 0; right: 0; bottom: 0; - border-bottom: 1px solid #248bcc; - border-radius: 25px 0 25px 25px; - filter: drop-shadow(0 0 2px #248bcc) - drop-shadow(0 0 4px #248bcc) - drop-shadow(0 0 8px #248bcc); - pointer-events: none; - z-index: -1; - } - .datapoint { - margin: 0; - padding-bottom: 0px; - font-size: 10px; - } - .video img { - margin-top: 15px; - width: 100%; - padding-left: 5px; - } diff --git a/index.sh b/index.sh index 8ba4a08..6b49f27 100755 --- a/index.sh +++ b/index.sh @@ -176,6 +176,12 @@ echo -e " var popup = document.getElementById(\"infopop\"); popup.classList.toggle(\"show\"); } + document.addEventListener(\"click\", function(e) { + var popup = document.getElementById(\"infopop\"); + if (!e.target.closest(\".popup\")) { + popup.classList.remove(\"show\"); + } + });