diff --git a/.htaccess b/.htaccess index 36b3f0a..fc13343 100644 --- a/.htaccess +++ b/.htaccess @@ -15,8 +15,13 @@ Header set Pragma "no-cache" Header set Expires "0" + + Header set Cache-Control "no-cache, no-store, must-revalidate" + Header set Pragma "no-cache" + Header set Expires "0" + - Header set Cache-Control "public, max-age=2592000" + Header set Cache-Control "public, max-age=2592000, immutable" diff --git a/PATCH_NOTES.md b/PATCH_NOTES.md index 938feeb..b705442 100644 --- a/PATCH_NOTES.md +++ b/PATCH_NOTES.md @@ -1,8 +1,12 @@ -## 15.9.2 修正 -- 巣箱アイコンとゲーム内描画から、枠内の明色・透過っぽく見える装飾を除去。 -- アリのHPバーを、たりないと同様にダメージ直後だけ表示する方式へ変更。 -- 道具UIに「げんこつ」を追加。添付画像から正義げんこつ部分を切り抜き、上から落下してたりない・アリにダメージと吹っ飛びを与える効果を追加。 -- 初期ロード画面と読み込み進捗バーを追加。JS/CSSをdefer化し、CSS/JSのサーバーキャッシュを有効化して再訪問時の通信量を削減。 +## 15.15.0 + +- 巨大ファイル分割を実施。 +- `world.js` をコアクラス、視点/家系/戦闘/環境/空間管理/アリ/更新/配置ログ/ブートストラップに分割。 +- `tarinai.js` をコアクラス、人格・関係、病気・巣箱、欲求・アイテム、社会/移動/寿命、描画に分割。 +- `ui.js` を状態、ログ、選択詳細、レイアウト/ダイアログ、道具、イベント束縛に分割。 +- `ui_family.js` をデータ、非同期構築、レイアウト、パス生成、描画に分割。 +- 既存グローバルAPI互換を維持し、挙動変更を避ける形で分割。 +- Service Workerキャッシュと静的アセットバージョンを `15.15.0` に更新。 ## 15.9.1 修正 @@ -67,3 +71,78 @@ - Removed the separate ant corpse sprite asset. Ant corpses now render by flipping the worker ant sprite vertically and remain stationary while decaying. - Added shared ant damage handling for firecracker explosions and dropped-object impacts. - Kept ant worker HP in the nest worker pool so damaged workers remain damaged after returning to and leaving the nest. + + +## 15.11.0 +- イベントUI下部にログ種別別のプッシュ通知設定を追加。ON時は左下最前面に通知表示 +- 巣がなくなったアリは空きのある別巣へ所属変更。空き巣がない場合は死亡せず彷徨う +- 女王アリを大きめに表示 +- 画像アセットをWebP化し、参照をWebPへ切り替え +- Service Workerによる静的アセットキャッシュを追加し、indexのno-cache指定を解除 + +## 15.12.0 +- 優先度S/A/B相当の効果音イベントを追加。未指定音源はWeb Audioの仮SEで再生。 +- 効果音カテゴリを「たりないの声」「通知」「操作」に分類し、イベントUI下部から個別ON/OFF可能にした。 +- 音素材差し替え用の安定IDを `docs/SOUND_IDS.md` に整理。 +- げんこつ、爆竹、喧嘩、ダメージ、死亡、誕生、アリ、病気、回復、水、草、zunchi、UI操作などに音フックを追加。 + + +## 15.12.3 +- プッシュ通知の保存キーを更新し、初期状態はOFFに戻した。 +- 効果音設定は右上の音設定で、操作音・通知音のみデフォルトON、たりないの声はデフォルトOFFに変更。 +- 操作音と通知音の内蔵仮SE音量を大幅に増加。 +- つまむ操作でたりないデータカードが開く挙動を修正。 +- 道具から配置する全オブジェクトで配置音が鳴るよう、placeItem側に配置音を統合。 +- イベントUI折り畳み時の高さを圧縮。 + + +## 15.12.4 +- 効果音の仮SE音量を再度引き上げ。 +- イベントUI内の効果音設定を廃止し、右上の音設定メニューへ統一。 +- イベントログ欄が上下端に達した時、右メニュー全体へスクロールを受け渡すよう修正。 + +## 15.15.0 +- バージョン/キャッシュ管理を `js/version.js` と `service-worker.js` に統一。 +- Service Worker登録を `updateViaCache: "none"` に変更し、`.htaccess` でService Worker本体をno-cache化。 +- `js/event_bus.js` を追加し、ログ/フェーズ/配置/地形dirty/FPS変化などをイベント化。 +- `js/performance_manager.js` を追加し、FPSレベル、アリ更新間引き、エフェクト上限、統計更新間隔、地形再描画間隔を中央管理。 +- 地面キャッシュを全走査ハッシュ方式から `terrainVersion` dirty方式へ変更。 +- SpatialGridをアリ/障害物/食料/危険物セルに拡張。 +- `?debug=1` の内部デバッグオーバーレイを追加。 +- 音システムに音ID別ゲイン、音ID別最小間隔、同時発音上限、サンプル読み込み失敗イベントを追加。 + +## v15.15.0 +- 個体パラメータ変化アイテムを追加: 下剤、プロテイン、ンイテロプ、弾薬、怪しい薬。 +- 下剤: 効果時間中3秒ごとにずんちを放出し、食事で空腹度が下がらない。 +- プロテイン/ンイテロプ: 永続の与ダメージ・病気発症確率補正を追加。両者は排他で、最後に食べたものだけ有効。 +- 弾薬: 効果時間中の歩行速度10倍と、移動中のたりない/アリ衝突ノックバックを追加。 +- 怪しい薬: 行動変容アイテム効果と病気の中からランダム2種を付与。 +- たりないデータに「現在のアイテム効果」を追加。 +- バージョンとService Workerキャッシュを15.15.0に更新。 + +## v15.18.0 +- Implemented static `app_manifest.json` and `scripts/generate_app_files.py` for HTML/Service Worker static-list synchronization. +- Split `css/styles.css` into ordered CSS files while keeping a compatibility shim. +- Added `js/effect_registry.js` and routed item-effect labels/colors/random pools/selected display text through the registry. +- Added `js/sound_pack.js`; `audio.js` now consumes sound pack gains, cooldowns, and sample paths. +- Added mobile canvas input modes: 自動 / カメラ / 道具 / 家系図. +- Expanded debug overlay with Service Worker/cache/audio/effect diagnostics. +- Added dedicated tool icons for 下剤, プロテイン, ンイテロプ, 弾薬, 怪しい薬, 水銀, 巨大薬, 矮小薬, ずんだ汁. + +## v15.19.1 +- 効果音のマスター出力、カテゴリ別ゲイン、ID別ゲインを再調整。連続再生で小さくなりにくいよう同時発音上限とWeb Audio出力経路を変更。 +- 食べ物の自然消耗を連続減少から半日に2回程度の離散消耗へ変更。衛生統計ペナルティも同じタイミングに抑制。 +- 薬系アイテムの地面表示とUIアイコンを錠剤風に変更。 +- プロテイン/ンイテロプの外観を山盛りの粉に変更。永続効果中は継続的なオーラ/粒子エフェクトを表示。 +- ずんだ汁を緑の水滴外観へ変更。雨と水滴表示は灰色寄りへ変更。 +- バージョンとService Workerキャッシュを 15.19.1 に更新。 + + +## v15.19.1 +- Removed embedded letters/sub-labels from new item sprites and tool icons. +- Refreshed parameter item UI icons; cache-busted updated icon URLs. +- Fixed firecracker placement triggering explosion sound through accident log inference. +- Made giant drug placed sprite larger and dwarf drug placed sprite smaller. +- Redrew mercury, zunda juice, and water as rain-drop style sprites. +- Changed protein/niteropu persistent visuals to red rising particles and purple falling particles. +- Fixed remaining colony chart tab label from 生活 to 精神. diff --git a/README.md b/README.md index 69725d1..2431355 100644 --- a/README.md +++ b/README.md @@ -49,11 +49,30 @@ js/render.js Background, weather, lighting, HUD, global canvas render. js/sim_core.js Names, personalities, relationships, effects, spatial grid. js/health.js Damage memory, death-cause normalization, damage application. js/items.js Item state, lifecycle, drawing, grass/zunchi/ball/firecracker logic. -js/tarinai.js Agent state, AI, disease state, eating, conflict, reproduction, draw. -js/world.js World update, placement, weather, logs, global interactions. -js/ui.js Input, tool selection, dialogs, observation panel. -js/ui_charts.js Population/statistics charts. -js/ui_family.js Family/archive UI and cause-of-death display. +js/tarinai.js Tarinai constructor/core state only. +js/tarinai_identity_social.js Agent identity, records, personality, relations, stress/damage wrappers. +js/tarinai_disease_nest.js Diseases, water effects, nest-box entry/exit. +js/tarinai_needs_items.js Needs AI, eating/drinking, item interaction, facing, zunchi behavior. +js/tarinai_social_move_life.js Social interaction, movement, life/death. +js/tarinai_render.js Agent drawing and hit testing. +js/world.js World constructor/core state only. +js/world_view.js Field scale, camera, viewport, tool sizing, time/phase helpers. +js/world_family_social.js Family tree, birth, fights, social conflict entry points. +js/world_combat_effects.js Damage, explosions, water hose, effects, balls, collision outcomes. +js/world_environment.js Obstacles, fences, grass placement, temperature, nearest queries. +js/world_spatial_budget.js Spatial grid, draw list, budgets, compaction, performance helpers. +js/world_ants_system.js Ant updates, nest haul/founding, queen spawning. +js/world_update.js Main world update, weather, out-of-bounds sanitation, pointer info. +js/world_placement_log.js Placement, click handling, log classification/dispatch. +js/world_bootstrap.js Creates global `world` after World mixins load. +js/ui.js UI state/cache references only. +js/ui_log.js Log rendering, push notification controls, sound setting sync. +js/ui_selected.js Selected Tarinai data panel and text formatting. +js/ui_layout_dialogs.js Canvas resize, dialogs, field switching, top buttons. +js/ui_tools.js Tool size badges and tool size cycling. +js/ui_bind.js Event listeners and input binding. +js/ui_charts.js Population/statistics charts. +js/ui_family*.js Family/archive data, async build, layout, paths, render. docs/AI_CONTEXT.md Minimal implementation context for AI edits. docs/code_map.md Symbol-to-file lookup table. ``` @@ -77,3 +96,61 @@ docs/code_map.md Symbol-to-file lookup table. - \u5de3\u7bb1\u5165\u9000\u5ba4\u3092\u5c02\u7528\u72b6\u614b\u5316\u3057\u3001\u900f\u660e\u5316\u30fb\u5f53\u305f\u308a\u5224\u5b9a\u6d88\u6ec5\u30fb\u500b\u4f53\u6570\u53cd\u6620\u30fb\u9000\u51fa\u5fa9\u5e30\u3092\u5b89\u5b9a\u5316\u3002 - \u7761\u7720\u6642\u306e\u512a\u5148\u9806\u4f4d\u3092\u300c\u5de3\u7bb1 \u2192 \u5e72\u3057\u8349\u30d9\u30c3\u30c9 \u2192 \u305d\u306e\u5834\u300d\u306b\u5909\u66f4\u3002 - \u305f\u308a\u306a\u3044\u30c7\u30fc\u30bfUI\u306e\u53cb\u9054/\u6575\u5bfe\u3092\u5168\u4ef6\u30c1\u30c3\u30d7\u8868\u793a\u306b\u3057\u3001\u30af\u30ea\u30c3\u30af\u3067\u500b\u4f53\u3078\u79fb\u52d5\u3067\u304d\u308b\u3088\u3046\u306b\u5909\u66f4\u3002 + + +## 15.18.0 +- イベントUI下部にログ種別別のプッシュ通知設定を追加。ON時は左下最前面に通知表示 +- 巣がなくなったアリは空きのある別巣へ所属変更。空き巣がない場合は死亡せず彷徨う +- 女王アリを大きめに表示 +- 画像アセットをWebP化し、参照をWebPへ切り替え +- Service Workerによる静的アセットキャッシュを追加し、indexのno-cache指定を解除 + +### 効果音差し替え +v15.18.0以降、`js/audio.js` の `samplePaths` に `sfx_genkotsu_impact` などの音IDとファイルパスを追加すると、内蔵の仮SEよりその音源が優先されます。ID一覧は `docs/SOUND_IDS.md` を参照してください。 + + +## 15.18.0 +- プッシュ通知の保存キーを更新し、初期状態はOFFに戻した。 +- 効果音設定は右上の音設定で、操作音・通知音のみデフォルトON、たりないの声はデフォルトOFFに変更。 +- 操作音と通知音の内蔵仮SE音量を大幅に増加。 +- つまむ操作でたりないデータカードが開く挙動を修正。 +- 道具から配置する全オブジェクトで配置音が鳴るよう、placeItem側に配置音を統合。 +- イベントUI折り畳み時の高さを圧縮。 + + +## 15.18.0 +- 効果音の仮SE音量を再度引き上げ。 +- イベントUI内の効果音設定を廃止し、右上の音設定メニューへ統一。 +- イベントログ欄が上下端に達した時、右メニュー全体へスクロールを受け渡すよう修正。 + +## 15.18.0 内部システム更新 +- バージョン/キャッシュ管理、イベントバス、PerformanceManager、地形dirtyキャッシュ、拡張SpatialGrid、デバッグモードを追加しました。 +- `?debug=1` をURLに付けるとFPS/負荷レベル/エンティティ数/イベント履歴を確認できます。 +- 詳細は `docs/INTERNAL_SYSTEMS.md` を参照してください。 + +### v15.18.0 個体効果アイテム +- 下剤、プロテイン、ンイテロプ、弾薬、怪しい薬を追加。 +- たりないデータの「現在のアイテム効果」で、永続効果と残り時間つき効果を確認できます。 + +### v15.18.0 internal maintenance +- Static loading order is centralized in `app_manifest.json`. +- Run `python3 scripts/generate_app_files.py` after adding/removing CSS or JS files. +- Sound replacement is centralized in `js/sound_pack.js`. +- Item/disease effect metadata is centralized in `js/effect_registry.js`. + +## v15.19.1 +- 効果音のマスター出力、カテゴリ別ゲイン、ID別ゲインを再調整。連続再生で小さくなりにくいよう同時発音上限とWeb Audio出力経路を変更。 +- 食べ物の自然消耗を連続減少から半日に2回程度の離散消耗へ変更。衛生統計ペナルティも同じタイミングに抑制。 +- 薬系アイテムの地面表示とUIアイコンを錠剤風に変更。 +- プロテイン/ンイテロプの外観を山盛りの粉に変更。永続効果中は継続的なオーラ/粒子エフェクトを表示。 +- ずんだ汁を緑の水滴外観へ変更。雨と水滴表示は灰色寄りへ変更。 +- バージョンとService Workerキャッシュを 15.19.1 に更新。 + + +### v15.19.1 +- 新アイテム系スプライト/道具アイコンから文字表示を削除。 +- 爆竹配置時に爆発音が鳴る問題を修正。 +- 巨大薬/矮小薬の設置サイズを視覚的に差別化。 +- 水銀/ずんだ汁/水滴を降雨の水滴表現に合わせて再描画。 +- プロテイン/ンイテロプの永続演出を粒子表現へ変更。 +- 統計タブの「生活」表記残りを「精神」に修正。 diff --git a/app_manifest.json b/app_manifest.json new file mode 100644 index 0000000..90e5ae8 --- /dev/null +++ b/app_manifest.json @@ -0,0 +1,67 @@ +{ + "version": "15.19.1", + "css": [ + "css/base.css", + "css/layout.css", + "css/panel.css", + "css/components.css", + "css/mobile.css" + ], + "js": [ + "js/version.js", + "js/event_bus.js", + "js/performance_manager.js", + "js/effect_registry.js", + "js/sound_pack.js", + "js/data.js", + "js/math.js", + "js/assets.js", + "js/audio.js", + "js/render.js", + "js/sim_core.js", + "js/items.js", + "js/ants.js", + "js/health.js", + "js/tarinai.js", + "js/tarinai_identity_social.js", + "js/tarinai_disease_nest.js", + "js/tarinai_item_effects.js", + "js/tarinai_needs_items.js", + "js/tarinai_social_move_life.js", + "js/tarinai_render.js", + "js/world.js", + "js/world_view.js", + "js/world_family_social.js", + "js/world_combat_effects.js", + "js/world_environment.js", + "js/world_spatial_budget.js", + "js/world_ants_system.js", + "js/world_update.js", + "js/world_placement_log.js", + "js/world_bootstrap.js", + "js/text_catalog.js", + "js/ui.js", + "js/ui_log.js", + "js/ui_selected.js", + "js/ui_layout_dialogs.js", + "js/ui_tools.js", + "js/ui_bind.js", + "js/ui_charts.js", + "js/ui_family.js", + "js/ui_family_data.js", + "js/ui_family_async.js", + "js/ui_family_layout.js", + "js/ui_family_paths.js", + "js/ui_family_render.js", + "js/main.js", + "js/debug_tools.js" + ], + "assetGlobs": [ + "assets/ui/*.webp", + "assets/objects/*.webp", + "assets/sprites/*.webp", + "assets/sounds/*.wav", + "assets/sounds/*.mp3" + ], + "notes": "Source of truth for static loading order; generated files are index.html script/link tags and service-worker.js cache list." +} diff --git a/assets/objects/ant_corpse.png b/assets/objects/ant_corpse.png deleted file mode 100644 index 2f19212..0000000 Binary files a/assets/objects/ant_corpse.png and /dev/null differ diff --git a/assets/objects/ant_corpse.webp b/assets/objects/ant_corpse.webp new file mode 100644 index 0000000..ec1fdc8 Binary files /dev/null and b/assets/objects/ant_corpse.webp differ diff --git a/assets/objects/ant_queen.png b/assets/objects/ant_queen.png deleted file mode 100644 index e26b998..0000000 Binary files a/assets/objects/ant_queen.png and /dev/null differ diff --git a/assets/objects/ant_queen.webp b/assets/objects/ant_queen.webp new file mode 100644 index 0000000..4ffcce9 Binary files /dev/null and b/assets/objects/ant_queen.webp differ diff --git a/assets/objects/ant_worker.png b/assets/objects/ant_worker.png deleted file mode 100644 index 59c0142..0000000 Binary files a/assets/objects/ant_worker.png and /dev/null differ diff --git a/assets/objects/ant_worker.webp b/assets/objects/ant_worker.webp new file mode 100644 index 0000000..3845cd8 Binary files /dev/null and b/assets/objects/ant_worker.webp differ diff --git a/assets/objects/ant_worker_mid.png b/assets/objects/ant_worker_mid.png deleted file mode 100644 index 226d40f..0000000 Binary files a/assets/objects/ant_worker_mid.png and /dev/null differ diff --git a/assets/objects/ant_worker_mid.webp b/assets/objects/ant_worker_mid.webp new file mode 100644 index 0000000..9423f5b Binary files /dev/null and b/assets/objects/ant_worker_mid.webp differ diff --git a/assets/objects/ant_worker_small.png b/assets/objects/ant_worker_small.png deleted file mode 100644 index 7f9b4c3..0000000 Binary files a/assets/objects/ant_worker_small.png and /dev/null differ diff --git a/assets/objects/ant_worker_small.webp b/assets/objects/ant_worker_small.webp new file mode 100644 index 0000000..2dde4c6 Binary files /dev/null and b/assets/objects/ant_worker_small.webp differ diff --git a/assets/objects/ant_worker_small_b.png b/assets/objects/ant_worker_small_b.png deleted file mode 100644 index 4653f4d..0000000 Binary files a/assets/objects/ant_worker_small_b.png and /dev/null differ diff --git a/assets/objects/ant_worker_small_b.webp b/assets/objects/ant_worker_small_b.webp new file mode 100644 index 0000000..734d40c Binary files /dev/null and b/assets/objects/ant_worker_small_b.webp differ diff --git a/assets/objects/genkotsu.png b/assets/objects/genkotsu.png deleted file mode 100644 index 8160368..0000000 Binary files a/assets/objects/genkotsu.png and /dev/null differ diff --git a/assets/objects/genkotsu.webp b/assets/objects/genkotsu.webp new file mode 100644 index 0000000..af7ff3b Binary files /dev/null and b/assets/objects/genkotsu.webp differ diff --git a/assets/objects/zunchi.png b/assets/objects/zunchi.png deleted file mode 100644 index 70a90d7..0000000 Binary files a/assets/objects/zunchi.png and /dev/null differ diff --git a/assets/objects/zunchi.webp b/assets/objects/zunchi.webp new file mode 100644 index 0000000..5e97dc6 Binary files /dev/null and b/assets/objects/zunchi.webp differ diff --git a/assets/objects/zunchi_02.png b/assets/objects/zunchi_02.png deleted file mode 100644 index a2c270d..0000000 Binary files a/assets/objects/zunchi_02.png and /dev/null differ diff --git a/assets/objects/zunchi_02.webp b/assets/objects/zunchi_02.webp new file mode 100644 index 0000000..73a377a Binary files /dev/null and b/assets/objects/zunchi_02.webp differ diff --git a/assets/sprites/tarinai_01_smile.png b/assets/sprites/tarinai_01_smile.png deleted file mode 100644 index 2c64d7c..0000000 Binary files a/assets/sprites/tarinai_01_smile.png and /dev/null differ diff --git a/assets/sprites/tarinai_01_smile.webp b/assets/sprites/tarinai_01_smile.webp new file mode 100644 index 0000000..bcaab40 Binary files /dev/null and b/assets/sprites/tarinai_01_smile.webp differ diff --git a/assets/sprites/tarinai_02_angry.png b/assets/sprites/tarinai_02_angry.png deleted file mode 100644 index 557b003..0000000 Binary files a/assets/sprites/tarinai_02_angry.png and /dev/null differ diff --git a/assets/sprites/tarinai_02_angry.webp b/assets/sprites/tarinai_02_angry.webp new file mode 100644 index 0000000..643c5ad Binary files /dev/null and b/assets/sprites/tarinai_02_angry.webp differ diff --git a/assets/sprites/tarinai_03_teary.png b/assets/sprites/tarinai_03_teary.png deleted file mode 100644 index bdd7bc5..0000000 Binary files a/assets/sprites/tarinai_03_teary.png and /dev/null differ diff --git a/assets/sprites/tarinai_03_teary.webp b/assets/sprites/tarinai_03_teary.webp new file mode 100644 index 0000000..85ecf3b Binary files /dev/null and b/assets/sprites/tarinai_03_teary.webp differ diff --git a/assets/sprites/tarinai_04_jito.png b/assets/sprites/tarinai_04_jito.png deleted file mode 100644 index 3cd4c57..0000000 Binary files a/assets/sprites/tarinai_04_jito.png and /dev/null differ diff --git a/assets/sprites/tarinai_04_jito.webp b/assets/sprites/tarinai_04_jito.webp new file mode 100644 index 0000000..068dd35 Binary files /dev/null and b/assets/sprites/tarinai_04_jito.webp differ diff --git a/assets/sprites/tarinai_05_drool.png b/assets/sprites/tarinai_05_drool.png deleted file mode 100644 index bbd9f12..0000000 Binary files a/assets/sprites/tarinai_05_drool.png and /dev/null differ diff --git a/assets/sprites/tarinai_05_drool.webp b/assets/sprites/tarinai_05_drool.webp new file mode 100644 index 0000000..b0cca44 Binary files /dev/null and b/assets/sprites/tarinai_05_drool.webp differ diff --git a/assets/sprites/tarinai_06_cry.png b/assets/sprites/tarinai_06_cry.png deleted file mode 100644 index 3f25d00..0000000 Binary files a/assets/sprites/tarinai_06_cry.png and /dev/null differ diff --git a/assets/sprites/tarinai_06_cry.webp b/assets/sprites/tarinai_06_cry.webp new file mode 100644 index 0000000..a823445 Binary files /dev/null and b/assets/sprites/tarinai_06_cry.webp differ diff --git a/assets/sprites/tarinai_07_sleep.png b/assets/sprites/tarinai_07_sleep.png deleted file mode 100644 index 48c44b2..0000000 Binary files a/assets/sprites/tarinai_07_sleep.png and /dev/null differ diff --git a/assets/sprites/tarinai_07_sleep.webp b/assets/sprites/tarinai_07_sleep.webp new file mode 100644 index 0000000..c378529 Binary files /dev/null and b/assets/sprites/tarinai_07_sleep.webp differ diff --git a/assets/sprites/tarinai_08_pokan.png b/assets/sprites/tarinai_08_pokan.png deleted file mode 100644 index 8c8a24b..0000000 Binary files a/assets/sprites/tarinai_08_pokan.png and /dev/null differ diff --git a/assets/sprites/tarinai_08_pokan.webp b/assets/sprites/tarinai_08_pokan.webp new file mode 100644 index 0000000..e1e6b2a Binary files /dev/null and b/assets/sprites/tarinai_08_pokan.webp differ diff --git a/assets/sprites/tarinai_09_stretch.png b/assets/sprites/tarinai_09_stretch.png deleted file mode 100644 index f6fe904..0000000 Binary files a/assets/sprites/tarinai_09_stretch.png and /dev/null differ diff --git a/assets/sprites/tarinai_09_stretch.webp b/assets/sprites/tarinai_09_stretch.webp new file mode 100644 index 0000000..c8a245b Binary files /dev/null and b/assets/sprites/tarinai_09_stretch.webp differ diff --git a/assets/sprites/tarinai_10_hurt.png b/assets/sprites/tarinai_10_hurt.png deleted file mode 100644 index 0598a61..0000000 Binary files a/assets/sprites/tarinai_10_hurt.png and /dev/null differ diff --git a/assets/sprites/tarinai_10_hurt.webp b/assets/sprites/tarinai_10_hurt.webp new file mode 100644 index 0000000..e53c759 Binary files /dev/null and b/assets/sprites/tarinai_10_hurt.webp differ diff --git a/assets/sprites/tarinai_11_weak.png b/assets/sprites/tarinai_11_weak.png deleted file mode 100644 index 9b27132..0000000 Binary files a/assets/sprites/tarinai_11_weak.png and /dev/null differ diff --git a/assets/sprites/tarinai_11_weak.webp b/assets/sprites/tarinai_11_weak.webp new file mode 100644 index 0000000..4a36e52 Binary files /dev/null and b/assets/sprites/tarinai_11_weak.webp differ diff --git a/assets/sprites/tarinai_12_back.png b/assets/sprites/tarinai_12_back.png deleted file mode 100644 index 4418fb0..0000000 Binary files a/assets/sprites/tarinai_12_back.png and /dev/null differ diff --git a/assets/sprites/tarinai_12_back.webp b/assets/sprites/tarinai_12_back.webp new file mode 100644 index 0000000..3a60bfb Binary files /dev/null and b/assets/sprites/tarinai_12_back.webp differ diff --git a/assets/sprites/tarinai_13_flee.png b/assets/sprites/tarinai_13_flee.png deleted file mode 100644 index d05bcb7..0000000 Binary files a/assets/sprites/tarinai_13_flee.png and /dev/null differ diff --git a/assets/sprites/tarinai_13_flee.webp b/assets/sprites/tarinai_13_flee.webp new file mode 100644 index 0000000..047449c Binary files /dev/null and b/assets/sprites/tarinai_13_flee.webp differ diff --git a/assets/sprites/tarinai_14_zunda_eat.png b/assets/sprites/tarinai_14_zunda_eat.png deleted file mode 100644 index 8e71ba0..0000000 Binary files a/assets/sprites/tarinai_14_zunda_eat.png and /dev/null differ diff --git a/assets/sprites/tarinai_14_zunda_eat.webp b/assets/sprites/tarinai_14_zunda_eat.webp new file mode 100644 index 0000000..06c956b Binary files /dev/null and b/assets/sprites/tarinai_14_zunda_eat.webp differ diff --git a/assets/sprites/tarinai_15_hurt2.png b/assets/sprites/tarinai_15_hurt2.png deleted file mode 100644 index b92d10e..0000000 Binary files a/assets/sprites/tarinai_15_hurt2.png and /dev/null differ diff --git a/assets/sprites/tarinai_15_hurt2.webp b/assets/sprites/tarinai_15_hurt2.webp new file mode 100644 index 0000000..a79cf25 Binary files /dev/null and b/assets/sprites/tarinai_15_hurt2.webp differ diff --git a/assets/sprites/tarinai_16_normal_smirk.png b/assets/sprites/tarinai_16_normal_smirk.png deleted file mode 100644 index 73e343a..0000000 Binary files a/assets/sprites/tarinai_16_normal_smirk.png and /dev/null differ diff --git a/assets/sprites/tarinai_16_normal_smirk.webp b/assets/sprites/tarinai_16_normal_smirk.webp new file mode 100644 index 0000000..4029f70 Binary files /dev/null and b/assets/sprites/tarinai_16_normal_smirk.webp differ diff --git a/assets/sprites/tarinai_17_normal_tongue.png b/assets/sprites/tarinai_17_normal_tongue.png deleted file mode 100644 index 5edf621..0000000 Binary files a/assets/sprites/tarinai_17_normal_tongue.png and /dev/null differ diff --git a/assets/sprites/tarinai_17_normal_tongue.webp b/assets/sprites/tarinai_17_normal_tongue.webp new file mode 100644 index 0000000..8623cec Binary files /dev/null and b/assets/sprites/tarinai_17_normal_tongue.webp differ diff --git a/assets/sprites/tarinai_18_fear.png b/assets/sprites/tarinai_18_fear.png deleted file mode 100644 index aa04096..0000000 Binary files a/assets/sprites/tarinai_18_fear.png and /dev/null differ diff --git a/assets/sprites/tarinai_18_fear.webp b/assets/sprites/tarinai_18_fear.webp new file mode 100644 index 0000000..245190b Binary files /dev/null and b/assets/sprites/tarinai_18_fear.webp differ diff --git a/assets/sprites/tarinai_19_flee_fear2.png b/assets/sprites/tarinai_19_flee_fear2.png deleted file mode 100644 index dddfb4b..0000000 Binary files a/assets/sprites/tarinai_19_flee_fear2.png and /dev/null differ diff --git a/assets/sprites/tarinai_19_flee_fear2.webp b/assets/sprites/tarinai_19_flee_fear2.webp new file mode 100644 index 0000000..f10ac23 Binary files /dev/null and b/assets/sprites/tarinai_19_flee_fear2.webp differ diff --git a/assets/sprites/tarinai_20_sleep2.png b/assets/sprites/tarinai_20_sleep2.png deleted file mode 100644 index 4d6bee7..0000000 Binary files a/assets/sprites/tarinai_20_sleep2.png and /dev/null differ diff --git a/assets/sprites/tarinai_20_sleep2.webp b/assets/sprites/tarinai_20_sleep2.webp new file mode 100644 index 0000000..63b558f Binary files /dev/null and b/assets/sprites/tarinai_20_sleep2.webp differ diff --git a/assets/sprites/tarinai_21_normal_happy.png b/assets/sprites/tarinai_21_normal_happy.png deleted file mode 100644 index b2730c5..0000000 Binary files a/assets/sprites/tarinai_21_normal_happy.png and /dev/null differ diff --git a/assets/sprites/tarinai_21_normal_happy.webp b/assets/sprites/tarinai_21_normal_happy.webp new file mode 100644 index 0000000..2d1df1f Binary files /dev/null and b/assets/sprites/tarinai_21_normal_happy.webp differ diff --git a/assets/sprites/tarinai_22_fear_blue.png b/assets/sprites/tarinai_22_fear_blue.png deleted file mode 100644 index 0d5d167..0000000 Binary files a/assets/sprites/tarinai_22_fear_blue.png and /dev/null differ diff --git a/assets/sprites/tarinai_22_fear_blue.webp b/assets/sprites/tarinai_22_fear_blue.webp new file mode 100644 index 0000000..99eb408 Binary files /dev/null and b/assets/sprites/tarinai_22_fear_blue.webp differ diff --git a/assets/sprites/tarinai_23_fear_cry.png b/assets/sprites/tarinai_23_fear_cry.png deleted file mode 100644 index 869217b..0000000 Binary files a/assets/sprites/tarinai_23_fear_cry.png and /dev/null differ diff --git a/assets/sprites/tarinai_23_fear_cry.webp b/assets/sprites/tarinai_23_fear_cry.webp new file mode 100644 index 0000000..cd7687a Binary files /dev/null and b/assets/sprites/tarinai_23_fear_cry.webp differ diff --git a/assets/sprites/tarinai_24_stress_dizzy.png b/assets/sprites/tarinai_24_stress_dizzy.png deleted file mode 100644 index f9474ca..0000000 Binary files a/assets/sprites/tarinai_24_stress_dizzy.png and /dev/null differ diff --git a/assets/sprites/tarinai_24_stress_dizzy.webp b/assets/sprites/tarinai_24_stress_dizzy.webp new file mode 100644 index 0000000..b0367ed Binary files /dev/null and b/assets/sprites/tarinai_24_stress_dizzy.webp differ diff --git a/assets/sprites/tarinai_25_stress_sweat.png b/assets/sprites/tarinai_25_stress_sweat.png deleted file mode 100644 index 1385ebf..0000000 Binary files a/assets/sprites/tarinai_25_stress_sweat.png and /dev/null differ diff --git a/assets/sprites/tarinai_25_stress_sweat.webp b/assets/sprites/tarinai_25_stress_sweat.webp new file mode 100644 index 0000000..1a537e1 Binary files /dev/null and b/assets/sprites/tarinai_25_stress_sweat.webp differ diff --git a/assets/sprites/tarinai_26_intimidate.png b/assets/sprites/tarinai_26_intimidate.png deleted file mode 100644 index 1813759..0000000 Binary files a/assets/sprites/tarinai_26_intimidate.png and /dev/null differ diff --git a/assets/sprites/tarinai_26_intimidate.webp b/assets/sprites/tarinai_26_intimidate.webp new file mode 100644 index 0000000..4575fb1 Binary files /dev/null and b/assets/sprites/tarinai_26_intimidate.webp differ diff --git a/assets/sprites/tarinai_27_birth_ritual.png b/assets/sprites/tarinai_27_birth_ritual.png deleted file mode 100644 index 7d13ae8..0000000 Binary files a/assets/sprites/tarinai_27_birth_ritual.png and /dev/null differ diff --git a/assets/sprites/tarinai_27_birth_ritual.webp b/assets/sprites/tarinai_27_birth_ritual.webp new file mode 100644 index 0000000..1a75b86 Binary files /dev/null and b/assets/sprites/tarinai_27_birth_ritual.webp differ diff --git a/assets/sprites/tarinai_28_zunchi_slave.png b/assets/sprites/tarinai_28_zunchi_slave.png deleted file mode 100644 index 7722fc4..0000000 Binary files a/assets/sprites/tarinai_28_zunchi_slave.png and /dev/null differ diff --git a/assets/sprites/tarinai_28_zunchi_slave.webp b/assets/sprites/tarinai_28_zunchi_slave.webp new file mode 100644 index 0000000..1842738 Binary files /dev/null and b/assets/sprites/tarinai_28_zunchi_slave.webp differ diff --git a/assets/ui/ecology_hp_stress.png b/assets/ui/ecology_hp_stress.png deleted file mode 100644 index b1b0a7d..0000000 Binary files a/assets/ui/ecology_hp_stress.png and /dev/null differ diff --git a/assets/ui/ecology_hp_stress.webp b/assets/ui/ecology_hp_stress.webp new file mode 100644 index 0000000..f507df7 Binary files /dev/null and b/assets/ui/ecology_hp_stress.webp differ diff --git a/assets/ui/tool_ammo.webp b/assets/ui/tool_ammo.webp new file mode 100644 index 0000000..31b2db8 Binary files /dev/null and b/assets/ui/tool_ammo.webp differ diff --git a/assets/ui/tool_ant_nest.png b/assets/ui/tool_ant_nest.png deleted file mode 100644 index c854138..0000000 Binary files a/assets/ui/tool_ant_nest.png and /dev/null differ diff --git a/assets/ui/tool_ant_nest.webp b/assets/ui/tool_ant_nest.webp new file mode 100644 index 0000000..2047162 Binary files /dev/null and b/assets/ui/tool_ant_nest.webp differ diff --git a/assets/ui/tool_ball.png b/assets/ui/tool_ball.png deleted file mode 100644 index e58011f..0000000 Binary files a/assets/ui/tool_ball.png and /dev/null differ diff --git a/assets/ui/tool_ball.webp b/assets/ui/tool_ball.webp new file mode 100644 index 0000000..91b6621 Binary files /dev/null and b/assets/ui/tool_ball.webp differ diff --git a/assets/ui/tool_bed.png b/assets/ui/tool_bed.png deleted file mode 100644 index c9243ec..0000000 Binary files a/assets/ui/tool_bed.png and /dev/null differ diff --git a/assets/ui/tool_bed.webp b/assets/ui/tool_bed.webp new file mode 100644 index 0000000..5c97940 Binary files /dev/null and b/assets/ui/tool_bed.webp differ diff --git a/assets/ui/tool_delete.png b/assets/ui/tool_delete.png deleted file mode 100644 index e518a51..0000000 Binary files a/assets/ui/tool_delete.png and /dev/null differ diff --git a/assets/ui/tool_delete.webp b/assets/ui/tool_delete.webp new file mode 100644 index 0000000..cf7788c Binary files /dev/null and b/assets/ui/tool_delete.webp differ diff --git a/assets/ui/tool_dwarf_drug.webp b/assets/ui/tool_dwarf_drug.webp new file mode 100644 index 0000000..1e45e0f Binary files /dev/null and b/assets/ui/tool_dwarf_drug.webp differ diff --git a/assets/ui/tool_fence_h.png b/assets/ui/tool_fence_h.png deleted file mode 100644 index 74872d7..0000000 Binary files a/assets/ui/tool_fence_h.png and /dev/null differ diff --git a/assets/ui/tool_fence_h.webp b/assets/ui/tool_fence_h.webp new file mode 100644 index 0000000..cd5f00d Binary files /dev/null and b/assets/ui/tool_fence_h.webp differ diff --git a/assets/ui/tool_fence_v.png b/assets/ui/tool_fence_v.png deleted file mode 100644 index d5bcf85..0000000 Binary files a/assets/ui/tool_fence_v.png and /dev/null differ diff --git a/assets/ui/tool_fence_v.webp b/assets/ui/tool_fence_v.webp new file mode 100644 index 0000000..5015e8a Binary files /dev/null and b/assets/ui/tool_fence_v.webp differ diff --git a/assets/ui/tool_fight_mochi.png b/assets/ui/tool_fight_mochi.png deleted file mode 100644 index 9c54caa..0000000 Binary files a/assets/ui/tool_fight_mochi.png and /dev/null differ diff --git a/assets/ui/tool_fight_mochi.webp b/assets/ui/tool_fight_mochi.webp new file mode 100644 index 0000000..b61a598 Binary files /dev/null and b/assets/ui/tool_fight_mochi.webp differ diff --git a/assets/ui/tool_firecracker.png b/assets/ui/tool_firecracker.png deleted file mode 100644 index c530161..0000000 Binary files a/assets/ui/tool_firecracker.png and /dev/null differ diff --git a/assets/ui/tool_firecracker.webp b/assets/ui/tool_firecracker.webp new file mode 100644 index 0000000..6a65c7d Binary files /dev/null and b/assets/ui/tool_firecracker.webp differ diff --git a/assets/ui/tool_genkotsu.png b/assets/ui/tool_genkotsu.png deleted file mode 100644 index 8160368..0000000 Binary files a/assets/ui/tool_genkotsu.png and /dev/null differ diff --git a/assets/ui/tool_genkotsu.webp b/assets/ui/tool_genkotsu.webp new file mode 100644 index 0000000..427095e Binary files /dev/null and b/assets/ui/tool_genkotsu.webp differ diff --git a/assets/ui/tool_giant_drug.webp b/assets/ui/tool_giant_drug.webp new file mode 100644 index 0000000..9e0e09e Binary files /dev/null and b/assets/ui/tool_giant_drug.webp differ diff --git a/assets/ui/tool_grass.png b/assets/ui/tool_grass.png deleted file mode 100644 index 38020e3..0000000 Binary files a/assets/ui/tool_grass.png and /dev/null differ diff --git a/assets/ui/tool_grass.webp b/assets/ui/tool_grass.webp new file mode 100644 index 0000000..83bd48e Binary files /dev/null and b/assets/ui/tool_grass.webp differ diff --git a/assets/ui/tool_laxative.webp b/assets/ui/tool_laxative.webp new file mode 100644 index 0000000..9c7a599 Binary files /dev/null and b/assets/ui/tool_laxative.webp differ diff --git a/assets/ui/tool_love_mochi.png b/assets/ui/tool_love_mochi.png deleted file mode 100644 index 73cf643..0000000 Binary files a/assets/ui/tool_love_mochi.png and /dev/null differ diff --git a/assets/ui/tool_love_mochi.webp b/assets/ui/tool_love_mochi.webp new file mode 100644 index 0000000..5c8b79f Binary files /dev/null and b/assets/ui/tool_love_mochi.webp differ diff --git a/assets/ui/tool_mercury.webp b/assets/ui/tool_mercury.webp new file mode 100644 index 0000000..b8cdac4 Binary files /dev/null and b/assets/ui/tool_mercury.webp differ diff --git a/assets/ui/tool_mystery_drug.webp b/assets/ui/tool_mystery_drug.webp new file mode 100644 index 0000000..62694ff Binary files /dev/null and b/assets/ui/tool_mystery_drug.webp differ diff --git a/assets/ui/tool_nest_box.png b/assets/ui/tool_nest_box.png deleted file mode 100644 index 4f60156..0000000 Binary files a/assets/ui/tool_nest_box.png and /dev/null differ diff --git a/assets/ui/tool_nest_box.webp b/assets/ui/tool_nest_box.webp new file mode 100644 index 0000000..5cc7cd6 Binary files /dev/null and b/assets/ui/tool_nest_box.webp differ diff --git a/assets/ui/tool_new.png b/assets/ui/tool_new.png deleted file mode 100644 index 3b1e13f..0000000 Binary files a/assets/ui/tool_new.png and /dev/null differ diff --git a/assets/ui/tool_new.webp b/assets/ui/tool_new.webp new file mode 100644 index 0000000..f55ee81 Binary files /dev/null and b/assets/ui/tool_new.webp differ diff --git a/assets/ui/tool_niteropu.webp b/assets/ui/tool_niteropu.webp new file mode 100644 index 0000000..d50ba60 Binary files /dev/null and b/assets/ui/tool_niteropu.webp differ diff --git a/assets/ui/tool_observe.png b/assets/ui/tool_observe.png deleted file mode 100644 index 64f6964..0000000 Binary files a/assets/ui/tool_observe.png and /dev/null differ diff --git a/assets/ui/tool_observe.webp b/assets/ui/tool_observe.webp new file mode 100644 index 0000000..6c2b3ec Binary files /dev/null and b/assets/ui/tool_observe.webp differ diff --git a/assets/ui/tool_protein.webp b/assets/ui/tool_protein.webp new file mode 100644 index 0000000..8d78b1a Binary files /dev/null and b/assets/ui/tool_protein.webp differ diff --git a/assets/ui/tool_sleep_drug.png b/assets/ui/tool_sleep_drug.png deleted file mode 100644 index c8d0f5a..0000000 Binary files a/assets/ui/tool_sleep_drug.png and /dev/null differ diff --git a/assets/ui/tool_sleep_drug.webp b/assets/ui/tool_sleep_drug.webp new file mode 100644 index 0000000..4c4c923 Binary files /dev/null and b/assets/ui/tool_sleep_drug.webp differ diff --git a/assets/ui/tool_stone.png b/assets/ui/tool_stone.png deleted file mode 100644 index 8bf6596..0000000 Binary files a/assets/ui/tool_stone.png and /dev/null differ diff --git a/assets/ui/tool_stone.webp b/assets/ui/tool_stone.webp new file mode 100644 index 0000000..dd0ce27 Binary files /dev/null and b/assets/ui/tool_stone.webp differ diff --git a/assets/ui/tool_sweet.png b/assets/ui/tool_sweet.png deleted file mode 100644 index 5560116..0000000 Binary files a/assets/ui/tool_sweet.png and /dev/null differ diff --git a/assets/ui/tool_sweet.webp b/assets/ui/tool_sweet.webp new file mode 100644 index 0000000..39a38c9 Binary files /dev/null and b/assets/ui/tool_sweet.webp differ diff --git a/assets/ui/tool_water.png b/assets/ui/tool_water.png deleted file mode 100644 index 8270a2a..0000000 Binary files a/assets/ui/tool_water.png and /dev/null differ diff --git a/assets/ui/tool_water.webp b/assets/ui/tool_water.webp new file mode 100644 index 0000000..b8cdac4 Binary files /dev/null and b/assets/ui/tool_water.webp differ diff --git a/assets/ui/tool_water_bowl.png b/assets/ui/tool_water_bowl.png deleted file mode 100644 index d934cfb..0000000 Binary files a/assets/ui/tool_water_bowl.png and /dev/null differ diff --git a/assets/ui/tool_water_bowl.webp b/assets/ui/tool_water_bowl.webp new file mode 100644 index 0000000..3dc7384 Binary files /dev/null and b/assets/ui/tool_water_bowl.webp differ diff --git a/assets/ui/tool_water_hose.png b/assets/ui/tool_water_hose.png deleted file mode 100644 index 31cb91a..0000000 Binary files a/assets/ui/tool_water_hose.png and /dev/null differ diff --git a/assets/ui/tool_water_hose.webp b/assets/ui/tool_water_hose.webp new file mode 100644 index 0000000..0b91bf1 Binary files /dev/null and b/assets/ui/tool_water_hose.webp differ diff --git a/assets/ui/tool_zunchi.png b/assets/ui/tool_zunchi.png deleted file mode 100644 index d7e5168..0000000 Binary files a/assets/ui/tool_zunchi.png and /dev/null differ diff --git a/assets/ui/tool_zunchi.webp b/assets/ui/tool_zunchi.webp new file mode 100644 index 0000000..560f113 Binary files /dev/null and b/assets/ui/tool_zunchi.webp differ diff --git a/assets/ui/tool_zunda_juice.webp b/assets/ui/tool_zunda_juice.webp new file mode 100644 index 0000000..c59324c Binary files /dev/null and b/assets/ui/tool_zunda_juice.webp differ diff --git a/css/base.css b/css/base.css new file mode 100644 index 0000000..799d6e5 --- /dev/null +++ b/css/base.css @@ -0,0 +1,411 @@ +/* Generated CSS split from styles.css; preserve load order. */ +@import url("https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic:wght@400;500;700&family=M+PLUS+Rounded+1c:wght@400;500;700&family=Yomogi&display=swap"); + +:root { + --bg: #f7f5ec; + --panel: rgba(255,251,245,0.90); + --ink: #2a241d; + --muted: #756a5e; + --line: rgba(84, 68, 48, 0.18); + --accent: #9ce84b; + --accent-2: #f5a8b7; + --danger: #b64545; + --shadow: 0 18px 50px rgba(64, 48, 32, 0.14); + --radius: 18px; + --bubble-font: "Yomogi", "Zen Maru Gothic", "M PLUS Rounded 1c", ui-rounded, sans-serif; +} + +* { box-sizing: border-box; } + +body { + margin: 0; + font-family: "Zen Maru Gothic", "M PLUS Rounded 1c", ui-rounded, "Hiragino Maru Gothic ProN", "Yu Gothic", "Meiryo", system-ui, sans-serif; + background: + radial-gradient(circle at 12% 0%, rgba(168, 228, 113, 0.28), transparent 33%), + radial-gradient(circle at 88% 8%, rgba(255, 222, 147, 0.24), transparent 28%), + radial-gradient(circle at 82% 90%, rgba(126, 181, 120, 0.16), transparent 34%), + linear-gradient(180deg, #dff0ff 0%, #edf8ff 12%, #f9f6eb 46%, var(--bg) 100%); + color: var(--ink); + min-height: 100vh; + overflow-x: hidden; + position: relative; +} + +button { + font: inherit; + color: inherit; +} + +.loading-screen { + position: fixed; + inset: 0; + z-index: 9999; + display: grid; + place-items: center; + padding: 24px; + background: + radial-gradient(circle at 50% 30%, rgba(164, 225, 104, 0.22), transparent 32%), + linear-gradient(180deg, rgba(239, 248, 255, 0.98), rgba(247, 245, 236, 0.98)); + transition: opacity 180ms ease, visibility 180ms ease; +} +.loading-screen.hidden { + opacity: 0; + visibility: hidden; + pointer-events: none; +} +.loading-panel { + width: min(420px, 92vw); + padding: 24px 22px; + border-radius: 24px; + border: 1px solid rgba(84, 68, 48, 0.16); + background: rgba(255, 252, 246, 0.92); + box-shadow: 0 18px 48px rgba(64, 48, 32, 0.16); + text-align: center; +} +.loading-title { + font-weight: 700; + font-size: 18px; + letter-spacing: 0.04em; + margin-bottom: 8px; +} +.loading-text { + color: var(--muted); + font-size: 13px; + line-height: 1.55; + min-height: 1.55em; +} +.loading-bar { + height: 12px; + margin: 18px 0 8px; + border-radius: 999px; + overflow: hidden; + background: rgba(90, 70, 48, 0.12); +} +.loading-bar-fill { + width: 0%; + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, #9ce84b, #f0d35b); + transition: width 160ms ease; +} +.loading-percent { + color: var(--muted); + font-size: 12px; + font-variant-numeric: tabular-nums; +} + +#app { + width: min(1480px, 100vw); + margin: 0 auto; + padding: 18px; + position: relative; +} + +.topbar { + display: flex; + justify-content: space-between; + gap: 18px; + align-items: center; + margin-bottom: 16px; +} + +.top-left { + display: flex; + align-items: center; + gap: 12px; + min-width: 0; +} + +.brand { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: nowrap; + min-width: 0; +} + +.room-link { + text-decoration: none; + white-space: nowrap; + background: rgba(255,255,255,0.86); +} + +h1 { + margin: 0; + font-size: clamp(24px, 3.4vw, 42px); + letter-spacing: 0.03em; + white-space: nowrap; +} + +.subtitle { + margin: 0; + color: var(--muted); + font-size: clamp(11px, 1.1vw, 13px); + line-height: 1.35; + white-space: nowrap; +} + +.top-actions { + display: flex; + gap: 8px; + flex-wrap: wrap; + justify-content: flex-end; +} + +.btn, .tool { + border: 1px solid var(--line); + background: rgba(255,255,255,0.76); + border-radius: 999px; + padding: 9px 13px; + cursor: pointer; + box-shadow: 0 4px 14px rgba(80,60,40,0.06); + transition: transform 130ms ease, background 130ms ease, border-color 130ms ease; + user-select: none; +} + +.btn:hover, .tool:hover { transform: translateY(-1px); background: #fff; } +.btn:active, .tool:active { transform: translateY(1px); } + +.btn.primary { + background: linear-gradient(180deg, #a9ef5d, #8bdc3f); + border-color: rgba(89, 128, 47, 0.28); +} + +.btn.danger { + color: #7a2828; +} + +.layout { + display: grid; + grid-template-columns: minmax(520px, 1fr) 380px; + gap: 16px; + align-items: stretch; +} + +.stage-wrap { + position: relative; + background: linear-gradient(180deg, rgba(255,255,255,0.46), rgba(246, 240, 228, 0.56)); + border: 1px solid rgba(84, 68, 48, 0.12); + border-radius: calc(var(--radius) + 8px); + overflow: hidden; + box-shadow: 0 16px 42px rgba(42, 45, 80, 0.12), inset 0 0 0 1px rgba(255,255,255,0.24); + min-height: var(--field-min-height, 620px); +} + +#gameCanvas { + width: 100%; + height: var(--field-height, calc(100vh - 140px)); + min-height: var(--field-min-height, 620px); + display: block; + cursor: crosshair; + background: linear-gradient(180deg, #cfe3d3, #d9d0ad); +} + +.field-dialog { + position: fixed; + inset: 0; + z-index: 30; + display: grid; + place-items: center; + padding: 18px; + background: rgba(34, 29, 22, 0.38); + backdrop-filter: blur(3px); +} +.field-dialog.hidden { display: none; } +.field-dialog-panel { + width: min(440px, 100%); + max-height: calc(100vh - 36px); + overflow: auto; + border-radius: 16px; + padding: 16px; + background: rgba(255, 252, 245, 0.96); + border: 1px solid rgba(84,68,48,0.16); + box-shadow: 0 18px 46px rgba(40, 32, 24, 0.22); +} +.field-dialog-panel h2 { + margin: 0 0 12px; + font-size: 17px; +} +.field-choice-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; +} +.field-choice { + min-height: 74px; + border: 1px solid rgba(84,68,48,0.16); + border-radius: 12px; + background: linear-gradient(180deg, rgba(255,255,255,0.86), rgba(241,235,221,0.72)); + cursor: pointer; + color: var(--ink); +} +.field-choice:hover { border-color: rgba(112,178,66,0.45); } +.field-choice strong, .field-choice span { display: block; } +.field-choice strong { font-size: 15px; } +.field-choice span { margin-top: 4px; color: var(--muted); font-size: 12px; } +.field-dialog-actions { + margin-top: 12px; + display: flex; + justify-content: flex-end; + gap: 8px; +} +.archive-reset-dialog-panel { + width: min(420px, 100%); +} +.archive-reset-actions { + justify-content: space-between; + gap: 10px; +} +.archive-reset-actions .btn { + min-width: 132px; +} + + +.ecology-dialog-panel { + width: min(760px, 100%); + max-height: calc(100vh - 36px); + overflow-y: auto; + overscroll-behavior: auto; +} +.ecology-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} +.ecology-card { + display: grid; + grid-template-columns: 72px minmax(0, 1fr); + gap: 10px; + align-items: center; + padding: 10px; + border-radius: 14px; + background: linear-gradient(180deg, rgba(255,255,255,0.88), rgba(243,237,225,0.76)); + border: 1px solid rgba(84,68,48,0.12); +} +.ecology-card img { + width: 72px; + height: 72px; + object-fit: contain; + filter: drop-shadow(0 8px 18px rgba(56, 44, 32, 0.10)); +} +.ecology-card strong { + display: block; + margin-bottom: 4px; + font-size: 15px; +} +.ecology-card p { + margin: 0; + color: var(--muted); + font-size: 12px; + line-height: 1.40; +} + +.toast { + position: absolute; + left: 50%; + bottom: 22px; + transform: translateX(-50%); + background: rgba(42,36,29,0.86); + color: white; + padding: 10px 16px; + border-radius: 999px; + font-size: 14px; + pointer-events: none; + opacity: 1; + transition: opacity 200ms ease, transform 200ms ease; +} +.toast.hidden { opacity: 0; transform: translateX(-50%) translateY(8px); } + +.panel { + display: flex; + flex-direction: column; + gap: 12px; + height: calc(100vh - 120px); + max-height: calc(100vh - 120px); + overflow-y: auto; + overflow-x: hidden; + padding-right: 3px; +} + +.card { + position: relative; + background: var(--panel); + border: 1px solid var(--line); + border-radius: var(--radius); + padding: 14px; + box-shadow: 0 10px 30px rgba(64, 48, 32, 0.08); + backdrop-filter: blur(10px); + position: relative; +} + +.card h2 { + margin: 0 0 12px; + font-size: 17px; + letter-spacing: 0.03em; +} + +.tool-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0,1fr)); + gap: 8px; +} + +.tool { + border-radius: 14px; + display: flex; + align-items: center; + gap: 7px; + justify-content: flex-start; + padding: 8px 8px 8px 42px; + min-height: 46px; + position: relative; + overflow: hidden; + background-repeat: no-repeat; + background-position: 7px center, center; + background-size: 30px 30px, cover; +} +.tool::before { + content: ""; + position: absolute; + left: 7px; + top: 50%; + width: 30px; + height: 30px; + transform: translateY(-50%); + background: var(--tool-icon) center / contain no-repeat; + opacity: 0.92; + filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); +} +.tool::after { + content: ""; + position: absolute; + inset: 0; + background: var(--tool-icon) right -8px center / 54px 54px no-repeat; + opacity: 0.10; + pointer-events: none; +} +.tool > span:not(.tool-size-badge) { display: none; } +.tool[data-tool="observe"] { --tool-icon: url("../assets/ui/tool_observe.webp"); } +.tool[data-tool="zunchi"] { --tool-icon: url("../assets/ui/tool_zunchi.webp"); } +.tool[data-tool="sweet"] { --tool-icon: url("../assets/ui/tool_sweet.webp"); } +.tool[data-tool="grass"] { --tool-icon: url("../assets/ui/tool_grass.webp"); } +.tool[data-tool="stone"] { --tool-icon: url("../assets/ui/tool_stone.webp"); } +.tool[data-tool="genkotsu"] { --tool-icon: url("../assets/ui/tool_genkotsu.webp"); } +.tool[data-tool="firecracker"] { --tool-icon: url("../assets/ui/tool_firecracker.webp"); } +.tool[data-tool="fence_v"] { --tool-icon: url("../assets/ui/tool_fence_v.webp"); } +.tool[data-tool="fence_h"] { --tool-icon: url("../assets/ui/tool_fence_h.webp"); } +.tool[data-tool="bed"] { --tool-icon: url("../assets/ui/tool_bed.webp"); } +.tool[data-tool="love_mochi"] { --tool-icon: url("../assets/ui/tool_love_mochi.webp"); } +.tool[data-tool="fight_mochi"] { --tool-icon: url("../assets/ui/tool_fight_mochi.webp"); } +.tool[data-tool="water_bowl"] { --tool-icon: url("../assets/ui/tool_water_bowl.webp"); } + +/* v15.19.1: updated parameter item tool icons */ +.tool[data-tool="laxative"] { --tool-icon: url("../assets/ui/tool_laxative.webp?v=15.19.1"); } +.tool[data-tool="protein"] { --tool-icon: url("../assets/ui/tool_protein.webp?v=15.19.1"); } +.tool[data-tool="niteropu"] { --tool-icon: url("../assets/ui/tool_niteropu.webp?v=15.19.1"); } +.tool[data-tool="ammo"] { --tool-icon: url("../assets/ui/tool_ammo.webp?v=15.19.1"); } +.tool[data-tool="mystery_drug"] { --tool-icon: url("../assets/ui/tool_mystery_drug.webp?v=15.19.1"); } +.tool[data-tool="mercury"] { --tool-icon: url("../assets/ui/tool_mercury.webp?v=15.19.1"); } +.tool[data-tool="giant_drug"] { --tool-icon: url("../assets/ui/tool_giant_drug.webp?v=15.19.1"); } +.tool[data-tool="dwarf_drug"] { --tool-icon: url("../assets/ui/tool_dwarf_drug.webp?v=15.19.1"); } +.tool[data-tool="zunda_juice"] { --tool-icon: url("../assets/ui/tool_zunda_juice.webp?v=15.19.1"); } diff --git a/css/components.css b/css/components.css new file mode 100644 index 0000000..6f01648 --- /dev/null +++ b/css/components.css @@ -0,0 +1,411 @@ +/* Generated CSS split from styles.css; preserve load order. */ +.tool-tip-popover { + position: fixed; + z-index: 2147483000; + width: 220px; + max-width: min(220px, calc(100vw - 16px)); + padding: 7px 9px; + border-radius: 10px; + background: rgba(46, 38, 30, 0.78); + color: #fff8e6; + font-family: "Yomogi", "Hiragino Maru Gothic ProN", "Yu Gothic", sans-serif; + font-size: 12px; + line-height: 1.45; + box-shadow: 0 10px 28px rgba(40, 32, 22, 0.18); + backdrop-filter: blur(1px); + text-shadow: 0 1px 3px rgba(25, 18, 12, 0.55); + pointer-events: none; +} +.tool-tip-popover.hidden { display: none; } +.selected-actions { + display: flex; + gap: 8px; + flex-wrap: wrap; + margin: 8px 0 4px; +} +.favorite-toggle { + border: 1px solid rgba(128, 102, 56, 0.32); + border-radius: 999px; + background: rgba(255, 248, 221, 0.92); + color: #5a4630; + font-weight: 700; + padding: 5px 10px; + cursor: pointer; +} +.favorite-toggle.active { + background: rgba(255, 229, 122, 0.95); + border-color: rgba(180, 132, 34, 0.55); +} + +.selected-records { + margin-top: 8px; + padding-top: 7px; + border-top: 1px dashed rgba(126, 96, 64, 0.24); +} +.selected-records h3 { + margin: 0 0 5px; + font-size: 12px; + color: var(--muted); +} +.selected-records ol { + margin: 0; + padding: 0; + list-style: none; + display: grid; + gap: 4px; +} +.selected-records li { + display: grid; + grid-template-columns: 38px 1fr; + gap: 6px; + align-items: start; + font-size: 11px; + line-height: 1.35; +} +.selected-records li span { + color: var(--muted); + font-variant-numeric: tabular-nums; +} +.selected-records li strong { + font-weight: 600; +} + +.relation-list-row { + align-items: start; +} +.relation-list-row > strong { + min-width: 0; + width: 100%; + justify-content: flex-end; +} +.relation-chip-list { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 5px; + max-width: 100%; +} +.relation-chip { + display: inline-flex; + align-items: center; + gap: 4px; + max-width: 138px; + min-width: 0; + border: 1px solid rgba(104, 150, 84, 0.24); + border-radius: 999px; + background: rgba(250, 255, 242, 0.88); + color: #4d6140; + padding: 2px 6px 2px 2px; + font: inherit; + font-size: 11px; + line-height: 1.2; + cursor: pointer; + box-shadow: 0 1px 0 rgba(255,255,255,0.74); +} +.relation-chip.enemy { + border-color: rgba(178, 92, 74, 0.28); + background: rgba(255, 246, 240, 0.92); + color: #754739; +} +.relation-chip:hover, +.relation-chip:focus-visible { + transform: translateY(-1px); + background: rgba(255,255,255,0.98); + outline: 2px solid rgba(118, 186, 72, 0.18); +} +.relation-chip.enemy:hover, +.relation-chip.enemy:focus-visible { + outline-color: rgba(190, 92, 72, 0.18); +} +.relation-chip .relation-face { + width: 22px; + height: 22px; +} +.relation-chip-name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + min-width: 0; +} +.relation-chip em { + font-style: normal; + font-size: 10px; + opacity: 0.72; + flex: 0 0 auto; +} + + +.loading-screen { + position: fixed; + inset: 0; + z-index: 1000; + display: grid; + place-items: center; + padding: 20px; + background: radial-gradient(circle at top, rgba(255,251,243,0.98), rgba(245,238,225,0.96) 56%, rgba(234,225,208,0.98)); + transition: opacity .22s ease, visibility .22s ease; +} +.loading-screen.hidden { + opacity: 0; + visibility: hidden; + pointer-events: none; +} +.loading-kicker { + font-size: 12px; + letter-spacing: 0.14em; + color: rgba(116, 96, 76, 0.82); + margin-bottom: 6px; +} +.loading-title { + margin: 0 0 8px; + font-size: 28px; + color: #3f3429; +} +.loading-text { + margin: 0 0 12px; + color: rgba(90, 74, 58, 0.86); +} +.loading-sprite-strip { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin: 8px 0 14px; +} +.loading-sprite-card { + border-radius: 16px; + background: linear-gradient(180deg, rgba(255,255,255,0.84), rgba(248,243,232,0.90)); + border: 1px solid rgba(126, 104, 80, 0.12); + min-height: 92px; + display: grid; + place-items: center; + padding: 8px; + box-shadow: 0 8px 18px rgba(83, 63, 44, 0.06); +} +.loading-sprite-card img { + width: 68px; + height: 68px; + object-fit: contain; +} +.loading-progress-track { + width: 100%; + height: 14px; + border-radius: 999px; + overflow: hidden; + background: rgba(132, 164, 217, 0.16); + border: 1px solid rgba(92, 126, 181, 0.14); +} +.loading-progress-bar { + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, #92d1ff, #a3dfa0 58%, #ffe192); + transition: width .18s ease; +} +.loading-progress-meta { + margin-top: 8px; + display: flex; + justify-content: space-between; + align-items: center; + font-size: 12px; + color: rgba(88, 73, 60, 0.82); +} +.loading-hint { + margin: 10px 0 0; + font-size: 12px; + line-height: 1.55; + color: rgba(111, 92, 73, 0.78); +} + +.collapsible-card { + padding-top: 10px; +} +.panel-card-toggle { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + border: 0; + border-radius: 14px; + padding: 10px 12px; + cursor: pointer; + font: inherit; + color: var(--ink); + background: rgba(255,255,255,0.48); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.54); +} +.panel-card-title { + font-size: 17px; + font-weight: 700; + letter-spacing: 0.03em; +} +.panel-card-state { + font-size: 12px; + color: rgba(98, 82, 64, 0.78); + padding-left: 16px; + position: relative; +} +.panel-card-state::before { + content: "▾"; + position: absolute; + left: 0; + top: 50%; + transform: translateY(-52%); + color: rgba(98, 82, 64, 0.72); +} +.collapsible-card.collapsed .panel-card-state::before { content: "▸"; } +.collapsible-card.collapsed .panel-card-body { display: none; } +.panel-card-body { padding-top: 12px; } + +.tool-card { + background: linear-gradient(180deg, rgba(255,247,252,0.92), rgba(249,240,249,0.90)); + border-color: rgba(200, 153, 186, 0.34); +} +.colony-card { + background: linear-gradient(180deg, rgba(244,250,238,0.92), rgba(235,246,230,0.90)); + border-color: rgba(132, 178, 128, 0.34); +} +.log-card { + background: linear-gradient(180deg, rgba(255,246,238,0.92), rgba(252,239,226,0.90)); + border-color: rgba(207, 157, 121, 0.34); +} +.tool-card .panel-card-toggle { + background: linear-gradient(180deg, rgba(255,239,248,0.82), rgba(253,234,246,0.84)); +} +.colony-card .panel-card-toggle { + background: linear-gradient(180deg, rgba(240,252,237,0.82), rgba(230,247,228,0.86)); +} +.log-card .panel-card-toggle { + background: linear-gradient(180deg, rgba(255,242,231,0.84), rgba(253,235,220,0.86)); +} +.tool-card .tool-category { + background: rgba(255,255,255,0.40); + border-color: rgba(165,118,150,0.14); +} +.colony-card .stat { + background: linear-gradient(180deg, rgba(255,255,255,0.68), rgba(239,248,234,0.84)); +} +.colony-card .chart-tabs button.active { + background: rgba(202, 239, 193, 0.88); + border-color: rgba(110,168,92,0.38); +} +.log-card .log-entry { + background: rgba(255,250,246,0.86); +} +@media (max-width: 920px) { + .loading-sprite-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } +} + + +.log-push-controls { + margin-top: 10px; + padding: 10px; + border-radius: 14px; + border: 1px solid rgba(192, 138, 96, 0.24); + background: rgba(255, 247, 239, 0.74); +} +.push-master { + display: flex; + align-items: center; + gap: 7px; + font-size: 12px; + font-weight: 700; + margin-bottom: 8px; +} +.push-kind-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 6px 8px; + font-size: 11px; + color: rgba(82, 66, 52, 0.88); +} +.push-kind-grid label { + display: inline-flex; + align-items: center; + gap: 5px; + min-width: 0; +} +.push-master input, +.push-kind-grid input { + accent-color: #dc966c; +} +.log-push-overlay { + position: fixed; + left: 16px; + bottom: 16px; + z-index: 20000; + display: flex; + flex-direction: column; + gap: 8px; + width: min(360px, calc(100vw - 32px)); + pointer-events: none; +} +.log-push-toast { + position: relative; + border-radius: 16px; + padding: 10px 12px 10px 14px; + border: 1px solid rgba(92, 72, 54, 0.18); + background: rgba(255, 251, 244, 0.96); + box-shadow: 0 14px 36px rgba(46, 34, 24, 0.20); + color: #2f271f; + backdrop-filter: blur(8px); + animation: logPushIn .18s ease both; + overflow: hidden; +} +.log-push-toast::before { + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 5px; + background: rgba(146, 122, 92, 0.42); +} +.log-push-toast .log-push-tag { + display: inline-block; + margin-right: 6px; + padding: 2px 6px; + border-radius: 999px; + background: rgba(238, 224, 204, 0.78); + font-size: 10px; + font-weight: 700; +} +.log-push-toast .log-push-time { + color: rgba(96, 78, 62, 0.72); + font-size: 10px; +} +.log-push-toast .log-push-text { + margin-top: 5px; + font-size: 12px; + line-height: 1.45; +} +.log-push-toast.log-push-death::before { background: #8f817a; } +.log-push-toast.log-push-accident::before { background: #ee9e5d; } +.log-push-toast.log-push-birth::before { background: #98cf7a; } +.log-push-toast.log-push-fight::before { background: #e47b80; } +.log-push-toast.log-push-relation::before { background: #b99be0; } +.log-push-toast.log-push-food::before { background: #e9bd61; } +.log-push-toast.log-push-weather::before { background: #7bbbdc; } +.log-push-toast.log-push-grass::before { background: #8cc77a; } +.log-push-toast.leaving { + animation: logPushOut .18s ease both; +} +@keyframes logPushIn { + from { transform: translateY(14px); opacity: 0; } + to { transform: translateY(0); opacity: 1; } +} +@keyframes logPushOut { + from { transform: translateY(0); opacity: 1; } + to { transform: translateY(8px); opacity: 0; } +} + +/* v15.12.0: loading / collapsible cards / sound settings */ +.loading-screen { + position: fixed; + inset: 0; + z-index: 1000; + display: grid; + place-items: center; + padding: 20px; + background: radial-gradient(circle at top, rgba(255,251,243,0.98), rgba(245,238,225,0.96) 56%, rgba(234,225,208,0.98)); + transition: opacity .22s ease, visibility .22s ease; +} diff --git a/css/layout.css b/css/layout.css new file mode 100644 index 0000000..1f9f88d --- /dev/null +++ b/css/layout.css @@ -0,0 +1,366 @@ +/* Generated CSS split from styles.css; preserve load order. */ +.tool[data-tool="sleep_drug"] { --tool-icon: url("../assets/ui/tool_sleep_drug.webp"); } +.tool[data-tool="nest_box"] { --tool-icon: url("../assets/ui/tool_nest_box.webp"); } +.tool[data-tool="ant_nest"] { --tool-icon: url("../assets/ui/tool_ant_nest.webp"); } +.tool[data-tool="ball"] { --tool-icon: url("../assets/ui/tool_ball.webp"); } +.tool[data-tool="poke"] { --tool-icon: none; } +.tool[data-tool="poke"]::before { + content: "\1F448"; + background: none; + font-size: 25px; + line-height: 1; + filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); +} +.tool[data-tool="poke"]::after { + content: "\1F448"; + background: none; + font-size: 48px; + line-height: 1; + opacity: 0.11; + right: -6px; + left: auto; + top: 50%; + bottom: auto; + transform: translateY(-50%); + width: 54px; + height: 54px; +} + +.tool[data-tool="pinch"] { --tool-icon: none; } +.tool[data-tool="pinch"]::before { + content: "\1F90F"; + background: none; + font-size: 25px; + line-height: 1; + filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); +} +.tool[data-tool="pinch"]::after { + content: "\1F90F"; + background: none; + font-size: 48px; + line-height: 1; + opacity: 0.10; + right: -6px; + left: auto; + top: 50%; + bottom: auto; + transform: translateY(-50%); + width: 54px; + height: 54px; +} +.tool[data-tool="water_hose"] { --tool-icon: none; } +.tool[data-tool="water_hose"]::before { + content: "\1F6BF"; + background: none; + font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif; + font-size: 24px; + line-height: 1; + filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); +} +.tool[data-tool="water_hose"]::after { + content: "\1F6BF"; + background: none; + font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif; + font-size: 46px; + line-height: 1; + opacity: 0.10; + right: -6px; + left: auto; + top: 50%; + bottom: auto; + transform: translateY(-50%); + width: 54px; + height: 54px; +} + +.tool[data-tool="delete"] { --tool-icon: url("../assets/ui/tool_delete.webp"); } +.tool[data-tool="new"] { --tool-icon: url("../assets/ui/tool_new.webp"); } +.tool.selected { + background: linear-gradient(180deg, #ffffff, #efffde); + border-color: rgba(103, 178, 44, 0.52); + box-shadow: inset 0 0 0 1px rgba(156,232,75,0.38), 0 8px 20px rgba(117, 166, 64, 0.13); +} + +.hint { + color: var(--muted); + font-size: 12px; + line-height: 1.40; + margin: 10px 0 0; +} + +.tool-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; } +.tool-head h2 { margin-bottom: 0; } +.btn.mini { padding: 6px 10px; font-size: 12px; } +.tool-body { margin-top: 12px; } +.tool-palette { display: flex; flex-direction: column; gap: 9px; } +.tool-category { + border: 1px solid rgba(84,68,48,0.10); + border-radius: 14px; + background: rgba(255,255,255,0.34); + overflow: hidden; +} +.tool-category-toggle { + width: 100%; + border: 0; + border-bottom: 1px solid rgba(84,68,48,0.08); + background: rgba(255,252,244,0.66); + padding: 8px 10px; + text-align: left; + cursor: pointer; + font-weight: 700; + font-size: 12px; +} +.tool-category-toggle::before { content: "\25be "; display: inline-block; width: 16px; color: var(--muted); } +.tool-category.collapsed .tool-category-toggle::before { content: "\25b8 "; } +.tool-category-body { padding: 8px; } +.tool-category.collapsed .tool-category-body { display: none; } + +.selected-data-groups { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 8px; +} +.selected-category { + border: 1px solid rgba(84,68,48,0.10); + border-radius: 14px; + background: rgba(255,255,255,0.30); + overflow: hidden; +} +.selected-category-toggle { + width: 100%; + border: 0; + border-bottom: 1px solid rgba(84,68,48,0.08); + background: rgba(255,252,244,0.66); + padding: 8px 10px; + text-align: left; + cursor: pointer; + font-weight: 700; + font-size: 12px; + color: var(--ink); +} +.selected-category-toggle::before { content: "\25be "; display: inline-block; width: 16px; color: var(--muted); } +.selected-category.collapsed .selected-category-toggle::before { content: "\25b8 "; } +.selected-category-body { padding: 7px 9px; } +.selected-category.collapsed .selected-category-body { display: none; } +.selected-category-body .info-row:last-child { border-bottom: 0; } +.tool-size-badge { + position: absolute; + right: 7px; + bottom: 6px; + min-width: 20px; + padding: 2px 5px; + border-radius: 999px; + background: rgba(42,36,29,0.68); + color: #fff; + font-size: 10px; + line-height: 1; + text-align: center; + box-shadow: 0 1px 4px rgba(42,36,29,0.16); + pointer-events: none; +} +.chart-tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; margin: 3px 0 8px; } +.chart-tabs button { border: 1px solid var(--line); background: rgba(255,255,255,0.62); border-radius: 999px; padding: 5px 4px; font-size: 11px; cursor: pointer; } +.chart-tabs button.active { background: #efffde; border-color: rgba(103,178,44,0.46); font-weight: 700; } +.log-accident { border-left-color: rgba(226, 136, 54, 0.76); } + + +.stats { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 8px; + margin-bottom: 12px; +} + +.stat { + background: linear-gradient(180deg, rgba(255,255,255,0.58), rgba(246, 240, 228, 0.72)); + border: 1px solid var(--line); + border-radius: 13px; + padding: 9px 8px; + text-align: center; +} +.stat span { display: block; font-size: 11px; color: var(--muted); } +.stat strong { font-size: 18px; } + +.meter-row { + display: grid; + grid-template-columns: 72px 1fr; + align-items: center; + gap: 8px; + font-size: 12px; + margin: 6px 0; +} +meter { + width: 100%; + height: 12px; + accent-color: var(--accent); +} + + +.selected-card.hidden { display: none; } +.selected-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-bottom: 8px; +} +.selected-head h2 { margin-bottom: 0; } +.selected-close { + width: 28px; + height: 28px; + border: 1px solid rgba(84,68,48,0.16); + border-radius: 999px; + background: rgba(255,255,255,0.76); + color: rgba(76,58,42,0.78); + font-size: 20px; + line-height: 24px; + cursor: pointer; + display: grid; + place-items: center; + padding: 0; +} +.selected-close:hover { background: #fff; } + +.selected-info { + font-size: 13px; + line-height: 1.40; +} +.selected-info.empty { + color: var(--muted); +} + +.selected-name-editor { + margin: 0 0 8px; +} +.selected-name-input { + width: 100%; + box-sizing: border-box; + border: 1px solid rgba(103,178,44,0.34); + border-radius: 13px; + background: rgba(246,252,238,0.96); + color: var(--ink); + font-size: 18px; + font-weight: 700; + line-height: 1.25; + padding: 8px 10px; + box-shadow: inset 0 1px 0 rgba(255,255,255,0.82); +} +.selected-name-input:focus { + outline: 2px solid rgba(103,178,44,0.24); + border-color: rgba(103,178,44,0.62); + background: #fff; +} +.selected-effects { + margin: 2px 0 6px; +} +.badge { + display: inline-block; + font-size: 11px; + line-height: 1; + border-radius: 999px; + padding: 5px 8px; + background: #f1f8e9; + border: 1px solid rgba(103, 178, 44, 0.28); + margin: 0 4px 4px 0; +} +.info-row { + display: flex; + justify-content: space-between; + gap: 10px; + border-bottom: 1px dashed rgba(84,68,48,0.16); + padding: 5px 0; +} +.info-row span:first-child { color: var(--muted); } +.personality-values strong { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 2px 8px; + max-width: 68%; + text-align: right; +} +.personality-values strong span { + color: var(--ink); + white-space: nowrap; +} +.personality-tag { + display: inline-block; + border-radius: 999px; + padding: 2px 7px; + background: rgba(103,178,44,0.10); + border: 1px solid rgba(103,178,44,0.22); +} +.personality-tag.neutral { + background: rgba(120,110,90,0.08); + border-color: rgba(120,110,90,0.16); +} + +.log-card { min-height: 260px; flex: 0 0 auto; display: flex; flex-direction: column; } +.log { + max-height: 360px; + min-height: 170px; + flex: 1 1 auto; + overflow: auto; + display: flex; + flex-direction: column; + gap: 7px; + font-size: 12px; + overscroll-behavior: auto; +} +.log-entry { + padding: 8px 9px; + border-radius: 12px; + background: rgba(255,252,246,0.82); + border: 1px solid rgba(84,68,48,0.12); + border-left: 4px solid rgba(118, 101, 74, 0.24); +} +.log-tag { + display: inline-block; + min-width: 34px; + margin-right: 6px; + padding: 2px 5px; + border-radius: 999px; + font-size: 9px; + line-height: 1.1; + text-align: center; + background: rgba(84,68,48,0.08); + color: rgba(72,58,43,0.72); + text-transform: uppercase; +} +.log-entry .time { color: var(--muted); margin-right: 6px; } +.log-birth { border-left-color: rgba(115, 185, 75, 0.66); } +.log-death { border-left-color: rgba(91, 83, 75, 0.60); } +.log-fight { border-left-color: rgba(214, 94, 70, 0.68); } +.log-food { border-left-color: rgba(118, 185, 77, 0.68); } +.log-grass { border-left-color: rgba(72, 148, 67, 0.68); } +.log-weather { border-left-color: rgba(92, 142, 210, 0.62); } +.log-relation { border-left-color: rgba(204, 126, 176, 0.62); } +.log-observe { border-left-color: rgba(175, 146, 86, 0.62); } + +@media (max-width: 980px) { + #app { padding: 10px; } + .topbar { align-items: flex-start; flex-direction: column; } + .top-left { align-items: flex-start; flex-direction: column; } + .brand { align-items: center; flex-direction: row; gap: 10px; } + .layout { grid-template-columns: 1fr; } + .panel { max-height: none; overflow: visible; } + #gameCanvas { height: var(--field-mobile-height, 66vh); min-height: var(--field-mobile-min-height, 460px); } + .stage-wrap { min-height: var(--field-mobile-min-height, 460px); } + .field-choice-grid { grid-template-columns: 1fr; } +} + + + + +.tree-note { + color: var(--muted); + font-size: 12px; + line-height: 1.45; + margin: 0 0 10px; + padding: 8px 10px; + border-radius: 10px; + background: rgba(255,255,255,0.54); + border: 1px solid rgba(84,68,48,0.10); +} + diff --git a/css/mobile.css b/css/mobile.css new file mode 100644 index 0000000..bb6cf29 --- /dev/null +++ b/css/mobile.css @@ -0,0 +1,226 @@ +/* Generated CSS split from styles.css; preserve load order. */ +.loading-screen.hidden { opacity: 0; visibility: hidden; pointer-events: none; } +.loading-kicker { font-size: 12px; letter-spacing: .14em; color: rgba(116,96,76,.82); margin-bottom: 6px; } +.loading-title { margin: 0 0 8px; font-size: 28px; color: #3f3429; } +.loading-text { margin: 0 0 12px; color: rgba(90,74,58,.86); } +.loading-sprite-strip { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 10px; margin: 8px 0 14px; } +.loading-sprite-card { border-radius: 16px; background: linear-gradient(180deg,rgba(255,255,255,.84),rgba(248,243,232,.90)); border: 1px solid rgba(126,104,80,.12); min-height: 92px; display: grid; place-items: center; padding: 8px; box-shadow: 0 8px 18px rgba(83,63,44,.06); } +.loading-sprite-card img { width: 68px; height: 68px; object-fit: contain; } +.loading-progress-track { width: 100%; height: 14px; border-radius: 999px; overflow: hidden; background: rgba(132,164,217,.16); border: 1px solid rgba(92,126,181,.14); } +.loading-progress-bar { height: 100%; border-radius: inherit; background: linear-gradient(90deg,#92d1ff,#a3dfa0 58%,#ffe192); transition: width .18s ease; } +.loading-progress-meta { margin-top: 8px; display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: rgba(88,73,60,.82); } +.loading-hint { margin: 10px 0 0; font-size: 12px; line-height: 1.55; color: rgba(111,92,73,.78); } + +.collapsible-card { padding-top: 10px; } +.panel-card-toggle { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px; border: 0; border-radius: 14px; padding: 10px 12px; cursor: pointer; font: inherit; color: var(--ink); background: rgba(255,255,255,.48); box-shadow: inset 0 1px 0 rgba(255,255,255,.54); } +.panel-card-title { font-size: 17px; font-weight: 700; letter-spacing: .03em; } +.panel-card-state { font-size: 12px; color: rgba(98,82,64,.78); padding-left: 16px; position: relative; } +.panel-card-state::before { content: "▾"; position: absolute; left: 0; top: 50%; transform: translateY(-52%); color: rgba(98,82,64,.72); } +.collapsible-card.collapsed .panel-card-state::before { content: "▸"; } +.collapsible-card.collapsed .panel-card-body { display: none; } +.panel-card-body { padding-top: 12px; } +.tool-card { background: linear-gradient(180deg, rgba(255,247,252,.92), rgba(249,240,249,.90)); border-color: rgba(200,153,186,.34); } +.colony-card { background: linear-gradient(180deg, rgba(244,250,238,.92), rgba(235,246,230,.90)); border-color: rgba(132,178,128,.34); } +.log-card { background: linear-gradient(180deg, rgba(255,246,238,.92), rgba(252,239,226,.90)); border-color: rgba(207,157,121,.34); } +.tool-card .panel-card-toggle { background: linear-gradient(180deg,rgba(255,239,248,.82),rgba(253,234,246,.84)); } +.colony-card .panel-card-toggle { background: linear-gradient(180deg,rgba(240,252,237,.82),rgba(230,247,228,.86)); } +.log-card .panel-card-toggle { background: linear-gradient(180deg,rgba(255,242,231,.84),rgba(253,235,220,.86)); } + +.sound-category-controls, +.log-push-controls { + margin-top: 10px; + padding: 10px; + border-radius: 14px; + border: 1px solid rgba(84,68,48,.12); + background: rgba(255,255,255,.46); + font-size: 12px; +} +.control-group-title { font-weight: 700; margin-bottom: 7px; color: rgba(58,48,39,.88); } +.sound-category-controls { display: grid; grid-template-columns: 1fr; gap: 6px; } +.sound-category-controls label, +.push-master, +.push-kind-grid label { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; } +.sound-category-controls input, +.push-master input, +.push-kind-grid input { accent-color: #82bf66; } +.log-push-controls { display: flex; flex-direction: column; gap: 8px; } +.push-kind-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px 8px; } +.log-push-overlay { position: fixed; left: 18px; bottom: 18px; z-index: 9998; width: min(320px, calc(100vw - 36px)); display: flex; flex-direction: column; gap: 8px; pointer-events: none; } +.log-push-toast { position: relative; overflow: hidden; padding: 10px 12px 10px 17px; border-radius: 15px; background: rgba(255,252,246,.94); border: 1px solid rgba(84,68,48,.16); box-shadow: 0 12px 32px rgba(44,34,25,.18); animation: logPushIn .18s ease-out; } +.log-push-toast::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 5px; background: #a5c77a; } +.log-push-toast .log-push-tag { display: inline-block; margin-right: 6px; font-size: 11px; font-weight: 700; color: rgba(54,45,38,.88); } +.log-push-toast .log-push-time { font-size: 10px; color: rgba(104,88,72,.72); } +.log-push-toast .log-push-text { margin-top: 3px; font-size: 12px; line-height: 1.35; color: rgba(48,40,33,.92); } +.log-push-toast.log-push-death::before { background: #8f817a; } +.log-push-toast.log-push-accident::before { background: #ee9e5d; } +.log-push-toast.log-push-birth::before { background: #98cf7a; } +.log-push-toast.log-push-fight::before { background: #e47b80; } +.log-push-toast.log-push-relation::before { background: #b99be0; } +.log-push-toast.log-push-food::before { background: #e9bd61; } +.log-push-toast.log-push-weather::before { background: #7bbbdc; } +.log-push-toast.log-push-grass::before { background: #8cc77a; } +.log-push-toast.leaving { opacity: 0; transform: translateY(8px); transition: opacity .22s ease, transform .22s ease; } +@keyframes logPushIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } +@media (max-width: 920px) { .loading-sprite-strip { grid-template-columns: repeat(2,minmax(0,1fr)); } } + + +/* v15.12.1: top-right sound settings panel */ +.sound-menu { position: relative; display: inline-block; } +.sound-menu-btn.active { background: linear-gradient(180deg, #f3ffe9, #e7f8db); border-color: rgba(103,178,44,.46); } +.sound-panel { + position: absolute; + right: 0; + top: calc(100% + 8px); + z-index: 12000; + min-width: 210px; + padding: 11px; + border-radius: 16px; + border: 1px solid rgba(84,68,48,.16); + background: rgba(255,252,246,.98); + box-shadow: 0 16px 42px rgba(44,34,25,.20); + display: grid; + gap: 7px; + text-align: left; +} +.sound-panel.hidden { display: none; } +.sound-panel label { display: flex; align-items: center; gap: 7px; font-size: 12px; cursor: pointer; white-space: nowrap; } +.sound-panel input { accent-color: #82bf66; } +.sound-panel input:disabled + span { opacity: .55; } +.sound-master { font-weight: 700; } +.sound-panel-divider { height: 1px; background: rgba(84,68,48,.12); margin: 2px 0; } +@media (max-width: 760px) { .sound-panel { right: auto; left: 0; } } + + +/* v15.12.3: collapsed event panel should be genuinely thin */ +.log-card.collapsed { + min-height: 0 !important; + padding: 5px 7px !important; + flex: 0 0 auto !important; +} +.log-card.collapsed .panel-card-toggle { + min-height: 30px; + padding: 5px 9px; + border-radius: 11px; +} +.log-card.collapsed .panel-card-title { + font-size: 13px; + line-height: 1.1; +} +.log-card.collapsed .panel-card-state { + font-size: 10px; +} + + +/* v15.12.4: event log scroll chains to the right menu at top/bottom */ +.log { + overscroll-behavior-y: auto !important; +} + +/* v15.12.4: sound settings live only in the top-right sound menu */ +.log-card .sound-category-controls { + display: none !important; +} + +/* v15.17.0: mobile layout isolation and canvas touch gestures */ +#app { overflow-x: clip; } +.layout { position: relative; z-index: 2; } +.panel { position: relative; z-index: 3; } +.lineage-main-card { + position: relative; + z-index: 1; + overflow: hidden; + contain: layout paint; +} +#gameCanvas { + touch-action: none; + -webkit-user-select: none; + user-select: none; +} +.archive-content, +.lineage-main-content, +.lineage-family-tree { + max-width: 100%; + box-sizing: border-box; +} +@media (max-width: 980px) { + .layout { + position: relative; + z-index: 4; + } + .panel { + position: relative; + z-index: 5; + isolation: isolate; + } + .lineage-main-card { + z-index: 1; + width: 100%; + max-width: 100%; + margin-top: 14px; + clear: both; + } + .lineage-main-content { + height: auto; + min-height: 340px; + max-height: 72vh; + overflow: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; + touch-action: pan-x pan-y pinch-zoom; + } + .lineage-family-tree { + overflow: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; + touch-action: pan-x pan-y pinch-zoom; + } + .lineage-family-tree .lineage-tree-panel { + max-width: none; + } +} + +/* v15.18.0: item icons and mobile input mode */ +.tool[data-tool="laxative"] { --tool-icon: url("../assets/ui/tool_laxative.webp?v=15.19.1"); } +.tool[data-tool="protein"] { --tool-icon: url("../assets/ui/tool_protein.webp?v=15.19.1"); } +.tool[data-tool="niteropu"] { --tool-icon: url("../assets/ui/tool_niteropu.webp?v=15.19.1"); } +.tool[data-tool="ammo"] { --tool-icon: url("../assets/ui/tool_ammo.webp?v=15.19.1"); } +.tool[data-tool="mystery_drug"] { --tool-icon: url("../assets/ui/tool_mystery_drug.webp?v=15.19.1"); } +.tool[data-tool="mercury"] { --tool-icon: url("../assets/ui/tool_mercury.webp?v=15.19.1"); } +.tool[data-tool="giant_drug"] { --tool-icon: url("../assets/ui/tool_giant_drug.webp?v=15.19.1"); } +.tool[data-tool="dwarf_drug"] { --tool-icon: url("../assets/ui/tool_dwarf_drug.webp?v=15.19.1"); } +.tool[data-tool="zunda_juice"] { --tool-icon: url("../assets/ui/tool_zunda_juice.webp?v=15.19.1"); } +.mobile-mode-controls { + display: none; + position: absolute; + left: 10px; + bottom: 10px; + z-index: 24; + gap: 5px; + padding: 6px; + border-radius: 14px; + background: rgba(255, 251, 245, 0.90); + box-shadow: 0 8px 22px rgba(80,60,35,.18); + border: 1px solid rgba(120, 95, 60, .16); + backdrop-filter: blur(8px); +} +.mobile-mode-controls button { + border: 0; + border-radius: 10px; + padding: 7px 8px; + font-size: 12px; + font-weight: 800; + color: #65533f; + background: rgba(255,255,255,.78); + box-shadow: inset 0 -1px 0 rgba(0,0,0,.05); +} +.mobile-mode-controls button.active { + color: #3d321f; + background: linear-gradient(180deg, #ffe9a8, #ffd376); + box-shadow: 0 3px 10px rgba(150, 105, 30, .20); +} +@media (pointer: coarse), (max-width: 760px) { + .mobile-mode-controls { display: flex; } + body.mobile-mode-camera #gameCanvas { cursor: grab; } + body.mobile-mode-tool #gameCanvas { cursor: crosshair; } + body.mobile-mode-family .lineage-main-card { z-index: 9; } +} diff --git a/css/panel.css b/css/panel.css new file mode 100644 index 0000000..70d357c --- /dev/null +++ b/css/panel.css @@ -0,0 +1,396 @@ +/* Generated CSS split from styles.css; preserve load order. */ +.lineage-tree { + overflow: auto; + padding: 8px 10px 18px; + contain: content; +} + +.lineage-main-card { + margin-top: 16px; + min-height: 0; +} + +.lineage-main-card h2 { + margin-bottom: 6px; +} + +.lineage-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 8px; + flex-wrap: wrap; +} + +.lineage-head h2 { margin-bottom: 0; } + +.lineage-main-content { + height: min(78vh, 980px); + min-height: 520px; + max-height: calc(100vh - 120px); + overflow: auto; + overscroll-behavior: auto; + padding: 10px 6px 24px; + background: rgba(255,250,244,0.48); + border-radius: 14px; + border: 1px solid rgba(84,68,48,0.10); + scrollbar-gutter: stable both-edges; +} + +.lineage-forest { + display: flex; + flex-direction: column; + gap: 12px; +} + +.lineage-main-content .lineage-tree { + min-width: 360px; + overflow: visible; + padding-right: 2px; +} + + +body::before { + content: ""; + position: fixed; + inset: 0; + pointer-events: none; + background: + radial-gradient(circle at 8% 20%, rgba(255,255,255,0.62), transparent 16%), + radial-gradient(circle at 92% 18%, rgba(255,255,255,0.45), transparent 18%), + linear-gradient(180deg, transparent 0%, rgba(114, 152, 78, 0.05) 100%); +} + + +.stage-wrap::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient(circle at 18% 14%, rgba(255,255,255,0.12), transparent 18%), + radial-gradient(circle at 84% 10%, rgba(255,255,255,0.09), transparent 16%), + linear-gradient(180deg, rgba(255,255,255,0.07), transparent 24%); + z-index: 1; +} +#gameCanvas { + position: relative; + z-index: 0; +} + +.card::after { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + border-radius: inherit; + box-shadow: inset 0 1px 0 rgba(255,255,255,0.55); +} + +/* Family tree node primitives. The archive deliberately uses these nodes inside an SVG-backed tree, not the old card/grid UI. */ +.family-node { + position: relative; + display: block; + min-width: 0; + min-height: 34px; + padding: 6px 8px; + border-radius: 10px; + background: linear-gradient(180deg, rgba(255,253,248,0.96), rgba(248,241,229,0.90)); + border: 1px solid rgba(84,68,48,0.14); + box-shadow: 0 3px 8px rgba(64,48,32,0.045); + overflow: hidden; + isolation: isolate; +} +.family-node.child { + border-color: rgba(103, 178, 44, 0.38); + box-shadow: inset 0 0 0 1px rgba(156,232,75,0.17), 0 3px 8px rgba(64,48,32,0.045); +} +.family-node[data-family-tarinai-id] { cursor: pointer; transition: transform .12s ease, border-color .12s ease, box-shadow .12s ease; } +.family-node[data-family-tarinai-id]:hover { transform: translateY(-1px); border-color: rgba(112,178,66,0.42); box-shadow: 0 5px 12px rgba(64,48,32,0.08); } +.family-node.dead { opacity: 0.9; filter: grayscale(0.32); } +.family-node.missing { opacity: 0.48; border-style: dashed; } +.family-portrait { + position: absolute; + right: -6px; + bottom: -8px; + width: 64px; + height: 64px; + z-index: 0; + pointer-events: none; +} +.family-node.alive .family-portrait { opacity: 0.80; } +.family-node.dead .family-portrait { opacity: 0.20; } +.family-portrait img { + width: 100%; + height: 100%; + object-fit: contain; + filter: saturate(0.95); +} +.family-copy { position: relative; z-index: 1; min-width: 0; line-height: 1.12; max-width: calc(100% - 8px); } +.family-copy strong, .family-copy span { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.family-copy .death-reason { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: 1.12; + margin-top: 1px; + color: rgba(126, 80, 64, 0.92); +} +.family-copy strong { font-size: 11px; } +.family-copy span { color: var(--muted); font-size: 8.5px; margin-top: 1px; } + + +.colony-card { overflow: visible; min-height: 0; flex: 0 0 auto; } +.colony-stats { + grid-template-columns: repeat(2, 1fr); + margin-bottom: 8px; +} +.colony-chart { + display: block; + width: 100%; + height: 188px; + min-height: 188px; + border: 1px solid rgba(84, 68, 48, 0.14); + border-radius: 14px; + background: linear-gradient(180deg, rgba(255,255,255,0.70), rgba(246,240,228,0.54)); + overflow: hidden; +} +.colony-card h2 { line-height: 1.45; margin-bottom: 10px; } +.colony-chart svg { display: block; width: 100%; height: 100%; } +.colony-chart-legend { + display: flex; + flex-wrap: wrap; + gap: 4px 8px; + align-items: center; + margin: 4px 0 8px; + font-size: 11px; + color: var(--muted); + line-height: 1.25; +} +.colony-chart-legend span { + display: inline-flex; + align-items: center; + gap: 4px; + white-space: nowrap; +} +.colony-chart-legend i { + width: 8px; + height: 8px; + border-radius: 999px; + display: inline-block; + box-shadow: 0 0 0 1px rgba(70, 52, 36, 0.10); +} + +.relation-row strong { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; } +.relation-face { + width: 24px; + height: 24px; + object-fit: contain; + border-radius: 999px; + background: rgba(255,255,255,0.66); + border: 1px solid rgba(84,68,48,0.12); + vertical-align: middle; + flex: 0 0 auto; +} + + +.lineage-family { + padding: 10px; + margin: 0 0 12px; + border-radius: 15px; + background: rgba(255,253,248,0.62); + border: 1px solid rgba(84,68,48,0.12); +} +.lineage-family h3 { + margin: 0 0 8px; + font-size: 13px; + color: rgba(64,52,38,0.86); +} +/* Family archive: actual top-down tree diagram. */ +.lineage-family-tree { + overflow-x: auto; + overflow-y: visible; + padding: 10px 10px 22px; + -webkit-overflow-scrolling: touch; + overscroll-behavior-x: contain; +} +.lineage-family-tree h3 { + position: sticky; + left: 0; + z-index: 3; + width: max-content; + padding-right: 12px; + background: rgba(255,253,248,0.82); + border-radius: 8px; +} +.lineage-tree-hint { + position: sticky; + left: 0; + z-index: 3; + width: max-content; + max-width: 100%; + margin: -2px 0 8px; + padding: 5px 8px; + border-radius: 9px; + color: var(--muted); + font-size: 11px; + background: rgba(255,255,255,0.62); + border: 1px solid rgba(84,68,48,0.08); +} +.lineage-family-tree .lineage-tree-panel { + position: relative; + overflow: visible; + min-width: 360px; + margin-top: 6px; + border-radius: 14px; + background: + linear-gradient(90deg, rgba(84,68,48,0.045) 1px, transparent 1px), + linear-gradient(180deg, rgba(84,68,48,0.040) 1px, transparent 1px), + rgba(255,250,244,0.48); + background-size: 34px 34px, 34px 34px, auto; + border: 1px solid rgba(84,68,48,0.10); +} +.lineage-family-tree .lineage-links { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + overflow: visible; + pointer-events: none; + z-index: 1; + isolation: isolate; +} + +.lineage-actions { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; + justify-content: flex-end; +} +.btn.active { + background: #efffde; + border-color: rgba(103,178,44,0.46); + font-weight: 700; +} + +.lineage-render-status { + position: sticky; + top: 0; + left: 0; + z-index: 6; + width: max-content; + margin: 0 0 8px; + padding: 6px 10px; + border-radius: 999px; + font-size: 12px; + color: var(--muted); + background: rgba(255,255,255,0.88); + border: 1px solid rgba(84,68,48,0.10); + box-shadow: 0 4px 10px rgba(64,48,32,0.06); +} +.lineage-stale-status { + position: sticky; + top: 0; + left: 0; + z-index: 6; + width: max-content; + max-width: calc(100% - 12px); + margin: 0 0 8px; + padding: 6px 10px; + border-radius: 999px; + font-size: 12px; + color: rgba(92, 75, 52, 0.82); + background: rgba(255, 249, 232, 0.92); + border: 1px solid rgba(150, 115, 46, 0.16); + box-shadow: 0 4px 10px rgba(64,48,32,0.05); +} +.lineage-family-tree .lineage-links path { + fill: none; + stroke: rgba(107, 88, 61, 0.58); + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; +} +.lineage-family-tree .lineage-links .partner-link { + stroke-width: 2.4; + stroke: rgba(98, 80, 56, 0.68); + stroke-dasharray: 5 4; +} +.lineage-family-tree .lineage-links .child-link { + stroke-width: 2; + stroke: rgba(107, 88, 61, 0.58); +} +.lineage-family-tree .tree-node { + position: absolute; + width: 132px; + height: 68px; + min-height: 68px; + box-sizing: border-box; + align-items: flex-start; + background: linear-gradient(180deg, #fffdf8, #f8f1e5); + box-shadow: 0 2px 5px rgba(64,48,32,0.035); + contain: layout paint style; + z-index: 2; + isolation: isolate; +} +.lineage-family-tree .tree-node.child { + border-color: rgba(103,178,44,0.34); +} +.lineage-family-tree .tree-node.dead { + opacity: 1; + filter: none; +} +.lineage-family-tree .tree-node[data-family-tarinai-id]:hover { + transform: none; +} +.lineage-family-tree .tree-node .family-portrait { + right: 0; + bottom: -6px; + width: 58px; + height: 58px; +} +.lineage-family-tree .tree-generation-label { + position: absolute; + left: 10px; + width: 54px; + padding: 3px 0; + border-radius: 999px; + font-size: 10px; + color: var(--muted); + text-align: center; + background: rgba(255,255,255,0.70); + border: 1px solid rgba(84,68,48,0.08); + z-index: 2; +} +.lineage-family-tree .lineage-empty-family { + position: absolute; + left: 72px; + bottom: 8px; + padding: 5px 8px; + border-radius: 9px; + background: rgba(255,255,255,0.70); +} + +@media (max-width: 720px) { + .ecology-grid { grid-template-columns: 1fr; } + .ecology-card { grid-template-columns: 68px minmax(0, 1fr); } + .ecology-card img { width: 68px; height: 68px; } +} + +@media (max-width: 720px) { + .lineage-main-content { + height: 70vh; + min-height: 420px; + max-height: none; + } +} + + +.tool[data-tip] { position: relative; } diff --git a/css/styles.css b/css/styles.css index c41a5e0..73fb48b 100644 --- a/css/styles.css +++ b/css/styles.css @@ -1,1293 +1 @@ -@import url("https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic:wght@400;500;700&family=M+PLUS+Rounded+1c:wght@400;500;700&family=Yomogi&display=swap"); - -:root { - --bg: #f7f5ec; - --panel: rgba(255,251,245,0.88); - --ink: #2a241d; - --muted: #756a5e; - --line: rgba(84, 68, 48, 0.18); - --accent: #9ce84b; - --accent-2: #f5a8b7; - --danger: #b64545; - --shadow: 0 18px 50px rgba(64, 48, 32, 0.14); - --radius: 18px; - --bubble-font: "Yomogi", "Zen Maru Gothic", "M PLUS Rounded 1c", ui-rounded, sans-serif; -} - -* { box-sizing: border-box; } - -body { - margin: 0; - font-family: "Zen Maru Gothic", "M PLUS Rounded 1c", ui-rounded, "Hiragino Maru Gothic ProN", "Yu Gothic", "Meiryo", system-ui, sans-serif; - background: - radial-gradient(circle at 12% 0%, rgba(168, 228, 113, 0.28), transparent 33%), - radial-gradient(circle at 88% 8%, rgba(255, 222, 147, 0.24), transparent 28%), - radial-gradient(circle at 82% 90%, rgba(126, 181, 120, 0.16), transparent 34%), - linear-gradient(180deg, #dff0ff 0%, #edf8ff 12%, #f9f6eb 46%, var(--bg) 100%); - color: var(--ink); - min-height: 100vh; - overflow-x: hidden; - position: relative; -} - -button { - font: inherit; - color: inherit; -} - -.loading-screen { - position: fixed; - inset: 0; - z-index: 9999; - display: grid; - place-items: center; - padding: 24px; - background: - radial-gradient(circle at 50% 30%, rgba(164, 225, 104, 0.22), transparent 32%), - linear-gradient(180deg, rgba(239, 248, 255, 0.98), rgba(247, 245, 236, 0.98)); - transition: opacity 180ms ease, visibility 180ms ease; -} -.loading-screen.hidden { - opacity: 0; - visibility: hidden; - pointer-events: none; -} -.loading-panel { - width: min(420px, 92vw); - padding: 24px 22px; - border-radius: 24px; - border: 1px solid rgba(84, 68, 48, 0.16); - background: rgba(255, 252, 246, 0.92); - box-shadow: 0 18px 48px rgba(64, 48, 32, 0.16); - text-align: center; -} -.loading-title { - font-weight: 700; - font-size: 18px; - letter-spacing: 0.04em; - margin-bottom: 8px; -} -.loading-text { - color: var(--muted); - font-size: 13px; - line-height: 1.55; - min-height: 1.55em; -} -.loading-bar { - height: 12px; - margin: 18px 0 8px; - border-radius: 999px; - overflow: hidden; - background: rgba(90, 70, 48, 0.12); -} -.loading-bar-fill { - width: 0%; - height: 100%; - border-radius: inherit; - background: linear-gradient(90deg, #9ce84b, #f0d35b); - transition: width 160ms ease; -} -.loading-percent { - color: var(--muted); - font-size: 12px; - font-variant-numeric: tabular-nums; -} - -#app { - width: min(1480px, 100vw); - margin: 0 auto; - padding: 18px; - position: relative; -} - -.topbar { - display: flex; - justify-content: space-between; - gap: 18px; - align-items: center; - margin-bottom: 16px; -} - -.top-left { - display: flex; - align-items: center; - gap: 12px; - min-width: 0; -} - -.brand { - display: flex; - align-items: center; - gap: 10px; - flex-wrap: nowrap; - min-width: 0; -} - -.room-link { - text-decoration: none; - white-space: nowrap; - background: rgba(255,255,255,0.86); -} - -h1 { - margin: 0; - font-size: clamp(24px, 3.4vw, 42px); - letter-spacing: 0.03em; - white-space: nowrap; -} - -.subtitle { - margin: 0; - color: var(--muted); - font-size: clamp(11px, 1.1vw, 13px); - line-height: 1.35; - white-space: nowrap; -} - -.top-actions { - display: flex; - gap: 8px; - flex-wrap: wrap; - justify-content: flex-end; -} - -.btn, .tool { - border: 1px solid var(--line); - background: rgba(255,255,255,0.76); - border-radius: 999px; - padding: 9px 13px; - cursor: pointer; - box-shadow: 0 4px 14px rgba(80,60,40,0.06); - transition: transform 130ms ease, background 130ms ease, border-color 130ms ease; - user-select: none; -} - -.btn:hover, .tool:hover { transform: translateY(-1px); background: #fff; } -.btn:active, .tool:active { transform: translateY(1px); } - -.btn.primary { - background: linear-gradient(180deg, #a9ef5d, #8bdc3f); - border-color: rgba(89, 128, 47, 0.28); -} - -.btn.danger { - color: #7a2828; -} - -.layout { - display: grid; - grid-template-columns: minmax(520px, 1fr) 380px; - gap: 16px; - align-items: stretch; -} - -.stage-wrap { - position: relative; - background: linear-gradient(180deg, rgba(255,255,255,0.46), rgba(246, 240, 228, 0.56)); - border: 1px solid rgba(84, 68, 48, 0.12); - border-radius: calc(var(--radius) + 8px); - overflow: hidden; - box-shadow: 0 16px 42px rgba(42, 45, 80, 0.12), inset 0 0 0 1px rgba(255,255,255,0.24); - min-height: var(--field-min-height, 620px); -} - -#gameCanvas { - width: 100%; - height: var(--field-height, calc(100vh - 140px)); - min-height: var(--field-min-height, 620px); - display: block; - cursor: crosshair; - background: linear-gradient(180deg, #cfe3d3, #d9d0ad); -} - -.field-dialog { - position: fixed; - inset: 0; - z-index: 30; - display: grid; - place-items: center; - padding: 18px; - background: rgba(34, 29, 22, 0.38); - backdrop-filter: blur(3px); -} -.field-dialog.hidden { display: none; } -.field-dialog-panel { - width: min(440px, 100%); - max-height: calc(100vh - 36px); - overflow: auto; - border-radius: 16px; - padding: 16px; - background: rgba(255, 252, 245, 0.96); - border: 1px solid rgba(84,68,48,0.16); - box-shadow: 0 18px 46px rgba(40, 32, 24, 0.22); -} -.field-dialog-panel h2 { - margin: 0 0 12px; - font-size: 17px; -} -.field-choice-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 8px; -} -.field-choice { - min-height: 74px; - border: 1px solid rgba(84,68,48,0.16); - border-radius: 12px; - background: linear-gradient(180deg, rgba(255,255,255,0.86), rgba(241,235,221,0.72)); - cursor: pointer; - color: var(--ink); -} -.field-choice:hover { border-color: rgba(112,178,66,0.45); } -.field-choice strong, .field-choice span { display: block; } -.field-choice strong { font-size: 15px; } -.field-choice span { margin-top: 4px; color: var(--muted); font-size: 12px; } -.field-dialog-actions { - margin-top: 12px; - display: flex; - justify-content: flex-end; - gap: 8px; -} -.archive-reset-dialog-panel { - width: min(420px, 100%); -} -.archive-reset-actions { - justify-content: space-between; - gap: 10px; -} -.archive-reset-actions .btn { - min-width: 132px; -} - - -.ecology-dialog-panel { - width: min(760px, 100%); - max-height: calc(100vh - 36px); - overflow-y: auto; - overscroll-behavior: contain; -} -.ecology-grid { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 10px; -} -.ecology-card { - display: grid; - grid-template-columns: 72px minmax(0, 1fr); - gap: 10px; - align-items: center; - padding: 10px; - border-radius: 14px; - background: linear-gradient(180deg, rgba(255,255,255,0.88), rgba(243,237,225,0.76)); - border: 1px solid rgba(84,68,48,0.12); -} -.ecology-card img { - width: 72px; - height: 72px; - object-fit: contain; - filter: drop-shadow(0 8px 18px rgba(56, 44, 32, 0.10)); -} -.ecology-card strong { - display: block; - margin-bottom: 4px; - font-size: 15px; -} -.ecology-card p { - margin: 0; - color: var(--muted); - font-size: 12px; - line-height: 1.40; -} - -.toast { - position: absolute; - left: 50%; - bottom: 22px; - transform: translateX(-50%); - background: rgba(42,36,29,0.86); - color: white; - padding: 10px 16px; - border-radius: 999px; - font-size: 14px; - pointer-events: none; - opacity: 1; - transition: opacity 200ms ease, transform 200ms ease; -} -.toast.hidden { opacity: 0; transform: translateX(-50%) translateY(8px); } - -.panel { - display: flex; - flex-direction: column; - gap: 12px; - height: calc(100vh - 120px); - max-height: calc(100vh - 120px); - overflow-y: auto; - overflow-x: hidden; - padding-right: 3px; -} - -.card { - position: relative; - background: var(--panel); - border: 1px solid var(--line); - border-radius: var(--radius); - padding: 14px; - box-shadow: 0 10px 30px rgba(64, 48, 32, 0.08); - backdrop-filter: blur(10px); - position: relative; -} - -.card h2 { - margin: 0 0 12px; - font-size: 17px; - letter-spacing: 0.03em; -} - -.tool-grid { - display: grid; - grid-template-columns: repeat(2, minmax(0,1fr)); - gap: 8px; -} - -.tool { - border-radius: 14px; - display: flex; - align-items: center; - gap: 7px; - justify-content: flex-start; - padding: 8px 8px 8px 42px; - min-height: 46px; - position: relative; - overflow: hidden; - background-repeat: no-repeat; - background-position: 7px center, center; - background-size: 30px 30px, cover; -} -.tool::before { - content: ""; - position: absolute; - left: 7px; - top: 50%; - width: 30px; - height: 30px; - transform: translateY(-50%); - background: var(--tool-icon) center / contain no-repeat; - opacity: 0.92; - filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); -} -.tool::after { - content: ""; - position: absolute; - inset: 0; - background: var(--tool-icon) right -8px center / 54px 54px no-repeat; - opacity: 0.10; - pointer-events: none; -} -.tool > span:not(.tool-size-badge) { display: none; } -.tool[data-tool="observe"] { --tool-icon: url("../assets/ui/tool_observe.png"); } -.tool[data-tool="zunchi"] { --tool-icon: url("../assets/ui/tool_zunchi.png"); } -.tool[data-tool="sweet"] { --tool-icon: url("../assets/ui/tool_sweet.png"); } -.tool[data-tool="grass"] { --tool-icon: url("../assets/ui/tool_grass.png"); } -.tool[data-tool="stone"] { --tool-icon: url("../assets/ui/tool_stone.png"); } -.tool[data-tool="genkotsu"] { --tool-icon: url("../assets/ui/tool_genkotsu.png"); } -.tool[data-tool="firecracker"] { --tool-icon: url("../assets/ui/tool_firecracker.png"); } -.tool[data-tool="fence_v"] { --tool-icon: url("../assets/ui/tool_fence_v.png"); } -.tool[data-tool="fence_h"] { --tool-icon: url("../assets/ui/tool_fence_h.png"); } -.tool[data-tool="bed"] { --tool-icon: url("../assets/ui/tool_bed.png"); } -.tool[data-tool="love_mochi"] { --tool-icon: url("../assets/ui/tool_love_mochi.png"); } -.tool[data-tool="fight_mochi"] { --tool-icon: url("../assets/ui/tool_fight_mochi.png"); } -.tool[data-tool="water_bowl"] { --tool-icon: url("../assets/ui/tool_water_bowl.png"); } -.tool[data-tool="sleep_drug"] { --tool-icon: url("../assets/ui/tool_sleep_drug.png"); } -.tool[data-tool="nest_box"] { --tool-icon: url("../assets/ui/tool_nest_box.png"); } -.tool[data-tool="ant_nest"] { --tool-icon: url("../assets/ui/tool_ant_nest.png"); } -.tool[data-tool="ball"] { --tool-icon: url("../assets/ui/tool_ball.png"); } -.tool[data-tool="poke"] { --tool-icon: none; } -.tool[data-tool="poke"]::before { - content: "\1F448"; - background: none; - font-size: 25px; - line-height: 1; - filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); -} -.tool[data-tool="poke"]::after { - content: "\1F448"; - background: none; - font-size: 48px; - line-height: 1; - opacity: 0.11; - right: -6px; - left: auto; - top: 50%; - bottom: auto; - transform: translateY(-50%); - width: 54px; - height: 54px; -} - -.tool[data-tool="pinch"] { --tool-icon: none; } -.tool[data-tool="pinch"]::before { - content: "\1F90F"; - background: none; - font-size: 25px; - line-height: 1; - filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); -} -.tool[data-tool="pinch"]::after { - content: "\1F90F"; - background: none; - font-size: 48px; - line-height: 1; - opacity: 0.10; - right: -6px; - left: auto; - top: 50%; - bottom: auto; - transform: translateY(-50%); - width: 54px; - height: 54px; -} -.tool[data-tool="water_hose"] { --tool-icon: none; } -.tool[data-tool="water_hose"]::before { - content: "\1F6BF"; - background: none; - font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif; - font-size: 24px; - line-height: 1; - filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); -} -.tool[data-tool="water_hose"]::after { - content: "\1F6BF"; - background: none; - font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif; - font-size: 46px; - line-height: 1; - opacity: 0.10; - right: -6px; - left: auto; - top: 50%; - bottom: auto; - transform: translateY(-50%); - width: 54px; - height: 54px; -} - -.tool[data-tool="delete"] { --tool-icon: url("../assets/ui/tool_delete.png"); } -.tool[data-tool="new"] { --tool-icon: url("../assets/ui/tool_new.png"); } -.tool.selected { - background: linear-gradient(180deg, #ffffff, #efffde); - border-color: rgba(103, 178, 44, 0.52); - box-shadow: inset 0 0 0 1px rgba(156,232,75,0.38), 0 8px 20px rgba(117, 166, 64, 0.13); -} - -.hint { - color: var(--muted); - font-size: 12px; - line-height: 1.40; - margin: 10px 0 0; -} - -.tool-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; } -.tool-head h2 { margin-bottom: 0; } -.btn.mini { padding: 6px 10px; font-size: 12px; } -.tool-body { margin-top: 12px; } -.tool-palette { display: flex; flex-direction: column; gap: 9px; } -.tool-category { - border: 1px solid rgba(84,68,48,0.10); - border-radius: 14px; - background: rgba(255,255,255,0.34); - overflow: hidden; -} -.tool-category-toggle { - width: 100%; - border: 0; - border-bottom: 1px solid rgba(84,68,48,0.08); - background: rgba(255,252,244,0.66); - padding: 8px 10px; - text-align: left; - cursor: pointer; - font-weight: 700; - font-size: 12px; -} -.tool-category-toggle::before { content: "\25be "; display: inline-block; width: 16px; color: var(--muted); } -.tool-category.collapsed .tool-category-toggle::before { content: "\25b8 "; } -.tool-category-body { padding: 8px; } -.tool-category.collapsed .tool-category-body { display: none; } - -.selected-data-groups { - display: flex; - flex-direction: column; - gap: 8px; - margin-top: 8px; -} -.selected-category { - border: 1px solid rgba(84,68,48,0.10); - border-radius: 14px; - background: rgba(255,255,255,0.30); - overflow: hidden; -} -.selected-category-toggle { - width: 100%; - border: 0; - border-bottom: 1px solid rgba(84,68,48,0.08); - background: rgba(255,252,244,0.66); - padding: 8px 10px; - text-align: left; - cursor: pointer; - font-weight: 700; - font-size: 12px; - color: var(--ink); -} -.selected-category-toggle::before { content: "\25be "; display: inline-block; width: 16px; color: var(--muted); } -.selected-category.collapsed .selected-category-toggle::before { content: "\25b8 "; } -.selected-category-body { padding: 7px 9px; } -.selected-category.collapsed .selected-category-body { display: none; } -.selected-category-body .info-row:last-child { border-bottom: 0; } -.tool-size-badge { - position: absolute; - right: 7px; - bottom: 6px; - min-width: 20px; - padding: 2px 5px; - border-radius: 999px; - background: rgba(42,36,29,0.68); - color: #fff; - font-size: 10px; - line-height: 1; - text-align: center; - box-shadow: 0 1px 4px rgba(42,36,29,0.16); - pointer-events: none; -} -.chart-tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; margin: 3px 0 8px; } -.chart-tabs button { border: 1px solid var(--line); background: rgba(255,255,255,0.62); border-radius: 999px; padding: 5px 4px; font-size: 11px; cursor: pointer; } -.chart-tabs button.active { background: #efffde; border-color: rgba(103,178,44,0.46); font-weight: 700; } -.log-accident { border-left-color: rgba(226, 136, 54, 0.76); } - - -.stats { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 8px; - margin-bottom: 12px; -} - -.stat { - background: linear-gradient(180deg, rgba(255,255,255,0.58), rgba(246, 240, 228, 0.72)); - border: 1px solid var(--line); - border-radius: 13px; - padding: 9px 8px; - text-align: center; -} -.stat span { display: block; font-size: 11px; color: var(--muted); } -.stat strong { font-size: 18px; } - -.meter-row { - display: grid; - grid-template-columns: 72px 1fr; - align-items: center; - gap: 8px; - font-size: 12px; - margin: 6px 0; -} -meter { - width: 100%; - height: 12px; - accent-color: var(--accent); -} - - -.selected-card.hidden { display: none; } -.selected-head { - display: flex; - align-items: center; - justify-content: space-between; - gap: 8px; - margin-bottom: 8px; -} -.selected-head h2 { margin-bottom: 0; } -.selected-close { - width: 28px; - height: 28px; - border: 1px solid rgba(84,68,48,0.16); - border-radius: 999px; - background: rgba(255,255,255,0.76); - color: rgba(76,58,42,0.78); - font-size: 20px; - line-height: 24px; - cursor: pointer; - display: grid; - place-items: center; - padding: 0; -} -.selected-close:hover { background: #fff; } - -.selected-info { - font-size: 13px; - line-height: 1.40; -} -.selected-info.empty { - color: var(--muted); -} - -.selected-name-editor { - margin: 0 0 8px; -} -.selected-name-input { - width: 100%; - box-sizing: border-box; - border: 1px solid rgba(103,178,44,0.34); - border-radius: 13px; - background: rgba(246,252,238,0.96); - color: var(--ink); - font-size: 18px; - font-weight: 700; - line-height: 1.25; - padding: 8px 10px; - box-shadow: inset 0 1px 0 rgba(255,255,255,0.82); -} -.selected-name-input:focus { - outline: 2px solid rgba(103,178,44,0.24); - border-color: rgba(103,178,44,0.62); - background: #fff; -} -.selected-effects { - margin: 2px 0 6px; -} -.badge { - display: inline-block; - font-size: 11px; - line-height: 1; - border-radius: 999px; - padding: 5px 8px; - background: #f1f8e9; - border: 1px solid rgba(103, 178, 44, 0.28); - margin: 0 4px 4px 0; -} -.info-row { - display: flex; - justify-content: space-between; - gap: 10px; - border-bottom: 1px dashed rgba(84,68,48,0.16); - padding: 5px 0; -} -.info-row span:first-child { color: var(--muted); } -.personality-values strong { - display: flex; - flex-wrap: wrap; - justify-content: flex-end; - gap: 2px 8px; - max-width: 68%; - text-align: right; -} -.personality-values strong span { - color: var(--ink); - white-space: nowrap; -} -.personality-tag { - display: inline-block; - border-radius: 999px; - padding: 2px 7px; - background: rgba(103,178,44,0.10); - border: 1px solid rgba(103,178,44,0.22); -} -.personality-tag.neutral { - background: rgba(120,110,90,0.08); - border-color: rgba(120,110,90,0.16); -} - -.log-card { min-height: 260px; flex: 0 0 auto; display: flex; flex-direction: column; } -.log { - max-height: 360px; - min-height: 170px; - flex: 1 1 auto; - overflow: auto; - display: flex; - flex-direction: column; - gap: 7px; - font-size: 12px; - overscroll-behavior: contain; -} -.log-entry { - padding: 8px 9px; - border-radius: 12px; - background: rgba(255,252,246,0.82); - border: 1px solid rgba(84,68,48,0.12); - border-left: 4px solid rgba(118, 101, 74, 0.24); -} -.log-tag { - display: inline-block; - min-width: 34px; - margin-right: 6px; - padding: 2px 5px; - border-radius: 999px; - font-size: 9px; - line-height: 1.1; - text-align: center; - background: rgba(84,68,48,0.08); - color: rgba(72,58,43,0.72); - text-transform: uppercase; -} -.log-entry .time { color: var(--muted); margin-right: 6px; } -.log-birth { border-left-color: rgba(115, 185, 75, 0.66); } -.log-death { border-left-color: rgba(91, 83, 75, 0.60); } -.log-fight { border-left-color: rgba(214, 94, 70, 0.68); } -.log-food { border-left-color: rgba(118, 185, 77, 0.68); } -.log-grass { border-left-color: rgba(72, 148, 67, 0.68); } -.log-weather { border-left-color: rgba(92, 142, 210, 0.62); } -.log-relation { border-left-color: rgba(204, 126, 176, 0.62); } -.log-observe { border-left-color: rgba(175, 146, 86, 0.62); } - -@media (max-width: 980px) { - #app { padding: 10px; } - .topbar { align-items: flex-start; flex-direction: column; } - .top-left { align-items: flex-start; flex-direction: column; } - .brand { align-items: center; flex-direction: row; gap: 10px; } - .layout { grid-template-columns: 1fr; } - .panel { max-height: none; overflow: visible; } - #gameCanvas { height: var(--field-mobile-height, 66vh); min-height: var(--field-mobile-min-height, 460px); } - .stage-wrap { min-height: var(--field-mobile-min-height, 460px); } - .field-choice-grid { grid-template-columns: 1fr; } -} - - - - -.tree-note { - color: var(--muted); - font-size: 12px; - line-height: 1.45; - margin: 0 0 10px; - padding: 8px 10px; - border-radius: 10px; - background: rgba(255,255,255,0.54); - border: 1px solid rgba(84,68,48,0.10); -} - -.lineage-tree { - overflow: auto; - padding: 8px 10px 18px; - contain: content; -} - -.lineage-main-card { - margin-top: 16px; - min-height: 0; -} - -.lineage-main-card h2 { - margin-bottom: 6px; -} - -.lineage-head { - display: flex; - align-items: center; - justify-content: space-between; - gap: 10px; - margin-bottom: 8px; - flex-wrap: wrap; -} - -.lineage-head h2 { margin-bottom: 0; } - -.lineage-main-content { - height: min(78vh, 980px); - min-height: 520px; - max-height: calc(100vh - 120px); - overflow: auto; - overscroll-behavior: contain; - padding: 10px 6px 24px; - background: rgba(255,250,244,0.48); - border-radius: 14px; - border: 1px solid rgba(84,68,48,0.10); - scrollbar-gutter: stable both-edges; -} - -.lineage-forest { - display: flex; - flex-direction: column; - gap: 12px; -} - -.lineage-main-content .lineage-tree { - min-width: 360px; - overflow: visible; - padding-right: 2px; -} - - -body::before { - content: ""; - position: fixed; - inset: 0; - pointer-events: none; - background: - radial-gradient(circle at 8% 20%, rgba(255,255,255,0.62), transparent 16%), - radial-gradient(circle at 92% 18%, rgba(255,255,255,0.45), transparent 18%), - linear-gradient(180deg, transparent 0%, rgba(114, 152, 78, 0.05) 100%); -} - - -.stage-wrap::before { - content: ""; - position: absolute; - inset: 0; - pointer-events: none; - background: - radial-gradient(circle at 18% 14%, rgba(255,255,255,0.12), transparent 18%), - radial-gradient(circle at 84% 10%, rgba(255,255,255,0.09), transparent 16%), - linear-gradient(180deg, rgba(255,255,255,0.07), transparent 24%); - z-index: 1; -} -#gameCanvas { - position: relative; - z-index: 0; -} - -.card::after { - content: ""; - position: absolute; - inset: 0; - pointer-events: none; - border-radius: inherit; - box-shadow: inset 0 1px 0 rgba(255,255,255,0.55); -} - -/* Family tree node primitives. The archive deliberately uses these nodes inside an SVG-backed tree, not the old card/grid UI. */ -.family-node { - position: relative; - display: block; - min-width: 0; - min-height: 34px; - padding: 6px 8px; - border-radius: 10px; - background: linear-gradient(180deg, rgba(255,253,248,0.96), rgba(248,241,229,0.90)); - border: 1px solid rgba(84,68,48,0.14); - box-shadow: 0 3px 8px rgba(64,48,32,0.045); - overflow: hidden; - isolation: isolate; -} -.family-node.child { - border-color: rgba(103, 178, 44, 0.38); - box-shadow: inset 0 0 0 1px rgba(156,232,75,0.17), 0 3px 8px rgba(64,48,32,0.045); -} -.family-node[data-family-tarinai-id] { cursor: pointer; transition: transform .12s ease, border-color .12s ease, box-shadow .12s ease; } -.family-node[data-family-tarinai-id]:hover { transform: translateY(-1px); border-color: rgba(112,178,66,0.42); box-shadow: 0 5px 12px rgba(64,48,32,0.08); } -.family-node.dead { opacity: 0.9; filter: grayscale(0.32); } -.family-node.missing { opacity: 0.48; border-style: dashed; } -.family-portrait { - position: absolute; - right: -6px; - bottom: -8px; - width: 64px; - height: 64px; - z-index: 0; - pointer-events: none; -} -.family-node.alive .family-portrait { opacity: 0.80; } -.family-node.dead .family-portrait { opacity: 0.20; } -.family-portrait img { - width: 100%; - height: 100%; - object-fit: contain; - filter: saturate(0.95); -} -.family-copy { position: relative; z-index: 1; min-width: 0; line-height: 1.12; max-width: calc(100% - 8px); } -.family-copy strong, .family-copy span { - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.family-copy .death-reason { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - line-height: 1.12; - margin-top: 1px; - color: rgba(126, 80, 64, 0.92); -} -.family-copy strong { font-size: 11px; } -.family-copy span { color: var(--muted); font-size: 8.5px; margin-top: 1px; } - - -.colony-card { overflow: visible; min-height: 0; flex: 0 0 auto; } -.colony-stats { - grid-template-columns: repeat(2, 1fr); - margin-bottom: 8px; -} -.colony-chart { - display: block; - width: 100%; - height: 188px; - min-height: 188px; - border: 1px solid rgba(84, 68, 48, 0.14); - border-radius: 14px; - background: linear-gradient(180deg, rgba(255,255,255,0.70), rgba(246,240,228,0.54)); - overflow: hidden; -} -.colony-card h2 { line-height: 1.45; margin-bottom: 10px; } -.colony-chart svg { display: block; width: 100%; height: 100%; } -.colony-chart-legend { - display: flex; - flex-wrap: wrap; - gap: 4px 8px; - align-items: center; - margin: 4px 0 8px; - font-size: 11px; - color: var(--muted); - line-height: 1.25; -} -.colony-chart-legend span { - display: inline-flex; - align-items: center; - gap: 4px; - white-space: nowrap; -} -.colony-chart-legend i { - width: 8px; - height: 8px; - border-radius: 999px; - display: inline-block; - box-shadow: 0 0 0 1px rgba(70, 52, 36, 0.10); -} - -.relation-row strong { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; } -.relation-face { - width: 24px; - height: 24px; - object-fit: contain; - border-radius: 999px; - background: rgba(255,255,255,0.66); - border: 1px solid rgba(84,68,48,0.12); - vertical-align: middle; - flex: 0 0 auto; -} - - -.lineage-family { - padding: 10px; - margin: 0 0 12px; - border-radius: 15px; - background: rgba(255,253,248,0.62); - border: 1px solid rgba(84,68,48,0.12); -} -.lineage-family h3 { - margin: 0 0 8px; - font-size: 13px; - color: rgba(64,52,38,0.86); -} -/* Family archive: actual top-down tree diagram. */ -.lineage-family-tree { - overflow-x: auto; - overflow-y: visible; - padding: 10px 10px 22px; - -webkit-overflow-scrolling: touch; - overscroll-behavior-x: contain; -} -.lineage-family-tree h3 { - position: sticky; - left: 0; - z-index: 3; - width: max-content; - padding-right: 12px; - background: rgba(255,253,248,0.82); - border-radius: 8px; -} -.lineage-tree-hint { - position: sticky; - left: 0; - z-index: 3; - width: max-content; - max-width: 100%; - margin: -2px 0 8px; - padding: 5px 8px; - border-radius: 9px; - color: var(--muted); - font-size: 11px; - background: rgba(255,255,255,0.62); - border: 1px solid rgba(84,68,48,0.08); -} -.lineage-family-tree .lineage-tree-panel { - position: relative; - overflow: visible; - min-width: 360px; - margin-top: 6px; - border-radius: 14px; - background: - linear-gradient(90deg, rgba(84,68,48,0.045) 1px, transparent 1px), - linear-gradient(180deg, rgba(84,68,48,0.040) 1px, transparent 1px), - rgba(255,250,244,0.48); - background-size: 34px 34px, 34px 34px, auto; - border: 1px solid rgba(84,68,48,0.10); -} -.lineage-family-tree .lineage-links { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - overflow: visible; - pointer-events: none; - z-index: 1; - isolation: isolate; -} - -.lineage-actions { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; - justify-content: flex-end; -} -.btn.active { - background: #efffde; - border-color: rgba(103,178,44,0.46); - font-weight: 700; -} - -.lineage-render-status { - position: sticky; - top: 0; - left: 0; - z-index: 6; - width: max-content; - margin: 0 0 8px; - padding: 6px 10px; - border-radius: 999px; - font-size: 12px; - color: var(--muted); - background: rgba(255,255,255,0.88); - border: 1px solid rgba(84,68,48,0.10); - box-shadow: 0 4px 10px rgba(64,48,32,0.06); -} -.lineage-stale-status { - position: sticky; - top: 0; - left: 0; - z-index: 6; - width: max-content; - max-width: calc(100% - 12px); - margin: 0 0 8px; - padding: 6px 10px; - border-radius: 999px; - font-size: 12px; - color: rgba(92, 75, 52, 0.82); - background: rgba(255, 249, 232, 0.92); - border: 1px solid rgba(150, 115, 46, 0.16); - box-shadow: 0 4px 10px rgba(64,48,32,0.05); -} -.lineage-family-tree .lineage-links path { - fill: none; - stroke: rgba(107, 88, 61, 0.58); - stroke-width: 2; - stroke-linecap: round; - stroke-linejoin: round; -} -.lineage-family-tree .lineage-links .partner-link { - stroke-width: 2.4; - stroke: rgba(98, 80, 56, 0.68); - stroke-dasharray: 5 4; -} -.lineage-family-tree .lineage-links .child-link { - stroke-width: 2; - stroke: rgba(107, 88, 61, 0.58); -} -.lineage-family-tree .tree-node { - position: absolute; - width: 132px; - height: 68px; - min-height: 68px; - box-sizing: border-box; - align-items: flex-start; - background: linear-gradient(180deg, #fffdf8, #f8f1e5); - box-shadow: 0 2px 5px rgba(64,48,32,0.035); - contain: layout paint style; - z-index: 2; - isolation: isolate; -} -.lineage-family-tree .tree-node.child { - border-color: rgba(103,178,44,0.34); -} -.lineage-family-tree .tree-node.dead { - opacity: 1; - filter: none; -} -.lineage-family-tree .tree-node[data-family-tarinai-id]:hover { - transform: none; -} -.lineage-family-tree .tree-node .family-portrait { - right: 0; - bottom: -6px; - width: 58px; - height: 58px; -} -.lineage-family-tree .tree-generation-label { - position: absolute; - left: 10px; - width: 54px; - padding: 3px 0; - border-radius: 999px; - font-size: 10px; - color: var(--muted); - text-align: center; - background: rgba(255,255,255,0.70); - border: 1px solid rgba(84,68,48,0.08); - z-index: 2; -} -.lineage-family-tree .lineage-empty-family { - position: absolute; - left: 72px; - bottom: 8px; - padding: 5px 8px; - border-radius: 9px; - background: rgba(255,255,255,0.70); -} - -@media (max-width: 720px) { - .ecology-grid { grid-template-columns: 1fr; } - .ecology-card { grid-template-columns: 68px minmax(0, 1fr); } - .ecology-card img { width: 68px; height: 68px; } -} - -@media (max-width: 720px) { - .lineage-main-content { - height: 70vh; - min-height: 420px; - max-height: none; - } -} - - -.tool[data-tip] { position: relative; } -.tool-tip-popover { - position: fixed; - z-index: 2147483000; - width: 220px; - max-width: min(220px, calc(100vw - 16px)); - padding: 7px 9px; - border-radius: 10px; - background: rgba(46, 38, 30, 0.78); - color: #fff8e6; - font-family: "Yomogi", "Hiragino Maru Gothic ProN", "Yu Gothic", sans-serif; - font-size: 12px; - line-height: 1.45; - box-shadow: 0 10px 28px rgba(40, 32, 22, 0.18); - backdrop-filter: blur(1px); - text-shadow: 0 1px 3px rgba(25, 18, 12, 0.55); - pointer-events: none; -} -.tool-tip-popover.hidden { display: none; } -.selected-actions { - display: flex; - gap: 8px; - flex-wrap: wrap; - margin: 8px 0 4px; -} -.favorite-toggle { - border: 1px solid rgba(128, 102, 56, 0.32); - border-radius: 999px; - background: rgba(255, 248, 221, 0.92); - color: #5a4630; - font-weight: 700; - padding: 5px 10px; - cursor: pointer; -} -.favorite-toggle.active { - background: rgba(255, 229, 122, 0.95); - border-color: rgba(180, 132, 34, 0.55); -} - -.selected-records { - margin-top: 8px; - padding-top: 7px; - border-top: 1px dashed rgba(126, 96, 64, 0.24); -} -.selected-records h3 { - margin: 0 0 5px; - font-size: 12px; - color: var(--muted); -} -.selected-records ol { - margin: 0; - padding: 0; - list-style: none; - display: grid; - gap: 4px; -} -.selected-records li { - display: grid; - grid-template-columns: 38px 1fr; - gap: 6px; - align-items: start; - font-size: 11px; - line-height: 1.35; -} -.selected-records li span { - color: var(--muted); - font-variant-numeric: tabular-nums; -} -.selected-records li strong { - font-weight: 600; -} - -.relation-list-row { - align-items: start; -} -.relation-list-row > strong { - min-width: 0; - width: 100%; - justify-content: flex-end; -} -.relation-chip-list { - display: flex; - flex-wrap: wrap; - justify-content: flex-end; - gap: 5px; - max-width: 100%; -} -.relation-chip { - display: inline-flex; - align-items: center; - gap: 4px; - max-width: 138px; - min-width: 0; - border: 1px solid rgba(104, 150, 84, 0.24); - border-radius: 999px; - background: rgba(250, 255, 242, 0.88); - color: #4d6140; - padding: 2px 6px 2px 2px; - font: inherit; - font-size: 11px; - line-height: 1.2; - cursor: pointer; - box-shadow: 0 1px 0 rgba(255,255,255,0.74); -} -.relation-chip.enemy { - border-color: rgba(178, 92, 74, 0.28); - background: rgba(255, 246, 240, 0.92); - color: #754739; -} -.relation-chip:hover, -.relation-chip:focus-visible { - transform: translateY(-1px); - background: rgba(255,255,255,0.98); - outline: 2px solid rgba(118, 186, 72, 0.18); -} -.relation-chip.enemy:hover, -.relation-chip.enemy:focus-visible { - outline-color: rgba(190, 92, 72, 0.18); -} -.relation-chip .relation-face { - width: 22px; - height: 22px; -} -.relation-chip-name { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - min-width: 0; -} -.relation-chip em { - font-style: normal; - font-size: 10px; - opacity: 0.72; - flex: 0 0 auto; -} +/* v15.18.0: split into base.css, layout.css, panel.css, components.css, mobile.css. Keep this file as a compatibility shim only. */ diff --git a/docs/AI_CONTEXT.md b/docs/AI_CONTEXT.md index 53984ed..08c3f36 100644 --- a/docs/AI_CONTEXT.md +++ b/docs/AI_CONTEXT.md @@ -2,11 +2,11 @@ Purpose: dense orientation for code-editing agents. Browser-only simulation; no build system. Source uses globals and strict script order, not ESM. -Load order from `index.html`: `data -> math -> assets -> audio -> render -> sim_core -> items -> health -> tarinai -> world -> text_catalog -> ui -> ui_charts -> ui_family -> main`. +Load order from `index.html`: `version -> event_bus -> performance_manager -> data -> math -> assets -> audio -> render -> sim_core -> items -> ants -> health -> tarinai core/mixins -> world core/mixins -> world_bootstrap -> text_catalog -> ui state/helpers/bind -> ui_charts -> ui_family modules -> main -> debug_tools`. Primary objects: -- `World` (`js/world.js`): owns field size, time/weather, tarinai array, items, effects, logs, archive, placement, collision, interaction dispatch. -- `Tarinai` (`js/tarinai.js`): agent state and AI. Use helper files for shared rules; avoid making this file larger. +- `World` (`js/world.js` + `js/world_*.js`): constructor is in `world.js`; methods are split by concern into `world_view`, `world_family_social`, `world_combat_effects`, `world_environment`, `world_spatial_budget`, `world_ants_system`, `world_update`, and `world_placement_log`. +- `Tarinai` (`js/tarinai.js` + `js/tarinai_*.js`): constructor is in `tarinai.js`; methods are split into identity/social, disease/nest, needs/items, social/move/life, and render modules. - `Item` (`js/items.js`): item state, draw, lifecycle. - `HEALTH` (`js/health.js`): damage memory, major-damage window, death-cause classification, damage application. - `TEXT_CATALOG` (`js/text_catalog.js`): Japanese tooltips and ecology cards. Keep Japanese escaped. diff --git a/docs/INTERNAL_SYSTEMS.md b/docs/INTERNAL_SYSTEMS.md new file mode 100644 index 0000000..cdfefce --- /dev/null +++ b/docs/INTERNAL_SYSTEMS.md @@ -0,0 +1,69 @@ +# Internal systems v15.18.0 + +Implemented systems except full save/load serialization. + +## Version/cache +- `js/version.js` owns the runtime app version. +- `index.html` and `service-worker.js` use `15.18.0` cache-busting consistently. +- `service-worker.js` is registered with `updateViaCache: "none"`. +- `.htaccess` marks `service-worker.js` as no-cache/no-store and static assets as immutable. + +## Event bus +- `js/event_bus.js` exposes `window.TarinaiEvents`. +- `World.emit/on` forward to the shared event bus. +- Current emitted events include `log:entry`, `world:phase`, `tool:place`, `terrain:dirty`, `performance:level`, `ant:nest-built`, and `audio:sample-error`. + +## Performance manager +- `js/performance_manager.js` exposes `window.TarinaiPerformance`. +- FPS samples are averaged and converted into `level` 0-3. +- Ant update stride, effect cap, terrain redraw interval, and UI/stats intervals can now be tuned from one place. + +## Terrain dirty cache +- Terrain cache no longer hashes every cached terrain item every frame. +- `World.markTerrainDirty(reason)` increments `terrainVersion`. +- The cached terrain layer redraws from `terrainVersion`, light bucket, field, and canvas size. + +## Spatial grid +- `SpatialGrid` now maintains `itemCells`, `tarinaiCells`, `antCells`, `obstacleCells`, `foodCells`, and `hazardCells`. +- `World.nearbyAnts/nearbyObstacles/nearbyFood/nearbyHazards` are available for future behavior/collision work. + +## Debug mode +- Add `?debug=1` to the URL to show a lightweight overlay with FPS, performance level, entity counts, terrain/spatial versions, and recent event bus entries. + +## Audio system +- Audio has per-ID gain, per-ID minimum gap, a concurrent voice cap, sample load failure reporting, and a test event hook: `TarinaiEvents.emit("audio:test", { id: "sfx_notify" })`. + + +## File split in 15.18.0 + +Large legacy files were split into mixin-style modules. `world.js` and `tarinai.js` now define constructors only; prototype methods are attached by adjacent `world_*` and `tarinai_*` files before `world_bootstrap.js` creates the global `world` instance. This preserves the no-build browser deployment model while reducing edit conflicts and improving maintainability. + +## v15.18.0 internal system pass + +### Static manifest +- `app_manifest.json` is the source of truth for CSS and JS loading order. +- `scripts/generate_app_files.py` regenerates `index.html` link/script tags and `service-worker.js` cache lists. +- This prevents drift between HTML, Service Worker, and versioned cache assets. + +### Effect registry +- `js/effect_registry.js` defines item/disease effect metadata in one place: label, color, effect kind, exclusivity group, and display text. +- `tarinai_item_effects.js` now reads labels, colors, random-effect candidates, and selected-data display strings from `TarinaiEffectRegistry`. +- Future item effects should be registered here first, then only behavior-specific logic should be added to the Tarinai methods. + +### Sound pack +- `js/sound_pack.js` defines category gains, ID gains, cooldowns, and optional audio file paths. +- `js/audio.js` consumes `window.TARINAI_SOUND_PACK` at startup. +- Material replacement should normally edit `sound_pack.js`, not core audio synthesis code. + +### CSS split +- `css/styles.css` is now a compatibility shim. +- Actual styles are loaded in order: `base.css`, `layout.css`, `panel.css`, `components.css`, `mobile.css`. +- Preserve this order unless selector precedence is audited. + +### Mobile input modes +- Coarse pointer/mobile displays show a small canvas mode selector. +- Modes: automatic, camera, tool, family-tree priority. +- Camera mode treats one-finger drag as camera pan; tool mode suppresses accidental panning and favors tap/tool use. + +### Diagnostics +- `?debug=1` now shows cache name, Service Worker control state, sound pack version, recent audio IDs, and registered effect count. diff --git a/docs/SOUND_IDS.md b/docs/SOUND_IDS.md new file mode 100644 index 0000000..901e357 --- /dev/null +++ b/docs/SOUND_IDS.md @@ -0,0 +1,55 @@ +# 効果音ID一覧 v15.12.0 + +音素材を差し替える場合は `js/audio.js` の `samplePaths` に、下記IDとファイルパスを追加してください。未指定IDはブラウザ内蔵音で仮再生します。 + +## たりないの声 +- `voice_hau` +- `voice_flee` +- `voice_poop` +- `voice_stress` +- `sfx_eat` +- `sfx_sleep` +- `sfx_wake` +- `sfx_birth` +- `sfx_death` +- `sfx_damage_soft` +- `sfx_damage_heavy` +- `sfx_fight_hit` +- `sfx_fight_finish` +- `sfx_disease` +- `sfx_heal` +- `sfx_ant_drag` +- `sfx_ant_die` +- `sfx_queen_ant` + +## 通知 +- `sfx_notify` +- `sfx_log_push` +- `sfx_phase` + +## 操作 +- `sfx_ui_click` +- `sfx_ui_fold` +- `sfx_place` +- `sfx_delete` +- `sfx_poke` +- `sfx_grab` +- `sfx_drop` +- `sfx_water_hose` +- `sfx_water_clean` +- `sfx_drink` +- `sfx_ball_hit` +- `sfx_stone_impact` +- `sfx_firecracker_fuse` +- `sfx_firecracker_explode` +- `sfx_genkotsu_fall` +- `sfx_genkotsu_impact` +- `sfx_ground_rumble` +- `sfx_grass` +- `sfx_zunchi` +- `sfx_ant_nest` + +## v15.18.0 sound pack + +Sound paths, per-ID volume multipliers, category multipliers, and minimum replay intervals are now centralized in `js/sound_pack.js`. +For normal sound replacement, edit `TARINAI_SOUND_PACK.samplePaths` with the same stable sound ID instead of changing `js/audio.js`. diff --git a/docs/code_map.md b/docs/code_map.md index 5ae1a80..2737394 100644 --- a/docs/code_map.md +++ b/docs/code_map.md @@ -9,17 +9,17 @@ Use this as the first lookup table before opening large files. | Lazy image loading | `js/assets.js` / `loadInitialImages`, `loadDeferredImages`, `getRenderableImage` | | UI Japanese text catalog | `js/text_catalog.js` / `TEXT_CATALOG` | | Core agent state | `js/tarinai.js` / `class Tarinai` constructor | -| Agent AI target choice | `js/tarinai.js` / `resolveNeeds`, target helpers | -| Disease state transitions | `js/tarinai.js` / `infect*`, `recover*`, `update*Disease*` | +| Agent AI target choice | `js/tarinai_needs_items.js` / `resolveNeeds`, target helpers | +| Disease state transitions | `js/tarinai_disease_nest.js` / `infect*`, `recover*`, `update*Disease*` | | Damage/death cause rules | `js/health.js` / `HEALTH` | | Item creation/lifecycle/draw | `js/items.js` / `class Item` | -| Cleaning, rain, placement | `js/world.js` / placement/update interaction helpers | -| Fence collision | `js/world.js` / `resolveFenceCollision` | -| Logs/archive | `js/world.js` | +| Cleaning, rain, placement | `js/world_combat_effects.js`, `js/world_update.js`, `js/world_placement_log.js` | +| Fence collision | `js/world_environment.js` / `resolveFenceCollision` | +| Logs/archive | `js/world_placement_log.js`, `js/ui_family*.js` | | Main renderer | `js/render.js` / `render` helpers | -| Agent drawing | `js/tarinai.js` / `draw` | -| Input/tools/dialogs | `js/ui.js` | +| Agent drawing | `js/tarinai_render.js` / `draw` | +| Input/tools/dialogs | `js/ui.js`, `js/ui_bind.js`, `js/ui_layout_dialogs.js`, `js/ui_tools.js` | | Statistics UI | `js/ui_charts.js` | -| Family tree UI | `js/ui_family.js` | +| Family tree UI | `js/ui_family_data.js`, `js/ui_family_async.js`, `js/ui_family_layout.js`, `js/ui_family_paths.js`, `js/ui_family_render.js` | Refactor guidance: extract isolated rule sets into small helper files, then delegate from `Tarinai`/`World`. Keep shared domain terms centralized (`HEALTH`, `TEXT_CATALOG`, `CONFIG`) to reduce repeated prompt context. diff --git a/index.html b/index.html index c95f7b3..3594cce 100644 --- a/index.html +++ b/index.html @@ -3,18 +3,23 @@ - - たりない観察 - + + + + + - + - たりない観察を読み込み中 - 通信量を抑えて初期化しています… - - 0% + たりないコロニー + 読み込み中… + 準備しています + + + 進行状況0% + 初期表示に必要な画像だけ先に読み込み、残りは後から順次ロードします。 @@ -29,7 +34,16 @@ 一時停止 速度 x1 たりないの生態 - 音 OFF + + 音設定 ON + + 効果音 + + たりないの声 + 通知 + 操作 + + クレジット リセット @@ -38,6 +52,12 @@ + + 自動 + カメラ + 道具 + 家系図 + @@ -50,8 +70,9 @@ 未選択 - - 道具 + + 道具折り畳み + @@ -74,6 +95,15 @@ けんか餅 水の皿 ねむり薬 + 下剤 + プロテイン + ンイテロプ + 弾薬 + 怪しい薬 + 水銀 + 巨大薬 + 矮小薬 + ずんだ汁 草 @@ -81,11 +111,11 @@ オブジェクト 石 - げんこつ 干草寝床 巣箱 アリの巣 ボール + げんこつ 爆竹 縦の柵 横の柵 @@ -94,22 +124,40 @@ 同じ道具ボタンをもう一度押すと、対応道具の大きさが小・中・大で切り替わります。 + - - コロニー + + コロニー折り畳み + 個体数0 累計死亡数0 - 人口生活環境オブジェクト + 人口精神環境オブジェクト + - - イベント - + + イベント折り畳み + + + + プッシュ通知 + + 死亡 + 事故 + 誕生 + 喧嘩 + 食事 + 天気 + 草 + 関係 + + + @@ -178,21 +226,53 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
準備しています
初期表示に必要な画像だけ先に読み込み、残りは後から順次ロードします。
同じ道具ボタンをもう一度押すと、対応道具の大きさが小・中・大で切り替わります。