Deploy Aether Garden application
Browse files- app.py +118 -15
- ui/map.py +17 -1
- ui/styles.css +120 -10
app.py
CHANGED
|
@@ -689,11 +689,25 @@ def build_app() -> gr.Blocks:
|
|
| 689 |
'<div class="tome-ornament top" aria-hidden="true">✦ ─── ❧ ─── ✦</div>'
|
| 690 |
'<p class="tome-printed-kicker">The Living Realm</p>'
|
| 691 |
'<p class="tome-printed-hint">Tap a place on the map — a vision shall rise.</p>'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 692 |
)
|
| 693 |
world_map = gr.HTML(
|
| 694 |
value=render_world_map(),
|
| 695 |
elem_id="world-map",
|
| 696 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 697 |
location_panel = gr.HTML(
|
| 698 |
value=render_location_panel(None),
|
| 699 |
elem_id="location-panel-host-wrap",
|
|
@@ -1749,34 +1763,122 @@ def build_app() -> gr.Blocks:
|
|
| 1749 |
}
|
| 1750 |
|
| 1751 |
const triggerGradioInput = (elemId, value) => {
|
| 1752 |
-
const
|
|
|
|
|
|
|
|
|
|
| 1753 |
if (!root) return false;
|
| 1754 |
-
const input = root.
|
| 1755 |
-
|
| 1756 |
-
|
|
|
|
| 1757 |
if (!input) return false;
|
| 1758 |
const proto = input.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
|
| 1759 |
const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
|
| 1760 |
-
|
| 1761 |
-
|
|
|
|
| 1762 |
input.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
| 1763 |
input.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
| 1764 |
return true;
|
| 1765 |
};
|
| 1766 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1767 |
const bind = () => {
|
| 1768 |
-
document.querySelectorAll('#world-map
|
| 1769 |
-
if (node.dataset.mapBound) return;
|
| 1770 |
-
node.dataset.mapBound = '1';
|
| 1771 |
node.style.cursor = 'pointer';
|
| 1772 |
-
node.addEventListener('click', (e) => {
|
| 1773 |
-
e.preventDefault();
|
| 1774 |
-
e.stopPropagation();
|
| 1775 |
-
const id = node.getAttribute('data-location-id');
|
| 1776 |
-
if (id) triggerGradioInput('map_location_pick', id);
|
| 1777 |
-
});
|
| 1778 |
});
|
| 1779 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1780 |
const fireHiddenInput = (id, value) => {
|
| 1781 |
const elemId = (id || '').replace(/^#/, '');
|
| 1782 |
triggerGradioInput(elemId, value);
|
|
@@ -1797,6 +1899,7 @@ def build_app() -> gr.Blocks:
|
|
| 1797 |
const closeLocationModal = () => {
|
| 1798 |
document.querySelectorAll('.location-modal-overlay').forEach((m) => m.classList.remove('is-open'));
|
| 1799 |
};
|
|
|
|
| 1800 |
|
| 1801 |
const bindSpreadClicks = () => {
|
| 1802 |
document.querySelectorAll('.place-ribbon-item').forEach((btn) => {
|
|
|
|
| 689 |
'<div class="tome-ornament top" aria-hidden="true">✦ ─── ❧ ─── ✦</div>'
|
| 690 |
'<p class="tome-printed-kicker">The Living Realm</p>'
|
| 691 |
'<p class="tome-printed-hint">Tap a place on the map — a vision shall rise.</p>'
|
| 692 |
+
'<div class="tome-map-chrome" aria-hidden="true">'
|
| 693 |
+
'<span class="tome-map-chrome-glyph">⟡</span>'
|
| 694 |
+
'<span class="tome-map-chrome-line"></span>'
|
| 695 |
+
'<span class="tome-map-chrome-label">Map of the Canopy</span>'
|
| 696 |
+
'<span class="tome-map-chrome-line"></span>'
|
| 697 |
+
'<span class="tome-map-chrome-glyph">⟡</span>'
|
| 698 |
+
'</div>'
|
| 699 |
)
|
| 700 |
world_map = gr.HTML(
|
| 701 |
value=render_world_map(),
|
| 702 |
elem_id="world-map",
|
| 703 |
)
|
| 704 |
+
gr.HTML(
|
| 705 |
+
'<div class="tome-map-divider" aria-hidden="true">'
|
| 706 |
+
'<span class="tome-map-vine left"></span>'
|
| 707 |
+
'<span class="tome-map-divider-text">✧ Sacred Places ✧</span>'
|
| 708 |
+
'<span class="tome-map-vine right"></span>'
|
| 709 |
+
'</div>'
|
| 710 |
+
)
|
| 711 |
location_panel = gr.HTML(
|
| 712 |
value=render_location_panel(None),
|
| 713 |
elem_id="location-panel-host-wrap",
|
|
|
|
| 1763 |
}
|
| 1764 |
|
| 1765 |
const triggerGradioInput = (elemId, value) => {
|
| 1766 |
+
const clean = String(elemId || '').replace(/^#/, '');
|
| 1767 |
+
const root = document.getElementById(clean)
|
| 1768 |
+
|| document.querySelector('#' + clean)
|
| 1769 |
+
|| document.querySelector('[id="' + clean + '"]');
|
| 1770 |
if (!root) return false;
|
| 1771 |
+
const input = (root.tagName === 'TEXTAREA' || root.tagName === 'INPUT') ? root
|
| 1772 |
+
: (root.querySelector('textarea:not([disabled])')
|
| 1773 |
+
|| root.querySelector('input[type="text"]')
|
| 1774 |
+
|| root.querySelector('input:not([type="hidden"])'));
|
| 1775 |
if (!input) return false;
|
| 1776 |
const proto = input.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
|
| 1777 |
const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
|
| 1778 |
+
const next = String(value);
|
| 1779 |
+
if (setter) setter.call(input, next);
|
| 1780 |
+
else input.value = next;
|
| 1781 |
input.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
| 1782 |
input.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
| 1783 |
return true;
|
| 1784 |
};
|
| 1785 |
|
| 1786 |
+
const ensureLocationModal = () => {
|
| 1787 |
+
let modal = document.getElementById('aether-location-modal');
|
| 1788 |
+
if (modal) return modal;
|
| 1789 |
+
modal = document.createElement('div');
|
| 1790 |
+
modal.id = 'aether-location-modal';
|
| 1791 |
+
modal.className = 'location-modal-overlay';
|
| 1792 |
+
modal.innerHTML = `
|
| 1793 |
+
<div class="location-modal-card">
|
| 1794 |
+
<div class="location-modal-close" role="button" tabindex="0" aria-label="Close">✕</div>
|
| 1795 |
+
<div class="location-panel location-panel-animate open">
|
| 1796 |
+
<div class="location-panel-banner">
|
| 1797 |
+
<div class="location-panel-scrim"></div>
|
| 1798 |
+
<h3 class="location-panel-name"></h3>
|
| 1799 |
+
</div>
|
| 1800 |
+
<div class="location-panel-content">
|
| 1801 |
+
<p class="location-panel-desc"></p>
|
| 1802 |
+
<p class="location-panel-special"></p>
|
| 1803 |
+
<p class="location-soul-count"></p>
|
| 1804 |
+
</div>
|
| 1805 |
+
</div>
|
| 1806 |
+
</div>`;
|
| 1807 |
+
document.body.appendChild(modal);
|
| 1808 |
+
const closeBtn = modal.querySelector('.location-modal-close');
|
| 1809 |
+
if (closeBtn) {
|
| 1810 |
+
closeBtn.addEventListener('click', () => modal.classList.remove('is-open'));
|
| 1811 |
+
closeBtn.addEventListener('keydown', (e) => {
|
| 1812 |
+
if (e.key === 'Enter' || e.key === ' ') {
|
| 1813 |
+
e.preventDefault();
|
| 1814 |
+
modal.classList.remove('is-open');
|
| 1815 |
+
}
|
| 1816 |
+
});
|
| 1817 |
+
}
|
| 1818 |
+
modal.addEventListener('click', (e) => {
|
| 1819 |
+
if (e.target === modal) modal.classList.remove('is-open');
|
| 1820 |
+
});
|
| 1821 |
+
return modal;
|
| 1822 |
+
};
|
| 1823 |
+
|
| 1824 |
+
const openLocationFromNode = (node) => {
|
| 1825 |
+
if (!node) return;
|
| 1826 |
+
const id = node.getAttribute('data-location-id');
|
| 1827 |
+
if (!id) return;
|
| 1828 |
+
const modal = ensureLocationModal();
|
| 1829 |
+
const name = node.getAttribute('data-name') || 'Unknown place';
|
| 1830 |
+
const desc = node.getAttribute('data-desc') || '';
|
| 1831 |
+
const special = node.getAttribute('data-special') || '';
|
| 1832 |
+
const souls = node.getAttribute('data-souls') || '0';
|
| 1833 |
+
const img = node.getAttribute('data-img') || '';
|
| 1834 |
+
const nameEl = modal.querySelector('.location-panel-name');
|
| 1835 |
+
const descEl = modal.querySelector('.location-panel-desc');
|
| 1836 |
+
const specialEl = modal.querySelector('.location-panel-special');
|
| 1837 |
+
const soulsEl = modal.querySelector('.location-soul-count');
|
| 1838 |
+
const banner = modal.querySelector('.location-panel-banner');
|
| 1839 |
+
if (nameEl) nameEl.textContent = name;
|
| 1840 |
+
if (descEl) descEl.textContent = desc;
|
| 1841 |
+
if (specialEl) specialEl.textContent = special ? ('✦ ' + special) : '';
|
| 1842 |
+
if (soulsEl) soulsEl.textContent = souls + ' souls currently here';
|
| 1843 |
+
if (banner) {
|
| 1844 |
+
banner.style.backgroundImage = img ? ("url('" + img.replace(/'/g, "%27") + "')") : '';
|
| 1845 |
+
banner.style.backgroundSize = 'cover';
|
| 1846 |
+
banner.style.backgroundPosition = 'center';
|
| 1847 |
+
}
|
| 1848 |
+
modal.classList.add('is-open');
|
| 1849 |
+
document.querySelectorAll('.location-node').forEach((n) => {
|
| 1850 |
+
n.classList.toggle('location-selected', n.getAttribute('data-location-id') === id);
|
| 1851 |
+
});
|
| 1852 |
+
triggerGradioInput('map_location_pick', id);
|
| 1853 |
+
};
|
| 1854 |
+
|
| 1855 |
const bind = () => {
|
| 1856 |
+
document.querySelectorAll('#world-map .location-node, [id="world-map"] .location-node').forEach((node) => {
|
|
|
|
|
|
|
| 1857 |
node.style.cursor = 'pointer';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1858 |
});
|
| 1859 |
};
|
| 1860 |
+
|
| 1861 |
+
if (!window._aetherMapDelegationBound) {
|
| 1862 |
+
window._aetherMapDelegationBound = true;
|
| 1863 |
+
document.addEventListener('click', (e) => {
|
| 1864 |
+
const node = e.target.closest('.location-node[data-location-id]');
|
| 1865 |
+
if (!node) return;
|
| 1866 |
+
const inMap = node.closest('#world-map') || node.closest('[id="world-map"]');
|
| 1867 |
+
if (!inMap) return;
|
| 1868 |
+
e.preventDefault();
|
| 1869 |
+
e.stopPropagation();
|
| 1870 |
+
openLocationFromNode(node);
|
| 1871 |
+
}, true);
|
| 1872 |
+
document.addEventListener('keydown', (e) => {
|
| 1873 |
+
if (e.key !== 'Enter' && e.key !== ' ') return;
|
| 1874 |
+
const node = e.target.closest('.location-node[data-location-id]');
|
| 1875 |
+
if (!node) return;
|
| 1876 |
+
const inMap = node.closest('#world-map') || node.closest('[id="world-map"]');
|
| 1877 |
+
if (!inMap) return;
|
| 1878 |
+
e.preventDefault();
|
| 1879 |
+
openLocationFromNode(node);
|
| 1880 |
+
});
|
| 1881 |
+
}
|
| 1882 |
const fireHiddenInput = (id, value) => {
|
| 1883 |
const elemId = (id || '').replace(/^#/, '');
|
| 1884 |
triggerGradioInput(elemId, value);
|
|
|
|
| 1899 |
const closeLocationModal = () => {
|
| 1900 |
document.querySelectorAll('.location-modal-overlay').forEach((m) => m.classList.remove('is-open'));
|
| 1901 |
};
|
| 1902 |
+
window._aetherCloseLocationModal = closeLocationModal;
|
| 1903 |
|
| 1904 |
const bindSpreadClicks = () => {
|
| 1905 |
document.querySelectorAll('.place-ribbon-item').forEach((btn) => {
|
ui/map.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
from __future__ import annotations
|
| 4 |
|
|
|
|
| 5 |
import math
|
| 6 |
import random
|
| 7 |
|
|
@@ -126,9 +127,24 @@ def render_world_map(selected_location_id: int | None = None) -> str:
|
|
| 126 |
count = loc["entity_count"]
|
| 127 |
icon_path = LOCATION_ICONS.get(loc["slug"], "M0,-6 A6,6 0 1,1 0,6")
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
svg_parts.append(
|
| 130 |
f'<g class="location-node{pulse_class}{selected_class}" '
|
| 131 |
-
f'data-location-id="{loc["id"]}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
)
|
| 133 |
|
| 134 |
filter_id = "pulse-glow" if is_affected else "glow"
|
|
|
|
| 2 |
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
+
import html
|
| 6 |
import math
|
| 7 |
import random
|
| 8 |
|
|
|
|
| 127 |
count = loc["entity_count"]
|
| 128 |
icon_path = LOCATION_ICONS.get(loc["slug"], "M0,-6 A6,6 0 1,1 0,6")
|
| 129 |
|
| 130 |
+
img = assets.location_image_url(loc.get("slug")) or ""
|
| 131 |
+
special = loc.get("special_property", "") or ""
|
| 132 |
+
desc = loc.get("short_description", "") or ""
|
| 133 |
+
|
| 134 |
svg_parts.append(
|
| 135 |
f'<g class="location-node{pulse_class}{selected_class}" '
|
| 136 |
+
f'data-location-id="{loc["id"]}" '
|
| 137 |
+
f'data-name="{html.escape(loc["name"], quote=True)}" '
|
| 138 |
+
f'data-desc="{html.escape(desc, quote=True)}" '
|
| 139 |
+
f'data-special="{html.escape(special, quote=True)}" '
|
| 140 |
+
f'data-img="{html.escape(img, quote=True)}" '
|
| 141 |
+
f'data-souls="{count}" '
|
| 142 |
+
f'role="button" tabindex="0" '
|
| 143 |
+
f'transform="translate({x},{y})">'
|
| 144 |
+
)
|
| 145 |
+
|
| 146 |
+
svg_parts.append(
|
| 147 |
+
'<circle r="50" fill="transparent" class="location-hit" pointer-events="all"/>'
|
| 148 |
)
|
| 149 |
|
| 150 |
filter_id = "pulse-glow" if is_affected else "glow"
|
ui/styles.css
CHANGED
|
@@ -1966,6 +1966,12 @@ body,
|
|
| 1966 |
|
| 1967 |
.location-node {
|
| 1968 |
filter: drop-shadow(0 7px 12px rgba(0,0,0,0.36));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1969 |
}
|
| 1970 |
|
| 1971 |
.location-selected .location-circle {
|
|
@@ -3866,11 +3872,11 @@ body,
|
|
| 3866 |
font-family: 'Cinzel', serif !important;
|
| 3867 |
}
|
| 3868 |
|
| 3869 |
-
.tome-printed-page #world-map,
|
| 3870 |
-
.tome-printed-page .realm-map {
|
| 3871 |
-
flex:
|
| 3872 |
-
min-height:
|
| 3873 |
-
max-height:
|
| 3874 |
width: 100% !important;
|
| 3875 |
border: 1px solid rgba(98, 62, 28, 0.28) !important;
|
| 3876 |
border-radius: 2px !important;
|
|
@@ -4774,8 +4780,16 @@ body.aether-realm-entered #realm-opening-host {
|
|
| 4774 |
0 18px 38px rgba(76, 50, 22, 0.26) !important;
|
| 4775 |
}
|
| 4776 |
|
| 4777 |
-
/* Page I
|
| 4778 |
-
.tome-page-centered {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4779 |
display: flex !important;
|
| 4780 |
flex-direction: column !important;
|
| 4781 |
justify-content: space-between !important;
|
|
@@ -4783,6 +4797,77 @@ body.aether-realm-entered #realm-opening-host {
|
|
| 4783 |
min-height: 0 !important;
|
| 4784 |
}
|
| 4785 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4786 |
.tome-page-centered .realm-stats-strip,
|
| 4787 |
.tome-page-centered .current-event,
|
| 4788 |
.tome-page-centered .realm-pulse,
|
|
@@ -4799,9 +4884,34 @@ body.aether-realm-entered #realm-opening-host {
|
|
| 4799 |
|
| 4800 |
.tome-page-left .realm-map,
|
| 4801 |
.tome-page-left #world-map {
|
| 4802 |
-
flex:
|
| 4803 |
-
|
| 4804 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4805 |
}
|
| 4806 |
|
| 4807 |
/* Explore left — padding */
|
|
|
|
| 1966 |
|
| 1967 |
.location-node {
|
| 1968 |
filter: drop-shadow(0 7px 12px rgba(0,0,0,0.36));
|
| 1969 |
+
cursor: pointer;
|
| 1970 |
+
pointer-events: all;
|
| 1971 |
+
}
|
| 1972 |
+
|
| 1973 |
+
.location-node .location-hit {
|
| 1974 |
+
pointer-events: all;
|
| 1975 |
}
|
| 1976 |
|
| 1977 |
.location-selected .location-circle {
|
|
|
|
| 3872 |
font-family: 'Cinzel', serif !important;
|
| 3873 |
}
|
| 3874 |
|
| 3875 |
+
.tome-page-left.tome-printed-page #world-map,
|
| 3876 |
+
.tome-page-left.tome-printed-page .realm-map {
|
| 3877 |
+
flex: 0 0 auto !important;
|
| 3878 |
+
min-height: 200px !important;
|
| 3879 |
+
max-height: min(300px, 36vh) !important;
|
| 3880 |
width: 100% !important;
|
| 3881 |
border: 1px solid rgba(98, 62, 28, 0.28) !important;
|
| 3882 |
border-radius: 2px !important;
|
|
|
|
| 4780 |
0 18px 38px rgba(76, 50, 22, 0.26) !important;
|
| 4781 |
}
|
| 4782 |
|
| 4783 |
+
/* Page I — left: tight map stack; right: distribute vertically */
|
| 4784 |
+
.tome-page-left.tome-page-centered {
|
| 4785 |
+
display: flex !important;
|
| 4786 |
+
flex-direction: column !important;
|
| 4787 |
+
justify-content: flex-start !important;
|
| 4788 |
+
gap: 0.28rem !important;
|
| 4789 |
+
min-height: 0 !important;
|
| 4790 |
+
}
|
| 4791 |
+
|
| 4792 |
+
.tome-page-right.tome-page-centered {
|
| 4793 |
display: flex !important;
|
| 4794 |
flex-direction: column !important;
|
| 4795 |
justify-content: space-between !important;
|
|
|
|
| 4797 |
min-height: 0 !important;
|
| 4798 |
}
|
| 4799 |
|
| 4800 |
+
.tome-page-left .tome-ornament.bottom {
|
| 4801 |
+
margin-top: auto !important;
|
| 4802 |
+
padding-top: 0.2rem !important;
|
| 4803 |
+
}
|
| 4804 |
+
|
| 4805 |
+
.tome-map-chrome {
|
| 4806 |
+
display: flex;
|
| 4807 |
+
align-items: center;
|
| 4808 |
+
justify-content: center;
|
| 4809 |
+
gap: 0.45rem;
|
| 4810 |
+
margin: 0.1rem 0 0.15rem;
|
| 4811 |
+
flex-shrink: 0;
|
| 4812 |
+
}
|
| 4813 |
+
|
| 4814 |
+
.tome-map-chrome-line {
|
| 4815 |
+
flex: 1;
|
| 4816 |
+
max-width: 72px;
|
| 4817 |
+
height: 1px;
|
| 4818 |
+
background: linear-gradient(90deg, transparent, rgba(138, 106, 58, 0.35), transparent);
|
| 4819 |
+
}
|
| 4820 |
+
|
| 4821 |
+
.tome-map-chrome-label {
|
| 4822 |
+
font-family: 'Cinzel', serif;
|
| 4823 |
+
font-size: 0.58rem;
|
| 4824 |
+
letter-spacing: 0.2em;
|
| 4825 |
+
text-transform: uppercase;
|
| 4826 |
+
color: rgba(122, 90, 40, 0.55);
|
| 4827 |
+
white-space: nowrap;
|
| 4828 |
+
}
|
| 4829 |
+
|
| 4830 |
+
.tome-map-chrome-glyph {
|
| 4831 |
+
color: rgba(138, 106, 58, 0.45);
|
| 4832 |
+
font-size: 0.7rem;
|
| 4833 |
+
}
|
| 4834 |
+
|
| 4835 |
+
.tome-map-divider {
|
| 4836 |
+
display: flex;
|
| 4837 |
+
align-items: center;
|
| 4838 |
+
justify-content: center;
|
| 4839 |
+
gap: 0.5rem;
|
| 4840 |
+
margin: 0.12rem 0 0.08rem;
|
| 4841 |
+
flex-shrink: 0;
|
| 4842 |
+
}
|
| 4843 |
+
|
| 4844 |
+
.tome-map-divider-text {
|
| 4845 |
+
font-family: 'Cinzel', serif;
|
| 4846 |
+
font-size: 0.58rem;
|
| 4847 |
+
letter-spacing: 0.16em;
|
| 4848 |
+
color: rgba(122, 90, 40, 0.5);
|
| 4849 |
+
white-space: nowrap;
|
| 4850 |
+
}
|
| 4851 |
+
|
| 4852 |
+
.tome-map-vine {
|
| 4853 |
+
flex: 1;
|
| 4854 |
+
height: 10px;
|
| 4855 |
+
max-width: 88px;
|
| 4856 |
+
background-repeat: no-repeat;
|
| 4857 |
+
background-size: contain;
|
| 4858 |
+
opacity: 0.55;
|
| 4859 |
+
}
|
| 4860 |
+
|
| 4861 |
+
.tome-map-vine.left {
|
| 4862 |
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 10'%3E%3Cpath d='M0 5 Q20 0 40 5 T80 5' fill='none' stroke='%238a6a3a' stroke-width='0.8'/%3E%3Ccircle cx='40' cy='5' r='1.2' fill='%23c9a13b'/%3E%3C/svg%3E");
|
| 4863 |
+
background-position: right center;
|
| 4864 |
+
}
|
| 4865 |
+
|
| 4866 |
+
.tome-map-vine.right {
|
| 4867 |
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 10'%3E%3Cpath d='M0 5 Q20 10 40 5 T80 5' fill='none' stroke='%238a6a3a' stroke-width='0.8'/%3E%3Ccircle cx='40' cy='5' r='1.2' fill='%23c9a13b'/%3E%3C/svg%3E");
|
| 4868 |
+
background-position: left center;
|
| 4869 |
+
}
|
| 4870 |
+
|
| 4871 |
.tome-page-centered .realm-stats-strip,
|
| 4872 |
.tome-page-centered .current-event,
|
| 4873 |
.tome-page-centered .realm-pulse,
|
|
|
|
| 4884 |
|
| 4885 |
.tome-page-left .realm-map,
|
| 4886 |
.tome-page-left #world-map {
|
| 4887 |
+
flex: 0 0 auto !important;
|
| 4888 |
+
width: 100% !important;
|
| 4889 |
+
min-height: 200px !important;
|
| 4890 |
+
max-height: min(300px, 36vh) !important;
|
| 4891 |
+
margin: 0 !important;
|
| 4892 |
+
}
|
| 4893 |
+
|
| 4894 |
+
.tome-page-left #world-map .html-container,
|
| 4895 |
+
.tome-page-left #world-map .prose {
|
| 4896 |
+
min-height: 0 !important;
|
| 4897 |
+
}
|
| 4898 |
+
|
| 4899 |
+
.tome-page-left .location-panel-host {
|
| 4900 |
+
flex-shrink: 0 !important;
|
| 4901 |
+
margin: 0 !important;
|
| 4902 |
+
}
|
| 4903 |
+
|
| 4904 |
+
.tome-page-left .location-panel-host .map-hint {
|
| 4905 |
+
padding: 0.35rem 0.55rem !important;
|
| 4906 |
+
margin: 0 !important;
|
| 4907 |
+
font-size: 0.78rem !important;
|
| 4908 |
+
border: 1px solid rgba(138, 106, 58, 0.22);
|
| 4909 |
+
border-radius: 4px;
|
| 4910 |
+
background: rgba(255, 249, 232, 0.5);
|
| 4911 |
+
}
|
| 4912 |
+
|
| 4913 |
+
#aether-location-modal {
|
| 4914 |
+
z-index: 90000 !important;
|
| 4915 |
}
|
| 4916 |
|
| 4917 |
/* Explore left — padding */
|