diff --git a/CLAUDE.md b/CLAUDE.md index 54007e1..b3cce7e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -110,7 +110,7 @@ Drop → RESERVED → confirm/reject. `_gate_context()` builds slot state; `_exp `epic:room` view at `/gameboard/room//`. `gatekeeper` redirects there when `table_status` is set. Error redirects in `select_role`/`select_sig` use `epic:room` if `table_status` is set, else `epic:gatekeeper`. ## SCSS Import Order -`core.scss`: `rootvars → applets → base → button-pad → dashboard → gameboard → palette-picker → room → card-deck → natus → tray → billboard → tooltips → game-kit → wallet-tokens` +`core.scss`: `rootvars → applets → base → button-pad → dashboard → gameboard → palette-picker → room → card-deck → sky → tray → billboard → tooltips → game-kit → wallet-tokens` ## Critical Gotchas diff --git a/src/apps/dashboard/tests/integrated/test_views.py b/src/apps/dashboard/tests/integrated/test_views.py index 7cf4f37..3352fda 100644 --- a/src/apps/dashboard/tests/integrated/test_views.py +++ b/src/apps/dashboard/tests/integrated/test_views.py @@ -619,13 +619,13 @@ class SkySaveViewTest(TestCase): self.assertAlmostEqual(self.user.sky_chart_data["houses"]["asc"], 123.4) -class SkyNatusDataViewTest(TestCase): +class SkyDataViewTest(TestCase): def setUp(self): self.user = User.objects.create(email="disco@test.io") self.client.force_login(self.user) def test_returns_stored_chart_with_asc_preserved(self): - """sky_natus_data returns sky_chart_data — asc must match what was saved.""" + """sky_data returns sky_chart_data — asc must match what was saved.""" stored = { "planets": {}, "houses": {"cusps": [float(i * 30) for i in range(12)], "asc": 236.1, "mc": 159.1}, diff --git a/src/apps/dashboard/urls.py b/src/apps/dashboard/urls.py index 94717b0..9417a99 100644 --- a/src/apps/dashboard/urls.py +++ b/src/apps/dashboard/urls.py @@ -17,6 +17,6 @@ urlpatterns = [ path('sky/', views.sky_view, name='sky'), path('sky/preview', views.sky_preview, name='sky_preview'), path('sky/save', views.sky_save, name='sky_save'), - path('sky/data', views.sky_natus_data, name='sky_natus_data'), + path('sky/data', views.sky_data, name='sky_data'), path('set-pronouns', views.set_pronouns, name='set_pronouns'), ] diff --git a/src/apps/dashboard/views.py b/src/apps/dashboard/views.py index cd1273f..4fd5062 100644 --- a/src/apps/dashboard/views.py +++ b/src/apps/dashboard/views.py @@ -287,7 +287,7 @@ def save_payment_method(request): # ── My Sky (personal natal chart) ──────────────────────────────────────────── -def _sky_natus_preview(request): +def _sky_preview_data(request): """Shared preview logic — proxies to PySwiss, no DB writes.""" date_str = request.GET.get('date') time_str = request.GET.get('time', '12:00') @@ -380,7 +380,7 @@ def sky_view(request): @login_required(login_url="/") def sky_preview(request): - return _sky_natus_preview(request) + return _sky_preview_data(request) @login_required(login_url="/") @@ -440,7 +440,7 @@ def sky_save(request): @login_required(login_url="/") -def sky_natus_data(request): +def sky_data(request): user = request.user if not user.sky_chart_data: return HttpResponse(status=404) diff --git a/src/apps/epic/models.py b/src/apps/epic/models.py index 5537f69..169db4d 100644 --- a/src/apps/epic/models.py +++ b/src/apps/epic/models.py @@ -653,7 +653,7 @@ class Character(models.Model): on_delete=models.SET_NULL, related_name='character_significators', ) - # ── natus input (what the gamer entered) ───────────────────────────── + # ── sky input (what the gamer entered) ───────────────────────────── birth_dt = models.DateTimeField(null=True, blank=True) # UTC birth_lat = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) birth_lon = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) @@ -662,7 +662,7 @@ class Character(models.Model): max_length=1, choices=HOUSE_SYSTEM_CHOICES, default=PORPHYRY, ) - # ── computed natus snapshot (full PySwiss response) ─────────────────── + # ── computed sky snapshot (full PySwiss response) ─────────────────── chart_data = models.JSONField(null=True, blank=True) # ── celtic cross spread (added at PICK SEA) ─────────────────────────── diff --git a/src/apps/epic/tests/integrated/test_views.py b/src/apps/epic/tests/integrated/test_views.py index 4a82121..9f6212c 100644 --- a/src/apps/epic/tests/integrated/test_views.py +++ b/src/apps/epic/tests/integrated/test_views.py @@ -1933,16 +1933,16 @@ class SelectSigViewTest(TestCase): self.assertEqual(response.status_code, 400) -# ── natus_preview (epic) ────────────────────────────────────────────────────── +# ── sky_preview (epic) ────────────────────────────────────────────────────── -class NatusPreviewViewTest(TestCase): +class SkyPreviewViewTest(TestCase): def setUp(self): - self.user = User.objects.create(email="pc@natus.io") + self.user = User.objects.create(email="pc@sky.io") self.client.force_login(self.user) self.room, _ = _make_sig_room(self.user) self.room.table_status = Room.SKY_SELECT self.room.save() - self.url = reverse("epic:natus_preview", kwargs={"room_id": self.room.id}) + self.url = reverse("epic:sky_preview", kwargs={"room_id": self.room.id}) def test_missing_params_returns_400(self): response = self.client.get(self.url, {"date": "1990-06-15"}) @@ -2025,16 +2025,16 @@ class TarotDealViewTest(TestCase): ) -# ── natus_save (epic) ───────────────────────────────────────────────────────── +# ── sky_save (epic) ───────────────────────────────────────────────────────── -class NatusSaveViewTest(TestCase): +class SkySaveViewTest(TestCase): def setUp(self): - self.user = User.objects.create(email="pc@natussave.io") + self.user = User.objects.create(email="pc@skysave.io") self.client.force_login(self.user) self.room, _ = _make_sig_room(self.user) self.room.table_status = Room.SKY_SELECT self.room.save() - self.url = reverse("epic:natus_save", kwargs={"room_id": self.room.id}) + self.url = reverse("epic:sky_save", kwargs={"room_id": self.room.id}) def _post(self, payload): import json as _json @@ -2134,7 +2134,7 @@ class NatusSaveViewTest(TestCase): def test_confirm_with_dict_shaped_elements_extracts_count(self): """Some chart payloads enrich each element to {count, contributors}; - natus_save should read .count rather than treating the dict as a value.""" + sky_save should read .count rather than treating the dict as a value.""" from apps.drama.models import GameEvent chart = { "elements": { @@ -2156,7 +2156,7 @@ class NatusSaveViewTest(TestCase): self.assertEqual(event.data.get("top_capacitors"), ["Ardor"]) def test_confirm_copies_seat_significator_to_character(self): - """natus_save with action=confirm copies seat.significator onto Character.""" + """sky_save with action=confirm copies seat.significator onto Character.""" earthman, _ = DeckVariant.objects.get_or_create( slug="earthman", defaults={"name": "Earthman Deck", "card_count": 108} ) diff --git a/src/apps/epic/urls.py b/src/apps/epic/urls.py index e7e6d42..394e092 100644 --- a/src/apps/epic/urls.py +++ b/src/apps/epic/urls.py @@ -25,8 +25,8 @@ urlpatterns = [ path('room//abandon', views.abandon_room, name='abandon_room'), path('room//tarot/', views.tarot_deck, name='tarot_deck'), path('room//tarot/deal', views.tarot_deal, name='tarot_deal'), - path('room//natus/preview', views.natus_preview, name='natus_preview'), - path('room//natus/save', views.natus_save, name='natus_save'), + path('room//sky/preview', views.sky_preview, name='sky_preview'), + path('room//sky/save', views.sky_save, name='sky_save'), path('room//sea/partial', views.sea_partial, name='sea_partial'), path('room//sea/deck', views.sea_deck, name='sea_deck'), ] diff --git a/src/apps/epic/utils.py b/src/apps/epic/utils.py index 74d4761..f2255d4 100644 --- a/src/apps/epic/utils.py +++ b/src/apps/epic/utils.py @@ -25,7 +25,7 @@ def stack_reversal_probability(user=None, room=None): -# Element key → in-game capacitor name (mirrors ELEMENT_INFO in natus-wheel.js). +# Element key → in-game capacitor name (mirrors ELEMENT_INFO in sky-wheel.js). # Used by the SKY_SAVED provenance event to render prose like # "yields them a unique Ardor capacity." ELEMENT_CAPACITOR_NAMES = { diff --git a/src/apps/epic/views.py b/src/apps/epic/views.py index 3e94cb3..13e474e 100644 --- a/src/apps/epic/views.py +++ b/src/apps/epic/views.py @@ -975,10 +975,10 @@ def tarot_deal(request, room_id): }) -# ── Natus (natal chart) ─────────────────────────────────────────────────────── +# ── Sky (natal chart) ─────────────────────────────────────────────────────── @login_required -def natus_preview(request, room_id): +def sky_preview(request, room_id): """Proxy GET to PySwiss /api/chart/ and augment with distinction counts. Query params: @@ -1064,7 +1064,7 @@ def natus_preview(request, room_id): @login_required -def natus_save(request, room_id): +def sky_save(request, room_id): """Create or update the draft Character for the requesting gamer's seat. POST body (JSON): diff --git a/src/apps/gameboard/static/apps/gameboard/natus-wheel.js b/src/apps/gameboard/static/apps/gameboard/sky-wheel.js similarity index 98% rename from src/apps/gameboard/static/apps/gameboard/natus-wheel.js rename to src/apps/gameboard/static/apps/gameboard/sky-wheel.js index be6cd81..4a9bbc8 100644 --- a/src/apps/gameboard/static/apps/gameboard/natus-wheel.js +++ b/src/apps/gameboard/static/apps/gameboard/sky-wheel.js @@ -1,12 +1,12 @@ /** - * natus-wheel.js — Self-contained D3 natal-chart module. + * sky-wheel.js — Self-contained D3 natal-chart module. * * Public API: - * NatusWheel.draw(svgEl, data) — first render - * NatusWheel.redraw(data) — live update (same SVG) - * NatusWheel.clear() — empty the SVG + * SkyWheel.draw(svgEl, data) — first render + * SkyWheel.redraw(data) — live update (same SVG) + * SkyWheel.clear() — empty the SVG * - * `data` shape — matches the /epic/natus/preview/ proxy response: + * `data` shape — matches the /epic/sky/preview/ proxy response: * { * planets: { Sun: { sign, degree, speed, retrograde }, … }, * houses: { cusps: [f×12], asc: f, mc: f }, @@ -28,7 +28,7 @@ * already defined in the page; falls back to neutral colours if absent. */ -const NatusWheel = (() => { +const SkyWheel = (() => { 'use strict'; // ── Constants ────────────────────────────────────────────────────────────── @@ -223,8 +223,8 @@ const NatusWheel = (() => { if (_staticBase) return _staticBase; const scripts = document.querySelectorAll('script[src]'); for (const s of scripts) { - if (s.src.includes('natus-wheel')) { - _staticBase = s.src.replace(/natus-wheel\.js.*$/, ''); + if (s.src.includes('sky-wheel')) { + _staticBase = s.src.replace(/sky-wheel\.js.*$/, ''); return _staticBase; } } @@ -957,7 +957,7 @@ const NatusWheel = (() => { * Called on every draw() so a fresh innerHTML replaces any stale state. */ function _injectTooltipControls() { - _tooltipEl = document.getElementById('id_natus_tooltip'); + _tooltipEl = document.getElementById('id_sky_tooltip'); if (!_tooltipEl) return; _tooltipEl.innerHTML = `` + @@ -1384,8 +1384,8 @@ const NatusWheel = (() => { (() => { const scripts = document.querySelectorAll('script[src]'); for (const s of scripts) { - if (s.src.includes('natus-wheel')) { - return s.src.replace(/natus-wheel\.js.*$/, 'icons/zodiac-signs/'); + if (s.src.includes('sky-wheel')) { + return s.src.replace(/sky-wheel\.js.*$/, 'icons/zodiac-signs/'); } } return '/static/apps/gameboard/icons/zodiac-signs/'; @@ -1394,7 +1394,7 @@ const NatusWheel = (() => { await Promise.all(SIGNS.map(async sign => { const url = base + sign.name.toLowerCase() + '.svg'; const resp = await window.fetch(url); - if (!resp.ok) { console.warn(`NatusWheel: failed to load ${url}`); return; } + if (!resp.ok) { console.warn(`SkyWheel: failed to load ${url}`); return; } const text = await resp.text(); const doc = new DOMParser().parseFromString(text, 'image/svg+xml'); const path = doc.querySelector('path'); diff --git a/src/functional_tests/test_applet_my_notes.py b/src/functional_tests/test_applet_my_notes.py index 9d99af6..7fc31a0 100644 --- a/src/functional_tests/test_applet_my_notes.py +++ b/src/functional_tests/test_applet_my_notes.py @@ -119,7 +119,7 @@ class StargazerNoteFromDashboardTest(FunctionalTest): self.browser.get(self.live_server_url) confirm_btn = self.wait_for( - lambda: self.browser.find_element(By.ID, "id_natus_confirm") + lambda: self.browser.find_element(By.ID, "id_sky_confirm") ) self.assertIsNotNone(confirm_btn.get_attribute("disabled")) self.assertFalse(self.browser.find_elements(By.CSS_SELECTOR, ".note-banner")) @@ -136,7 +136,7 @@ class StargazerNoteFromDashboardTest(FunctionalTest): self.browser.execute_script(_mock_preview_js(_CHART_FIXTURE)) _fill_valid_sky_form(self.browser) - confirm_btn = self.browser.find_element(By.ID, "id_natus_confirm") + confirm_btn = self.browser.find_element(By.ID, "id_sky_confirm") self.wait_for(lambda: self.assertIsNone(confirm_btn.get_attribute("disabled"))) confirm_btn.click() @@ -338,7 +338,7 @@ class StargazerNoteFromSkyPageTest(FunctionalTest): self.browser.get(self.sky_url) confirm_btn = self.wait_for( - lambda: self.browser.find_element(By.ID, "id_natus_confirm") + lambda: self.browser.find_element(By.ID, "id_sky_confirm") ) self.assertIsNotNone(confirm_btn.get_attribute("disabled")) self.assertFalse(self.browser.find_elements(By.CSS_SELECTOR, ".note-banner")) @@ -351,11 +351,11 @@ class StargazerNoteFromSkyPageTest(FunctionalTest): self.create_pre_authenticated_session("stargazer@test.io") self.browser.get(self.sky_url) - self.wait_for(lambda: self.browser.find_element(By.ID, "id_natus_confirm")) + self.wait_for(lambda: self.browser.find_element(By.ID, "id_sky_confirm")) self.browser.execute_script(_mock_preview_js(_CHART_FIXTURE)) _fill_valid_sky_form(self.browser) - confirm_btn = self.browser.find_element(By.ID, "id_natus_confirm") + confirm_btn = self.browser.find_element(By.ID, "id_sky_confirm") self.wait_for(lambda: self.assertIsNone(confirm_btn.get_attribute("disabled"))) confirm_btn.click() @@ -386,11 +386,11 @@ class StargazerNoteFromSkyPageTest(FunctionalTest): self.create_pre_authenticated_session("stargazer@test.io") self.browser.get(self.sky_url) - self.wait_for(lambda: self.browser.find_element(By.ID, "id_natus_confirm")) + self.wait_for(lambda: self.browser.find_element(By.ID, "id_sky_confirm")) self.browser.execute_script(_mock_preview_js(_CHART_FIXTURE)) _fill_valid_sky_form(self.browser) - confirm_btn = self.browser.find_element(By.ID, "id_natus_confirm") + confirm_btn = self.browser.find_element(By.ID, "id_sky_confirm") self.wait_for(lambda: self.assertIsNone(confirm_btn.get_attribute("disabled"))) confirm_btn.click() diff --git a/src/functional_tests/test_applet_my_sky.py b/src/functional_tests/test_applet_my_sky.py index 2a8c475..f0e9eaa 100644 --- a/src/functional_tests/test_applet_my_sky.py +++ b/src/functional_tests/test_applet_my_sky.py @@ -1,7 +1,7 @@ """Functional tests for the My Sky dashboard feature. My Sky is a dashboard applet linking to /dashboard/sky/ — a full-page -natus (natal chart) interface where the user can save their personal sky +sky (natal chart) interface where the user can save their personal sky to their account (stored on the User model, independent of any game room). """ @@ -61,7 +61,7 @@ class MySkyAppletTest(FunctionalTest): def test_my_sky_applet_links_to_sky_page_with_form(self): """Applet is visible on dashboard; link leads to /dashboard/sky/ with - all natus form fields present.""" + all sky form fields present.""" self.create_pre_authenticated_session("stargazer@test.io") self.browser.get(self.live_server_url) @@ -80,14 +80,14 @@ class MySkyAppletTest(FunctionalTest): lambda: self.assertRegex(self.browser.current_url, r"/dashboard/sky/$") ) - # 4. All natus form fields are present + # 4. All sky form fields are present self.browser.find_element(By.ID, "id_nf_date") self.browser.find_element(By.ID, "id_nf_time") self.browser.find_element(By.ID, "id_nf_place") self.browser.find_element(By.ID, "id_nf_lat") self.browser.find_element(By.ID, "id_nf_lon") self.browser.find_element(By.ID, "id_nf_tz") - self.browser.find_element(By.ID, "id_natus_confirm") + self.browser.find_element(By.ID, "id_sky_confirm") class MySkyLocalStorageTest(FunctionalTest): @@ -171,7 +171,7 @@ class MySkyAppletWheelTest(FunctionalTest): def test_saved_sky_wheel_renders_with_element_tooltip_in_applet(self): """When the user has saved sky data, the natal wheel appears in the My Sky applet and clicking an element-ring slice shows the tooltip. - (Planet click tooltip is covered by NatusWheelSpec.js T3/T4/T5.)""" + (Planet click tooltip is covered by SkyWheelSpec.js T3/T4/T5.)""" self.create_pre_authenticated_session("stargazer@test.io") self.browser.get(self.live_server_url) @@ -192,14 +192,14 @@ class MySkyAppletWheelTest(FunctionalTest): slice_el, ) self.wait_for(lambda: self.assertEqual( - self.browser.find_element(By.ID, "id_natus_tooltip") + self.browser.find_element(By.ID, "id_sky_tooltip") .value_of_css_property("display"), "block", )) class MySkyAppletFormTest(FunctionalTest): - """My Sky applet shows natus entry form when no sky data is saved.""" + """My Sky applet shows sky entry form when no sky data is saved.""" def setUp(self): super().setUp() @@ -212,7 +212,7 @@ class MySkyAppletFormTest(FunctionalTest): # ── T4 ─────────────────────────────────────────────────────────────────── def test_applet_shows_entry_form_when_no_sky_saved(self): - """When no sky data is saved the My Sky applet shows all natus form + """When no sky data is saved the My Sky applet shows all sky form fields and a disabled SAVE SKY button; no wheel is drawn yet.""" self.create_pre_authenticated_session("stargazer@test.io") self.browser.get(self.live_server_url) @@ -227,7 +227,7 @@ class MySkyAppletFormTest(FunctionalTest): applet.find_element(By.ID, "id_nf_lat") applet.find_element(By.ID, "id_nf_lon") applet.find_element(By.ID, "id_nf_tz") - applet.find_element(By.ID, "id_natus_confirm") + applet.find_element(By.ID, "id_sky_confirm") self.assertFalse(applet.find_elements(By.CSS_SELECTOR, ".nw-root")) @@ -276,7 +276,7 @@ class MySkyAppletFormTest(FunctionalTest): """) # Wait for confirm button to be enabled (preview resolved) - confirm_btn = self.browser.find_element(By.ID, "id_natus_confirm") + confirm_btn = self.browser.find_element(By.ID, "id_sky_confirm") self.wait_for(lambda: self.assertIsNone( confirm_btn.get_attribute("disabled") )) @@ -331,4 +331,4 @@ class MySkyWheelConjunctionTest(FunctionalTest): )) # (T7 tick-extends-past-zodiac, T8 click-raises-to-front, and T9c/T9n/T9w - # cycle navigation are covered by NatusWheelSpec.js.) + # cycle navigation are covered by SkyWheelSpec.js.) diff --git a/src/functional_tests/test_room_sea_select.py b/src/functional_tests/test_room_sea_select.py index c612290..f3ef437 100644 --- a/src/functional_tests/test_room_sea_select.py +++ b/src/functional_tests/test_room_sea_select.py @@ -38,7 +38,7 @@ def _make_sky_confirmed_room(live_server_url, user, earthman): @tag("channels") class PickSeaAsyncTransitionTest(ChannelsFunctionalTest): - """After sky confirm, the natus overlay closes and the room reloads to the + """After sky confirm, the sky overlay closes and the room reloads to the table hex w. the PICK SEA btn visible — the gamer must opt into the sea overlay rather than be auto-launched into it.""" @@ -66,19 +66,19 @@ class PickSeaAsyncTransitionTest(ChannelsFunctionalTest): self.room_url = self.live_server_url + reverse( "epic:room", kwargs={"room_id": self.room.id} ) - self.natus_save_url = self.live_server_url + reverse( - "epic:natus_save", kwargs={"room_id": self.room.id} + self.sky_save_url = self.live_server_url + reverse( + "epic:sky_save", kwargs={"room_id": self.room.id} ) def _confirm_sky(self): - """POST to natus_save with action=confirm from browser JS (bypasses chart form).""" + """POST to sky_save with action=confirm from browser JS (bypasses chart form).""" # Wait for the room WS connection to be ready before triggering confirm self.wait_for(lambda: self.browser.execute_script( "return !!(window._roomSocket && window._roomSocket.readyState === 1);" )) self.browser.execute_script(f""" const csrf = (document.cookie.match(/csrftoken=([^;]+)/) || ['',''])[1]; - fetch('{self.natus_save_url}', {{ + fetch('{self.sky_save_url}', {{ method: 'POST', credentials: 'same-origin', headers: {{'Content-Type': 'application/json', 'X-CSRFToken': csrf}}, @@ -113,8 +113,8 @@ class PickSeaAsyncTransitionTest(ChannelsFunctionalTest): ) self.assertFalse(has_sea_open) - def test_natus_overlay_closed_after_sky_confirm(self): - """Natus overlay is gone (page reloaded) after sky confirm.""" + def test_sky_overlay_closed_after_sky_confirm(self): + """Sky overlay is gone (page reloaded) after sky confirm.""" self.create_pre_authenticated_session("founder@test.io") self.browser.get(self.room_url) self.wait_for(lambda: self.browser.find_element(By.ID, "id_pick_sky_btn")) @@ -122,8 +122,8 @@ class PickSeaAsyncTransitionTest(ChannelsFunctionalTest): self._confirm_sky() self.wait_for(lambda: self.browser.find_element(By.ID, "id_pick_sea_btn")) - natus = self.browser.find_elements(By.ID, "id_natus_overlay") - self.assertTrue(not natus or not natus[0].is_displayed()) + sky = self.browser.find_elements(By.ID, "id_sky_overlay") + self.assertTrue(not sky or not sky[0].is_displayed()) def test_clicking_pick_sea_btn_opens_sea_overlay(self): """The gamer's explicit click on PICK SEA is what opens the sea overlay.""" diff --git a/src/functional_tests/test_room_sky_select.py b/src/functional_tests/test_room_sky_select.py index f16a727..b2c1624 100644 --- a/src/functional_tests/test_room_sky_select.py +++ b/src/functional_tests/test_room_sky_select.py @@ -46,7 +46,7 @@ class PickSkyLocalStorageTest(FunctionalTest): ) self.browser.execute_script("arguments[0].click()", btn) self.wait_for( - lambda: self.browser.find_element(By.ID, "id_natus_overlay") + lambda: self.browser.find_element(By.ID, "id_sky_overlay") ) def _fill_form(self): @@ -89,7 +89,7 @@ class PickSkyLocalStorageTest(FunctionalTest): self._fill_form() # Close via NVM - self.browser.find_element(By.ID, "id_natus_cancel").click() + self.browser.find_element(By.ID, "id_sky_cancel").click() # Reopen self._open_overlay() diff --git a/src/functional_tests/test_room_tray.py b/src/functional_tests/test_room_tray.py index 74d8c7b..f272c60 100644 --- a/src/functional_tests/test_room_tray.py +++ b/src/functional_tests/test_room_tray.py @@ -27,7 +27,7 @@ from apps.lyric.models import User # - On page reload: tray always starts closed (JS in-memory only). # # Contents (populated in later sprints): Role card, Significator, Celtic Cross -# draw, natus wheel, committed dice/cards for this table. +# draw, sky wheel, committed dice/cards for this table. # # ───────────────────────────────────────────────────────────────────────────── diff --git a/src/static/tests/NatusWheelSpec.js b/src/static/tests/SkyWheelSpec.js similarity index 94% rename from src/static/tests/NatusWheelSpec.js rename to src/static/tests/SkyWheelSpec.js index 868702a..68dce18 100644 --- a/src/static/tests/NatusWheelSpec.js +++ b/src/static/tests/SkyWheelSpec.js @@ -1,15 +1,15 @@ -// ── NatusWheelSpec.js ───────────────────────────────────────────────────────── +// ── SkyWheelSpec.js ───────────────────────────────────────────────────────── // -// Unit specs for natus-wheel.js — planet/element click-to-lock tooltips. +// Unit specs for sky-wheel.js — planet/element click-to-lock tooltips. // // DOM contract assumed: -// — target for NatusWheel.draw() -//
— tooltip portal (position:fixed on page) +// — target for SkyWheel.draw() +//
— tooltip portal (position:fixed on page) // // Click-lock contract: // click on [data-planet] group → adds .nw-planet--active class // raises group to DOM front -// shows #id_natus_tooltip with +// shows #id_sky_tooltip with // planet name, in-sign degree, sign name, // ℞ if retrograde, and "n / total" index // click same planet again → removes .nw-planet--active; hides tooltip @@ -40,7 +40,7 @@ const CONJUNCTION_CHART = { house_system: "O", }; -describe("NatusWheel — planet click tooltips", () => { +describe("SkyWheel — planet click tooltips", () => { const SYNTHETIC_CHART = { planets: { @@ -67,7 +67,7 @@ describe("NatusWheel — planet click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -75,16 +75,16 @@ describe("NatusWheel — planet click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, SYNTHETIC_CHART); + SkyWheel.draw(svgEl, SYNTHETIC_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -145,13 +145,13 @@ describe("NatusWheel — planet click tooltips", () => { }); }); -describe("NatusWheel — tick lines, raise, and cycle navigation", () => { +describe("SkyWheel — tick lines, raise, and cycle navigation", () => { let svgEl2, tooltipEl; beforeEach(() => { svgEl2 = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl2.setAttribute("id", "id_natus_svg_conj"); + svgEl2.setAttribute("id", "id_sky_svg_conj"); svgEl2.setAttribute("width", "400"); svgEl2.setAttribute("height", "400"); svgEl2.style.width = "400px"; @@ -159,17 +159,17 @@ describe("NatusWheel — tick lines, raise, and cycle navigation", () => { document.body.appendChild(svgEl2); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; tooltipEl.style.position = "fixed"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl2, CONJUNCTION_CHART); + SkyWheel.draw(svgEl2, CONJUNCTION_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl2.remove(); tooltipEl.remove(); }); @@ -295,7 +295,7 @@ describe("NatusWheel — tick lines, raise, and cycle navigation", () => { // - DOFF clears lines; re-opening same planet finds DON active // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — DON/DOFF aspect line persistence", () => { +describe("SkyWheel — DON/DOFF aspect line persistence", () => { const ASPECT_CHART = { planets: { @@ -326,7 +326,7 @@ describe("NatusWheel — DON/DOFF aspect line persistence", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -334,16 +334,16 @@ describe("NatusWheel — DON/DOFF aspect line persistence", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, ASPECT_CHART); + SkyWheel.draw(svgEl, ASPECT_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -454,7 +454,7 @@ describe("NatusWheel — DON/DOFF aspect line persistence", () => { }); }); -xdescribe("NatusWheel — half-wheel tooltip positioning", () => { +xdescribe("SkyWheel — half-wheel tooltip positioning", () => { const HALF_CHART = { planets: { @@ -481,7 +481,7 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { beforeEach(() => { svgEl3 = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl3.setAttribute("id", "id_natus_svg_half"); + svgEl3.setAttribute("id", "id_sky_svg_half"); svgEl3.setAttribute("width", "400"); svgEl3.setAttribute("height", "400"); svgEl3.style.width = "400px"; @@ -489,7 +489,7 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { document.body.appendChild(svgEl3); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; tooltipEl.style.position = "fixed"; @@ -501,11 +501,11 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { { left: 0, top: 0, width: 400, height: 400, right: 400, bottom: 400 } ); - NatusWheel.draw(svgEl3, HALF_CHART); + SkyWheel.draw(svgEl3, HALF_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl3.remove(); tooltipEl.remove(); }); @@ -561,7 +561,7 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { // clicking a classic-element slice lists contributor planet names in the tooltip. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — element tooltip contributor display", () => { +describe("SkyWheel — element tooltip contributor display", () => { const ENRICHED_CHART = { planets: { @@ -608,7 +608,7 @@ describe("NatusWheel — element tooltip contributor display", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -616,16 +616,16 @@ describe("NatusWheel — element tooltip contributor display", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, ENRICHED_CHART); + SkyWheel.draw(svgEl, ENRICHED_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -682,7 +682,7 @@ describe("NatusWheel — element tooltip contributor display", () => { // Clicking the same sign again closes the tooltip. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — sign ring click tooltips", () => { +describe("SkyWheel — sign ring click tooltips", () => { const SIGN_CHART = { planets: { @@ -703,7 +703,7 @@ describe("NatusWheel — sign ring click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -711,16 +711,16 @@ describe("NatusWheel — sign ring click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, SIGN_CHART); + SkyWheel.draw(svgEl, SIGN_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -756,7 +756,7 @@ describe("NatusWheel — sign ring click tooltips", () => { // Clicking the same house again closes the tooltip. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — house ring click tooltips", () => { +describe("SkyWheel — house ring click tooltips", () => { const HOUSE_CHART = { planets: { @@ -777,7 +777,7 @@ describe("NatusWheel — house ring click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -785,16 +785,16 @@ describe("NatusWheel — house ring click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, HOUSE_CHART); + SkyWheel.draw(svgEl, HOUSE_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -835,7 +835,7 @@ describe("NatusWheel — house ring click tooltips", () => { // Planet tooltips include angle aspects in their own aspect lists. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — angle (ASC/MC) click tooltips", () => { +describe("SkyWheel — angle (ASC/MC) click tooltips", () => { // ASC=0°(Aries): Sun@8° → Conjunction orb 8° ✓; Mars@188° → Opposition orb 8° ✓ // MC=90°(Cancer): Moon@97° → Conjunction orb 7° ✓ @@ -863,7 +863,7 @@ describe("NatusWheel — angle (ASC/MC) click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -871,16 +871,16 @@ describe("NatusWheel — angle (ASC/MC) click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, ANGLE_CHART); + SkyWheel.draw(svgEl, ANGLE_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); diff --git a/src/static/tests/SpecRunner.html b/src/static/tests/SpecRunner.html index 5f38d99..93dcbf9 100644 --- a/src/static/tests/SpecRunner.html +++ b/src/static/tests/SpecRunner.html @@ -25,7 +25,7 @@ - + @@ -40,7 +40,7 @@ - + diff --git a/src/static_src/scss/_card-deck.scss b/src/static_src/scss/_card-deck.scss index d0a3b94..3ef4db2 100644 --- a/src/static_src/scss/_card-deck.scss +++ b/src/static_src/scss/_card-deck.scss @@ -926,7 +926,7 @@ html:has(.sig-backdrop) { } // ── PICK SEA overlay ───────────────────────────────────────────────────────── -// Mirrors .natus-* structure but with columns reversed: +// Mirrors .sky-* structure but with columns reversed: // left = transparent (Celtic Cross card positions) // right = rgba(--priUser) opaque (spread select) @@ -1414,7 +1414,7 @@ $_glow-gravity: 0 0 0.8rem 0.15rem rgba(var(--quaUser), 0.6); } -// NVM button — same positioning as .natus-modal-wrap > .btn-cancel +// NVM button — same positioning as .sky-modal-wrap > .btn-cancel .sea-modal-wrap > .btn-cancel { position: absolute; top: -1rem; diff --git a/src/static_src/scss/_natus.scss b/src/static_src/scss/_sky.scss similarity index 93% rename from src/static_src/scss/_natus.scss rename to src/static_src/scss/_sky.scss index 2836a54..298c969 100644 --- a/src/static_src/scss/_natus.scss +++ b/src/static_src/scss/_sky.scss @@ -1,13 +1,13 @@ -// ─── Natus (Pick Sky) overlay ──────────────────────────────────────────────── +// ─── Sky (Pick Sky) overlay ──────────────────────────────────────────────── // Gaussian backdrop + centred modal, matching the gate/sig overlay pattern. -// Open state: html.natus-open (added by JS on PICK SKY click). +// Open state: html.sky-open (added by JS on PICK SKY click). // // Layout: header / two-column body (form | wheel) / footer // Collapses to stacked single-column below 600 px. // ── Scroll-lock ─────────────────────────────────────────────────────────────── -html.natus-open { +html.sky-open { overflow: hidden; #id_aperture_fill { opacity: 1; } @@ -15,7 +15,7 @@ html.natus-open { // ── Backdrop ────────────────────────────────────────────────────────────────── -.natus-backdrop { +.sky-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.75); @@ -23,18 +23,18 @@ html.natus-open { z-index: 100; pointer-events: none; - // Hidden until html.natus-open + // Hidden until html.sky-open opacity: 0; transition: opacity 0.15s ease; } -html.natus-open .natus-backdrop { +html.sky-open .sky-backdrop { opacity: 1; } // ── Overlay shell (positions + scrolls the modal) ───────────────────────────── -.natus-overlay { +.sky-overlay { position: fixed; inset: 0; display: flex; @@ -45,7 +45,7 @@ html.natus-open .natus-backdrop { overscroll-behavior: contain; pointer-events: none; - // Hidden until html.natus-open + // Hidden until html.sky-open visibility: hidden; @media (orientation: landscape) { @@ -55,7 +55,7 @@ html.natus-open .natus-backdrop { } } -html.natus-open .natus-overlay { +html.sky-open .sky-overlay { visibility: visible; pointer-events: none; // modal itself is pointer-events: auto } @@ -64,7 +64,7 @@ html.natus-open .natus-overlay { // Thin wrapper: position:relative so the NVM circle can sit on the corner // without being clipped by the modal's overflow:hidden. -.natus-modal-wrap { +.sky-modal-wrap { position: relative; pointer-events: none; // overlay handles pointer-events; children re-enable width: 92vw; @@ -76,16 +76,16 @@ html.natus-open .natus-overlay { transition: opacity 0.2s ease, transform 0.2s ease; } -html.natus-open .natus-modal-wrap { +html.sky-open .sky-modal-wrap { opacity: 1; transform: translateY(0); } -.natus-modal { +.sky-modal { pointer-events: auto; display: flex; flex-direction: column; - width: 100%; // fills .natus-modal-wrap + width: 100%; // fills .sky-modal-wrap max-height: 96vh; border: 0.1rem solid rgba(var(--terUser), 0.25); border-radius: 0.5rem; @@ -94,7 +94,7 @@ html.natus-open .natus-modal-wrap { // ── Header ──────────────────────────────────────────────────────────────────── -.natus-modal-header { +.sky-modal-header { flex-shrink: 0; padding: 0.6rem 1rem; background: rgba(var(--priUser), 1); @@ -121,7 +121,7 @@ html.natus-open .natus-modal-wrap { // ── Body: two columns ───────────────────────────────────────────────────────── -.natus-modal-body { +.sky-modal-body { flex: 1; min-height: 0; display: flex; @@ -130,7 +130,7 @@ html.natus-open .natus-modal-wrap { } // Form column — fixed width; form-main scrolls, confirm btn pinned at bottom -.natus-form-col { +.sky-form-col { flex: 0 0 240px; overflow: hidden; padding: 0.9rem 1rem; @@ -142,7 +142,7 @@ html.natus-open .natus-modal-wrap { } // Scrollable inner container (form fields + status) -.natus-form-main { +.sky-form-main { flex: 1; min-height: 0; overflow-y: auto; @@ -152,12 +152,12 @@ html.natus-open .natus-modal-wrap { } // Confirm btn inside form-col — full width, pinned at column bottom -.natus-form-col > #id_natus_confirm { +.sky-form-col > #id_sky_confirm { flex-shrink: 0; } // Wheel column — fills remaining space -.natus-wheel-col { +.sky-wheel-col { flex: 1; min-width: 0; display: flex; @@ -168,7 +168,7 @@ html.natus-open .natus-modal-wrap { position: relative; } -.natus-svg { +.sky-svg { display: block; width: 100%; height: 100%; @@ -179,7 +179,7 @@ html.natus-open .natus-modal-wrap { // ── Form fields ─────────────────────────────────────────────────────────────── -.natus-field { +.sky-field { display: flex; flex-direction: column; gap: 0.25rem; @@ -204,9 +204,9 @@ html.natus-open .natus-modal-wrap { } // Place search field wrapper: text input + geo button inline -.natus-place-field { position: relative; } +.sky-place-field { position: relative; } -.natus-place-wrap { +.sky-place-wrap { display: flex; gap: 0.4rem; align-items: center; @@ -216,7 +216,7 @@ html.natus-open .natus-modal-wrap { } // Nominatim suggestion dropdown -.natus-suggestions { +.sky-suggestions { position: absolute; left: 0; right: 0; @@ -230,7 +230,7 @@ html.natus-open .natus-modal-wrap { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); } -.natus-suggestion-item { +.sky-suggestion-item { display: block; width: 100%; padding: 0.4rem 0.6rem; @@ -253,7 +253,7 @@ html.natus-open .natus-modal-wrap { } // Coords row: lat | lon (read-only, populated by place selection) -.natus-coords { +.sky-coords { flex-direction: row; align-items: flex-end; gap: 0.4rem; @@ -282,7 +282,7 @@ html.natus-open .natus-modal-wrap { // ── Status line ─────────────────────────────────────────────────────────────── -.natus-status { +.sky-status { font-size: 0.65rem; opacity: 0.6; min-height: 1rem; @@ -295,11 +295,11 @@ html.natus-open .natus-modal-wrap { } // ── NVM corner btn ──────────────────────────────────────────────────────────── -// Absolutely pinned to top-right corner of .natus-modal-wrap. +// Absolutely pinned to top-right corner of .sky-modal-wrap. // transform: translate(50%,-50%) centres the circle on the corner point. -// Lives outside .natus-modal so overflow:hidden doesn't clip it. +// Lives outside .sky-modal so overflow:hidden doesn't clip it. -#id_natus_cancel { +#id_sky_cancel { position: absolute; top: 0; right: 0; @@ -312,22 +312,22 @@ html.natus-open .natus-modal-wrap { // ── Narrow / portrait ───────────────────────────────────────────────────────── @media (max-width: 600px) { - .natus-modal-wrap { + .sky-modal-wrap { width: 92vw; } - .natus-modal { + .sky-modal { max-height: 96vh; } - .natus-modal-body { + .sky-modal-body { flex-direction: column; overflow-y: auto; } // Form col stacks above wheel; internally becomes a flex-row so // form-main gets most of the width and confirm btn sits to its right. - .natus-form-col { + .sky-form-col { flex: 0 0 auto; flex-direction: row; align-items: flex-end; @@ -337,19 +337,19 @@ html.natus-open .natus-modal-wrap { gap: 0.5rem; } - .natus-form-main { + .sky-form-main { flex: 1; min-width: 0; overflow-y: auto; max-height: 40vh; } - .natus-form-col > #id_natus_confirm { + .sky-form-col > #id_sky_confirm { flex-shrink: 0; align-self: flex-end; } - .natus-wheel-col { + .sky-wheel-col { flex: 0 0 280px; } } @@ -512,10 +512,10 @@ body[class*="-light"] { // ── Planet hover tooltip — must live outside any ancestor with transform or // container-type (both break position:fixed). Placed as a direct sibling of -// .natus-overlay in room.html; alongside #id_tooltip_portal in home.html. ── +// .sky-overlay in room.html; alongside #id_tooltip_portal in home.html. ── -#id_natus_tooltip, -#id_natus_tooltip_2 { +#id_sky_tooltip, +#id_sky_tooltip_2 { position: fixed; z-index: 200; pointer-events: auto; @@ -787,8 +787,8 @@ body[class*="-light"] { } // Element title colors — primary tier on dark palettes -#id_natus_tooltip, -#id_natus_tooltip_2 { +#id_sky_tooltip, +#id_sky_tooltip_2 { .tt-title--el-fire { color: rgba(var(--priRd), 1); } .tt-title--el-stone { color: rgba(var(--priFs), 1); } .tt-title--el-time { color: rgba(var(--priYl), 1); } @@ -798,8 +798,8 @@ body[class*="-light"] { } // Sign tooltip title + sign icon SVG — element border colors (Stone/Air/Fire/Water schema) -#id_natus_tooltip, -#id_natus_tooltip_2 { +#id_sky_tooltip, +#id_sky_tooltip_2 { .tt-title--sign-fire { color: rgba(var(--priOr), 1); } .tt-title--sign-stone { color: rgba(var(--priMe), 1); } .tt-title--sign-air { color: rgba(var(--priBl), 1); } @@ -816,8 +816,8 @@ body[class*="-light"] { } // On light palettes — switch to tertiary tier for legibility -body[class*="-light"] #id_natus_tooltip, -body[class*="-light"] #id_natus_tooltip_2 { +body[class*="-light"] #id_sky_tooltip, +body[class*="-light"] #id_sky_tooltip_2 { .tt-title--el-fire { color: rgba(var(--terRd), 1); } .tt-title--el-stone { color: rgba(var(--terFs), 1); } .tt-title--el-time { color: rgba(var(--terYl), 1); } @@ -827,8 +827,8 @@ body[class*="-light"] #id_natus_tooltip_2 { } // On light palettes — switch to primary (darkest) tier for legibility -body[class*="-light"] #id_natus_tooltip, -body[class*="-light"] #id_natus_tooltip_2 { +body[class*="-light"] #id_sky_tooltip, +body[class*="-light"] #id_sky_tooltip_2 { .tt-title--au { color: rgba(var(--priAu), 1); } .tt-title--ag { color: rgba(var(--priAg), 1); } .tt-title--hg { color: rgba(var(--priHg), 1); } @@ -849,7 +849,7 @@ body[class*="-light"] #id_natus_tooltip_2 { h2 { flex-shrink: 0; } - .natus-svg { + .sky-svg { flex: 1; min-height: 0; max-width: none; @@ -866,7 +866,7 @@ body[class*="-light"] #id_natus_tooltip_2 { flex-direction: column; gap: 0.5rem; - #id_natus_confirm { + #id_sky_confirm { margin-top: -1.5rem; align-self: center; position: relative; @@ -908,13 +908,13 @@ body.page-sky { } // Stack wheel above form; allow body to grow past viewport (page scrolls, not body) -.sky-page .natus-modal-body { +.sky-page .sky-modal-body { flex-direction: column; flex-shrink: 0; } // Wheel takes its natural square size from its width — never shrinks for the form -.sky-page .natus-wheel-col { +.sky-page .sky-wheel-col { order: -1; flex: 0 0 auto; width: 100%; @@ -925,7 +925,7 @@ body.page-sky { } // Form col runs horizontally below the wheel (same compact pattern as narrow-portrait modal) -.sky-page .natus-form-col { +.sky-page .sky-form-col { flex: 0 0 auto; flex-direction: row; align-items: flex-end; @@ -933,7 +933,7 @@ body.page-sky { border-top: 0.1rem solid rgba(var(--terUser), 0.12); } -.sky-page .natus-form-main { +.sky-page .sky-form-main { flex: 1; min-width: 0; overflow-y: visible; @@ -942,8 +942,8 @@ body.page-sky { // ── Sidebar z-index sink (landscape sidebars must go below backdrop) ─────────── @media (orientation: landscape) { - html.natus-open body .container .navbar, - html.natus-open body #id_footer { + html.sky-open body .container .navbar, + html.sky-open body #id_footer { z-index: 90; } } diff --git a/src/static_src/scss/_tooltips.scss b/src/static_src/scss/_tooltips.scss index bf2bb94..c516a21 100644 --- a/src/static_src/scss/_tooltips.scss +++ b/src/static_src/scss/_tooltips.scss @@ -1,6 +1,6 @@ // ── Tooltip base styles ─────────────────────────────────────────────────────── -// Shared by wallet tokens, game-kit kit bag, and natus wheel tooltips. -// Portal tooltips (#id_tooltip_portal, #id_natus_tooltip) are position:fixed +// Shared by wallet tokens, game-kit kit bag, and sky wheel tooltips. +// Portal tooltips (#id_tooltip_portal, #id_sky_tooltip) are position:fixed // and override z-index; inline .tt cards use position:absolute within their // parent token container. diff --git a/src/static_src/scss/_tray.scss b/src/static_src/scss/_tray.scss index 115bb1e..a1655e3 100644 --- a/src/static_src/scss/_tray.scss +++ b/src/static_src/scss/_tray.scss @@ -258,7 +258,7 @@ $tray-bevel: 0.3rem; // inner bevel ring; grid must sit inside this position: relative; // Whatever a cell holds (role-card img, sig stage card, future Celtic Cross - // / natus wheel / dice) gets a soft drop shadow to lift it off the felt. + // / sky wheel / dice) gets a soft drop shadow to lift it off the felt. // Applied to the child rather than the cell itself so the dotted grid // borders stay shadow-free. > * { diff --git a/src/static_src/scss/core.scss b/src/static_src/scss/core.scss index 8b230a4..44a768f 100644 --- a/src/static_src/scss/core.scss +++ b/src/static_src/scss/core.scss @@ -7,7 +7,7 @@ @import 'palette-picker'; @import 'room'; @import 'card-deck'; -@import 'natus'; +@import 'sky'; @import 'tray'; @import 'billboard'; @import 'note'; diff --git a/src/static_src/tests/NatusWheelSpec.js b/src/static_src/tests/SkyWheelSpec.js similarity index 94% rename from src/static_src/tests/NatusWheelSpec.js rename to src/static_src/tests/SkyWheelSpec.js index 868702a..68dce18 100644 --- a/src/static_src/tests/NatusWheelSpec.js +++ b/src/static_src/tests/SkyWheelSpec.js @@ -1,15 +1,15 @@ -// ── NatusWheelSpec.js ───────────────────────────────────────────────────────── +// ── SkyWheelSpec.js ───────────────────────────────────────────────────────── // -// Unit specs for natus-wheel.js — planet/element click-to-lock tooltips. +// Unit specs for sky-wheel.js — planet/element click-to-lock tooltips. // // DOM contract assumed: -// — target for NatusWheel.draw() -//
— tooltip portal (position:fixed on page) +// — target for SkyWheel.draw() +//
— tooltip portal (position:fixed on page) // // Click-lock contract: // click on [data-planet] group → adds .nw-planet--active class // raises group to DOM front -// shows #id_natus_tooltip with +// shows #id_sky_tooltip with // planet name, in-sign degree, sign name, // ℞ if retrograde, and "n / total" index // click same planet again → removes .nw-planet--active; hides tooltip @@ -40,7 +40,7 @@ const CONJUNCTION_CHART = { house_system: "O", }; -describe("NatusWheel — planet click tooltips", () => { +describe("SkyWheel — planet click tooltips", () => { const SYNTHETIC_CHART = { planets: { @@ -67,7 +67,7 @@ describe("NatusWheel — planet click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -75,16 +75,16 @@ describe("NatusWheel — planet click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, SYNTHETIC_CHART); + SkyWheel.draw(svgEl, SYNTHETIC_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -145,13 +145,13 @@ describe("NatusWheel — planet click tooltips", () => { }); }); -describe("NatusWheel — tick lines, raise, and cycle navigation", () => { +describe("SkyWheel — tick lines, raise, and cycle navigation", () => { let svgEl2, tooltipEl; beforeEach(() => { svgEl2 = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl2.setAttribute("id", "id_natus_svg_conj"); + svgEl2.setAttribute("id", "id_sky_svg_conj"); svgEl2.setAttribute("width", "400"); svgEl2.setAttribute("height", "400"); svgEl2.style.width = "400px"; @@ -159,17 +159,17 @@ describe("NatusWheel — tick lines, raise, and cycle navigation", () => { document.body.appendChild(svgEl2); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; tooltipEl.style.position = "fixed"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl2, CONJUNCTION_CHART); + SkyWheel.draw(svgEl2, CONJUNCTION_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl2.remove(); tooltipEl.remove(); }); @@ -295,7 +295,7 @@ describe("NatusWheel — tick lines, raise, and cycle navigation", () => { // - DOFF clears lines; re-opening same planet finds DON active // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — DON/DOFF aspect line persistence", () => { +describe("SkyWheel — DON/DOFF aspect line persistence", () => { const ASPECT_CHART = { planets: { @@ -326,7 +326,7 @@ describe("NatusWheel — DON/DOFF aspect line persistence", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -334,16 +334,16 @@ describe("NatusWheel — DON/DOFF aspect line persistence", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, ASPECT_CHART); + SkyWheel.draw(svgEl, ASPECT_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -454,7 +454,7 @@ describe("NatusWheel — DON/DOFF aspect line persistence", () => { }); }); -xdescribe("NatusWheel — half-wheel tooltip positioning", () => { +xdescribe("SkyWheel — half-wheel tooltip positioning", () => { const HALF_CHART = { planets: { @@ -481,7 +481,7 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { beforeEach(() => { svgEl3 = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl3.setAttribute("id", "id_natus_svg_half"); + svgEl3.setAttribute("id", "id_sky_svg_half"); svgEl3.setAttribute("width", "400"); svgEl3.setAttribute("height", "400"); svgEl3.style.width = "400px"; @@ -489,7 +489,7 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { document.body.appendChild(svgEl3); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; tooltipEl.style.position = "fixed"; @@ -501,11 +501,11 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { { left: 0, top: 0, width: 400, height: 400, right: 400, bottom: 400 } ); - NatusWheel.draw(svgEl3, HALF_CHART); + SkyWheel.draw(svgEl3, HALF_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl3.remove(); tooltipEl.remove(); }); @@ -561,7 +561,7 @@ xdescribe("NatusWheel — half-wheel tooltip positioning", () => { // clicking a classic-element slice lists contributor planet names in the tooltip. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — element tooltip contributor display", () => { +describe("SkyWheel — element tooltip contributor display", () => { const ENRICHED_CHART = { planets: { @@ -608,7 +608,7 @@ describe("NatusWheel — element tooltip contributor display", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -616,16 +616,16 @@ describe("NatusWheel — element tooltip contributor display", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, ENRICHED_CHART); + SkyWheel.draw(svgEl, ENRICHED_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -682,7 +682,7 @@ describe("NatusWheel — element tooltip contributor display", () => { // Clicking the same sign again closes the tooltip. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — sign ring click tooltips", () => { +describe("SkyWheel — sign ring click tooltips", () => { const SIGN_CHART = { planets: { @@ -703,7 +703,7 @@ describe("NatusWheel — sign ring click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -711,16 +711,16 @@ describe("NatusWheel — sign ring click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, SIGN_CHART); + SkyWheel.draw(svgEl, SIGN_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -756,7 +756,7 @@ describe("NatusWheel — sign ring click tooltips", () => { // Clicking the same house again closes the tooltip. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — house ring click tooltips", () => { +describe("SkyWheel — house ring click tooltips", () => { const HOUSE_CHART = { planets: { @@ -777,7 +777,7 @@ describe("NatusWheel — house ring click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -785,16 +785,16 @@ describe("NatusWheel — house ring click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, HOUSE_CHART); + SkyWheel.draw(svgEl, HOUSE_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); @@ -835,7 +835,7 @@ describe("NatusWheel — house ring click tooltips", () => { // Planet tooltips include angle aspects in their own aspect lists. // ───────────────────────────────────────────────────────────────────────────── -describe("NatusWheel — angle (ASC/MC) click tooltips", () => { +describe("SkyWheel — angle (ASC/MC) click tooltips", () => { // ASC=0°(Aries): Sun@8° → Conjunction orb 8° ✓; Mars@188° → Opposition orb 8° ✓ // MC=90°(Cancer): Moon@97° → Conjunction orb 7° ✓ @@ -863,7 +863,7 @@ describe("NatusWheel — angle (ASC/MC) click tooltips", () => { beforeEach(() => { svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svgEl.setAttribute("id", "id_natus_svg"); + svgEl.setAttribute("id", "id_sky_svg"); svgEl.setAttribute("width", "400"); svgEl.setAttribute("height", "400"); svgEl.style.width = "400px"; @@ -871,16 +871,16 @@ describe("NatusWheel — angle (ASC/MC) click tooltips", () => { document.body.appendChild(svgEl); tooltipEl = document.createElement("div"); - tooltipEl.id = "id_natus_tooltip"; + tooltipEl.id = "id_sky_tooltip"; tooltipEl.className = "tt"; tooltipEl.style.display = "none"; document.body.appendChild(tooltipEl); - NatusWheel.draw(svgEl, ANGLE_CHART); + SkyWheel.draw(svgEl, ANGLE_CHART); }); afterEach(() => { - NatusWheel.clear(); + SkyWheel.clear(); svgEl.remove(); tooltipEl.remove(); }); diff --git a/src/static_src/tests/SpecRunner.html b/src/static_src/tests/SpecRunner.html index 5f38d99..93dcbf9 100644 --- a/src/static_src/tests/SpecRunner.html +++ b/src/static_src/tests/SpecRunner.html @@ -25,7 +25,7 @@ - + @@ -40,7 +40,7 @@ - + diff --git a/src/templates/apps/dashboard/_partials/_applet-my-sky.html b/src/templates/apps/dashboard/_partials/_applet-my-sky.html index 646a7f1..8ccad62 100644 --- a/src/templates/apps/dashboard/_partials/_applet-my-sky.html +++ b/src/templates/apps/dashboard/_partials/_applet-my-sky.html @@ -10,22 +10,22 @@ {% if not request.user.sky_chart_data %}
-
+ -
+
-
+
Local time at birth place. Use 12:00 if unknown.
-
+
-
+
@@ -35,10 +35,10 @@
- +
-
+
-
+
@@ -60,15 +60,15 @@ -
+
-
{% endif %} - {% if request.user.sky_chart_data %} {{ request.user.sky_chart_data|json_script:"id_my_sky_data" }} @@ -76,7 +76,7 @@ - + - + - +