5 커밋 a8d99a3370 ... be55b4eddc

작성자 SHA1 메시지 날짜
  0225015 be55b4eddc Initial Django project structure with accounts app 1 개월 전
  0225015 f4a1e7e99f Add .gitignore to exclude venv and other files 1 개월 전
  0225015 82affc1cf0 Add initial dependencies 1 개월 전
  0225015 a8d99a3370 Add 同趣U.html preview page 2 달 전
  0225015 c9758b503c Add README.md 2 달 전
17개의 변경된 파일253개의 추가작업 그리고 1120개의 파일을 삭제
  1. 20 0
      .gitignore
  2. 0 113
      README.md
  3. 0 0
      accounts/__init__.py
  4. 3 0
      accounts/admin.py
  5. 6 0
      accounts/apps.py
  6. 0 0
      accounts/migrations/__init__.py
  7. 3 0
      accounts/models.py
  8. 3 0
      accounts/tests.py
  9. 3 0
      accounts/views.py
  10. 0 0
      config/__init__.py
  11. 16 0
      config/asgi.py
  12. 138 0
      config/settings.py
  13. 23 0
      config/urls.py
  14. 16 0
      config/wsgi.py
  15. 22 0
      manage.py
  16. BIN
      requirements.txt
  17. 0 1007
      同趣U.html

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+# Virtualenv
+venv/
+/venv/
+
+# Python bytecode and cache
+__pycache__/
+*.py[cod]
+*$py.class
+
+# Django specific
+*.log
+db.sqlite3
+db.sqlite3-journal
+local_settings.py # 如果你打算用一个本地独有的设置文件
+
+# IDE / Editor specific (optional, but good practice)
+.vscode/
+.idea/
+*.swp
+*~

+ 0 - 113
README.md

@@ -1,113 +0,0 @@
-# 同趣U (InterestU) - 大学生兴趣社交平台
-
-[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) <!-- 你可以选择一个适合的开源协议 -->
-<!-- 可选: [![Build Status](URL_TO_YOUR_CI_BADGE)](URL_TO_YOUR_CI_SERVER) -->
-<!-- 可选: [![Version](URL_TO_YOUR_VERSION_BADGE)](URL_TO_YOUR_PACKAGE_REGISTRY) -->
-
-**同趣U (InterestU)** 是一款专为在校大学生设计的移动社交应用,旨在帮助他们基于共同的兴趣爱好轻松发现伙伴、组织活动、拓展社交圈,让大学生活更加丰富多彩。
-
-## 项目背景
-
-在当前的大学校园中,学生们拥有多元的兴趣和强烈的社交需求,但常常面临以下痛点:
-
-*   **信息不对称:** 难以高效找到与自己有相同小众或特定兴趣的伙伴。
-*   **平台错位:** 现有通用社交平台难以满足纯粹基于兴趣的连接需求。
-*   **连接障碍:** 主动发起线下或线上连接存在一定的社交压力。
-*   **活动分散:** 校园内外的兴趣活动信息零散,不易发现和组织。
-
-“同趣U”致力于解决这些问题,为大学生提供一个专注、高效、友好的兴趣社交环境。
-
-## 核心目标
-
-*   **精准匹配:** 通过精细化的兴趣标签和智能推荐,帮助用户快速找到志同道合的人。
-*   **轻松连接:** 提供低压力的连接方式,鼓励用户发起和参与互动。
-*   **场景丰富:** 支持从线上聊天到线下活动组织的多元社交场景。
-*   **校园认证:** (可选,推荐)通过校园邮箱等方式认证,营造更真实、安全的社区氛围。
-
-## 主要功能 (设想)
-
-### 1. 核心功能 (MVP)
-
-*   **用户注册与登录:** 支持手机号/邮箱注册,可选第三方登录及校园邮箱认证。
-*   **个人资料:** 展示昵称、头像、学校、简介,并突出显示用户的兴趣标签和当前状态(如“想找人一起...”)。
-*   **精细化兴趣标签系统:** 用户可选择预设标签或自定义兴趣,支持多维度定义。
-*   **智能匹配与发现:**
-    *   **推荐:** 基于共同兴趣、学校、地理位置(可选)等因素推荐用户。
-    *   **搜索:** 支持按兴趣、用户、学校等关键词搜索。
-*   **低压力连接:**
-    *   **“打个招呼”/“Vibe Check”:** 代替传统的“添加好友”,降低发起连接的门槛。
-    *   **双向确认开启私信。**
-*   **基础即时通讯 (私信):** 支持文本、表情,未来可扩展图片、语音。
-*   **通知中心:** 聚合新招呼、新消息、系统通知等。
-
-### 2. 特色/进阶功能
-
-*   **兴趣圈子/小组:**
-    *   用户可创建或加入基于特定兴趣或学校的公开/私密小组。
-    *   小组内可发布话题、组织讨论、共享资源。
-*   **活动发布与匹配:**
-    *   用户可发布线上/线下活动邀约(如组队学习、看电影、运动等)。
-    *   其他用户可浏览、筛选、报名参加活动。
-*   **技能交换/互助:**
-    *   用户可发布自己能提供的技能或需要的帮助,进行匹配。
-*   **地图模式 (LBS - 隐私优先):**
-    *   (需用户授权)在地图上模糊显示附近有相同兴趣的用户或活动。
-*   **游戏化元素 (可选):**
-    *   积分、等级、徽章等,提升用户参与度和活跃度。
-
-## 技术栈 (设想)
-
-*   **前端 (App):** [例如: React Native, Flutter, Swift (iOS), Kotlin (Android)]
-*   **后端:** [例如: Node.js (Express/NestJS), Python (Django/Flask), Java (Spring Boot), Go]
-*   **数据库:** [例如: PostgreSQL, MySQL, MongoDB, Firebase Realtime Database/Firestore]
-*   **即时通讯:** [例如: WebSocket, Socket.IO, 或第三方服务如 Firebase Cloud Messaging, Agora]
-*   **推荐算法:** [初步可基于标签匹配,后续可引入协同过滤、机器学习模型]
-*   **部署:** [例如: Docker, Kubernetes, AWS, Google Cloud, Vercel, Heroku]
-*   **版本控制:** Git & GitHub/GitLab/Bitbucket
-
-## 预览效果 (概念)
-
-*(此处可以链接到您的PPT预览截图,或者如果项目有UI设计稿,可以放几张关键页面的截图或链接到设计稿。)*
-
-例如:
-
-*   [首页推荐](link_to_home_preview.png)
-*   [兴趣选择](link_to_interests_preview.png)
-*   [小组详情](link_to_group_preview.png)
-
-## 如何贡献 (示例)
-
-我们欢迎各种形式的贡献!如果您对本项目感兴趣,可以通过以下方式参与:
-
-1.  **Fork** 本仓库
-2.  创建您的特性分支 (`git checkout -b feature/AmazingFeature`)
-3.  提交您的更改 (`git commit -m 'Add some AmazingFeature'`)
-4.  将您的更改推送到分支 (`git push origin feature/AmazingFeature`)
-5.  开启一个 **Pull Request**
-
-请确保您的代码遵循项目的编码规范,并添加必要的测试。
-
-## 待办事项 / 未来展望
-
-*   [ ] 完成详细的UI/UX设计。
-*   [ ] 搭建基础后端框架。
-*   [ ] 实现核心用户注册、资料、兴趣标签功能。
-*   [ ] 开发匹配算法V1。
-*   [ ] ... (根据项目实际情况列出)
-*   长期目标:打造成为大学生首选的兴趣社交平台,探索更多校园生活服务场景。
-
-## 许可证
-
-本项目采用 [MIT许可证](LICENSE.md) <!-- 确保你创建了相应的LICENSE.md文件 -->。
-
----
-
-**使用说明:**
-
-*   **方括号 `[]` 中的内容**:是提示您需要根据实际情况填写或选择的部分。
-*   **链接 `(URL_TO_...)` 或 `(link_to_...)`**:需要替换为实际的链接地址。
-*   **技术栈、待办事项等**:都是示例,请根据您的具体规划调整。
-*   **开源协议**:MIT是一个比较宽松的协议,您可以根据需要选择其他协议。
-*   **预览效果**:如果您有原型或设计稿,嵌入图片或链接会非常有帮助。
-
-这个 `README.md` 提供了一个良好的起点,您可以根据项目的演进不断更新它。

+ 0 - 0
accounts/__init__.py


+ 3 - 0
accounts/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 6 - 0
accounts/apps.py

@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class AccountsConfig(AppConfig):
+    default_auto_field = "django.db.models.BigAutoField"
+    name = "accounts"

+ 0 - 0
accounts/migrations/__init__.py


+ 3 - 0
accounts/models.py

@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.

+ 3 - 0
accounts/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
accounts/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 0 - 0
config/__init__.py


+ 16 - 0
config/asgi.py

@@ -0,0 +1,16 @@
+"""
+ASGI config for config project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
+
+application = get_asgi_application()

+ 138 - 0
config/settings.py

@@ -0,0 +1,138 @@
+"""
+Django settings for config project.
+
+Generated by 'django-admin startproject' using Django 5.2.1.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.2/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/5.2/ref/settings/
+"""
+import os
+from pathlib import Path # Path 通常也在顶部
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = "django-insecure-12o%i9mzoyn8ua+j#l!8fed0-4d&y$x3%vtk00y82@97f9702+"
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'rest_framework',             # 新增
+    'rest_framework_simplejwt',   # 新增
+    'accounts.apps.AccountsConfig', # 新增,或者直接用 'accounts'
+                                  # 当你创建app时,Django会在app的apps.py中生成一个配置类,
+                                  # 使用完整的路径 'accounts.apps.AccountsConfig' 是更推荐的方式。
+]
+
+MIDDLEWARE = [
+    "django.middleware.security.SecurityMiddleware",
+    "django.contrib.sessions.middleware.SessionMiddleware",
+    "django.middleware.common.CommonMiddleware",
+    "django.middleware.csrf.CsrfViewMiddleware",
+    "django.contrib.auth.middleware.AuthenticationMiddleware",
+    "django.contrib.messages.middleware.MessageMiddleware",
+    "django.middleware.clickjacking.XFrameOptionsMiddleware",
+]
+
+ROOT_URLCONF = "config.urls"
+
+TEMPLATES = [
+    {
+        "BACKEND": "django.template.backends.django.DjangoTemplates",
+        "DIRS": [],
+        "APP_DIRS": True,
+        "OPTIONS": {
+            "context_processors": [
+                "django.template.context_processors.request",
+                "django.contrib.auth.context_processors.auth",
+                "django.contrib.messages.context_processors.messages",
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = "config.wsgi.application"
+
+
+# Database
+# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.postgresql',
+        'NAME': 'tongqu_v2_db',         # 你创建的数据库名
+        'USER': 'postgres',             # 你的PostgreSQL用户名 (如果是默认超级用户)
+                                        # 或者 'tongqu_v2_user' (如果你创建了专用用户)
+        'PASSWORD': '20030316', # 你的PostgreSQL密码
+        'HOST': 'localhost',            # 或者 '127.0.0.1'
+        'PORT': '5432',                 # PostgreSQL默认端口
+    }
+}
+
+# Password validation
+# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
+    },
+    {
+        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
+    },
+    {
+        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
+    },
+    {
+        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/5.2/topics/i18n/
+
+LANGUAGE_CODE = 'zh-hans'
+
+TIME_ZONE = '亚洲/上海'
+
+USE_I18N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/5.2/howto/static-files/
+
+STATIC_URL = '静态/'
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles_collected') # 运行 collectstatic 时文件的存放位置
+STATICFILES_DIRS = [
+    os.path.join(BASE_DIR, 'static'), # 项目级static文件夹
+]
+MEDIA_URL = '/media/'
+MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

+ 23 - 0
config/urls.py

@@ -0,0 +1,23 @@
+"""
+URL configuration for config project.
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/5.2/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  path('', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
+Including another URLconf
+    1. Import the include() function: from django.urls import include, path
+    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
+"""
+
+from django.contrib import admin
+from django.urls import path
+
+urlpatterns = [
+    path("admin/", admin.site.urls),
+]

+ 16 - 0
config/wsgi.py

@@ -0,0 +1,16 @@
+"""
+WSGI config for config project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
+
+application = get_wsgi_application()

+ 22 - 0
manage.py

@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+    """Run administrative tasks."""
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)
+
+
+if __name__ == "__main__":
+    main()

BIN
requirements.txt


+ 0 - 1007
同趣U.html

@@ -1,1007 +0,0 @@
-<!DOCTYPE html>
-<html lang="zh-CN">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>大学生兴趣伙伴 App - 页面预览</title>
-    <style>
-        body {
-            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
-            margin: 0;
-            padding: 0;
-            background-color: #f0f2f5;
-            display: flex;
-            justify-content: center;
-            align-items: flex-start; /* Align items to the top */
-            padding-top: 20px; /* Add some top padding */
-            padding-bottom: 100px; /* Add padding to see all content */
-        }
-
-        .phone-mockup {
-            width: 375px; /* Typical phone width */
-            height: 750px; /* Typical phone height */
-            border: 10px solid #333;
-            border-radius: 40px;
-            background-color: #fff;
-            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
-            position: relative; /* Needed for absolute positioning of header/footer */
-            overflow: hidden; /* Hide content that overflows */
-            display: flex;
-            flex-direction: column;
-        }
-
-        .app-header {
-            background-color: #007bff;
-            color: white;
-            padding: 15px;
-            text-align: center;
-            font-weight: bold;
-            font-size: 1.1em;
-            flex-shrink: 0; /* Prevent header from shrinking */
-            position: sticky; /* Keep header visible when scrolling content */
-            top: 0;
-            z-index: 10;
-            display: flex;
-            align-items: center;
-            justify-content: space-between; /* Align items */
-        }
-        .app-header .icon, .app-header .back-button {
-            color: white;
-            text-decoration: none;
-            font-size: 1.2em;
-            padding: 0 10px;
-        }
-         .app-header .back-button {
-            font-size: 1.5em; /* Make back arrow slightly larger */
-         }
-
-
-        .app-content {
-            flex-grow: 1; /* Allow content to fill available space */
-            overflow-y: auto; /* Enable scrolling for content */
-            padding: 15px;
-        }
-
-        .app-footer {
-            display: flex;
-            justify-content: space-around;
-            padding: 10px 0;
-            border-top: 1px solid #eee;
-            background-color: #fff;
-            flex-shrink: 0; /* Prevent footer from shrinking */
-            position: sticky; /* Keep footer visible */
-            bottom: 0;
-            z-index: 10;
-        }
-
-        .tab-item {
-            text-align: center;
-            color: #888;
-            text-decoration: none;
-            font-size: 0.8em;
-        }
-        .tab-item.active {
-            color: #007bff;
-        }
-        .tab-item span { /* Icon placeholder */
-            display: block;
-            font-size: 1.5em;
-            margin-bottom: 3px;
-        }
-
-        /* Basic Element Styles */
-        h2, h3 { margin-top: 10px; margin-bottom: 10px; color: #333; }
-        p { color: #555; line-height: 1.5; margin-bottom: 10px; }
-        button, .button-link {
-            display: inline-block;
-            padding: 10px 15px;
-            background-color: #007bff;
-            color: white;
-            border: none;
-            border-radius: 20px;
-            cursor: pointer;
-            text-align: center;
-            font-size: 0.9em;
-            margin: 5px 0;
-            text-decoration: none;
-        }
-        button:hover, .button-link:hover { background-color: #0056b3; }
-        button.secondary, .button-link.secondary { background-color: #6c757d; }
-        button.secondary:hover, .button-link.secondary:hover { background-color: #5a6268; }
-        button.outline, .button-link.outline { background-color: transparent; border: 1px solid #007bff; color: #007bff; }
-        button.outline:hover, .button-link.outline:hover { background-color: rgba(0, 123, 255, 0.1); }
-
-
-        input[type="text"], input[type="password"], input[type="email"], textarea, select {
-            width: calc(100% - 22px); /* Adjust for padding and border */
-            padding: 10px;
-            margin-bottom: 10px;
-            border: 1px solid #ccc;
-            border-radius: 5px;
-            font-size: 1em;
-        }
-        textarea { height: 80px; resize: vertical; }
-
-        /* Component Styles */
-        .card {
-            background-color: #fff;
-            border: 1px solid #eee;
-            border-radius: 8px;
-            padding: 15px;
-            margin-bottom: 15px;
-            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
-        }
-        .user-card, .message-item, .group-item, .event-item, .notification-item, .skill-item {
-            display: flex;
-            align-items: center;
-            margin-bottom: 15px;
-            padding-bottom: 10px;
-            border-bottom: 1px solid #f0f0f0;
-        }
-        .user-card:last-child, .message-item:last-child, .group-item:last-child, .event-item:last-child, .notification-item:last-child, .skill-item:last-child {
-             border-bottom: none;
-             margin-bottom: 0;
-             padding-bottom: 0;
-        }
-        .avatar {
-            width: 50px;
-            height: 50px;
-            border-radius: 50%;
-            background-color: #e0e0e0;
-            margin-right: 15px;
-            object-fit: cover; /* Make images fit well */
-            flex-shrink: 0;
-        }
-        .content-details { flex-grow: 1; }
-        .content-details h3 { margin: 0 0 5px 0; font-size: 1em; }
-        .content-details p { margin: 0; font-size: 0.9em; color: #777; }
-        .user-card .actions { margin-left: auto; }
-        .interest-tag {
-            display: inline-block;
-            background-color: #e7f3ff;
-            color: #007bff;
-            padding: 3px 8px;
-            border-radius: 15px;
-            font-size: 0.8em;
-            margin: 2px;
-            border: 1px solid #cce5ff;
-        }
-         .interest-category h3 { font-size: 1em; margin-bottom: 5px; border-bottom: 1px solid #eee; padding-bottom: 5px;}
-         .interest-category .tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 15px;}
-         .interest-category .tag-button {
-             background-color: #f0f0f0;
-             border: 1px solid #ddd;
-             color: #555;
-             padding: 5px 10px;
-             border-radius: 15px;
-             font-size: 0.9em;
-             cursor: pointer;
-         }
-          .interest-category .tag-button.selected {
-             background-color: #007bff;
-             color: white;
-             border-color: #007bff;
-          }
-
-        .chat-bubble {
-            max-width: 75%;
-            padding: 10px 15px;
-            border-radius: 18px;
-            margin-bottom: 10px;
-            line-height: 1.4;
-            word-wrap: break-word;
-        }
-        .chat-bubble.sent {
-            background-color: #007bff;
-            color: white;
-            margin-left: auto;
-            border-bottom-right-radius: 5px;
-        }
-        .chat-bubble.received {
-            background-color: #e9ecef;
-            color: #333;
-            margin-right: auto;
-            border-bottom-left-radius: 5px;
-        }
-        .chat-input {
-            display: flex;
-            padding: 10px;
-            border-top: 1px solid #eee;
-            background: #f8f9fa;
-        }
-        .chat-input input { flex-grow: 1; margin-right: 10px; margin-bottom: 0; }
-
-        .profile-header { text-align: center; margin-bottom: 20px; }
-        .profile-header .avatar { width: 100px; height: 100px; margin: 0 auto 10px auto; }
-        .profile-header h2 { margin: 5px 0; }
-        .profile-header p { color: #666; font-size: 0.9em; }
-
-        .section-title { font-weight: bold; margin-top: 20px; margin-bottom: 10px; border-bottom: 1px solid #eee; padding-bottom: 5px;}
-
-        .map-placeholder {
-            width: 100%;
-            height: 300px;
-            background-color: #e0e0e0;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            color: #999;
-            font-style: italic;
-            text-align: center;
-            border-radius: 8px;
-            border: 1px dashed #ccc;
-            position: relative;
-        }
-        .map-placeholder::after { /* Simple pin example */
-            content: '📍';
-            font-size: 2em;
-            position: absolute;
-            top: 40%;
-            left: 50%;
-            transform: translate(-50%, -50%);
-        }
-         .map-placeholder p { padding: 0 20px;}
-
-        /* Hide all pages initially */
-        .app-page { display: none; }
-        /* Show the default page (Home) */
-        #page-home { display: block; }
-
-    </style>
-</head>
-<body>
-
-    <div class="phone-mockup">
-        <!-- Dynamic Header will be controlled by JS in a real app -->
-        <!-- Placeholder Header -->
-        <div class="app-header" id="app-header">
-             <!-- Content changes based on active page -->
-        </div>
-
-        <!-- Content Area: Contains all pages -->
-        <div class="app-content">
-
-            <!-- PAGE: Home / Feed -->
-            <div class="app-page" id="page-home">
-                <script>document.getElementById('app-header').innerHTML = '<span>兴趣伙伴</span><a href="#page-notifications" class="icon">🔔</a>';</script>
-                <h2>为你推荐</h2>
-                <div class="card user-card">
-                    <img src="https://via.placeholder.com/50/FFA500/FFFFFF?text=U1" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <h3>张伟 <span style="font-size: 0.8em; color: #777;">(北京大学)</span></h3>
-                        <p>共同兴趣: <span class="interest-tag">摄影</span> <span class="interest-tag">爬山</span></p>
-                        <p style="font-size: 0.8em; color: #999;">"周末想找人一起去奥森拍照~"</p>
-                    </div>
-                    <div class="actions">
-                        <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">打招呼</a>
-                    </div>
-                </div>
-                 <div class="card user-card">
-                    <img src="https://via.placeholder.com/50/4682B4/FFFFFF?text=U2" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <h3>李静 <span style="font-size: 0.8em; color: #777;">(清华大学)</span></h3>
-                        <p>共同兴趣: <span class="interest-tag">日语学习</span> <span class="interest-tag">看动漫</span></p>
-                         <p style="font-size: 0.8em; color: #999;">"寻找N1备考伙伴,互相监督!"</p>
-                    </div>
-                    <div class="actions">
-                        <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">打招呼</a>
-                    </div>
-                </div>
-                <div class="card user-card">
-                    <img src="https://via.placeholder.com/50/32CD32/FFFFFF?text=U3" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <h3>王磊 <span style="font-size: 0.8em; color: #777;">(人民大学)</span></h3>
-                        <p>共同兴趣: <span class="interest-tag">篮球</span> <span class="interest-tag">说唱音乐</span></p>
-                         <p style="font-size: 0.8em; color: #999;">"下午东操场3v3,来不来?"</p>
-                    </div>
-                     <div class="actions">
-                        <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">打招呼</a>
-                    </div>
-                </div>
-                 <h2>附近的活动</h2>
-                 <div class="card event-item">
-                    <img src="https://via.placeholder.com/50/FF6347/FFFFFF?text=E" alt="Event Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <h3>周末狼人杀局</h3>
-                        <p>时间: 周六 14:00</p>
-                        <p>地点: 学校咖啡厅</p>
-                    </div>
-                    <div class="actions">
-                        <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">查看详情</a>
-                    </div>
-                </div>
-            </div>
-
-            <!-- PAGE: Discover / Search -->
-            <div class="app-page" id="page-discover">
-                 <script>document.getElementById('app-header').innerHTML = '<span>发现</span>';</script>
-                 <input type="text" placeholder="搜索用户、兴趣、小组、活动...">
-                 <button style="width: 100%; margin-bottom: 15px;">搜索</button>
-
-                 <h3>按兴趣浏览</h3>
-                 <div>
-                     <span class="interest-tag">摄影</span>
-                     <span class="interest-tag">篮球</span>
-                     <span class="interest-tag">吉他</span>
-                     <span class="interest-tag">Python</span>
-                     <span class="interest-tag">日语学习</span>
-                     <span class="interest-tag">电影</span>
-                     <span class="interest-tag">爬山</span>
-                     <span class="interest-tag">桌游</span>
-                     <a href="#page-interests" style="font-size: 0.9em; color: #007bff;">更多...</a>
-                 </div>
-
-                 <h3 style="margin-top: 20px;">推荐用户</h3>
-                 <!-- User cards like on home page -->
-                 <div class="card user-card">
-                    <img src="https://via.placeholder.com/50/8A2BE2/FFFFFF?text=U4" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <h3>赵敏 <span style="font-size: 0.8em; color: #777;">(北京师范大学)</span></h3>
-                        <p>兴趣: <span class="interest-tag">志愿者活动</span> <span class="interest-tag">阅读</span></p>
-                    </div>
-                    <div class="actions"> <a href="#page-profile-other" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">查看资料</a> </div>
-                </div>
-
-                 <h3 style="margin-top: 20px;">热门小组</h3>
-                 <div class="card group-item">
-                     <img src="https://via.placeholder.com/50/FFD700/000000?text=G1" alt="Group Icon" class="avatar" style="border-radius: 8px;">
-                     <div class="content-details">
-                        <h3>北邮吉他社</h3>
-                        <p>128 成员 | 活跃度高</p>
-                     </div>
-                      <div class="actions"> <a href="#page-group-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">加入</a> </div>
-                 </div>
-                 <a href="#page-groups" class="button-link secondary" style="width: 100%; text-align: center; margin-top: 10px;">查看所有小组</a>
-
-                 <h3 style="margin-top: 20px;">推荐活动</h3>
-                  <div class="card event-item">
-                    <img src="https://via.placeholder.com/50/00CED1/FFFFFF?text=E2" alt="Event Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <h3>校园编程马拉松</h3>
-                        <p>时间: 下周五 9:00</p>
-                        <p>地点: 计算机学院楼</p>
-                    </div>
-                    <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">感兴趣</a> </div>
-                </div>
-                 <a href="#page-events" class="button-link secondary" style="width: 100%; text-align: center; margin-top: 10px;">查看所有活动</a>
-
-                 <h3 style="margin-top: 20px;">技能交换</h3>
-                 <div class="card skill-item">
-                     <img src="https://via.placeholder.com/50/6495ED/FFFFFF?text=S1" alt="User Avatar" class="avatar">
-                     <div class="content-details">
-                        <h3>刘洋 <span style="font-size: 0.8em; color: #777;">(北京航空航天大学)</span></h3>
-                        <p><strong>提供:</strong> PPT美化 <span style="color: green;">|</span> <strong>需要:</strong> 英语口语练习</p>
-                     </div>
-                     <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
-                 </div>
-                  <a href="#page-skills" class="button-link secondary" style="width: 100%; text-align: center; margin-top: 10px;">查看技能交换</a>
-
-                  <h3 style="margin-top: 20px;">附近的人 (地图)</h3>
-                  <a href="#page-map" class="button-link" style="width: 100%; text-align: center;">查看地图模式</a>
-
-
-            </div>
-
-            <!-- PAGE: Messages List -->
-            <div class="app-page" id="page-messages">
-                <script>document.getElementById('app-header').innerHTML = '<span>消息</span><a href="#page-chat" class="icon">+</a>';</script>
-                 <div class="message-item">
-                    <img src="https://via.placeholder.com/50/4682B4/FFFFFF?text=U2" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <h3>李静</h3>
-                        <p>好的,那我们周二晚上图书馆见!</p>
-                    </div>
-                    <span style="font-size: 0.8em; color: #999; margin-left: auto;">10:35</span>
-                 </div>
-                 <div class="message-item">
-                    <img src="https://via.placeholder.com/50/FFA500/FFFFFF?text=U1" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <h3>张伟</h3>
-                        <p>[图片]</p>
-                    </div>
-                    <span style="font-size: 0.8em; color: #999; margin-left: auto;">昨天</span>
-                 </div>
-                 <div class="message-item">
-                    <img src="https://via.placeholder.com/50/FFD700/000000?text=G1" alt="Group Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <h3>北邮吉他社 (群)</h3>
-                        <p>@所有人 周五晚上有迎新演出!</p>
-                    </div>
-                    <span style="font-size: 0.8em; color: red; background: red; color: white; border-radius: 50%; padding: 2px 6px; margin-left: auto;">3</span>
-                 </div>
-            </div>
-
-             <!-- PAGE: Chat / Direct Message -->
-            <div class="app-page" id="page-chat">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-messages" class="back-button">‹</a><span>李静</span><a href="#" class="icon">···</a>';</script>
-                <div style="height: calc(100% - 60px); overflow-y: auto; display: flex; flex-direction: column-reverse; padding-bottom: 10px;"> <!-- Chat history area -->
-                    <!-- Messages would load here, newest at the bottom -->
-                     <div class="chat-bubble sent">好的,那我们周二晚上图书馆见!</div>
-                     <div class="chat-bubble received">太好了!我正好也在复习,可以一起。</div>
-                     <div class="chat-bubble sent">我看到你也选了高数,下周考试一起复习怎么样?地点图书馆?</div>
-                     <div class="chat-bubble received">你好,看到你也喜欢日语学习,我也是!😊</div>
-                     <div class="chat-bubble sent">[系统提示] 你们都对“日语学习”感兴趣,可以聊聊哦~</div>
-                </div>
-                 <div class="chat-input">
-                    <input type="text" placeholder="输入消息...">
-                    <button>发送</button>
-                 </div>
-            </div>
-
-
-            <!-- PAGE: User Profile (Self) -->
-            <div class="app-page" id="page-profile-self">
-                <script>document.getElementById('app-header').innerHTML = '<span>我的资料</span><a href="#page-settings" class="icon">⚙️</a>';</script>
-                <div class="profile-header">
-                    <img src="https://via.placeholder.com/100/007BFF/FFFFFF?text=ME" alt="My Avatar" class="avatar">
-                    <h2>你的昵称</h2>
-                    <p>北京邮电大学 | 计算机科学 | 大二</p>
-                    <p>"努力成为有趣的人 | Coding & Reading"</p>
-                     <a href="#page-interests" class="button-link outline" style="margin-top: 10px;">编辑兴趣标签</a>
-                </div>
-
-                <div class="section-title">我的兴趣</div>
-                <div class="card">
-                    <span class="interest-tag">Python</span>
-                    <span class="interest-tag">机器学习</span>
-                    <span class="interest-tag">科幻电影</span>
-                    <span class="interest-tag">羽毛球</span>
-                    <span class="interest-tag">独立音乐</span>
-                </div>
-
-                <div class="section-title">我的小组</div>
-                 <div class="card group-item">
-                     <img src="https://via.placeholder.com/50/20B2AA/FFFFFF?text=G2" alt="Group Icon" class="avatar" style="border-radius: 8px;">
-                     <div class="content-details">
-                        <h3>BUPT算法交流群</h3>
-                        <p>55 成员</p>
-                     </div>
-                 </div>
-                 <a href="#page-groups" class="button-link secondary" style="width: 100%; text-align: center;">查看所有小组</a>
-
-
-                <div class="section-title">我发布的活动</div>
-                <p style="text-align: center; color: #999;">暂无活动</p>
-                <a href="#page-event-post" class="button-link" style="width: 100%; text-align: center;">发布新活动</a>
-
-
-                 <div class="section-title">我的技能/需求</div>
-                  <div class="card skill-item">
-                     <img src="https://via.placeholder.com/50/007BFF/FFFFFF?text=ME" alt="User Avatar" class="avatar">
-                     <div class="content-details">
-                        <p><strong>提供:</strong> Python基础教学 <span style="color: green;">|</span> <strong>需要:</strong> 羽毛球球友</p>
-                     </div>
-                     <div class="actions"> <a href="#page-skills" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">编辑</a> </div>
-                 </div>
-                 <a href="#page-skills" class="button-link" style="width: 100%; text-align: center;">发布技能/需求</a>
-            </div>
-
-            <!-- PAGE: User Profile (Other) -->
-            <div class="app-page" id="page-profile-other">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>用户资料</span><a href="#" class="icon">···</a>';</script>
-                 <div class="profile-header">
-                    <img src="https://via.placeholder.com/100/FFA500/FFFFFF?text=U1" alt="User Avatar" class="avatar">
-                    <h2>张伟</h2>
-                    <p>北京大学 | 艺术学院 | 大三</p>
-                     <p>"周末想找人一起去奥森拍照~"</p>
-                     <a href="#page-chat" class="button-link" style="margin-top: 10px;">发消息</a>
-                     <button class="secondary">关注</button>
-                </div>
-
-                <div class="section-title">Ta的兴趣</div>
-                 <div class="card">
-                    <span class="interest-tag">摄影</span>
-                    <span class="interest-tag">后期制作</span>
-                    <span class="interest-tag">爬山</span>
-                    <span class="interest-tag">纪录片</span>
-                </div>
-
-                 <div class="section-title">共同兴趣</div>
-                  <div class="card">
-                    <span class="interest-tag">摄影</span>
-                    <span class="interest-tag">爬山</span>
-                </div>
-
-                <div class="section-title">Ta的小组</div>
-                 <p style="text-align: center; color: #999;">用户尚未加入任何小组</p>
-
-                <div class="section-title">Ta发布的活动</div>
-                 <div class="card event-item">
-                    <img src="https://via.placeholder.com/50/FFA500/FFFFFF?text=U1" alt="Host Avatar" class="avatar">
-                    <div class="content-details">
-                        <h3>奥森公园外拍活动</h3>
-                        <p>时间: 本周六 10:00</p>
-                        <p>地点: 奥林匹克森林公园南门</p>
-                    </div>
-                     <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">查看详情</a> </div>
-                </div>
-            </div>
-
-            <!-- PAGE: Interest Selection/Editing -->
-            <div class="app-page" id="page-interests">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-profile-self" class="back-button">‹</a><span>选择我的兴趣</span><a href="#page-profile-self" class="icon" style="font-size: 0.9em;">保存</a>';</script>
-                <input type="text" placeholder="搜索兴趣标签...">
-
-                <div class="interest-category">
-                    <h3>运动</h3>
-                    <div class="tags">
-                        <button class="tag-button selected">羽毛球</button>
-                        <button class="tag-button">篮球</button>
-                        <button class="tag-button">跑步</button>
-                        <button class="tag-button">游泳</button>
-                        <button class="tag-button">健身</button>
-                        <button class="tag-button">瑜伽</button>
-                        <button class="tag-button">乒乓球</button>
-                        <button class="tag-button">爬山</button>
-                    </div>
-                </div>
-
-                 <div class="interest-category">
-                    <h3>音乐</h3>
-                    <div class="tags">
-                        <button class="tag-button selected">独立音乐</button>
-                        <button class="tag-button">摇滚</button>
-                        <button class="tag-button">流行</button>
-                        <button class="tag-button">古典</button>
-                        <button class="tag-button">吉他</button>
-                        <button class="tag-button">钢琴</button>
-                    </div>
-                </div>
-
-                 <div class="interest-category">
-                    <h3>学术/技术</h3>
-                    <div class="tags">
-                        <button class="tag-button selected">Python</button>
-                        <button class="tag-button selected">机器学习</button>
-                        <button class="tag-button">Web开发</button>
-                        <button class="tag-button">算法</button>
-                        <button class="tag-button">考研</button>
-                        <button class="tag-button">四六级</button>
-                    </div>
-                </div>
-
-                 <div class="interest-category">
-                    <h3>艺术/生活</h3>
-                    <div class="tags">
-                        <button class="tag-button selected">科幻电影</button>
-                        <button class="tag-button">摄影</button>
-                        <button class="tag-button">阅读</button>
-                        <button class="tag-button">绘画</button>
-                        <button class="tag-button">桌游</button>
-                        <button class="tag-button">美食探店</button>
-                    </div>
-                </div>
-                 <p style="color: #888; font-size: 0.9em;">找不到你的兴趣?可以尝试搜索或 <a href="#">创建新标签</a>。</p>
-            </div>
-
-             <!-- PAGE: Notifications -->
-            <div class="app-page" id="page-notifications">
-                 <script>document.getElementById('app-header').innerHTML = '<a href="#page-home" class="back-button">‹</a><span>通知</span>';</script>
-                 <div class="notification-item">
-                    <img src="https://via.placeholder.com/50/32CD32/FFFFFF?text=U3" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <p><strong>王磊</strong> 赞了你的动态。</p>
-                        <p style="font-size: 0.8em; color: #999;">5分钟前</p>
-                    </div>
-                 </div>
-                 <div class="notification-item">
-                     <img src="https://via.placeholder.com/50/FF6347/FFFFFF?text=E" alt="Event Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <p>你报名的活动 <strong>周末狼人杀局</strong> 将在1小时后开始。</p>
-                        <p style="font-size: 0.8em; color: #999;">15分钟前</p>
-                    </div>
-                 </div>
-                  <div class="notification-item">
-                    <img src="https://via.placeholder.com/50/8A2BE2/FFFFFF?text=U4" alt="User Avatar" class="avatar">
-                    <div class="content-details">
-                        <p><strong>赵敏</strong> 开始关注你了。</p>
-                         <p style="font-size: 0.8em; color: #999;">1小时前</p>
-                    </div>
-                      <div class="actions"> <a href="#page-profile-other" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">回关</a> </div>
-                 </div>
-                  <div class="notification-item">
-                    <img src="https://via.placeholder.com/50/FFD700/000000?text=G1" alt="Group Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <p><strong>北邮吉他社</strong> 有新公告。</p>
-                         <p style="font-size: 0.8em; color: #999;">3小时前</p>
-                    </div>
-                 </div>
-            </div>
-
-            <!-- PAGE: Settings -->
-            <div class="app-page" id="page-settings">
-                 <script>document.getElementById('app-header').innerHTML = '<a href="#page-profile-self" class="back-button">‹</a><span>设置</span>';</script>
-                 <ul style="list-style: none; padding: 0;">
-                     <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#page-profile-self" style="text-decoration: none; color: #333;">编辑个人资料</a></li>
-                     <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">账号与安全</a></li>
-                     <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">隐私设置</a></li>
-                     <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#page-notifications" style="text-decoration: none; color: #333;">通知设置</a></li>
-                     <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">关于我们</a></li>
-                     <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">帮助与反馈</a></li>
-                 </ul>
-                 <button style="width: 100%; background-color: #dc3545; margin-top: 30px;">退出登录</button>
-            </div>
-
-             <!-- PAGE: Group List -->
-            <div class="app-page" id="page-groups">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-profile-self" class="back-button">‹</a><span>我的小组</span><a href="#" class="icon">+</a>';</script>
-                <!-- Add Tabs for My Groups / Discover Groups -->
-                 <div class="card group-item">
-                     <img src="https://via.placeholder.com/50/20B2AA/FFFFFF?text=G2" alt="Group Icon" class="avatar" style="border-radius: 8px;">
-                     <div class="content-details">
-                        <h3>BUPT算法交流群</h3>
-                        <p>55 成员</p>
-                     </div>
-                     <div class="actions"> <a href="#page-group-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">进入</a> </div>
-                 </div>
-                 <div class="card group-item">
-                     <img src="https://via.placeholder.com/50/DAA520/FFFFFF?text=G3" alt="Group Icon" class="avatar" style="border-radius: 8px;">
-                     <div class="content-details">
-                        <h3>电影爱好者协会</h3>
-                        <p>210 成员</p>
-                     </div>
-                     <div class="actions"> <a href="#page-group-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">进入</a> </div>
-                 </div>
-                 <p style="text-align: center; margin-top: 20px;"><a href="#page-discover" style="color: #007bff;">发现更多小组...</a></p>
-            </div>
-
-             <!-- PAGE: Group Detail -->
-            <div class="app-page" id="page-group-detail">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-groups" class="back-button">‹</a><span>BUPT算法交流群</span><a href="#" class="icon">···</a>';</script>
-                 <div style="text-align: center; margin-bottom: 15px;">
-                    <img src="https://via.placeholder.com/80/20B2AA/FFFFFF?text=G2" alt="Group Icon" class="avatar" style="width: 80px; height: 80px; border-radius: 15px; margin: 0 auto 10px auto;">
-                    <h2>BUPT算法交流群</h2>
-                    <p>55 成员 | <a href="#">查看成员</a></p>
-                    <p style="font-size: 0.9em; color: #666;">欢迎对算法、数据结构、ACM竞赛感兴趣的同学加入讨论!</p>
-                    <button class="secondary">已加入</button>
-                 </div>
-                 <hr>
-                 <h3>小组动态</h3>
-                  <div class="card"> <!-- Post within group -->
-                     <div class="user-card" style="border-bottom: none; margin-bottom: 10px; padding-bottom: 0;">
-                         <img src="https://via.placeholder.com/40/CD5C5C/FFFFFF?text=U5" alt="User Avatar" class="avatar" style="width: 40px; height: 40px;">
-                         <div class="content-details">
-                             <h3 style="font-size: 0.9em;">陈晨</h3>
-                             <p style="font-size: 0.8em;">5小时前</p>
-                         </div>
-                     </div>
-                     <p>LeetCode今天这道Hard题有人AC了吗?求思路分享!#每日一题</p>
-                     <div style="font-size: 0.8em; color: #888;">👍 5    💬 2</div>
-                 </div>
-                  <div class="card"> <!-- Post within group -->
-                     <div class="user-card" style="border-bottom: none; margin-bottom: 10px; padding-bottom: 0;">
-                         <img src="https://via.placeholder.com/40/4682B4/FFFFFF?text=U2" alt="User Avatar" class="avatar" style="width: 40px; height: 40px;">
-                         <div class="content-details">
-                             <h3 style="font-size: 0.9em;">李静 (管理员)</h3>
-                             <p style="font-size: 0.8em;">昨天</p>
-                         </div>
-                     </div>
-                     <p>【公告】下周三晚上7点,邀请学长分享蓝桥杯备赛经验,地点教三201,欢迎参加!</p>
-                     <div style="font-size: 0.8em; color: #888;">👍 15    💬 1</div>
-                 </div>
-                 <button style="width: 100%; margin-top: 15px;">发布新动态</button>
-            </div>
-
-             <!-- PAGE: Event Listing -->
-            <div class="app-page" id="page-events">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>活动广场</span><a href="#page-event-post" class="icon">+</a>';</script>
-                <!-- Add Tabs for Upcoming / My Events / Discover -->
-                <div class="card event-item">
-                    <img src="https://via.placeholder.com/50/FF6347/FFFFFF?text=E" alt="Event Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <h3>周末狼人杀局</h3>
-                        <p>时间: 周六 14:00</p>
-                        <p>地点: 学校咖啡厅 | 发起人: 王磊</p>
-                    </div>
-                    <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">详情</a> </div>
-                </div>
-                <div class="card event-item">
-                    <img src="https://via.placeholder.com/50/00CED1/FFFFFF?text=E2" alt="Event Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <h3>校园编程马拉松</h3>
-                        <p>时间: 下周五 9:00 - 周日 17:00</p>
-                        <p>地点: 计算机学院楼 | 主办方: 计算机学院</p>
-                    </div>
-                    <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">详情</a> </div>
-                </div>
-                 <div class="card event-item">
-                    <img src="https://via.placeholder.com/50/9370DB/FFFFFF?text=E3" alt="Event Icon" class="avatar" style="border-radius: 8px;">
-                    <div class="content-details">
-                        <h3>草坪音乐分享会</h3>
-                        <p>时间: 周日 16:00</p>
-                        <p>地点: 学校大草坪 | 发起人: 赵敏</p>
-                    </div>
-                    <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">详情</a> </div>
-                </div>
-            </div>
-
-             <!-- PAGE: Event Detail -->
-            <div class="app-page" id="page-event-detail">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-events" class="back-button">‹</a><span>活动详情</span><a href="#" class="icon">☆</a>';</script>
-                <img src="https://via.placeholder.com/345x150/FF6347/FFFFFF?text=Event+Banner" alt="Event Image" style="width: 100%; height: 150px; object-fit: cover; border-radius: 8px; margin-bottom: 15px;">
-                <h2>周末狼人杀局</h2>
-                <p><strong>时间:</strong> 本周六 14:00 - 18:00</p>
-                <p><strong>地点:</strong> 学校南门咖啡厅二楼</p>
-                <p><strong>发起人:</strong> <a href="#page-profile-other">王磊</a> (人民大学)</p>
-                <p><strong>活动介绍:</strong> 找个地方一起玩狼人杀,新手友好,欢迎各种板子!目前已有3人,还差5-7人。费用AA(场地费)。</p>
-                <p><strong>兴趣标签:</strong> <span class="interest-tag">桌游</span> <span class="interest-tag">狼人杀</span> <span class="interest-tag">线下聚会</span></p>
-                <p><strong>已报名 (3/10):</strong> <img src="https://via.placeholder.com/30/32CD32/FFFFFF?text=U3" class="avatar" style="width:30px; height:30px; margin-right: 5px;"> <img src="https://via.placeholder.com/30/1E90FF/FFFFFF?text=U6" class="avatar" style="width:30px; height:30px; margin-right: 5px;"> <img src="https://via.placeholder.com/30/FF4500/FFFFFF?text=U7" class="avatar" style="width:30px; height:30px; margin-right: 5px;"> <a href="#">查看全部</a></p>
-                <button style="width: 100%;">我要报名</button>
-                 <button class="secondary" style="width: 100%; margin-top: 10px;">分享活动</button>
-            </div>
-
-             <!-- PAGE: Event Posting -->
-            <div class="app-page" id="page-event-post">
-                 <script>document.getElementById('app-header').innerHTML = '<a href="#page-events" class="back-button">‹</a><span>发布新活动</span><a href="#page-events" class="icon" style="font-size: 0.9em;">发布</a>';</script>
-                 <label for="event-title">活动标题:</label>
-                 <input type="text" id="event-title" placeholder="如:周日图书馆约学习">
-                 <label for="event-desc">活动描述:</label>
-                 <textarea id="event-desc" placeholder="详细说明活动内容、目的、要求等..."></textarea>
-                 <label for="event-time">时间:</label>
-                 <input type="text" id="event-time" placeholder="如:本周日 下午2点-5点">
-                 <label for="event-loc">地点:</label>
-                 <input type="text" id="event-loc" placeholder="如:学校图书馆三楼自习室">
-                 <label for="event-tags">关联兴趣标签 (可选):</label>
-                 <input type="text" id="event-tags" placeholder="如:考研, 学习伙伴, 图书馆">
-                 <label for="event-limit">人数限制 (可选):</label>
-                 <input type="number" id="event-limit" placeholder="如:5 (留空表示不限)">
-                 <label for="event-cover">上传封面图 (可选):</label>
-                 <button class="outline">选择图片</button>
-            </div>
-
-
-            <!-- PAGE: Skill Exchange Listing -->
-            <div class="app-page" id="page-skills">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>技能交换</span><a href="#page-skill-post" class="icon">+</a>';</script>
-                 <!-- Add Tabs: 提供 / 需求 / 浏览 -->
-                 <div class="card skill-item">
-                     <img src="https://via.placeholder.com/50/6495ED/FFFFFF?text=S1" alt="User Avatar" class="avatar">
-                     <div class="content-details">
-                        <h3>刘洋 <span style="font-size: 0.8em; color: #777;">(北航)</span></h3>
-                        <p><strong style="color: green;">提供:</strong> PPT美化, 海报设计</p>
-                        <p><strong style="color: orange;">需要:</strong> 英语口语练习</p>
-                     </div>
-                     <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
-                 </div>
-                 <div class="card skill-item">
-                     <img src="https://via.placeholder.com/50/DC143C/FFFFFF?text=S2" alt="User Avatar" class="avatar">
-                     <div class="content-details">
-                        <h3>孙悦 <span style="font-size: 0.8em; color: #777;">(北理)</span></h3>
-                         <p><strong style="color: green;">提供:</strong> 日语N2辅导</p>
-                         <p><strong style="color: orange;">需要:</strong> Python爬虫教学</p>
-                     </div>
-                     <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
-                 </div>
-                  <div class="card skill-item">
-                     <img src="https://via.placeholder.com/50/FF8C00/FFFFFF?text=S3" alt="User Avatar" class="avatar">
-                     <div class="content-details">
-                        <h3>周峰 <span style="font-size: 0.8em; color: #777;">(北交大)</span></h3>
-                         <p><strong style="color: green;">提供:</strong> 吉他弹唱教学 (入门)</p>
-                         <p><strong style="color: orange;">需要:</strong> 无</p>
-                     </div>
-                     <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
-                 </div>
-            </div>
-
-             <!-- PAGE: Skill Post/Edit -->
-            <div class="app-page" id="page-skill-post">
-                 <script>document.getElementById('app-header').innerHTML = '<a href="#page-skills" class="back-button">‹</a><span>发布技能/需求</span><a href="#page-skills" class="icon" style="font-size: 0.9em;">发布</a>';</script>
-                 <label for="skill-provide">我能提供的技能/帮助:</label>
-                 <textarea id="skill-provide" placeholder="详细描述你能提供的技能或帮助,如:Python数据分析入门、日语五十音教学..."></textarea>
-                 <label for="skill-need">我需要的技能/帮助:</label>
-                 <textarea id="skill-need" placeholder="详细描述你需要的技能或帮助,如:寻找英语口语语伴、求PS修图指导..."></textarea>
-                 <p style="font-size: 0.9em; color: #888;">可以只填写一项或两项都填。</p>
-            </div>
-
-            <!-- PAGE: Map View (Conceptual) -->
-            <div class="app-page" id="page-map">
-                <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>附近 (<span style="color:red;">隐私保护模式</span>)</span><a href="#" class="icon">⚙️</a>';</script>
-                <p style="font-size: 0.85em; color: #dc3545; text-align: center; border: 1px solid #f5c6cb; background-color: #f8d7da; padding: 8px; border-radius: 5px; margin-bottom: 15px;">
-                    <strong>注意:</strong> 为保护隐私,地图仅显示模糊位置和共同兴趣,不会暴露精确坐标或个人身份。你需要明确授权才能使用此功能。
-                </p>
-                 <div class="map-placeholder">
-                    <p>模拟地图区域<br/>(显示附近有相同兴趣的用户或活动的大致位置)</p>
-                 </div>
-                 <div style="margin-top: 15px;">
-                     <label for="map-filter-interest">筛选兴趣:</label>
-                     <select id="map-filter-interest">
-                         <option>所有兴趣</option>
-                         <option>摄影</option>
-                         <option>篮球</option>
-                         <option>学习伙伴</option>
-                     </select>
-                     <label for="map-filter-radius">范围:</label>
-                     <select id="map-filter-radius">
-                         <option>1公里内</option>
-                         <option>3公里内</option>
-                         <option>5公里内</option>
-                     </select>
-                 </div>
-                 <!-- List nearby items below the map? -->
-                 <p style="text-align: center; color: #999; margin-top: 20px;">地图下方可列出匹配项</p>
-
-            </div>
-
-            <!-- PAGE: Login -->
-            <div class="app-page" id="page-login">
-                <script>document.getElementById('app-header').innerHTML = '<span>登录</span>';</script>
-                <h2 style="text-align: center; margin-top: 40px;">欢迎回来</h2>
-                 <label for="login-email">邮箱/手机号:</label>
-                 <input type="email" id="login-email" placeholder="输入你的注册邮箱或手机号">
-                 <label for="login-password">密码:</label>
-                 <input type="password" id="login-password" placeholder="输入密码">
-                 <button style="width: 100%; margin-top: 20px;">登录</button>
-                 <div style="display: flex; justify-content: space-between; margin-top: 15px; font-size: 0.9em;">
-                     <a href="#" style="color: #007bff;">忘记密码?</a>
-                     <a href="#page-signup" style="color: #007bff;">没有账号?去注册</a>
-                 </div>
-                 <p style="text-align: center; color: #aaa; margin: 30px 0 15px 0;">--- 第三方登录 ---</p>
-                 <div style="text-align: center;">
-                    <button class="outline" style="margin: 5px; border-radius: 50%; width: 50px; height: 50px; font-size: 1.5em;">微</button>
-                    <button class="outline" style="margin: 5px; border-radius: 50%; width: 50px; height: 50px; font-size: 1.5em;">Q</button>
-                     <button class="outline" style="margin: 5px; border-radius: 50%; width: 50px; height: 50px; font-size: 1.5em;"></button>
-                 </div>
-            </div>
-
-             <!-- PAGE: Signup -->
-            <div class="app-page" id="page-signup">
-                <script>document.getElementById('app-header').innerHTML = '<span>注册</span>';</script>
-                 <h2 style="text-align: center; margin-top: 20px;">创建新账号</h2>
-                  <label for="signup-school-email">学校邮箱 (.edu):</label>
-                 <input type="email" id="signup-school-email" placeholder="推荐使用edu邮箱验证身份">
-                  <label for="signup-nickname">昵称:</label>
-                 <input type="text" id="signup-nickname" placeholder="给自己取个名字吧">
-                  <label for="signup-password">设置密码:</label>
-                 <input type="password" id="signup-password" placeholder="至少8位,包含字母和数字">
-                  <label for="signup-password-confirm">确认密码:</label>
-                 <input type="password" id="signup-password-confirm" placeholder="再次输入密码">
-                 <button style="width: 100%; margin-top: 20px;">注册</button>
-                 <p style="font-size: 0.8em; color: #888; margin-top: 10px; text-align: center;">
-                    点击注册表示同意 <a href="#" style="color: #007bff;">用户协议</a> 和 <a href="#" style="color: #007bff;">隐私政策</a>
-                 </p>
-                  <p style="text-align: center; margin-top: 15px;">
-                     <a href="#page-login" style="color: #007bff;">已有账号?去登录</a>
-                 </p>
-            </div>
-
-        </div> <!-- End .app-content -->
-
-        <!-- Footer / Tab Bar -->
-        <div class="app-footer" id="app-footer">
-            <a href="#page-home" class="tab-item active" onclick="setActiveTab(this)"><span>🏠</span>首页</a>
-            <a href="#page-discover" class="tab-item" onclick="setActiveTab(this)"><span>🔍</span>发现</a>
-            <a href="#page-messages" class="tab-item" onclick="setActiveTab(this)"><span>💬</span>消息</a>
-            <a href="#page-profile-self" class="tab-item" onclick="setActiveTab(this)"><span>👤</span>我的</a>
-        </div>
-    </div> <!-- End .phone-mockup -->
-
-<script>
-    // Simple JavaScript for page navigation simulation and tab highlighting
-    const pages = document.querySelectorAll('.app-page');
-    const footerTabs = document.querySelectorAll('.app-footer .tab-item');
-    const header = document.getElementById('app-header');
-
-    function showPage(pageId) {
-        pages.forEach(page => {
-            page.style.display = 'none'; // Hide all pages
-        });
-        const targetPage = document.getElementById(pageId);
-        if (targetPage) {
-            targetPage.style.display = 'block'; // Show the target page
-             // Find the script inside the target page and run it to update the header
-            const headerScript = targetPage.querySelector('script');
-            if (headerScript) {
-                try {
-                    eval(headerScript.innerText); // Execute the script to set the header
-                } catch (e) {
-                    console.error("Error executing header script for page:", pageId, e);
-                    // Set a default header if script fails
-                     header.innerHTML = '<span>App Name</span>';
-                }
-            } else {
-                 // Set a default header if no script found
-                  header.innerHTML = '<span>App Name</span>';
-            }
-
-            // Scroll content to top when changing pages
-            targetPage.parentElement.scrollTop = 0;
-
-        } else {
-             console.warn("Page not found:", pageId);
-             document.getElementById('page-home').style.display = 'block'; // Fallback to home
-             header.innerHTML = '<span>兴趣伙伴</span><a href="#page-notifications" class="icon">🔔</a>';
-        }
-    }
-
-    function setActiveTab(selectedTab) {
-        footerTabs.forEach(tab => {
-            tab.classList.remove('active');
-        });
-        selectedTab.classList.add('active');
-        // Navigate to the page specified in the tab's href
-        const pageId = selectedTab.getAttribute('href').substring(1); // Remove #
-        showPage(pageId);
-    }
-
-    // Handle initial page load based on URL hash, or default to home
-    window.addEventListener('load', () => {
-        const hash = window.location.hash;
-        if (hash) {
-            const pageId = hash.substring(1);
-            showPage(pageId);
-            // Update active tab based on hash
-            footerTabs.forEach(tab => {
-                 if(tab.getAttribute('href') === hash) {
-                     setActiveTab(tab);
-                 } else {
-                      tab.classList.remove('active');
-                 }
-             });
-             // Ensure at least one tab is active if hash matches a main page
-             const activeTabs = document.querySelectorAll('.app-footer .tab-item.active');
-             if(activeTabs.length === 0 && ['page-home', 'page-discover', 'page-messages', 'page-profile-self'].includes(pageId)) {
-                 document.querySelector(`.app-footer .tab-item[href="#${pageId}"]`).classList.add('active');
-             } else if (activeTabs.length === 0) {
-                 document.querySelector('.app-footer .tab-item[href="#page-home"]').classList.add('active'); // Default active tab
-             }
-
-        } else {
-            showPage('page-home'); // Default page
-            document.querySelector('.app-footer .tab-item[href="#page-home"]').classList.add('active'); // Default active tab
-        }
-    });
-
-    // Optional: Handle browser back/forward navigation
-    window.addEventListener('hashchange', () => {
-         const hash = window.location.hash;
-         if (hash) {
-            const pageId = hash.substring(1);
-            showPage(pageId);
-             // Update active tab based on hash
-             footerTabs.forEach(tab => {
-                 if(tab.getAttribute('href') === hash) {
-                     setActiveTab(tab); // This already calls showPage
-                 } else {
-                     tab.classList.remove('active');
-                 }
-             });
-              // Ensure at least one tab is active if hash matches a main page
-             const activeTabs = document.querySelectorAll('.app-footer .tab-item.active');
-             if(activeTabs.length === 0 && ['page-home', 'page-discover', 'page-messages', 'page-profile-self'].includes(pageId)) {
-                 document.querySelector(`.app-footer .tab-item[href="#${pageId}"]`).classList.add('active');
-             } else if (activeTabs.length === 0) {
-                 document.querySelector('.app-footer .tab-item[href="#page-home"]').classList.add('active'); // Default active tab
-             }
-         } else {
-             showPage('page-home'); // Default to home if hash is empty
-             setActiveTab(document.querySelector('.app-footer .tab-item[href="#page-home"]'));
-         }
-    });
-
-    // Make internal links work for navigation
-    document.addEventListener('click', function(event) {
-        let target = event.target;
-        // Traverse up the DOM if the click was inside a link
-        while(target && target.tagName !== 'A') {
-            target = target.parentElement;
-        }
-
-        if (target && target.tagName === 'A' && target.getAttribute('href') && target.getAttribute('href').startsWith('#')) {
-            const href = target.getAttribute('href');
-            // Check if it's a tab bar link (already handled by setActiveTab)
-            if (!target.classList.contains('tab-item')) {
-                event.preventDefault(); // Prevent default anchor jump
-                const pageId = href.substring(1);
-                window.location.hash = pageId; // Change hash to trigger navigation
-            } else {
-                 // If it IS a tab item, ensure setActiveTab is called (covers cases where onclick might fail or be absent)
-                 setActiveTab(target);
-            }
-        }
-    });
-
-
-</script>
-
-</body>
-</html>