diff --git a/src/apps/gameboard/views.py b/src/apps/gameboard/views.py
index 987c7ca..33b50fe 100644
--- a/src/apps/gameboard/views.py
+++ b/src/apps/gameboard/views.py
@@ -249,6 +249,21 @@ def _my_sea_deck_data(user):
"levity_qualifier": c.levity_qualifier,
"gravity_qualifier": c.gravity_qualifier,
"reversal_qualifier": c.reversal_qualifier,
+ # Polarity-split full-title overrides — required for Major
+ # Arcana (Earthman trumps 19-21 + cards 48-49) to render
+ # their per-polarity emanation/reversal names on the stage
+ # card. Without these StageCard.populateCard falls back to
+ # the plain `name_title` w. no qualifier. Mirrors the
+ # gameroom `epic.views.sea_deck` JSON shape exactly.
+ "levity_emanation": c.levity_emanation,
+ "gravity_emanation": c.gravity_emanation,
+ "levity_reversal": c.levity_reversal,
+ "gravity_reversal": c.gravity_reversal,
+ "italic_word": c.italic_word,
+ "keywords_upright": c.keywords_upright,
+ "keywords_reversed": c.keywords_reversed,
+ "energies": c.energies,
+ "operations": c.operations,
"reversed": random.random() < reversal_prob,
}
diff --git a/src/functional_tests/test_game_my_sea.py b/src/functional_tests/test_game_my_sea.py
index 8d9ed1c..6aa9105 100644
--- a/src/functional_tests/test_game_my_sea.py
+++ b/src/functional_tests/test_game_my_sea.py
@@ -533,7 +533,7 @@ class MySeaSpreadFormTest(FunctionalTest):
"past-present-future": {"leave", "cover", "loom"},
"situation-action-outcome": {"lay", "cover", "crown"},
"mind-body-spirit": {"crown", "lay", "loom"},
- "desire-obstacle-solution": {"loom", "cross", "cover"},
+ "desire-obstacle-solution": {"loom", "cross", "crown"},
"waite-smith": ALL_POSITIONS,
"escape-velocity": ALL_POSITIONS,
}
@@ -583,7 +583,7 @@ class MySeaSpreadFormTest(FunctionalTest):
"situation-action-outcome": {"lay": "Situation", "cover": "Action", "crown": "Outcome"},
"past-present-future": {"leave": "Past", "cover": "Present", "loom": "Future"},
"mind-body-spirit": {"crown": "Mind", "lay": "Body", "loom": "Spirit"},
- "desire-obstacle-solution": {"loom": "Desire", "cross": "Obstacle","cover":"Solution"},
+ "desire-obstacle-solution": {"loom": "Desire", "cross": "Obstacle","crown":"Solution"},
"waite-smith": {"crown": "Crown", "leave": "Beneath", "cover": "Cover",
"cross": "Cross", "loom": "Before", "lay": "Behind"},
}
@@ -670,9 +670,10 @@ class MySeaCardDrawTest(FunctionalTest):
)
)
- def _draw_one(self, picker, polarity):
- """Click a polarity swatch + the FLIP btn that appears →
- deposits a card. `polarity` is `'levity'` or `'gravity'`."""
+ def _draw_open_modal(self, picker, polarity):
+ """Click a polarity swatch + the FLIP btn that appears → opens
+ the SeaDeal stage modal. Returns the stage element so callers
+ can assert on it before dismissing."""
stack = picker.find_element(
By.CSS_SELECTOR, f".sea-deck-stack--{polarity}"
)
@@ -680,9 +681,45 @@ class MySeaCardDrawTest(FunctionalTest):
flip = self.wait_for(
lambda: stack.find_element(By.CSS_SELECTOR, ".sea-stack-ok")
)
- # FLIP btn becomes visible after the stack click; wait for it.
self.wait_for(lambda: self.assertTrue(flip.is_displayed()))
flip.click()
+ # SeaDeal.openStage shows #id_sea_stage. Wait for the modal.
+ return self.wait_for(
+ lambda: self._stage_visible()
+ )
+
+ def _stage_visible(self):
+ stage = self.browser.find_element(By.CSS_SELECTOR, "#id_sea_stage")
+ if not stage.is_displayed():
+ raise AssertionError("sea-stage not visible after FLIP click")
+ return stage
+
+ def _dismiss_modal(self):
+ """Click the stage backdrop → SeaDeal._hideStage → modal hides +
+ slot gains `.--visible` (thumbnail fades in).
+
+ Uses `execute_script` to dispatch the click rather than a native
+ Selenium `.click()` — `.sea-stage-content` overlays the backdrop
+ visually (centered card + stat block), so Selenium reports
+ ElementClickInterceptedException for a direct click. This is
+ the documented Selenium-limitation exception per the TDD skill;
+ the actual backdrop-click → close behaviour is Jasmine-tested
+ in [[SeaDealSpec.js]] / "Backdrop click closes the stage"."""
+ self.browser.execute_script(
+ "document.querySelector('#id_sea_stage .sea-stage-backdrop').click();"
+ )
+ self.wait_for(
+ lambda: self.assertFalse(
+ self.browser.find_element(By.CSS_SELECTOR, "#id_sea_stage").is_displayed()
+ )
+ )
+
+ def _draw_one(self, picker, polarity):
+ """Full single-draw cycle: open modal + dismiss it. Used by FTs
+ that need to deposit multiple cards in sequence (the stage
+ backdrop blocks subsequent deck-stack clicks)."""
+ self._draw_open_modal(picker, polarity)
+ self._dismiss_modal()
# ── Test 1 ───────────────────────────────────────────────────────────────
@@ -890,3 +927,71 @@ class MySeaCardDrawTest(FunctionalTest):
hint = picker.find_element(By.CSS_SELECTOR, ".sea-reversal-hint")
self.assertIn("25", hint.text)
self.assertIn("reversal", hint.text.lower())
+
+ # ── Test (modal bug fix) ────────────────────────────────────────────────
+
+ def test_flip_click_opens_portaled_stage_modal(self):
+ """Bug fix (2026-05-19): the user-reported missing modal. After
+ clicking the deck stack + the FLIP btn that appears, SeaDeal.
+ openStage should fire — showing `#id_sea_stage` (position-fixed
+ full-viewport portal) above everything else. Before the fix the
+ slot got filled directly at opacity 0 → 'thumbnail summarily
+ disappears'. Now: modal opens; slot stays at `--filled` but
+ `--visible` is NOT added yet (waits for backdrop dismiss)."""
+ picker = self._enter_picker_phase()
+ stage = self._draw_open_modal(picker, "levity")
+ # Stage card carries the drawn card's data — non-empty corner rank.
+ rank = stage.find_element(
+ By.CSS_SELECTOR, ".sea-stage-card .fan-card-corner--tl .fan-corner-rank"
+ )
+ self.assertTrue(rank.text.strip(), "stage card should display the drawn card's corner rank")
+ # Slot in the cross is in `.--filled` state but the thumbnail is
+ # invisible until the modal dismisses (the bug we're guarding).
+ slot = picker.find_element(
+ By.CSS_SELECTOR, ".sea-pos-lay .sea-card-slot.sea-card-slot--filled"
+ )
+ self.assertNotIn(
+ "sea-card-slot--visible", slot.get_attribute("class"),
+ "slot should still be in pre-reveal opacity-0 state while modal is open",
+ )
+
+ # ── Test (modal bug fix, dismiss reveal) ───────────────────────────────
+
+ def test_backdrop_click_dismisses_modal_and_reveals_thumbnail(self):
+ """Bug fix part 2: clicking the `.sea-stage-backdrop` closes the
+ modal AND adds `.sea-card-slot--visible` to the deposited slot,
+ making the thumbnail fade in. Confirms the user-reported 'card
+ appears where the slot was' behavior post-dismiss."""
+ picker = self._enter_picker_phase()
+ self._draw_open_modal(picker, "levity")
+ self._dismiss_modal()
+ slot = picker.find_element(
+ By.CSS_SELECTOR, ".sea-pos-lay .sea-card-slot.sea-card-slot--filled"
+ )
+ self.assertIn(
+ "sea-card-slot--visible", slot.get_attribute("class"),
+ "post-dismiss, the slot should fade in via `.--visible`",
+ )
+
+ # ── Test (modal bug fix, stat block populates) ─────────────────────────
+
+ def test_modal_stage_renders_stat_block_dom_contract(self):
+ """SeaDeal._populate populates the stat-block keyword `
`s
+ via `#id_sea_stat_upright` / `#id_sea_stat_reversed`. The DOM
+ contract — these IDs exist inside the stage — is what this FT
+ pins; the actual stat content (keyword text, qualifier render)
+ is exercised by [[SeaDealSpec.js]]. Earthman seed cards in the
+ iter-4a FT pile carry empty keyword arrays so we can't assert
+ text content here without enriching the seed."""
+ picker = self._enter_picker_phase()
+ self._draw_open_modal(picker, "levity")
+ # Stat-block UL elements exist inside the visible stage.
+ upright = self.browser.find_element(By.CSS_SELECTOR, "#id_sea_stat_upright")
+ reversed_ul = self.browser.find_element(By.CSS_SELECTOR, "#id_sea_stat_reversed")
+ self.assertIsNotNone(upright)
+ self.assertIsNotNone(reversed_ul)
+ # The sea stat block is inside the visible stage modal.
+ stat_block = self.browser.find_element(
+ By.CSS_SELECTOR, "#id_sea_stage .sea-stat-block"
+ )
+ self.assertIsNotNone(stat_block)
diff --git a/src/static_src/scss/_card-deck.scss b/src/static_src/scss/_card-deck.scss
index e31ca4a..80413a3 100644
--- a/src/static_src/scss/_card-deck.scss
+++ b/src/static_src/scss/_card-deck.scss
@@ -1324,9 +1324,30 @@ $sea-card-h: 6.5rem;
.sea-pos-cover { z-index: 3; } // above sig (z-index: 2)
.sea-pos-cross { z-index: 4; } // above cover
-// Empty Cover/Cross slots are invisible — they reveal only once a card is deposited
+// Empty Cover/Cross slots — subtle dotted outline (no fill) so the
+// underlying Sig card shows through. Hovering/touching reveals the
+// full --duoUser mask, opaquing the slot + obscuring the Sig behind.
+// Border + label dim to 0.25 alpha default; bounce to full on hover.
+// The filled-slot hover behavior (opacity 0.3/0.15 → 1) at lines 1300-
+// 1301 is untouched — this only restyles the EMPTY state.
.sea-pos-cover .sea-card-slot--empty,
-.sea-pos-cross .sea-card-slot--empty { opacity: 0; pointer-events: none; }
+.sea-pos-cross .sea-card-slot--empty {
+ background-color: transparent;
+ border-color: rgba(var(--terUser), 0.25);
+ box-shadow: none;
+ pointer-events: auto;
+ transition: background-color 0.15s ease, border-color 0.15s ease;
+
+ .sea-pos-label { opacity: 0.25; }
+}
+
+.sea-pos-cover .sea-card-slot--empty:hover,
+.sea-pos-cross .sea-card-slot--empty:hover {
+ background-color: rgba(var(--duoUser), 1);
+ border-color: rgba(var(--terUser), 1);
+
+ .sea-pos-label { opacity: 0.6; }
+}
.sea-pos-cross .sea-card-slot { transform: rotate(90deg); }
diff --git a/src/static_src/scss/_gameboard.scss b/src/static_src/scss/_gameboard.scss
index c722640..3b71cec 100644
--- a/src/static_src/scss/_gameboard.scss
+++ b/src/static_src/scss/_gameboard.scss
@@ -297,10 +297,19 @@ body.page-gameboard {
// PPF: leave (1) cover (2) loom (3) — horizontal middle row
// SAO: lay (1) cover (2) crown (3) — vertical center column
// MBS: crown (1) lay (2) loom (3) — T-shape (crown + lay vertical, loom right)
-// DOS: loom (1) cross (2) cover (3) — sig-anchored cluster + loom
+// DOS: loom (1) cross (2) crown (3) — loom right · cross overlay · crown above
// CC variants: all 6 positions (Waite-Smith / Escape Velocity differ in DRAW ORDER only,
// not in position visibility).
+// Bump grid gap on my-sea (gameroom .sea-cross stays at 0.5rem since
+// gameroom slots have no per-position labels). The vertical leave/loom
+// labels need ~1.5rem of horizontal clearance from adjacent cells, and
+// the horizontal crown/cover/lay/cross labels need ~1rem of vertical
+// clearance so they don't overlap into the next row.
+.my-sea-cross {
+ gap: 1rem !important;
+}
+
.my-sea-cross[data-spread="past-present-future"] {
.sea-pos-crown,
.sea-pos-cross,
@@ -321,28 +330,106 @@ body.page-gameboard {
.my-sea-cross[data-spread="desire-obstacle-solution"] {
.sea-pos-leave,
- .sea-pos-crown,
+ .sea-pos-cover,
.sea-pos-lay { display: none; }
}
// Celtic Cross variants (waite-smith / escape-velocity) — all positions
// visible by default. No `display: none` overrides needed.
-// Position-name caption inside each empty `.sea-card-slot--empty` —
-// re-appropriates the GRAVITY/LEVITY `.sea-stack-name` typographic
-// look (_card-deck.scss line 1557): small uppercase letter-spaced w.
-// a subtle scaleY stretch, --terUser ink at 0.6 opacity. No polarity
-// coloring — these are spread-position labels, not deck identifiers.
+// Position-name caption — re-appropriates the GRAVITY/LEVITY
+// `.sea-stack-name` typographic look (_card-deck.scss line 1557):
+// small uppercase letter-spaced w. a subtle scaleY stretch,
+// --terUser ink at 0.6 opacity. No polarity coloring — these are
+// spread-position labels, not deck identifiers.
+//
+// Labels live OUTSIDE the .sea-card-slot (sibling, inside the crucifix
+// cell or the cover/cross wrapper) so they survive SeaDeal._fillSlot's
+// `slot.innerHTML = …` clobber on draw. Each label is absolute-
+// positioned to nearly touch the slot's nearest border per the user-
+// locked spec:
+// crown / cover — above top border
+// lay / cross — below bottom border
+// leave — left of left border, rotated 90° CCW
+// loom — right of right border, rotated 90° CW
.sea-pos-label {
font-size: 0.65rem;
letter-spacing: 0.08em;
text-transform: uppercase;
font-weight: 600;
- opacity: 0.6;
- transform: scaleY(1.2);
- color: rgba(var(--terUser), 1);
+ opacity: 1;
+ color: rgba(var(--seciUser), 1);
text-align: center;
pointer-events: none;
+ white-space: nowrap;
+ position: absolute;
+ z-index: 2;
+}
+
+// Cells need `position: relative` so absolute label children anchor
+// to them. `.sea-pos-core` already has `position: relative` per the
+// existing rule in _card-deck.scss line 1311; the other crucifix
+// cells need it added.
+.my-sea-cross .sea-crucifix-cell { position: relative; }
+
+// Above top border — overlaps slot's top edge by 0.1rem (per the
+// `.sea-stack-name` "tuck under" treatment in _card-deck.scss:1564).
+.sea-pos-crown > .sea-pos-label,
+.sea-pos-cover > .sea-pos-label {
+ bottom: 100%;
+ left: 50%;
+ transform: translate(-50%, 0.1rem) scaleY(1.2);
+}
+
+// Cover + cross labels dim w. their slots — they sit on top of the
+// sig card so a vivid label would compete w. the sig at idle. Default
+// 0.25 opacity matches the slot's faint dotted-outline at idle; the
+// parent's :hover state (propagated up when the inside `.sea-card-
+// slot:hover` fires per CSS hover-ancestor rules) boosts to the
+// `.sea-pos-label` baseline 0.6, matching the slot's `--duoUser` mask
+// reveal.
+.sea-pos-cover > .sea-pos-label,
+.sea-pos-cross > .sea-pos-label {
+ opacity: 0.5;
+ transition: opacity 0.15s ease;
+}
+
+.sea-pos-cover:hover > .sea-pos-label,
+.sea-pos-cross:hover > .sea-pos-label {
+ opacity: 1;
+}
+
+// Below bottom border — same `0.1rem` overlap but downward.
+.sea-pos-lay > .sea-pos-label,
+.sea-pos-cross > .sea-pos-label {
+ top: 100%;
+ left: 50%;
+ transform: translate(-50%, -0.1rem) scaleY(1.2);
+}
+
+// Left of left border, rotated 90° CCW — text reads bottom-to-top.
+// `writing-mode: vertical-rl` puts text top-to-bottom (CW); a 180°
+// rotation flips it to read bottom-to-top (CCW), satisfying the user-
+// locked "Leave: counterclockwise" spec.
+//
+// `scaleX(1.2)` (instead of the horizontal labels' scaleY) widens the
+// character column (perpendicular to text-flow) — for vertical-rl
+// labels, that's the visible "width" the user noticed had been lost
+// at this angle. Without it, the rotated labels look squat.
+.sea-pos-leave > .sea-pos-label {
+ right: 100%;
+ top: 50%;
+ writing-mode: vertical-rl;
+ transform: translate(0.1rem, -50%) rotate(180deg) scaleX(1.2);
+}
+
+// Right of right border, rotated 90° CW — text reads top-to-bottom.
+// Native `writing-mode: vertical-rl` direction; no extra rotation.
+.sea-pos-loom > .sea-pos-label {
+ left: 100%;
+ top: 50%;
+ writing-mode: vertical-rl;
+ transform: translate(-0.1rem, -50%) scaleX(1.2);
}
// Section dividers inside the SPREAD combobox — labels "3-card spreads"
@@ -370,6 +457,26 @@ body.page-gameboard {
.my-sea-form-col {
flex: 0 0 16rem;
max-width: 16rem;
+
+ // Portal the SPREAD dropdown out of `.sea-form-main`'s overflow
+ // clip — by default the gameroom's `.sea-form-main { overflow-y:
+ // auto }` (from _card-deck.scss:1424) keeps the modal contents
+ // scrollable, but for my-sea's much shorter form the dropdown gets
+ // clipped instead of overlaying the LOCK HAND / DEL btns below.
+ // Setting overflow visible here lets the absolute-positioned
+ // `.sea-select-list` extend past the form area + sit "above
+ // everything else" via its existing z-index: 100.
+ .sea-form-main {
+ overflow: visible;
+ }
+
+ // Bump the dropdown z-index well above the picker's stacking ints
+ // (cover z:3, cross z:4, modal stage z:9999 only opens on draw
+ // anyway). 1000 sits above any in-page layer the user might be
+ // interacting w. when they open the SPREAD picker.
+ .sea-select-list {
+ z-index: 1000;
+ }
}
// LOCK HAND post-commit visual-lock: dim everything that mutates the
@@ -385,3 +492,14 @@ body.page-gameboard {
cursor: default;
}
}
+
+// SPREAD combobox lock — applied after the first deposit so the user
+// can't switch spread mid-draw + scramble the in-progress hand's
+// position-to-card mapping. DEL releases the lock by removing this
+// class. Same `pointer-events: none` treatment as `.btn-disabled` per
+// [[feedback_btn_disabled_pointer_events]].
+.sea-select.sea-select--locked {
+ pointer-events: none;
+ opacity: 0.5;
+ cursor: default;
+}
diff --git a/src/templates/apps/gameboard/_partials/_sea_overlay.html b/src/templates/apps/gameboard/_partials/_sea_overlay.html
index d2879a9..988d5e3 100644
--- a/src/templates/apps/gameboard/_partials/_sea_overlay.html
+++ b/src/templates/apps/gameboard/_partials/_sea_overlay.html
@@ -139,50 +139,9 @@
{# /.sea-modal-wrap #}
{# ── Sea stage — big card viewer ─────────────────────────────────────────── #}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {# Default DOM order — matches non-major arcana layout. stage-card.js #}
- {# swaps the class names on these
s for Major arcana so each #}
- {# element's class still matches its semantic content. #}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Emanation
-
-
-
-
Reversal
-
-
- {% include "apps/gameboard/_partials/_sig_fyi_panel.html" with panel_id="id_sea_fyi_panel" panel_extra_attrs='style="display:none"' %}
-
-
-
+ {# Extracted to a shared partial so the my-sea picker (Sprint 5 iter 4-bugs) #}
+ {# reuses the same DOM contract that SeaDeal binds to. #}
+ {% include "apps/gameboard/_partials/_sea_stage.html" %}
{# /.sea-overlay #}
diff --git a/src/templates/apps/gameboard/_partials/_sea_stage.html b/src/templates/apps/gameboard/_partials/_sea_stage.html
new file mode 100644
index 0000000..a576020
--- /dev/null
+++ b/src/templates/apps/gameboard/_partials/_sea_stage.html
@@ -0,0 +1,52 @@
+{# Sea stage — full-viewport portaled modal (`position: fixed; inset: 0` #}
+{# per _card-deck.scss:1615) that opens above the picker / overlay when #}
+{# `SeaDeal.openStage(card, posSelector, isLevity)` fires. Hosts the #}
+{# full card face + stat block + SPIN / FYI controls; click backdrop to #}
+{# dismiss + reveal the deposited card thumbnail in its slot. #}
+{# #}
+{# Shared by the gameroom SEA SELECT phase and the my-sea picker — same #}
+{# HTML, same SeaDeal module bindings; only the parent overlay differs. #}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {# Default DOM order — matches non-major arcana layout. stage-card.js #}
+ {# swaps the class names on these
s for Major arcana so each #}
+ {# element's class still matches its semantic content. #}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Emanation
+
+
+
+
Reversal
+
+
+ {% include "apps/gameboard/_partials/_sig_fyi_panel.html" with panel_id="id_sea_fyi_panel" panel_extra_attrs='style="display:none"' %}
+
+
+
diff --git a/src/templates/apps/gameboard/my_sea.html b/src/templates/apps/gameboard/my_sea.html
index 2bb8ffd..5080d4d 100644
--- a/src/templates/apps/gameboard/my_sea.html
+++ b/src/templates/apps/gameboard/my_sea.html
@@ -75,18 +75,28 @@
{# Each empty slot carries a `.sea-pos-label` caption (re- #}
{# appropriated from the GRAVITY/LEVITY .sea-stack-name look) #}
{# that JS updates per spread. #}
-
+ {# #}
+ {# `id="id_sea_overlay"` aliases the picker to what SeaDeal #}
+ {# binds to (the gameroom uses the same ID on a different #}
+ {# page — no DOM collision since my-sea + gameroom never co- #}
+ {# exist in one DOM). FLIP click delegates to SeaDeal. #}
+ {# openStage(), which fills the slot AND opens the portaled #}
+ {# stage modal w. SPIN / FYI controls. #}
+
+ {# `.sea-pos-label` lives OUTSIDE the slot so SeaDeal._fillSlot's #}
+ {# `slot.innerHTML = …` (which writes the drawn card's corner- #}
+ {# rank + suit-icon) doesn't clobber it. Labels persist as #}
+ {# adjacent siblings + are positioned via absolute SCSS to #}
+ {# touch the slot's nearest edge. #}
-
- Outcome
-
+ Outcome
+
-
-
-
+
+
{% endif %}
-
- Action
-
+ Action
+
-
-
-
+
+
-
-
-
+
+
-
- Situation
-
+ Situation
+
@@ -129,8 +135,16 @@
{{ reversals_pct|default:25 }}% reversals
+ {# autocomplete="off" opts the hidden input out of #}
+ {# Firefox's form-history autofill, which otherwise #}
+ {# restores the LAST value on soft reload (F5). #}
+ {# Without this, combobox.js's `select(i)` short- #}
+ {# circuits its change-event dispatch when the #}
+ {# user re-picks the value Firefox already restored #}
+ {# → my-sea's sync() never fires → data-spread on #}
+ {# .my-sea-cross stays stuck on SAO default. #}
+ value="{{ default_spread }}" autocomplete="off">
+ {# Sea stage — portaled modal that opens on FLIP click via #}
+ {# SeaDeal.openStage. `position:fixed; inset:0` covers the #}
+ {# viewport; click backdrop to dismiss + reveal the slot #}
+ {# thumbnail. #}
+ {% include "apps/gameboard/_partials/_sea_stage.html" %}
{# Sprint 5 iter 4a — shuffled deck (levity + gravity halves, #}
{# sig excluded) embedded as JSON; JS reads on init and #}
{# pops from the relevant pile on each deposit. #}
{{ sea_deck_data|json_script:"id_my_sea_deck" }}
+ {# StageCard + SeaDeal — both bind to `#id_sea_overlay` (the #}
+ {# my-sea-picker) + `#id_sea_stage` (the stage partial) on #}
+ {# DOMContentLoaded; openStage() runs on FLIP click below. #}
+
+