/* =====================================================================
   窓辺の計器 — /quiet.html 専用スタイル（3つ目のトップページ）
   ---------------------------------------------------------------------
   このファイルは quiet.html だけが読む。classic.html と index.html は
   1バイトも読まない。逆にこの画面は次を「読み込まない」:

     tailwind.min.css / site-nav.css / design-system.css / home.css /
     home-theme.css / home-stage.css / activity-chart.css /
     Font Awesome / Material Icons

   だから .sr-only も :focus-visible の既定も虹ラインも「無い」。
   必要なものはこのファイルが自前で持つ。

   ★ Tailwind のクラス名をこのファイルにも quiet.html にも書かないこと。
     tailwind.config.js の content が html 配下の全 .html を走査するので、
     書くと共有の tailwind.min.css が太り、classic と index の
     レンダーブロック CSS まで増える。この画面のためだけに他2画面を
     遅くすることになる。

   ★ 既存7ページと同じ顔にしないための「5つの禁止」。実装後に grep で検査する。
     1. text-transform: uppercase を1回も書かない
     2. font-weight: 900 を使わない（400 / 500 / 700 の3つだけ）
     3. Orbitron（--nzw-font-display）を使わない
     4. 見出しの下に罫を引かない（罫は「枠」か「区切り」にだけ使う）
     5. rgba(255,255,255,0.05〜0.10) の白い細罫を作らない（zerohalf と衝突する）

     さらに字間の向きを逆にする。他7ページは「格の高い見出しの上に、
     広い字間の小さい文字」。この画面は格が低いほど字間が広い
     （計器のキー .22em ＞ 札 .10em ＞ 値 .05em ＞ 項目名 .01em ＞ 巨大数字 -0.03em）。

   ★ コントラストの実測（最小 4.10:1）。値を変えたら回し直すこと。
     python3 - <<'PY'
     def lum(h):
         h=h.lstrip('#'); c=[int(h[i:i+2],16)/255 for i in (0,2,4)]
         c=[x/12.92 if x<=.03928 else ((x+.055)/1.055)**2.4 for x in c]
         return .2126*c[0]+.7152*c[1]+.0722*c[2]
     def cr(a,b):
         la,lb=lum(a),lum(b); hi,lo=max(la,lb),min(la,lb); return (hi+.05)/(lo+.05)
     pairs=[('#F3ECD9','#0E1730'),('#C3CCE0','#0E1730'),('#F3ECD9','#1E2E4C'),
            ('#C3CCE0','#1E2E4C'),('#16203C','#FBF5E6'),('#3E4A66','#FBF5E6'),
            ('#16203C','#E7DFC8'),('#3E4A66','#E7DFC8'),('#6B4709','#E7DFC8')]
     for f,b in pairs: print(f,b,round(cr(f,b),2))
     PY

   ★ 既存キーとの互換。この画面は home-theme.js も bg-manager.js も読まないが、
     localStorage の timeMode / weatherMode / nzw:bg-tier は同じ意味論で
     読み書きする（home-quiet.js）。だから index / classic と設定が揃う。
     CSS が読むのは documentElement の data-qt-time / data-qt-weather /
     data-qt-tier の3つだけ。body.theme-* は互換のために付けるが参照しない。
   ===================================================================== */

/* --- 色を補間させるための型登録 -------------------------------------
   about/index.html と同じ技法。@property で <color> として登録しないと
   カスタムプロパティは transition しない（値が離散的に飛ぶ）。
   ★ min() を含む値を <length> で登録しないこと（about/index.html の事故）。
     長さは <number> で持って scale() や calc() に渡す。 */
@property --qt-sky-top   { syntax: '<color>'; inherits: true; initial-value: #0E1730; }
@property --qt-sky-bot   { syntax: '<color>'; inherits: true; initial-value: #22305A; }
@property --qt-snow      { syntax: '<color>'; inherits: true; initial-value: #E7DFC8; }
@property --qt-snow-shade{ syntax: '<color>'; inherits: true; initial-value: #D3CAB0; }
@property --qt-tree-near { syntax: '<color>'; inherits: true; initial-value: #EDF3F9; }
@property --qt-tree-mid  { syntax: '<color>'; inherits: true; initial-value: #8E9BBC; }
@property --qt-tree-far  { syntax: '<color>'; inherits: true; initial-value: #3A4770; }
@property --qt-glow-o    { syntax: '<number>'; inherits: true; initial-value: 0.24; }
@property --qt-leaf-far  { syntax: '<color>'; inherits: true; initial-value: transparent; }
@property --qt-leaf-mid  { syntax: '<color>'; inherits: true; initial-value: transparent; }
@property --qt-leaf-near { syntax: '<color>'; inherits: true; initial-value: transparent; }

/* =====================================================================
   1. 不変トークン
   ===================================================================== */
:root {
    /* 原色は3つ。これ以外の色相をページに1つも足さない */
    --qt-navy: #16203C;
    --qt-paper: #F3ECD9;
    --qt-gold: #E8B04B;
    /* 金の沈み。雪原の上（明るい面）で使う */
    --qt-gold-deep: #6B4709;

    /* 空の上 / 雪原の上、それぞれの第一と第二 */
    --qt-ink-sky: #F3ECD9;
    --qt-sub-sky: #C3CCE0;
    --qt-ink-gnd: #16203C;
    --qt-sub-gnd: #3E4A66;

    /* 罫。★ アルファ 0.05〜0.10 の白い細罫を作らないこと */
    --qt-rule-sky: rgba(232, 176, 75, 0.34);
    --qt-rule-gnd: rgba(22, 32, 60, 0.22);
    --qt-rule-gnd-soft: rgba(22, 32, 60, 0.12);

    --qt-sans: 'Noto Sans JP', system-ui, -apple-system, 'Hiragino Kaku Gothic ProN', sans-serif;
    --qt-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    /* 巨大数字だけ。Urbanist は既存フォント URL に含まれている（追加取得ゼロ） */
    --qt-num: 'Urbanist', 'Noto Sans JP', system-ui, sans-serif;

    --qt-dial: 176px;
    --qt-rail-w: 152px;
    --qt-ease: cubic-bezier(0.20, 0.74, 0.34, 1);

    /* --- 季節。既定は冬（裸木＋雪原）。JS が data-qt-season を立てる --- */
    --qt-leaf-far: transparent;
    --qt-leaf-mid: transparent;
    --qt-leaf-near: transparent;
    --qt-season-wash: rgba(0, 0, 0, 0);
    /* 舞うもの（雪・花びら・光・落ち葉）の形と動き。季節が上書きする */
    --qt-mote: var(--qt-paper);
    --qt-p-rx: 2.2;
    --qt-p-ry: 2.2;
    --qt-p-swayk: 1;
    --qt-p-durk: 1;

    /* --- 太陽と月。位置は JS が分から計算して入れる（弧を描く） --- */
    --qt-sun-x: 50%;
    --qt-sun-y: 120%;
    --qt-sun-o: 0;
    --qt-moon-x: 50%;
    --qt-moon-y: 120%;
    --qt-moon-o: 0;
    --qt-moon-shift: 62px;

    /* 天気で動く粒立ち。色相は1つも変えない */
    --qt-star-o: 1;
    /* 時間帯で決まる星の見えかた。昼は 0（昼に星は出ない） */
    --qt-star-t: 1;
    /* 天気で動く 3 つ。雲の濃さ・空の翳り・天体の翳り */
    --qt-cloud-o: .10;
    --qt-sky-dim: 0;
    --qt-orb-dim: 1;
    --qt-tick-o: 0.95;
    --qt-haze-o: 0;
    --qt-flake-force: 0;

    /* 空の下端にレールが入る時間帯だけ、レール幅の縦帯を敷く */
    --qt-rail-scrim-o: 0;

    /* 既定＝夜（@property 非対応ブラウザの保険。素の :root に必ず書く） */
    --qt-sky-top: #0E1730;
    --qt-sky-bot: #22305A;
    --qt-snow: #E7DFC8;
    --qt-snow-shade: #D3CAB0;
    --qt-tree-near: #EDF3F9;
    --qt-tree-mid: #8E9BBC;
    --qt-tree-far: #3A4770;
    --qt-glow-o: 0.24;

    color-scheme: dark;
}

/* 時間帯を跨ぐときの補間。transition-property に変数名を1つずつ列挙する
   （`all` はカスタムプロパティを含まない ── about/index.html の実測メモ） */
:root {
    transition:
        --qt-sky-top 1.2s ease,
        --qt-sky-bot 1.2s ease,
        --qt-snow 1.2s ease,
        --qt-snow-shade 1.2s ease,
        --qt-tree-near 1.2s ease,
        --qt-tree-mid 1.2s ease,
        --qt-tree-far 1.2s ease,
        --qt-glow-o 1.2s ease;
}

/* 夜へ入るときだけ、雪原が沈むのを空より 0.45s 遅らせる。
   「空が暗くなったから雪原も沈んだ」という順序を作る（about/index.html の技法）。
   行き先の状態に delay を持たせるのが要（出発側に持たせると逆向きで効かない）。 */
:root[data-qt-time="night"] {
    transition-delay: 0s, 0s, .45s, .45s, .30s, .30s, .30s, 0s;
}

/* =====================================================================
   2. 4テーマ
   空の上端は4テーマとも深いまま保ち、明るくなるのは地平側だけにする。
   夜明けと日中の光は地平から来る、という理屈でもあり、
   これで「空の上に置いた文字のコントラストが時間帯でほぼ変わらない」。
   ===================================================================== */
:root[data-qt-time="night"] {
    --qt-star-t: 1;
    --qt-sky-top: #0E1730;
    --qt-sky-bot: #22305A;
    --qt-snow: #E7DFC8;
    --qt-snow-shade: #D3CAB0;
    --qt-tree-near: #EDF3F9;
    --qt-tree-mid: #8E9BBC;
    --qt-tree-far: #3A4770;
    --qt-glow-o: 0.24;
    --qt-rail-scrim-o: 0;
}

:root[data-qt-time="sunset"] {
    --qt-star-t: .46;
    --qt-sky-top: #1E1836;
    --qt-sky-bot: #7A4A50;
    --qt-snow: #EFE1C6;
    --qt-snow-shade: #DCC9A8;
    --qt-tree-near: #FBF4E7;
    --qt-tree-mid: #B99EA0;
    --qt-tree-far: #5A4257;
    --qt-glow-o: 0.46;
    --qt-rail-scrim-o: 0;
}

:root[data-qt-time="morning"] {
    --qt-star-t: .16;
    --qt-sky-top: #1B2A47;
    --qt-sky-bot: #A8AEC2;
    --qt-snow: #F5EEDA;
    --qt-snow-shade: #E2D9BF;
    --qt-tree-near: #FDFAF1;
    --qt-tree-mid: #AEBACC;
    --qt-tree-far: #5A6A88;
    --qt-glow-o: 0.38;
    --qt-rail-scrim-o: 0.55;
}

:root[data-qt-time="day"] {
    --qt-star-t: 0;
    --qt-sky-top: #1E2E4C;
    --qt-sky-bot: #BFCBDD;
    --qt-snow: #FBF5E6;
    --qt-snow-shade: #E9E0C9;
    --qt-tree-near: #FFFFFF;
    --qt-tree-mid: #BCC8D9;
    --qt-tree-far: #66789A;
    --qt-glow-o: 0.30;
    --qt-rail-scrim-o: 0.55;
}

/* =====================================================================
   2-2. 季節
   ★ 地面の「明るさ」は時間帯が持ち、季節は「色味」だけを薄く足す。
     こうしないと 4 テーマ × 4 季節 = 16 通りの地面色を手で書くことになり、
     しかも読みやすさ（雪原の上の濃紺 4.5:1）が季節ごとに崩れる。
   ★ 木は白樺のまま（幹は時間帯が持つ）。季節で変わるのは葉と舞うものだけ。
     幹まで季節で変えると、about/index.html の山（季節 4 軸）と同じ土俵に乗る。
   ===================================================================== */
:root[data-qt-season="winter"] {
    --qt-leaf-far: transparent;
    --qt-leaf-mid: transparent;
    --qt-leaf-near: transparent;
    --qt-season-wash: rgba(0, 0, 0, 0);
    --qt-mote: var(--qt-paper);
    --qt-p-rx: 2.2; --qt-p-ry: 2.2; --qt-p-swayk: 1; --qt-p-durk: 1;
}
:root[data-qt-season="spring"] {
    --qt-leaf-far: #B9909F;
    --qt-leaf-mid: #DCAFBD;
    --qt-leaf-near: #F0C8D2;
    --qt-season-wash: rgba(150, 170, 120, 0.13);
    --qt-mote: #EFC6D0;
    /* 花びらは大きく横に流れ、ゆっくり落ちる */
    --qt-p-rx: 3.0; --qt-p-ry: 1.7; --qt-p-swayk: 2.6; --qt-p-durk: 1.8;
}
:root[data-qt-season="summer"] {
    --qt-leaf-far: #55764F;
    --qt-leaf-mid: #789A66;
    --qt-leaf-near: #9BBA7C;
    --qt-season-wash: rgba(120, 160, 100, 0.18);
    --qt-mote: #F2E2A8;
    /* 光の粒は落ちずに漂う（.qt-p を逆再生して下から上へ） */
    --qt-p-rx: 2.0; --qt-p-ry: 2.0; --qt-p-swayk: 3.2; --qt-p-durk: 2.6;
    --qt-p-sway: qt-sway-glow;
}
:root[data-qt-season="autumn"] {
    --qt-leaf-far: #9C6A3C;
    --qt-leaf-mid: #C0854A;
    --qt-leaf-near: #D9A05C;
    --qt-season-wash: rgba(180, 140, 80, 0.16);
    --qt-mote: #C57742;
    /* 落ち葉は速く落ちて大きく舞う */
    --qt-p-rx: 3.2; --qt-p-ry: 1.9; --qt-p-swayk: 3.0; --qt-p-durk: 0.85;
}
:root[data-qt-season="summer"] .qt-p { animation-direction: reverse; }

/* =====================================================================
   天気
   ★ 星の濃さだけで表さないこと。昼は星が 0 なので、晴れと雨を
     押し比べても何も変わらなかった（実際にそう報告を受けた）。
     いまは 4 つを動かす:
       雲（--qt-cloud-o）／空の翳り（--qt-sky-dim）／
       天体の翳り（--qt-orb-dim）／降るもの（--qt-mote と形）
   ★ 色相は足さない。翳りは紺、雲は生成りの濃度だけで作る。
   ===================================================================== */
:root[data-qt-weather="clear"] {
    --qt-star-o: 1.00; --qt-tick-o: .95; --qt-haze-o: .00;
    --qt-cloud-o: .10; --qt-sky-dim: 0; --qt-orb-dim: 1;
}
:root[data-qt-weather="cloudy"] {
    --qt-star-o: 0.16; --qt-tick-o: .70; --qt-haze-o: .30;
    --qt-cloud-o: .90; --qt-sky-dim: .22; --qt-orb-dim: .42;
}
:root[data-qt-weather="rain"] {
    --qt-star-o: 0.04; --qt-tick-o: .80; --qt-haze-o: .44;
    --qt-cloud-o: 1; --qt-sky-dim: .34; --qt-orb-dim: .20;
    /* 雨粒は細い縦線。速く落ちて、ほとんど揺れず、回らない */
    --qt-mote: #C3CCE0; --qt-p-rx: .7; --qt-p-ry: 7; --qt-p-swayk: .22; --qt-p-durk: .30;
}
/* 大雨。雨の «強い» 側で、別の天気ではない。
   ★ 3 画面のうち雨を絵として持つのはこの画面だけ、と決めた。
     カード版と 6 幕には前面に降る粒を置かない（home.css の «天気のオーバーレイは
     廃止した» を見ること）。だから大雨の見せ場もここにある。
   ★ 増やすのは «長さ・速さ・翳り・本数» の 4 つだけ。色相は足さない
     （この画面の天気は、翳りは紺・雲は生成りの濃度だけで作る決まり）。
   ★ 本数は home-quiet.js が .qt-motes に足す（描き込みの量の約束に乗せる）。 */
:root[data-qt-weather="heavy"] {
    --qt-star-o: 0.00; --qt-tick-o: .86; --qt-haze-o: .62;
    --qt-cloud-o: 1; --qt-sky-dim: .48; --qt-orb-dim: .08;
    /* 雨脚は雨の 1.9 倍の長さで、1.8 倍速い。揺れはさらに小さくする
       （強い雨は «真っ直ぐ落ちて見える» のが効く） */
    --qt-mote: #AEBBD2; --qt-p-rx: .85; --qt-p-ry: 13; --qt-p-swayk: .12; --qt-p-durk: .17;
}
:root[data-qt-weather="snow"] {
    --qt-star-o: 0.55; --qt-tick-o: .58; --qt-haze-o: .18;
    --qt-cloud-o: .55; --qt-sky-dim: .14; --qt-orb-dim: .62;
    /* 降っているのは雪なので、季節にかかわらず白い丸にする */
    --qt-mote: var(--qt-paper); --qt-p-rx: 2.2; --qt-p-ry: 2.2; --qt-p-swayk: 1.1; --qt-p-durk: 1;
}
/* 雨は回らない（縦線が回るとおかしい）。大雨も同じ扱いで、少しだけ濃くする */
:root[data-qt-weather="rain"] .qt-p-i,
:root[data-qt-weather="heavy"] .qt-p-i {
    animation: qt-sway var(--sd) ease-in-out infinite alternate;
    opacity: calc(0.16 + var(--s) * 0.30);
}
:root[data-qt-weather="heavy"] .qt-p-i {
    opacity: calc(0.22 + var(--s) * 0.34);
}

/* =====================================================================
   3. 土台
   ===================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
    /* <head> の同期スクリプトが background-color を直接当てている。
       ここは CSS が届いた後の受け皿（同じ色に落ち着く） */
    background: var(--qt-sky-top);
}

body {
    margin: 0;
    /* 絵（.qt-scene）を absolute にしたとき、その基準になる */
    position: relative;
    min-height: 100svh;
    font-family: var(--qt-sans);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    color: var(--qt-ink-sky);
    -webkit-font-smoothing: antialiased;
    /* 一枚の窓。ただし overflow:hidden は1箇所も書かない
       （入りきらない環境では素直にスクロールさせる） */
}

a { color: inherit; }

/* Tailwind の .sr-only を読まないので自前で持つ */
.qt-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.qt-skip {
    position: absolute;
    left: 8px;
    top: -60px;
    z-index: 90;
    padding: 10px 14px;
    font-size: 12px;
    letter-spacing: .04em;
    color: var(--qt-navy);
    background: var(--qt-paper);
    border: 1px solid var(--qt-gold-deep);
    text-decoration: none;
    transition: top .18s var(--qt-ease);
}
.qt-skip:nth-of-type(2) { left: 220px; }
.qt-skip:focus-visible { top: 8px; }

/* フォーカスの印は金。design-system.css を読まないので自前 */
a:focus-visible,
button:focus-visible,
[role="slider"]:focus-visible {
    outline: 2px solid var(--qt-gold);
    outline-offset: 3px;
    border-radius: 2px;
}
.qt-ground-side a:focus-visible,
.qt-ground-side button:focus-visible,
.qt-dial-wrap [role="slider"]:focus-visible {
    outline-color: var(--qt-gold-deep);
}

/* =====================================================================
   4. 絵（空・星・林・地平・雪原・雪片）
   すべて背後の固定レイヤー。文字は触らせない
   ===================================================================== */
.qt-scene {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    /* 地平の曲線より下はここが受ける。SVG を縦に引き伸ばさずに済む。
       季節の色味は上に重ねる（時間帯の明るさを壊さないため） */
    background: linear-gradient(var(--qt-season-wash), var(--qt-season-wash)), var(--qt-snow);
    transition: background-color 1.2s ease;
}

.qt-sky {
    position: absolute;
    inset: 0 0 42% 0;
    /* 上端を 26% まで平らに保つのが要。ここを崩すとコントラストが破れる */
    background: linear-gradient(to bottom,
            var(--qt-sky-top) 0%,
            var(--qt-sky-top) 26%,
            var(--qt-sky-bot) 100%);
    /* 曇りと雨の翳り。要素を増やさずに 1 枚かぶせる */
    box-shadow: inset 0 0 0 100vmax rgba(22, 32, 60, var(--qt-sky-dim));
    transition: box-shadow 1s ease;
}

/* 雲。生成りの濃度だけで作る（色相は足さない）。ゆっくり流れる */
.qt-clouds {
    position: absolute;
    left: -20%;
    top: 4%;
    width: 140%;
    height: 46%;
    opacity: var(--qt-cloud-o);
    transition: opacity 1s ease;
    pointer-events: none;
    background:
        radial-gradient(38% 46% at 18% 62%, rgba(226, 232, 242, .30) 0%, rgba(226, 232, 242, 0) 70%),
        radial-gradient(30% 38% at 40% 40%, rgba(226, 232, 242, .24) 0%, rgba(226, 232, 242, 0) 72%),
        radial-gradient(44% 40% at 68% 66%, rgba(226, 232, 242, .28) 0%, rgba(226, 232, 242, 0) 70%),
        radial-gradient(26% 32% at 88% 34%, rgba(226, 232, 242, .22) 0%, rgba(226, 232, 242, 0) 74%);
    animation: qt-drift 120s linear infinite alternate;
}
@keyframes qt-drift {
    from { transform: translateX(-3%); }
    to   { transform: translateX(3%); }
}
:root[data-qt-tier="off"] .qt-clouds { animation: none; }

/* 空の下端の光。天体は描かない（太陽と月は about/index.html の主題なので譲る） */
.qt-glow {
    position: absolute;
    left: 50%;
    top: 58%;
    width: 150vw;
    height: 46vh;
    transform: translate(-50%, -70%);
    background: radial-gradient(ellipse at 50% 100%,
            var(--qt-sky-bot) 0%,
            rgba(0, 0, 0, 0) 68%);
    opacity: var(--qt-glow-o);
}

/* 曇り・雨のもや。粒立ちだけを変える役 */
.qt-haze {
    position: absolute;
    inset: 0 0 42% 0;
    background: linear-gradient(to bottom,
            rgba(150, 160, 180, 0) 0%,
            rgba(150, 160, 180, .55) 100%);
    opacity: var(--qt-haze-o);
}

/* =====================================================================
   太陽と月
   ---------------------------------------------------------------------
   about/index.html と同じ「測る道具」としての天体（同心円・破線の環・目盛り環）。
   ただし運行のさせ方は違う。

   ★ about は時間帯 4 状態の切り替えなので、left/top に別々の緩急を当てて
     弧に「見せて」いる（x と y に同じ緩急を当てると、どんな cubic-bezier を
     選んでも 2 点を結ぶ直線にしかならない、というのがあちらの注記）。
     この画面のダイヤルは分単位で連続しているので、JS が
     sin 曲線から座標そのものを毎フレーム出す。だから本物の弧になり、
     針をドラッグしている間も太陽が空をなぞる。
     → left/top に transition を当てないこと。当てると二重に補間されて遅れる。

   ★ 月の満ち欠けは実際の月齢から出す（about/index.html と同じ計算）。
     飾りで毎回同じ形を出すより、今夜の形と合っているほうが面白い。
   ===================================================================== */
/* ★ 天体は「空の帯」を基準に置くこと。.qt-scene 直下に置くと、
   モバイルで scene が本文の高さいっぱい（例 1170px）に伸びたとき、
   top:20% が 234px になって空（372px）から外れる。
   この入れ物が空と同じ矩形を持つので、どの版面でも弧が空に収まる */
.qt-orbit {
    position: absolute;
    inset: 0 0 42% 0;
    pointer-events: none;
}

.qt-sun,
.qt-moon {
    position: absolute;
    left: var(--qt-sun-x);
    top: var(--qt-sun-y);
    width: 92px;
    height: 92px;
    margin: -46px 0 0 -46px;
    overflow: visible;
    opacity: calc(var(--qt-sun-o) * var(--qt-orb-dim));
    transition: opacity 1.1s ease;
}
.qt-moon {
    left: var(--qt-moon-x);
    top: var(--qt-moon-y);
    width: 78px;
    height: 78px;
    margin: -39px 0 0 -39px;
    opacity: calc(var(--qt-moon-o) * var(--qt-orb-dim));
}

.qt-sun-halo { fill: url(#qt-sun-halo); }
.qt-sun-ring,
.qt-sun-dial {
    fill: none;
    stroke: var(--qt-gold);
    stroke-linecap: round;
}
.qt-sun-ring { stroke-width: 1.6; opacity: .40; }
.qt-sun-ring--dash { stroke-dasharray: 3 13; opacity: .30; }
.qt-sun-dial { stroke-width: 9; opacity: .26; stroke-linecap: butt; }
.qt-sun-disc { fill: url(#qt-sun-disc); }
.qt-sun-edge { fill: none; stroke: #FFF3D6; stroke-width: 2; opacity: .5; }

.qt-moon-halo { fill: url(#qt-moon-halo); }
.qt-moon-ring,
.qt-moon-dial {
    fill: none;
    stroke: var(--qt-paper);
    stroke-linecap: round;
}
.qt-moon-ring { stroke-width: 1.4; opacity: .26; }
.qt-moon-ring--dash { stroke-dasharray: 2 11; opacity: .22; }
.qt-moon-dial { stroke-width: 7; opacity: .18; stroke-linecap: butt; }
.qt-moon-body { fill: #F6F1E2; }
.qt-moon-crater { fill: #D9D2BE; opacity: .55; }
/* 欠け際は「同じ半径の円を横へずらしたマスク」で作る。
   ずらす量 --qt-moon-shift は今夜の月齢から JS が入れる */
.qt-moon-shadow {
    transform: translateX(var(--qt-moon-shift));
    transform-box: view-box;
}

.qt-stars {
    position: absolute;
    inset: 0 0 46% 0;
    width: 100%;
    height: 54%;
    /* 天気（粒立ち）× 時間帯（明るさ）。どちらかが 0 なら星は出ない */
    opacity: calc(var(--qt-star-o) * var(--qt-star-t));
    transition: opacity 1.2s ease;
}
.qt-stars circle { fill: var(--qt-paper); }
/* 1〜2 等級の星に添えるにじみ。点が「光っている」ように見える */
.qt-stars .qt-halo {
    /* 平らな円だと灰色の円盤に見える。中心から消えていくぼかしにする */
    fill: url(#qt-star-halo);
    opacity: 1;
}
/* 瞬きは粒ごとに周期が違う（生成側で --duration / --delay を振ってある） */
.qt-stars .tw { animation: qt-twinkle ease-in-out infinite alternate; }

/* 天の川。夜だけ薄く出す。色は増やさず生成りのまま濃度だけで作る */
.qt-milky {
    position: absolute;
    left: -12%;
    top: -8%;
    width: 124%;
    height: 62%;
    transform: rotate(-14deg);
    background:
        radial-gradient(60% 42% at 32% 46%, rgba(243, 236, 217, .085) 0%, rgba(243, 236, 217, 0) 72%),
        radial-gradient(48% 30% at 66% 54%, rgba(243, 236, 217, .07) 0%, rgba(243, 236, 217, 0) 74%),
        radial-gradient(70% 16% at 50% 50%, rgba(243, 236, 217, .06) 0%, rgba(243, 236, 217, 0) 80%);
    opacity: calc(var(--qt-star-o) * var(--qt-star-t));
    transition: opacity 1.2s ease;
    pointer-events: none;
}
:root[data-qt-tier="off"] .qt-milky { display: none; }

/* 林。symbol 4種を use で並べ、奥・中・手前の3層で色を変える */
.qt-forest {
    position: absolute;
    left: 0;
    right: 0;
    /* 足元が地平線（58%）のわずかに下に来るように置く */
    bottom: 39%;
    width: 100%;
    height: 33%;
}
/* 葉。冬は透明なので消える。季節をまたぐときは 1s でにじませる */
.qt-canopy { transition: fill 1s ease; }
.qt-l-far  { fill: var(--qt-leaf-far);  opacity: .80; }
.qt-l-mid  { fill: var(--qt-leaf-mid);  opacity: .85; }
.qt-l-near { fill: var(--qt-leaf-near); opacity: .90; }

.qt-forest .qt-far  { color: var(--qt-tree-far); }
.qt-forest .qt-mid  { color: var(--qt-tree-mid); }
.qt-forest .qt-near { color: var(--qt-tree-near); }
.qt-trunk { stroke: currentColor; }

/* 雪原。preserveAspectRatio="none" で横に伸ばす（曲線は伸びるが完全に応答的） */
.qt-ground {
    position: absolute;
    left: 0;
    right: 0;
    top: 52%;
    bottom: 0;
    width: 100%;
    height: 48%;
}
.qt-ground .qt-snow-fill { fill: var(--qt-snow); }
.qt-ground .qt-season-fill { fill: var(--qt-season-wash); }
.qt-ground .qt-snow-drift { fill: var(--qt-snow-shade); opacity: .55; }

/* =====================================================================
   舞うもの（雪・花びら・光の粒・落ち葉）
   ---------------------------------------------------------------------
   ★ 落下と横揺れを別の要素に分けること。1 つの要素の transform に
     両方のアニメーションを載せると後勝ちで片方が黙って消える。
     ここでは親の <g> が transform（落下）を、子の <ellipse> が
     translate / rotate（横揺れ・回転）という別プロパティを持つ。

   ★ まっすぐ落とさない。実物の雪は
       (1) 横に揺れる       … 揺れ幅と周期を粒ごとに変える
       (2) 大きいほど速い   … 手前＝大きい＝速い（生成側で --dur を --s で割ってある）
       (3) 大きいほど濃い   … これで奥行きが出る
       (4) 回りながら落ちる … 丸では見えないが、花びらと落ち葉で効く
     の 4 つが揃って初めて「降っている」に見える。前の版は (1)〜(4) が
     どれも無く、同じ速さで垂直に落ちる点の列だった。
   ===================================================================== */
.qt-motes {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: none;
}

/* 落下。親の <g> が持つ */
.qt-p {
    animation-name: qt-fall;
    animation-duration: calc(var(--dur) * var(--qt-p-durk));
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-delay: var(--delay);
}

/* 横揺れと回転。子の <ellipse> が持つ */
.qt-p-i {
    rx: calc(var(--s) * var(--qt-p-rx) * 1px);
    ry: calc(var(--s) * var(--qt-p-ry) * 1px);
    fill: var(--qt-mote);
    opacity: calc(0.26 + var(--s) * 0.36);
    animation:
        var(--qt-p-sway, qt-sway) var(--sd) ease-in-out infinite alternate,
        qt-spin var(--rd) linear infinite;
    transition: rx .8s ease, ry .8s ease, fill .8s ease;
}

@keyframes qt-fall {
    from { transform: translateY(-24px); }
    to   { transform: translateY(1024px); }
}
@keyframes qt-sway {
    from { translate: calc(var(--sw) * var(--qt-p-swayk) * -1) 0; }
    to   { translate: calc(var(--sw) * var(--qt-p-swayk)) 0; }
}
/* 夏の光の粒だけ、揺れながら明るさも呼吸する */
@keyframes qt-sway-glow {
    from { translate: calc(var(--sw) * var(--qt-p-swayk) * -1) 0; opacity: .16; }
    to   { translate: calc(var(--sw) * var(--qt-p-swayk)) 0; opacity: .95; }
}
@keyframes qt-spin {
    from { rotate: 0deg; }
    to   { rotate: 360deg; }
}

/* 描き込みの量。星・幹・葉・舞うものの本数で表す
   静か=幹12/星0/舞0 ／ ふつう=幹26/星34/舞12 ／ 濃い=幹44/星90/舞24 */
:root[data-qt-tier="off"] .qt-stars { display: none; }
:root[data-qt-tier="off"] .lv2,
:root[data-qt-tier="off"] .lv3 { display: none; }
:root[data-qt-tier="light"] .lv3 { display: none; }
:root[data-qt-tier="light"] .qt-motes,
:root[data-qt-tier="rich"] .qt-motes { display: block; }
:root[data-qt-tier="light"] .qt-motes .mo2 { display: none; }
@keyframes qt-twinkle {
    from { opacity: .28; }
    to   { opacity: 1; }
}

/* レールが空の下端に掛かる時間帯（朝・昼）だけ、レール幅の縦帯を敷く。
   塗りの箱を1つだけ許すのはここ。空と同色なので箱には見えない */
.qt-rail-scrim {
    position: absolute;
    top: 0;
    right: 8px;
    width: calc(var(--qt-rail-w) + 26px);
    /* ★ 地平線（58%）より手前で消しきること。越えると雪原に黒い染みが出る */
    height: 52%;
    background: linear-gradient(to bottom,
            rgba(0, 0, 0, 0) 0%,
            var(--qt-sky-top) 18%,
            var(--qt-sky-top) 66%,
            rgba(0, 0, 0, 0) 100%);
    /* ぼかして端を消す。硬い矩形のままだと「灰色の箱」に見える */
    filter: blur(12px);
    opacity: calc(var(--qt-rail-scrim-o) * .92);
    transition: opacity 1.2s ease;
}

/* =====================================================================
   3 つのデザインの案内バー
   ★ 行き先どうしに強弱を付けないこと。片方だけ塗ると、塗られたほうが
     「いまの画面」に見える。現在地は破線と印で別扱いにする。
   ===================================================================== */
/* ★ グリッドの行にしないこと。行にすると、閉じたときにその行が 0 になり、
   地平線に合わせてある版面が上へずれる。頭のブロックの中に置けば、
   出ていても閉じていても下の段は動かない。 */
.qt-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin: 0 0 14px;
    padding: 10px 12px 10px 14px;
    background: rgba(14, 23, 48, .62);
    border: 1px solid var(--qt-rule-sky);
}
.qt-banner[hidden] { display: none; }
/* 出し入れの動き。hidden は補間できないので data-state で動かす。
   畳むときの max-height は JS が実測して入れる（auto からは補間できない）。 */
.qt-banner {
    overflow: hidden;
    transition:
        opacity .32s var(--qt-ease),
        transform .38s var(--qt-ease),
        max-height .42s cubic-bezier(0.62, 0.02, 0.80, 0.40),
        margin-bottom .42s cubic-bezier(0.62, 0.02, 0.80, 0.40);
}
.qt-banner[data-state="enter"] { opacity: 0; transform: translateY(-10px); }
.qt-banner[data-state="in"] { opacity: 1; transform: translateY(0); }
.qt-banner[data-state="out"] {
    opacity: 0;
    transform: translateY(-8px);
    margin-bottom: 0;
    padding-top: 0;
    padding-bottom: 0;
    border-width: 0;
}
.qt-banner-main,
.qt-banner-actions,
.qt-banner-bye { transition: opacity .26s ease; }
.qt-banner-text {
    margin: 0;
    font-size: 12.5px;
    letter-spacing: .02em;
    color: var(--qt-ink-sky);
}
.qt-banner-text strong { font-weight: 500; color: var(--qt-gold); }
.qt-banner-hint {
    margin: 3px 0 0;
    font-size: 10.5px;
    line-height: 1.6;
    color: var(--qt-sub-sky);
}
.qt-banner-actions { display: flex; align-items: center; gap: 8px; }
.qt-banner-cta {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 0 13px;
    font-size: 12px;
    letter-spacing: .04em;
    text-decoration: none;
    color: var(--qt-ink-sky);
    border: 1px solid var(--qt-gold);
    background: rgba(232, 176, 75, .16);
    transition: background-color .18s ease-out, color .18s ease-out;
}
.qt-banner-cta:hover,
.qt-banner-cta:focus-visible { background: var(--qt-gold); color: #2A1B02; }
/* いま開いている画面。押せない */
.qt-banner-cta--here {
    color: var(--qt-sub-sky);
    background: none;
    border-style: dashed;
    border-color: var(--qt-rule-sky);
    cursor: default;
}
.qt-banner-cta--here::before { content: "\25AA\00A0"; }
.qt-banner-close {
    width: 32px;
    height: 32px;
    font-size: 17px;
    line-height: 1;
    color: var(--qt-sub-sky);
    background: none;
    border: 0;
    cursor: pointer;
}
.qt-banner-close:hover { color: var(--qt-gold); }
/* 閉じたときだけ出す一行 */
.qt-banner-bye { display: none; margin: 0; font-size: 12px; color: var(--qt-ink-sky); }
.qt-banner[data-state="bye"] .qt-banner-main,
.qt-banner[data-state="bye"] .qt-banner-actions { display: none; }
.qt-banner[data-state="bye"] .qt-banner-bye { display: block; }

/* =====================================================================
   5. 版面
   ===================================================================== */
.qt-page {
    position: relative;
    z-index: 1;
    display: grid;
    min-height: 100svh;
    padding: 40px 24px 24px 56px;
    column-gap: 40px;
    row-gap: 0;
    /* 盤を左、数字と一覧を右に並べる。縦に積むと雪原（42%）に収まらず
       ページがスクロールしてしまう（「一枚の窓」でなくなる） */
    grid-template-columns: 208px minmax(230px, 380px) minmax(240px, 1fr) var(--qt-rail-w);
    /* ★ 1 行目の高さを地平線（58%）に固定する。auto 1fr auto にすると
       2 行目が空の中ほどに落ちて、数字と一覧が林の上に重なって読めなくなる */
    grid-template-rows: calc(58svh - 40px) auto 1fr;
    grid-template-areas:
        "head head head rail"
        "dial now  list rail"
        "dial meta meta rail";
}

.qt-head { grid-area: head; align-self: start; }
/* 地平線のすぐ下から始める */
.qt-now  { grid-area: now;  align-self: start; padding-top: 20px; }
.qt-list { grid-area: list; align-self: start; padding-top: 22px; }
.qt-dial-wrap { grid-area: dial; align-self: start; padding-top: 16px; }
.qt-meta { grid-area: meta; align-self: end; }
.qt-rail { grid-area: rail; align-self: start; justify-self: end; }

/* =====================================================================
   6. 計器の行（キー＋値）
   キーは日本語2文字固定。大文字のラテン語キッカーを置かない
   ===================================================================== */
.qt-row {
    display: flex;
    align-items: baseline;
    gap: 14px;
    margin: 0 0 6px;
    line-height: 1.5;
}
.qt-k {
    flex: none;
    font-family: var(--qt-mono);
    font-size: 9px;
    font-weight: 400;
    letter-spacing: .22em;
    /* 格が低いほど字間が広い。7ページの型と方向が反対であることが要 */
}
.qt-v {
    font-family: var(--qt-mono);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: .05em;
}

/* いまの時刻に追いかけているのか、手で止めているのか。
   ★ 文字だけだと気づかれないので、点の「息づかい」で状態を出す。
     追従中は 2.4 秒で明滅、手動は中空の点で止まる。
     動きを減らす設定のときは明滅しない（下の全称セレクタが止める）。 */
.qt-live {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 10px;
    font-size: 9.5px;
    letter-spacing: .1em;
    white-space: nowrap;
}
.qt-live::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    border: 1px solid currentColor;
    background: currentColor;
    animation: qt-breathe 2.4s ease-in-out infinite;
}
/* 手で止めているときは塗らない・動かさない */
:root[data-qt-manual] .qt-live::before {
    background: none;
    animation: none;
}
@keyframes qt-breathe {
    0%, 100% { opacity: .28; transform: scale(.78); }
    50%      { opacity: 1;   transform: scale(1); }
}
.qt-head .qt-live { color: var(--qt-gold); }
.qt-meta .qt-live { color: var(--qt-gold-deep); }
:root[data-qt-manual] .qt-head .qt-live { color: var(--qt-sub-sky); }
:root[data-qt-manual] .qt-meta .qt-live { color: var(--qt-sub-gnd); }

/* 空の上（頭のブロック）。空帯の上 40% 以内に収める */
.qt-head .qt-k { color: var(--qt-sub-sky); }
.qt-head .qt-v { color: var(--qt-ink-sky); }

/* 雪原の上（右下のブロック） */
.qt-meta .qt-k { color: var(--qt-sub-gnd); }
.qt-meta .qt-v,
.qt-meta a { color: var(--qt-ink-gnd); }
.qt-meta a { text-decoration-color: var(--qt-rule-gnd); text-underline-offset: 3px; }
.qt-meta a:hover { text-decoration-color: var(--qt-gold-deep); }

/* ロゴ。前のデザイン（6 幕）へ戻るボタンを兼ねる */
.qt-logo {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 16px -6px;
    padding: 5px 12px 5px 6px;
    text-decoration: none;
    border: 1px solid transparent;
    transition: border-color .18s ease-out, background-color .18s ease-out;
}
.qt-logo img {
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: 50%;
}
.qt-logo-x { display: flex; flex-direction: column; gap: 1px; }
.qt-logo-x strong {
    font-size: 15px;
    font-weight: 500;
    letter-spacing: .02em;
    color: var(--qt-ink-sky);
}
.qt-logo-x small {
    font-size: 10.5px;
    letter-spacing: .04em;
    color: var(--qt-sub-sky);
}
.qt-logo:hover,
.qt-logo:focus-visible {
    border-color: var(--qt-gold);
    background: rgba(232, 176, 75, .12);
}
/* ロゴから開くデザインの切り替えメニュー */
.qt-brand { position: relative; width: fit-content; }
.qt-caret {
    width: 14px;
    height: 14px;
    margin-left: 2px;
    opacity: .55;
    color: var(--qt-sub-sky);
    transition: transform .18s var(--qt-ease), opacity .18s ease-out;
}
.qt-logo:hover .qt-caret { opacity: 1; }
#brand-switch[aria-expanded="true"] .qt-caret { transform: rotate(180deg); opacity: 1; }

.qt-brand-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 40;
    min-width: 226px;
    padding: 5px;
    background: rgba(14, 23, 48, .96);
    border: 1px solid var(--qt-gold);
    box-shadow: 0 14px 36px rgba(0, 0, 0, .40);
}
.qt-brand-menu[hidden] { display: none; }
.qt-brand-item {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 9px 11px;
    text-decoration: none;
    color: var(--qt-ink-sky);
}
.qt-brand-item strong { font-size: 13px; font-weight: 500; letter-spacing: .04em; }
.qt-brand-item small { font-size: 10px; color: var(--qt-sub-sky); }
.qt-brand-item:hover,
.qt-brand-item:focus-visible { background: rgba(232, 176, 75, .16); }
/* いま見ている画面。押せない */
.qt-brand-item--here { cursor: default; opacity: .62; }
.qt-brand-item--here strong::before { content: "\25AA\00A0"; color: var(--qt-gold); }
.qt-brand-item--here:hover { background: none; }

.qt-logo:hover .qt-logo-x small,
.qt-logo:focus-visible .qt-logo-x small { color: var(--qt-gold); }


/* 画面の切替（旧・番号だけの版。使っていないが design-system の見本に残す） */

/* =====================================================================
   7. 雪原の上の数（この画面で唯一の 700）
   ===================================================================== */
.qt-now {
    padding-left: 18px;
    border-left: 1px solid var(--qt-rule-gnd);
}
.qt-big {
    display: block;
    margin: 0;
    font-family: var(--qt-num);
    font-weight: 700;
    font-size: clamp(72px, 8.4vw, 132px);
    line-height: .92;
    letter-spacing: -0.03em;
    color: var(--qt-ink-gnd);
}
.qt-big-cap {
    margin: 6px 0 0;
    font-size: 12px;
    line-height: 1.7;
    letter-spacing: .02em;
    color: var(--qt-sub-gnd);
}
.qt-repos {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 26px;
    height: 26px;
    padding: 0 7px;
    margin-left: 6px;
    font-family: var(--qt-mono);
    font-size: 13px;
    letter-spacing: .02em;
    color: var(--qt-ink-gnd);
    border: 1px solid var(--qt-rule-gnd);
    border-radius: 100px;
}

/* =====================================================================
   8. いま出しているもの（コンテンツカードの受け皿）
   ===================================================================== */
.qt-list h2 {
    margin: 0 0 10px;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: .06em;
    color: var(--qt-sub-gnd);
    /* ★ 見出しの下に罫を引かない */
}
.qt-now-list {
    position: relative;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--qt-rule-gnd-soft);
}

/* 一覧の下からせり上がるカード。
   ★ 当たり判定を持たせないこと（pointer-events:none）。持たせると
     カードへマウスを移す途中で行から外れて消える「追いかけっこ」になる。
     行そのものがリンクなので、カードは読ませるだけでよい。
   ★ 位置の基準は <ul>。どの行に乗っても同じ場所に出る（首が振れない）。 */
.qt-card {
    position: absolute;
    top: calc(100% + 14px);
    left: 0;
    right: 0;
    padding: 15px 18px 16px;
    background: var(--qt-snow);
    border: 1px solid var(--qt-rule-gnd);
    box-shadow: 0 12px 34px rgba(22, 32, 60, .16);
    opacity: 0;
    transform: translateY(16px);
    transition: opacity .2s var(--qt-ease), transform .3s var(--qt-ease);
    pointer-events: none;
    z-index: 8;
}
.qt-now-list li:hover .qt-card,
.qt-now-list li:focus-within .qt-card {
    opacity: 1;
    transform: translateY(0);
}
.qt-card-t {
    margin: 0;
    font-size: 19px;
    font-weight: 500;
    letter-spacing: .01em;
    color: var(--qt-ink-gnd);
}
.qt-card-b {
    margin: 7px 0 0;
    font-size: 13px;
    line-height: 1.85;
    color: var(--qt-sub-gnd);
}
.qt-card-m {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin: 12px 0 0;
    padding-top: 10px;
    border-top: 1px solid var(--qt-rule-gnd-soft);
    font-family: var(--qt-mono);
    font-size: 10px;
    letter-spacing: .12em;
    color: var(--qt-sub-gnd);
}
.qt-card-go { color: var(--qt-gold-deep); }

/* 行にも「押せる」ことを出す */
.qt-now-list a { transition: padding-left .18s var(--qt-ease); }
.qt-now-list a:hover { padding-left: 8px; }
.qt-now-list li { border-bottom: 1px solid var(--qt-rule-gnd-soft); }
/* ★ justify-content: space-between で並べないこと。
     アイコンが入った時点で 3 つ子になり、名前が行の真ん中へ飛んだ。
     名前を伸ばして（flex:1）札を右端に押す、が正しい。 */
.qt-now-list li > *:not(.qt-card) {
    display: flex;
    align-items: center;
    gap: 12px;
    /* ★ アイコンを足しても行の高さを 44px から上げないこと。
         4 行ぶんの伸びがそのまま下のカード（絶対配置で常に在る）を押し下げ、
         窓の底からはみ出す。強調はアイコンと字の大きさで出す、高さでは出さない */
    min-height: 44px;
    padding: 6px 2px;
    text-decoration: none;
}
.qt-now-list a:hover .qt-now-t { color: var(--qt-gold-deep); }

/* --- アプリのアイコン ------------------------------------------------
   ★ 既定はグレースケール。1. の「原色は3つ」を守るため、4 つのアイコンの
     色相をそのまま雪原に置かない。触れた行だけ本来の色に戻す
     （notes.css の .logo と同じ作法。この画面はあれを読まないので自前で持つ）。
   ★ 枠と地を必ず敷くこと。Bearise は角が透けた丸、Dotpile は四角と
     元の形がそろっていないので、同じ札に収めないと 4 行の頭が揃わない。 */
.qt-now-i {
    flex: none;
    width: 30px;
    height: 30px;
    overflow: hidden;
    border: 1px solid var(--qt-rule-gnd-soft);
    border-radius: 9px;
    background: rgba(251, 245, 230, .66);
}
.qt-now-i img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: grayscale(1) contrast(1.03);
    transition: filter .2s var(--qt-ease);
}
.qt-now-list a:hover .qt-now-i img,
.qt-now-list li:focus-within .qt-now-i img { filter: none; }
/* API 側の行にアイコン URL が無いとき用。頭文字を 1 字だけ置いて頭を揃える */
.qt-now-i span {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-family: var(--qt-mono);
    font-size: 14px;
    color: var(--qt-sub-gnd);
}

.qt-now-t {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 17px;
    font-weight: 500;
    letter-spacing: .01em;
    color: var(--qt-ink-gnd);
}
/* 状態は札にする。.qt-repos と同じ丸札の語彙をそのまま使う */
.qt-now-s {
    display: inline-flex;
    flex: none;
    align-items: center;
    height: 23px;
    padding: 0 11px 0 9px;
    font-family: var(--qt-mono);
    font-size: 10.5px;
    letter-spacing: .06em;
    color: var(--qt-sub-gnd);
    border: 1px solid var(--qt-rule-gnd);
    border-radius: 100px;
}
.qt-now-s::before {
    content: "";
    flex: none;
    width: 5px;
    height: 5px;
    margin-right: 7px;
    border-radius: 50%;
    background: var(--qt-gold-deep);
}

/* --- 先頭の 1 行（いま推したいもの） ---------------------------------
   ★ 高さでは目立たせない（上の min-height 44px の注意と同じ理由）。
     色の付いた表紙・塗った札・太字の 3 つだけで差をつける。
   ★ 地をうすく塗るのは雪原の上だけ。空の上に面を置かない決まりには触れない。
   ★ 題名は 1 行に詰める。2 行にすると行が伸びて、スマホで窓の底からはみ出す */
.qt-now-list li.qt-now-feature { background: rgba(232, 176, 75, .16); }
.qt-now-feature .qt-now-i { border-color: var(--qt-rule-gnd); }
/* 表紙は上 4 割が白い題字の地なので、アオサギの絵のあたりを見せる */
.qt-now-feature .qt-now-i img { filter: none; object-position: center 62%; }
.qt-now-feature .qt-now-t {
    overflow: hidden;
    font-weight: 700;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.qt-now-t2 {
    margin-left: .5em;
    font-size: .82em;
    font-weight: 500;
    color: var(--qt-sub-gnd);
}
/* 一覧が狭いと副題が「AIプロジェク…」で切れる。切れて読めない字を出すより、
   主題だけにする。境目は一覧の幅で決める（画面幅だと 1366px と 390px の両方を拾えない） */
.qt-list { container-type: inline-size; }
@container (max-width: 470px) {
    .qt-now-t2 { display: none; }
}
.qt-now-feature .qt-now-s {
    color: #2A1B02;
    background: var(--qt-gold);
    border-color: var(--qt-gold);
}

/* =====================================================================
   9. 左下のダイヤル
   骨：1つの操作面に1つの操作しか置かない。盤の上に <button> は0個。
   だから当たり判定の重なり計算が発生しない
   ===================================================================== */
.qt-dial-wrap { position: relative; }

.qt-dial {
    position: relative;
    width: var(--qt-dial);
    height: var(--qt-dial);
}
.qt-dial svg { display: block; width: 100%; height: 100%; }

.qt-ticks {
    stroke: var(--qt-gold-deep);
    opacity: calc(var(--qt-tick-o) * .62);
    transition: opacity .8s ease;
}
.qt-band { stroke: var(--qt-sub-gnd); opacity: .28; transition: opacity .5s ease, stroke .5s ease; }
.qt-band.is-on { stroke: var(--qt-gold-deep); opacity: 1; }
.qt-hour { fill: var(--qt-ink-gnd); font-family: var(--qt-mono); font-size: 9px; }

.qt-hand {
    stroke: var(--qt-gold-deep);
    stroke-width: 1.5;
    stroke-linecap: round;
    transform-origin: 100px 100px;
    transition: transform .9s var(--qt-ease);
}
.qt-hand-dot { fill: var(--qt-gold-deep); opacity: 0; }
:root[data-qt-manual] .qt-hand-dot { opacity: 1; }

.qt-hub {
    fill: none;
    stroke: var(--qt-rule-gnd);
    stroke-width: 1;
}
.qt-hub-t {
    fill: var(--qt-ink-gnd);
    font-family: var(--qt-mono);
    font-size: 15px;
    letter-spacing: .02em;
    text-anchor: middle;
}
.qt-hub-s {
    fill: var(--qt-sub-gnd);
    font-family: var(--qt-sans);
    font-size: 8px;
    text-anchor: middle;
    opacity: 0;
}
:root[data-qt-manual] .qt-hub-s { opacity: 1; }
/* ハブは表示だけ。掴ませない */
.qt-hub-g { pointer-events: none; }

/* 唯一の操作面。r ≒ 72 の円 */
.qt-scrub {
    position: absolute;
    inset: 14%;
    border-radius: 50%;
    cursor: grab;
    /* ★ 必須。無いと指の動きがブラウザのパンに取られて pointercancel が飛び、
       盤が動かない。左下は iOS Safari の端スワイプとも競合するので、
       盤の左辺は画面左端から離して置くこと（版面の padding-left で確保） */
    touch-action: none;
}
.qt-scrub:active { cursor: grabbing; }

/* 盤の外の操作（全部 44px 以上の矩形） */
.qt-dial-btns {
    display: flex;
    gap: 8px;
    margin-top: 10px;
}
.qt-dial-btns button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 52px;
    height: 36px;
    font-family: var(--qt-sans);
    font-size: 11px;
    letter-spacing: .04em;
    color: var(--qt-ink-gnd);
    background: none;
    border: 1px solid var(--qt-rule-gnd);
    cursor: pointer;
}
.qt-dial-btns button:hover { border-color: var(--qt-gold-deep); }

/* 「いま」はボタンである前に表示灯。
   ★ 塗るのは「追従中（ON）」のとき。以前は逆で、手で止めているときだけ
     金で塗っていた（戻り道を目立たせるつもり）が、塗られている方が
     ON に見えるのでちょうど逆に読めていた。
   押されている見た目は .qt-tier button[aria-pressed="true"] と揃える。
   点の明滅は .qt-live と同じ qt-breathe を使い回す（同じ状態を指すので
   別のリズムにしない）。動きを減らす設定のときは全称セレクタが止める */
.qt-now-btn::before {
    content: "";
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    border: 1px solid currentColor;
    border-radius: 50%;
}
:root:not([data-qt-manual]) .qt-now-btn {
    color: var(--qt-gold-deep);
    border-color: var(--qt-gold-deep);
    background: rgba(232, 176, 75, .18);
    box-shadow: inset 0 -2px 0 var(--qt-gold-deep);
    cursor: default;
}
:root:not([data-qt-manual]) .qt-now-btn::before {
    background: currentColor;
    animation: qt-breathe 2.4s ease-in-out infinite;
}

/* 描き込みの量。円周上に置かないので当たり判定は原理的に重ならない */
.qt-tier {
    display: flex;
    margin-top: 14px;
    border: 1px solid var(--qt-rule-gnd);
}
.qt-tier button {
    width: 60px;
    height: 44px;
    font-family: var(--qt-sans);
    font-size: 11px;
    letter-spacing: .08em;
    color: var(--qt-sub-gnd);
    background: none;
    border: 0;
    border-left: 1px solid var(--qt-rule-gnd);
    cursor: pointer;
}
.qt-tier button:first-child { border-left: 0; }
.qt-tier button[aria-pressed="true"] {
    color: var(--qt-gold-deep);
    box-shadow: inset 0 -2px 0 var(--qt-gold-deep);
}

/* 季節。描き込みの量と同じ形にして、計器がひと続きに見えるようにする */
.qt-season {
    display: flex;
    margin-top: 8px;
    border: 1px solid var(--qt-rule-gnd);
}
.qt-season button {
    width: 52px;
    height: 38px;
    font-family: var(--qt-sans);
    font-size: 12px;
    letter-spacing: .12em;
    color: var(--qt-sub-gnd);
    background: none;
    border: 0;
    border-left: 1px solid var(--qt-rule-gnd);
    cursor: pointer;
}
.qt-season button:first-child { border-left: 0; }
.qt-season button[aria-pressed="true"] {
    color: var(--qt-gold-deep);
    box-shadow: inset 0 -2px 0 var(--qt-gold-deep);
}

/* 詳細（ジェスチャが使えない人の確実な代替経路） */
/* ★ hidden 属性で出し入れしない。display の切り替えは補間できないので、
   ぱっと出てぱっと消えるだけになる。visibility なら
   （読み上げとタブ順から外したまま）位置と濃さを補間できる。 */
.qt-menu {
    position: absolute;
    left: 0;
    bottom: calc(100% + 8px);
    z-index: 20;
    min-width: 262px;
    max-width: min(320px, calc(100vw - 32px));
    max-height: min(520px, calc(100svh - 120px));
    overflow-y: auto;
    padding: 8px 0 10px;
    background: var(--qt-snow);
    border: 1px solid var(--qt-rule-gnd);
    box-shadow: 0 8px 28px rgba(22, 32, 60, .18);

    visibility: hidden;
    opacity: 0;
    transform: translateY(18px);
    transition:
        opacity .2s var(--qt-ease),
        transform .34s var(--qt-ease),
        visibility 0s linear .34s;
}
.qt-menu[data-open="true"] {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity .2s var(--qt-ease),
        transform .34s var(--qt-ease),
        visibility 0s;
}
.qt-menu-h {
    margin: 6px 0 2px;
    padding: 0 14px;
    font-family: var(--qt-mono);
    font-size: 9px;
    letter-spacing: .22em;
    color: var(--qt-sub-gnd);
}
/* 選択肢はチップで並べる。縦のリストだと 19 行 = 800px を超えて
   スマホの画面に収まらない。
   ★ flex + flex:1 1 0 で「残り幅を等分」にしないこと。選択肢が 4 つの節
     （描き込みの量）だけチップが広くなり、各節の 1 つめ——「いま」「自動」
     「実測」——の文字が縦に揃わなくなる。列数を 5 に固定して、
     どの節も同じ位置に列が来るようにする（4 つの節は右が 1 つ空く）。 */
.qt-menu-g {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 5px;
    padding: 0 12px 4px;
}
/* 選択肢が 5 つに満たない節（描き込みの量 4 つ・画面 3 つ）は右が空く。
   幅いっぱいに引き伸ばして埋めないこと。埋めた瞬間に列が揃わなくなり、
   もとの不具合に戻る。空けておくほうが「同じ列に同じ役割」が読める */
.qt-menu button,
.qt-menu .qt-menu-go {
    /* button の既定の中央寄せに任せず、明示して <a>/<span> と挙動を揃える */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 40px;
    padding: 0 4px;
    font-family: var(--qt-sans);
    font-size: 12.5px;
    letter-spacing: .02em;
    /* ★ 折り返さない。1 つ（「くもり」）だけ 2 行になると、その節の文字の
       縦位置だけ他とずれる。日本語は既定で字と字の間どこでも折れるので、
       keep-all も併記して二重に止める */
    white-space: nowrap;
    word-break: keep-all;
    color: var(--qt-ink-gnd);
    background: none;
    border: 1px solid var(--qt-rule-gnd);
    cursor: pointer;
}
.qt-menu button:hover { background: var(--qt-snow-shade); }
/* 画面の切替。
   ★ 以前はここだけ言い方が逆だった。行き先の 2 つ（6幕・カード）に金の枠と
     地を敷き、いま開いている画面を破線＋■ にしていたので、押されている方が
     反対に見えていた。他の節と同じ語彙に揃える——
     選べるものは素の枠、いまのものは金の字＋金の枠＋下線。
     ■ も外す。中身が 1 字ぶん右へ寄って、文字が中心から 8px ずれていた。 */
.qt-menu-go {
    text-align: center;
    text-decoration: none;
}
.qt-menu .qt-menu-go:hover,
.qt-menu .qt-menu-go:focus-visible { background: var(--qt-snow-shade); border-color: var(--qt-gold-deep); }
/* ★ 基底が「.qt-menu .qt-menu-go」なので、ここも 2 つ以上の class で書くこと。
   .qt-menu-here だけだと color と border-color が基底に負ける */
.qt-menu .qt-menu-here,
.qt-menu .qt-menu-here:hover {
    color: var(--qt-gold-deep);
    border-color: var(--qt-gold-deep);
    background: none;
    box-shadow: inset 0 -2px 0 var(--qt-gold-deep);
    cursor: default;
}

/* 閉じるは選択肢ではないので、印を付けず幅いっぱいに */
.qt-menu-close { grid-template-columns: 1fr; margin-top: 4px; padding-top: 8px; border-top: 1px solid var(--qt-rule-gnd-soft); }
.qt-menu-close button { color: var(--qt-sub-gnd); }
.qt-menu-close button[aria-pressed] { box-shadow: none; }

.qt-menu button[aria-pressed="true"] {
    color: var(--qt-gold-deep);
    border-color: var(--qt-gold-deep);
    box-shadow: inset 0 -2px 0 var(--qt-gold-deep);
}

/* =====================================================================
   10. 右の縦アイコン列
   ホバーは引き出し線（leader line）。ツールチップにしない。
   この画面に塗りの箱は1つも無い
   ===================================================================== */
.qt-rail {
    position: relative;
    z-index: 5;
    width: var(--qt-rail-w);
    /* ITEMS が8つ目・9つ目に増えても溢れない */
    max-height: min(420px, calc(52svh - 56px));
    overflow-y: auto;
    overscroll-behavior: contain;
}
.qt-rail ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
.qt-rail ul + ul {
    margin-top: 5px;
    padding-top: 5px;
    /* グループの区切り。幅14px の罫（見出しの装飾ではなく区切り） */
    background: linear-gradient(to right, var(--qt-rule-sky) 14px, transparent 14px) no-repeat top left / 14px 1px;
}
.qt-rail li { min-height: 44px; margin-bottom: 3px; }

/* ★ 札は常に出しておくこと。
   最初はアイコンだけを並べてホバーで札を出していたが、
   「何のボタンか分からない」「目立たなすぎる」ので常時表示にした。
   ホバーの引き出し線は残して、指す動きだけを演出として使う。 */
.qt-rail a {
    position: relative;
    display: grid;
    grid-template-columns: 22px 1fr;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 44px;
    padding: 5px 8px 5px 10px;
    text-decoration: none;
    color: var(--qt-ink-sky);
    border-left: 2px solid transparent;
    transition: border-color .18s ease-out, background-color .18s ease-out;
}
.qt-rail svg {
    /* ★ 位置を明示すること。.qt-lead が absolute でグリッドから抜けるため、
       自動配置に任せると「札が 22px の列、アイコンが札の列」と逆に入り、
       札が 1 文字ずつ縦に折り返す（実際にそうなった） */
    grid-column: 1;
    grid-row: 1;
    width: 22px;
    height: 22px;
    opacity: .9;
    transition: opacity .18s ease-out, transform .18s ease-out, color .18s ease-out;
}

/* 金の1px線。項目の左外へ 0 → 30px 伸びて「ここ」を指す */
.qt-lead {
    position: absolute;
    right: 100%;
    top: 50%;
    width: 0;
    height: 1px;
    background: var(--qt-gold);
    transition: width .2s var(--qt-ease);
}
/* 札は常時表示。ホバーで色と位置だけ動く */
.qt-label {
    grid-column: 2;
    grid-row: 1;
    justify-self: start;
    font-size: 11.5px;
    letter-spacing: .04em;
    line-height: 1.35;
    /* ★ 折り返さない。「デザインシステ / ム」と割れると読みにくい */
    white-space: nowrap;
    color: var(--qt-ink-sky);
    opacity: .92;
    /* 背景を塗らずに、光で持ち上げる */
    text-shadow: 0 0 10px var(--qt-sky-top), 0 0 4px var(--qt-sky-top);
    transition: opacity .15s var(--qt-ease), transform .18s var(--qt-ease), color .18s ease-out;
}
.qt-num {
    margin-left: 6px;
    font-family: var(--qt-mono);
    font-size: 10px;
    font-style: normal;
    letter-spacing: .04em;
    color: var(--qt-sub-sky);
}
.qt-ext {
    display: block;
    font-size: 9px;
    font-style: normal;
    letter-spacing: .04em;
    color: var(--qt-sub-sky);
}

/* ホバー・フォーカス・フォーカス内包の3つに同内容を当てる。
   キーボードだけでも同じ表現が出ること */
.qt-rail a:hover .qt-lead,
.qt-rail a:focus-visible .qt-lead,
.qt-rail li:focus-within .qt-lead { width: 30px; }

.qt-rail a:hover,
.qt-rail a:focus-visible,
.qt-rail li:focus-within a {
    border-left-color: var(--qt-gold);
    background: rgba(232, 176, 75, .10);
}
.qt-rail a:hover .qt-label,
.qt-rail a:focus-visible .qt-label,
.qt-rail li:focus-within .qt-label { opacity: 1; color: var(--qt-gold); transform: translateX(2px); }

.qt-rail a:hover svg,
.qt-rail a:focus-visible svg,
.qt-rail li:focus-within svg { opacity: 1; color: var(--qt-gold); transform: translateX(1px); }

/* レール全体に触れると、全項目の線が少しだけ伸びる（ここに何かある、の予告） */
.qt-rail:hover .qt-lead { width: 10px; }
.qt-rail:hover a:hover .qt-lead { width: 30px; }

/* ログインは二重罫の下 */
.qt-rail .qt-login {
    margin-top: 8px;
    padding-top: 8px;
    background:
        linear-gradient(to right, var(--qt-rule-sky) 14px, transparent 14px) no-repeat top left / 14px 1px,
        linear-gradient(to right, var(--qt-rule-sky) 14px, transparent 14px) no-repeat 0 3px / 14px 1px;
}

/* スマホでレールを畳むボタン。PC では出さない */
.qt-rail-btn {
    display: none;
    align-items: center;
    gap: 7px;
    height: 44px;
    padding: 0 13px 0 10px;
    font-family: var(--qt-sans);
    font-size: 12px;
    letter-spacing: .06em;
    color: var(--qt-ink-sky);
    background: rgba(14, 23, 48, .72);
    border: 1px solid var(--qt-gold);
    cursor: pointer;
}
.qt-rail-btn svg { width: 18px; height: 18px; flex: none; }
.qt-rail-btn[aria-expanded="true"] {
    background: var(--qt-gold);
    border-color: var(--qt-gold);
    color: #2A1B02;
}

/* タッチ端末ではホバー規則を1行も書かず、常時表示に倒す。
   preventDefault する主体を作らないので、iOS の
   「1回目のタップでラベル、2回目で遷移」が構造的に起きない */
@media (hover: none) {
    /* 触る端末ではカードを出さない。ホバーが無いので出す機会が
       「タップしてフォーカスが入った一瞬」しかなく、遷移の直前に
       下の計器へ被さるだけで読めない。行そのものがリンクなのでこれでよい */
    .qt-card { display: none; }

    .qt-rail a:hover, .qt-rail a:focus-visible, .qt-rail li:focus-within a {
        border-left-color: transparent;
        border-top-color: var(--qt-gold);
    }
    /* 触る端末にはホバーが無い＝アイコンが一生グレーのままになる。
       ここだけは本来の色に戻す（notes.css の .logo と同じ扱い） */
    .qt-now-i img { filter: none; }

    /* 指で押す的は 44px 以上。マウスのときは 36px / 38px のままでよい */
    .qt-dial-btns button { height: 44px; }
    .qt-season button { height: 44px; }
    .qt-rail { --qt-rail-w: 72px; width: 72px; }
    .qt-rail li { height: auto; min-height: 52px; margin-bottom: 2px; }
    .qt-rail a { grid-template-columns: 1fr; justify-items: center; align-content: center; gap: 3px;
                  padding: 4px 2px; height: auto; min-height: 52px; border-left: 0; border-top: 2px solid transparent; }
    .qt-rail svg { grid-column: 1; grid-row: 1; }
    .qt-rail .qt-label { grid-column: 1; grid-row: 2; justify-self: center; }
    .qt-lead { display: none; }
    .qt-label {
        position: static;
        transform: none;
        opacity: 1;
        font-size: 9px;
        line-height: 1.2;
        letter-spacing: .04em;
        text-align: center;
        white-space: normal;
    }
    .qt-rail svg { opacity: .85; }
    .qt-num, .qt-ext { display: block; margin: 0; }
}

/* =====================================================================
   11. 応答
   ===================================================================== */
@media (max-width: 899px) {
    /* =================================================================
       スマホは「ファーストビューに全部入れる」。
       ★ 実機は Safari のバーぶん画面が低い（375x667 の端末で見えるのは
         553px 前後）。svh をそのまま並べると溢れるので、空の高さを
         --qt-skyh 1 本にまとめ、clamp で下限と上限を決めて全部そこから引く。
       ★ 盤の外のバー（描き込みの量・季節）はここでは出さない。
         4 軸ぜんぶ「詳細」の中へ寄せてある（スマホではあれが唯一の入口）。
       ★ 読み値も削る。画面に出すのは「更新」「時間」「規約」だけ。
       ================================================================= */
    :root {
        --qt-dial: 96px;
        /* 空の高さ。版面も絵も全部これから引く。
           画面のおよそ半分まで見せて、ロゴ・メニュー・読み値はその上に重ねる。
           下限と上限を決めておかないと、低い端末で本文が押し出される */
        --qt-skyh: clamp(182px, 41svh, 310px);
    }

    /* 絵も本文と一緒に流す（fixed だと下へスクロールした本文が空に乗る） */
    .qt-scene { position: absolute; inset: 0; height: auto; }
    .qt-sky { inset: 0 0 auto 0; height: var(--qt-skyh); }
    .qt-orbit { inset: 0 0 auto 0; height: var(--qt-skyh); }
    .qt-haze { inset: 0 0 auto 0; height: var(--qt-skyh); }
    .qt-clouds { top: 2%; height: calc(var(--qt-skyh) * .5); }
    .qt-milky { height: calc(var(--qt-skyh) * .8); }
    .qt-stars { inset: 0 0 auto 0; height: calc(var(--qt-skyh) * .9); }
    .qt-glow { top: var(--qt-skyh); height: calc(var(--qt-skyh) * .55); }
    .qt-forest { top: calc(var(--qt-skyh) * .36); bottom: auto; height: calc(var(--qt-skyh) * .68); }
    /* 曲線だけを描き、その下は .qt-scene の地が受け持つ */
    .qt-ground { top: calc(var(--qt-skyh) * .86); bottom: auto; height: calc(var(--qt-skyh) * .45); }
    .qt-rail-scrim { display: none; }

    .qt-page {
        padding: 12px 14px 12px;
        column-gap: 12px;
        row-gap: 8px;
        grid-template-columns: 1fr auto;
        grid-template-rows: var(--qt-skyh) auto auto auto auto;
        /* 規約を時計の横に押し込むと 390px 幅で「利用規 / 約」と割れる。
           1 行ぶん使って、そのぶん空を少し詰めた */
        grid-template-areas:
            "head rail"
            "now  now"
            "list list"
            "dial dial"
            "meta meta";
    }
    .qt-head { align-self: start; }
    .qt-now { align-self: start; padding-top: 0; padding-left: 12px; }
    .qt-list, .qt-dial-wrap { margin-top: 0; }
    .qt-meta { align-self: end; justify-self: start; }

    /* ★ 案内は読み値の「下」へ回すこと。
       頭のブロックの先頭に置くと、その高さぶん読み値が下がって林の中に
       潜り、濃紺の文字が枝に重なって読めなくなる（実機で発生）。
       order で最後に送れば、ロゴと読み値はいつも空のいちばん上に居られる。 */
    .qt-head { display: flex; flex-direction: column; }
    .qt-banner {
        order: 9;
        margin: 12px 0 0;
        padding: 9px 10px 9px 12px;
        gap: 8px;
        /* 林の上に来るので、地を濃くして文字を守る */
        background: rgba(14, 23, 48, .88);
    }
    .qt-banner-text { font-size: 11.5px; }
    .qt-banner-hint { font-size: 10px; }
    .qt-banner-actions { gap: 6px; width: 100%; }
    .qt-banner-cta { min-height: 34px; padding: 0 11px; font-size: 11.5px; }
    .qt-banner-close { width: 34px; height: 34px; margin-left: auto; }

    /* 読み値を削る。空の上は「更新」と「時間」だけ。
       ★ :nth-child で数えないこと。ロゴを 1 つ足した瞬間に 1 つずつずれて、
         残したい行が消え、消したい行が残った（実際にそうなった）。中身で指す。 */
    .qt-head .qt-row:has([data-qt="repos"]),
    .qt-head .qt-row:has([data-qt="tier"]) { display: none; }
    /* 更新と時間は横に並べる */
    .qt-head .qt-row { display: inline-flex; margin: 0 14px 0 0; gap: 8px; }
    .qt-head .qt-k { font-size: 8.5px; letter-spacing: .18em; }
    .qt-head .qt-v { font-size: 10.5px; }
    /* 雪原の上は規約だけ（他は詳細を開けば分かる） */
    .qt-meta > .qt-row:not(#qt-sub) { display: none; }
    .qt-meta .qt-row { gap: 8px; }
    .qt-meta .qt-v { font-size: 10px; }

    /* 空の上に重ねる文字は、絵に負けないよう影で持ち上げる
       （面を塗らない。塗ると絵の上に箱が乗って一枚の窓でなくなる） */
    .qt-head .qt-k,
    .qt-head .qt-v,
    
    /* --- ロゴと戻る導線をコンパクトに ---------------------------------- */
    /* inline-flex のままだと読み値がロゴの横へ回り込む。
       行を切って、更新と時間を 1 行にそろえる */
    .qt-logo { display: flex; width: fit-content; margin: 0 0 8px -4px; padding: 3px 9px 3px 4px; gap: 7px; }
    .qt-logo img { width: 30px; height: 30px; }
    .qt-logo-x strong { font-size: 12.5px; }
    .qt-logo-x small { font-size: 10px; }
            
    /* --- 数字は説明と横に並べる（1 行ぶん節約） ------------------------- */
    .qt-now { display: flex; align-items: baseline; gap: 12px; }
    .qt-big { font-size: clamp(44px, 12.5vw, 58px); }
    .qt-big-cap { margin: 0; font-size: 10.5px; line-height: 1.6; }

    .qt-list h2 { margin-bottom: 2px; font-size: 10.5px; }
    .qt-now-list li > *:not(.qt-card) { min-height: 38px; gap: 9px; padding: 3px 2px; }
    /* ★ アイコンを縮めずに min-height だけ下げないこと。30px の札が
         行の高さを決めてしまい、4 行ぶんで雪原からはみ出す */
    .qt-now-i { width: 26px; height: 26px; border-radius: 7px; }
    .qt-now-i span { font-size: 12px; }
    .qt-now-t { font-size: 14.5px; }
    .qt-now-s { height: 20px; padding: 0 9px 0 8px; font-size: 9.5px; }
    .qt-now-s::before { width: 4px; height: 4px; margin-right: 6px; }

    /* 盤とボタンを横に。バー 2 段はここでは出さない */
    .qt-dial-wrap { display: flex; align-items: center; gap: 12px; padding-top: 0; }
    .qt-dial-btns { margin-top: 0; gap: 8px; }
    .qt-dial-btns button { width: 52px; height: 40px; }
    .qt-tier, .qt-season { display: none; }

    /* --- 右のメニューは畳んでおく。字は出さずアイコンだけ --------------- */
    .qt-rail-btn {
        display: inline-flex;
        justify-content: center;
        grid-area: rail;
        align-self: start;
        justify-self: end;
        width: 44px;
        height: 44px;
        padding: 0;
    }
    .qt-rail-btn span { display: none; }
    .qt-rail {
        position: absolute;
        top: 60px;
        right: 14px;
        z-index: 30;
        width: 186px;
        max-height: min(400px, calc(100svh - 120px));
        overflow-y: auto;
        padding: 5px;
        background: rgba(14, 23, 48, .96);
        border: 1px solid var(--qt-gold);
        box-shadow: 0 14px 36px rgba(0, 0, 0, .38);
    }
    /* レールも同じ出し方。display の切り替えだと補間できない */
    .qt-rail {
        transform-origin: top right;
        transition:
            opacity .18s var(--qt-ease),
            transform .28s var(--qt-ease),
            visibility 0s;
    }
    :root[data-qt-rail="closed"] .qt-rail {
        visibility: hidden;
        opacity: 0;
        transform: translateY(-10px) scale(.98);
        transition:
            opacity .18s var(--qt-ease),
            transform .28s var(--qt-ease),
            visibility 0s linear .28s;
    }

    .qt-rail ul + ul {
        margin-top: 4px;
        padding-top: 4px;
        background: linear-gradient(to right, var(--qt-rule-sky) 20px, transparent 20px) no-repeat top left / 20px 1px;
    }
    .qt-rail li { min-height: 44px; margin-bottom: 1px; }
    /* 横並び 1 行。折り返さない */
    .qt-rail a {
        grid-template-columns: 22px 1fr;
        justify-items: start;
        align-items: center;
        gap: 10px;
        min-height: 44px;
        padding: 0 8px;
        border-left: 2px solid transparent;
        border-top: 0;
    }
    .qt-rail svg { grid-column: 1; grid-row: 1; }
    .qt-rail .qt-label {
        grid-column: 2;
        grid-row: 1;
        justify-self: start;
        font-size: 12.5px;
        letter-spacing: .04em;
        text-align: left;
        white-space: nowrap;
        text-shadow: none;
    }
    .qt-lead { display: none; }
    .qt-num { display: inline; }

    /* カードは出さない（ホバーが無く、出しても遷移の直前に被さるだけ） */
    .qt-card { display: none; }

    /* スマホの詳細は、盤の横の小さなポップアップではなく画面の下から出るシート。
       盤が画面の下のほうにあるので、その真上に出すと指で隠れる */
    .qt-menu {
        position: fixed;
        left: 12px;
        right: 12px;
        bottom: 12px;
        top: auto;
        min-width: 0;
        max-width: none;
        max-height: min(70svh, 460px);
        padding: 10px 0 12px;
        transform: translateY(calc(100% + 24px));
        box-shadow: 0 -10px 40px rgba(22, 32, 60, .26);
    }
    .qt-menu[data-open="true"] { transform: translateY(0); }
    .qt-menu-g { padding: 0 14px 6px; }
    .qt-menu button,
    .qt-menu .qt-menu-go { min-height: 44px; }
}

/* 横向きスマホ・縮めたウィンドウ。
   ★ ここでレイアウトを作り直さないこと。以前は position や display を
     丸ごと差し替えていて、@media (max-width:899px) の設計を後から
     上書きしていた（レールが absolute に戻らず、本文の下へ落ちていた）。
     いまは上のモバイル設計に乗せる「詰め」だけにする。 */
@media (max-width: 899px) and (max-height: 620px) {
    :root {
        --qt-dial: 84px;
        --qt-skyh: clamp(132px, 34svh, 190px);
    }
    .qt-page { padding: 10px 12px; row-gap: 8px; }
    .qt-big { font-size: clamp(38px, 11vw, 50px); }
    .qt-now-list li > *:not(.qt-card) { min-height: 32px; gap: 8px; padding: 2px; }
    .qt-now-i { width: 22px; height: 22px; border-radius: 6px; }
    .qt-now-t { font-size: 13.5px; }
    .qt-now-s { height: 18px; font-size: 9px; }
    .qt-logo { margin-bottom: 5px; }
    }
/* =====================================================================
   12. 動きを減らす設定
   ★ duration だけでなく delay も潰すこと。design-system.css を読まないので
     ここが唯一の受け皿になる（delay を残すと「何も起きずに待たされる」）
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        animation-delay: 0.01ms !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .qt-motes { display: none !important; }
    .qt-stars .tw { animation: none !important; opacity: .8; }
    /* 操作そのものは殺さない。描き込みの量のボタンは押せるまま */
    /* home-quiet-events.js は起動時に window.PREFERS_REDUCED_MOTION を見て
       そもそも層を作らないが、OS設定がセッション中に変わった場合の保険として
       ここでも畳む（.qt-motes と同じ二重の保険） */
    .qt-ev-sky, .qt-ev-ground { display: none !important; }
}

/* スクラブ中は絵と数字を止める。
   指を動かしている間に巨大数字が再アニメーションしたり
   1.2s の色補間が追いかけてくると、盤が重く感じる */
:root[data-qt-scrub] *,
:root[data-qt-scrub] *::before,
:root[data-qt-scrub] *::after {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
    animation-play-state: paused !important;
}
:root[data-qt-scrub] .qt-hand { transition: none !important; }
/* 弧をなぞっている間も針は毎フレーム書き換えるので、CSS の補間は切る
   （残すと transition が毎フレーム再スタートして、針だけが遅れて付いてくる） */
:root[data-qt-tween] .qt-hand { transition: none !important; }
:root[data-qt-scrub] .qt-scrub { cursor: grabbing; }

/* =====================================================================
   13. ランダムイベント（人・動物・木・流れ星・宇宙船）
   ---------------------------------------------------------------------
   home-quiet-events.js が実行時に生成・破棄する層。quiet.html の絵には
   1行も手を入れない（.qt-scene の子として insertBefore で差し込む）。

   ★ ここだけは translate / scale を transform の代わりに独立プロパティとして
     使う。理由: 1要素に「横断」「上下ボブ」「向きの反転」を同時に乗せたいが、
     transform に2本の @keyframes を重ねると後勝ちで片方が消える（上の
     qt-p/qt-p-i の実装コメントが警告している落とし穴と同じ）。
     translate（位置）・scale（向き）・opacity はそれぞれ独立した CSS
     プロパティなので、別々の animation 宣言を1つの要素に積んでも競合しない。
   ★ 色は新しい変数を増やさず --qt-tree-near 等の既存 @property を使う。
     時刻ダイヤルを動かしている最中でも自動で色が追従する。
   ===================================================================== */
:root[data-qt-tier="off"] .qt-ev-sky,
:root[data-qt-tier="off"] .qt-ev-ground { display: none; }

/* ★ UFO・牛・ビームも専用の全画面レイヤーを別に作らず、この2つに同居させる
   （UFOは.qt-ev-sky、牛とビームは.qt-ev-ground）。全画面 inset:0 の第3の
   レイヤーを作ると、.qt-scene の高さの基準がデスクトップ(fixed)とモバイル
   (absolute;height:auto)で違うことを3箇所で別々に合わせる羽目になり、
   実機確認で牛だけ地平線からビューポート最下端までずれる不具合を踏んだ。
   既に時間帯問わず正しく地平線に合っている .qt-ev-ground に乗せれば、
   その補正を1箇所書くだけで済む。 */
.qt-ev-sky {
    position: absolute;
    inset: 0 0 42% 0;
    overflow: hidden;
    pointer-events: none;
}
.qt-ev-ground {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 38%;
    height: 1px;
    overflow: visible;
    pointer-events: none;
}

/* --- 歩く人・走る動物。.qt-ev-ground の地平線を足元の基準にする --- */
.qt-ev-mover {
    position: absolute;
    bottom: 0;
    left: calc(var(--ev-x0, 0) * 1px);
    animation: qt-ev-cross var(--ev-dur, 16s) linear forwards;
}
@keyframes qt-ev-cross {
    from { left: calc(var(--ev-x0, 0) * 1px); }
    to   { left: calc(var(--ev-x1, 0) * 1px); }
}
.qt-ev-mover .qt-ev-bob {
    display: block;
    animation: qt-ev-bob var(--ev-bob-dur, .55s) ease-in-out infinite;
}
@keyframes qt-ev-bob {
    0%, 100% { translate: 0 0; }
    50%      { translate: 0 -2px; }
}
.qt-ev-walker .qt-ev-bob { fill: none; stroke: var(--qt-tree-near); stroke-width: 2.4; stroke-linecap: round; }
.qt-ev-critter .qt-ev-bob { fill: var(--qt-tree-mid); }

/* --- 読書するビネット。横移動はせず、その場でポップイン→ゆるい呼吸→フェード --- */
.qt-ev-reader {
    position: absolute;
    bottom: 0;
    opacity: 0;
    scale: .82;
    animation: qt-ev-reader-in .6s var(--qt-ease) forwards;
}
.qt-ev-reader.is-leaving { animation: qt-ev-reader-out 1s ease forwards; }
.qt-ev-reader .qt-ev-bob { animation: qt-ev-bob 3.4s ease-in-out .6s infinite; }
@keyframes qt-ev-reader-in { to { opacity: 1; scale: 1; } }
@keyframes qt-ev-reader-out { to { opacity: 0; } }
.qt-ev-reader-art { fill: none; stroke: var(--qt-tree-near); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.qt-ev-reader-book { fill: var(--qt-tree-near); stroke: none; }

/* --- 木が育つ。既存の .qt-trunk / .qt-leaf に一時的に乗せるだけ --- */
.qt-ev-grow {
    animation: qt-ev-treepop 2s var(--qt-ease);
    transform-box: fill-box;
    transform-origin: 50% 100%;
}
@keyframes qt-ev-treepop {
    0%   { scale: 1; }
    55%  { scale: 1.16; }
    100% { scale: 1; }
}

/* --- 流れ星。.qt-ev-sky の中を対角線に駆け抜ける光の帯 --- */
.qt-ev-star {
    position: absolute;
    width: 86px;
    height: 2px;
    left: calc(var(--ev-x0, 0) * 1px);
    top: calc(var(--ev-y0, 0) * 1px);
    background: linear-gradient(to right, transparent, var(--qt-paper));
    border-radius: 2px;
    opacity: 0;
    transform-origin: 0 50%;
    animation: qt-ev-shoot var(--ev-dur, 1.2s) ease-in forwards;
}
@keyframes qt-ev-shoot {
    0%   { opacity: 0; translate: 0 0; }
    8%   { opacity: 1; }
    92%  { opacity: 1; }
    100% { opacity: 0; translate: var(--ev-dx, 220px) var(--ev-dy, 140px); }
}

/* --- 宇宙船が牛を連れ去る。JS が setTimeout でフェーズクラスを切り替え、
       ここは transition で緩急だけを持つ（paintSky と同じ役割分担）。
       ★ UFOは.qt-ev-sky、牛とビームは.qt-ev-groundの子として追加する
       （専用の全画面レイヤーを別に持たない。理由は上の.qt-ev-groundの
       コメント参照）。だから top/bottom は「その親レイヤーの中での位置」
       であり、.qt-ev-mover と同じ考え方で揃う。 --- */
.qt-ev-ufo {
    position: absolute;
    top: 14%;
    width: 72px;
    height: 30px;
    margin: -15px 0 0 -36px;
    left: var(--ev-ufo-x, -12%);
    opacity: 0;
    transition: left 2s var(--qt-ease), opacity 1.1s ease, translate .5s ease-in-out;
}
.qt-ev-ufo.is-arriving,
.qt-ev-ufo.is-hover,
.qt-ev-ufo.is-beaming,
.qt-ev-ufo.is-rising { opacity: 1; left: var(--ev-ufo-stop, 46%); }
.qt-ev-ufo.is-hover,
.qt-ev-ufo.is-beaming,
.qt-ev-ufo.is-rising { translate: 0 -3px; }
.qt-ev-ufo.is-departing { opacity: 0; left: var(--ev-ufo-exit, 112%); translate: 0 0; }
.qt-ev-ufo-body { fill: var(--qt-sub-sky); }
.qt-ev-ufo-dome { fill: url(#qt-sun-disc); opacity: .9; }
.qt-ev-ufo-light { fill: var(--qt-gold); opacity: .85; }

/* 牛とビームは .qt-ev-ground（地平線に揃えてある1pxの帯）の子。
   .qt-ev-mover と同じく bottom:0 が足元＝地平線になる。
   --ev-rise は「牛が昇る距離／ビームの長さ」を、UFO と地平線の実測ギャップ
   から home-quiet-events.js が計算して入れる（画面の高さやモバイルの
   レイアウトでギャップが変わるため、固定pxでは合わない）。 */
.qt-ev-cow {
    position: absolute;
    bottom: 0;
    left: var(--ev-cow-x, 46%);
    opacity: 0;
    scale: .85;
    transition: opacity .8s ease, scale .8s ease, translate 2.4s var(--qt-ease);
}
.qt-ev-cow.is-shown { opacity: 1; scale: 1; }
.qt-ev-cow.is-rising { translate: 0 calc(var(--ev-rise, 168) * -1px); scale: .4; opacity: 0; }
.qt-ev-cow-body { fill: var(--qt-paper); }
.qt-ev-cow-spot { fill: var(--qt-tree-far); opacity: .7; }

.qt-ev-beam {
    position: absolute;
    bottom: 0;
    left: var(--ev-cow-x, 46%);
    width: 70px;
    height: 0;
    margin-left: -35px;
    clip-path: polygon(44% 100%, 56% 100%, 100% 0, 0 0);
    background: linear-gradient(to top, rgba(232, 176, 75, .5), rgba(232, 176, 75, 0));
    opacity: 0;
    transition: opacity 1s ease, height 2.3s var(--qt-ease);
}
.qt-ev-beam.is-on { opacity: 1; height: calc(var(--ev-rise, 150) * 1px); }
.qt-ev-beam.is-off { opacity: 0; }

@media (max-width: 899px) {
    .qt-ev-sky { inset: 0 0 auto 0; height: var(--qt-skyh); }
    .qt-ev-ground { bottom: auto; top: calc(var(--qt-skyh) * .98); }
}

