diff --git a/AI_MAP.md b/AI_MAP.md new file mode 100644 index 0000000..78a68e1 --- /dev/null +++ b/AI_MAP.md @@ -0,0 +1,58 @@ +# tarinai_ AI map + +Purpose: static Japanese browser simulation/game. Optimize context by reading this file only after `README.md`, then open the relevant subsystem files. For exact file expansion, use `scripts/ai_inventory.ps1` or `scripts/ai_inventory.py`. + +## Architecture + +- 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`. +- 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`. +- 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. + +## Subsystem Map + +- Core/bootstrap: `js/version.js`, `js/event_bus.js`, registries, `js/data.js`, `js/ground_types.js`, `js/health.js`, `js/main.js`, `js/debug_tools.js`, `js/perf_profiler.js`. +- Rendering/assets/audio: `js/assets.js`, `js/audio.js`, `js/render.js`, `js/tarinai_render.js`, `js/item_render_runtime.js`, `js/sound_pack.js`. +- Simulation phases: `js/sim_core.js`, `js/simulation*.js`, `js/world_update*.js`, `js/system_order.js`. +- World domain: `js/world*.js`, `js/weather_system.js`; covers state, camera/view, environment, combat/effects, placement/history, tools, family/social, ants, spatial budgets. +- Creature domain: `js/tarinai*.js`; covers state, identity, needs, actions, forced behavior, social life, item effects, disease/nests, movement/update pipeline, rendering. +- Item/structure domain: `js/item*.js`, `js/items.js`, `js/structures.js`, `js/structure_lifecycle.js`; covers definitions, spawning defaults, lifecycle, dynamic behavior, rendering. +- Physics/mechanics: `js/physics*.js`, `js/mechanical_system.js`, `js/constraint_system.js`, `js/collision_footprint_system.js`. +- UI/input: `js/ui*.js`, `js/text_catalog.js`, `js/command_dispatcher.js`; covers panels, tools, selected creature, logs, charts, family tree, mouse/touch, dialogs, labels. +- Family tree: `js/family_graph.js`, `js/ui_family_*.js`; data transform, layout, paths, async rendering, validation. +- Save/history: `js/save*.js`, `js/snapshot_system.js`, `js/restore_coordinator.js`, `js/history_system.js`. +- Scripts: `scripts/generate_app_files.py`, `scripts/generate_item_icons.py`, `scripts/regression_check.py`, `scripts/ai_inventory.py`, `scripts/ai_inventory.ps1`. + +## File Pattern Semantics + +- `*_pipeline.js`: ordered runner/facade for update or lifecycle work. +- `*_step_*.js`: narrow pipeline step wrapper. +- `*_system.js`: domain service, phase service, or compatibility facade. +- `*_runtime.js`: stable runtime-facing facade around split modules. +- `*_registry.js`: definition registry and lookup/normalization helpers. +- `world_*`: world-owned behavior; `tarinai_*`: creature-owned behavior; `item_*`: item-owned behavior; `ui_*`: DOM/input/panel behavior. +- `assets/sprites/tarinai_*.webp`: creature visual state sprites; numeric prefix is stable asset ID/order. +- `assets/ui/tool_*`: tool palette icons; `assets/ui/favicon*`, `apple-touch-icon`, `ecology_*` are app/help icons. +- `assets/objects/*`: field object sprites for ants, zunchi, pushpin, oshibyo, genkotsu, plushie. +- `assets/sounds/voice_*`: creature voice samples; `shoot_*`, `major_damage_*`, `firecracker_*` are SFX. + +## Task-Oriented Read Sets + +- UI/layout bug: `index.html`, relevant `css/*.css`, `js/ui_bind.js`, `js/ui_layout_dialogs.js`, matching `js/ui_*.js`. +- 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`. +- 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`. + +## Invariants + +- 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. +- Prefer focused edits in the owning subsystem; split modules are intentional compatibility boundaries. +- Run `node --check js/*.js` and `python scripts/regression_check.py` for behavior changes. diff --git a/FILES.json b/FILES.json new file mode 100644 index 0000000..3e7d929 --- /dev/null +++ b/FILES.json @@ -0,0 +1,91 @@ +{ + "purpose": "Token-efficient machine-readable routing for tarinai_. Use scripts/ai_inventory.py for exact current file expansion.", + "version": "39.15.47", + "entrypoints": { + "app": "index.html", + "runtime": "js/main.js", + "update_order": "js/system_order.js", + "manifest": "app_manifest.json", + "service_worker": "service-worker.js" + }, + "read_strategy": { + "default": ["README.md"], + "architecture": ["README.md", "AI_MAP.md"], + "exact_inventory": ["powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ai_inventory.ps1 -All", "python scripts/ai_inventory.py --all"], + "machine_routing": ["FILES.json"] + }, + "groups": [ + { + "id": "root", + "patterns": [".gitignore", ".htaccess", "app_manifest.json", "favicon.ico", "index.html", "README.md", "AI_MAP.md", "FILES.json", "service-worker.js"], + "meaning": "Repo/app shell metadata, server/static cache config, docs, manifest, entrypoint." + }, + { + "id": "css", + "patterns": ["css/*.css"], + "meaning": "Base, layout, panel, component, and mobile responsive styling." + }, + { + "id": "scripts", + "patterns": ["scripts/*.py", "scripts/*.ps1"], + "meaning": "Generators, regression checks, and token-aware AI inventory tooling." + }, + { + "id": "core", + "patterns": ["js/version.js", "js/event_bus.js", "js/registry_base.js", "js/disease_registry.js", "js/sound_pack.js", "js/data.js", "js/ground_types.js", "js/health.js", "js/input_mode_manager.js", "js/main.js", "js/math.js", "js/patch_helpers.js", "js/perf_profiler.js", "js/debug_tools.js"], + "meaning": "Bootstrap, shared constants/helpers, registries, config, profiling/debug." + }, + { + "id": "assets_runtime", + "patterns": ["js/assets.js", "js/audio.js", "js/render.js", "js/tarinai_render.js", "js/item_render_runtime.js"], + "meaning": "Image/audio loading and canvas rendering." + }, + { + "id": "simulation", + "patterns": ["js/sim_core.js", "js/simulation*.js", "js/system_order.js"], + "meaning": "Simulation primitives, concrete systems, phase ordering." + }, + { + "id": "world", + "patterns": ["js/world*.js", "js/weather_system.js"], + "meaning": "World state/view/update/tools/environment/combat/family/social/ants." + }, + { + "id": "physics", + "patterns": ["js/physics*.js", "js/mechanical_system.js", "js/constraint_system.js", "js/collision_footprint_system.js"], + "meaning": "Geometry, collisions, constraints, mechanical item behavior." + }, + { + "id": "items", + "patterns": ["js/item*.js", "js/items.js", "js/structures.js", "js/structure_lifecycle.js"], + "meaning": "Item/structure registry, lifecycle, dynamic behavior, rendering." + }, + { + "id": "tarinai", + "patterns": ["js/tarinai*.js", "js/ants.js"], + "meaning": "Creature state/actions/needs/social life/item effects/disease/rendering plus ant actor model." + }, + { + "id": "save", + "patterns": ["js/save*.js", "js/snapshot_system.js", "js/restore_coordinator.js", "js/history_system.js"], + "meaning": "Snapshot schema/codec/storage/restore/history." + }, + { + "id": "ui", + "patterns": ["js/ui*.js", "js/text_catalog.js", "js/command_dispatcher.js", "js/family_graph.js"], + "meaning": "DOM UI, input, tools, selected panel, logs, charts, family tree, text labels, command routing." + }, + { + "id": "assets", + "patterns": ["assets/sprites/tarinai_*.webp", "assets/ui/tool_*", "assets/ui/favicon*", "assets/ui/apple-touch-icon.png", "assets/ui/ecology_*.webp", "assets/objects/*", "assets/sounds/*"], + "meaning": "Creature sprites, UI/tool icons, field object images, voice/SFX samples." + } + ], + "conventions": { + "*_pipeline.js": "ordered runner/facade", + "*_step_*.js": "pipeline stage wrapper", + "*_system.js": "domain service or compatibility facade", + "*_runtime.js": "stable runtime-facing facade", + "*_registry.js": "definition lookup/normalization" + } +} diff --git a/README.md b/README.md index 08b101d..36d7f2d 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,82 @@ -# tarinai v39.15.39 +# tarinai_ -## 変更点 +AI-first entrypoint for a static browser simulation/game. Keep this file small; read deeper docs only when needed. -- PC表示を再度ロールバックし、PC側の変更はクイックスクロールの「本体」「道具」ボタン非表示に限定。道具UI本体は維持。 -- PC上部ボタンを右詰め・やや大きめに調整し、ゲームタイトルがボタンに押されて省略されないように修正。 -- スマホ用のスクロールスナップ系指定を無効化し、通常スクロールを妨げないように修正。 -- スマホで「家系図」へ移動したとき、更新OFFでも手動ジャンプ扱いで現在の家系図を描画してからスクロールするように修正。 -- スマホの自動スクロールボタンは、初期折り畳み部分を開いてから目的地へ移動。ユーザーが手動で閉じた部分は開かない挙動を維持。 -- たりない/道具系ツールチップの最大幅・折り返し・画面端補正を維持。 -- 「333の部屋に移動」のリンク先は `https://2012r2.nishi.boats/~333/`。 -- 「観察」は「たりないデータ」の表記を維持。 +## Read Strategy -## 確認 +- Start here for architecture, script order constraints, and where to look next. +- For subsystem work, read `AI_MAP.md` plus only the matching files. +- For exact file inventory, run `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ai_inventory.ps1 -All` or narrow it: `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ai_inventory.ps1 ui`. Python equivalent: `python scripts/ai_inventory.py --all`. +- For machine-readable routing, read `FILES.json`. +- Avoid loading all assets into context; asset filenames are mostly self-describing and grouped by glob. -- `node --check js/*.js` passed -- `python3 scripts/regression_check.py` passed -- version synchronized: `39.15.39` +## Runtime Shape + +- No bundler; `index.html` loads ordered global-IIFE scripts with `?v=39.15.47`. +- 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`. +- Generated/static app shell: `app_manifest.json`, `service-worker.js`, and `js/version.js` must stay version-aligned. + +## File Routing + +- `index.html`: DOM shell, CSS/JS load order, panels/dialogs/canvas. +- `css/*.css`: base/layout/panel/components/mobile styling. +- `js/world*.js`: world state, view, update phases, tools, placement, combat, environment, family/social, ants. +- `js/tarinai*.js`: creature state, needs, actions, behavior, social life, item effects, update pipeline, rendering. +- `js/item*.js`, `js/structures*.js`: item registry/runtime/lifecycle/dynamic behavior/rendering plus structures. +- `js/simulation*.js`, `js/system_order.js`, `js/sim_core.js`: concrete update systems and phase ordering. +- `js/ui*.js`, `js/text_catalog.js`, `js/command_dispatcher.js`: DOM UI, input, selected panel, logs, charts, family tree, tools, labels. +- `js/save*.js`, `js/snapshot_system.js`, `js/restore_coordinator.js`, `js/history_system.js`: persistence and history. +- `js/physics*.js`, `js/mechanical_system.js`, `js/constraint_system.js`, `js/collision_footprint_system.js`: geometry, mechanics, constraints, collisions. +- `assets/sprites/tarinai_*.webp`: creature state sprites. +- `assets/ui/tool_*`: tool palette icons; other `assets/ui/*` are app/help icons. +- `assets/objects/*`: field object images. +- `assets/sounds/*`: voice and SFX samples. +- `scripts/*`: generators, regression checks, and AI inventory. + +## Conventions + +- `*_pipeline` = ordered runner/facade. +- `*_step_*` = pipeline stage wrapper. +- `*_system` = domain service or compatibility facade. +- `*_runtime` = stable runtime-facing facade. +- `*_registry` = definition lookup/normalization. +- Many split files preserve regression contracts; do not collapse them casually. + +## Checks + +- Syntax: `node --check js/*.js` +- Regression: `python scripts/regression_check.py` +- Inventory sanity: `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ai_inventory.ps1 -All` + + +## v39.15.47 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. +- Smartphone manual scroll no longer uses internal vertical scroll traps for event log / family tree content. +- Auto-scroll does not open collapsed cards. + + +## v39.15.47 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. +- Family tree nodes show inherited stats in a 2x2 grid and move the tarinai portrait to the upper-right. +- Oshibyo lodged position is anchored to the left side of the tarinai sprite. + + +## v39.15.47 family / sprinkler 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. +- Sprinkler rendering is redesigned to a more realistic yard-sprinkler look and now emits water-like spray effects when active. + + +## v39.15.47 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. +- Shooting impact effects are larger and remain visible for slightly longer. diff --git a/SENSOR_IDEAS.md b/SENSOR_IDEAS.md deleted file mode 100644 index 59d2b36..0000000 --- a/SENSOR_IDEAS.md +++ /dev/null @@ -1,43 +0,0 @@ -# センサー系アイデア - -実験観察ゲームとして、直接介入ではなく「測る」ための道具案。 - -## 低コストで入れやすいもの - -| センサー | 役割 | 記録する値 | 観察上の使い道 | -|---|---|---|---| -| ストレスセンサー | 範囲内の緊張度を測る | 平均ストレス / 最大ストレス / 急上昇回数 | 地形・混雑・病気・王者個体の影響を見る | -| 通過カウンター | 置いた地点を通った回数を数える | 通過数 / 個体別通過数 | 道・縄張り・回避行動の発見 | -| 滞在センサー | 範囲内にいた時間を測る | 滞在秒数 / 個体ID / 世代 | 好まれる場所・避けられる場所の比較 | -| けんかセンサー | 範囲内の争いを記録 | 勝者 / 敗者 / 勝率変化 | 王者候補・危険地帯の検出 | -| 汚染センサー | ずんち・病気・汚れを見る | 汚染量 / 増加量 / 感染者数 | スプリンクラーや隔離の効果検証 | -| 出生センサー | 近くで生まれた個体を記録 | 親 / 子 / 遺伝値 | 繁殖条件・血統観察 | - -## 中コストのセンサー - -| センサー | 仕様 | -|---|---| -| 個体追跡ビーコン | 特定個体に付ける。移動経路、接触相手、食事、喧嘩、睡眠を時系列で記録する。 | -| 関係センサー | 範囲内で友好・敵対が増減した時だけログを残す。群れの分裂や王者の圧力を見やすくする。 | -| 遺伝スキャナー | 選択個体の寿命・サイズ・攻撃・速度の遺伝倍率を読み取る。家系図の補助UIにも使える。 | -| 行動理由センサー | 近くの個体が「なぜその行動を選んだか」を短く記録する。空腹、恐怖、王者回避、繁殖欲求など。 | -| 死因センサー | 範囲内の死亡時に、直前の状態・接触相手・地面・病気・道具をまとめる。事故検証用。 | - -## 高コストだが強いもの - -| センサー | 仕様 | -|---|---| -| ヒートマップ装置 | ストレス、滞在、喧嘩、死亡、汚染、出生を色で重ねて表示する。 | -| A/B実験レコーダー | 2つの区画に別条件を設定し、生存数・出生数・平均寿命・王者発生率を比較する。 | -| 血統観察端末 | 家系ごとの平均寿命、平均サイズ、勝率、移動速度、病気耐性をランキング表示する。 | -| 社会構造センサー | 群れの中心個体、孤立個体、王者、敵対ネットワークをグラフ化する。 | - -## 特に相性が良い実装順 - -1. 通過カウンター -2. ストレスセンサー -3. けんかセンサー -4. 遺伝スキャナー -5. ヒートマップ装置 - -最初は「画面内に結果を出す道具」ではなく、ログとグラフに測定値を流すだけでも十分に実験感が出る。 diff --git a/app_manifest.json b/app_manifest.json index 06bddab..f625184 100644 --- a/app_manifest.json +++ b/app_manifest.json @@ -1,5 +1,5 @@ { - "version": "39.15.39", + "version": "39.15.47", "css": [ "css/base.css", "css/layout.css", diff --git a/css/components.css b/css/components.css index 6eed2b6..0e998ff 100644 --- a/css/components.css +++ b/css/components.css @@ -801,3 +801,9 @@ max-width: min(280px, calc(100vw - 24px)); } } + +/* v39.15.47: 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; } +.log-card.collapsed .panel-card-body { display: none !important; } diff --git a/css/mobile.css b/css/mobile.css index a3c1f51..877dd25 100644 --- a/css/mobile.css +++ b/css/mobile.css @@ -59,7 +59,7 @@ .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; } } +@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. */ @@ -363,7 +363,7 @@ body.touch-mobile-ui .tool-tip-popover { } -/* v39.15.39: desktop rollback guard. Keep the normal PC layout; only remove duplicated quick-scroll buttons. */ +/* v39.15.47: desktop rollback guard. Keep the normal PC layout; only remove duplicated quick-scroll buttons. */ @media (min-width: 981px) { .topbar { display: flex; @@ -410,19 +410,281 @@ body.touch-mobile-ui .tool-tip-popover { } } -/* v39.15.39: mobile scroll must remain manual; disable any CSS scroll snapping. */ +/* v39.15.47: PC / smartphone UI isolation. All override UI placement is scoped by width. */ +@media (min-width: 981px) { + html, + body { + overflow-x: hidden; + overflow-y: auto; + } + #app { + width: min(1480px, 100vw); + 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%; + } + .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; + } + .layout { + display: grid; + grid-template-columns: minmax(680px, 1fr) minmax(320px, 390px); + align-items: start; + } + .panel { + position: sticky; + top: 12px; + align-self: start; + max-height: calc(100vh - 24px); + overflow-y: auto; + overflow-x: hidden; + } + .panel-quick-tabs { + position: sticky; + top: 0; + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + .panel-quick-tabs [data-panel-tab="game"], + .panel-quick-tabs [data-panel-tab="tools"] { + 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); + min-height: 520px; + max-height: calc(100vh - 120px); + overflow: auto; + overscroll-behavior: auto; + } +} + @media (max-width: 980px) { - html, body, #app, .layout, .stage-wrap, .panel, .card, .lineage-main-card { - scroll-snap-type: none !important; - scroll-snap-align: none !important; - scroll-snap-stop: normal !important; + html, + body { + width: 100%; + max-width: 100%; + min-height: 100%; + overflow-x: hidden; + overflow-y: auto; + overscroll-behavior-y: auto; + } + #app { + width: 100%; + max-width: 100%; + padding: 10px max(10px, env(safe-area-inset-right, 0px)) calc(env(safe-area-inset-bottom, 0px) + 104px) max(10px, env(safe-area-inset-left, 0px)); + overflow-x: clip; + overflow-y: visible; + } + .topbar, + .top-left, + .brand, + .layout, + .stage-wrap, + .panel, + .card, + .lineage-main-card { + min-width: 0; + max-width: 100%; + box-sizing: border-box; + } + .topbar { + display: flex; + flex-direction: column; + align-items: stretch; + gap: 8px; + } + .top-left { + display: flex; + align-items: center; + gap: 8px; + } + .brand h1, + h1 { + max-width: 100%; + overflow: visible; + text-overflow: clip; + white-space: nowrap; + font-size: clamp(20px, 7vw, 30px); + } + .top-actions { + display: flex; + flex-wrap: nowrap; + justify-content: flex-start; + gap: 5px; + width: 100%; + overflow-x: auto; + overflow-y: hidden; + padding: 1px 0 5px; + -webkit-overflow-scrolling: touch; + } + .top-actions > .btn, + .top-actions > .sound-menu, + .top-actions .sound-menu-btn { + flex: 0 0 auto; + white-space: nowrap; + } + .top-actions .btn, + .top-actions .sound-menu-btn { + min-height: 34px; + padding: 7px 9px; + font-size: 11px; + } + .layout { + display: flex; + flex-direction: column; + align-items: stretch; + gap: 10px; + position: relative; + z-index: 2; + overflow: visible; + } + .stage-wrap { + position: relative; + width: 100%; + overflow: hidden; + } + .panel { + position: relative !important; + top: auto !important; + display: flex; + flex-direction: column; + gap: 10px; + width: 100%; + max-height: none !important; + height: auto !important; + overflow: visible !important; + isolation: auto; + } + body.touch-mobile-ui .panel-quick-tabs, + .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; + display: grid; + grid-template-columns: repeat(6, minmax(0, 1fr)); + gap: 4px; + width: auto; + max-width: none; + 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); + } + .panel-quick-tabs button { + min-height: 34px; + padding: 5px 2px; + font-size: 10px; + } + body.touch-mobile-ui .mobile-mode-controls:not([hidden]) { + display: flex !important; + position: absolute; + left: 50%; + right: auto; + bottom: 10px; + transform: translateX(-50%); + z-index: 24; + max-width: calc(100% - 18px); + } + body.touch-mobile-ui.mobile-mode-auto #gameCanvas { + touch-action: pan-y pinch-zoom !important; + } + body.touch-mobile-ui.mobile-mode-camera #gameCanvas, + body.touch-mobile-ui.mobile-mode-tool #gameCanvas { + touch-action: none !important; + } + .log { + max-height: none !important; + height: auto !important; + overflow: visible !important; + overscroll-behavior-y: auto !important; } .lineage-main-card { display: block !important; visibility: visible !important; - margin-bottom: calc(env(safe-area-inset-bottom, 0px) + 132px); + position: relative; + z-index: 1; + width: 100%; + margin: 10px 0 calc(env(safe-area-inset-bottom, 0px) + 132px); + overflow: visible !important; + contain: none !important; + clear: both; } .lineage-main-content { + display: block !important; + height: auto !important; min-height: 360px; + max-height: none !important; + overflow-x: hidden !important; + overflow-y: visible !important; + overscroll-behavior-y: auto !important; + -webkit-overflow-scrolling: auto; + touch-action: pan-y pinch-zoom; + } + .lineage-family-tree { + max-width: 100%; + overflow-x: auto !important; + overflow-y: visible !important; + overscroll-behavior-x: contain; + overscroll-behavior-y: auto; + -webkit-overflow-scrolling: touch; + touch-action: pan-x pan-y pinch-zoom; + } + .lineage-family-tree .lineage-tree-panel { + max-width: none; + } + .selected-card, + .tool-card, + .colony-card, + .log-card, + .lineage-main-card, + .stage-wrap { + scroll-margin-top: 0 !important; + scroll-margin-bottom: calc(env(safe-area-inset-bottom, 0px) + 104px); } } diff --git a/css/panel.css b/css/panel.css index 81b8109..6cd69fd 100644 --- a/css/panel.css +++ b/css/panel.css @@ -121,19 +121,39 @@ body::before { } .family-genetic-stats { - display: block; + display: grid !important; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 1px 5px; margin-top: 2px; font-size: 9px; - line-height: 1.16; + line-height: 1.12; color: rgba(88, 70, 48, 0.86); letter-spacing: -0.02em; white-space: normal; - max-width: 104px; + max-width: 82px; } -.family-genetic-stats b { +.family-genetic-stats span { + display: inline-flex; + gap: 1px; + min-width: 0; + white-space: nowrap; +} +.family-genetic-stats b, +.family-fight-stat b { font-weight: 800; color: rgba(120, 86, 30, 0.92); } +.family-fight-stat { + display: block; + margin-top: 1px; + max-width: 82px; + font-size: 9px; + line-height: 1.12; + color: rgba(88, 70, 48, 0.82); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} .lineage-family-tree .tree-node.champion { border-color: rgba(202, 146, 33, 0.58); box-shadow: inset 0 0 0 1px rgba(247, 200, 64, 0.30), 0 3px 8px rgba(120, 78, 12, 0.09); @@ -173,18 +193,19 @@ body::before { color: rgba(126, 80, 64, 0.92); } .family-personality-tags { - display: flex !important; + display: grid !important; + grid-template-columns: repeat(2, minmax(0, 1fr)); overflow: visible !important; text-overflow: clip !important; - flex-wrap: wrap; - gap: 2px; + gap: 2px 4px; margin-top: 2px; white-space: normal !important; - overflow: visible; max-height: none; + max-width: 84px; } .family-personality-tags em { - display: inline-block; + display: block; + min-width: 0; max-width: none; padding: 1px 4px; border-radius: 999px; @@ -194,8 +215,8 @@ body::before { font-size: 7.5px; font-style: normal; line-height: 1.25; - overflow: visible; - text-overflow: clip; + overflow: hidden; + text-overflow: ellipsis; white-space: nowrap; } .family-copy strong { font-size: 11px; } @@ -407,10 +428,11 @@ body::before { transform: none; } .lineage-family-tree .tree-node .family-portrait { - right: 0; - bottom: -6px; - width: 58px; - height: 58px; + right: 4px; + top: 4px; + bottom: auto; + width: 48px; + height: 48px; } .lineage-family-tree .tree-generation-label { position: absolute; @@ -450,3 +472,11 @@ body::before { .tool[data-tip] { position: relative; } + +.lineage-family-tree .tree-node .family-copy { + max-width: calc(100% - 46px); +} +.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%; +} diff --git a/index.html b/index.html index 6ef0b14..d5ecc3d 100644 --- a/index.html +++ b/index.html @@ -7,11 +7,11 @@ - - - - - + + + + +