@@ -98,10 +98,10 @@ function LoginFormInline({ saveAuth, onClose, onSwitch }) {
|
|||||||
|
|
||||||
<SubmitButton loading={loading} label={t('auth.login')} />
|
<SubmitButton loading={loading} label={t('auth.login')} />
|
||||||
|
|
||||||
<p style={{textAlign: "center", marginTop: 14, color: "rgba(255,255,255,.45)", fontSize: ".85rem"}}>
|
<p style={{textAlign: "center", marginTop: 14, color: "var(--muted)", fontSize: ".85rem"}}>
|
||||||
{t('auth.noAccount')}{" "}
|
{t('auth.noAccount')}{" "}
|
||||||
<button onClick={onSwitch}
|
<button onClick={onSwitch}
|
||||||
style={{background: "none", border: "none", color: "#2de0c8", cursor: "pointer", fontWeight: 700, fontSize: ".85rem", fontFamily: "var(--font)",}}
|
style={{background: "none", border: "none", color: "var(--teal)", cursor: "pointer", fontWeight: 700, fontSize: ".85rem", fontFamily: "var(--font)",}}
|
||||||
>
|
>
|
||||||
{t('auth.register')}
|
{t('auth.register')}
|
||||||
</button>
|
</button>
|
||||||
@@ -216,10 +216,10 @@ function RegisterFormInline({ saveAuth, onClose, onSwitch }) {
|
|||||||
|
|
||||||
<SubmitButton loading={loading} label={t('auth.createAccountBtn')} />
|
<SubmitButton loading={loading} label={t('auth.createAccountBtn')} />
|
||||||
|
|
||||||
<p style={{textAlign: "center", marginTop: 14, color: "rgba(255,255,255,.45)", fontSize: ".85rem"}}>
|
<p style={{textAlign: "center", marginTop: 14, color: "var(--muted)", fontSize: ".85rem"}}>
|
||||||
{t('auth.hasAccount')}{" "}
|
{t('auth.hasAccount')}{" "}
|
||||||
<button onClick={onSwitch}
|
<button onClick={onSwitch}
|
||||||
style={{background: "none", border: "none", color: "#2de0c8", cursor: "pointer", fontWeight: 700, fontSize: ".85rem", fontFamily: "var(--font)",}}>
|
style={{background: "none", border: "none", color: "var(--teal)", cursor: "pointer", fontWeight: 700, fontSize: ".85rem", fontFamily: "var(--font)",}}>
|
||||||
{t('auth.loginLink')}
|
{t('auth.loginLink')}
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,14 +1,89 @@
|
|||||||
|
import { useState } from "react";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import ProfileAvatar from "./profile/ProfileAvatar";
|
||||||
|
|
||||||
export default function RightSidebar() {
|
function FollowButton() {
|
||||||
|
const [following, setFollowing] = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<button className="f-right-action-btn" onClick={() => setFollowing(f => !f)}>
|
||||||
|
{following ? t('rightSidebar.following') : t('rightSidebar.subscribe')}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RightSidebar({ ads, profileData, isAuthenticated, onProfileClick, onLoginClick, onNavClick }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const suggestions = [...(ads || [])]
|
||||||
|
.sort((a, b) => (b.likeCount || 0) - (a.likeCount || 0))
|
||||||
|
.slice(0, 4);
|
||||||
|
|
||||||
|
const profileName = isAuthenticated
|
||||||
|
? `${profileData?.firstName || ""} ${profileData?.lastName || ""}`.trim() || profileData?.login
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="f-right">
|
<div className="f-right">
|
||||||
<div className="f-right-label">{t('rightSidebar.advertisement')}</div>
|
<div className="f-right-profile">
|
||||||
<div className="f-right-empty">
|
{isAuthenticated ? (
|
||||||
<div className="f-right-empty-icon">📢</div>
|
<>
|
||||||
<div className="f-right-empty-text" dangerouslySetInnerHTML={{ __html: t('rightSidebar.emptyText') }} />
|
<ProfileAvatar avatar={profileData?.avatar} name={profileName} />
|
||||||
<button className="f-add-promo-btn">{t('rightSidebar.addAd')}</button>
|
<div className="f-right-profile-info">
|
||||||
|
<div className="f-right-profile-name">{profileName}</div>
|
||||||
|
<div className="f-right-profile-sub">{profileData?.login}</div>
|
||||||
|
</div>
|
||||||
|
<button className="f-right-action-btn" onClick={onProfileClick}>
|
||||||
|
{t('rightSidebar.yourProfile')}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="f-ig-ring">
|
||||||
|
<div className="f-ig-avatar">👤</div>
|
||||||
|
</div>
|
||||||
|
<div className="f-right-profile-info">
|
||||||
|
<div className="f-right-profile-name">{t('rightSidebar.guest')}</div>
|
||||||
|
<div className="f-right-profile-sub">{t('rightSidebar.guestSub')}</div>
|
||||||
|
</div>
|
||||||
|
<button className="f-right-action-btn" onClick={onLoginClick}>
|
||||||
|
{t('feed.login')}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="f-right-header">
|
||||||
|
<span className="f-right-label">{t('rightSidebar.suggestions')}</span>
|
||||||
|
<button className="f-right-link" onClick={() => onNavClick?.("home")}>
|
||||||
|
{t('rightSidebar.all')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{suggestions.length === 0 && (
|
||||||
|
<div className="f-right-suggest-sub">{t('rightSidebar.empty')}</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{suggestions.map(ad => (
|
||||||
|
<div className="f-right-suggest" key={ad.id}>
|
||||||
|
<div className="f-ig-ring f-ig-ring-sm">
|
||||||
|
<div className="f-ig-avatar">{ad.emoji || "📋"}</div>
|
||||||
|
</div>
|
||||||
|
<div className="f-right-suggest-info">
|
||||||
|
<div className="f-right-suggest-name">{ad.title}</div>
|
||||||
|
<div className="f-right-suggest-sub">
|
||||||
|
{ad.city || (ad.type === "loss" ? t('postCard.loss') : t('postCard.found'))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FollowButton />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div className="f-right-foot">
|
||||||
|
<span>© {new Date().getFullYear()} {t('app.name')}</span>
|
||||||
|
<span>{t('rightSidebar.footRules')}</span>
|
||||||
|
<span>{t('rightSidebar.footPrivacy')}</span>
|
||||||
|
<span>{t('rightSidebar.footSupport')}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { useUnread } from "../context/UnreadContext";
|
|||||||
import { useLanguageToggle } from "../hooks/useLanguageToggle";
|
import { useLanguageToggle } from "../hooks/useLanguageToggle";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import SupportModal from "./SupportModal";
|
import SupportModal from "./SupportModal";
|
||||||
|
import ProfileAvatar from "./profile/ProfileAvatar";
|
||||||
|
|
||||||
export default function Sidebar({
|
export default function Sidebar({
|
||||||
open,
|
open,
|
||||||
@@ -21,6 +22,9 @@ export default function Sidebar({
|
|||||||
onLoginClick,
|
onLoginClick,
|
||||||
onRulesClick,
|
onRulesClick,
|
||||||
onReviewsClick,
|
onReviewsClick,
|
||||||
|
onCreatePost,
|
||||||
|
onProfileClick,
|
||||||
|
profileData,
|
||||||
}) {
|
}) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { theme, toggle: toggleTheme } = useTheme();
|
const { theme, toggle: toggleTheme } = useTheme();
|
||||||
@@ -28,6 +32,35 @@ export default function Sidebar({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { language, toggleLanguage } = useLanguageToggle();
|
const { language, toggleLanguage } = useLanguageToggle();
|
||||||
const [supportOpen, setSupportOpen] = useState(false);
|
const [supportOpen, setSupportOpen] = useState(false);
|
||||||
|
const HelpIcon = NavIcons.help;
|
||||||
|
|
||||||
|
const handleNavItem = (itemKey) => {
|
||||||
|
if (!isAuthenticated && itemKey === "myads") {
|
||||||
|
onLoginClick();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (itemKey === "chat") {
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
onLoginClick();
|
||||||
|
} else {
|
||||||
|
navigate("/chats");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (itemKey === "create") {
|
||||||
|
onCreatePost?.();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onNavClick(itemKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleProfileClick = () => {
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
onLoginClick();
|
||||||
|
} else {
|
||||||
|
onProfileClick?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -40,27 +73,15 @@ export default function Sidebar({
|
|||||||
<nav className="f-sb-nav">
|
<nav className="f-sb-nav">
|
||||||
{NAV_ITEMS.map(({ icon, key: itemKey, labelKey }) => {
|
{NAV_ITEMS.map(({ icon, key: itemKey, labelKey }) => {
|
||||||
const Ic = NavIcons[icon];
|
const Ic = NavIcons[icon];
|
||||||
const handleClick = () => {
|
|
||||||
// «Мои объявления» требует авторизации
|
|
||||||
if (!isAuthenticated && itemKey === "myads") {
|
|
||||||
onLoginClick();
|
|
||||||
} else if (itemKey === "chat") {
|
|
||||||
if (!isAuthenticated) {
|
|
||||||
onLoginClick();
|
|
||||||
} else {
|
|
||||||
navigate("/chats");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onNavClick(itemKey);
|
|
||||||
}
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
key={itemKey}
|
key={itemKey}
|
||||||
className={`f-sb-item${activeNav === itemKey ? " active" : ""}`}
|
className={`f-sb-item${activeNav === itemKey ? " active" : ""}${itemKey === "create" ? " f-sb-create" : ""}`}
|
||||||
onClick={handleClick}
|
onClick={() => {
|
||||||
|
handleNavItem(itemKey);
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Ic /> {t(labelKey)}
|
<Ic /> {t(labelKey)}
|
||||||
{itemKey === "chat" && totalUnread > 0 && (
|
{itemKey === "chat" && totalUnread > 0 && (
|
||||||
@@ -99,17 +120,37 @@ export default function Sidebar({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<button type="button" className="f-sb-item" onClick={() => setSupportOpen(true)}>
|
<button type="button" className="f-sb-item" onClick={() => setSupportOpen(true)}>
|
||||||
<NavIcons.help /> {t('nav.support')}
|
<HelpIcon /> {t('nav.support')} </button>
|
||||||
</button>
|
|
||||||
<div className="f-sb-divider" />
|
<div className="f-sb-divider" />
|
||||||
<button type="button" className="f-sb-item f-sb-theme-toggle" onClick={toggleTheme}>
|
<button type="button" className="f-sb-item" onClick={toggleTheme}>
|
||||||
{theme === "dark" ? <SunIcon /> : <MoonIcon />}
|
{theme === "dark" ? <SunIcon /> : <MoonIcon />}
|
||||||
{theme === "dark" ? t('sidebar.lightTheme') : t('sidebar.darkTheme')}
|
{theme === "dark" ? t('sidebar.lightTheme') : t('sidebar.darkTheme')}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" className="f-sb-item f-sb-lang-toggle" onClick={toggleLanguage}>
|
<button type="button" className="f-sb-item" onClick={toggleLanguage}>
|
||||||
<GlobeIcon />
|
<GlobeIcon />
|
||||||
{language === 'ru' ? 'English' : 'Русский'}
|
{language === 'ru' ? 'English' : 'Русский'}
|
||||||
</button>
|
</button>
|
||||||
|
<div className="f-sb-divider" />
|
||||||
|
<button type="button" className="f-sb-profile" onClick={handleProfileClick}>
|
||||||
|
{isAuthenticated ? (
|
||||||
|
<ProfileAvatar
|
||||||
|
avatar={profileData?.avatar}
|
||||||
|
name={`${profileData?.firstName || ""} ${profileData?.lastName || ""}`}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="f-profile-avatar-placeholder">👤</div>
|
||||||
|
)}
|
||||||
|
<div className="f-sb-profile-info">
|
||||||
|
<div className="f-sb-profile-name">
|
||||||
|
{isAuthenticated
|
||||||
|
? `${profileData?.firstName || ""} ${profileData?.lastName || ""}`.trim() || profileData?.login
|
||||||
|
: t('feed.login')}
|
||||||
|
</div>
|
||||||
|
<div className="f-sb-profile-login">
|
||||||
|
{isAuthenticated ? profileData?.login || t('profile.default') : t('auth.noAccount')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{supportOpen && <SupportModal onClose={() => setSupportOpen(false)} />}
|
{supportOpen && <SupportModal onClose={() => setSupportOpen(false)} />}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useRef } from "react";
|
|||||||
import Picker from "@emoji-mart/react";
|
import Picker from "@emoji-mart/react";
|
||||||
import emojiData from "@emoji-mart/data";
|
import emojiData from "@emoji-mart/data";
|
||||||
import { useClickOutside } from "../../hooks/useClickOutside";
|
import { useClickOutside } from "../../hooks/useClickOutside";
|
||||||
|
import { useTheme } from "../../context/ThemeContext";
|
||||||
|
|
||||||
export default function ChatInputBar({
|
export default function ChatInputBar({
|
||||||
input,
|
input,
|
||||||
@@ -16,6 +17,7 @@ export default function ChatInputBar({
|
|||||||
}) {
|
}) {
|
||||||
const emojiPickerRef = useRef(null);
|
const emojiPickerRef = useRef(null);
|
||||||
useClickOutside(emojiPickerRef, onCloseEmoji, showEmoji);
|
useClickOutside(emojiPickerRef, onCloseEmoji, showEmoji);
|
||||||
|
const { theme } = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="chat-input-area">
|
<div className="chat-input-area">
|
||||||
@@ -24,7 +26,7 @@ export default function ChatInputBar({
|
|||||||
<Picker
|
<Picker
|
||||||
data={emojiData}
|
data={emojiData}
|
||||||
onEmojiSelect={onEmojiSelect}
|
onEmojiSelect={onEmojiSelect}
|
||||||
theme="dark"
|
theme={theme}
|
||||||
previewPosition="none"
|
previewPosition="none"
|
||||||
skinTonePosition="none"
|
skinTonePosition="none"
|
||||||
searchPosition="sticky"
|
searchPosition="sticky"
|
||||||
|
|||||||
@@ -1,28 +1,10 @@
|
|||||||
import AppTopBar from "../layout/AppTopBar";
|
import AppTopBar from "../layout/AppTopBar";
|
||||||
|
|
||||||
export default function FeedTopBar({
|
export default function FeedTopBar({ onMenuClick }) {
|
||||||
onMenuClick,
|
|
||||||
onCreatePost,
|
|
||||||
isAuthenticated,
|
|
||||||
profileData,
|
|
||||||
onProfileClick,
|
|
||||||
onLoginClick,
|
|
||||||
t,
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<AppTopBar
|
<AppTopBar
|
||||||
onMenuClick={onMenuClick}
|
onMenuClick={onMenuClick}
|
||||||
isAuthenticated={isAuthenticated}
|
hideProfile
|
||||||
profileData={profileData}
|
|
||||||
onProfileClick={onProfileClick}
|
|
||||||
onLoginClick={onLoginClick}
|
|
||||||
loginLabel={t('feed.login')}
|
|
||||||
centerContent={
|
|
||||||
<button className="f-post-btn" onClick={onCreatePost}>
|
|
||||||
<span style={{ fontSize: "0.9rem", fontWeight: 900, lineHeight: 1 }}>+</span>
|
|
||||||
{t('feed.createPost')}
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -51,4 +51,11 @@ export const NavIcons = {
|
|||||||
<line x1="12" y1="17" x2="12.01" y2="17" />
|
<line x1="12" y1="17" x2="12.01" y2="17" />
|
||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
|
plus: () => (
|
||||||
|
<svg width={20} height={20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2.4} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<rect x="3" y="3" width="18" height="18" rx="6" />
|
||||||
|
<line x1="12" y1="8" x2="12" y2="16" />
|
||||||
|
<line x1="8" y1="12" x2="16" y2="12" />
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import MenuIcon from "../icons/MenuIcon";
|
import MenuIcon from "../icons/MenuIcon";
|
||||||
import ProfileAvatar from "../profile/ProfileAvatar";
|
import ProfileAvatar from "../profile/ProfileAvatar";
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Общая верхняя панель приложения: бургер-меню слева,
|
* Общая верхняя панель приложения (мобильная версия Instagram-style):
|
||||||
* произвольный контент по центру, профиль/логин справа.
|
* бургер-меню слева, название сервиса, контент по центру, профиль/логин справа.
|
||||||
*/
|
*/
|
||||||
export default function AppTopBar({
|
export default function AppTopBar({
|
||||||
onMenuClick,
|
onMenuClick,
|
||||||
@@ -13,14 +14,19 @@ export default function AppTopBar({
|
|||||||
onProfileClick,
|
onProfileClick,
|
||||||
onLoginClick,
|
onLoginClick,
|
||||||
loginLabel,
|
loginLabel,
|
||||||
|
hideProfile = false,
|
||||||
}) {
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div className="f-topbar">
|
<div className="f-topbar">
|
||||||
<button className="f-menu-btn" onClick={onMenuClick}>
|
<button className="f-menu-btn" onClick={onMenuClick}>
|
||||||
<MenuIcon />
|
<MenuIcon />
|
||||||
</button>
|
</button>
|
||||||
|
<span className="f-topbar-wordmark">{t('app.name')}</span>
|
||||||
<div className="f-topbar-center">{centerContent}</div>
|
<div className="f-topbar-center">{centerContent}</div>
|
||||||
{isAuthenticated ? (
|
{hideProfile ? (
|
||||||
|
<span className="f-topbar-spacer" />
|
||||||
|
) : isAuthenticated ? (
|
||||||
<div className="f-topbar-profile" onClick={onProfileClick}>
|
<div className="f-topbar-profile" onClick={onProfileClick}>
|
||||||
<ProfileAvatar
|
<ProfileAvatar
|
||||||
avatar={profileData.avatar}
|
avatar={profileData.avatar}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
export const NAV_ITEMS = [
|
export const NAV_ITEMS = [
|
||||||
{ icon: "grid", key: "home", labelKey: "nav.home" },
|
{ icon: "grid", key: "home", labelKey: "nav.home" },
|
||||||
{ icon: "file", key: "myads", labelKey: "nav.myAds" },
|
{ icon: "chat", key: "chat", labelKey: "nav.chat" },
|
||||||
{ icon: "box", key: "items", labelKey: "nav.items" },
|
{ icon: "box", key: "items", labelKey: "nav.items" },
|
||||||
{ icon: "paw", key: "pets", labelKey: "nav.pets" },
|
{ icon: "paw", key: "pets", labelKey: "nav.pets" },
|
||||||
{ icon: "chat", key: "chat", labelKey: "nav.chat" },
|
{ icon: "file", key: "myads", labelKey: "nav.myAds" },
|
||||||
|
{ icon: "plus", key: "create", labelKey: "nav.create" },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const NAV_BOTTOM = [
|
export const NAV_BOTTOM = [
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ const STORAGE_KEY = "theme";
|
|||||||
export function ThemeProvider({ children }) {
|
export function ThemeProvider({ children }) {
|
||||||
const [theme, setTheme] = useState(() => {
|
const [theme, setTheme] = useState(() => {
|
||||||
try {
|
try {
|
||||||
return localStorage.getItem(STORAGE_KEY) || "dark";
|
return localStorage.getItem(STORAGE_KEY) || "light";
|
||||||
} catch {
|
} catch {
|
||||||
return "dark";
|
return "light";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
"items": "Items",
|
"items": "Items",
|
||||||
"pets": "Pets",
|
"pets": "Pets",
|
||||||
"chat": "Chat",
|
"chat": "Chat",
|
||||||
|
"create": "Create",
|
||||||
|
"search": "Search",
|
||||||
|
"map": "Map",
|
||||||
|
"profile": "Profile",
|
||||||
"reviews": "Reviews",
|
"reviews": "Reviews",
|
||||||
"rules": "Platform Rules",
|
"rules": "Platform Rules",
|
||||||
"support": "Support"
|
"support": "Support"
|
||||||
@@ -126,9 +130,9 @@
|
|||||||
"createPost": "Create ad",
|
"createPost": "Create ad",
|
||||||
"login": "Log in",
|
"login": "Log in",
|
||||||
"searchPlaceholder": "Search by title or description...",
|
"searchPlaceholder": "Search by title or description...",
|
||||||
"filterLoss": "🔴 Lost",
|
"filterLoss": "Lost",
|
||||||
"filterAll": "All ads",
|
"filterAll": "All ads",
|
||||||
"filterFound": "🟢 Found",
|
"filterFound": "Found",
|
||||||
"filterCitiesPlaceholder": "Select city…",
|
"filterCitiesPlaceholder": "Select city…",
|
||||||
"filterCitiesEmpty": "No cities found",
|
"filterCitiesEmpty": "No cities found",
|
||||||
"filterCitiesAdd": "Add \"{{city}}\"",
|
"filterCitiesAdd": "Add \"{{city}}\"",
|
||||||
@@ -149,7 +153,8 @@
|
|||||||
"itemFound": "✓ Item found",
|
"itemFound": "✓ Item found",
|
||||||
"showOnMap": "Show on map — {{address}}",
|
"showOnMap": "Show on map — {{address}}",
|
||||||
"contactError": "Unable to open the chat. Please try again",
|
"contactError": "Unable to open the chat. Please try again",
|
||||||
"reward": "Reward"
|
"reward": "Reward",
|
||||||
|
"likes": "Likes: {{count}}"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"title": "Chat",
|
"title": "Chat",
|
||||||
@@ -188,7 +193,18 @@
|
|||||||
"rightSidebar": {
|
"rightSidebar": {
|
||||||
"advertisement": "Advertisement",
|
"advertisement": "Advertisement",
|
||||||
"emptyText": "Your ad<br />could be here",
|
"emptyText": "Your ad<br />could be here",
|
||||||
"addAd": "+ Add advertisement"
|
"addAd": "+ Add advertisement",
|
||||||
|
"suggestions": "Suggestions for you",
|
||||||
|
"all": "See all",
|
||||||
|
"subscribe": "Follow",
|
||||||
|
"following": "Following",
|
||||||
|
"yourProfile": "Your profile",
|
||||||
|
"guest": "Guest",
|
||||||
|
"guestSub": "Log in to open your profile",
|
||||||
|
"empty": "No ads yet",
|
||||||
|
"footRules": "Rules",
|
||||||
|
"footPrivacy": "Privacy",
|
||||||
|
"footSupport": "Support"
|
||||||
},
|
},
|
||||||
"landing": {
|
"landing": {
|
||||||
"eyebrow": "Service for finding lost pets and items",
|
"eyebrow": "Service for finding lost pets and items",
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
"items": "Вещи",
|
"items": "Вещи",
|
||||||
"pets": "Питомцы",
|
"pets": "Питомцы",
|
||||||
"chat": "Чат",
|
"chat": "Чат",
|
||||||
|
"create": "Создать",
|
||||||
|
"search": "Поиск",
|
||||||
|
"map": "Карта",
|
||||||
|
"profile": "Профиль",
|
||||||
"reviews": "Отзывы",
|
"reviews": "Отзывы",
|
||||||
"rules": "Правила площадки",
|
"rules": "Правила площадки",
|
||||||
"support": "Поддержка"
|
"support": "Поддержка"
|
||||||
@@ -127,9 +131,9 @@
|
|||||||
"createPost": "Разместить объявление",
|
"createPost": "Разместить объявление",
|
||||||
"login": "Войти",
|
"login": "Войти",
|
||||||
"searchPlaceholder": "Поиск по названию или описанию...",
|
"searchPlaceholder": "Поиск по названию или описанию...",
|
||||||
"filterLoss": "🔴 Потери",
|
"filterLoss": "Потери",
|
||||||
"filterAll": "Все объявления",
|
"filterAll": "Все объявления",
|
||||||
"filterFound": "🟢 Находки",
|
"filterFound": "Находки",
|
||||||
"filterCitiesPlaceholder": "Выберите город…",
|
"filterCitiesPlaceholder": "Выберите город…",
|
||||||
"filterCitiesEmpty": "Города не найдены",
|
"filterCitiesEmpty": "Города не найдены",
|
||||||
"filterCitiesAdd": "Добавить «{{city}}»",
|
"filterCitiesAdd": "Добавить «{{city}}»",
|
||||||
@@ -150,7 +154,8 @@
|
|||||||
"itemFound": "✓ Вещь найдена",
|
"itemFound": "✓ Вещь найдена",
|
||||||
"showOnMap": "Показать на карте — {{address}}",
|
"showOnMap": "Показать на карте — {{address}}",
|
||||||
"contactError": "Не удалось открыть чат. Попробуйте ещё раз",
|
"contactError": "Не удалось открыть чат. Попробуйте ещё раз",
|
||||||
"reward": "Вознаграждение"
|
"reward": "Вознаграждение",
|
||||||
|
"likes": "Нравится: {{count}}"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"title": "Чат",
|
"title": "Чат",
|
||||||
@@ -189,7 +194,18 @@
|
|||||||
"rightSidebar": {
|
"rightSidebar": {
|
||||||
"advertisement": "Реклама",
|
"advertisement": "Реклама",
|
||||||
"emptyText": "Здесь будет<br />ваша реклама",
|
"emptyText": "Здесь будет<br />ваша реклама",
|
||||||
"addAd": "+ Добавить рекламу"
|
"addAd": "+ Добавить рекламу",
|
||||||
|
"suggestions": "Рекомендации для вас",
|
||||||
|
"all": "Все",
|
||||||
|
"subscribe": "Подписаться",
|
||||||
|
"following": "Подписано",
|
||||||
|
"yourProfile": "Ваш профиль",
|
||||||
|
"guest": "Гость",
|
||||||
|
"guestSub": "Войдите, чтобы открыть профиль",
|
||||||
|
"empty": "Объявлений пока нет",
|
||||||
|
"footRules": "Правила",
|
||||||
|
"footPrivacy": "Конфиденциальность",
|
||||||
|
"footSupport": "Поддержка"
|
||||||
},
|
},
|
||||||
"landing": {
|
"landing": {
|
||||||
"eyebrow": "Сервис поиска пропавших питомцев и вещей",
|
"eyebrow": "Сервис поиска пропавших питомцев и вещей",
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { useState, useEffect, useCallback, useMemo } from "react";
|
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
||||||
import { useNavigate, useLocation } from "react-router-dom";
|
import { useNavigate, useLocation } from "react-router-dom";
|
||||||
import "../styles/index.css";
|
import "../styles/index.css";
|
||||||
import { getImageUrl } from "../config/authConstants";
|
import { getImageUrl } from "../config/authConstants";
|
||||||
import Sidebar from "../components/Sidebar";
|
import Sidebar from "../components/Sidebar";
|
||||||
|
import BottomNav from "../components/nav/BottomNav";
|
||||||
import RightSidebar from "../components/RightSidebar";
|
import RightSidebar from "../components/RightSidebar";
|
||||||
import CreateUpdatePost from "./CreateUpdatePost";
|
import CreateUpdatePost from "./CreateUpdatePost";
|
||||||
import ImageViewer from "../components/ImageViewer";
|
import ImageViewer from "../components/ImageViewer";
|
||||||
@@ -45,6 +46,11 @@ export default function MainFeed() {
|
|||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
const [liked, setLiked] = useState(new Set());
|
const [liked, setLiked] = useState(new Set());
|
||||||
|
|
||||||
|
const feedRef = useRef(null);
|
||||||
|
|
||||||
|
const isSearchView = new URLSearchParams(location.search).get("view") === "search";
|
||||||
|
const hasActiveFilters = searchQuery.trim().length > 0 || selectedCities.length > 0;
|
||||||
|
|
||||||
const feed = useFeedPosts();
|
const feed = useFeedPosts();
|
||||||
const myPosts = useMyPosts(user?.id);
|
const myPosts = useMyPosts(user?.id);
|
||||||
const cityFeed = useCityFeed(selectedCities);
|
const cityFeed = useCityFeed(selectedCities);
|
||||||
@@ -135,6 +141,28 @@ export default function MainFeed() {
|
|||||||
else modals.open("edit", ad);
|
else modals.open("edit", ad);
|
||||||
}, [isAuthenticated, modals]);
|
}, [isAuthenticated, modals]);
|
||||||
|
|
||||||
|
const handleHomeClick = useCallback(() => {
|
||||||
|
setActiveNav("home");
|
||||||
|
if (isSearchView) navigate("/feed");
|
||||||
|
feedRef.current?.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
|
}, [isSearchView, navigate]);
|
||||||
|
|
||||||
|
const handleSearchClick = useCallback(() => {
|
||||||
|
setActiveNav("home");
|
||||||
|
setSearchQuery("");
|
||||||
|
setSelectedCities([]);
|
||||||
|
if (!isSearchView) navigate("/feed?view=search");
|
||||||
|
feedRef.current?.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
|
}, [isSearchView, navigate]);
|
||||||
|
|
||||||
|
// Карта с объявлениями — иконка добавлена, функционал ещё не реализован
|
||||||
|
const handleMapClick = useCallback(() => {}, []);
|
||||||
|
|
||||||
|
const handleProfileClick = useCallback(() => {
|
||||||
|
if (!isAuthenticated) modals.open("auth");
|
||||||
|
else modals.open("profile");
|
||||||
|
}, [isAuthenticated, modals]);
|
||||||
|
|
||||||
const filteredAds = useMemo(() => {
|
const filteredAds = useMemo(() => {
|
||||||
let result;
|
let result;
|
||||||
if (activeNav === "myads") {
|
if (activeNav === "myads") {
|
||||||
@@ -161,7 +189,7 @@ export default function MainFeed() {
|
|||||||
const listError = activeNav === "myads" ? myPosts.error : feed.error;
|
const listError = activeNav === "myads" ? myPosts.error : feed.error;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="f-app">
|
<div className={`f-app${isSearchView ? " f-search-view" : ""}`}>
|
||||||
<Sidebar
|
<Sidebar
|
||||||
open={sidebarOpen}
|
open={sidebarOpen}
|
||||||
activeNav={activeNav}
|
activeNav={activeNav}
|
||||||
@@ -171,19 +199,15 @@ export default function MainFeed() {
|
|||||||
onLoginClick={() => modals.open("auth")}
|
onLoginClick={() => modals.open("auth")}
|
||||||
onRulesClick={() => modals.open("rules")}
|
onRulesClick={() => modals.open("rules")}
|
||||||
onReviewsClick={() => navigate("/reviews")}
|
onReviewsClick={() => navigate("/reviews")}
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="f-main">
|
|
||||||
<FeedTopBar
|
|
||||||
onMenuClick={() => setSidebarOpen(v => !v)}
|
|
||||||
onCreatePost={handleCreatePost}
|
onCreatePost={handleCreatePost}
|
||||||
isAuthenticated={isAuthenticated}
|
|
||||||
profileData={profileData}
|
|
||||||
onProfileClick={() => modals.open("profile")}
|
onProfileClick={() => modals.open("profile")}
|
||||||
onLoginClick={() => modals.open("auth")}
|
profileData={profileData}
|
||||||
t={t}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div className="f-main f-main-feed">
|
||||||
|
<FeedTopBar onMenuClick={() => setSidebarOpen(v => !v)} />
|
||||||
|
|
||||||
|
<div className="f-search-panel">
|
||||||
<FeedSearchBar value={searchQuery} onChange={setSearchQuery} t={t} />
|
<FeedSearchBar value={searchQuery} onChange={setSearchQuery} t={t} />
|
||||||
|
|
||||||
{activeNav === "home" && (
|
{activeNav === "home" && (
|
||||||
@@ -191,11 +215,12 @@ export default function MainFeed() {
|
|||||||
<CityFilter cities={cities} value={selectedCities} onChange={setSelectedCities} />
|
<CityFilter cities={cities} value={selectedCities} onChange={setSelectedCities} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<TypeFilterBar value={typeFilter} onChange={setTypeFilter} t={t} />
|
<TypeFilterBar value={typeFilter} onChange={setTypeFilter} t={t} />
|
||||||
|
|
||||||
<div className="f-wrap">
|
<div className="f-wrap">
|
||||||
<div className="f-feed">
|
<div className="f-feed" ref={feedRef}>
|
||||||
<FeedContent
|
<FeedContent
|
||||||
loading={listLoading}
|
loading={listLoading}
|
||||||
cityLoading={cityFeed.cityLoading}
|
cityLoading={cityFeed.cityLoading}
|
||||||
@@ -221,7 +246,14 @@ export default function MainFeed() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<RightSidebar />
|
<RightSidebar
|
||||||
|
ads={filteredAds}
|
||||||
|
profileData={profileData}
|
||||||
|
isAuthenticated={isAuthenticated}
|
||||||
|
onProfileClick={() => modals.open("profile")}
|
||||||
|
onLoginClick={() => modals.open("auth")}
|
||||||
|
onNavClick={setActiveNav}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -253,6 +285,18 @@ export default function MainFeed() {
|
|||||||
postData={modals.modal.payload.ad}
|
postData={modals.modal.payload.ad}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<BottomNav
|
||||||
|
activeTab={isSearchView ? "search" : "home"}
|
||||||
|
hasFilters={hasActiveFilters}
|
||||||
|
profileData={profileData}
|
||||||
|
onHome={handleHomeClick}
|
||||||
|
onMap={handleMapClick}
|
||||||
|
onCreatePost={handleCreatePost}
|
||||||
|
onSearch={handleSearchClick}
|
||||||
|
onProfile={handleProfileClick}
|
||||||
|
t={t}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import {useRef, useState} from "react";
|
import {useRef, useState, useEffect} from "react";
|
||||||
import PinIcon from "../components/icons/PinIcon";
|
import PinIcon from "../components/icons/PinIcon";
|
||||||
import CalendarIcon from "../components/icons/CalendarIcon";
|
import CalendarIcon from "../components/icons/CalendarIcon";
|
||||||
import PhoneIcon from "../components/icons/PhoneIcon";
|
import PhoneIcon from "../components/icons/PhoneIcon";
|
||||||
@@ -14,10 +14,31 @@ import {useTranslation} from 'react-i18next';
|
|||||||
export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMarkFound, isOwner, onImageClick, onAuthRequired }) {
|
export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMarkFound, isOwner, onImageClick, onAuthRequired }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [showCalendar, setShowCalendar] = useState(false);
|
const [showCalendar, setShowCalendar] = useState(false);
|
||||||
|
const [titleExpanded, setTitleExpanded] = useState(false);
|
||||||
|
const [descExpanded, setDescExpanded] = useState(false);
|
||||||
|
const [titleTruncated, setTitleTruncated] = useState(false);
|
||||||
|
const [descTruncated, setDescTruncated] = useState(false);
|
||||||
const dateAnchorRef = useRef(null);
|
const dateAnchorRef = useRef(null);
|
||||||
|
const titleRef = useRef(null);
|
||||||
|
const descRef = useRef(null);
|
||||||
const { isAuthenticated } = useAuthContext();
|
const { isAuthenticated } = useAuthContext();
|
||||||
const { contactSeller, error: contactError, clearError } = useContactSeller(ad);
|
const { contactSeller, error: contactError, clearError } = useContactSeller(ad);
|
||||||
|
|
||||||
|
// Определяем, обрезан ли title/description (тремя точками), и реагируем на ресайз
|
||||||
|
useEffect(() => {
|
||||||
|
const check = () => {
|
||||||
|
if (!titleExpanded && titleRef.current) {
|
||||||
|
setTitleTruncated(titleRef.current.scrollWidth > titleRef.current.clientWidth + 1);
|
||||||
|
}
|
||||||
|
if (!descExpanded && descRef.current) {
|
||||||
|
setDescTruncated(descRef.current.scrollHeight > descRef.current.clientHeight + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
check();
|
||||||
|
window.addEventListener("resize", check);
|
||||||
|
return () => window.removeEventListener("resize", check);
|
||||||
|
}, [titleExpanded, descExpanded]);
|
||||||
|
|
||||||
const handleContact = (e) => {
|
const handleContact = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
@@ -35,57 +56,91 @@ export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMark
|
|||||||
|
|
||||||
const isClosed = ad.status === 'CLOSED';
|
const isClosed = ad.status === 'CLOSED';
|
||||||
|
|
||||||
const roleClass = ad.userRole === 'LOST_AND_FOUND' ? 'f-card-role-lost-found'
|
const typeBadge = (
|
||||||
: ad.userRole === 'METRO' ? 'f-card-role-metro' : '';
|
<div className={`f-type-badge ${ad.type === "loss" ? "f-type-loss" : "f-type-found"}`}>
|
||||||
|
{ad.type === "loss" ? t('postCard.loss') : t('postCard.found')}
|
||||||
const roleBadge = ad.userRole === 'LOST_AND_FOUND' ? (
|
|
||||||
<div className="f-role-badge f-role-lost-found" title={t('postCard.lostFoundBureau')}>
|
|
||||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
|
||||||
<circle cx="12" cy="12" r="10"/>
|
|
||||||
<path d="M12 6v6l4 2"/>
|
|
||||||
</svg>
|
|
||||||
{t('postCard.lostFoundBureau')}
|
|
||||||
</div>
|
</div>
|
||||||
) : ad.userRole === 'METRO' ? (
|
);
|
||||||
<div className="f-role-badge f-role-metro" title={t('postCard.metro')}>
|
|
||||||
<span className="f-role-metro-letter">М</span>
|
|
||||||
{t('postCard.metro')}
|
|
||||||
</div>
|
|
||||||
) : null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`f-card${isClosed ? ' f-card-closed' : ''}${roleClass ? ' ' + roleClass : ''}`}>
|
<div className={`f-card${isClosed ? ' f-card-closed' : ''}`}>
|
||||||
|
|
||||||
<div className="f-card-inner">
|
<div className="f-card-head">
|
||||||
<div className="f-card-img" onClick={e => { e.stopPropagation(); if (onImageClick) onImageClick(ad.images, 0, ad); }}>
|
<div className="f-card-author">
|
||||||
{ad.reward && (
|
<div
|
||||||
<div className="f-card-reward">
|
ref={titleRef}
|
||||||
💰 {t("postCard.reward")}
|
className={`f-card-author-name${titleTruncated ? " f-truncatable" : ""}${titleExpanded ? " f-expanded" : ""}`}
|
||||||
|
onClick={titleTruncated ? () => setTitleExpanded(v => !v) : undefined}
|
||||||
|
>
|
||||||
|
{ad.title}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="f-card-head-side">
|
||||||
|
{typeBadge}
|
||||||
|
{isClosed && (
|
||||||
|
<span className="f-status-badge f-status-closed">{t('postCard.foundStatus')}</span>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="f-card-img" onClick={e => { e.stopPropagation(); if (onImageClick) onImageClick(ad.images, 0, ad); }}>
|
||||||
{imageUrl
|
{imageUrl
|
||||||
? <img src={imageUrl} alt={ad.title} />
|
? <img src={imageUrl} alt={ad.title} />
|
||||||
: <span className="f-card-emoji">{ad.emoji || "📋"}</span>
|
: <span className="f-card-emoji">{ad.emoji || "📋"}</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="f-card-body">
|
|
||||||
<div className="f-card-badges">
|
<div className="f-card-actions">
|
||||||
{ad.category && <div className="f-cat-badge">{ad.category}</div>}
|
<div className="f-card-actions-left">
|
||||||
<div className={`f-type-badge ${ad.type === "loss" ? "f-type-loss"
|
<button type="button"
|
||||||
: "f-type-found"}`}>
|
className={`f-card-icon-btn${liked ? " liked" : ""}`}
|
||||||
{ad.type === "loss" ? t('postCard.loss') : t('postCard.found')}
|
onClick={e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onLike(ad.id);
|
||||||
|
}}>
|
||||||
|
<HeartIcon filled={liked}/>
|
||||||
|
</button>
|
||||||
|
<span className="f-card-like-count">{ad.likeCount || 0}</span>
|
||||||
</div>
|
</div>
|
||||||
{roleBadge}
|
<div className="f-card-actions-right">
|
||||||
|
{onEdit && isOwner && !isClosed && (
|
||||||
|
<button type="button" className="f-card-edit-btn"
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onEdit(ad);
|
||||||
|
}}>
|
||||||
|
✏️
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{onDelete && isOwner && (
|
||||||
|
<button type="button" className="f-card-delete-btn"
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onDelete(ad.id);
|
||||||
|
}}>
|
||||||
|
<TrashIcon/>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{ad.reward && (
|
||||||
|
<span className="f-card-reward-text">
|
||||||
|
{t("postCard.reward")}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="f-card-title">
|
|
||||||
{ad.title}
|
|
||||||
{isClosed && <span className="f-status-badge f-status-closed">{t(
|
|
||||||
'postCard.foundStatus')}</span>}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="f-card-desc">{ad.description}</div>
|
|
||||||
|
<div className="f-card-caption">
|
||||||
|
<span
|
||||||
|
ref={descRef}
|
||||||
|
className={`f-card-caption-text${descTruncated ? " f-truncatable" : ""}${descExpanded ? " f-expanded" : ""}`}
|
||||||
|
onClick={descTruncated ? () => setDescExpanded(v => !v) : undefined}
|
||||||
|
>
|
||||||
|
{ad.description}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="f-card-meta">
|
<div className="f-card-meta">
|
||||||
{address && <div className="f-meta-pill"><PinIcon/> {address}
|
{address && <div className="f-meta-pill"><PinIcon/> {address}</div>}
|
||||||
</div>}
|
|
||||||
{createdAt && (
|
{createdAt && (
|
||||||
<div
|
<div
|
||||||
className="f-meta-pill f-date-pill"
|
className="f-meta-pill f-date-pill"
|
||||||
@@ -106,6 +161,7 @@ export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMark
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="f-card-foot">
|
<div className="f-card-foot">
|
||||||
<div className="f-card-foot-left">
|
<div className="f-card-foot-left">
|
||||||
{ad.phone && (
|
{ad.phone && (
|
||||||
@@ -122,24 +178,6 @@ export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMark
|
|||||||
{t('postCard.write')}
|
{t('postCard.write')}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{onEdit && isOwner && !isClosed && (
|
|
||||||
<button type="button" className="f-card-edit-btn"
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onEdit(ad);
|
|
||||||
}}>
|
|
||||||
✏️
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{onDelete && isOwner && (
|
|
||||||
<button type="button" className="f-card-delete-btn"
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onDelete(ad.id);
|
|
||||||
}}>
|
|
||||||
<TrashIcon/>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{onMarkFound && isOwner && !isClosed && (
|
{onMarkFound && isOwner && !isClosed && (
|
||||||
<button type="button" className="f-card-found-btn"
|
<button type="button" className="f-card-found-btn"
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
@@ -149,17 +187,6 @@ export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMark
|
|||||||
{t('postCard.itemFound')}
|
{t('postCard.itemFound')}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button type="button"
|
|
||||||
className={`f-like-btn${liked ? " liked" : ""}`}
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onLike(ad.id);
|
|
||||||
}}>
|
|
||||||
<HeartIcon filled={liked}/>
|
|
||||||
{ad.likeCount || 0}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ export default function ReviewsPage() {
|
|||||||
isAuthenticated={isAuthenticated}
|
isAuthenticated={isAuthenticated}
|
||||||
onLoginClick={() => setAuthModalOpen(true)}
|
onLoginClick={() => setAuthModalOpen(true)}
|
||||||
onRulesClick={() => setRulesModalOpen(true)}
|
onRulesClick={() => setRulesModalOpen(true)}
|
||||||
|
onCreatePost={() => navigate("/feed")}
|
||||||
|
onProfileClick={() => setProfileModalOpen(true)}
|
||||||
|
profileData={profileData}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="f-main">
|
<div className="f-main">
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
.nk-page {
|
.nk-page {
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
background: #0A1F1E;
|
background: linear-gradient(180deg, #ffffff 0%, #fafafa 100%);
|
||||||
color: #F4F7F6;
|
color: #262626;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +71,10 @@
|
|||||||
.nk-grid {
|
.nk-grid {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background-image: radial-gradient(rgba(244, 247, 246, 0.10) 1px, transparent 1px);
|
background-image: radial-gradient(rgba(38, 38, 38, 0.10) 1px, transparent 1px);
|
||||||
background-size: 26px 26px;
|
background-size: 26px 26px;
|
||||||
animation: drift 14s linear infinite;
|
animation: drift 14s linear infinite;
|
||||||
opacity: 0.6;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-glow {
|
.nk-glow {
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
right: -10%;
|
right: -10%;
|
||||||
width: 600px;
|
width: 600px;
|
||||||
height: 600px;
|
height: 600px;
|
||||||
background: radial-gradient(circle, rgba(245, 166, 35, 0.18) 0%, transparent 70%);
|
background: radial-gradient(circle, rgba(0, 149, 246, 0.14) 0%, transparent 70%);
|
||||||
filter: blur(10px);
|
filter: blur(10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +100,7 @@
|
|||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
letter-spacing: 0.01em;
|
letter-spacing: 0.01em;
|
||||||
|
color: #262626;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-nav-right {
|
.nk-nav-right {
|
||||||
@@ -109,9 +110,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nk-lang-btn {
|
.nk-lang-btn {
|
||||||
background: rgba(244, 247, 246, 0.06);
|
background: #ffffff;
|
||||||
border: 1px solid rgba(244, 247, 246, 0.12);
|
border: 1px solid #dbdbdb;
|
||||||
color: #F4F7F6;
|
color: #262626;
|
||||||
padding: 9px 12px;
|
padding: 9px 12px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@@ -120,23 +121,26 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
backdrop-filter: blur(6px);
|
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-lang-btn:hover {
|
.nk-lang-btn:hover {
|
||||||
background: rgba(244, 247, 246, 0.12);
|
background: #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-nav-btn {
|
.nk-nav-btn {
|
||||||
background: rgba(244, 247, 246, 0.08);
|
background: var(--teal, #0095f6);
|
||||||
border: 1px solid rgba(244, 247, 246, 0.16);
|
border: 1px solid var(--teal, #0095f6);
|
||||||
color: #F4F7F6;
|
color: #fff;
|
||||||
padding: 9px 20px;
|
padding: 9px 20px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
backdrop-filter: blur(6px);
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.nk-nav-btn:hover {
|
||||||
|
background: #0074d9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-radar {
|
.nk-radar {
|
||||||
@@ -156,7 +160,7 @@
|
|||||||
width: 140px;
|
width: 140px;
|
||||||
height: 140px;
|
height: 140px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 1px solid rgba(245, 166, 35, 0.55);
|
border: 1px solid rgba(0, 149, 246, 0.5);
|
||||||
animation: beaconPulse 3.9s ease-out infinite;
|
animation: beaconPulse 3.9s ease-out infinite;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
@@ -166,14 +170,14 @@
|
|||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: #F5A623;
|
background: #0095f6;
|
||||||
box-shadow: 0 0 22px 6px rgba(245, 166, 35, 0.55);
|
box-shadow: 0 0 22px 6px rgba(0, 149, 246, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-marker {
|
.nk-marker {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #0A1F1E;
|
color: #fff;
|
||||||
background: #F5A623;
|
background: #0095f6;
|
||||||
width: 34px;
|
width: 34px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@@ -181,7 +185,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
animation: markerIn 3.2s ease-in-out infinite;
|
animation: markerIn 3.2s ease-in-out infinite;
|
||||||
box-shadow: 0 4px 14px rgba(245, 166, 35, 0.4);
|
box-shadow: 0 4px 14px rgba(0, 149, 246, 0.4);
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
}
|
}
|
||||||
@@ -197,10 +201,11 @@
|
|||||||
.nk-eyebrow {
|
.nk-eyebrow {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #8FADA8;
|
color: #737373;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-h1 {
|
.nk-h1 {
|
||||||
@@ -209,16 +214,20 @@
|
|||||||
font-size: clamp(34px, 5.2vw, 58px);
|
font-size: clamp(34px, 5.2vw, 58px);
|
||||||
line-height: 1.08;
|
line-height: 1.08;
|
||||||
margin: 0 0 22px;
|
margin: 0 0 22px;
|
||||||
|
color: #262626;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-accent {
|
.nk-accent {
|
||||||
color: #F5A623;
|
background: linear-gradient(45deg, #feda75, #fa7e1e, #d62976, #962fbf, #4f5bd5);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-lead {
|
.nk-lead {
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
color: #C7DAD6;
|
color: #737373;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
margin-bottom: 34px;
|
margin-bottom: 34px;
|
||||||
}
|
}
|
||||||
@@ -231,28 +240,28 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nk-cta-primary {
|
.nk-cta-primary {
|
||||||
background: #F5A623;
|
background: #0095f6;
|
||||||
color: #0A1F1E;
|
color: #fff;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 15px 30px;
|
padding: 15px 30px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.2s, box-shadow 0.2s;
|
transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-cta-primary:hover {
|
.nk-cta-primary:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 12px 28px rgba(245, 166, 35, 0.35);
|
background: #0074d9;
|
||||||
|
box-shadow: 0 12px 28px rgba(0, 149, 246, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-cta-hint {
|
.nk-cta-hint {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #7FA39D;
|
color: #737373;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.nk-steps-section {
|
.nk-steps-section {
|
||||||
padding: 0 6vw 60px;
|
padding: 0 6vw 60px;
|
||||||
}
|
}
|
||||||
@@ -263,6 +272,7 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin-bottom: 42px;
|
margin-bottom: 42px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: #262626;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-steps-grid {
|
.nk-steps-grid {
|
||||||
@@ -274,21 +284,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nk-step-card {
|
.nk-step-card {
|
||||||
background: rgba(244, 247, 246, 0.04);
|
background: #ffffff;
|
||||||
border: 1px solid rgba(244, 247, 246, 0.10);
|
border: 1px solid #dbdbdb;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
padding: 26px 24px;
|
padding: 26px 24px;
|
||||||
transition: border-color 0.2s;
|
transition: border-color 0.2s, box-shadow 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-step-card:hover {
|
.nk-step-card:hover {
|
||||||
border-color: rgba(244, 247, 246, 0.22);
|
border-color: rgba(0, 149, 246, 0.4);
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-step-num {
|
.nk-step-num {
|
||||||
font-family: 'Fraunces', serif;
|
font-family: 'Fraunces', serif;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: #F5A623;
|
color: #0095f6;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,12 +307,13 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: 12px 0 8px;
|
margin: 12px 0 8px;
|
||||||
|
color: #262626;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-step-text {
|
.nk-step-text {
|
||||||
font-size: 14.5px;
|
font-size: 14.5px;
|
||||||
line-height: 1.55;
|
line-height: 1.55;
|
||||||
color: #9FBAB5;
|
color: #737373;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nk-final-cta {
|
.nk-final-cta {
|
||||||
@@ -315,7 +327,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 24px 0 34px;
|
padding: 24px 0 34px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #5F827D;
|
color: #b0b0b0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
|||||||
@@ -3,48 +3,48 @@
|
|||||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--teal: #2de0c8;
|
--teal: #0095f6;
|
||||||
--teal-rgb: 45, 224, 200;
|
--teal-rgb: 0, 149, 246;
|
||||||
--teal2: #1fc9b0;
|
--teal2: #0074d9;
|
||||||
--border: rgba(255,255,255,0.09);
|
--border: #dbdbdb;
|
||||||
--muted: rgba(255,255,255,0.38);
|
--muted: #737373;
|
||||||
--muted2: rgba(255,255,255,0.15);
|
--muted2: #c7c7c7;
|
||||||
--font: 'Nunito', sans-serif;
|
--font: 'Nunito', sans-serif;
|
||||||
--err: #ff6b6b;
|
--err: #ed4956;
|
||||||
|
|
||||||
--bg-app: linear-gradient(135deg, #1a2340 0%, #0d1018 100%);
|
--bg-app: #fafafa;
|
||||||
--bg-card: linear-gradient(155deg, #1d2436, #131720);
|
|
||||||
--bg-card-popup: linear-gradient(155deg, #2b3552, #1e2742);
|
|
||||||
--bg-surface: rgba(13,16,24,.7);
|
|
||||||
--bg-surface-solid: #131720;
|
|
||||||
--bg-filter: rgba(13,16,24,.4);
|
|
||||||
--bg-card-img: linear-gradient(135deg, #1a3a4a 0%, #0f2235 100%);
|
|
||||||
--bg-input: rgba(255,255,255,.055);
|
|
||||||
--bg-overlay: rgba(0,0,0,.65);
|
|
||||||
--text-primary: #fff;
|
|
||||||
--hover-bg: rgba(255,255,255,.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="light"] {
|
|
||||||
--teal: #1a9e8a;
|
|
||||||
--teal-rgb: 26, 158, 138;
|
|
||||||
--teal2: #148d7a;
|
|
||||||
--border: rgba(0,0,0,0.1);
|
|
||||||
--muted: rgba(0,0,0,0.45);
|
|
||||||
--muted2: rgba(0,0,0,0.18);
|
|
||||||
--err: #d32f2f;
|
|
||||||
|
|
||||||
--bg-app: linear-gradient(135deg, #f0f2f5 0%, #e2e6ed 100%);
|
|
||||||
--bg-card: #ffffff;
|
--bg-card: #ffffff;
|
||||||
--bg-card-popup: #ffffff;
|
--bg-card-popup: #ffffff;
|
||||||
--bg-surface: rgba(255,255,255,.8);
|
--bg-surface: #ffffff;
|
||||||
--bg-surface-solid: #ffffff;
|
--bg-surface-solid: #ffffff;
|
||||||
--bg-filter: rgba(255,255,255,.6);
|
--bg-filter: rgba(255,255,255,.8);
|
||||||
--bg-card-img: linear-gradient(135deg, #e8ecf2 0%, #d6dce6 100%);
|
--bg-card-img: linear-gradient(135deg, #feda75 0%, #fa7e1e 35%, #d62976 65%, #962fbf 100%);
|
||||||
--bg-input: rgba(0,0,0,.04);
|
--bg-input: rgba(0,0,0,.045);
|
||||||
--bg-overlay: rgba(0,0,0,.35);
|
--bg-overlay: rgba(0,0,0,.5);
|
||||||
--text-primary: #111;
|
--text-primary: #262626;
|
||||||
--hover-bg: rgba(0,0,0,.06);
|
--hover-bg: rgba(0,0,0,.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] {
|
||||||
|
--teal: #0095f6;
|
||||||
|
--teal-rgb: 0, 149, 246;
|
||||||
|
--teal2: #0074d9;
|
||||||
|
--border: #262626;
|
||||||
|
--muted: #a8a8a8;
|
||||||
|
--muted2: #4b4b4b;
|
||||||
|
--err: #ed4956;
|
||||||
|
|
||||||
|
--bg-app: #000000;
|
||||||
|
--bg-card: #1b1b1b;
|
||||||
|
--bg-card-popup: #262626;
|
||||||
|
--bg-surface: #000000;
|
||||||
|
--bg-surface-solid: #000000;
|
||||||
|
--bg-filter: rgba(0,0,0,.6);
|
||||||
|
--bg-card-img: linear-gradient(135deg, #5a3d00 0%, #6b3a10 35%, #4d1f38 65%, #3a205e 100%);
|
||||||
|
--bg-input: rgba(255,255,255,.08);
|
||||||
|
--bg-overlay: rgba(0,0,0,.65);
|
||||||
|
--text-primary: #f5f5f5;
|
||||||
|
--hover-bg: rgba(255,255,255,.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }
|
@keyframes shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }
|
||||||
|
|||||||
@@ -1,70 +1,192 @@
|
|||||||
/* ── Ad Card ── */
|
/* ── Post Card (Instagram-style vertical post) ── */
|
||||||
.f-card {
|
.f-card {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: var(--bg-card);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--border); border-radius: 20px; overflow: hidden;
|
border: 1px solid var(--border); border-radius: 16px; overflow: hidden;
|
||||||
transition: border-color .2s, transform .2s, background .2s; cursor: pointer;
|
transition: border-color .2s;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.f-card:hover { border-color: rgba(var(--teal-rgb), .3); transform: translateY(-2px); }
|
.f-card:hover { border-color: var(--muted2); }
|
||||||
|
|
||||||
.f-card-inner {
|
/* ── Post header ── */
|
||||||
display: flex; flex-direction: row; min-height: 180px;
|
.f-card-head {
|
||||||
|
display: flex; align-items: center; gap: 12px;
|
||||||
|
padding: 12px 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Image Panel */
|
.f-card-avatar-ring {
|
||||||
|
width: 42px; height: 42px; border-radius: 50%;
|
||||||
|
background: linear-gradient(45deg, #feda75, #fa7e1e, #d62976, #962fbf, #4f5bd5);
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.f-card-avatar {
|
||||||
|
width: 36px; height: 36px; border-radius: 50%;
|
||||||
|
background: var(--bg-card);
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
font-size: 1.05rem; overflow: hidden;
|
||||||
|
}
|
||||||
|
.f-card-avatar img { width: 100%; height: 100%; object-fit: cover; }
|
||||||
|
|
||||||
|
.f-card-author { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; align-items: flex-start; }
|
||||||
|
.f-card-author-name {
|
||||||
|
color: var(--text-primary); font-weight: 800; font-size: 1.1rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
|
||||||
|
}
|
||||||
|
.f-card-author-name.f-truncatable { cursor: pointer; }
|
||||||
|
.f-card-author-name.f-expanded {
|
||||||
|
white-space: normal;
|
||||||
|
overflow: visible;
|
||||||
|
text-overflow: clip;
|
||||||
|
}
|
||||||
|
.f-card-author-loc {
|
||||||
|
color: var(--muted); font-size: .78rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.f-card-head-side { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
|
||||||
|
|
||||||
|
/* ── Image panel ── */
|
||||||
.f-card-img {
|
.f-card-img {
|
||||||
width: 180px; min-width: 180px;
|
position: relative;
|
||||||
align-self: stretch;
|
width: 100%;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
background: var(--bg-card-img);
|
background: var(--bg-card-img);
|
||||||
display: flex; align-items: center; justify-content: center;
|
display: flex; align-items: center; justify-content: center;
|
||||||
position: relative; overflow: hidden; flex-shrink: 0;
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.f-card-img img {
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
object-fit: cover; object-position: center;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.f-card-emoji { font-size: 4rem; opacity: .85; filter: drop-shadow(0 4px 12px rgba(0,0,0,.3)); }
|
||||||
|
.f-card-reward {
|
||||||
|
position: absolute; top: 12px; right: 12px; z-index: 2;
|
||||||
|
background: rgba(0,0,0,.55); backdrop-filter: blur(6px);
|
||||||
|
border-radius: 999px; padding: 5px 12px;
|
||||||
|
font-size: .75rem; font-weight: 800;
|
||||||
|
color: #f5d76e;
|
||||||
}
|
}
|
||||||
.f-card-img img { width: 100%; height: 100%; object-fit: contain; object-position: center; display: block; position: absolute; inset: 0; }
|
|
||||||
.f-card-emoji { font-size: 3rem; opacity: .22; }
|
|
||||||
|
|
||||||
/* Badges */
|
/* ── Action row ── */
|
||||||
.f-card-badges {
|
.f-card-actions {
|
||||||
display: flex; align-items: center;
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
gap: 6px; margin-bottom: 8px;
|
padding: 10px 12px 4px;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
.f-cat-badge {
|
.f-card-actions-left, .f-card-actions-right {
|
||||||
background: var(--bg-surface); backdrop-filter: blur(8px);
|
display: flex; align-items: center; gap: 6px;
|
||||||
border: 1px solid var(--border); border-radius: 20px;
|
|
||||||
padding: 3px 10px; font-size: .72rem; font-weight: 700; color: var(--teal);
|
|
||||||
}
|
}
|
||||||
.f-type-badge {
|
.f-card-icon-btn {
|
||||||
border-radius: 20px; padding: 3px 10px;
|
background: none; border: none; cursor: pointer;
|
||||||
font-size: .72rem; font-weight: 900;
|
color: var(--text-primary);
|
||||||
|
width: 38px; height: 38px;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: background .15s, transform .15s, color .15s;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.f-card-icon-btn:hover { background: var(--hover-bg); transform: scale(1.08); }
|
||||||
|
.f-card-icon-btn:active { transform: scale(.92); }
|
||||||
|
.f-card-icon-btn.liked { color: #ed4956; }
|
||||||
|
.f-card-icon-btn.liked svg { fill: #ed4956; stroke: #ed4956; }
|
||||||
|
.f-card-icon-btn svg { transition: transform .15s; width: 24px; height: 24px; }
|
||||||
|
|
||||||
|
.f-card-like-count {
|
||||||
|
color: var(--text-primary); font-weight: 800; font-size: .9rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.f-card-reward-text {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: .74rem; font-weight: 600; letter-spacing: .02em;
|
||||||
|
white-space: nowrap;
|
||||||
|
background: linear-gradient(110deg, #e6b800 30%, #ffec99 50%, #e6b800 70%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
animation: f-reward-shimmer 5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
@keyframes f-reward-shimmer {
|
||||||
|
0% { background-position: 200% 0; }
|
||||||
|
100% { background-position: -200% 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Likes ── */
|
||||||
|
.f-card-likes {
|
||||||
|
padding: 2px 16px;
|
||||||
|
color: var(--text-primary); font-weight: 800; font-size: .9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Caption ── */
|
||||||
|
.f-card-caption {
|
||||||
|
padding: 6px 16px;
|
||||||
|
color: var(--text-primary); font-size: .87rem; line-height: 1.5;
|
||||||
|
}
|
||||||
|
.f-card-caption-name { font-weight: 800; margin-right: 6px; }
|
||||||
|
.f-card-caption-text {
|
||||||
|
color: var(--text-primary);
|
||||||
|
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
|
||||||
|
}
|
||||||
|
.f-card-caption-text.f-truncatable { cursor: pointer; }
|
||||||
|
.f-card-caption-text.f-expanded {
|
||||||
|
-webkit-line-clamp: unset;
|
||||||
|
line-clamp: unset;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Meta pills ── */
|
||||||
|
.f-card-meta {
|
||||||
|
display: flex; flex-wrap: wrap; align-items: center;
|
||||||
|
gap: 6px; padding: 8px 16px 4px;
|
||||||
|
}
|
||||||
|
.f-card-meta .f-date-pill {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
.f-type-loss { background: rgba(255,107,107,.2); color: #ff6b6b; border: 1px solid rgba(255,107,107,.3); }
|
.f-meta-pill {
|
||||||
.f-type-found { background: rgba(var(--teal-rgb), .2); color: var(--teal); border: 1px solid rgba(var(--teal-rgb), .3); }
|
display: inline-flex; align-items: center; gap: 4px;
|
||||||
|
background: var(--hover-bg);
|
||||||
|
border-radius: 999px; padding: 3px 10px;
|
||||||
|
font-size: .74rem; color: var(--muted);
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
.f-cat-badge {
|
||||||
|
display: inline-flex; align-items: center;
|
||||||
|
background: rgba(var(--teal-rgb), .08);
|
||||||
|
border: 1px solid rgba(var(--teal-rgb), .25);
|
||||||
|
border-radius: 999px; padding: 3px 10px;
|
||||||
|
font-size: .74rem; font-weight: 700; color: var(--teal);
|
||||||
|
}
|
||||||
|
.f-type-badge {
|
||||||
|
border-radius: 999px; padding: 3px 10px;
|
||||||
|
font-size: .74rem; font-weight: 800;
|
||||||
|
}
|
||||||
|
.f-type-loss { background: rgba(237,73,86,.1); color: #ed4956; border: 1px solid rgba(237,73,86,.25); }
|
||||||
|
.f-type-found { background: rgba(var(--teal-rgb), .1); color: var(--teal); border: 1px solid rgba(var(--teal-rgb), .25); }
|
||||||
|
|
||||||
/* Status badge for closed/found posts */
|
/* Status badge for closed/found posts */
|
||||||
.f-status-badge {
|
.f-status-badge {
|
||||||
border-radius: 20px; padding: 2px 8px;
|
border-radius: 999px; padding: 2px 8px;
|
||||||
font-size: .7rem; font-weight: 900;
|
font-size: .7rem; font-weight: 800;
|
||||||
display: inline-block; vertical-align: middle;
|
display: inline-block; vertical-align: middle;
|
||||||
margin-left: 8px;
|
|
||||||
}
|
}
|
||||||
.f-status-closed {
|
.f-status-closed {
|
||||||
background: rgba(72,187,120,.2); color: #48bb78; border: 1px solid rgba(72,187,120,.3);
|
background: rgba(48,168,94,.12); color: #30a85e; border: 1px solid rgba(48,168,94,.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Role badges (LOST_AND_FOUND / METRO) ── */
|
/* ── Role badges (LOST_AND_FOUND / METRO) ── */
|
||||||
.f-role-badge {
|
.f-role-badge {
|
||||||
display: inline-flex; align-items: center; gap: 4px;
|
display: inline-flex; align-items: center; gap: 4px;
|
||||||
border-radius: 20px; padding: 3px 8px;
|
border-radius: 999px; padding: 3px 8px;
|
||||||
font-size: .68rem; font-weight: 800;
|
font-size: .68rem; font-weight: 800;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.f-role-lost-found {
|
.f-role-lost-found {
|
||||||
background: rgba(255,200,50,.18); color: #f5c842;
|
background: rgba(255,200,50,.15); color: #b8890f;
|
||||||
border: 1px solid rgba(255,200,50,.3);
|
border: 1px solid rgba(255,200,50,.35);
|
||||||
}
|
}
|
||||||
.f-role-metro {
|
.f-role-metro {
|
||||||
background: rgba(227,6,19,.15); color: #e30613;
|
background: rgba(227,6,19,.1); color: #e30613;
|
||||||
border: 1px solid rgba(227,6,19,.25);
|
border: 1px solid rgba(227,6,19,.25);
|
||||||
}
|
}
|
||||||
.f-role-metro-letter {
|
.f-role-metro-letter {
|
||||||
@@ -74,121 +196,49 @@
|
|||||||
font-size: 9px; font-weight: 900; line-height: 1;
|
font-size: 9px; font-weight: 900; line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Role-based card border */
|
/* ── Footer (phone + owner actions) ── */
|
||||||
.f-card-role-lost-found {
|
|
||||||
border-color: rgba(255,200,50,.3);
|
|
||||||
box-shadow: 0 0 20px rgba(255,200,50,.08), inset 0 0 20px rgba(255,200,50,.04);
|
|
||||||
}
|
|
||||||
.f-card-role-lost-found:hover {
|
|
||||||
border-color: rgba(255,200,50,.5);
|
|
||||||
box-shadow: 0 0 30px rgba(255,200,50,.15), inset 0 0 25px rgba(255,200,50,.06);
|
|
||||||
}
|
|
||||||
.f-card-role-metro {
|
|
||||||
border-color: rgba(227,6,19,.25);
|
|
||||||
box-shadow: 0 0 20px rgba(227,6,19,.08), inset 0 0 20px rgba(227,6,19,.04);
|
|
||||||
}
|
|
||||||
.f-card-role-metro:hover {
|
|
||||||
border-color: rgba(227,6,19,.45);
|
|
||||||
box-shadow: 0 0 30px rgba(227,6,19,.15), inset 0 0 25px rgba(227,6,19,.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Body */
|
|
||||||
.f-card-body {
|
|
||||||
flex: 1; padding: 14px 16px;
|
|
||||||
display: flex; flex-direction: column; min-width: 0;
|
|
||||||
}
|
|
||||||
.f-card-title { color: var(--text-primary); font-weight: 900; font-size: 1rem; margin-bottom: 5px; line-height: 1.3; }
|
|
||||||
.f-card-desc {
|
|
||||||
color: var(--muted); font-size: .82rem; line-height: 1.5; margin-bottom: 10px;
|
|
||||||
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Meta pills */
|
|
||||||
.f-card-meta {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 6px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.f-meta-pill {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
background: var(--hover-bg);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 3px 9px;
|
|
||||||
font-size: .73rem;
|
|
||||||
color: var(--muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.f-date-pill {
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
.f-date-pill:hover {
|
|
||||||
background: rgba(128,128,128,.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map stub */
|
|
||||||
.f-card-map {
|
|
||||||
width: 100%; height: 76px;
|
|
||||||
background: var(--bg-input); margin-bottom: 14px; border-radius: 12px;
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
display: flex; align-items: center; justify-content: center;
|
|
||||||
gap: 8px; color: var(--muted); font-size: .78rem;
|
|
||||||
cursor: pointer; transition: border-color .2s;
|
|
||||||
font-family: var(--font); font-weight: 600;
|
|
||||||
}
|
|
||||||
.f-card-map:hover { border-color: rgba(var(--teal-rgb), .3); color: var(--teal); }
|
|
||||||
|
|
||||||
/* Footer */
|
|
||||||
.f-card-foot {
|
.f-card-foot {
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
padding-top: 10px; border-top: 1px solid var(--border); margin-top: auto;
|
gap: 8px; padding: 10px 16px 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.f-card-foot-left { display: flex; align-items: center; }
|
.f-card-foot-left { display: flex; align-items: center; min-width: 0; }
|
||||||
.f-card-foot-right { display: flex; align-items: center; gap: 6px; }
|
.f-card-foot-right { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||||||
.f-card-phone {
|
.f-card-phone {
|
||||||
color: var(--teal); font-size: .82rem; font-weight: 700;
|
color: var(--teal); font-size: .85rem; font-weight: 700;
|
||||||
text-decoration: none; display: flex; align-items: center; gap: 5px;
|
text-decoration: none; display: flex; align-items: center; gap: 6px;
|
||||||
}
|
}
|
||||||
.f-card-date { color: var(--muted2); font-size: .75rem; }
|
.f-card-date { color: var(--muted2); font-size: .75rem; }
|
||||||
.f-like-btn {
|
|
||||||
|
.f-card-contact {
|
||||||
display: flex; align-items: center; gap: 5px;
|
display: flex; align-items: center; gap: 5px;
|
||||||
background: none; border: 1px solid var(--border);
|
background: rgba(var(--teal-rgb), .1);
|
||||||
border-radius: 20px; padding: 5px 11px; cursor: pointer;
|
border: 1px solid rgba(var(--teal-rgb), .3);
|
||||||
font-family: var(--font); font-size: .8rem; font-weight: 700;
|
border-radius: 999px; padding: 12px 32px;
|
||||||
color: var(--muted); transition: all .2s; line-height: 1;
|
cursor: pointer; font-family: var(--font);
|
||||||
|
font-size: 1.05rem; font-weight: 700;
|
||||||
|
color: var(--teal); transition: all .2s;
|
||||||
}
|
}
|
||||||
.f-like-btn:hover, .f-like-btn.liked {
|
.f-card-contact:hover {
|
||||||
border-color: rgba(255,107,107,.5); color: #ff6b6b; background: rgba(255,107,107,.08);
|
background: rgba(var(--teal-rgb), .18);
|
||||||
|
border-color: rgba(var(--teal-rgb), .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Closed/Found card styling */
|
/* Closed/Found card styling */
|
||||||
.f-card-closed {
|
.f-card-closed {
|
||||||
opacity: 0.7;
|
opacity: .8;
|
||||||
border-color: rgba(72,187,120,.3);
|
border-color: rgba(48,168,94,.3);
|
||||||
}
|
|
||||||
.f-card-closed:hover {
|
|
||||||
border-color: rgba(72,187,120,.5);
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
.f-card-closed .f-card-img {
|
|
||||||
filter: grayscale(0.5);
|
|
||||||
}
|
|
||||||
.f-card-closed .f-card-title {
|
|
||||||
text-decoration: line-through;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
}
|
||||||
|
.f-card-closed:hover { border-color: rgba(48,168,94,.5); }
|
||||||
|
.f-card-closed .f-card-img { filter: grayscale(.5); }
|
||||||
|
.f-card-closed .f-card-caption-name { text-decoration: line-through; opacity: .7; }
|
||||||
|
|
||||||
/* Edit & Delete buttons */
|
/* Edit & Delete buttons */
|
||||||
.f-card-edit-btn,
|
.f-card-edit-btn,
|
||||||
.f-card-delete-btn {
|
.f-card-delete-btn {
|
||||||
display: flex; align-items: center; justify-content: center;
|
display: flex; align-items: center; justify-content: center;
|
||||||
background: none; border: 1px solid var(--border);
|
background: none; border: 1px solid var(--border);
|
||||||
border-radius: 8px; width: 32px; height: 32px;
|
border-radius: 50%; width: 34px; height: 34px;
|
||||||
cursor: pointer; transition: all .2s;
|
cursor: pointer; transition: all .2s;
|
||||||
color: var(--muted); padding: 0;
|
color: var(--muted); padding: 0;
|
||||||
}
|
}
|
||||||
@@ -196,51 +246,20 @@
|
|||||||
border-color: rgba(var(--teal-rgb), .5); color: var(--teal); background: rgba(var(--teal-rgb), .08);
|
border-color: rgba(var(--teal-rgb), .5); color: var(--teal); background: rgba(var(--teal-rgb), .08);
|
||||||
}
|
}
|
||||||
.f-card-delete-btn:hover {
|
.f-card-delete-btn:hover {
|
||||||
border-color: rgba(255,107,107,.5); color: #ff6b6b; background: rgba(255,107,107,.08);
|
border-color: rgba(237,73,86,.5); color: #ed4956; background: rgba(237,73,86,.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark as Found button */
|
/* Mark as Found button */
|
||||||
.f-card-found-btn {
|
.f-card-found-btn {
|
||||||
display: flex; align-items: center; gap: 5px;
|
display: flex; align-items: center; gap: 5px;
|
||||||
background: rgba(72,187,120,.1); border: 1px solid rgba(72,187,120,.3);
|
background: rgba(48,168,94,.1); border: 1px solid rgba(48,168,94,.3);
|
||||||
border-radius: 20px; padding: 5px 11px;
|
border-radius: 999px; padding: 5px 11px;
|
||||||
cursor: pointer; transition: all .2s;
|
cursor: pointer; transition: all .2s;
|
||||||
font-family: var(--font); font-size: .75rem; font-weight: 700;
|
font-family: var(--font); font-size: .75rem; font-weight: 700;
|
||||||
color: #48bb78;
|
color: #30a85e;
|
||||||
}
|
}
|
||||||
.f-card-found-btn:hover {
|
.f-card-found-btn:hover {
|
||||||
background: rgba(72,187,120,.2); border-color: rgba(72,187,120,.5);
|
background: rgba(48,168,94,.18); border-color: rgba(48,168,94,.5);
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 4px 12px rgba(72,187,120,.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
/* Карточка становится вертикальной */
|
|
||||||
.f-card-inner {
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Картинка — горизонтальная полоса сверху */
|
|
||||||
.f-card-img {
|
|
||||||
width: 100%;
|
|
||||||
min-width: unset;
|
|
||||||
height: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Убираем кнопку карты на мобилке — занимает много места */
|
|
||||||
.f-card-map {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Чуть меньше паддинг в теле карточки */
|
|
||||||
.f-card-body {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.f-card-phone {
|
|
||||||
font-size: 0.72rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Calendar Popup ── */
|
/* ── Calendar Popup ── */
|
||||||
@@ -250,7 +269,7 @@
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
box-shadow: 0 8px 32px rgba(0,0,0,.25);
|
box-shadow: 0 8px 32px rgba(0,0,0,.2);
|
||||||
}
|
}
|
||||||
.f-date-calendar-overlay {
|
.f-date-calendar-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -265,6 +284,7 @@
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
font-size: .82rem;
|
font-size: .82rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
.f-cal-header button {
|
.f-cal-header button {
|
||||||
background: none;
|
background: none;
|
||||||
@@ -277,7 +297,7 @@
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
.f-cal-header button:hover {
|
.f-cal-header button:hover {
|
||||||
background: rgba(128,128,128,.15);
|
background: var(--hover-bg);
|
||||||
}
|
}
|
||||||
.f-cal-grid {
|
.f-cal-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -311,11 +331,7 @@
|
|||||||
color: #d4af37;
|
color: #d4af37;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
.f-reward-checkbox input { display: none; }
|
||||||
.f-reward-checkbox input {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.f-reward-checkmark {
|
.f-reward-checkmark {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
@@ -325,12 +341,10 @@
|
|||||||
transition: .2s;
|
transition: .2s;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-reward-checkbox input:checked + .f-reward-checkmark {
|
.f-reward-checkbox input:checked + .f-reward-checkmark {
|
||||||
background: #d4af37;
|
background: #d4af37;
|
||||||
box-shadow: 0 0 10px rgba(212, 175, 55, .35);
|
box-shadow: 0 0 10px rgba(212, 175, 55, .35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-reward-checkbox input:checked + .f-reward-checkmark::after {
|
.f-reward-checkbox input:checked + .f-reward-checkmark::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -342,23 +356,13 @@
|
|||||||
border-width: 0 2px 2px 0;
|
border-width: 0 2px 2px 0;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-reward-text {
|
.f-reward-text {
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-card-img {
|
.f-date-pill {
|
||||||
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
.f-date-pill:hover { background: var(--hover-bg); }
|
||||||
.f-card-reward {
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
left: 10px;
|
|
||||||
z-index: 2;
|
|
||||||
font-size: .72rem;
|
|
||||||
font-weight: 800;
|
|
||||||
color: #f5d76e;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/* ── Chat Page ── */
|
/* ── Chat Page (Instagram Direct style) ── */
|
||||||
.chat-page {
|
.chat-page {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: linear-gradient(135deg, #1a2340 0%, #0d1018 100%);
|
background: var(--bg-app);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header */
|
/* Header */
|
||||||
@@ -12,9 +12,9 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
padding: 14px 18px;
|
padding: 12px 18px;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: rgba(13, 16, 24, .7);
|
background: var(--bg-surface-solid);
|
||||||
backdrop-filter: blur(12px);
|
backdrop-filter: blur(12px);
|
||||||
}
|
}
|
||||||
.chat-back-btn {
|
.chat-back-btn {
|
||||||
@@ -28,30 +28,30 @@
|
|||||||
transition: background .15s, color .15s;
|
transition: background .15s, color .15s;
|
||||||
}
|
}
|
||||||
.chat-back-btn:hover {
|
.chat-back-btn:hover {
|
||||||
background: rgba(255, 255, 255, .08);
|
background: var(--hover-bg);
|
||||||
color: #fff;
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
.chat-header-title {
|
.chat-header-title {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
color: #fff;
|
color: var(--text-primary);
|
||||||
font-weight: 900;
|
font-weight: 800;
|
||||||
font-size: 1.1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
.chat-status {
|
.chat-status {
|
||||||
font-size: .75rem;
|
font-size: .72rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
.chat-status.connected {
|
.chat-status.connected {
|
||||||
color: #2de0c8;
|
color: #30a85e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-header-avatar {
|
.chat-header-avatar {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: rgba(45, 224, 200, .15);
|
background: var(--bg-input);
|
||||||
border: 2px solid rgba(45, 224, 200, .3);
|
border: 2px solid var(--border);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -73,10 +73,10 @@
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
.chat-messages::-webkit-scrollbar { width: 4px; }
|
.chat-messages::-webkit-scrollbar { width: 4px; }
|
||||||
.chat-messages::-webkit-scrollbar-thumb { background: rgba(255,255,255,.1); border-radius: 2px; }
|
.chat-messages::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
|
||||||
|
|
||||||
.chat-empty {
|
.chat-empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -97,18 +97,20 @@
|
|||||||
.chat-bubble {
|
.chat-bubble {
|
||||||
max-width: 70%;
|
max-width: 70%;
|
||||||
padding: 10px 14px;
|
padding: 10px 14px;
|
||||||
border-radius: 14px;
|
border-radius: 18px;
|
||||||
font-size: .93rem;
|
font-size: .92rem;
|
||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
background: rgba(255, 255, 255, .08);
|
background: var(--bg-surface-solid);
|
||||||
color: #fff;
|
border: 1px solid var(--border);
|
||||||
|
color: var(--text-primary);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
.chat-bubble.mine {
|
.chat-bubble.mine {
|
||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
background: #2de0c8;
|
background: #3797f0;
|
||||||
color: #082320;
|
border-color: #3797f0;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
.chat-bubble-time {
|
.chat-bubble-time {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -123,39 +125,38 @@
|
|||||||
/* Input row */
|
/* Input row */
|
||||||
.chat-input-row {
|
.chat-input-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
padding: 16px;
|
padding: 14px 16px;
|
||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
background: rgba(13, 16, 24, .5);
|
background: var(--bg-surface-solid);
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
}
|
}
|
||||||
.chat-input {
|
.chat-input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 12px 16px;
|
padding: 12px 18px;
|
||||||
border-radius: 12px;
|
border-radius: 999px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
background: rgba(255, 255, 255, .08);
|
background: var(--bg-input);
|
||||||
color: #fff;
|
color: var(--text-primary);
|
||||||
font-family: var(--font);
|
font-family: var(--font);
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: border-color .2s;
|
transition: border-color .2s, box-shadow .2s;
|
||||||
}
|
}
|
||||||
.chat-input::placeholder { color: var(--muted); }
|
.chat-input::placeholder { color: var(--muted); }
|
||||||
.chat-input:focus { border-color: rgba(45, 224, 200, .5); }
|
.chat-input:focus { border-color: rgba(var(--teal-rgb), .5); box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .12); }
|
||||||
|
|
||||||
.chat-send-btn {
|
.chat-send-btn {
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
border-radius: 12px;
|
border-radius: 999px;
|
||||||
border: none;
|
border: none;
|
||||||
background: #2de0c8;
|
background: var(--teal);
|
||||||
color: #082320;
|
color: #fff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.1rem;
|
font-size: 1rem;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
transition: background .2s, opacity .2s;
|
transition: background .2s, opacity .2s;
|
||||||
}
|
}
|
||||||
.chat-send-btn:hover:not(:disabled) { background: #24c9b2; }
|
.chat-send-btn:hover:not(:disabled) { background: var(--teal2); }
|
||||||
.chat-send-btn:disabled { opacity: .4; cursor: default; }
|
.chat-send-btn:disabled { opacity: .4; cursor: default; }
|
||||||
|
|
||||||
/* ── Emoji picker ── */
|
/* ── Emoji picker ── */
|
||||||
@@ -172,23 +173,21 @@
|
|||||||
.chat-emoji-picker em-emoji-picker {
|
.chat-emoji-picker em-emoji-picker {
|
||||||
width: 320px;
|
width: 320px;
|
||||||
max-height: 350px;
|
max-height: 350px;
|
||||||
--rgb-background: 13, 16, 24;
|
|
||||||
--rgb-accent: 45, 224, 200;
|
|
||||||
}
|
}
|
||||||
.chat-emoji-btn {
|
.chat-emoji-btn {
|
||||||
background: rgba(255, 255, 255, .08);
|
background: var(--bg-input);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 12px;
|
border-radius: 999px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.3rem;
|
font-size: 1.2rem;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
transition: background .15s, border-color .15s;
|
transition: background .15s, border-color .15s;
|
||||||
}
|
}
|
||||||
.chat-emoji-btn:hover,
|
.chat-emoji-btn:hover,
|
||||||
.chat-emoji-btn.active {
|
.chat-emoji-btn.active {
|
||||||
background: rgba(255, 255, 255, .14);
|
background: var(--hover-bg);
|
||||||
border-color: rgba(45, 224, 200, .5);
|
border-color: rgba(var(--teal-rgb), .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Chat List ── */
|
/* ── Chat List ── */
|
||||||
@@ -196,37 +195,38 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
max-width: 560px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
.chat-list::-webkit-scrollbar { width: 4px; }
|
.chat-list::-webkit-scrollbar { width: 4px; }
|
||||||
.chat-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,.1); border-radius: 2px; }
|
.chat-list::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
|
||||||
|
|
||||||
.chat-list-item {
|
.chat-list-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
padding: 14px 16px;
|
padding: 12px 16px;
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background .15s;
|
transition: background .15s;
|
||||||
border: 1px solid transparent;
|
|
||||||
}
|
}
|
||||||
.chat-list-item:hover {
|
.chat-list-item:hover {
|
||||||
background: rgba(255, 255, 255, .05);
|
background: var(--hover-bg);
|
||||||
border-color: rgba(45, 224, 200, .2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-list-avatar {
|
.chat-list-avatar {
|
||||||
width: 44px;
|
width: 44px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: rgba(45, 224, 200, .15);
|
background: var(--bg-input);
|
||||||
border: 2px solid rgba(45, 224, 200, .3);
|
border: 2px solid var(--border);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #2de0c8;
|
color: var(--muted);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@@ -242,14 +242,14 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
.chat-list-item.unread .chat-list-name {
|
.chat-list-item.unread .chat-list-name {
|
||||||
color: #2de0c8;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
.chat-list-item.unread .chat-list-preview {
|
.chat-list-item.unread .chat-list-preview {
|
||||||
color: rgba(45, 224, 200, .6);
|
color: var(--text-primary);
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.chat-list-name {
|
.chat-list-name {
|
||||||
color: #fff;
|
color: var(--text-primary);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -267,10 +267,10 @@
|
|||||||
|
|
||||||
/* ── Unread Badge ── */
|
/* ── Unread Badge ── */
|
||||||
.chat-list-unread-badge {
|
.chat-list-unread-badge {
|
||||||
background: #2de0c8;
|
background: #ff3040;
|
||||||
color: #082320;
|
color: #fff;
|
||||||
font-size: .7rem;
|
font-size: .7rem;
|
||||||
font-weight: 900;
|
font-weight: 800;
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
@@ -283,10 +283,10 @@
|
|||||||
|
|
||||||
/* ── Sidebar Unread Badge ── */
|
/* ── Sidebar Unread Badge ── */
|
||||||
.f-sb-unread-badge {
|
.f-sb-unread-badge {
|
||||||
background: #2de0c8;
|
background: #ff3040;
|
||||||
color: #082320;
|
color: #fff;
|
||||||
font-size: .65rem;
|
font-size: .65rem;
|
||||||
font-weight: 900;
|
font-weight: 800;
|
||||||
min-width: 18px;
|
min-width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
border-radius: 9px;
|
border-radius: 9px;
|
||||||
@@ -302,24 +302,24 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
background: rgba(45, 224, 200, .12);
|
background: rgba(var(--teal-rgb), .1);
|
||||||
border: 1px solid rgba(45, 224, 200, .3);
|
border: 1px solid rgba(var(--teal-rgb), .3);
|
||||||
border-radius: 20px;
|
border-radius: 999px;
|
||||||
padding: 5px 14px;
|
padding: 5px 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: var(--font);
|
font-family: var(--font);
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #2de0c8;
|
color: var(--teal);
|
||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
}
|
}
|
||||||
.f-card-contact:hover {
|
.f-card-contact:hover {
|
||||||
background: rgba(45, 224, 200, .22);
|
background: rgba(var(--teal-rgb), .18);
|
||||||
border-color: rgba(45, 224, 200, .5);
|
border-color: rgba(var(--teal-rgb), .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-list-delete-btn {
|
.chat-list-delete-btn {
|
||||||
background: rgba(255, 71, 87, .1);
|
background: rgba(255, 71, 87, .08);
|
||||||
border: 1px solid rgba(255, 71, 87, .2);
|
border: 1px solid rgba(255, 71, 87, .2);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
color: rgba(255, 71, 87, .5);
|
color: rgba(255, 71, 87, .5);
|
||||||
@@ -336,7 +336,7 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.chat-list-delete-btn:hover {
|
.chat-list-delete-btn:hover {
|
||||||
background: rgba(255, 71, 87, .2);
|
background: rgba(255, 71, 87, .15);
|
||||||
border-color: rgba(255, 71, 87, .4);
|
border-color: rgba(255, 71, 87, .4);
|
||||||
color: #ff4757;
|
color: #ff4757;
|
||||||
}
|
}
|
||||||
@@ -344,10 +344,10 @@
|
|||||||
/* Mobile adjustments */
|
/* Mobile adjustments */
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.chat-header {
|
.chat-header {
|
||||||
padding: 12px 14px;
|
padding: 10px 12px;
|
||||||
}
|
}
|
||||||
.chat-input-row {
|
.chat-input-row {
|
||||||
padding: 12px;
|
padding: 10px 12px;
|
||||||
}
|
}
|
||||||
.chat-bubble {
|
.chat-bubble {
|
||||||
max-width: 85%;
|
max-width: 85%;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* ── App Shell ── */
|
/* ── App Shell (Instagram-style) ── */
|
||||||
.f-app {
|
.f-app {
|
||||||
display: flex; height: 100vh;
|
display: flex; height: 100vh;
|
||||||
background: var(--bg-app);
|
background: var(--bg-app);
|
||||||
@@ -18,12 +18,12 @@
|
|||||||
min-width: 0; height: 100vh; overflow: hidden;
|
min-width: 0; height: 100vh; overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Topbar ── */
|
/* ── Topbar (mobile only; desktop uses the nav sidebar) ── */
|
||||||
.f-topbar {
|
.f-topbar {
|
||||||
display: flex; align-items: center; gap: 12px;
|
display: flex; align-items: center; gap: 8px;
|
||||||
padding: 14px 16px;
|
padding: 8px 16px;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: var(--bg-surface); backdrop-filter: blur(12px);
|
background: var(--bg-surface);
|
||||||
position: sticky; top: 0; z-index: 10;
|
position: sticky; top: 0; z-index: 10;
|
||||||
}
|
}
|
||||||
.f-menu-btn {
|
.f-menu-btn {
|
||||||
@@ -33,7 +33,11 @@
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
.f-menu-btn:hover { background: var(--hover-bg); }
|
.f-menu-btn:hover { background: var(--hover-bg); }
|
||||||
.f-topbar-center { flex: 1; display: flex; justify-content: center; }
|
.f-topbar-center { flex: 1; display: flex; justify-content: center; min-width: 0; }
|
||||||
|
.f-topbar-wordmark {
|
||||||
|
color: var(--text-primary); font-weight: 900; font-size: 1.05rem;
|
||||||
|
letter-spacing: -.4px; white-space: nowrap; margin-left: 2px;
|
||||||
|
}
|
||||||
.f-topbar-spacer { width: 32px; flex-shrink: 0; }
|
.f-topbar-spacer { width: 32px; flex-shrink: 0; }
|
||||||
|
|
||||||
/* ── Topbar Profile ── */
|
/* ── Topbar Profile ── */
|
||||||
@@ -55,8 +59,8 @@
|
|||||||
/* ── Search Bar ── */
|
/* ── Search Bar ── */
|
||||||
.f-search-bar {
|
.f-search-bar {
|
||||||
display: flex; align-items: center; gap: 10px;
|
display: flex; align-items: center; gap: 10px;
|
||||||
padding: 8px 16px;
|
padding: 10px 16px;
|
||||||
background: var(--bg-filter); backdrop-filter: blur(8px);
|
background: var(--bg-surface);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,58 +72,53 @@
|
|||||||
.f-search-input {
|
.f-search-input {
|
||||||
flex: 1; min-width: 0;
|
flex: 1; min-width: 0;
|
||||||
background: var(--bg-input);
|
background: var(--bg-input);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid transparent;
|
||||||
border-radius: 10px;
|
border-radius: 999px;
|
||||||
padding: 10px 14px;
|
padding: 10px 18px;
|
||||||
font-family: var(--font); font-size: 0.9rem;
|
font-family: var(--font); font-size: 0.9rem;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: border-color .2s, box-shadow .2s;
|
transition: border-color .2s, box-shadow .2s, background .2s;
|
||||||
}
|
}
|
||||||
.f-search-input::placeholder { color: var(--muted); }
|
.f-search-input::placeholder { color: var(--muted); }
|
||||||
.f-search-input:focus {
|
.f-search-input:focus {
|
||||||
border-color: rgba(var(--teal-rgb), .5);
|
border-color: var(--border);
|
||||||
box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .12);
|
background: var(--bg-surface);
|
||||||
|
box-shadow: 0 1px 6px rgba(0,0,0,.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-search-clear {
|
.f-search-clear {
|
||||||
background: none; border: none; cursor: pointer;
|
background: none; border: none; cursor: pointer;
|
||||||
color: var(--muted); padding: 4px; border-radius: 6px;
|
color: var(--muted); padding: 4px; border-radius: 50%;
|
||||||
display: flex; align-items: center; justify-content: center;
|
display: flex; align-items: center; justify-content: center;
|
||||||
flex-shrink: 0; transition: color .15s, background .15s;
|
flex-shrink: 0; transition: color .15s, background .15s;
|
||||||
}
|
}
|
||||||
.f-search-clear:hover { color: var(--text-primary); background: var(--hover-bg); }
|
.f-search-clear:hover { color: var(--text-primary); background: var(--hover-bg); }
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.f-search-bar { padding: 8px 12px; }
|
|
||||||
.f-search-input { padding: 8px 12px; font-size: 0.85rem; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Filter Bar ── */
|
/* ── Filter Bar ── */
|
||||||
.f-filter-bar {
|
.f-filter-bar {
|
||||||
display: flex; gap: 10px;
|
display: flex; gap: 8px;
|
||||||
padding: 12px 16px;
|
padding: 10px 16px;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: var(--bg-filter); backdrop-filter: blur(8px);
|
background: var(--bg-surface);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-filter-btn {
|
.f-filter-btn {
|
||||||
display: flex; align-items: center; gap: 6px;
|
display: flex; align-items: center; gap: 6px;
|
||||||
padding: 10px 18px; border-radius: 12px;
|
padding: 8px 16px; border-radius: 999px;
|
||||||
font-family: var(--font); font-size: 0.9rem; font-weight: 600;
|
font-family: var(--font); font-size: 0.85rem; font-weight: 600;
|
||||||
background: var(--hover-bg); border: 1px solid var(--border);
|
background: var(--bg-input); border: 1px solid var(--border);
|
||||||
color: var(--muted); cursor: pointer;
|
color: var(--muted); cursor: pointer;
|
||||||
transition: all 0.25s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
.f-filter-btn:hover {
|
.f-filter-btn:hover {
|
||||||
background: var(--hover-bg); border-color: rgba(var(--teal-rgb), .3);
|
background: var(--hover-bg); color: var(--text-primary);
|
||||||
color: var(--text-primary);
|
|
||||||
}
|
}
|
||||||
.f-filter-btn.active {
|
.f-filter-btn.active {
|
||||||
background: rgba(var(--teal-rgb), .15); border-color: rgba(var(--teal-rgb), .5);
|
background: rgba(var(--teal-rgb), .08);
|
||||||
color: var(--teal); box-shadow: 0 0 12px rgba(var(--teal-rgb), .25);
|
border-color: rgba(var(--teal-rgb), .5);
|
||||||
font-weight: 700;
|
color: var(--teal); font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── City Multiselect ── */
|
/* ── City Multiselect ── */
|
||||||
@@ -128,7 +127,7 @@
|
|||||||
display: flex; align-items: center;
|
display: flex; align-items: center;
|
||||||
padding: 10px 16px;
|
padding: 10px 16px;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: var(--bg-filter); backdrop-filter: blur(8px);
|
background: var(--bg-surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-city-multiselect {
|
.f-city-multiselect {
|
||||||
@@ -140,9 +139,9 @@
|
|||||||
display: flex; align-items: center; gap: 8px;
|
display: flex; align-items: center; gap: 8px;
|
||||||
background: var(--bg-input);
|
background: var(--bg-input);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 12px;
|
border-radius: 999px;
|
||||||
padding: 8px 12px;
|
padding: 6px 14px;
|
||||||
min-height: 44px;
|
min-height: 42px;
|
||||||
cursor: text;
|
cursor: text;
|
||||||
transition: border-color .2s, box-shadow .2s;
|
transition: border-color .2s, box-shadow .2s;
|
||||||
}
|
}
|
||||||
@@ -162,12 +161,12 @@
|
|||||||
|
|
||||||
.f-city-ms-tag {
|
.f-city-ms-tag {
|
||||||
display: inline-flex; align-items: center; gap: 4px;
|
display: inline-flex; align-items: center; gap: 4px;
|
||||||
background: rgba(var(--teal-rgb), .15);
|
background: rgba(var(--teal-rgb), .1);
|
||||||
border: 1px solid rgba(var(--teal-rgb), .4);
|
border: 1px solid rgba(var(--teal-rgb), .35);
|
||||||
color: var(--teal);
|
color: var(--teal);
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
padding: 4px 10px;
|
padding: 3px 10px;
|
||||||
font-size: 0.8rem; font-weight: 600;
|
font-size: 0.78rem; font-weight: 600;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.f-city-ms-tag-remove {
|
.f-city-ms-tag-remove {
|
||||||
@@ -202,10 +201,10 @@
|
|||||||
|
|
||||||
.f-city-ms-dropdown {
|
.f-city-ms-dropdown {
|
||||||
position: absolute; top: calc(100% + 6px); left: 0; right: 0;
|
position: absolute; top: calc(100% + 6px); left: 0; right: 0;
|
||||||
background: var(--bg-surface);
|
background: var(--bg-surface-solid);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 12px 32px rgba(0, 0, 0, .4);
|
box-shadow: 0 12px 32px rgba(0, 0, 0, .18);
|
||||||
max-height: 260px; overflow-y: auto;
|
max-height: 260px; overflow-y: auto;
|
||||||
z-index: 30; padding: 6px;
|
z-index: 30; padding: 6px;
|
||||||
}
|
}
|
||||||
@@ -233,7 +232,7 @@
|
|||||||
}
|
}
|
||||||
.f-city-ms-option.selected .f-city-ms-check {
|
.f-city-ms-option.selected .f-city-ms-check {
|
||||||
border-color: var(--teal);
|
border-color: var(--teal);
|
||||||
background: rgba(var(--teal-rgb), .15);
|
background: rgba(var(--teal-rgb), .12);
|
||||||
}
|
}
|
||||||
.f-city-ms-option.f-city-ms-add .f-city-ms-check {
|
.f-city-ms-option.f-city-ms-add .f-city-ms-check {
|
||||||
border-color: rgba(var(--teal-rgb), .5);
|
border-color: rgba(var(--teal-rgb), .5);
|
||||||
@@ -243,61 +242,134 @@
|
|||||||
padding: 10px; text-align: center; color: var(--muted); font-size: 0.85rem;
|
padding: 10px; text-align: center; color: var(--muted); font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Bottom Navigation (Instagram-style) ── */
|
||||||
|
.f-bottom-nav {
|
||||||
|
position: fixed; left: 0; right: 0; bottom: 0;
|
||||||
|
display: flex; align-items: center; justify-content: space-around;
|
||||||
|
padding: 6px 0 calc(6px + env(safe-area-inset-bottom));
|
||||||
|
background: var(--bg-surface-solid);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
z-index: 35;
|
||||||
|
}
|
||||||
|
.f-bn-item {
|
||||||
|
position: relative;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
width: 44px; height: 44px;
|
||||||
|
border: none; background: none; cursor: pointer;
|
||||||
|
color: var(--text-primary);
|
||||||
|
transition: color .15s, transform .1s;
|
||||||
|
}
|
||||||
|
.f-bn-item:active { transform: scale(.92); }
|
||||||
|
.f-bn-item svg { width: 26px; height: 26px; }
|
||||||
|
.f-bn-item.active { color: var(--teal); }
|
||||||
|
.f-bn-item.active::before {
|
||||||
|
content: ""; position: absolute; inset: 3px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(var(--teal-rgb), .12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create button — бирюзовая рамка как у старой кнопки «Разместить» */
|
||||||
|
.f-bn-create {
|
||||||
|
width: 44px; height: 44px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: var(--teal);
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: 0 2px 10px rgba(var(--teal-rgb), .35);
|
||||||
|
}
|
||||||
|
.f-bn-create:hover { background: var(--teal2); }
|
||||||
|
.f-bn-create svg { color: #fff; }
|
||||||
|
|
||||||
|
/* Profile avatar inside the nav */
|
||||||
|
.f-bn-profile .f-profile-avatar,
|
||||||
|
.f-bn-profile .f-profile-avatar-placeholder {
|
||||||
|
width: 28px; height: 28px;
|
||||||
|
}
|
||||||
|
.f-bn-profile .f-profile-avatar-placeholder { font-size: 1rem; }
|
||||||
|
.f-bn-item.f-bn-profile.active::before {
|
||||||
|
inset: -1px;
|
||||||
|
box-shadow: 0 0 0 2px var(--teal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Indicator: активные фильтры поиска */
|
||||||
|
.f-bn-dot {
|
||||||
|
position: absolute; top: 6px; right: 4px;
|
||||||
|
width: 8px; height: 8px; border-radius: 50%;
|
||||||
|
background: #ff3040;
|
||||||
|
box-shadow: 0 0 0 2px var(--bg-surface-solid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search panel — видна только во вкладке «Поиск» (на десктопе всегда) */
|
||||||
|
.f-search-panel { display: none; }
|
||||||
|
.f-app.f-search-view .f-search-panel { display: block; }
|
||||||
|
|
||||||
/* ── Feed Wrap + Scroll ── */
|
/* ── Feed Wrap + Scroll ── */
|
||||||
.f-wrap { display: flex; flex: 1; overflow: hidden; min-height: 0; }
|
.f-wrap { display: flex; flex: 1; overflow: hidden; min-height: 0; }
|
||||||
|
|
||||||
.f-feed {
|
.f-feed {
|
||||||
flex: 1; overflow-y: scroll; min-height: 0;
|
flex: 1; overflow-y: scroll; min-height: 0;
|
||||||
padding: 16px; display: flex; flex-direction: column; gap: 14px;
|
padding: 20px 16px; display: flex; flex-direction: column; gap: 16px;
|
||||||
|
width: 100%; max-width: 660px; margin: 0 auto;
|
||||||
}
|
}
|
||||||
.f-feed::-webkit-scrollbar { width: 4px; }
|
.f-feed::-webkit-scrollbar { width: 4px; }
|
||||||
.f-feed::-webkit-scrollbar-track { background: transparent; }
|
.f-feed::-webkit-scrollbar-track { background: transparent; }
|
||||||
.f-feed::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
|
.f-feed::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (min-width: 900px) {
|
||||||
/* Лента занимает весь экран без отступов */
|
.f-main-feed .f-topbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.f-search-panel {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.f-bottom-nav {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
.f-feed {
|
.f-feed {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
gap: 10px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Топбар компактнее */
|
|
||||||
.f-topbar {
|
.f-topbar {
|
||||||
padding: 10px 12px;
|
padding: 8px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Кнопка создания объявления — как «Войти» */
|
|
||||||
.f-post-btn {
|
.f-post-btn {
|
||||||
padding: 10px 14px;
|
padding: 8px 14px;
|
||||||
font-size: 0.8rem;
|
font-size: 0.78rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-login-btn {
|
.f-login-btn {
|
||||||
padding: 6px 14px;
|
padding: 6px 14px;
|
||||||
font-size: 0.8rem;
|
font-size: 0.78rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Фильтр компактнее */
|
|
||||||
.f-filter-bar {
|
.f-filter-bar {
|
||||||
padding: 10px 12px;
|
padding: 8px 12px;
|
||||||
gap: 8px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
.f-filter-btn {
|
.f-filter-btn {
|
||||||
padding: 8px 14px;
|
padding: 7px 13px;
|
||||||
font-size: 0.85rem;
|
font-size: 0.82rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Городской фильтр компактнее */
|
|
||||||
.f-city-filter-wrap { padding: 8px 12px; }
|
.f-city-filter-wrap { padding: 8px 12px; }
|
||||||
.f-city-ms-control { padding: 6px 10px; min-height: 40px; }
|
.f-city-ms-control { padding: 5px 12px; min-height: 38px; }
|
||||||
.f-city-ms-input { font-size: 0.85rem; }
|
.f-city-ms-input { font-size: 0.85rem; }
|
||||||
.f-city-ms-tag { font-size: 0.75rem; padding: 3px 8px; }
|
.f-city-ms-tag { font-size: 0.75rem; padding: 2px 8px; }
|
||||||
|
|
||||||
|
/* Нижняя панель fixed — освобождаем место в конце ленты */
|
||||||
|
.f-feed {
|
||||||
|
padding-bottom: calc(72px + env(safe-area-inset-bottom));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.f-post-btn {
|
.f-post-btn {
|
||||||
padding: 8px 8px;
|
padding: 7px 10px;
|
||||||
font-size: 0.68rem;
|
font-size: 0.7rem;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
@@ -309,13 +381,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.f-login-btn {
|
.f-login-btn {
|
||||||
padding: 4px 8px;
|
padding: 4px 10px;
|
||||||
font-size: 0.68rem;
|
font-size: 0.7rem;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-filter-btn {
|
.f-filter-btn {
|
||||||
padding: 8px 12px;
|
padding: 7px 12px;
|
||||||
font-size: 0.8rem;
|
font-size: 0.78rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
.f-m-field:focus { border-color: var(--teal); background: rgba(var(--teal-rgb), .07); box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .12); }
|
.f-m-field:focus { border-color: var(--teal); background: rgba(var(--teal-rgb), .07); box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .12); }
|
||||||
.f-m-field::placeholder { color: var(--muted); }
|
.f-m-field::placeholder { color: var(--muted); }
|
||||||
.f-m-field option { background: var(--bg-surface-solid); color: var(--text-primary); }
|
.f-m-field option { background: var(--bg-surface-solid); color: var(--text-primary); }
|
||||||
.f-m-field.err { border-color: rgba(255,107,107,.55); }
|
.f-m-field.err { border-color: rgba(237,73,86,.55); }
|
||||||
|
|
||||||
/* Type Toggle */
|
/* Type Toggle */
|
||||||
.f-type-toggle { display: flex; gap: 8px; }
|
.f-type-toggle { display: flex; gap: 8px; }
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
color: var(--muted); font-family: var(--font); font-size: .85rem;
|
color: var(--muted); font-family: var(--font); font-size: .85rem;
|
||||||
font-weight: 800; cursor: pointer; text-align: center; transition: all .2s;
|
font-weight: 800; cursor: pointer; text-align: center; transition: all .2s;
|
||||||
}
|
}
|
||||||
.f-type-opt.loss { border-color: rgba(255,107,107,.5); background: rgba(255,107,107,.12); color: #ff6b6b; }
|
.f-type-opt.loss { border-color: rgba(237,73,86,.5); background: rgba(237,73,86,.12); color: #ff6b6b; }
|
||||||
.f-type-opt.found { border-color: rgba(var(--teal-rgb), .5); background: rgba(var(--teal-rgb), .1); color: var(--teal); }
|
.f-type-opt.found { border-color: rgba(var(--teal-rgb), .5); background: rgba(var(--teal-rgb), .1); color: var(--teal); }
|
||||||
|
|
||||||
/* Map picker */
|
/* Map picker */
|
||||||
@@ -211,13 +211,13 @@
|
|||||||
/* Submit Button */
|
/* Submit Button */
|
||||||
.f-m-submit {
|
.f-m-submit {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(90deg, var(--teal2), var(--teal), var(--teal2));
|
background: var(--teal);
|
||||||
background-size: 200% 100%; border: none; border-radius: 13px;
|
border: none; border-radius: 13px;
|
||||||
padding: 14px; color: #082320; font-family: var(--font);
|
padding: 14px; color: #fff; font-family: var(--font);
|
||||||
font-size: 1rem; font-weight: 900; cursor: pointer; margin-top: 6px;
|
font-size: 1rem; font-weight: 800; cursor: pointer; margin-top: 6px;
|
||||||
animation: shimmer 3s linear infinite; transition: opacity .15s, transform .15s;
|
transition: background .15s, opacity .15s, transform .15s;
|
||||||
}
|
}
|
||||||
.f-m-submit:hover:not(:disabled) { opacity: .88; transform: translateY(-1px); }
|
.f-m-submit:hover:not(:disabled) { background: var(--teal2); transform: translateY(-1px); }
|
||||||
.f-m-submit:active:not(:disabled) { transform: translateY(0); }
|
.f-m-submit:active:not(:disabled) { transform: translateY(0); }
|
||||||
.f-m-submit:disabled { opacity: .5; cursor: not-allowed; animation: none; background: var(--muted2); color: var(--muted); }
|
.f-m-submit:disabled { opacity: .5; cursor: not-allowed; animation: none; background: var(--muted2); color: var(--muted); }
|
||||||
.f-m-submit-row { display: flex; align-items: center; justify-content: center; gap: 8px; }
|
.f-m-submit-row { display: flex; align-items: center; justify-content: center; gap: 8px; }
|
||||||
@@ -225,18 +225,18 @@
|
|||||||
/* ── Modal Logout Button ── */
|
/* ── Modal Logout Button ── */
|
||||||
.f-modal-logout {
|
.f-modal-logout {
|
||||||
display: block; width: 100%; margin-top: 16px; padding: 10px;
|
display: block; width: 100%; margin-top: 16px; padding: 10px;
|
||||||
border-radius: 10px; border: 1px solid rgba(255,107,107,.3);
|
border-radius: 10px; border: 1px solid rgba(237,73,86,.3);
|
||||||
background: rgba(255,107,107,.08); color: rgba(255,107,107,.8);
|
background: rgba(237,73,86,.08); color: rgba(237,73,86,.8);
|
||||||
font-family: var(--font); font-size: .9rem; font-weight: 700; cursor: pointer;
|
font-family: var(--font); font-size: .9rem; font-weight: 700; cursor: pointer;
|
||||||
transition: background .15s, border-color .15s;
|
transition: background .15s, border-color .15s;
|
||||||
}
|
}
|
||||||
.f-modal-logout:hover {
|
.f-modal-logout:hover {
|
||||||
background: rgba(255,107,107,.18);
|
background: rgba(237,73,86,.18);
|
||||||
border-color: rgba(255,107,107,.5);
|
border-color: rgba(237,73,86,.5);
|
||||||
}
|
}
|
||||||
.f-m-spinner {
|
.f-m-spinner {
|
||||||
width: 16px; height: 16px;
|
width: 16px; height: 16px;
|
||||||
border: 2px solid var(--border); border-top-color: var(--teal);
|
border: 2px solid rgba(255,255,255,.4); border-top-color: #fff;
|
||||||
border-radius: 50%; animation: spin .7s linear infinite;
|
border-radius: 50%; animation: spin .7s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +302,7 @@
|
|||||||
.f-rules-input:checked + .f-rules-checkmark::after {
|
.f-rules-input:checked + .f-rules-checkmark::after {
|
||||||
content: ""; position: absolute; left: 5px; top: 1px;
|
content: ""; position: absolute; left: 5px; top: 1px;
|
||||||
width: 6px; height: 10px;
|
width: 6px; height: 10px;
|
||||||
border: solid #082320; border-width: 0 2.5px 2.5px 0;
|
border: solid #fff; border-width: 0 2.5px 2.5px 0;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
.f-rules-input:focus + .f-rules-checkmark {
|
.f-rules-input:focus + .f-rules-checkmark {
|
||||||
@@ -357,15 +357,13 @@
|
|||||||
.f-result-btn:hover { opacity: .88; transform: translateY(-1px); }
|
.f-result-btn:hover { opacity: .88; transform: translateY(-1px); }
|
||||||
.f-result-btn:active { transform: translateY(0); }
|
.f-result-btn:active { transform: translateY(0); }
|
||||||
.f-result-btn.ok {
|
.f-result-btn.ok {
|
||||||
background: linear-gradient(90deg, var(--teal2), var(--teal), var(--teal2));
|
background: var(--teal);
|
||||||
background-size: 200% 100%;
|
color: #fff;
|
||||||
color: #082320;
|
|
||||||
animation: shimmer 3s linear infinite;
|
|
||||||
}
|
}
|
||||||
.f-result-btn.err {
|
.f-result-btn.err {
|
||||||
background: rgba(255, 107, 107, .12);
|
background: rgba(237, 73, 86, .1);
|
||||||
border: 1.5px solid rgba(255, 107, 107, .35);
|
border: 1.5px solid rgba(237, 73, 86, .35);
|
||||||
color: #ff6b6b;
|
color: #ed4956;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-map-frame {
|
.f-map-frame {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* ── Reviews Page ── */
|
/* ── Reviews Page ── */
|
||||||
.rv-page-title {
|
.rv-page-title {
|
||||||
font-size: 1.15rem;
|
font-size: 1.1rem;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -12,6 +12,9 @@
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
max-width: 900px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Left sidebar (summary + form) ── */
|
/* ── Left sidebar (summary + form) ── */
|
||||||
@@ -25,7 +28,7 @@
|
|||||||
|
|
||||||
/* ── Summary block ── */
|
/* ── Summary block ── */
|
||||||
.rv-summary {
|
.rv-summary {
|
||||||
background: rgba(255, 255, 255, .04);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@@ -77,7 +80,7 @@
|
|||||||
.rv-dist-bar {
|
.rv-dist-bar {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
background: rgba(255, 255, 255, .06);
|
background: var(--bg-input);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@@ -101,7 +104,7 @@
|
|||||||
gap: 3px;
|
gap: 3px;
|
||||||
}
|
}
|
||||||
.rv-star {
|
.rv-star {
|
||||||
color: var(--muted);
|
color: var(--muted2);
|
||||||
transition: color .15s, transform .15s;
|
transition: color .15s, transform .15s;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -117,7 +120,7 @@
|
|||||||
|
|
||||||
/* ── Review Form ── */
|
/* ── Review Form ── */
|
||||||
.rv-form {
|
.rv-form {
|
||||||
background: rgba(255, 255, 255, .04);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@@ -142,14 +145,14 @@
|
|||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
.rv-form-error {
|
.rv-form-error {
|
||||||
color: #ff6b6b;
|
color: var(--err);
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.rv-form-textarea {
|
.rv-form-textarea {
|
||||||
background: var(--bg-input);
|
background: var(--bg-input);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 10px;
|
border-radius: 12px;
|
||||||
padding: 12px 14px;
|
padding: 12px 14px;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-family: var(--font);
|
font-family: var(--font);
|
||||||
@@ -160,7 +163,7 @@
|
|||||||
.rv-form-textarea:focus {
|
.rv-form-textarea:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: var(--teal);
|
border-color: var(--teal);
|
||||||
box-shadow: 0 0 0 3px rgba(45, 224, 200, .12);
|
box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .12);
|
||||||
}
|
}
|
||||||
.rv-form-textarea::placeholder {
|
.rv-form-textarea::placeholder {
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
@@ -176,19 +179,19 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.rv-form-submit {
|
.rv-form-submit {
|
||||||
background: linear-gradient(135deg, var(--teal2), var(--teal));
|
background: var(--teal);
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px 22px;
|
padding: 10px 22px;
|
||||||
color: #111;
|
color: #fff;
|
||||||
font-family: var(--font);
|
font-family: var(--font);
|
||||||
font-size: .85rem;
|
font-size: .85rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: opacity .15s, transform .15s;
|
transition: background .15s, transform .15s;
|
||||||
}
|
}
|
||||||
.rv-form-submit:hover:not(:disabled) {
|
.rv-form-submit:hover:not(:disabled) {
|
||||||
opacity: .9;
|
background: var(--teal2);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
.rv-form-submit:disabled {
|
.rv-form-submit:disabled {
|
||||||
@@ -198,7 +201,7 @@
|
|||||||
|
|
||||||
/* ── Login prompt ── */
|
/* ── Login prompt ── */
|
||||||
.rv-login-prompt {
|
.rv-login-prompt {
|
||||||
background: rgba(255, 255, 255, .04);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@@ -210,19 +213,19 @@
|
|||||||
margin: 0 0 14px;
|
margin: 0 0 14px;
|
||||||
}
|
}
|
||||||
.rv-login-btn {
|
.rv-login-btn {
|
||||||
background: linear-gradient(135deg, var(--teal2), var(--teal));
|
background: var(--teal);
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px 24px;
|
padding: 10px 24px;
|
||||||
color: #111;
|
color: #fff;
|
||||||
font-family: var(--font);
|
font-family: var(--font);
|
||||||
font-size: .85rem;
|
font-size: .85rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: opacity .15s;
|
transition: background .15s;
|
||||||
}
|
}
|
||||||
.rv-login-btn:hover {
|
.rv-login-btn:hover {
|
||||||
opacity: .9;
|
background: var(--teal2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Reviews List ── */
|
/* ── Reviews List ── */
|
||||||
@@ -236,7 +239,7 @@
|
|||||||
|
|
||||||
/* ── Review Card ── */
|
/* ── Review Card ── */
|
||||||
.rv-card {
|
.rv-card {
|
||||||
background: rgba(255, 255, 255, .04);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 18px 20px;
|
padding: 18px 20px;
|
||||||
@@ -247,7 +250,7 @@
|
|||||||
animation: rvCardIn .5s cubic-bezier(.34, 1.56, .64, 1) both;
|
animation: rvCardIn .5s cubic-bezier(.34, 1.56, .64, 1) both;
|
||||||
}
|
}
|
||||||
.rv-card:hover {
|
.rv-card:hover {
|
||||||
border-color: rgba(45, 224, 200, .25);
|
border-color: var(--muted2);
|
||||||
}
|
}
|
||||||
@keyframes rvCardIn {
|
@keyframes rvCardIn {
|
||||||
from { opacity: 0; transform: translateY(16px); }
|
from { opacity: 0; transform: translateY(16px); }
|
||||||
@@ -263,14 +266,14 @@
|
|||||||
width: 38px;
|
width: 38px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: rgba(45, 224, 200, .15);
|
background: var(--bg-input);
|
||||||
border: 2px solid rgba(45, 224, 200, .3);
|
border: 2px solid var(--border);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: var(--teal);
|
color: var(--muted);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.rv-card-meta {
|
.rv-card-meta {
|
||||||
@@ -288,6 +291,19 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
.rv-card-pending-badge {
|
||||||
|
align-self: flex-start;
|
||||||
|
font-size: .68rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--teal);
|
||||||
|
background: rgba(var(--teal-rgb), .1);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
}
|
||||||
|
.rv-card-pending {
|
||||||
|
border-style: dashed;
|
||||||
|
opacity: .85;
|
||||||
|
}
|
||||||
.rv-card-date {
|
.rv-card-date {
|
||||||
font-size: .72rem;
|
font-size: .72rem;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
|
|||||||
@@ -24,10 +24,10 @@
|
|||||||
|
|
||||||
/* Single section */
|
/* Single section */
|
||||||
.rules-section {
|
.rules-section {
|
||||||
border: 1px solid rgba(255,255,255,.07);
|
border: 1px solid var(--border);
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: rgba(255,255,255,.025);
|
background: var(--bg-card);
|
||||||
}
|
}
|
||||||
|
|
||||||
.rules-section-head {
|
.rules-section-head {
|
||||||
@@ -35,14 +35,14 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: 12px 16px 10px;
|
padding: 12px 16px 10px;
|
||||||
border-bottom: 1px solid rgba(255,255,255,.06);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.rules-num {
|
.rules-num {
|
||||||
min-width: 26px;
|
min-width: 26px;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
background: linear-gradient(135deg, #1fc9b0, #2de0c8);
|
background: var(--teal);
|
||||||
color: #082320;
|
color: #fff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: .75rem;
|
font-size: .75rem;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rules-title {
|
.rules-title {
|
||||||
color: #fff;
|
color: var(--text-primary);
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-size: .92rem;
|
font-size: .92rem;
|
||||||
letter-spacing: -.1px;
|
letter-spacing: -.1px;
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
/* Sub-section titles (3.1, 3.2 …) */
|
/* Sub-section titles (3.1, 3.2 …) */
|
||||||
.rules-sub-title {
|
.rules-sub-title {
|
||||||
color: rgba(255,255,255,.55);
|
color: var(--muted);
|
||||||
font-size: .75rem;
|
font-size: .75rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -113,11 +113,11 @@
|
|||||||
|
|
||||||
/* Warning paragraph */
|
/* Warning paragraph */
|
||||||
.rules-warn {
|
.rules-warn {
|
||||||
background: rgba(255,107,107,.1);
|
background: rgba(237,73,86,.08);
|
||||||
border: 1px solid rgba(255,107,107,.2);
|
border: 1px solid rgba(237,73,86,.25);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
color: #ff9999;
|
color: var(--err);
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
margin-top: 8px !important;
|
margin-top: 8px !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +1,217 @@
|
|||||||
|
/* ── Left Navigation (Instagram-style) ── */
|
||||||
|
|
||||||
.f-sb-head {
|
.f-sb-head {
|
||||||
padding: 22px 20px 16px;
|
padding: 16px 20px 20px;
|
||||||
display: flex; align-items: center; gap: 11px;
|
display: flex; align-items: center; gap: 11px;
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
}
|
}
|
||||||
.f-sb-logo {
|
.f-sb-logo {
|
||||||
width: 36px; height: 36px;
|
width: 40px; height: 40px;
|
||||||
background: linear-gradient(135deg, var(--teal2), var(--teal));
|
background: linear-gradient(45deg, #feda75, #fa7e1e, #d62976, #962fbf, #4f5bd5);
|
||||||
border-radius: 10px;
|
border-radius: 50%;
|
||||||
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
|
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.f-sb-name { color: var(--text-primary); font-weight: 900; font-size: 1.1rem; letter-spacing: -.3px; }
|
.f-sb-logo img { filter: brightness(0) invert(1); width: 20px; height: 20px; }
|
||||||
.f-sb-nav { padding: 12px 0; flex: 1; }
|
.f-sb-name {
|
||||||
.f-sb-bottom { padding: 12px 0; border-top: 1px solid var(--border); }
|
color: var(--text-primary); font-weight: 900; font-size: 1.15rem;
|
||||||
|
letter-spacing: -.4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.f-sb-nav { padding: 8px 8px; flex: 1; display: flex; flex-direction: column; gap: 4px; }
|
||||||
|
.f-sb-bottom { padding: 8px 8px 16px; border-top: 1px solid var(--border); }
|
||||||
|
|
||||||
.f-sb-item {
|
.f-sb-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 13px;
|
gap: 14px;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 11px 20px;
|
padding: 10px 12px;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background .15s, color .15s;
|
transition: background .15s, color .15s;
|
||||||
|
|
||||||
color: var(--muted);
|
color: var(--text-primary);
|
||||||
font: inherit;
|
font: inherit;
|
||||||
font-size: .9rem;
|
font-size: .92rem;
|
||||||
font-weight: 700;
|
font-weight: 500;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
border-left: 3px solid transparent;
|
|
||||||
background: none;
|
background: none;
|
||||||
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
.f-sb-item:hover { background: var(--hover-bg); color: var(--text-primary); }
|
.f-sb-item:hover { background: var(--hover-bg); }
|
||||||
.f-sb-item.active { background: rgba(var(--teal-rgb), .1); color: var(--teal); border-left-color: var(--teal); }
|
.f-sb-item.active { font-weight: 800; }
|
||||||
|
.f-sb-item svg { flex-shrink: 0; }
|
||||||
|
|
||||||
|
.f-sb-item.f-sb-create {
|
||||||
|
color: var(--teal);
|
||||||
|
}
|
||||||
|
.f-sb-item.f-sb-create svg { color: var(--teal); }
|
||||||
|
|
||||||
.f-sb-divider {
|
.f-sb-divider {
|
||||||
height: 1px; background: var(--border);
|
height: 1px; background: var(--border);
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
}
|
}
|
||||||
.f-right::-webkit-scrollbar { width: 3px; }
|
|
||||||
.f-right::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
|
|
||||||
.f-right-label {
|
|
||||||
font-size: .65rem; font-weight: 900;
|
|
||||||
text-transform: uppercase; letter-spacing: .8px; color: var(--muted2);
|
|
||||||
}
|
|
||||||
.f-right-empty {
|
|
||||||
flex: 1; display: flex; flex-direction: column;
|
|
||||||
align-items: center; justify-content: center;
|
|
||||||
gap: 12px; text-align: center;
|
|
||||||
border: 1.5px dashed var(--border);
|
|
||||||
border-radius: 16px; padding: 20px; min-height: 200px;
|
|
||||||
}
|
|
||||||
.f-right-empty-icon { font-size: 2rem; opacity: .2; }
|
|
||||||
.f-right-empty-text { color: var(--muted); font-size: .78rem; line-height: 1.5; }
|
|
||||||
.f-add-promo-btn {
|
|
||||||
background: rgba(var(--teal-rgb), .08); border: 1px solid rgba(var(--teal-rgb), .25);
|
|
||||||
border-radius: 10px; padding: 9px 14px;
|
|
||||||
color: var(--teal); font-family: var(--font);
|
|
||||||
font-size: .8rem; font-weight: 800; cursor: pointer;
|
|
||||||
transition: background .2s, transform .15s;
|
|
||||||
}
|
|
||||||
.f-add-promo-btn:hover { background: rgba(var(--teal-rgb), .15); transform: translateY(-1px); }
|
|
||||||
|
|
||||||
|
/* Unread badge (Instagram red) */
|
||||||
|
.f-sb-unread-badge {
|
||||||
|
background: #ff3040;
|
||||||
|
color: #fff;
|
||||||
|
font-size: .65rem;
|
||||||
|
font-weight: 800;
|
||||||
|
min-width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 9px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Profile row at nav bottom ── */
|
||||||
|
.f-sb-profile {
|
||||||
|
display: flex; align-items: center; gap: 12px;
|
||||||
|
padding: 10px 12px; border-radius: 10px;
|
||||||
|
cursor: pointer; transition: background .15s;
|
||||||
|
width: 100%; border: none; background: none;
|
||||||
|
text-align: left; font-family: var(--font);
|
||||||
|
}
|
||||||
|
.f-sb-profile:hover { background: var(--hover-bg); }
|
||||||
|
.f-sb-profile .f-profile-avatar {
|
||||||
|
width: 32px; height: 32px;
|
||||||
|
border: 2px solid var(--border);
|
||||||
|
}
|
||||||
|
.f-sb-profile .f-profile-avatar-placeholder {
|
||||||
|
width: 32px; height: 32px; font-size: 1rem;
|
||||||
|
}
|
||||||
|
.f-sb-profile-info { flex: 1; min-width: 0; }
|
||||||
|
.f-sb-profile-name {
|
||||||
|
color: var(--text-primary); font-weight: 700; font-size: .85rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.f-sb-profile-login {
|
||||||
|
color: var(--muted); font-size: .72rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── The drawer (mobile) ── */
|
||||||
.f-sidebar {
|
.f-sidebar {
|
||||||
width: 260px; min-width: 260px;
|
width: 260px; min-width: 260px;
|
||||||
background: var(--bg-surface);
|
background: var(--bg-surface-solid);
|
||||||
backdrop-filter: blur(18px);
|
|
||||||
-webkit-backdrop-filter: blur(18px);
|
|
||||||
border-right: 1px solid var(--border);
|
border-right: 1px solid var(--border);
|
||||||
display: flex; flex-direction: column;
|
display: flex; flex-direction: column;
|
||||||
|
position: fixed; left: 0; top: 0; height: 100%; z-index: 50;
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
transition: transform .32s cubic-bezier(.4,0,.2,1);
|
transition: transform .32s cubic-bezier(.4,0,.2,1);
|
||||||
position: fixed; left: 0; top: 0; height: 100%; z-index: 50;
|
|
||||||
}
|
}
|
||||||
.f-sidebar.open { transform: translateX(0); }
|
.f-sidebar.open { transform: translateX(0); }
|
||||||
|
|
||||||
.f-right {
|
@media (min-width: 900px) {
|
||||||
width: 220px; min-width: 220px; padding: 16px 12px;
|
.f-sidebar {
|
||||||
border-left: 1px solid var(--border);
|
position: relative;
|
||||||
background: var(--bg-surface);
|
transform: none;
|
||||||
backdrop-filter: blur(14px);
|
width: 244px; min-width: 244px;
|
||||||
-webkit-backdrop-filter: blur(14px);
|
height: 100vh;
|
||||||
display: flex; flex-direction: column; gap: 14px; overflow-y: auto;
|
}
|
||||||
|
.f-overlay { display: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Profile Component ── */
|
/* ── Right panel (suggestions, Instagram-style) ── */
|
||||||
|
.f-right {
|
||||||
|
width: 320px; min-width: 320px; padding: 24px 16px 24px 32px;
|
||||||
|
border-left: 1px solid transparent;
|
||||||
|
background: var(--bg-app);
|
||||||
|
display: flex; flex-direction: column; gap: 14px; overflow-y: auto;
|
||||||
|
}
|
||||||
|
.f-right::-webkit-scrollbar { width: 3px; }
|
||||||
|
.f-right::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
|
||||||
|
|
||||||
|
.f-right-header {
|
||||||
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.f-right-label {
|
||||||
|
font-size: .8rem; font-weight: 700;
|
||||||
|
color: var(--muted);
|
||||||
|
}
|
||||||
|
.f-right-link {
|
||||||
|
font-size: .75rem; font-weight: 700; color: var(--text-primary);
|
||||||
|
background: none; border: none; cursor: pointer; font-family: var(--font);
|
||||||
|
transition: color .15s;
|
||||||
|
}
|
||||||
|
.f-right-link:hover { color: var(--muted); }
|
||||||
|
|
||||||
|
.f-right-profile {
|
||||||
|
display: flex; align-items: center; gap: 12px;
|
||||||
|
padding: 8px 0; cursor: pointer;
|
||||||
|
}
|
||||||
|
.f-right-profile-info { flex: 1; min-width: 0; }
|
||||||
|
.f-right-profile-name {
|
||||||
|
color: var(--text-primary); font-weight: 700; font-size: .86rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.f-right-profile-sub {
|
||||||
|
color: var(--muted); font-size: .74rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.f-right-action-btn {
|
||||||
|
background: none; border: none; cursor: pointer;
|
||||||
|
color: var(--teal); font-family: var(--font);
|
||||||
|
font-size: .78rem; font-weight: 700; padding: 6px 10px;
|
||||||
|
border-radius: 8px; transition: background .15s, color .15s;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.f-right-action-btn:hover { background: rgba(var(--teal-rgb), .1); }
|
||||||
|
|
||||||
|
/* Suggestion rows */
|
||||||
|
.f-ig-ring {
|
||||||
|
width: 40px; height: 40px; border-radius: 50%;
|
||||||
|
background: linear-gradient(45deg, #feda75, #fa7e1e, #d62976, #962fbf, #4f5bd5);
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.f-ig-ring-sm { width: 34px; height: 34px; }
|
||||||
|
.f-ig-avatar {
|
||||||
|
width: 34px; height: 34px; border-radius: 50%;
|
||||||
|
background: var(--bg-app);
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
font-size: 1rem; overflow: hidden;
|
||||||
|
}
|
||||||
|
.f-ig-ring-sm .f-ig-avatar { width: 28px; height: 28px; font-size: .85rem; }
|
||||||
|
.f-ig-avatar img { width: 100%; height: 100%; object-fit: cover; }
|
||||||
|
|
||||||
|
.f-right-suggest {
|
||||||
|
display: flex; align-items: center; gap: 12px;
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
.f-right-suggest-info { flex: 1; min-width: 0; }
|
||||||
|
.f-right-suggest-name {
|
||||||
|
color: var(--text-primary); font-weight: 700; font-size: .86rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.f-right-suggest-sub {
|
||||||
|
color: var(--muted); font-size: .74rem;
|
||||||
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer small links */
|
||||||
|
.f-right-foot {
|
||||||
|
display: flex; flex-wrap: wrap; gap: 4px 12px;
|
||||||
|
margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.f-right-foot span {
|
||||||
|
color: var(--muted2); font-size: .68rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.f-right {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Profile Component (reused in modal header) ── */
|
||||||
.f-profile {
|
.f-profile {
|
||||||
display: flex; align-items: center; gap: 12px;
|
display: flex; align-items: center; gap: 12px;
|
||||||
padding: 10px 14px; border-radius: 12px;
|
padding: 10px 14px; border-radius: 12px;
|
||||||
@@ -93,20 +219,20 @@
|
|||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
.f-profile:hover {
|
.f-profile:hover {
|
||||||
background: rgba(45, 224, 200, .08);
|
background: rgba(var(--teal-rgb), .08);
|
||||||
border-color: rgba(45, 224, 200, .25);
|
border-color: rgba(var(--teal-rgb), .25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-profile-avatar {
|
.f-profile-avatar {
|
||||||
width: 40px; height: 40px;
|
width: 40px; height: 40px;
|
||||||
border-radius: 50%; object-fit: cover;
|
border-radius: 50%; object-fit: cover;
|
||||||
flex-shrink: 0; border: 2px solid var(--teal);
|
flex-shrink: 0; border: 2px solid var(--border);
|
||||||
}
|
}
|
||||||
.f-profile-avatar-placeholder {
|
.f-profile-avatar-placeholder {
|
||||||
width: 40px; height: 40px;
|
width: 40px; height: 40px;
|
||||||
border-radius: 50%; flex-shrink: 0;
|
border-radius: 50%; flex-shrink: 0;
|
||||||
background: rgba(45, 224, 200, .15);
|
background: var(--bg-input);
|
||||||
border: 2px solid rgba(45, 224, 200, .3);
|
border: 2px solid var(--border);
|
||||||
display: flex; align-items: center; justify-content: center;
|
display: flex; align-items: center; justify-content: center;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
}
|
}
|
||||||
@@ -120,9 +246,3 @@
|
|||||||
color: var(--muted); font-size: .7rem;
|
color: var(--muted); font-size: .7rem;
|
||||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
|
||||||
.f-right {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,78 +1,44 @@
|
|||||||
/* ── Post Button (topbar CTA) ── */
|
/* ── Post Button (topbar CTA, Instagram blue) ── */
|
||||||
.f-post-btn {
|
.f-post-btn {
|
||||||
display: flex; align-items: center; gap: 6px;
|
display: flex; align-items: center; gap: 6px;
|
||||||
padding: 14px 18px; border-radius: 14px;
|
padding: 8px 16px; border-radius: 999px;
|
||||||
font-family: var(--font); font-weight: 900; font-size: 0.85rem; letter-spacing: 0.3px;
|
font-family: var(--font); font-weight: 700; font-size: 0.82rem;
|
||||||
color: var(--teal);
|
color: #fff;
|
||||||
background: rgba(var(--teal-rgb), 0.12); backdrop-filter: blur(14px);
|
background: var(--teal);
|
||||||
border: 1px solid rgba(var(--teal-rgb), 0.25);
|
border: 1px solid transparent;
|
||||||
box-shadow: 0 4px 12px rgba(0,0,0,0.35), inset 0 0 6px rgba(var(--teal-rgb), 0.15), 0 0 9px rgba(var(--teal-rgb), 0.15);
|
box-shadow: 0 2px 8px rgba(var(--teal-rgb), .3);
|
||||||
cursor: pointer; transition: all 0.25s ease;
|
cursor: pointer; transition: all 0.2s ease;
|
||||||
position: relative; overflow: hidden;
|
white-space: nowrap;
|
||||||
animation: postBtnGlow 3s ease-in-out infinite;
|
|
||||||
}
|
|
||||||
.f-post-btn::before {
|
|
||||||
content: ""; position: absolute; top: 0; left: 0;
|
|
||||||
width: 60%; height: 100%;
|
|
||||||
background: linear-gradient(105deg, transparent, rgba(255,255,255,0.5) 45%, rgba(255,255,255,0.15) 62%, transparent);
|
|
||||||
transform: skewX(-20deg) translateX(-150%);
|
|
||||||
pointer-events: none;
|
|
||||||
animation: postBtnShine 2.6s ease-in-out infinite;
|
|
||||||
}
|
}
|
||||||
.f-post-btn:hover {
|
.f-post-btn:hover {
|
||||||
transform: translateY(-2px) scale(1.02);
|
background: var(--teal2);
|
||||||
border-color: rgba(var(--teal-rgb), 0.5);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 6px 16px rgba(0,0,0,0.45), inset 0 0 9px rgba(var(--teal-rgb), 0.25), 0 0 13px rgba(var(--teal-rgb), 0.35);
|
|
||||||
}
|
}
|
||||||
.f-post-btn:active {
|
.f-post-btn:active { transform: translateY(0) scale(.98); }
|
||||||
transform: translateY(0) scale(0.98);
|
|
||||||
box-shadow: 0 2px 6px rgba(0,0,0,0.4), inset 0 0 5px rgba(var(--teal-rgb), 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes postBtnShine {
|
|
||||||
0% { transform: skewX(-20deg) translateX(-150%); }
|
|
||||||
55% { transform: skewX(-20deg) translateX(250%); }
|
|
||||||
100% { transform: skewX(-20deg) translateX(250%); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes postBtnGlow {
|
|
||||||
0%, 100% { box-shadow: 0 4px 12px rgba(0,0,0,0.35), inset 0 0 6px rgba(var(--teal-rgb), 0.15), 0 0 8px rgba(var(--teal-rgb), 0.25); }
|
|
||||||
50% { box-shadow: 0 4px 12px rgba(0,0,0,0.35), inset 0 0 12px rgba(var(--teal-rgb), 0.3), 0 0 18px rgba(var(--teal-rgb), 0.5); }
|
|
||||||
}
|
|
||||||
/* ── Login Button (topbar) ── */
|
|
||||||
.f-login-btn {
|
|
||||||
display: flex; align-items: center; gap: 6px;
|
|
||||||
padding: 8px 18px; border-radius: 14px;
|
|
||||||
font-family: var(--font); font-weight: 800; font-size: 0.85rem; letter-spacing: 0.3px;
|
|
||||||
color: var(--teal);
|
|
||||||
background: rgba(var(--teal-rgb), 0.12); backdrop-filter: blur(14px);
|
|
||||||
border: 1px solid rgba(var(--teal-rgb), 0.25);
|
|
||||||
box-shadow: 0 6px 18px rgba(0,0,0,0.35), inset 0 0 10px rgba(var(--teal-rgb), 0.12), 0 0 14px rgba(var(--teal-rgb), 0.12);
|
|
||||||
cursor: pointer; transition: all 0.25s ease;
|
|
||||||
position: relative; overflow: hidden; white-space: nowrap;
|
|
||||||
}
|
|
||||||
.f-login-btn::before {
|
|
||||||
content: ""; position: absolute; inset: 0;
|
|
||||||
background: linear-gradient(120deg, rgba(255,255,255,0.25), rgba(255,255,255,0.05) 40%, transparent 60%);
|
|
||||||
opacity: 0.4; pointer-events: none;
|
|
||||||
}
|
|
||||||
.f-login-btn:hover {
|
|
||||||
transform: translateY(-2px) scale(1.02);
|
|
||||||
border-color: rgba(var(--teal-rgb), 0.5);
|
|
||||||
box-shadow: 0 10px 26px rgba(0,0,0,0.45), inset 0 0 14px rgba(var(--teal-rgb), 0.22), 0 0 20px rgba(var(--teal-rgb), 0.3);
|
|
||||||
}
|
|
||||||
.f-login-btn:active {
|
|
||||||
transform: translateY(0) scale(0.98);
|
|
||||||
box-shadow: 0 3px 10px rgba(0,0,0,0.4), inset 0 0 8px rgba(var(--teal-rgb), 0.18);
|
|
||||||
}
|
|
||||||
|
|
||||||
.f-post-btn span {
|
.f-post-btn span {
|
||||||
display: flex; align-items: center; justify-content: center;
|
display: flex; align-items: center; justify-content: center;
|
||||||
width: 16px; height: 16px; border-radius: 50%;
|
width: 16px; height: 16px; border-radius: 50%;
|
||||||
background: rgba(var(--teal-rgb), 0.2); box-shadow: 0 0 6px rgba(var(--teal-rgb), 0.4);
|
background: rgba(255,255,255,.25);
|
||||||
font-size: 0.9rem; transform: translateY(-1px);
|
font-size: 0.9rem; transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Login Button (topbar) ── */
|
||||||
|
.f-login-btn {
|
||||||
|
display: flex; align-items: center; gap: 6px;
|
||||||
|
padding: 8px 18px; border-radius: 999px;
|
||||||
|
font-family: var(--font); font-weight: 700; font-size: 0.85rem;
|
||||||
|
color: var(--teal);
|
||||||
|
background: var(--bg-input);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
cursor: pointer; transition: all 0.2s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.f-login-btn:hover {
|
||||||
|
background: rgba(var(--teal-rgb), .1);
|
||||||
|
border-color: rgba(var(--teal-rgb), .4);
|
||||||
|
}
|
||||||
|
.f-login-btn:active { transform: translateY(0) scale(.98); }
|
||||||
|
|
||||||
/* ── Feed Empty / Error States ── */
|
/* ── Feed Empty / Error States ── */
|
||||||
.f-center {
|
.f-center {
|
||||||
flex: 1; display: flex; flex-direction: column;
|
flex: 1; display: flex; flex-direction: column;
|
||||||
@@ -91,6 +57,7 @@
|
|||||||
border-radius: 50%; animation: spin .7s linear infinite; flex-shrink: 0;
|
border-radius: 50%; animation: spin .7s linear infinite; flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Toast ── */
|
||||||
.f-toast {
|
.f-toast {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 24px;
|
bottom: 24px;
|
||||||
@@ -100,23 +67,15 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, .3);
|
box-shadow: 0 4px 16px rgba(0, 0, 0, .25);
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
animation: f-toast-in .2s ease-out;
|
animation: f-toast-in .2s ease-out;
|
||||||
}
|
}
|
||||||
|
.f-toast-error { background: #ed4956; }
|
||||||
.f-toast-error {
|
.f-toast-success { background: #0095f6; }
|
||||||
background: #e5484d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.f-toast-success {
|
|
||||||
background: #2de0c8;
|
|
||||||
color: #0a0a0a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.f-toast-close {
|
.f-toast-close {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -126,7 +85,6 @@
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes f-toast-in {
|
@keyframes f-toast-in {
|
||||||
from { opacity: 0; transform: translate(-50%, 8px); }
|
from { opacity: 0; transform: translate(-50%, 8px); }
|
||||||
to { opacity: 1; transform: translate(-50%, 0); }
|
to { opacity: 1; transform: translate(-50%, 0); }
|
||||||
|
|||||||
Reference in New Issue
Block a user