beiser
This commit is contained in:
parent
e52e451d98
commit
70251093a8
|
|
@ -185,7 +185,7 @@ export default function MapView({ theme = "dark" }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="map-view">
|
<div className="map-page">\n <div className="map-stage">
|
||||||
<div ref={containerRef} className="map-container" />
|
<div ref={containerRef} className="map-container" />
|
||||||
{status && <div className="map-status">{status}</div>}
|
{status && <div className="map-status">{status}</div>}
|
||||||
|
|
||||||
|
|
@ -280,26 +280,36 @@ export default function MapView({ theme = "dark" }) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="map-overlay map-overlay-wall">
|
|
||||||
<div className="sociowall-panel">
|
</div>
|
||||||
<div className="sociowall-header">Sociowall</div>
|
|
||||||
<PostList
|
{/* BELOW THE MAP (page scroll) */}
|
||||||
posts={visiblePosts}
|
<div className="below-stage">
|
||||||
loading={loadingPosts}
|
<div className="below-row">
|
||||||
error={loadError}
|
<div className="sociowall-panel">
|
||||||
selectedPost={selectedPost}
|
<div className="sociowall-header">Sociowall</div>
|
||||||
onSelectPost={handleSelectPost}
|
<PostList
|
||||||
/>
|
posts={visiblePosts}
|
||||||
</div>
|
loading={loadingPosts}
|
||||||
<div className="chat-panel">
|
error={loadError}
|
||||||
<div className="chat-header">Chat</div>
|
selectedPost={selectedPost}
|
||||||
<ul className="chat-users">
|
onSelectPost={handleSelectPost}
|
||||||
<li>Yan</li>
|
/>
|
||||||
<li>Marc</li>
|
</div>
|
||||||
<li>Fiso</li>
|
|
||||||
</ul>
|
<div className="chat-panel">
|
||||||
|
<div className="chat-header">Chat</div>
|
||||||
|
<ul className="chat-users">
|
||||||
|
<li>Yan</li>
|
||||||
|
<li>Marc</li>
|
||||||
|
<li>Fiso</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style={{ height: 24 }} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,17 @@ import maplibregl from "maplibre-gl";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
|
|
||||||
import TemplateMarkerCard from "./TemplateMarkerCard";
|
import CardRenderer from "../Cards/CardRenderer";
|
||||||
import { getDefaultTemplateCached } from "../../api/templates";
|
import { cardTokens } from "../../theme/cardTokens";
|
||||||
|
import { getTemplateSpecForPost, adaptPostToTemplateData } from "./templateSpecs";
|
||||||
|
|
||||||
export function clearAllMarkers(markersRef, expandedElRef) {
|
export function clearAllMarkers(markersRef, expandedElRef) {
|
||||||
if (markersRef.current) {
|
if (markersRef.current) {
|
||||||
for (const m of markersRef.current) {
|
for (const m of markersRef.current) {
|
||||||
try {
|
try {
|
||||||
if (m?.el && m.el.__reactRoot) {
|
if (m?.el && m.el.__swUnmount) m.el.__swUnmount();
|
||||||
try { m.el.__reactRoot.unmount(); } catch {}
|
} catch {}
|
||||||
m.el.__reactRoot = null;
|
try {
|
||||||
}
|
|
||||||
m.marker.remove();
|
m.marker.remove();
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
@ -72,29 +72,30 @@ export function clearOcclusion(markersRef) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(str) {
|
function mountCard(container, spec, data, theme) {
|
||||||
return String(str)
|
const root = createRoot(container);
|
||||||
.replace(/&/g, "&")
|
const tokens = cardTokens?.[theme] || cardTokens.blue;
|
||||||
.replace(/</g, "<")
|
|
||||||
.replace(/>/g, ">")
|
root.render(
|
||||||
.replace(/"/g, """);
|
React.createElement(CardRenderer, {
|
||||||
|
spec,
|
||||||
|
data,
|
||||||
|
themeTokens: tokens,
|
||||||
|
onAction: (action, value) => {
|
||||||
|
if (action?.type === "open_url" && value) {
|
||||||
|
try { window.open(value, "_blank"); } catch {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
className: "",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
try { root.unmount(); } catch {}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentTheme() {
|
export function createMarkerForPost(post, mapRef, markersRef, expandedElRef, theme = "blue") {
|
||||||
try {
|
|
||||||
const t = document?.body?.getAttribute("data-theme") || "dark";
|
|
||||||
if (t === "dark" || t === "blue" || t === "light") return t;
|
|
||||||
} catch {}
|
|
||||||
return "dark";
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureReactRoot(el) {
|
|
||||||
if (el.__reactRoot) return el.__reactRoot;
|
|
||||||
el.__reactRoot = createRoot(el);
|
|
||||||
return el.__reactRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map) return;
|
if (!map) return;
|
||||||
|
|
||||||
|
|
@ -117,65 +118,98 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = (post.title || "").trim() || "Untitled";
|
|
||||||
|
|
||||||
const root = document.createElement("div");
|
const root = document.createElement("div");
|
||||||
root.className = "post-pin post-pin--compact";
|
root.className = "post-pin post-pin--compact";
|
||||||
root.style.zIndex = "1";
|
root.style.zIndex = "1";
|
||||||
|
|
||||||
|
function unmountIfAny() {
|
||||||
|
if (root.__swUnmount) {
|
||||||
|
try { root.__swUnmount(); } catch {}
|
||||||
|
root.__swUnmount = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function renderCompact() {
|
function renderCompact() {
|
||||||
|
unmountIfAny();
|
||||||
root.className = "post-pin post-pin--compact";
|
root.className = "post-pin post-pin--compact";
|
||||||
root.style.zIndex = "1";
|
root.style.zIndex = "1";
|
||||||
|
|
||||||
|
// pointer stays: .post-pin-pointer-small (UNCHANGED)
|
||||||
root.innerHTML = `
|
root.innerHTML = `
|
||||||
<div class="post-pin-bubble">
|
<div class="sw-template-mini-wrap"></div>
|
||||||
<div class="post-pin-dot"></div>
|
|
||||||
<div class="post-pin-text">${escapeHtml(title)}</div>
|
|
||||||
</div>
|
|
||||||
<div class="post-pin-pointer-small"></div>
|
<div class="post-pin-pointer-small"></div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (root.__reactRoot) {
|
const wrap = root.querySelector(".sw-template-mini-wrap");
|
||||||
try { root.__reactRoot.unmount(); } catch {}
|
if (wrap) {
|
||||||
root.__reactRoot = null;
|
const spec = getTemplateSpecForPost(post, "mini");
|
||||||
|
const data = adaptPostToTemplateData(post);
|
||||||
|
root.__swUnmount = mountCard(wrap, spec, data, theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearOcclusion(markersRef);
|
clearOcclusion(markersRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderExpanded() {
|
function renderExpanded() {
|
||||||
|
unmountIfAny();
|
||||||
root.className = "post-pin post-pin--expanded";
|
root.className = "post-pin post-pin--expanded";
|
||||||
root.style.zIndex = "999999";
|
root.style.zIndex = "999999";
|
||||||
|
|
||||||
|
// pointer stays: .post-card-pointer (UNCHANGED)
|
||||||
|
const headline = escapeHtml(post?.title || "Untitled");
|
||||||
|
|
||||||
root.innerHTML = `
|
root.innerHTML = `
|
||||||
<div class="post-card">
|
<div class="post-card sw-expanded-shell">
|
||||||
<div class="post-card-body" style="font-size:11px; opacity:.9;">Loading template…</div>
|
<div class="sw-expanded-top">
|
||||||
|
<div class="sw-expanded-left">
|
||||||
|
<div class="sw-template-full-wrap"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sw-expanded-right">
|
||||||
|
<div class="sw-watch-title">Watching</div>
|
||||||
|
<div class="sw-watch-list">
|
||||||
|
<div class="sw-watch-item">☑ Julia ★<div class="sw-watch-msg">— I see it…</div></div>
|
||||||
|
<div class="sw-watch-item">☑ Kim / CNN<div class="sw-watch-msg">— Blah blah blah</div></div>
|
||||||
|
<div class="sw-watch-item">☑ Yan ★<div class="sw-watch-msg">— Watch this!!</div></div>
|
||||||
|
</div>
|
||||||
|
<button class="sw-add-feed-btn" type="button">ADD TO FEED</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sw-news-generated">
|
||||||
|
<div class="sw-news-title">${headline}</div>
|
||||||
|
<div class="sw-news-sub">The news here (generated)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-card-footer sw-actions-row">
|
||||||
|
<button class="post-card-btn">Contact</button>
|
||||||
|
<button class="post-card-btn">Like</button>
|
||||||
|
<button class="post-card-btn">Share</button>
|
||||||
|
<button class="post-card-btn">Fix</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-card-comments sw-livechat">
|
||||||
|
<div class="sw-livechat-title">Live chat / comments</div>
|
||||||
|
<div class="sw-livechat-body">
|
||||||
|
<div class="sw-chat-line">— …</div>
|
||||||
|
<div class="sw-chat-line">— what the f***?</div>
|
||||||
|
<div class="sw-chat-line">— nice…</div>
|
||||||
|
<div class="sw-chat-line">— my eyes!!</div>
|
||||||
|
</div>
|
||||||
|
<div class="sw-livechat-inputrow">
|
||||||
|
<input class="sw-livechat-input" placeholder="Write a comment…" />
|
||||||
|
<button class="sw-livechat-post" type="button">POST</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="post-card-pointer"></div>
|
<div class="post-card-pointer"></div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const cardEl = root.querySelector(".post-card");
|
const wrap = root.querySelector(".sw-template-full-wrap");
|
||||||
if (!cardEl) return;
|
if (wrap) {
|
||||||
|
const spec = getTemplateSpecForPost(post, "full");
|
||||||
const theme = currentTheme();
|
const data = adaptPostToTemplateData(post);
|
||||||
|
root.__swUnmount = mountCard(wrap, spec, data, theme);
|
||||||
try {
|
|
||||||
const tpl = await getDefaultTemplateCached("news");
|
|
||||||
|
|
||||||
const rr = ensureReactRoot(cardEl);
|
|
||||||
rr.render(
|
|
||||||
React.createElement(TemplateMarkerCard, {
|
|
||||||
post,
|
|
||||||
template: tpl,
|
|
||||||
theme,
|
|
||||||
mode: "full",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
cardEl.innerHTML = `
|
|
||||||
<div style="font-weight:800; font-size:13px; margin-bottom:4px;">${escapeHtml(title)}</div>
|
|
||||||
<div style="font-size:11px; opacity:.9;">(template load failed)</div>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
|
|
@ -210,3 +244,11 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escapeHtml(str) {
|
||||||
|
return String(str ?? "")
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* Frontend-only template specs (no DB changes).
|
||||||
|
* Keep pointers as-is:
|
||||||
|
* - compact triangle: .post-pin-pointer-small
|
||||||
|
* - expanded triangle: .post-card-pointer
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const TEMPLATE_SPECS = {
|
||||||
|
news: {
|
||||||
|
mini_spec: {
|
||||||
|
size: { w: 280, h: 110 },
|
||||||
|
background: { type: "gradient", value: "newsBlue" },
|
||||||
|
radius: 18,
|
||||||
|
layers: [
|
||||||
|
{ id: "badge", type: "chip", x: 14, y: 12, text: "NEWS", style: "chip.news" },
|
||||||
|
{ id: "title", type: "text", x: 14, y: 40, w: 252, h: 44, bind: "data.headline", style: "text.title", maxLines: 2 },
|
||||||
|
{ id: "meta", type: "text", x: 14, y: 88, w: 252, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 }
|
||||||
|
],
|
||||||
|
},
|
||||||
|
full_spec: {
|
||||||
|
size: { w: 360, h: 520 },
|
||||||
|
background: { type: "solid", value: "surface" },
|
||||||
|
radius: 22,
|
||||||
|
layers: [
|
||||||
|
{ id: "hero", type: "image", x: 0, y: 0, w: 360, h: 220, bind: "data.image" },
|
||||||
|
{ id: "badge", type: "chip", x: 16, y: 16, text: "NEWS", style: "chip.news" },
|
||||||
|
{ id: "title", type: "text", x: 16, y: 240, w: 328, h: 78, bind: "data.headline", style: "text.h1", maxLines: 3 },
|
||||||
|
{ id: "summary", type: "text", x: 16, y: 325, w: 328, h: 110, bind: "data.summary", style: "text.body", maxLines: 5 },
|
||||||
|
{
|
||||||
|
id: "cta",
|
||||||
|
type: "button",
|
||||||
|
x: 16, y: 450, w: 328, h: 48,
|
||||||
|
text: "Open source",
|
||||||
|
style: "button.primary",
|
||||||
|
action: { type: "open_url", bind: "data.url" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function normCat(post) {
|
||||||
|
const c = (post?.category || "").toString().toUpperCase();
|
||||||
|
if (c === "NEWS") return "news";
|
||||||
|
if (c === "EVENT") return "news";
|
||||||
|
if (c === "FRIENDS") return "news";
|
||||||
|
if (c === "MARKET") return "news";
|
||||||
|
return "news";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTemplateKeyForPost(post) {
|
||||||
|
// Future mapping: if (post.template_id === 101) return "news";
|
||||||
|
return normCat(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTemplateSpecForPost(post, variant /* "mini"|"full" */) {
|
||||||
|
const key = getTemplateKeyForPost(post);
|
||||||
|
const t = TEMPLATE_SPECS[key] || TEMPLATE_SPECS.news;
|
||||||
|
return variant === "full" ? t.full_spec : t.mini_spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function adaptPostToTemplateData(post) {
|
||||||
|
const headline = post?.title || "Untitled";
|
||||||
|
const author = post?.author ? `by ${post.author}` : "";
|
||||||
|
const sub = post?.sub_category ? String(post.sub_category) : "";
|
||||||
|
const source = author || sub || "";
|
||||||
|
const summary = post?.snippet || post?.body || "";
|
||||||
|
const url = post?.url || "";
|
||||||
|
const image = post?.image_large || post?.image_small || post?.image || post?.media_url || "";
|
||||||
|
return { headline, source, summary, url, image };
|
||||||
|
}
|
||||||
|
|
@ -1,24 +1,28 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import CardRenderer from "../Cards/CardRenderer";
|
||||||
function getKmFromPost(post) {
|
import { cardTokens } from "../../theme/cardTokens";
|
||||||
return post.km ?? post.distance_km ?? post.distanceKm ?? post.dist_km ?? null;
|
import { getTemplateSpecForPost, adaptPostToTemplateData } from "../Map/templateSpecs";
|
||||||
}
|
|
||||||
|
|
||||||
export default function PostCard({ post, selected, onSelect }) {
|
export default function PostCard({ post, selected, onSelect }) {
|
||||||
const title = post.title || post.name || "Post";
|
const spec = getTemplateSpecForPost(post, "mini");
|
||||||
const fullBody = post.body || post.content || post.text || "";
|
const data = adaptPostToTemplateData(post);
|
||||||
const body = fullBody.length > 80 ? fullBody.slice(0, 77) + "..." : fullBody;
|
|
||||||
const km = getKmFromPost(post);
|
|
||||||
|
|
||||||
function handleClick() {
|
|
||||||
if (onSelect) onSelect(post);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={"post-card" + (selected ? " selected" : "")} onClick={handleClick}>
|
<article
|
||||||
<h3>{title}</h3>
|
className={"post-card" + (selected ? " selected" : "")}
|
||||||
<p>{body}</p>
|
onClick={() => onSelect && onSelect(post)}
|
||||||
{km != null && <span className="post-km">{km} km</span>}
|
style={{ padding: 6 }}
|
||||||
|
>
|
||||||
|
<div className="sw-wall-mini">
|
||||||
|
<CardRenderer
|
||||||
|
spec={spec}
|
||||||
|
data={data}
|
||||||
|
themeTokens={cardTokens.blue}
|
||||||
|
onAction={(action, value) => {
|
||||||
|
if (action?.type === "open_url" && value) window.open(value, "_blank");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</article>
|
</article>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
.app-root { height: 100vh; display: flex; flex-direction: column; }
|
.app-root{ min-height:100vh; display:flex; flex-direction:column; }
|
||||||
.main-shell { flex: 1; display: flex; padding: 0; }
|
|
||||||
.map-shell { position: relative; flex: 1; border-radius: 0; overflow: hidden; border: none; background: #020617; }
|
/* IMPORTANT: allow scrolling under the map */
|
||||||
|
.main-shell{ flex: 0 0 auto; display:block; padding:0; }
|
||||||
|
.map-shell{ position:relative; width:100%; height:62vh; border-radius:0; overflow:hidden; border:none; background:#020617; }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,19 @@
|
||||||
.map-view { position: relative; width: 100%; height: 100%; }
|
.map-page { display: flex; flex-direction: column; }
|
||||||
.map-container, .maplibre-container { position: absolute; inset: 0; width: 100%; height: 100%; }
|
|
||||||
|
/* Map stage (visible first). Then you scroll down for the wall. */
|
||||||
|
.map-stage {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: clamp(520px, 72vh, 860px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-container, .maplibre-container {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.map-status {
|
.map-status {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0.5rem;
|
left: 0.5rem;
|
||||||
|
|
@ -8,4 +22,21 @@
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
background: rgba(0, 0, 0, 0.6);
|
background: rgba(0, 0, 0, 0.6);
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
|
z-index: 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Below map area */
|
||||||
|
.below-stage{
|
||||||
|
padding: 0.25rem 0.7rem 1.0rem;
|
||||||
|
}
|
||||||
|
.below-row{
|
||||||
|
display:flex;
|
||||||
|
gap:.6rem;
|
||||||
|
align-items:stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile: stack */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
.map-stage{ height: clamp(520px, 78vh, 900px); }
|
||||||
|
.below-row{ flex-direction: column; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,3 +88,548 @@
|
||||||
border-top:11px solid rgba(8, 20, 40, 0.97);
|
border-top:11px solid rgba(8, 20, 40, 0.97);
|
||||||
filter: drop-shadow(0 2px 4px rgba(0,0,0,.8));
|
filter: drop-shadow(0 2px 4px rgba(0,0,0,.8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== Template marker wrappers (pointers stay the same classes) ===== */
|
||||||
|
.sw-template-mini-wrap{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
transform: translate(-50%, calc(-100% - 12px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-shell{
|
||||||
|
padding: 10px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-top{
|
||||||
|
display:flex;
|
||||||
|
gap:10px;
|
||||||
|
align-items:flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-left{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-right{
|
||||||
|
width: 150px;
|
||||||
|
min-width: 140px;
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-title{
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 800;
|
||||||
|
color:#bfdbfe;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .06em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-list{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-item{
|
||||||
|
font-size: 11px;
|
||||||
|
color:#e8f5ff;
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-msg{
|
||||||
|
opacity:.85;
|
||||||
|
margin-top:2px;
|
||||||
|
font-size: 10px;
|
||||||
|
color:#c7e3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-add-feed-btn{
|
||||||
|
margin-top: 2px;
|
||||||
|
border: 1px solid rgba(148,163,184,.7);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
background: rgba(5, 35, 70, 0.85);
|
||||||
|
color:#e8f5ff;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-generated{
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-title{
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 900;
|
||||||
|
color:#e8f5ff;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-sub{
|
||||||
|
font-size: 10px;
|
||||||
|
color:#9eb7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-actions-row{
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat{
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-title{
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing:.04em;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-body{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:3px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
opacity:.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-chat-line{
|
||||||
|
font-size: 10px;
|
||||||
|
color:#c7e3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-inputrow{
|
||||||
|
display:flex;
|
||||||
|
gap:8px;
|
||||||
|
align-items:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-input{
|
||||||
|
flex:1;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
color:#e8f5ff;
|
||||||
|
padding: 8px 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-post{
|
||||||
|
border:none;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: rgba(56,189,248,0.22);
|
||||||
|
color:#e8f5ff;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Template marker wrappers (pointers stay the same classes) ===== */
|
||||||
|
.sw-template-mini-wrap{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
transform: translate(-50%, calc(-100% - 12px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-shell{
|
||||||
|
padding: 10px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-top{
|
||||||
|
display:flex;
|
||||||
|
gap:10px;
|
||||||
|
align-items:flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-left{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-right{
|
||||||
|
width: 150px;
|
||||||
|
min-width: 140px;
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-title{
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 800;
|
||||||
|
color:#bfdbfe;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .06em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-list{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-item{
|
||||||
|
font-size: 11px;
|
||||||
|
color:#e8f5ff;
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-msg{
|
||||||
|
opacity:.85;
|
||||||
|
margin-top:2px;
|
||||||
|
font-size: 10px;
|
||||||
|
color:#c7e3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-add-feed-btn{
|
||||||
|
margin-top: 2px;
|
||||||
|
border: 1px solid rgba(148,163,184,.7);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
background: rgba(5, 35, 70, 0.85);
|
||||||
|
color:#e8f5ff;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-generated{
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-title{
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 900;
|
||||||
|
color:#e8f5ff;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-sub{
|
||||||
|
font-size: 10px;
|
||||||
|
color:#9eb7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-actions-row{
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat{
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-title{
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing:.04em;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-body{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:3px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
opacity:.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-chat-line{
|
||||||
|
font-size: 10px;
|
||||||
|
color:#c7e3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-inputrow{
|
||||||
|
display:flex;
|
||||||
|
gap:8px;
|
||||||
|
align-items:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-input{
|
||||||
|
flex:1;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
color:#e8f5ff;
|
||||||
|
padding: 8px 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-post{
|
||||||
|
border:none;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: rgba(56,189,248,0.22);
|
||||||
|
color:#e8f5ff;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Template marker wrappers (pointers stay the same classes) ===== */
|
||||||
|
.sw-template-mini-wrap{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
transform: translate(-50%, calc(-100% - 12px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-shell{ padding: 10px 12px; }
|
||||||
|
|
||||||
|
.sw-expanded-top{
|
||||||
|
display:flex;
|
||||||
|
gap:10px;
|
||||||
|
align-items:flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-expanded-left{ flex: 1; }
|
||||||
|
|
||||||
|
.sw-expanded-right{
|
||||||
|
width: 150px;
|
||||||
|
min-width: 140px;
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-title{
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 800;
|
||||||
|
color:#bfdbfe;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .06em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-list{ display:flex; flex-direction:column; gap:6px; }
|
||||||
|
|
||||||
|
.sw-watch-item{
|
||||||
|
font-size: 11px;
|
||||||
|
color:#e8f5ff;
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-msg{
|
||||||
|
opacity:.85;
|
||||||
|
margin-top:2px;
|
||||||
|
font-size: 10px;
|
||||||
|
color:#c7e3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-add-feed-btn{
|
||||||
|
margin-top: 2px;
|
||||||
|
border: 1px solid rgba(148,163,184,.7);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
background: rgba(5, 35, 70, 0.85);
|
||||||
|
color:#e8f5ff;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-generated{
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-title{
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 900;
|
||||||
|
color:#e8f5ff;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-news-sub{ font-size: 10px; color:#9eb7ff; }
|
||||||
|
|
||||||
|
.sw-actions-row{ margin-top: 8px; }
|
||||||
|
|
||||||
|
.sw-livechat{ margin-top: 8px; }
|
||||||
|
|
||||||
|
.sw-livechat-title{
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing:.04em;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-body{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap:3px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
opacity:.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-chat-line{ font-size: 10px; color:#c7e3ff; }
|
||||||
|
|
||||||
|
.sw-livechat-inputrow{ display:flex; gap:8px; align-items:center; }
|
||||||
|
|
||||||
|
.sw-livechat-input{
|
||||||
|
flex:1;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid rgba(90, 190, 255, 0.35);
|
||||||
|
background: rgba(3, 14, 32, 0.75);
|
||||||
|
color:#e8f5ff;
|
||||||
|
padding: 8px 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-livechat-post{
|
||||||
|
border:none;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: rgba(56,189,248,0.22);
|
||||||
|
color:#e8f5ff;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
RESPONSIVE SIZING FIX
|
||||||
|
- Mini markers were too big (280x110 real size)
|
||||||
|
- Expanded card was overflowing on mobile
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
/* Mini template wrapper: keep pointer EXACTLY as-is, only scale the card */
|
||||||
|
.sw-template-mini-wrap{
|
||||||
|
/* was: translate(-50%, calc(-100% - 12px)) */
|
||||||
|
transform: translate(-50%, calc(-100% - 12px)) scale(var(--sw-mini-scale, 0.72));
|
||||||
|
transform-origin: bottom center;
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expanded card: make it fit phone screens nicely */
|
||||||
|
.post-pin--expanded .post-card{
|
||||||
|
max-width: min(92vw, 380px);
|
||||||
|
width: auto;
|
||||||
|
max-height: min(72vh, 640px);
|
||||||
|
overflow: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layout in expanded sketch area */
|
||||||
|
.sw-expanded-top{
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile tweaks */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
/* Shrink mini markers even more on phones */
|
||||||
|
.sw-template-mini-wrap{
|
||||||
|
--sw-mini-scale: 0.58;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expanded: stack instead of side-by-side */
|
||||||
|
.sw-expanded-top{
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right panel becomes horizontal strip (or you can hide it if you prefer) */
|
||||||
|
.sw-expanded-right{
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-title{
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-list{
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-watch-item{
|
||||||
|
min-width: 180px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sw-add-feed-btn{
|
||||||
|
flex: 0 0 auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* SW_EXPANDED_OFFSET_FIX: lower expanded cards on phones (keep pointers unchanged) */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
.post-pin--expanded .post-card{
|
||||||
|
transform: translate(-50%, calc(-100% - 6px));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* SW_MOBILE_EXPANDED_TIGHTEN: make expanded marker card less tall on phones (no pointer change) */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
.post-pin--expanded .post-card{
|
||||||
|
padding: 8px 10px;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
.post-pin--expanded .post-card-main{ gap: 6px; margin-bottom: 6px; }
|
||||||
|
.post-pin--expanded .post-card-media{ width: 56px; height: 56px; border-radius: 10px; }
|
||||||
|
.post-pin--expanded .post-card-title{ font-size: 12px; line-height: 15px; }
|
||||||
|
.post-pin--expanded .post-card-body{ font-size: 11px; max-height: 56px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SW_TEMPLATE_FULL_TIGHTEN: make template-full card less tall on phones */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
.sw-template-full{
|
||||||
|
transform: translate(-50%, calc(-100% - 14px)) scale(0.88);
|
||||||
|
transform-origin: bottom center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== MOBILE TUNING: expanded marker popup (template OR classic) ===== */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
/* shrink the whole expanded marker a bit */
|
||||||
|
.post-pin--expanded{
|
||||||
|
transform: translate3d(0,0,0) scale(0.86);
|
||||||
|
transform-origin: bottom center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keep it inside screen */
|
||||||
|
.post-pin--expanded .post-card{
|
||||||
|
max-width: min(92vw, 340px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* title/body: prevent giant blocks */
|
||||||
|
.post-pin--expanded .post-card-title{ font-size: 12px !important; line-height: 15px !important; }
|
||||||
|
.post-pin--expanded .post-card-body{ font-size: 11px !important; line-height: 14px !important; max-height: 54px !important; }
|
||||||
|
|
||||||
|
/* buttons/footer area: tighter */
|
||||||
|
.post-pin--expanded .post-card-footer{ gap: 5px !important; }
|
||||||
|
.post-pin--expanded .post-card-btn{ font-size: 10px !important; padding: 3px 7px !important; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,39 @@
|
||||||
.map-overlay-wall {
|
/* Sociowall + Chat BELOW the map */
|
||||||
position:absolute;
|
.below-row{
|
||||||
left:.7rem; right:.7rem; bottom:.6rem;
|
display:flex;
|
||||||
display:flex; gap:.6rem; align-items:stretch;
|
gap:.6rem;
|
||||||
pointer-events:none; z-index:10;
|
align-items:stretch;
|
||||||
}
|
}
|
||||||
.map-overlay-wall * { pointer-events:auto; }
|
|
||||||
|
|
||||||
.sociowall-panel {
|
.sociowall-panel {
|
||||||
flex: 1.5;
|
flex: 1.8;
|
||||||
min-height: 80px;
|
min-height: 160px;
|
||||||
max-height: 150px;
|
|
||||||
background: rgba(15, 23, 42, 0.96);
|
background: rgba(15, 23, 42, 0.96);
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
border: 1px solid rgba(148, 163, 184, 0.9);
|
border: 1px solid rgba(148, 163, 184, 0.9);
|
||||||
box-shadow: 0 10px 28px rgba(0,0,0,.9), 0 0 18px rgba(56,189,248,.45);
|
box-shadow: 0 10px 28px rgba(0,0,0,.9), 0 0 18px rgba(56,189,248,.45);
|
||||||
padding: .45rem .55rem;
|
padding: .45rem .55rem;
|
||||||
display:flex; flex-direction:column;
|
display:flex;
|
||||||
}
|
flex-direction:column;
|
||||||
.sociowall-header {
|
|
||||||
font-size: .78rem; font-weight: 600;
|
|
||||||
letter-spacing: .06em; text-transform: uppercase;
|
|
||||||
color:#bfdbfe; margin-bottom:.25rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-list { flex:1; overflow-y:auto; padding-right:.15rem; }
|
.sociowall-header {
|
||||||
.post-list-header { display:flex; align-items:center; gap:.5rem; margin-bottom:.2rem; font-size:.7rem; color:#cbd5f5; }
|
font-size: .78rem;
|
||||||
.km-filter input[type="range"] { width:130px; }
|
font-weight: 700;
|
||||||
|
letter-spacing: .06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color:#bfdbfe;
|
||||||
|
margin-bottom:.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-list { flex: 1; overflow-y: auto; padding-right: .15rem; max-height: 44vh; }
|
||||||
|
.post-list-header { display:flex; align-items:center; gap:.5rem; margin-bottom:.25rem; font-size:.7rem; color:#cbd5f5; }
|
||||||
|
.km-filter input[type="range"] { width:160px; }
|
||||||
|
|
||||||
.status-text { font-size:.72rem; opacity:.85; margin:.15rem 0; }
|
.status-text { font-size:.72rem; opacity:.85; margin:.15rem 0; }
|
||||||
.status-error { color:#fecaca; }
|
.status-error { color:#fecaca; }
|
||||||
|
|
||||||
|
/* list items compact */
|
||||||
.post-card {
|
.post-card {
|
||||||
border-radius:10px;
|
border-radius:10px;
|
||||||
border:1px solid rgba(55, 65, 81, 0.9);
|
border:1px solid rgba(55, 65, 81, 0.9);
|
||||||
|
|
@ -53,28 +58,41 @@
|
||||||
.post-card h3 { margin:0 0 .12rem 0; font-size:.8rem; }
|
.post-card h3 { margin:0 0 .12rem 0; font-size:.8rem; }
|
||||||
.post-card p { margin:0; font-size:.72rem; opacity:.9; }
|
.post-card p { margin:0; font-size:.72rem; opacity:.9; }
|
||||||
|
|
||||||
.post-km {
|
|
||||||
display:inline-block; margin-top:.12rem; font-size:.68rem;
|
|
||||||
padding:.05rem .35rem; border-radius:999px;
|
|
||||||
background: rgba(15, 118, 110, 0.2);
|
|
||||||
border: 1px solid rgba(45, 212, 191, 0.7);
|
|
||||||
color: #a5f3fc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-panel {
|
.chat-panel {
|
||||||
width:150px; min-width:130px;
|
width: 170px;
|
||||||
max-height:150px;
|
min-width: 170px;
|
||||||
background: rgba(15, 23, 42, 0.96);
|
background: rgba(15, 23, 42, 0.96);
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
border: 1px solid rgba(148, 163, 184, 0.9);
|
border: 1px solid rgba(148, 163, 184, 0.9);
|
||||||
box-shadow: 0 10px 28px rgba(0,0,0,.9), 0 0 18px rgba(56,189,248,.45);
|
box-shadow: 0 10px 28px rgba(0,0,0,.9), 0 0 18px rgba(56,189,248,.45);
|
||||||
padding:.4rem .45rem;
|
padding:.4rem .45rem;
|
||||||
display:flex; flex-direction:column;
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
|
||||||
|
/* stays visible beside wall while scrolling inside the list */
|
||||||
|
position: sticky;
|
||||||
|
top: 10px;
|
||||||
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-header {
|
.chat-header {
|
||||||
font-size:.78rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
|
font-size:.78rem;
|
||||||
color:#bfdbfe; margin-bottom:.2rem;
|
font-weight:700;
|
||||||
|
letter-spacing:.06em;
|
||||||
|
text-transform:uppercase;
|
||||||
|
color:#bfdbfe;
|
||||||
|
margin-bottom:.2rem;
|
||||||
}
|
}
|
||||||
.chat-users { list-style:none; padding:0; margin:0; font-size:.76rem; }
|
.chat-users { list-style:none; padding:0; margin:0; font-size:.76rem; }
|
||||||
.chat-users li { display:flex; align-items:center; gap:.3rem; padding:.18rem .1rem; }
|
.chat-users li { display:flex; align-items:center; gap:.3rem; padding:.18rem .1rem; }
|
||||||
.chat-users li::before { content:"👤"; font-size:.72rem; opacity:.9; }
|
.chat-users li::before { content:"👤"; font-size:.72rem; opacity:.9; }
|
||||||
|
|
||||||
|
/* Mobile: stack */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
.below-row{ flex-direction: column; }
|
||||||
|
.chat-panel{ width: 100%; min-width: 0; position: static; }
|
||||||
|
.post-list{ max-height: 46vh; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Guard: never render Sociowall overlay on top of the map */
|
||||||
|
.map-overlay-wall{ display:none !important; }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue