Deploy Aether Garden application
Browse files- .github/workflows/ci.yml +2 -1
- .modalignore +1 -0
- README_HF_SPACE.md +11 -4
- ai/generation.py +1 -1
- app.py +93 -2
- ui/styles.css +282 -0
.github/workflows/ci.yml
CHANGED
|
@@ -2,8 +2,9 @@ name: CI
|
|
| 2 |
|
| 3 |
on:
|
| 4 |
push:
|
| 5 |
-
branches: [main, master]
|
| 6 |
pull_request:
|
|
|
|
| 7 |
|
| 8 |
jobs:
|
| 9 |
test:
|
|
|
|
| 2 |
|
| 3 |
on:
|
| 4 |
push:
|
| 5 |
+
branches: [main, master, variant/minicpm]
|
| 6 |
pull_request:
|
| 7 |
+
branches: [main, master, variant/minicpm]
|
| 8 |
|
| 9 |
jobs:
|
| 10 |
test:
|
.modalignore
CHANGED
|
@@ -8,4 +8,5 @@ data/
|
|
| 8 |
*.db
|
| 9 |
.gradio/
|
| 10 |
traces/
|
|
|
|
| 11 |
assets/verify/
|
|
|
|
| 8 |
*.db
|
| 9 |
.gradio/
|
| 10 |
traces/
|
| 11 |
+
node_modules/
|
| 12 |
assets/verify/
|
README_HF_SPACE.md
CHANGED
|
@@ -10,16 +10,23 @@ pinned: true
|
|
| 10 |
license: mit
|
| 11 |
tags:
|
| 12 |
- gradio
|
| 13 |
-
- minicpm
|
| 14 |
- agents
|
| 15 |
- simulation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
- modal
|
|
|
|
|
|
|
| 17 |
---
|
| 18 |
|
| 19 |
# Aether Garden
|
| 20 |
|
| 21 |
-
The
|
| 22 |
|
| 23 |
-
|
| 24 |
|
| 25 |
-
|
|
|
|
| 10 |
license: mit
|
| 11 |
tags:
|
| 12 |
- gradio
|
|
|
|
| 13 |
- agents
|
| 14 |
- simulation
|
| 15 |
+
- three.js
|
| 16 |
+
- persistent-world
|
| 17 |
+
- hackathon
|
| 18 |
+
- thousand-token-wood
|
| 19 |
+
- best-agent
|
| 20 |
+
- off-brand
|
| 21 |
- modal
|
| 22 |
+
- minicpm
|
| 23 |
+
- tiny-model
|
| 24 |
---
|
| 25 |
|
| 26 |
# Aether Garden
|
| 27 |
|
| 28 |
+
**The Living Tome** — a persistent AI world where every visitor writes a new page.
|
| 29 |
|
| 30 |
+
Open the leather cover, turn through six spreads (Realm, Explore, Book of Ages, Souls, Bonds, Summon), and watch a world that remembers. MiniCPM 3-4B on Modal powers entity generation; an hourly simulation tick runs whether anyone is watching.
|
| 31 |
|
| 32 |
+
**Try it:** summon something strange, explore the diorama, read the Book of Ages.
|
ai/generation.py
CHANGED
|
@@ -50,7 +50,7 @@ LOCATION_ALIASES = {
|
|
| 50 |
"Hollow Mountain": "The Hollow Mountain",
|
| 51 |
}
|
| 52 |
|
| 53 |
-
MODEL_ID = os.environ.get("MODEL_ID", "
|
| 54 |
|
| 55 |
|
| 56 |
class EntityProfile(BaseModel):
|
|
|
|
| 50 |
"Hollow Mountain": "The Hollow Mountain",
|
| 51 |
}
|
| 52 |
|
| 53 |
+
MODEL_ID = os.environ.get("MODEL_ID", "openbmb/MiniCPM3-4B")
|
| 54 |
|
| 55 |
|
| 56 |
class EntityProfile(BaseModel):
|
app.py
CHANGED
|
@@ -1277,6 +1277,8 @@ def build_app() -> gr.Blocks:
|
|
| 1277 |
window._aetherInitBound = true;
|
| 1278 |
|
| 1279 |
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
|
|
|
|
|
| 1280 |
|
| 1281 |
const sections = [
|
| 1282 |
{ key: 'realm', label: 'The Realm', kind: 'tab', panel: 0 },
|
|
@@ -1301,23 +1303,109 @@ def build_app() -> gr.Blocks:
|
|
| 1301 |
};
|
| 1302 |
|
| 1303 |
const setActivePanel = (panelIndex) => {
|
|
|
|
| 1304 |
const panels = Array.from(document.querySelectorAll('.realm-tabs [role="tabpanel"]'));
|
| 1305 |
panels.forEach((panel, i) => {
|
| 1306 |
const active = i === panelIndex;
|
| 1307 |
panel.style.setProperty('display', active ? 'flex' : 'none', 'important');
|
| 1308 |
panel.style.setProperty('flex-direction', 'column', 'important');
|
| 1309 |
-
|
| 1310 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1311 |
panel.style.setProperty('overflow', 'hidden', 'important');
|
| 1312 |
panel.setAttribute('aria-hidden', active ? 'false' : 'true');
|
| 1313 |
});
|
| 1314 |
wirePageExpand();
|
|
|
|
| 1315 |
const pad = document.getElementById('aether-walk-pad');
|
| 1316 |
if (pad && panelIndex !== 1) {
|
| 1317 |
pad.classList.remove('visible', 'explore-only');
|
| 1318 |
}
|
| 1319 |
};
|
| 1320 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1321 |
const ensureAmbientMelody = () => {
|
| 1322 |
if (window._aetherAmbientStarted) {
|
| 1323 |
window._aetherAmbientCtx?.resume?.();
|
|
@@ -1535,6 +1623,8 @@ def build_app() -> gr.Blocks:
|
|
| 1535 |
applyTurnFx(direction);
|
| 1536 |
|
| 1537 |
setActivePanel(spread.panel);
|
|
|
|
|
|
|
| 1538 |
|
| 1539 |
currentSpread = clamped;
|
| 1540 |
window._aetherCurrentSpread = spread.key;
|
|
@@ -1887,6 +1977,7 @@ def build_app() -> gr.Blocks:
|
|
| 1887 |
|
| 1888 |
wireOpening();
|
| 1889 |
wireTomeNav();
|
|
|
|
| 1890 |
wirePageExpand();
|
| 1891 |
|
| 1892 |
const gateOnLoad = document.getElementById('realm-opening');
|
|
|
|
| 1277 |
window._aetherInitBound = true;
|
| 1278 |
|
| 1279 |
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
| 1280 |
+
const MOBILE_QUERY = window.matchMedia('(max-width: 920px)');
|
| 1281 |
+
const isMobileSpread = () => MOBILE_QUERY.matches;
|
| 1282 |
|
| 1283 |
const sections = [
|
| 1284 |
{ key: 'realm', label: 'The Realm', kind: 'tab', panel: 0 },
|
|
|
|
| 1303 |
};
|
| 1304 |
|
| 1305 |
const setActivePanel = (panelIndex) => {
|
| 1306 |
+
const mobile = isMobileSpread();
|
| 1307 |
const panels = Array.from(document.querySelectorAll('.realm-tabs [role="tabpanel"]'));
|
| 1308 |
panels.forEach((panel, i) => {
|
| 1309 |
const active = i === panelIndex;
|
| 1310 |
panel.style.setProperty('display', active ? 'flex' : 'none', 'important');
|
| 1311 |
panel.style.setProperty('flex-direction', 'column', 'important');
|
| 1312 |
+
if (mobile) {
|
| 1313 |
+
panel.style.setProperty('height', active ? 'auto' : '0', 'important');
|
| 1314 |
+
panel.style.setProperty('max-height', active ? 'none' : '0', 'important');
|
| 1315 |
+
panel.style.setProperty('flex', active ? '1 1 auto' : '0 0 0', 'important');
|
| 1316 |
+
panel.style.setProperty('min-height', active ? '0' : '0', 'important');
|
| 1317 |
+
} else {
|
| 1318 |
+
panel.style.setProperty('height', active ? '565px' : '0', 'important');
|
| 1319 |
+
panel.style.setProperty('max-height', active ? '565px' : '0', 'important');
|
| 1320 |
+
panel.style.setProperty('flex', '', 'important');
|
| 1321 |
+
}
|
| 1322 |
panel.style.setProperty('overflow', 'hidden', 'important');
|
| 1323 |
panel.setAttribute('aria-hidden', active ? 'false' : 'true');
|
| 1324 |
});
|
| 1325 |
wirePageExpand();
|
| 1326 |
+
wireMobileSpreads();
|
| 1327 |
const pad = document.getElementById('aether-walk-pad');
|
| 1328 |
if (pad && panelIndex !== 1) {
|
| 1329 |
pad.classList.remove('visible', 'explore-only');
|
| 1330 |
}
|
| 1331 |
};
|
| 1332 |
|
| 1333 |
+
const resetActiveSpreadLeaf = () => {
|
| 1334 |
+
const panels = document.querySelectorAll('.realm-tabs [role="tabpanel"]');
|
| 1335 |
+
const activePanel = panels[currentSpread];
|
| 1336 |
+
if (!activePanel) return;
|
| 1337 |
+
const row = activePanel.querySelector('.tome-spread-row');
|
| 1338 |
+
if (!row) return;
|
| 1339 |
+
row.classList.remove('tome-leaf-right');
|
| 1340 |
+
row.classList.add('tome-leaf-left');
|
| 1341 |
+
};
|
| 1342 |
+
|
| 1343 |
+
const wireMobileSpreads = () => {
|
| 1344 |
+
const mobile = isMobileSpread();
|
| 1345 |
+
document.body.classList.toggle('tome-mobile', mobile);
|
| 1346 |
+
|
| 1347 |
+
document.querySelectorAll('.tome-spread-shell').forEach((shell) => {
|
| 1348 |
+
const row = shell.querySelector('.tome-spread-row');
|
| 1349 |
+
if (!row) return;
|
| 1350 |
+
|
| 1351 |
+
if (!mobile) {
|
| 1352 |
+
row.classList.remove('tome-leaf-left', 'tome-leaf-right');
|
| 1353 |
+
shell.querySelector('.tome-leaf-bar')?.remove();
|
| 1354 |
+
return;
|
| 1355 |
+
}
|
| 1356 |
+
|
| 1357 |
+
if (!row.classList.contains('tome-leaf-left') && !row.classList.contains('tome-leaf-right')) {
|
| 1358 |
+
row.classList.add('tome-leaf-left');
|
| 1359 |
+
}
|
| 1360 |
+
|
| 1361 |
+
let bar = shell.querySelector('.tome-leaf-bar');
|
| 1362 |
+
if (!bar) {
|
| 1363 |
+
bar = document.createElement('div');
|
| 1364 |
+
bar.className = 'tome-leaf-bar';
|
| 1365 |
+
bar.innerHTML = `
|
| 1366 |
+
<button type="button" class="tome-leaf-btn" data-leaf="left" aria-label="Show left leaf">‹ Leaf</button>
|
| 1367 |
+
<span class="tome-leaf-dots" aria-hidden="true"><i></i><i></i></span>
|
| 1368 |
+
<button type="button" class="tome-leaf-btn" data-leaf="right" aria-label="Show right leaf">Leaf ›</button>
|
| 1369 |
+
`;
|
| 1370 |
+
shell.appendChild(bar);
|
| 1371 |
+
|
| 1372 |
+
const syncLeafBar = () => {
|
| 1373 |
+
const onLeft = row.classList.contains('tome-leaf-left');
|
| 1374 |
+
bar.querySelectorAll('.tome-leaf-btn').forEach((btn) => {
|
| 1375 |
+
const active = btn.dataset.leaf === (onLeft ? 'left' : 'right');
|
| 1376 |
+
btn.classList.toggle('is-active', active);
|
| 1377 |
+
});
|
| 1378 |
+
bar.querySelectorAll('.tome-leaf-dots i').forEach((dot, idx) => {
|
| 1379 |
+
dot.classList.toggle('active', onLeft ? idx === 0 : idx === 1);
|
| 1380 |
+
});
|
| 1381 |
+
};
|
| 1382 |
+
|
| 1383 |
+
bar.querySelectorAll('.tome-leaf-btn').forEach((btn) => {
|
| 1384 |
+
btn.addEventListener('click', () => {
|
| 1385 |
+
const leaf = btn.dataset.leaf;
|
| 1386 |
+
row.classList.remove('tome-leaf-left', 'tome-leaf-right');
|
| 1387 |
+
row.classList.add(leaf === 'right' ? 'tome-leaf-right' : 'tome-leaf-left');
|
| 1388 |
+
syncLeafBar();
|
| 1389 |
+
});
|
| 1390 |
+
});
|
| 1391 |
+
bar._syncLeafBar = syncLeafBar;
|
| 1392 |
+
}
|
| 1393 |
+
|
| 1394 |
+
bar._syncLeafBar?.();
|
| 1395 |
+
});
|
| 1396 |
+
};
|
| 1397 |
+
|
| 1398 |
+
if (!window._aetherMobileBound) {
|
| 1399 |
+
window._aetherMobileBound = true;
|
| 1400 |
+
MOBILE_QUERY.addEventListener('change', () => {
|
| 1401 |
+
wireMobileSpreads();
|
| 1402 |
+
setActivePanel(currentSpread >= 0 ? sections[currentSpread].panel : 0);
|
| 1403 |
+
});
|
| 1404 |
+
window.addEventListener('resize', () => {
|
| 1405 |
+
wireMobileSpreads();
|
| 1406 |
+
}, { passive: true });
|
| 1407 |
+
}
|
| 1408 |
+
|
| 1409 |
const ensureAmbientMelody = () => {
|
| 1410 |
if (window._aetherAmbientStarted) {
|
| 1411 |
window._aetherAmbientCtx?.resume?.();
|
|
|
|
| 1623 |
applyTurnFx(direction);
|
| 1624 |
|
| 1625 |
setActivePanel(spread.panel);
|
| 1626 |
+
resetActiveSpreadLeaf();
|
| 1627 |
+
wireMobileSpreads();
|
| 1628 |
|
| 1629 |
currentSpread = clamped;
|
| 1630 |
window._aetherCurrentSpread = spread.key;
|
|
|
|
| 1977 |
|
| 1978 |
wireOpening();
|
| 1979 |
wireTomeNav();
|
| 1980 |
+
wireMobileSpreads();
|
| 1981 |
wirePageExpand();
|
| 1982 |
|
| 1983 |
const gateOnLoad = document.getElementById('realm-opening');
|
ui/styles.css
CHANGED
|
@@ -6172,3 +6172,285 @@ body.aether-realm-entered #realm-opening-host {
|
|
| 6172 |
border-radius: 10px;
|
| 6173 |
overflow: hidden;
|
| 6174 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6172 |
border-radius: 10px;
|
| 6173 |
overflow: hidden;
|
| 6174 |
}
|
| 6175 |
+
|
| 6176 |
+
/* -------------------------------------------------------------------------- */
|
| 6177 |
+
/* Mobile & tablet — single-leaf spreads (one page at a time, full width) */
|
| 6178 |
+
/* -------------------------------------------------------------------------- */
|
| 6179 |
+
.tome-leaf-bar {
|
| 6180 |
+
display: none;
|
| 6181 |
+
}
|
| 6182 |
+
|
| 6183 |
+
@media (max-width: 920px) {
|
| 6184 |
+
body.tome-mobile,
|
| 6185 |
+
body.tome-mobile html {
|
| 6186 |
+
overflow: hidden;
|
| 6187 |
+
height: 100%;
|
| 6188 |
+
}
|
| 6189 |
+
|
| 6190 |
+
body.tome-mobile .gradio-container {
|
| 6191 |
+
height: 100dvh !important;
|
| 6192 |
+
max-height: 100dvh !important;
|
| 6193 |
+
min-height: 100dvh !important;
|
| 6194 |
+
max-width: 100vw !important;
|
| 6195 |
+
width: 100% !important;
|
| 6196 |
+
padding: 0.2rem 0.35rem 0.25rem !important;
|
| 6197 |
+
box-sizing: border-box !important;
|
| 6198 |
+
overflow: hidden !important;
|
| 6199 |
+
}
|
| 6200 |
+
|
| 6201 |
+
body.tome-mobile #presence-bar {
|
| 6202 |
+
font-size: 0.68rem;
|
| 6203 |
+
padding: 0.25rem 0.5rem;
|
| 6204 |
+
margin-bottom: 0.2rem !important;
|
| 6205 |
+
}
|
| 6206 |
+
|
| 6207 |
+
body.tome-mobile .realm-tabs {
|
| 6208 |
+
height: auto !important;
|
| 6209 |
+
max-height: none !important;
|
| 6210 |
+
flex: 1 1 auto !important;
|
| 6211 |
+
min-height: 0 !important;
|
| 6212 |
+
overflow: hidden !important;
|
| 6213 |
+
}
|
| 6214 |
+
|
| 6215 |
+
body.tome-mobile .realm-tabs [role="tabpanel"] {
|
| 6216 |
+
padding: 0.35rem 0.45rem 0.25rem !important;
|
| 6217 |
+
overflow: hidden !important;
|
| 6218 |
+
clip-path: none !important;
|
| 6219 |
+
border-radius: 6px !important;
|
| 6220 |
+
}
|
| 6221 |
+
|
| 6222 |
+
body.tome-mobile .realm-tabs [role="tabpanel"]::before,
|
| 6223 |
+
body.tome-mobile .realm-tabs [role="tabpanel"]::after {
|
| 6224 |
+
display: none !important;
|
| 6225 |
+
}
|
| 6226 |
+
|
| 6227 |
+
body.tome-mobile .tome-spread-shell {
|
| 6228 |
+
height: 100%;
|
| 6229 |
+
min-height: 0;
|
| 6230 |
+
overflow: hidden;
|
| 6231 |
+
}
|
| 6232 |
+
|
| 6233 |
+
body.tome-mobile .tome-spread-row {
|
| 6234 |
+
flex: 1 1 auto !important;
|
| 6235 |
+
min-height: 0 !important;
|
| 6236 |
+
max-height: 100% !important;
|
| 6237 |
+
align-items: stretch !important;
|
| 6238 |
+
overflow: hidden !important;
|
| 6239 |
+
}
|
| 6240 |
+
|
| 6241 |
+
body.tome-mobile .tome-spread-row > .column,
|
| 6242 |
+
body.tome-mobile .tome-spread-row > .gr-column {
|
| 6243 |
+
min-height: 0 !important;
|
| 6244 |
+
max-height: 100% !important;
|
| 6245 |
+
}
|
| 6246 |
+
|
| 6247 |
+
/* Hide inactive leaf — show one full-width page only */
|
| 6248 |
+
body.tome-mobile .tome-spread-row.tome-leaf-left .tome-page-right,
|
| 6249 |
+
body.tome-mobile .tome-spread-row.tome-leaf-right .tome-page-left {
|
| 6250 |
+
display: none !important;
|
| 6251 |
+
flex: 0 0 0 !important;
|
| 6252 |
+
width: 0 !important;
|
| 6253 |
+
max-width: 0 !important;
|
| 6254 |
+
padding: 0 !important;
|
| 6255 |
+
margin: 0 !important;
|
| 6256 |
+
overflow: hidden !important;
|
| 6257 |
+
visibility: hidden !important;
|
| 6258 |
+
pointer-events: none !important;
|
| 6259 |
+
}
|
| 6260 |
+
|
| 6261 |
+
body.tome-mobile .tome-spread-row.tome-leaf-left .tome-page-left,
|
| 6262 |
+
body.tome-mobile .tome-spread-row.tome-leaf-right .tome-page-right {
|
| 6263 |
+
flex: 1 1 100% !important;
|
| 6264 |
+
width: 100% !important;
|
| 6265 |
+
max-width: 100% !important;
|
| 6266 |
+
min-height: 0 !important;
|
| 6267 |
+
overflow-x: hidden !important;
|
| 6268 |
+
overflow-y: auto !important;
|
| 6269 |
+
-webkit-overflow-scrolling: touch;
|
| 6270 |
+
padding: 0.55rem 0.75rem 0.45rem !important;
|
| 6271 |
+
}
|
| 6272 |
+
|
| 6273 |
+
body.tome-mobile .tome-spread-row > .column.tome-page-left::after,
|
| 6274 |
+
body.tome-mobile .tome-spread-row > .column.tome-page-right::before {
|
| 6275 |
+
display: none !important;
|
| 6276 |
+
}
|
| 6277 |
+
|
| 6278 |
+
body.tome-mobile .tome-spread-row > .column.tome-page-left.tome-printed-page,
|
| 6279 |
+
body.tome-mobile .tome-spread-row > .column.tome-page-right.tome-printed-page {
|
| 6280 |
+
padding: 0.55rem 0.75rem 0.45rem !important;
|
| 6281 |
+
}
|
| 6282 |
+
|
| 6283 |
+
/* Leaf toggle bar */
|
| 6284 |
+
body.tome-mobile .tome-leaf-bar {
|
| 6285 |
+
display: flex;
|
| 6286 |
+
align-items: center;
|
| 6287 |
+
justify-content: center;
|
| 6288 |
+
gap: 0.65rem;
|
| 6289 |
+
flex: 0 0 auto;
|
| 6290 |
+
padding: 0.3rem 0.5rem 0.15rem;
|
| 6291 |
+
border-top: 1px solid rgba(138, 106, 58, 0.2);
|
| 6292 |
+
margin-top: 0.15rem;
|
| 6293 |
+
}
|
| 6294 |
+
|
| 6295 |
+
body.tome-mobile .tome-leaf-btn {
|
| 6296 |
+
border: 1px solid rgba(138, 106, 58, 0.45) !important;
|
| 6297 |
+
background: rgba(255, 249, 232, 0.85) !important;
|
| 6298 |
+
color: #5c3e1e !important;
|
| 6299 |
+
font-family: 'Cinzel', serif !important;
|
| 6300 |
+
font-size: 0.62rem !important;
|
| 6301 |
+
letter-spacing: 0.08em;
|
| 6302 |
+
text-transform: uppercase;
|
| 6303 |
+
padding: 0.35rem 0.65rem !important;
|
| 6304 |
+
border-radius: 999px !important;
|
| 6305 |
+
min-height: 2rem;
|
| 6306 |
+
box-shadow: none !important;
|
| 6307 |
+
}
|
| 6308 |
+
|
| 6309 |
+
body.tome-mobile .tome-leaf-btn.is-active {
|
| 6310 |
+
background: rgba(201, 161, 59, 0.28) !important;
|
| 6311 |
+
border-color: rgba(138, 106, 58, 0.65) !important;
|
| 6312 |
+
}
|
| 6313 |
+
|
| 6314 |
+
body.tome-mobile .tome-leaf-dots {
|
| 6315 |
+
display: flex;
|
| 6316 |
+
gap: 0.35rem;
|
| 6317 |
+
align-items: center;
|
| 6318 |
+
}
|
| 6319 |
+
|
| 6320 |
+
body.tome-mobile .tome-leaf-dots i {
|
| 6321 |
+
display: block;
|
| 6322 |
+
width: 6px;
|
| 6323 |
+
height: 6px;
|
| 6324 |
+
border-radius: 50%;
|
| 6325 |
+
background: rgba(138, 106, 58, 0.28);
|
| 6326 |
+
transition: background 0.2s ease, transform 0.2s ease;
|
| 6327 |
+
}
|
| 6328 |
+
|
| 6329 |
+
body.tome-mobile .tome-leaf-dots i.active {
|
| 6330 |
+
background: #8a6a3a;
|
| 6331 |
+
transform: scale(1.15);
|
| 6332 |
+
}
|
| 6333 |
+
|
| 6334 |
+
/* Restore content hidden on desktop two-page layout */
|
| 6335 |
+
body.tome-mobile .tome-page-right.tome-page-centered > .block:has(.realm-pulse),
|
| 6336 |
+
body.tome-mobile .tome-page-right.tome-page-centered > .block:has(.activity-feed) {
|
| 6337 |
+
display: block !important;
|
| 6338 |
+
height: auto !important;
|
| 6339 |
+
min-height: 0 !important;
|
| 6340 |
+
max-height: none !important;
|
| 6341 |
+
margin: 0 0 0.35rem !important;
|
| 6342 |
+
padding: 0 !important;
|
| 6343 |
+
overflow: visible !important;
|
| 6344 |
+
}
|
| 6345 |
+
|
| 6346 |
+
body.tome-mobile .tome-page-right .pulse-card:nth-child(n+3) {
|
| 6347 |
+
display: flex !important;
|
| 6348 |
+
}
|
| 6349 |
+
|
| 6350 |
+
/* Map & diorama — use available height on small screens */
|
| 6351 |
+
body.tome-mobile .tome-page-left .realm-map,
|
| 6352 |
+
body.tome-mobile .tome-page-left #world-map {
|
| 6353 |
+
min-height: min(48dvh, 380px) !important;
|
| 6354 |
+
max-height: min(56dvh, 440px) !important;
|
| 6355 |
+
}
|
| 6356 |
+
|
| 6357 |
+
body.tome-mobile .tome-explore-stage .diorama-wrap,
|
| 6358 |
+
body.tome-mobile .tome-explore-stage .diorama-stage {
|
| 6359 |
+
min-height: min(52dvh, 460px) !important;
|
| 6360 |
+
}
|
| 6361 |
+
|
| 6362 |
+
body.tome-mobile .tome-explore-stage .diorama-frame,
|
| 6363 |
+
body.tome-mobile .diorama-frame {
|
| 6364 |
+
height: min(52dvh, 480px) !important;
|
| 6365 |
+
min-height: 260px !important;
|
| 6366 |
+
}
|
| 6367 |
+
|
| 6368 |
+
body.tome-mobile .rel-graph-stage {
|
| 6369 |
+
height: min(50dvh, 420px) !important;
|
| 6370 |
+
min-height: 280px !important;
|
| 6371 |
+
}
|
| 6372 |
+
|
| 6373 |
+
body.tome-mobile .book-entries {
|
| 6374 |
+
column-count: 1 !important;
|
| 6375 |
+
}
|
| 6376 |
+
|
| 6377 |
+
body.tome-mobile .entity-grid {
|
| 6378 |
+
grid-template-columns: 1fr !important;
|
| 6379 |
+
}
|
| 6380 |
+
|
| 6381 |
+
body.tome-mobile .souls-filter-row {
|
| 6382 |
+
flex-direction: column !important;
|
| 6383 |
+
}
|
| 6384 |
+
|
| 6385 |
+
/* Opening gate */
|
| 6386 |
+
body.tome-mobile .realm-opening {
|
| 6387 |
+
padding: 0.75rem !important;
|
| 6388 |
+
}
|
| 6389 |
+
|
| 6390 |
+
body.tome-mobile .realm-cover-card,
|
| 6391 |
+
body.tome-mobile .realm-prologue-card,
|
| 6392 |
+
body.tome-mobile .realm-toc-card {
|
| 6393 |
+
width: min(96vw, 100%) !important;
|
| 6394 |
+
max-width: 100% !important;
|
| 6395 |
+
}
|
| 6396 |
+
|
| 6397 |
+
body.tome-mobile .realm-cover-title span {
|
| 6398 |
+
font-size: clamp(1.4rem, 8vw, 2rem) !important;
|
| 6399 |
+
}
|
| 6400 |
+
|
| 6401 |
+
/* Tome navigation chrome */
|
| 6402 |
+
body.tome-mobile #tome-nav .tome-corner {
|
| 6403 |
+
width: 42px;
|
| 6404 |
+
height: 42px;
|
| 6405 |
+
bottom: calc(4.25rem + env(safe-area-inset-bottom, 0px));
|
| 6406 |
+
font-size: 1rem;
|
| 6407 |
+
}
|
| 6408 |
+
|
| 6409 |
+
body.tome-mobile #tome-nav .tome-corner-left {
|
| 6410 |
+
left: 0.5rem;
|
| 6411 |
+
}
|
| 6412 |
+
|
| 6413 |
+
body.tome-mobile #tome-nav .tome-corner-right {
|
| 6414 |
+
right: 0.5rem;
|
| 6415 |
+
}
|
| 6416 |
+
|
| 6417 |
+
body.tome-mobile .tome-ribbon {
|
| 6418 |
+
right: 0.5rem;
|
| 6419 |
+
top: 0;
|
| 6420 |
+
font-size: 0.62rem;
|
| 6421 |
+
max-width: 46vw;
|
| 6422 |
+
padding: 0.3rem 0.5rem;
|
| 6423 |
+
}
|
| 6424 |
+
|
| 6425 |
+
body.tome-mobile .tome-page-indicator {
|
| 6426 |
+
font-size: 0.62rem;
|
| 6427 |
+
bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px));
|
| 6428 |
+
}
|
| 6429 |
+
|
| 6430 |
+
body.tome-mobile #aether-walk-pad {
|
| 6431 |
+
left: 0.5rem;
|
| 6432 |
+
bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
|
| 6433 |
+
transform: scale(0.92);
|
| 6434 |
+
transform-origin: left bottom;
|
| 6435 |
+
}
|
| 6436 |
+
|
| 6437 |
+
body.tome-mobile .tome-floating-toc {
|
| 6438 |
+
max-height: min(70dvh, 520px);
|
| 6439 |
+
overflow-y: auto;
|
| 6440 |
+
}
|
| 6441 |
+
}
|
| 6442 |
+
|
| 6443 |
+
@media (max-width: 480px) {
|
| 6444 |
+
body.tome-mobile .tome-printed-kicker {
|
| 6445 |
+
font-size: 0.62rem !important;
|
| 6446 |
+
}
|
| 6447 |
+
|
| 6448 |
+
body.tome-mobile .tome-printed-hint {
|
| 6449 |
+
font-size: 0.72rem !important;
|
| 6450 |
+
}
|
| 6451 |
+
|
| 6452 |
+
body.tome-mobile .tome-leaf-btn {
|
| 6453 |
+
font-size: 0.58rem !important;
|
| 6454 |
+
padding: 0.3rem 0.5rem !important;
|
| 6455 |
+
}
|
| 6456 |
+
}
|