<!DOCTYPE html>

<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700;900&family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="icon" href="./cassie.ico">

    <title>Eureka Blizzard Weather</title>
    <style>
        :root{
            --bg: #DDEFD3;
            --panel: #F4FBF1;
            --panel-alt: #DCEFD3;
            --line: #B5D7A6;
            --text: #1f2e1c;
            --text-dim: #4a6544;
            --text-faint: #7d977a;
            --ice: #0284c7;
            --ice-deep: #0369a1;
            --ember: #c2410c;
            --violet: #7e22ce;
            --fog: #4d6a5a;
            --alert: #dc2626;
            --alert-deep: #b91c1c;
            --paper: #F7FCF4;
            --paper-shadow: #CFE5C4;
            --ink: #232320;
            --ink-soft: #5B5A52;
            --stamp: #B8402E;
            --stamp-soft: #E7CFC8;
            --r-sm: 4px;
            --r-md: 6px;
            --r-lg: 8px;
            --f-display: "Orbitron", sans-serif;
            --f-body: "Space Grotesk", "Hiragino Kaku Gothic ProN", sans-serif;
            --f-mono: "Yu Gothic UI", "IBM Plex Mono", "Courier New", monospace;
        }

        body {
            font-family: var(--f-body);
            background: radial-gradient(circle at 18% -10%, #F3FAEE 0%, var(--bg) 45%) fixed;
            color: var(--text);
            margin: 0;
            padding: 6px 8px 16px; /* 余白を最小化 */
            font-size: 13px;
            line-height: 1.25; /* 行間を小さく */
            -webkit-font-smoothing: antialiased;
        }

        .meteor-logo {
            font-family: var(--f-display);
            font-weight: 900;
            font-size: 17px; /* スペース最適化: 20pxから17pxにコンパクト化 */
            letter-spacing: 0.5px;
            background: linear-gradient(180deg, #aee6ff 0%, var(--ice) 45%, var(--ice-deep) 100%);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            text-shadow: 0 1px 6px rgba(47, 143, 192, 0.35);
            flex-shrink: 0;
            white-space: nowrap;
        }

        button { padding: 0 6px; border: 1px solid var(--line); border-radius: 999px; font-size: 10px; cursor: pointer; background: var(--panel-alt); color: var(--text-dim); height: 18px; line-height: 16px; flex-shrink: 0; font-weight: 600; font-family: var(--f-body); transition: background .15s ease, color .15s ease, border-color .15s ease, transform .1s ease; }
        button:hover { color: var(--text); border-color: var(--ice-deep); background: #C9E5BA; }
        button:active { transform: scale(.96); }
        button:disabled { opacity: 0.4; cursor: default; transform: none; }
        button:focus-visible { outline: 2px solid var(--ice); outline-offset: 1px; }

        .container { width: 100%; max-width: 1100px; margin: 10px auto 0; box-sizing: border-box; }
        .controls { background: var(--panel); padding: 5px 6px; margin-bottom: 6px; border-radius: var(--r-lg); border: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 4px; }
        .checkbox-group { display: flex; flex-wrap: wrap; gap: 4px 6px; }
        .checkbox-group .zone-toggle-title { display: flex; align-items: center; font-size: 12px; white-space: nowrap; color: var(--text-dim); font-weight: 600; }
        .checkbox-group label { display: flex; align-items: center; gap: 2px; font-size: 12px; cursor: pointer; white-space: nowrap; color: var(--text-dim); font-weight: 600; }
        .checkbox-group input[type="checkbox"] { appearance: none; -webkit-appearance: none; width: 13px; height: 13px; border-radius: 3px; border: 1px solid var(--line); background: var(--panel-alt); position: relative; cursor: pointer; margin: 0; }
        .checkbox-group input[type="checkbox"]:checked { background: #2f8f3e; border-color: #1f6f2d; }
        .checkbox-group input[type="checkbox"]:checked::before { content: ""; position: absolute; inset: 2px; background: #fff; border-radius: 1px; }
        .info { font-size: 11px; color: var(--text-dim); text-align: right; font-family: var(--f-mono); }

        /* 天気テーブルの並びと余白調整 */
        .weather-tables-wrapper { display: flex; flex-wrap: nowrap; gap: 8px; width: 100%; }
        .weather-table-container { flex: 1; min-width: 0; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
        /* 天気セルのマウスオーバー表示(新鋭など) */
        #weather-tip {
            position: fixed; z-index: 900; display: none; pointer-events: none; white-space: nowrap;
            background: var(--panel); border: 2px solid var(--text); border-radius: var(--r-md);
            padding: 1px 10px; font-size: 15.4px; font-weight: bold; line-height: 1.3; /* 天気の文字(11px)のマウスオーバー時サイズ(140%)に合わせる */ color: var(--text);
            box-shadow: 0 8px 20px -8px rgba(0,0,0,0.55);
        }
        /* ヒュダトス・アネモスはピューロス・パゴスの半分の幅 */
        #container-hydatos, #container-anemos { flex: 0.5 1 0%; }
        /* 4ゾーンを常に横並び。狭い画面では文字を小さくして収める */
        @media screen and (max-width: 1000px) {
            .weather-tables-wrapper { gap: 3px; flex-wrap: nowrap; }
            .weather-tables-wrapper th { font-size: 8px; letter-spacing: 0; padding: 3px 0; }
            .weather-tables-wrapper .zone-header { font-size: 9px; letter-spacing: 0; padding: 3px 1px; }
            .weather-tables-wrapper td { padding: 4px 0; }
            .weather-tables-wrapper .time-text { font-size: 7.5px; white-space: normal; line-height: 1.15; }
            .weather-tables-wrapper .weather-text { font-size: 9px; white-space: normal; }
            #container-hydatos th, #container-anemos th { word-break: normal; }
            #weather-tip { font-size: 12.6px; } /* 狭い画面の天気の文字(9px)×140% */
        }

        table {
            border-collapse: collapse;
            width: 100%;
            background: var(--panel);
            font-size: 12px;
            table-layout: fixed;
        }

        th, td {
            border: 1px solid var(--line);
            padding: 4px 2px; /* 天気セルの行間(上下パディング)を拡大 */
            text-align: center;
            word-break: break-all;
        }
        th { 
            background: var(--panel-alt); 
            font-weight: 600; 
            color: var(--text-dim); 
            font-family: var(--f-mono); 
            font-size: 11px; 
            letter-spacing: .04em; 
        }
        .zone-header { background: linear-gradient(135deg, #B9E0A0, #8FCB72); color: var(--text); font-size: 12px; padding: 4px 4px; font-family: var(--f-display); letter-spacing: 1px; font-weight: 700; }

	.cell-blizzard { background-color: #e0f2fe !important; }
        .cell-gales-night { background-color: #a9dd8c !important; } /* アネモス暴風 ET16:00 / ET00:00 */
        .cell-fog { background-color: #d1d5db !important; }
        .cell-heatwaves { background-color: rgba(255, 154, 90, 0.14) !important; }
        .cell-thunder { background-color: rgba(185, 138, 240, 0.14) !important; }

        .current-cell { background-color: rgba(255, 107, 94, 0.18) !important; border: 1px solid var(--alert) !important; box-shadow: inset 0 0 0 1px var(--alert); font-weight: bold; }

        .weather-blizzard { color: var(--ice); font-weight: bold; }
        .weather-heatwaves { color: var(--ember); font-weight: bold; }
        .weather-thunder { color: var(--violet); font-weight: bold; }
        .weather-fog { color: var(--fog); font-weight: bold; }
        .weather-text.weather-hydatos-thunder { /* ヒュダトス暴雨・雷雨:水色+黒縁取り */
            color: #0ea5e9; font-weight: bold;
            text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000,
                         0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000, 1px 0 0 #000;
            transition: transform .1s ease;
        }
        .weather-tables-wrapper .weather-text { transition: transform .1s ease; }
        .weather-tables-wrapper td:hover .weather-text { transform: scale(1.4); font-weight: bold; } /* 全ゾーン:セルのマウスオーバーで天候の文字を140%・太字 */
        .weather-text.weather-hydatos-gloom { /* ヒュダトス妖霧:紫+黒縁取り */
            color: #a855f7; font-weight: bold;
            text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000,
                         0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000, 1px 0 0 #000;
        }
        .weather-text.weather-hydatos-snow { /* ヒュダトス雪:白文字+黒縁取り */
            color: #fff; font-weight: bold;
            text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000,
                         0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000, 1px 0 0 #000;
        }
        .time-text { display: block; font-size: 9.5px; color: #000000; margin-bottom: 2px; white-space: nowrap; font-family: var(--f-mono); line-height: 1.3; font-weight: 600; } /* 日時を黒色に変更し行間と余白を調整 */
        .weather-text { display: block; font-size: 11px; line-height: 1.25; white-space: nowrap; color: var(--text-dim); }


        .weather-tables-wrapper tbody td {
            cursor: pointer;
            touch-action: manipulation;
            -webkit-tap-highlight-color: rgba(125, 211, 252, 0.15);
            user-select: none;
            transition: filter .1s ease;
        }
        .weather-tables-wrapper tbody td:hover { filter: brightness(0.95); }
        .weather-tables-wrapper tbody td:active { filter: brightness(0.88); }

        .popup-overlay {
            position: fixed;
            top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(6,9,14,0.72);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
        }
        .popup-overlay.hidden { display: none; }
        .popup-box {
            background: var(--panel);
            border: 1px solid var(--line);
            border-radius: var(--r-lg);
            padding: 12px 14px;
            width: 90%;
            max-width: 500px;
            max-height: 80vh;
            overflow-y: auto;
            overflow-x: auto;
            box-shadow: 0 24px 60px -20px rgba(0,0,0,0.7);
            color: var(--text);
        }
        .popup-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 6px;
            font-weight: bold;
            font-size: 14px;
            font-family: var(--f-display);
            letter-spacing: .03em;
        }
        .popup-header button {
            height: 24px;
            min-width: 28px;
            font-size: 14px;
            line-height: 22px;
            padding: 0 6px;
            touch-action: manipulation;
            border-radius: var(--r-sm);
        }

        .popup-table { width: 100%; border-collapse: collapse; font-size: 11px; }
        .popup-table th, .popup-table td { border: 1px solid var(--line); padding: 4px 6px; text-align: center; white-space: nowrap; color: var(--text-dim); }
        .popup-table th { background: var(--panel-alt); color: var(--text); font-family: var(--f-mono); }

        .hidden { display: none !important; }

        .info-box { display: inline-block; box-sizing: border-box; text-align: center; font-variant-numeric: tabular-nums; flex-shrink: 0; padding: 2px 6px; background: var(--panel); border: 1px solid #2f8f3e; border-radius: var(--r-md); color: var(--text); font-weight: 600; white-space: nowrap; }
        .site-title { margin: 0 0 6px; }
    </style>
</head>
<body>

<div class="container">
 <div class="site-title"><span class="meteor-logo">Eureka Blizzard Weather</span></div>
 <div class="controls">
  <div class="checkbox-group">
   <span class="zone-toggle-title">天気表示</span>
   <label><input type="checkbox" id="chk-hydatos" onchange="toggleZoneColumns()"> ヒュダトス</label>
   <label><input type="checkbox" id="chk-pyros" checked="" onchange="toggleZoneColumns()"> ピューロス</label>
   <label><input type="checkbox" id="chk-pagos" checked="" onchange="toggleZoneColumns()"> パゴス</label>
   <label><input type="checkbox" id="chk-anemos" onchange="toggleZoneColumns()"> アネモス</label>
  </div>
  <div class="info" style="display: flex; align-items: center; gap: 4px;">
   <span class="info-box" style="width: 10.5em;">天気更新 <span id="countdown">--:--</span></span>
   <span class="info-box" id="et-clock" style="width: 7em;">ET --:--</span>
  </div>
 </div>
 
 <div class="weather-tables-wrapper">
  <div class="weather-table-container hidden" id="container-hydatos">
   <table>
    <thead>
     <tr><th colspan="3" class="zone-header">ヒュダトス帯</th></tr>
     <tr><th>ET 00:00</th><th>ET 08:00</th><th>ET 16:00</th></tr>
    </thead>
    <tbody id="weather-tbody-hydatos"></tbody>
   </table>
  </div>

  <div class="weather-table-container" id="container-pyros">
   <table>
    <thead>
     <tr><th colspan="3" class="zone-header">ピューロス帯</th></tr>
     <tr><th>ET 00:00</th><th>ET 08:00</th><th>ET 16:00</th></tr>
    </thead>
    <tbody id="weather-tbody-pyros"></tbody>
   </table>
  </div>

  <div class="weather-table-container" id="container-pagos">
   <table>
    <thead>
     <tr><th colspan="3" class="zone-header">パゴス帯</th></tr>
     <tr><th>ET 00:00</th><th>ET 08:00</th><th>ET 16:00</th></tr>
    </thead>
    <tbody id="weather-tbody-pagos"></tbody>
   </table>
  </div>

  <div class="weather-table-container hidden" id="container-anemos">
   <table>
    <thead>
     <tr><th colspan="3" class="zone-header">アネモス帯</th></tr>
     <tr><th>ET 00:00</th><th>ET 08:00</th><th>ET 16:00</th></tr>
    </thead>
    <tbody id="weather-tbody-anemos"></tbody>
   </table>
  </div>
 </div>
</div>

<!-- 天気セルクリック用ポップアップ -->
<div id="weather-popup-overlay" class="popup-overlay hidden">
  <div class="popup-box">
    <div class="popup-header">
      <span id="popup-title"></span>
      <button id="popup-close">×</button>
    </div>
    <table class="popup-table">
      <thead><tr><th>天候</th><th>日付</th><th>時間</th><th>ET</th><th>今から</th></tr></thead>
      <tbody id="popup-tbody"></tbody>
    </table>
  </div>
</div>

<script>
const PAGOS_RATES = [
    { max: 9, name: "晴れ" },
    { max: 27, name: "霧", class: "weather-fog", cellClass: "cell-fog", tooltip: "キングアースロ" },
    { max: 45, name: "灼熱波" },
    { max: 63, name: "雪" },
    { max: 81, name: "雷" },
    { max: 99, name: "吹雪", class: "weather-blizzard", cellClass: "cell-blizzard", tooltip: "キャシー" }
];

const PYROS_RATES = [
    { max: 9, name: "晴れ" },
    { max: 27, name: "灼熱波" },
    { max: 45, name: "雷" },
    { max: 63, name: "吹雪", class: "weather-blizzard", cellClass: "cell-blizzard", tooltip: "スコル" },
    { max: 81, name: "霊風" },
    { max: 99, name: "雪" }
];

// ヒュダトス:晴れ12% / 暴雨22% / 妖霧22% / 雷雨22% / 雪22%
const HYDATOS_RATES = [
    { max: 11, name: "晴れ" },
    { max: 33, name: "暴雨", class: "weather-hydatos-thunder", tooltip: "リフレク狩り:新鋭" },
    { max: 55, name: "妖霧", class: "weather-hydatos-gloom", tooltip: "リフレク狩り:熟練" },
    { max: 77, name: "雷雨", class: "weather-hydatos-thunder", tooltip: "リフレク狩り:新鋭" },
    { max: 99, name: "雪", class: "weather-hydatos-snow", tooltip: "攻勢" }
];

// アネモス:晴れ30% / 暴風30% / 暴雨30% / 雪10%
const ANEMOS_RATES = [
    { max: 29, name: "晴れ" },
    { max: 59, name: "暴風", nightCellClass: "cell-gales-night", nightTooltip: "パズズ" },
    { max: 89, name: "暴雨" },
    { max: 99, name: "雪" }
];

// 表示順(左→右)。key は chk-◯◯ / container-◯◯ / weather-tbody-◯◯ のID用
const WEATHER_ZONES = [
    { key: "hydatos", rates: HYDATOS_RATES, showDate: false },
    { key: "pyros",   rates: PYROS_RATES, showDate: true },
    { key: "pagos",   rates: PAGOS_RATES, showDate: true },
    { key: "anemos",  rates: ANEMOS_RATES, showDate: false }
];

function getEorzeaInterval(ms) {
 const eoMs = ms * (1440 / 70);
 return Math.floor(eoMs / (8 * 60 * 60 * 1000));
}

function getJstTimeFromInterval(interval) {
 const eoMs = interval * 8 * 60 * 60 * 1000;
 return Math.round(eoMs / (1440 / 70));
}

function calculateWeather(interval, rates) {
 const baseMs = getJstTimeFromInterval(interval);
 const totalDays = Math.floor(baseMs / 4200000);
 const dayInterval = (interval % 3 + 3) % 3;
 const hour = dayInterval === 0 ? 0 : (dayInterval === 1 ? 8 : 16);
 const x = (totalDays * 100) + ((hour + 8 - (hour % 8)) % 24);
 let r0 = ((x << 11) ^ x) | 0;
 let r1 = ((r0 >>> 8) ^ r0) | 0;
 let seed = (r1 % 100 + 100) % 100;
 return rates.find(w => seed <= w.max) || { name: "不明", class: "", cellClass: "" };
}

let cachedCurrentInterval = null;

function buildWeatherCell(targetInterval, currentInterval, rates, showDate) {
 const jstMs = getJstTimeFromInterval(targetInterval);
 const weather = calculateWeather(targetInterval, rates);
 const date = new Date(jstMs);
 const mm = String(date.getMonth() + 1).padStart(2, '0');
 const dd = String(date.getDate()).padStart(2, '0');
 const hh = String(date.getHours()).padStart(2, '0');
 const min = String(date.getMinutes()).padStart(2, '0');

 const td = document.createElement("td");
 if (weather.cellClass) td.className = weather.cellClass;
 // ET 00:00 / ET 16:00 の列のみ背景色を付ける天候(アネモス暴風)
 if (weather.nightCellClass && (((targetInterval % 3) + 3) % 3) !== 1) td.classList.add(weather.nightCellClass);
 if (targetInterval === currentInterval) td.classList.add("current-cell");
 if (weather.tooltip) td.dataset.tip = weather.tooltip; // マウスオーバー表示(専用ツールチップ)
 // ET 00:00 / ET 16:00 の列のみ表示するツールチップ(アネモス暴風)
 if (weather.nightTooltip && (((targetInterval % 3) + 3) % 3) !== 1) td.dataset.tip = weather.nightTooltip;
 td.innerHTML = `<span class="time-text">${showDate ? `${mm}/${dd} ` : ""}${hh}:${min}</span><span class="weather-text ${weather.class || ''}">${weather.name}</span>`;
 td.addEventListener("click", () => showWeatherPopup(weather.name, rates));
 return td;
}

function updateWeatherTable() {
 const now = Date.now();
 const currentInterval = getEorzeaInterval(now);
 const currentMod = (currentInterval % 3 + 3) % 3;
 const baseInterval = currentInterval - currentMod;
 
 if (currentInterval !== cachedCurrentInterval) {
  cachedCurrentInterval = currentInterval;

  WEATHER_ZONES.forEach(zone => {
   const frag = document.createDocumentFragment();
   for (let r = -3; r <= 13; r++) {
    const tr = document.createElement("tr");
    for (let c = 0; c < 3; c++) {
     tr.appendChild(buildWeatherCell(baseInterval + (r * 3) + c, currentInterval, zone.rates, zone.showDate));
    }
    frag.appendChild(tr);
   }
   const tbody = document.getElementById(`weather-tbody-${zone.key}`);
   tbody.innerHTML = "";
   tbody.appendChild(frag);
  });
 }

 const nextJstMs = getJstTimeFromInterval(currentInterval + 1);
 const diffSec = Math.max(0, Math.floor((nextJstMs - now) / 1000));
 const cm = String(Math.floor(diffSec / 60)).padStart(2, '0');
 const cs = String(diffSec % 60).padStart(2, '0');
 document.getElementById("countdown").textContent = `${cm}:${cs}`;
 const etMs = now * (1440 / 70);
 const etH = String(Math.floor(etMs / 3600000) % 24).padStart(2, '0');
 const etM = String(Math.floor(etMs / 60000) % 60).padStart(2, '0');
 document.getElementById("et-clock").textContent = `ET ${etH}:${etM}`;
}

function etLabelFromInterval(interval) {
 const mod = ((interval % 3) + 3) % 3;
 const hour = mod === 0 ? 0 : (mod === 1 ? 8 : 16);
 return `ET ${String(hour).padStart(2, '0')}:00`;
}

function showWeatherPopup(weatherName, rates) {
 const now = Date.now();
 const currentInterval = getEorzeaInterval(now);
 const results = [];
 let interval = currentInterval;
 let safety = 0;

 while (results.length < 20 && safety < 8000) {
  const weather = calculateWeather(interval, rates);
  if (weather.name === weatherName) {
   const jstMs = getJstTimeFromInterval(interval);
   const date = new Date(jstMs);
   const mm = String(date.getMonth() + 1).padStart(2, '0');
   const dd = String(date.getDate()).padStart(2, '0');
   const hh = String(date.getHours()).padStart(2, '0');
   const min = String(date.getMinutes()).padStart(2, '0');
   const hoursFromNow = (jstMs - now) / 3600000;
   results.push({ date: `${mm}/${dd}`, time: `${hh}:${min}`, et: etLabelFromInterval(interval), hoursFromNow });
  }
  interval++;
  safety++;
 }
 renderWeatherPopup(weatherName, results);
}

// 天気セルのマウスオーバーで「新鋭」などを大きく表示(マウスのある端末のみ)
(function () {
    if (!window.matchMedia('(hover: hover) and (pointer: fine)').matches) return;
    const tip = document.createElement("div");
    tip.id = "weather-tip";
    document.body.appendChild(tip);
    const cellOf = (t) => (t && t.closest) ? t.closest("td[data-tip]") : null;
    const hide = () => { tip.style.display = "none"; };

    function show(td) {
        tip.textContent = td.dataset.tip;
        tip.style.display = "block";
        const r = td.getBoundingClientRect();
        const w = tip.offsetWidth, h = tip.offsetHeight;
        const left = Math.max(4, Math.min(r.left + r.width / 2 - w / 2, window.innerWidth - w - 4));
        let top = r.bottom + 4;
        if (top + h > window.innerHeight - 4) top = Math.max(4, r.top - h - 4); // 下に入らない場合のみ上に表示
        tip.style.left = left + "px";
        tip.style.top = top + "px";
    }

    document.addEventListener("mouseover", (e) => {
        const td = cellOf(e.target);
        if (td) show(td); else hide();
    });
    document.addEventListener("mouseout", (e) => { if (!e.relatedTarget) hide(); });
    window.addEventListener("scroll", hide, true);
})();

function renderWeatherPopup(weatherName, results) {
 document.getElementById("popup-title").textContent = `${weatherName} の発生予定`;
 const tbody = document.getElementById("popup-tbody");
 tbody.innerHTML = "";

 if (results.length === 0) {
  tbody.innerHTML = '<tr><td colspan="5" style="color:#999;">見つかりませんでした</td></tr>';
 } else {
  results.forEach(r => {
   const tr = document.createElement("tr");
   let hoursText;
   if (r.hoursFromNow < 0) {
    hoursText = "経過";
   } else {
    const totalMin = Math.floor(r.hoursFromNow * 60);
    const hh2 = String(Math.floor(totalMin / 60)).padStart(2, '0');
    const mm2 = String(totalMin % 60).padStart(2, '0');
    hoursText = `${hh2}:${mm2}後`;
   }
   tr.innerHTML = `<td>${weatherName}</td><td>${r.date}</td><td>${r.time}</td><td>${r.et}</td><td>${hoursText}</td>`;
   tbody.appendChild(tr);
  });
 }
 document.getElementById("weather-popup-overlay").classList.remove("hidden");
}

document.getElementById("popup-close").addEventListener("click", () => {
 document.getElementById("weather-popup-overlay").classList.add("hidden");
});
document.getElementById("weather-popup-overlay").classList.add("hidden"); // 初期状態補正
document.getElementById("weather-popup-overlay").addEventListener("click", (e) => {
 if (e.target.id === "weather-popup-overlay") document.getElementById("weather-popup-overlay").classList.add("hidden");
});

function toggleZoneColumns() {
 WEATHER_ZONES.forEach(zone => {
  const show = document.getElementById(`chk-${zone.key}`).checked;
  document.getElementById(`container-${zone.key}`).classList.toggle("hidden", !show);
 });
}

setInterval(updateWeatherTable, 1000);
updateWeatherTable();
toggleZoneColumns();
</script>

</body></html>

コメント

  1. こんにちは、これはコメントです。
    コメントの承認、編集、削除を始めるにはダッシュボードの「コメント」画面にアクセスしてください。
    コメントのアバターは「Gravatar」から取得されます。