diff --git a/AI_MAP.md b/AI_MAP.md index 78a68e1..f801193 100644 --- a/AI_MAP.md +++ b/AI_MAP.md @@ -6,9 +6,10 @@ Purpose: static Japanese browser simulation/game. Optimize context by reading th - Entrypoint: `index.html` defines the app shell, canvas, dialogs, right panels, and exact script order. - Runtime style: plain browser JS, global IIFEs, exports on `window`, no bundler/module loader. -- Version/cache: `app_manifest.json`, `js/version.js`, and generated `service-worker.js` share `39.15.47`. +- Version/cache: `app_manifest.json`, `js/version.js`, and generated `service-worker.js` share `39.15.103`. - Main loop: `js/main.js` initializes assets/audio/world/UI/save, then drives update/render. -- Update order: `js/system_order.js` calls phase facades from `js/world_update_phases.js` / `js/simulation_systems.js`. +- Performance/display settings: `js/perf_profiler.js` owns manual visual settings and profiler buckets; display tiers affect rendering/visuals, not simulation-quality branches. +- Update order: `js/system_order.js` calls phase facades from `js/simulation_systems.js`. - Command path: UI/input emits command objects; `js/command_dispatcher.js` routes tool, pointer, selection, save, reset, and UI intents. - Persistence: save files are schema/codec/storage/coordinator modules; snapshot/history modules keep world restoration and stats consistent. @@ -45,6 +46,8 @@ Purpose: static Japanese browser simulation/game. Optimize context by reading th - Tool behavior: `js/command_dispatcher.js`, `js/world_tool_actions.js`, `js/item_registry.js`, relevant `js/item_*` or `js/tarinai_item_*`. - Creature behavior: `js/tarinai.js`, `js/tarinai_update_pipeline.js`, relevant `js/tarinai_*`, `js/system_order.js`. - World/environment/combat: matching `js/world_*`, `js/simulation_*`, `js/system_order.js`. +- Fire/burning behavior: `js/fire_runtime_system.js`, `js/item_dynamic_tool_system.js`, relevant item definitions, `js/world_combat_effects.js`, and nearby environment helpers. +- Performance/crowding: `js/perf_profiler.js`, `js/item_update_scheduler.js`, `js/tarinai_update_policy.js`, `js/constraint_system.js`, `js/world_spatial_budget.js`, and render/detail code. - Save/load: `js/save_schema.js`, `js/save_codec.js`, `js/save_system.js`, `js/snapshot_system.js`, `js/restore_coordinator.js`. - Family tree: `js/world_family_social.js`, `js/family_graph.js`, `js/ui_family_*.js`. - Static app/cache/version: `app_manifest.json`, `scripts/generate_app_files.py`, `service-worker.js`, `js/version.js`, `index.html`. @@ -53,6 +56,7 @@ Purpose: static Japanese browser simulation/game. Optimize context by reading th - Preserve `index.html` script order unless all dependent manifests/generated files are updated together. - Keep `app_manifest.json`, `js/version.js`, `service-worker.js`, and cache query versions synchronized. -- Keep global exports for compatibility with regression checks and browser runtime. +- Keep intentional global exports for compatibility with regression checks and browser runtime; remove public facades only after repo-wide caller checks. - Prefer focused edits in the owning subsystem; split modules are intentional compatibility boundaries. +- Avoid reintroducing `simulationQualityTier` branches unless a real simulation-quality setting is restored; current quality controls are visual/detail controls. - Run `node --check js/*.js` and `python scripts/regression_check.py` for behavior changes. diff --git a/BUILD_NOTE.txt b/BUILD_NOTE.txt new file mode 100644 index 0000000..2809c20 --- /dev/null +++ b/BUILD_NOTE.txt @@ -0,0 +1,13 @@ +tarinai_water_balloon_fan_ui_v1 +- Fan drawing now shows the actual forward wind cone/range. +- Mobile rotator/reciprocator editor dialogs are scrollable; reciprocator canvas shares editor sizing. +- Balloon tool is replaced by water balloon visuals/text. +- Water balloons splash water when popped; low-openness tarinai panic and flee with behavior text: 水風船が割れておどろいている。 +- Version: 39.15.116 + +tarinai_king_fix_v10 +- Fire tool button hidden; flames spawn only from flame firecracker. +- Burning tarinai and ants draw lightweight flame-shaped overlays. +- Flame firecracker is redder and shows a countdown timer; normal firecracker is darker. +- Standalone flame and fire particles use a simpler flame silhouette. +- Version: 39.15.102 diff --git a/FILES.json b/FILES.json index 89f458d..376200a 100644 --- a/FILES.json +++ b/FILES.json @@ -1,6 +1,6 @@ { "purpose": "Token-efficient machine-readable routing for tarinai_. Use scripts/ai_inventory.py for exact current file expansion.", - "version": "39.15.77", + "version": "39.15.103", "entrypoints": { "app": "index.html", "runtime": "js/main.js", @@ -71,7 +71,9 @@ "js/main.js", "js/math.js", "js/perf_profiler.js", - "js/debug_tools.js" + "js/debug_tools.js", + "js/update_step_pipeline_runner.js", + "js/burn_motion_util.js" ], "meaning": "Bootstrap, shared constants/helpers, registries, config, profiling/debug." }, diff --git a/GAME_FEATURES.md b/GAME_FEATURES.md index a3d0acb..0907f3a 100644 --- a/GAME_FEATURES.md +++ b/GAME_FEATURES.md @@ -16,7 +16,8 @@ The core loop is: ## Main UI - **Canvas / field**: the main simulation area. Tarinai, items, effects, ants, weather, and terrain are drawn here. -- **Top buttons**: pause/resume, speed control, ecology guide, sound settings, credits, save, and reset. +- **Top buttons**: pause/resume, speed control, ecology guide, sound settings, credits, save, display settings, and reset. +- **Display settings**: manually adjust effects, shadows, and drawing detail. `High` keeps quality-preserving optimizations active, while lower tiers cut heavier visuals for crowded scenes without lowering object limits; simulation cadence remains quality-preserving. - **Mobile mode controls**: auto, camera, and tool modes for touch screens. - **Right panel tabs**: jump between main game, selected tarinai data, tools, colony, events, and family tree. - **Tarinai data panel**: appears when a tarinai is selected. Shows health, needs, personality, active effects, relations, inventory, behavior reason, and records. @@ -31,68 +32,68 @@ The core loop is: ### Operation -- **解除 / clear**: cancels the selected tool and returns to normal observe mode. -- **たりないデータ / observe**: select a tarinai or inspect compatible objects such as signboards. -- **追加 / new**: calls a new tarinai into the field. -- **つつく / poke**: pokes tarinai and can push balls. -- **つまむ / pinch**: drags tarinai and some placed objects. -- **コピー / copy**: copies a placed item and pastes a new instance with its settings. -- **戻す / undo** and **進む / redo**: reverse or reapply placement/edit actions. -- **削除 / delete**: removes placed tools, objects, and stains. -- **範囲削除 / area delete**: removes many nearby objects or stains around the cursor. -- **洗浄 / water hose**: drag to clean dirt, zunchi, corpses, and stains. +- **解除 / clear**: cancels the selected tool and returns to normal observe mode. +- **たりないデータ / observe**: select a tarinai or inspect compatible objects such as signboards. +- **追加 / new**: calls a new tarinai into the field. +- **つつく / poke**: pokes tarinai and can push balls. +- **つまむ / pinch**: drags tarinai and some placed objects. +- **コピー / copy**: copies a placed item and pastes a new instance with its settings. +- **戻す / undo** and **進む / redo**: reverse or reapply placement/edit actions. +- **削除 / delete**: removes placed tools, objects, and stains. +- **範囲削除 / area delete**: removes many nearby objects or stains around the cursor. +- **洗浄 / water hose**: drag to clean dirt, zunchi, corpses, and stains. ### Food -- **ずんだ餅 / sweet**: favored food; can cure some illness. -- **へこ餅 / love mochi**: makes reproduction behavior more likely for a while. -- **けんか餅 / fight mochi**: makes fighting behavior more likely for a while. -- **草 / grass**: food and comfort source; can grow and be used for simple beds. -- **水滴 / water**: drinkable water, also appears during rain and can be set in duplicators. -- **ずんだ汁 / zunda juice**: clears item effects from a tarinai. -- **複製機 / duplicator**: can be loaded with compatible food, medicine, grass, water, pushpins, or oshibyo and then produces or applies that content. +- **ずんだ餅 / sweet**: favored food; can cure some illness. +- **へこ餅 / love mochi**: makes reproduction behavior more likely for a while. +- **けんか餅 / fight mochi**: makes fighting behavior more likely for a while. +- **草 / grass**: food and comfort source; can grow, be used for simple beds, and sometimes dampen nearby fire instead of immediately catching. +- **水滴 / water**: drinkable water, also appears during rain and can be set in duplicators. +- **ずんだ汁 / zunda juice**: clears item effects from a tarinai. +- **複製機 / duplicator**: can be loaded with compatible food, medicine, grass, water, pushpins, or oshibyo and then produces or applies that content. ### Medicine -- **ねむり薬 / sleep drug**: causes sleepiness or sleep disease; damage can cure the disease. -- **下剤 / laxative**: causes repeated zunchi and reduces food benefit. -- **プロテイン / protein**: permanent power mode; more damage dealt, lower disease chance. -- **ンイテロプ / niteropu**: permanent weak mode; less damage dealt, higher disease chance. -- **弾薬 / ammo**: temporary high-speed movement and strong collision impact. -- **怪しい薬 / mystery drug**: randomly applies an eligible item effect or disease. -- **水銀 / mercury**: increases lifespan multiplier on each use. -- **巨大薬 / giant drug**: greatly increases size, attack, and speed, but deals ongoing damage. -- **矮小薬 / dwarf drug**: greatly decreases size, attack, and speed, and also deals ongoing damage. +- **ねむり薬 / sleep drug**: causes sleepiness or sleep disease; damage can cure the disease. +- **下剤 / laxative**: causes repeated zunchi and reduces food benefit. +- **プロテイン / protein**: permanent power mode; more damage dealt, lower disease chance. +- **ンイテロプ / niteropu**: permanent weak mode; less damage dealt, higher disease chance. +- **弾薬 / ammo**: temporary high-speed movement and strong collision impact. +- **怪しい薬 / mystery drug**: randomly applies an eligible item effect or disease. +- **水銀 / mercury**: increases lifespan multiplier on each use. +- **巨大薬 / giant drug**: greatly increases size, attack, and speed, but deals ongoing damage. +- **矮小薬 / dwarf drug**: greatly decreases size, attack, and speed, and also deals ongoing damage. ### Habitat -- **ずんち / zunchi**: tarinai waste; affects disease and can fertilize grass. -- **ロボ掃除機 / robot_cleaner**: moves through the field at fixed normal speed 60, or 120 in high-speed mode. It checks the nearest matching cleanup target every 2 seconds, keeps pursuing it between scans, and cleans every matching object it touches. The 死骸 target also covers blood traces; clicking the item opens its target settings. -- **干草寝床 / bed**: placeable sleeping spot; helps HP recovery. -- **巣箱 / nest box**: reduces stress nearby; improves sleep quality when used. -- **ボール / ball**: toy that tarinai can play with and the player can poke. -- **看板 / signboard**: editable text object; inspect with observe after placing. +- **ずんち / zunchi**: tarinai waste; affects disease and can fertilize grass. +- **ロボ掃除機 / robot_cleaner**: moves through the field at fixed normal speed 60, or 120 in high-speed mode. It checks the nearest matching cleanup target every 2 seconds, keeps pursuing it between scans, and cleans every matching object it touches. The 死骸 target also covers blood traces; clicking the item opens its target settings. +- **干草寝床 / bed**: placeable sleeping spot; helps HP recovery. +- **巣箱 / nest box**: reduces stress nearby; improves sleep quality when used. +- **ボール / ball**: toy that tarinai can play with and the player can poke. +- **看板 / signboard**: editable text object; inspect with observe after placing. ### Physics -- **ヒモ / rope**: connect two targets with a flexible link. -- **棒 / rod**: connect two targets with a rigid link. -- **柵 / fence**: blocks tarinai movement; Q/E rotate by 45 degrees, Shift+Q/E by 5 degrees. -- **バウンス柵 / bounce fence**: fence that rebounds things that hit it. -- **ゲート柵 / gate fence**: click to open or close. -- **回転体 / rotator**: custom mechanical shape that rotates; click to edit shape and speed. -- **毒ブロック / poison block**: custom hazard block; touching it damages skin; click to edit shape. -- **往復体 / reciprocator**: custom mechanical shape that moves back and forth; click to edit shape and speed. +- **ヒモ / rope**: connect two targets with a flexible link. +- **棒 / rod**: connect two targets with a rigid link. +- **柵 / fence**: blocks tarinai movement; Q/E rotate by 45 degrees, Shift+Q/E by 5 degrees. +- **バウンス柵 / bounce fence**: fence that rebounds things that hit it. +- **ゲート柵 / gate fence**: click to open or close. +- **回転体 / rotator**: custom mechanical shape that rotates; click to edit shape and speed. +- **毒ブロック / poison block**: custom hazard block; touching it damages skin; click to edit shape. +- **往復体 / reciprocator**: custom mechanical shape that moves back and forth; click to edit shape and speed. ### Danger -- **石 / stone**: heavy object; dangerous when dropped or moved into others. -- **げんこつ / genkotsu**: large fist impact on the ground. -- **爆竹 / firecracker**: creates an explosion. -- **画鋲 / pushpin**: rolls when dropped; can lodge in tarinai and cause panic plus continuous damage. -- **おしり鋲 / oshibyo**: blocks zunchi when lodged; pulling it out releases stored zunchi. -- **射撃 / shoot**: attacks with a gun effect. -- **アリの巣 / ant nest**: spawns ants that search for tarinai and carry them to the nest. +- **石 / stone**: heavy object; dangerous when dropped or moved into others. +- **げんこつ / genkotsu**: large fist impact on the ground. +- **爆竹 / firecracker**: creates an explosion; flame variants scatter fire while respecting active-fire limits. +- **画鋲 / pushpin**: rolls when dropped; can lodge in tarinai and cause panic plus continuous damage. +- **おしり鋲 / oshibyo**: blocks zunchi when lodged; pulling it out releases stored zunchi. +- **射撃 / shoot**: attacks with a gun effect. +- **アリの巣 / ant nest**: spawns ants that search for tarinai and carry them to the nest. ## Tarinai Needs And Stats @@ -139,7 +140,7 @@ Tarinai can be pushed by physics objects, carried or affected by ants, dragged b - **Field types**: park, garden, and cage provide different field sizes. - **Ground types**: sand, dirt, concrete, blanket, foot massage, ice, and laboratory-style ground affect stress, grass, and movement. - **Weather**: rain and other weather influence water, mood, and environment effects. -- **Grass ecology**: grass grows, feeds tarinai, comforts them, and can become bed material. +- **Grass ecology**: grass grows, feeds tarinai, comforts them, can become bed material, and has a small chance to reduce fire before burning. - **Dirt and corpses**: zunchi, splats, corpses, and ant corpses affect hygiene, disease, and observation results. - **Day/light conditions**: lighting and sun influence rendering and sunbath behavior. @@ -169,3 +170,23 @@ Recovery depends on the disease or effect. Water, rest, food, medicine, zunda ju - The app supports manual save and restore through browser storage. - Reset opens field selection and starts a new field state. - Service worker caching allows the static app shell to remain available after load, depending on browser support. + + +## 39.15.116 土管外観・内部温度 + +- 土管の外観を、丸い口と側面が見える斜め上からの視点に変更。 +- 土管内の体感温度を20℃へ近づける内部温度補正を追加。補正幅は最大7℃。 +- 土管ツールチップの内部気温表示にも、土管内補正後の温度を反映。 + +## 39.15.115 水風船の飛散強化・扇風機首振り設定 +- 水風船破裂時に水滴が放射状に飛び、短時間移動してから水たまり状に落ち着く。 +- 配置済み扇風機をクリックすると首振り設定UIを開ける。個別に首振りON/OFF、向き、振り幅、速度を設定可能。 +- 首振り中の扇風機は風の範囲表示と実際の風判定が現在角度に追従する。 + +## 39.15.115 土管 + +- 生活カテゴリに「土管」を追加。丸い口が見える配置アイテムとして表示。 +- たりないが巣箱のように土管の中へ入り、内部の個体は巣箱系ツールチップで確認可能。 +- 土管から出る時は、複数ある場合は別のランダムな土管から出る。 +- 土管内でも眠れるが、寝心地と睡眠優先順位は干草寝床の一段下。 + diff --git a/README.md b/README.md index 51fe40e..b85e8c8 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ AI-first entrypoint for a static browser simulation/game. Keep this file small; read deeper docs only when needed. ## v39.15.70 robot cleaner tuning -- Tuned ロボ掃除機 targeting: normal speed is 60, high-speed mode is 120, and speed no longer changes based on the selected cleanup targets. +- Tuned ロボ掃除機 targeting: normal speed is 60, high-speed mode is 120, and speed no longer changes based on the selected cleanup targets. - The cleaner checks the nearest matching target every 2 seconds, then keeps trying to clean that target between scans. Contact cleanup still removes every matching object it touches. -- The 死骸 target also covers blood traces. When たりない is enabled, nearby Tarinai panic while chased and are cleaned on contact. +- The 死骸 target also covers blood traces. When たりない is enabled, nearby Tarinai panic while chased and are cleaned on contact. ## Read Strategy @@ -18,7 +18,7 @@ AI-first entrypoint for a static browser simulation/game. Keep this file small; ## Runtime Shape -- No bundler; `index.html` loads ordered global-IIFE scripts with `?v=39.15.47`. +- No bundler; `index.html` loads ordered global-IIFE scripts with `?v=39.15.103`. - Mutable runtime lives on `window`; primary entities are `World`, `Tarinai`, items, structures, ants, family graph, weather, and save snapshots. - Update loop: `main.js` creates the world/UI loop; `World.update` delegates to `TarinaiSystemOrder.update`; `system_order.js` runs named phases. - UI loop: pointer/tool/UI intents go through `command_dispatcher.js`; canvas drawing is in render modules; side panels are `ui_*.js`. @@ -57,7 +57,7 @@ AI-first entrypoint for a static browser simulation/game. Keep this file small; - Inventory sanity: `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ai_inventory.ps1 -All` -## v39.15.47 UI media isolation / scroll repair +## UI media isolation / scroll repair - PC / smartphone UI override rules are separated into `@media (min-width: 981px)` and `@media (max-width: 980px)`. - PC family tree card is restored below the main game layout, not inside the right menu. @@ -65,7 +65,7 @@ AI-first entrypoint for a static browser simulation/game. Keep this file small; - Auto-scroll does not open collapsed cards. -## v39.15.47 event/family/oshibyo UI fixes +## Event/family/oshibyo UI fixes - Event UI hides direct player item placement records while keeping those records in the internal log. - Collapsed Event UI no longer leaves a large blank area from the log-card min-height. @@ -73,14 +73,14 @@ AI-first entrypoint for a static browser simulation/game. Keep this file small; - Oshibyo lodged position is anchored to the left side of the tarinai sprite. -## v39.15.47 family polish +## Family polish - Family tree generation row spacing is tightened. - Family tree personality tags also use a 2x2 grid (up to 4 visible tags). - Sprinkler effective cleaning radius is increased to 3x the previous value and still filters targets by actual distance. -## v39.15.47 owned object panic / shoot effect +## Owned object panic / shoot effect - Tarinai panic when their own plushie or simple grass bed is destroyed. - The selected Tarinai data behavior text explicitly shows the owned-object panic reason. diff --git a/app_manifest.json b/app_manifest.json index 0e1a0fe..a7f37e2 100644 --- a/app_manifest.json +++ b/app_manifest.json @@ -1,5 +1,5 @@ { - "version": "39.15.90", + "version": "39.15.116", "css": [ "css/base.css", "css/layout.css", @@ -14,6 +14,7 @@ "js/disease_registry.js", "js/sound_pack.js", "js/deterministic_helpers.js", + "js/item_tool_metadata.js", "js/item_tool_definitions.js", "js/item_visual_definitions.js", "js/item_food_definitions.js", @@ -23,6 +24,7 @@ "js/ground_types.js", "js/input_mode_manager.js", "js/math.js", + "js/geometry_helpers.js", "js/collision_footprint_system.js", "js/physics_helpers.js", "js/placement_preview_system.js", @@ -44,6 +46,8 @@ "js/item_type_initializers.js", "js/item_lifecycle_support.js", "js/item_update_policy.js", + "js/fire_runtime_system.js", + "js/robot_cleaner_system.js", "js/item_dynamic_tool_system.js", "js/item_dynamic_ball_system.js", "js/item_dynamic_duplicator_system.js", @@ -56,10 +60,13 @@ "js/item_lifecycle_step_decay.js", "js/item_lifecycle_step_dynamic.js", "js/item_lifecycle_step_growth.js", + "js/update_step_pipeline_runner.js", "js/item_lifecycle_pipeline.js", "js/item_runtime.js", "js/structure_lifecycle.js", + "js/item_render_helpers.js", "js/item_render_runtime.js", + "js/burn_motion_util.js", "js/ants.js", "js/health.js", "js/tarinai.js", @@ -79,6 +86,7 @@ "js/tarinai_building_behavior.js", "js/tarinai_action_definitions.js", "js/tarinai_needs_items.js", + "js/tarinai_food_prototype_mixin.js", "js/tarinai_need_planner_system.js", "js/tarinai_item_interaction_context.js", "js/tarinai_food_interaction_system.js", @@ -99,12 +107,16 @@ "js/world.js", "js/world_view.js", "js/family_graph.js", + "js/world_reset_presets.js", "js/world_family_social.js", "js/impact_core_system.js", "js/impact_response_system.js", "js/collision_response_system.js", "js/world_combat_effects.js", "js/world_environment.js", + "js/world_temperature_system.js", + "js/world_pathfinding_system.js", + "js/world_grass_placement_system.js", "js/world_spatial_budget.js", "js/world_ants_system.js", "js/weather_system.js", @@ -155,14 +167,5 @@ "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", - "assets/objects/*.png" - ], - "notes": "Boundary cleanup v38: freezer removed, washing expanded and continuous, laboratory ground added, and save schema synchronized." + ] } diff --git a/css/base.css b/css/base.css index ed57595..f87ca66 100644 --- a/css/base.css +++ b/css/base.css @@ -36,23 +36,6 @@ button { 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; @@ -62,18 +45,6 @@ button { 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; -} #app { width: min(1480px, 100vw); @@ -85,15 +56,17 @@ button { .topbar { display: flex; justify-content: space-between; - gap: 18px; + gap: 14px; align-items: center; + flex-wrap: nowrap; margin-bottom: 16px; } .top-left { display: flex; align-items: center; - gap: 12px; + gap: 10px; + flex: 1 1 auto; min-width: 0; } @@ -118,19 +91,21 @@ h1 { white-space: nowrap; } - .top-actions { display: flex; - gap: 8px; - flex-wrap: wrap; + gap: 6px; + flex: 0 0 auto; + flex-wrap: nowrap; justify-content: flex-end; + align-items: center; + white-space: nowrap; } .btn, .tool { border: 1px solid var(--line); background: rgba(255,255,255,0.76); border-radius: 999px; - padding: 9px 13px; + padding: 8px 11px; cursor: pointer; box-shadow: 0 4px 14px rgba(80,60,40,0.06); transition: transform 130ms ease, background 130ms ease, border-color 130ms ease; @@ -255,7 +230,6 @@ h1 { min-width: 132px; } - .ecology-dialog-panel { width: min(760px, 100%); max-height: calc(100vh - 36px); @@ -448,16 +422,15 @@ h1 { .tool[data-tool="oshibyo"] { --tool-icon: url("../assets/ui/tool_oshibyo.webp"); } /* Generated parameter item tool icons. */ -.tool[data-tool="laxative"] { --tool-icon: url("../assets/ui/tool_laxative.webp?v=15.20.16"); } -.tool[data-tool="protein"] { --tool-icon: url("../assets/ui/tool_protein.webp?v=15.20.16"); } -.tool[data-tool="niteropu"] { --tool-icon: url("../assets/ui/tool_niteropu.webp?v=15.20.16"); } -.tool[data-tool="ammo"] { --tool-icon: url("../assets/ui/tool_ammo.webp?v=15.20.16"); } -.tool[data-tool="mystery_drug"] { --tool-icon: url("../assets/ui/tool_mystery_drug.webp?v=15.20.16"); } -.tool[data-tool="mercury"] { --tool-icon: url("../assets/ui/tool_mercury.webp?v=15.20.16"); } -.tool[data-tool="giant_drug"] { --tool-icon: url("../assets/ui/tool_giant_drug.webp?v=15.20.16"); } -.tool[data-tool="dwarf_drug"] { --tool-icon: url("../assets/ui/tool_dwarf_drug.webp?v=15.20.16"); } -.tool[data-tool="zunda_juice"] { --tool-icon: url("../assets/ui/tool_zunda_juice.webp?v=15.20.16"); } - +.tool[data-tool="laxative"] { --tool-icon: url("../assets/ui/tool_laxative.webp"); } +.tool[data-tool="protein"] { --tool-icon: url("../assets/ui/tool_protein.webp"); } +.tool[data-tool="niteropu"] { --tool-icon: url("../assets/ui/tool_niteropu.webp"); } +.tool[data-tool="ammo"] { --tool-icon: url("../assets/ui/tool_ammo.webp"); } +.tool[data-tool="mystery_drug"] { --tool-icon: url("../assets/ui/tool_mystery_drug.webp"); } +.tool[data-tool="mercury"] { --tool-icon: url("../assets/ui/tool_mercury.webp"); } +.tool[data-tool="giant_drug"] { --tool-icon: url("../assets/ui/tool_giant_drug.webp"); } +.tool[data-tool="dwarf_drug"] { --tool-icon: url("../assets/ui/tool_dwarf_drug.webp"); } +.tool[data-tool="zunda_juice"] { --tool-icon: url("../assets/ui/tool_zunda_juice.webp"); } .signboard-editor { position: fixed; @@ -477,6 +450,10 @@ h1 { background: linear-gradient(180deg, rgba(255,253,247,0.98), rgba(245,237,221,0.96)); border: 1px solid rgba(94, 70, 42, 0.20); box-shadow: 0 22px 60px rgba(36, 28, 20, 0.28), inset 0 1px 0 rgba(255,255,255,0.72); + max-height: calc(100dvh - 36px); + overflow-y: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; } .signboard-editor-titlebar { display: flex; @@ -622,6 +599,10 @@ h1 { background: linear-gradient(180deg, rgba(255,253,247,0.98), rgba(245,237,221,0.97)); border: 1px solid rgba(94, 70, 42, 0.20); box-shadow: 0 22px 60px rgba(36, 28, 20, 0.28), inset 0 1px 0 rgba(255,255,255,0.72); + max-height: calc(100dvh - 36px); + overflow-y: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; } .rotator-editor-titlebar { display: flex; @@ -687,7 +668,8 @@ h1 { border-color: rgba(112, 80, 170, 0.38); font-weight: 700; } -#rotatorCanvas { +#rotatorCanvas, +#reciprocatorCanvas { width: 100%; height: min(58vh, 360px); display: block; @@ -709,7 +691,44 @@ h1 { margin-top: 12px; } @media (max-width: 560px) { - .rotator-editor-panel { padding: 10px; } + .rotator-editor { + place-items: start center; + padding: 8px; + overflow-y: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; + } + .rotator-editor-panel { + width: calc(100vw - 16px); + max-height: calc(100dvh - 16px); + padding: 10px; + } .rotator-editor-controls label { grid-template-columns: 1fr; align-items: stretch; } - #rotatorCanvas { height: 320px; } + .rotator-editor-tools { max-height: 22vh; overflow-y: auto; padding-right: 2px; } + #rotatorCanvas, #reciprocatorCanvas { height: min(44vh, 270px); } +} + +.fan-editor-panel { width: min(430px, calc(100vw - 28px)); } +.fan-editor-help { + color: var(--muted); + font-size: 12px; + line-height: 1.45; + margin: 0 2px 10px; +} +.fan-editor-controls label { + grid-template-columns: 56px 1fr 72px auto; +} +.fan-editor-controls .fan-editor-check { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 10px; + border-radius: 10px; + background: rgba(255,255,255,0.58); + border: 1px solid rgba(84,68,48,0.11); +} +.fan-editor-controls input[type="checkbox"] { accent-color: #70aee8; } +@media (max-width: 560px) { + .fan-editor-controls label { grid-template-columns: 1fr; align-items: stretch; } + .fan-editor-panel { width: calc(100vw - 16px); } } diff --git a/css/components.css b/css/components.css index 49fbfb5..9d4c636 100644 --- a/css/components.css +++ b/css/components.css @@ -17,7 +17,7 @@ backdrop-filter: blur(1px); text-shadow: 0 1px 3px rgba(25, 18, 12, 0.55); pointer-events: none; - white-space: normal; + white-space: pre-line; overflow-wrap: anywhere; word-break: break-word; } @@ -643,6 +643,60 @@ font-size: 12px; line-height: 1.45; } +.visual-settings-dialog-panel { + width: min(560px, calc(100vw - 32px)); +} +.visual-setting-row { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 12px; + align-items: center; + padding: 12px 0; + border-top: 1px solid rgba(115, 91, 62, 0.16); +} +.visual-setting-row strong, +.visual-setting-row span { + display: block; +} +.visual-setting-row strong { + color: #4f3928; + font-size: 15px; +} +.visual-setting-row span { + margin-top: 3px; + color: #6d5a46; + font-size: 12px; +} +.visual-setting-options { + display: inline-flex; + gap: 5px; + padding: 4px; + border: 1px solid rgba(115, 91, 62, 0.18); + border-radius: 999px; + background: rgba(255, 255, 255, 0.50); +} +.visual-setting-options button { + min-width: 46px; + min-height: 32px; + border: 1px solid transparent; + border-radius: 999px; + background: transparent; + color: #5d4938; + cursor: pointer; + font: inherit; + font-weight: 800; +} +.visual-setting-options button.active, +.visual-setting-options button[aria-pressed="true"] { + border-color: rgba(127, 94, 54, 0.28); + background: #fff4d8; + color: #3f3023; + box-shadow: 0 2px 8px rgba(96, 70, 40, 0.12); +} +.visual-setting-options button:focus-visible { + outline: 2px solid rgba(184, 128, 54, 0.45); + outline-offset: 2px; +} @media (max-width: 640px) { .save-slot-row { grid-template-columns: 1fr; @@ -650,6 +704,16 @@ .save-slot-actions { justify-content: flex-start; } + .visual-setting-row { + grid-template-columns: 1fr; + } + .visual-setting-options { + width: 100%; + justify-content: stretch; + } + .visual-setting-options button { + flex: 1 1 0; + } } .ground-stat { @@ -698,12 +762,10 @@ background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(231, 243, 255, 0.98)); border-bottom-color: rgba(82,128,190,0.30); } -.tool-category[data-tool-category="operate"] .tool-category-body { - background: rgba(238, 247, 255, 0.98); -} .tool-category[data-tool-category="operate"] .tool-category-body { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 5px; + background: rgba(238, 247, 255, 0.98); } .tool-category[data-tool-category="operate"] .tool { grid-template-columns: 1fr; @@ -738,7 +800,7 @@ } } -/* v39.15.47: collapsed event card must shrink to its header. +/* Collapsed event card must shrink to its header. layout.css gives .log-card a min-height, which left a large blank panel when folded. */ .collapsible-card.collapsed { min-height: 0 !important; } .log-card.collapsed { min-height: 0 !important; height: auto !important; flex: 0 0 auto !important; flex-basis: auto !important; } diff --git a/css/layout.css b/css/layout.css index ed5e7b7..07707eb 100644 --- a/css/layout.css +++ b/css/layout.css @@ -2,26 +2,15 @@ .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="ball"] { --tool-icon: url("../assets/ui/tool_ball.webp"); --tool-icon-zoom: 1.36; } .tool[data-tool="delete"] { --tool-icon: url("../assets/ui/tool_delete.webp"); } .tool[data-tool="area_delete"] { --tool-icon: url("../assets/ui/tool_delete.webp"); } .tool[data-tool="new"] { --tool-icon: url("../assets/ui/tool_new.webp"); } .tool[data-tool="shoot"] { --tool-icon: url("../assets/ui/tool_shoot.png"); --tool-icon-zoom: 1.48; } -.tool[data-tool="poke"] { --tool-emoji: "\1F448"; } -.tool[data-tool="pinch"] { --tool-emoji: "\1F90F"; } -.tool[data-tool="water_hose"] { --tool-emoji: "\1F6BF"; } -.tool[data-tool="clear_tool"] { --tool-emoji: "\2715"; } -.tool[data-tool="copy"] { --tool-emoji: "\29c9 "; } -.tool[data-tool="area_delete"] { --tool-emoji: "\d7 "; } -.tool[data-tool="rope"] { --tool-emoji: "\2570 "; } -.tool[data-tool="rod"] { --tool-emoji: "\2501 "; } -.tool[data-tool="reciprocator"] { --tool-emoji: "\21c4 "; } -.tool[data-tool="undo"] { --tool-emoji: "\21b6 "; } -.tool[data-tool="redo"] { --tool-emoji: "\21b7 "; } .tool.tool-emoji-icon { --tool-icon: none; } .tool.tool-emoji-icon::before { - content: var(--tool-emoji); + content: var(--tool-emoji, ""); background: none; display: grid; place-items: center; @@ -55,7 +44,6 @@ transform: translate(-50%, -50%) scale(var(--tool-icon-zoom, 1)) !important; } -.tool[data-tool="ball"] { --tool-icon-zoom: 1.36; } .tool[data-tool="observe"], .tool[data-tool="new"] { --tool-icon-zoom: 1.20; } .tool[data-tool="giant_drug"] { --tool-icon-zoom: 1.58; } @@ -78,16 +66,16 @@ .tool-body { margin-top: 10px; } .tool-palette { display: flex; flex-direction: column; gap: 8px; } .tool-category { - border: 1px solid rgba(84,68,48,0.10); + border: 1px solid var(--tool-cat-line, rgba(84,68,48,0.10)); border-radius: 14px; - background: rgba(255,255,255,0.34); + background: linear-gradient(180deg, var(--tool-cat-a, rgba(255,255,255,0.36)), rgba(255,255,255,0.28)); 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); + border-bottom: 1px solid var(--tool-cat-line, rgba(84,68,48,0.08)); + background: linear-gradient(180deg, var(--tool-cat-a, rgba(255,252,244,0.66)), var(--tool-cat-b, rgba(255,252,244,0.54))); padding: 7px 10px; text-align: left; cursor: pointer; @@ -114,8 +102,8 @@ .selected-category-toggle { width: 100%; border: 0; - border-bottom: 1px solid rgba(84,68,48,0.08); - background: rgba(255,252,244,0.66); + border-bottom: 1px solid var(--tool-cat-line, rgba(84,68,48,0.08)); + background: linear-gradient(180deg, var(--tool-cat-a, rgba(255,252,244,0.66)), var(--tool-cat-b, rgba(255,252,244,0.54))); padding: 8px 10px; text-align: left; cursor: pointer; @@ -340,8 +328,6 @@ meter { .tool-category[data-tool-category="habitat"] { --tool-cat-a: rgba(255,245,218,0.84); --tool-cat-b: rgba(250,229,186,0.76); --tool-cat-line: rgba(174,125,54,0.28); } .tool-category[data-tool-category="physics"] { --tool-cat-a: rgba(226,247,246,0.84); --tool-cat-b: rgba(199,232,231,0.76); --tool-cat-line: rgba(70,145,148,0.28); } .tool-category[data-tool-category="hazard"] { --tool-cat-a: rgba(255,230,224,0.84); --tool-cat-b: rgba(250,207,197,0.78); --tool-cat-line: rgba(189,88,66,0.30); } -.tool-category { border-color: var(--tool-cat-line, rgba(84,68,48,0.10)); background: linear-gradient(180deg, var(--tool-cat-a, rgba(255,255,255,0.36)), rgba(255,255,255,0.28)); } -.tool-category-toggle { background: linear-gradient(180deg, var(--tool-cat-a, rgba(255,252,244,0.66)), var(--tool-cat-b, rgba(255,252,244,0.54))); border-bottom-color: var(--tool-cat-line, rgba(84,68,48,0.08)); } @media (min-width: 921px) { .mobile-mode-controls { display: none !important; } } diff --git a/css/mobile.css b/css/mobile.css index dd123e7..9fa63f2 100644 --- a/css/mobile.css +++ b/css/mobile.css @@ -1,4 +1,4 @@ -/* v15.12.1: top-right sound settings panel */ +/* Sound menu */ .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 { @@ -22,19 +22,8 @@ .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: 980px) { .sound-panel { right: auto; left: 0; } } - -/* Collapsed card sizing is shared by the base panel rules; no event-only shrink override. */ - -/* 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 */ - -/* v15.17.0: mobile layout isolation and canvas touch gestures */ +/* Shared layout and gesture guards */ #app { overflow-x: clip; } .layout { position: relative; z-index: 2; } .panel { position: relative; z-index: 3; } @@ -55,81 +44,21 @@ 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; - } +.log { + overscroll-behavior-y: auto !important; } - -/* Mobile input mode */ -.mobile-mode-controls { +body.touch-mobile-ui .tool-tip-popover { + max-width: min(520px, calc(100vw - 24px)); +} +body.touch-mobile-ui .tool-category:not([data-tool-category="operate"]).collapsed .tool-category-body { 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); -} -body.touch-mobile-ui .mobile-mode-controls:not([hidden]) { display: flex; } -body:not(.touch-mobile-ui) .mobile-mode-controls { display: none !important; } +/* Mobile input controls */ +.mobile-mode-controls, .mobile-rotate-controls { display: none; position: absolute; - right: 10px; - bottom: 58px; z-index: 24; gap: 6px; padding: 6px; @@ -139,6 +68,17 @@ body:not(.touch-mobile-ui) .mobile-mode-controls { display: none !important; } border: 1px solid rgba(120, 95, 60, .16); backdrop-filter: blur(8px); } +.mobile-mode-controls { + left: 10px; + bottom: 10px; + gap: 5px; + background: rgba(255, 251, 245, 0.90); +} +.mobile-rotate-controls { + right: 10px; + bottom: 58px; +} +.mobile-mode-controls button, .mobile-rotate-controls button { border: 0; border-radius: 10px; @@ -149,83 +89,22 @@ body:not(.touch-mobile-ui) .mobile-mode-controls { display: none !important; } background: rgba(255,255,255,.82); box-shadow: inset 0 -1px 0 rgba(0,0,0,.05); } -.mobile-rotate-controls button:active { transform: translateY(1px); } -body.touch-mobile-ui .mobile-rotate-controls:not([hidden]) { display: flex; } -body:not(.touch-mobile-ui) .mobile-rotate-controls { display: none !important; } -@media (max-width: 980px) { - body.touch-mobile-ui .mobile-rotate-controls:not([hidden]) { - position: fixed; - left: 50%; - right: auto; - bottom: calc(env(safe-area-inset-bottom, 0px) + 56px); - transform: translateX(-50%); - z-index: 12002; - max-width: calc(100vw - 22px); - } +.mobile-mode-controls button { padding: 7px 8px; background: rgba(255,255,255,.78); } +.mobile-mode-controls button.active { + color: #3d321f; + background: linear-gradient(180deg, #ffe9a8, #ffd376); + box-shadow: 0 3px 10px rgba(150, 105, 30, .20); } - +.mobile-rotate-controls button:active { transform: translateY(1px); } +body.touch-mobile-ui .mobile-mode-controls:not([hidden]), +body.touch-mobile-ui .mobile-rotate-controls:not([hidden]) { display: flex; } +body:not(.touch-mobile-ui) .mobile-mode-controls, +body:not(.touch-mobile-ui) .mobile-rotate-controls { display: none !important; } body.touch-mobile-ui.mobile-mode-camera #gameCanvas { cursor: grab; } body.touch-mobile-ui.mobile-mode-tool #gameCanvas { cursor: crosshair; } -/* Keep panel themes on narrow layouts. */ -.card.tool-card { --ui-theme-rgb: 0, 114, 178; background: linear-gradient(180deg, rgba(242, 248, 252, 0.94), rgba(232, 243, 250, 0.91)); border-color: rgba(0, 114, 178, 0.24); } -.card.selected-card { --ui-theme-rgb: 204, 121, 167; background: linear-gradient(180deg, rgba(253, 245, 250, 0.94), rgba(249, 235, 244, 0.91)); border-color: rgba(204, 121, 167, 0.24); } -.card.colony-card { --ui-theme-rgb: 0, 158, 115; background: linear-gradient(180deg, rgba(240, 250, 247, 0.94), rgba(229, 245, 239, 0.91)); border-color: rgba(0, 158, 115, 0.24); } -.card.log-card { --ui-theme-rgb: 230, 159, 0; background: linear-gradient(180deg, rgba(255, 249, 236, 0.94), rgba(253, 242, 215, 0.91)); border-color: rgba(230, 159, 0, 0.24); } - - -/* v39.15.35: mobile controls and scroll affordances */ -@media (max-width: 980px) { - body.touch-mobile-ui .mobile-mode-controls:not([hidden]) { - display: flex !important; - } - .panel-quick-tabs { - grid-template-columns: repeat(5, minmax(0, 1fr)); - position: sticky; - top: 0; - } - .panel-quick-tabs button { - padding-left: 3px; - padding-right: 3px; - font-size: 10.5px; - } -} -body.touch-mobile-ui .tool-tip-popover { - max-width: min(520px, calc(100vw - 24px)); -} - -/* v39.15.36: mobile navigation redesign without family input mode */ -@media (max-width: 980px) { - body.touch-mobile-ui .mobile-mode-controls:not([hidden]) { - position: fixed; - left: 50%; - right: auto; - bottom: calc(env(safe-area-inset-bottom, 0px) + 10px); - transform: translateX(-50%); - z-index: 12001; - max-width: calc(100vw - 22px); - } - .panel-quick-tabs { - grid-template-columns: repeat(6, minmax(0, 1fr)); - } - .lineage-main-card { - margin: 10px 0 0; - contain: content; - } - .lineage-main-card .lineage-head { - gap: 8px; - } - .lineage-main-card .lineage-actions { - flex-wrap: wrap; - } - body.touch-mobile-ui .tool-category:not([data-tool-category="operate"]).collapsed .tool-category-body { - display: none; - } - body.touch-mobile-ui .log { - max-height: 240px; - } -} +/* Back to canvas affordance */ .back-to-game-btn { position: fixed; right: calc(env(safe-area-inset-right, 0px) + 12px); @@ -242,173 +121,7 @@ body.touch-mobile-ui .tool-tip-popover { backdrop-filter: blur(8px); } .back-to-game-btn[hidden] { display: none !important; } -@media (min-width: 981px) { - .back-to-game-btn { display: none !important; } -} -/* v39.15.38: keep desktop layout close to v39.15.36; only hide the PC quick-scroll buttons that duplicate the canvas/tool card. */ -@media (min-width: 981px) { - .panel-quick-tabs { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - .panel-quick-tabs [data-panel-tab="game"] { - display: none !important; - } -} - -/* v39.15.38: mobile navigation/footer room and family-graph reachability. */ -@media (max-width: 980px) { - html, - body { - max-width: 100%; - overflow-x: hidden; - } - #app { - width: 100%; - max-width: 100%; - box-sizing: border-box; - padding-left: max(10px, env(safe-area-inset-left, 0px)); - padding-right: max(10px, env(safe-area-inset-right, 0px)); - padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 92px); - overflow-x: clip; - } - .topbar, - .top-left, - .brand, - .layout, - .stage-wrap, - .panel, - .card, - .lineage-main-card { - min-width: 0; - max-width: 100%; - box-sizing: border-box; - } - .top-actions { - width: 100%; - max-width: 100%; - display: flex; - flex-wrap: nowrap; - justify-content: flex-start; - gap: 5px; - overflow-x: auto; - overflow-y: hidden; - padding: 1px 0 5px; - -webkit-overflow-scrolling: touch; - scrollbar-width: thin; - } - .top-actions > .btn, - .top-actions > .sound-menu, - .top-actions .sound-menu-btn { - flex: 0 0 auto; - white-space: nowrap; - } - .top-actions .btn { - padding: 7px 9px; - font-size: 11px; - } - .room-link { - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - } - body.touch-mobile-ui .mobile-mode-controls:not([hidden]) { - position: absolute; - left: 50%; - right: auto; - bottom: 10px; - transform: translateX(-50%); - z-index: 24; - max-width: calc(100% - 18px); - } - body.touch-mobile-ui .panel-quick-tabs { - position: fixed; - left: max(8px, env(safe-area-inset-left, 0px)); - right: max(8px, env(safe-area-inset-right, 0px)); - bottom: calc(env(safe-area-inset-bottom, 0px) + 8px); - top: auto; - z-index: 12002; - width: auto; - max-width: none; - grid-template-columns: repeat(6, minmax(0, 1fr)); - gap: 4px; - margin: 0; - padding: 6px; - border: 1px solid rgba(102, 169, 215, 0.34); - border-radius: 16px; - background: rgba(244, 250, 247, 0.95); - box-shadow: 0 12px 28px rgba(42, 54, 64, 0.18); - } - body.touch-mobile-ui .panel-quick-tabs button { - min-height: 34px; - padding: 5px 2px; - font-size: 10px; - } - body.touch-mobile-ui .selected-card, - body.touch-mobile-ui .tool-card, - body.touch-mobile-ui .colony-card, - body.touch-mobile-ui .log-card, - body.touch-mobile-ui .lineage-main-card { - scroll-margin-top: 10px; - scroll-margin-bottom: calc(env(safe-area-inset-bottom, 0px) + 88px); - } - body.touch-mobile-ui .lineage-main-card { - margin-bottom: calc(env(safe-area-inset-bottom, 0px) + 78px); - } - .back-to-game-btn { - bottom: calc(env(safe-area-inset-bottom, 0px) + 62px); - right: max(10px, env(safe-area-inset-right, 0px)); - } -} - - -/* v39.15.47: desktop rollback guard. Keep the normal PC layout; only remove duplicated quick-scroll buttons. */ -@media (min-width: 981px) { - .topbar { - display: flex; - align-items: center; - justify-content: space-between; - flex-wrap: wrap; - gap: 14px 18px; - } - .top-left { - flex: 1 0 auto; - min-width: max-content; - max-width: 100%; - } - .brand, - .brand h1, - h1 { - flex: 0 0 auto; - min-width: max-content; - max-width: none !important; - overflow: visible !important; - text-overflow: clip !important; - } - .top-actions { - flex: 1 1 560px; - margin-left: auto; - justify-content: flex-end; - align-items: center; - gap: 10px; - } - .top-actions .btn, - .top-actions .sound-menu-btn, - .room-link { - min-height: 42px; - padding: 10px 16px; - font-size: 13px; - line-height: 1.15; - } - .panel-quick-tabs { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - .panel-quick-tabs [data-panel-tab="game"] { - display: none !important; - } -} - -/* v39.15.47: PC / smartphone UI isolation. All override UI placement is scoped by width. */ @media (min-width: 981px) { html, body { @@ -420,18 +133,8 @@ body.touch-mobile-ui .tool-tip-popover { padding: 18px; overflow: visible; } - .topbar { - display: flex; - align-items: center; - justify-content: space-between; - flex-wrap: wrap; - gap: 14px 18px; - } - .top-left { - flex: 1 0 auto; - min-width: max-content; - max-width: 100%; - } + .topbar { gap: 12px; } + .top-left { max-width: 100%; } .brand, .brand h1, h1 { @@ -441,20 +144,19 @@ body.touch-mobile-ui .tool-tip-popover { overflow: visible !important; text-overflow: clip !important; } - .top-actions { - flex: 1 1 560px; - margin-left: auto; - justify-content: flex-end; - align-items: center; - gap: 10px; - } + .top-actions { margin-left: auto; } .top-actions .btn, .top-actions .sound-menu-btn, .room-link { - min-height: 42px; - padding: 10px 16px; - font-size: 13px; - line-height: 1.15; + min-height: 38px; + padding: 8px 10px; + font-size: 12px; + line-height: 1.12; + } + .room-link { + max-width: 180px; + overflow: hidden; + text-overflow: ellipsis; } .layout { display: grid; @@ -474,18 +176,12 @@ body.touch-mobile-ui .tool-tip-popover { top: 0; grid-template-columns: repeat(5, minmax(0, 1fr)); } - .panel-quick-tabs [data-panel-tab="game"] { - display: none !important; - } + .panel-quick-tabs [data-panel-tab="game"] { display: none !important; } .lineage-main-card { display: block; visibility: visible; - position: relative; - z-index: 1; width: auto; margin: 16px 0 0; - overflow: hidden; - contain: layout paint; } .lineage-main-content { height: min(78vh, 980px); @@ -494,6 +190,7 @@ body.touch-mobile-ui .tool-tip-popover { overflow: auto; overscroll-behavior: auto; } + .back-to-game-btn { display: none !important; } } @media (max-width: 980px) { @@ -526,16 +223,11 @@ body.touch-mobile-ui .tool-tip-popover { box-sizing: border-box; } .topbar { - display: flex; flex-direction: column; align-items: stretch; gap: 8px; } - .top-left { - display: flex; - align-items: center; - gap: 8px; - } + .top-left { gap: 8px; } .brand h1, h1 { max-width: 100%; @@ -545,8 +237,6 @@ body.touch-mobile-ui .tool-tip-popover { font-size: clamp(20px, 7vw, 30px); } .top-actions { - display: flex; - flex-wrap: nowrap; justify-content: flex-start; gap: 5px; width: 100%; @@ -567,13 +257,12 @@ body.touch-mobile-ui .tool-tip-popover { padding: 7px 9px; font-size: 11px; } + .sound-panel { right: auto; left: 0; } .layout { display: flex; flex-direction: column; align-items: stretch; gap: 10px; - position: relative; - z-index: 2; overflow: visible; } .stage-wrap { @@ -628,6 +317,15 @@ body.touch-mobile-ui .tool-tip-popover { z-index: 24; max-width: calc(100% - 18px); } + body.touch-mobile-ui .mobile-rotate-controls:not([hidden]) { + position: fixed; + left: 50%; + right: auto; + bottom: calc(env(safe-area-inset-bottom, 0px) + 56px); + transform: translateX(-50%); + z-index: 12002; + max-width: calc(100vw - 22px); + } body.touch-mobile-ui.mobile-mode-auto #gameCanvas { touch-action: pan-y pinch-zoom !important; } @@ -639,13 +337,10 @@ body.touch-mobile-ui .tool-tip-popover { max-height: none !important; height: auto !important; overflow: visible !important; - overscroll-behavior-y: auto !important; } .lineage-main-card { display: block !important; visibility: visible !important; - position: relative; - z-index: 1; width: 100%; margin: 10px 0 calc(env(safe-area-inset-bottom, 0px) + 132px); overflow: visible !important; @@ -664,7 +359,6 @@ body.touch-mobile-ui .tool-tip-popover { touch-action: pan-y pinch-zoom; } .lineage-family-tree { - max-width: 100%; overflow-x: auto !important; overflow-y: visible !important; overscroll-behavior-x: contain; @@ -672,9 +366,7 @@ body.touch-mobile-ui .tool-tip-popover { -webkit-overflow-scrolling: touch; touch-action: pan-x pan-y pinch-zoom; } - .lineage-family-tree .lineage-tree-panel { - max-width: none; - } + .lineage-family-tree .lineage-tree-panel { max-width: none; } .selected-card, .tool-card, .colony-card, @@ -684,4 +376,8 @@ body.touch-mobile-ui .tool-tip-popover { scroll-margin-top: 0 !important; scroll-margin-bottom: calc(env(safe-area-inset-bottom, 0px) + 104px); } + .back-to-game-btn { + bottom: calc(env(safe-area-inset-bottom, 0px) + 62px); + right: max(10px, env(safe-area-inset-right, 0px)); + } } diff --git a/css/panel.css b/css/panel.css index 80cfa3e..0dc1763 100644 --- a/css/panel.css +++ b/css/panel.css @@ -99,6 +99,7 @@ body::before { box-shadow: 0 3px 8px rgba(64,48,32,0.045); overflow: hidden; isolation: isolate; + overflow: hidden !important; } .family-node.child { border-color: rgba(103, 178, 44, 0.38); @@ -157,7 +158,7 @@ body::before { box-shadow: inset 0 0 0 1px rgba(247, 200, 64, 0.30), 0 3px 8px rgba(120, 78, 12, 0.09); } .lineage-family-tree .tree-node.champion::before { - content: "♛"; + content: "\265B "; position: absolute; right: 6px; top: 4px; @@ -182,40 +183,6 @@ body::before { text-overflow: ellipsis; white-space: nowrap; } -.family-personality-tags { - display: grid !important; - grid-template-columns: repeat(2, minmax(0, 1fr)); - grid-auto-rows: minmax(13px, auto); - align-items: stretch; - gap: 2px 4px; - margin-top: 2px; - max-width: 84px; - width: 84px; - max-height: 34px; - overflow: hidden !important; - text-overflow: clip !important; - white-space: normal !important; -} -.family-personality-tags em { - display: flex; - align-items: center; - justify-content: center; - min-width: 0; - max-width: 100%; - padding: 1px 3px; - border-radius: 999px; - background: rgba(103,178,44,0.11); - border: 1px solid rgba(103,178,44,0.20); - color: rgba(64,72,48,0.86); - font-size: 8.2px; - font-style: normal; - line-height: 1.18; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - - .tool[data-tip] { position: relative; } @@ -353,23 +320,6 @@ body::before { border-radius: 9px; background: rgba(255,255,255,0.70); } -.lineage-family-tree .tree-node .family-copy { - max-width: calc(100% - 46px); - width: auto; -} -.lineage-family-tree .tree-node .family-copy strong, -.lineage-family-tree .tree-node .family-copy > span:not(.family-genetic-stats):not(.family-fight-stat):not(.family-personality-tags) { - max-width: 100%; -} -.lineage-family-tree .tree-node .family-personality-tags { - max-width: 84px; - width: 84px; -} -.lineage-family-tree .tree-node .family-personality-tags em { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} @media (max-width: 720px) { .lineage-main-content { height: 70vh; @@ -421,21 +371,22 @@ body::before { } -/* v9: keep 2x2 personality tags inside fixed family-tree nodes. */ -.lineage-family-tree .tree-node .family-personality-tags, +/* Family tree personality tags: consolidated final cascade. */ .family-personality-tags { box-sizing: border-box !important; display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-auto-rows: 13px !important; gap: 2px 3px !important; - width: 86px !important; - max-width: 86px !important; + width: 100% !important; + max-width: 100% !important; height: 28px !important; max-height: 28px !important; + margin-left: 0 !important; + margin-right: 0 !important; + justify-self: stretch !important; overflow: hidden !important; } -.lineage-family-tree .tree-node .family-personality-tags em, .family-personality-tags em { box-sizing: border-box !important; display: block !important; @@ -449,42 +400,39 @@ body::before { white-space: nowrap !important; line-height: 11px !important; font-size: 7.2px !important; + font-style: normal; letter-spacing: -0.08em !important; text-align: center !important; -} - -/* v39.15.85: push family-tree personality tags to the node's right edge. */ -.lineage-family-tree .tree-node .family-personality-tags, -.family-personality-tags { - margin-left: auto !important; - margin-right: 0 !important; - justify-self: end !important; + border-radius: 999px; + background: rgba(103,178,44,0.11); + border: 1px solid rgba(103,178,44,0.20); + color: rgba(64,72,48,0.86); } .lineage-family-tree .tree-node .family-copy { width: 100% !important; max-width: 100% !important; + position: static !important; + display: flex !important; + flex-direction: column !important; + gap: 1px !important; } .lineage-family-tree .tree-node .family-copy strong, .lineage-family-tree .tree-node .family-copy > span:not(.family-personality-tags) { - max-width: calc(100% - 46px) !important; + max-width: 100% !important; } .lineage-family-tree .tree-node .family-copy > .family-personality-tags { - max-width: 86px !important; - width: 86px !important; -} - -/* v39.15.87: let family personality tags use the full node width. */ -.lineage-family-tree .tree-node .family-copy > .family-personality-tags, -.lineage-family-tree .tree-node .family-personality-tags, -.family-personality-tags { + position: static !important; width: 100% !important; max-width: 100% !important; - margin-left: 0 !important; - margin-right: 0 !important; - justify-self: stretch !important; - grid-template-columns: repeat(2, minmax(0, 1fr)) !important; + height: 24px !important; + max-height: 24px !important; + margin: 2px 0 0 !important; + grid-auto-rows: 11px !important; + gap: 1px 3px !important; + z-index: 3 !important; } -.lineage-family-tree .tree-node .family-copy strong, -.lineage-family-tree .tree-node .family-copy > span:not(.family-personality-tags) { - max-width: 100% !important; +.lineage-family-tree .tree-node .family-personality-tags em { + height: 11px !important; + line-height: 9px !important; + font-size: 6.8px !important; } diff --git a/index.html b/index.html index 30ac200..f017603 100644 --- a/index.html +++ b/index.html @@ -7,11 +7,11 @@ - - - - - + + + + +
@@ -48,6 +48,7 @@
+ @@ -102,8 +103,8 @@
状態安定
地面
-
-
気温10℃
+
+
気温10℃
@@ -158,20 +159,20 @@

リセット設定

サイズとプリセットを組み合わせて観察環境を生成します。

サイズ
-
+
プリセット
- - - - - - - + + + + + + +
@@ -182,15 +183,53 @@ + + + +