Compare commits

..

14 Commits

13 changed files with 1198 additions and 209 deletions
+107
View File
@@ -0,0 +1,107 @@
# 612 班级纪念站
这是一个用 Astro 搭建的班级纪念网站,用来保存毕业后的班级记忆:时间线、照片墙、同学近况、综合试卷和留言墙。
## 功能
- 首页:班级纪念入口、导航和基础统计。
- 三年时间线:记录高中阶段的重要片段。
- 照片墙:按专题整理课堂日常、班级活动、毕业当天和随手抓拍。
- 如今的我们:展示同学卡片和个人近况页面。
- 综合试卷:把纪念试卷做成网页,并保留 Word 原卷下载。
- 留言墙:接入 Twikoo 后可在页面中留言。
## 技术栈
- Astro 6
- TypeScript
- 原生 CSS
- Twikoo 评论系统
## 快速开始
```bash
npm install
npm run dev
```
本地开发服务启动后,按终端提示打开页面即可。
常用命令:
```bash
npm run dev # 启动开发服务器
npm run build # 构建静态站点到 dist
npm run preview # 预览构建结果
```
## 项目结构
```text
.
|-- public/
| `-- assets/ # 静态图片、试卷附件等资源
|-- scripts/ # GitHub Issue 自动更新数据脚本
|-- src/
| |-- data/ # 站点内容数据
| | |-- site.ts # 站点标题、导航、联系方式
| | |-- timeline.ts # 时间线内容
| | |-- photos.ts # 照片墙入口数据
| | |-- photo-topics/ # 各照片专题
| | |-- people.ts # 同学资料
| | |-- exam.ts # 综合试卷内容与评分配置
| | `-- messages.ts # 留言墙文案与 Twikoo 配置
| |-- layouts/ # 通用页面布局
| |-- pages/ # 路由页面
| `-- styles/ # 全局和页面样式
|-- astro.config.mjs
`-- package.json
```
## 内容维护
大部分网站内容都在 `src/data` 目录中维护。
- 修改站点名称、首页文案、导航和联系方式:编辑 `src/data/site.ts`
- 修改时间线:编辑 `src/data/timeline.ts`
- 修改照片墙专题:编辑 `src/data/photo-topics/*.ts`
- 修改同学资料:编辑 `src/data/people.ts`
- 修改试卷内容和答案:编辑 `src/data/exam.ts`
- 修改留言墙文案和 Twikoo 配置:编辑 `src/data/messages.ts`
新增静态资源时,放到 `public/assets` 下。页面中引用资源时使用以 `/assets/` 开头的路径,例如:
```ts
photo: "/assets/photos/example.jpg"
```
## 留言墙配置
留言墙使用 Twikoo。需要在本地或部署平台中配置环境变量:
```bash
PUBLIC_TWIKOO_ENV_ID=你的_Twikoo_envId
```
如果没有配置该变量,留言页会显示待配置提示,不会加载评论区。
## GitHub Issue 自动更新
仓库中包含用于收集内容更新的 Issue 模板和 GitHub Actions
- `people-update`:根据 Issue 表单更新 `src/data/people.ts`
- `photo-update`:根据 Issue 表单更新对应的照片专题数据
提交或编辑对应 Issue 后,工作流会运行脚本并自动创建更新 PR,方便审核后合并。
## 构建与部署
执行:
```bash
npm run build
```
构建产物会生成到 `dist/`。这个项目是静态站点,可以部署到 GitHub Pages、Vercel、Netlify 或任意静态资源服务器。
部署前建议检查 `astro.config.mjs` 中的 `site` 字段,把它改成真实站点地址。
+183 -179
View File
@@ -1,12 +1,12 @@
{
"name": "class-anniversary",
"version": "0.3.0",
"version": "1.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "class-anniversary",
"version": "0.3.0",
"version": "1.2.0",
"dependencies": {
"@astrojs/check": "^0.9.9",
"astro": "^6.2.1",
@@ -47,9 +47,9 @@
}
},
"node_modules/@astrojs/language-server": {
"version": "2.16.7",
"resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.7.tgz",
"integrity": "sha512-b64bWT74Vq/ORcSqW7TdIjjpB6hcl+Ei/lMANIUaAGlLPiYNtPTRI/j2tzvugT+LoVwfJtE2Ukq/t2OGCyEtfQ==",
"version": "2.16.8",
"resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.8.tgz",
"integrity": "sha512-yg1pZF6hs9FaKr2fgXMOGbW7pDLgFexFjuhWilPAc8VybTU+WSnbfbhYaUL1exm6dAK4sM3aKXGcfVwss+HXbg==",
"license": "MIT",
"dependencies": {
"@astrojs/compiler": "^2.13.1",
@@ -129,13 +129,12 @@
}
},
"node_modules/@astrojs/telemetry": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.1.tgz",
"integrity": "sha512-7fcIxXS9J4ls5tr8b3ww9rbAIz2+HrhNJYZdkAhhB4za/I5IZ/60g+Bs8q7zwG0tOIZfNB4JWhVJ1Qkl/OrNCw==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.2.tgz",
"integrity": "sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==",
"license": "MIT",
"dependencies": {
"ci-info": "^4.4.0",
"dlv": "^1.1.3",
"dset": "^3.1.4",
"is-docker": "^4.0.0",
"is-wsl": "^3.1.1",
@@ -1270,9 +1269,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz",
"integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz",
"integrity": "sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==",
"cpu": [
"arm"
],
@@ -1283,9 +1282,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz",
"integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz",
"integrity": "sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==",
"cpu": [
"arm64"
],
@@ -1296,9 +1295,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz",
"integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz",
"integrity": "sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==",
"cpu": [
"arm64"
],
@@ -1309,9 +1308,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz",
"integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.3.tgz",
"integrity": "sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==",
"cpu": [
"x64"
],
@@ -1322,9 +1321,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz",
"integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz",
"integrity": "sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==",
"cpu": [
"arm64"
],
@@ -1335,9 +1334,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz",
"integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz",
"integrity": "sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==",
"cpu": [
"x64"
],
@@ -1348,9 +1347,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz",
"integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz",
"integrity": "sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==",
"cpu": [
"arm"
],
@@ -1364,9 +1363,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz",
"integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz",
"integrity": "sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==",
"cpu": [
"arm"
],
@@ -1380,9 +1379,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz",
"integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz",
"integrity": "sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==",
"cpu": [
"arm64"
],
@@ -1396,9 +1395,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz",
"integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz",
"integrity": "sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==",
"cpu": [
"arm64"
],
@@ -1412,9 +1411,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz",
"integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz",
"integrity": "sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==",
"cpu": [
"loong64"
],
@@ -1428,9 +1427,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz",
"integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz",
"integrity": "sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==",
"cpu": [
"loong64"
],
@@ -1444,9 +1443,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz",
"integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz",
"integrity": "sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==",
"cpu": [
"ppc64"
],
@@ -1460,9 +1459,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz",
"integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz",
"integrity": "sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==",
"cpu": [
"ppc64"
],
@@ -1476,9 +1475,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz",
"integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz",
"integrity": "sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==",
"cpu": [
"riscv64"
],
@@ -1492,9 +1491,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz",
"integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz",
"integrity": "sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==",
"cpu": [
"riscv64"
],
@@ -1508,9 +1507,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz",
"integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz",
"integrity": "sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==",
"cpu": [
"s390x"
],
@@ -1524,9 +1523,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz",
"integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz",
"integrity": "sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==",
"cpu": [
"x64"
],
@@ -1540,9 +1539,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz",
"integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz",
"integrity": "sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==",
"cpu": [
"x64"
],
@@ -1556,9 +1555,9 @@
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz",
"integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz",
"integrity": "sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==",
"cpu": [
"x64"
],
@@ -1569,9 +1568,9 @@
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz",
"integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz",
"integrity": "sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==",
"cpu": [
"arm64"
],
@@ -1582,9 +1581,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz",
"integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz",
"integrity": "sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==",
"cpu": [
"arm64"
],
@@ -1595,9 +1594,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz",
"integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz",
"integrity": "sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==",
"cpu": [
"ia32"
],
@@ -1608,9 +1607,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz",
"integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz",
"integrity": "sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==",
"cpu": [
"x64"
],
@@ -1621,9 +1620,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz",
"integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz",
"integrity": "sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==",
"cpu": [
"x64"
],
@@ -1743,9 +1742,9 @@
}
},
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
"integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
"license": "MIT"
},
"node_modules/@types/hast": {
@@ -1788,9 +1787,9 @@
"license": "MIT"
},
"node_modules/@ungap/structured-clone": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz",
"integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==",
"license": "ISC"
},
"node_modules/@volar/kit": {
@@ -1877,6 +1876,12 @@
"vscode-uri": "^3.0.8"
}
},
"node_modules/@vscode/emmet-helper/node_modules/jsonc-parser": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz",
"integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==",
"license": "MIT"
},
"node_modules/@vscode/l10n": {
"version": "0.0.18",
"resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz",
@@ -1988,15 +1993,15 @@
}
},
"node_modules/astro": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/astro/-/astro-6.2.1.tgz",
"integrity": "sha512-3g1sYNly+QAkuO5ErNEQBYvsxorNDSCUNIeStBs+kcXGchvKQl1Q9EuDNOvSg010XLlHJFLVFZs9LV18Jjp4Hg==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/astro/-/astro-6.3.1.tgz",
"integrity": "sha512-atz6dmkE3Gu24bDgb7g2RE/BYnKqPYIHd6hTUM1UXvu/i7qNZOKLAqEHvgYpv9PQVcgWsXpk4/OOXZ0E/FzvSQ==",
"license": "MIT",
"dependencies": {
"@astrojs/compiler": "^4.0.0",
"@astrojs/internal-helpers": "0.9.0",
"@astrojs/markdown-remark": "7.1.1",
"@astrojs/telemetry": "3.3.1",
"@astrojs/telemetry": "3.3.2",
"@capsizecss/unpack": "^4.0.0",
"@clack/prompts": "^1.1.0",
"@oslojs/encoding": "^1.1.0",
@@ -2014,10 +2019,12 @@
"esbuild": "^0.27.3",
"flattie": "^1.1.1",
"fontace": "~0.4.1",
"get-tsconfig": "5.0.0-beta.4",
"github-slugger": "^2.0.0",
"html-escaper": "3.0.3",
"http-cache-semantics": "^4.2.0",
"js-yaml": "^4.1.1",
"jsonc-parser": "^3.3.1",
"magic-string": "^0.30.21",
"magicast": "^0.5.2",
"mrmime": "^2.0.1",
@@ -2036,7 +2043,6 @@
"tinyclip": "^0.1.12",
"tinyexec": "^1.0.4",
"tinyglobby": "^0.2.15",
"tsconfck": "^3.1.6",
"ultrahtml": "^1.6.0",
"unifont": "~0.7.4",
"unist-util-visit": "^5.1.0",
@@ -2070,26 +2076,6 @@
"integrity": "sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==",
"license": "MIT"
},
"node_modules/astro/node_modules/tsconfck": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz",
"integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==",
"license": "MIT",
"bin": {
"tsconfck": "bin/tsconfck.js"
},
"engines": {
"node": "^18 || >=20"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -2445,12 +2431,6 @@
"node": ">=0.3.1"
}
},
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
"license": "MIT"
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
@@ -2669,9 +2649,9 @@
}
},
"node_modules/fast-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
"funding": [
{
"type": "github",
@@ -2763,6 +2743,21 @@
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-tsconfig": {
"version": "5.0.0-beta.4",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz",
"integrity": "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==",
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
"engines": {
"node": ">=20.20.0"
},
"funding": {
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/github-slugger": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
@@ -3097,9 +3092,9 @@
"license": "MIT"
},
"node_modules/jsonc-parser": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz",
"integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==",
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
"integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
"license": "MIT"
},
"node_modules/kleur": {
@@ -3122,9 +3117,9 @@
}
},
"node_modules/lru-cache": {
"version": "11.3.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz",
"integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==",
"version": "11.3.6",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz",
"integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==",
"license": "BlueOak-1.0.0",
"engines": {
"node": "20 || >=22"
@@ -4202,9 +4197,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.13",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.13.tgz",
"integrity": "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==",
"version": "8.5.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz",
"integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==",
"funding": [
{
"type": "opencollective",
@@ -4472,6 +4467,15 @@
"node": ">=0.10.0"
}
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"license": "MIT",
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
"node_modules/retext": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz",
@@ -4534,9 +4538,9 @@
}
},
"node_modules/rollup": {
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz",
"integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==",
"version": "4.60.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz",
"integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==",
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
@@ -4549,34 +4553,40 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.60.2",
"@rollup/rollup-android-arm64": "4.60.2",
"@rollup/rollup-darwin-arm64": "4.60.2",
"@rollup/rollup-darwin-x64": "4.60.2",
"@rollup/rollup-freebsd-arm64": "4.60.2",
"@rollup/rollup-freebsd-x64": "4.60.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.60.2",
"@rollup/rollup-linux-arm-musleabihf": "4.60.2",
"@rollup/rollup-linux-arm64-gnu": "4.60.2",
"@rollup/rollup-linux-arm64-musl": "4.60.2",
"@rollup/rollup-linux-loong64-gnu": "4.60.2",
"@rollup/rollup-linux-loong64-musl": "4.60.2",
"@rollup/rollup-linux-ppc64-gnu": "4.60.2",
"@rollup/rollup-linux-ppc64-musl": "4.60.2",
"@rollup/rollup-linux-riscv64-gnu": "4.60.2",
"@rollup/rollup-linux-riscv64-musl": "4.60.2",
"@rollup/rollup-linux-s390x-gnu": "4.60.2",
"@rollup/rollup-linux-x64-gnu": "4.60.2",
"@rollup/rollup-linux-x64-musl": "4.60.2",
"@rollup/rollup-openbsd-x64": "4.60.2",
"@rollup/rollup-openharmony-arm64": "4.60.2",
"@rollup/rollup-win32-arm64-msvc": "4.60.2",
"@rollup/rollup-win32-ia32-msvc": "4.60.2",
"@rollup/rollup-win32-x64-gnu": "4.60.2",
"@rollup/rollup-win32-x64-msvc": "4.60.2",
"@rollup/rollup-android-arm-eabi": "4.60.3",
"@rollup/rollup-android-arm64": "4.60.3",
"@rollup/rollup-darwin-arm64": "4.60.3",
"@rollup/rollup-darwin-x64": "4.60.3",
"@rollup/rollup-freebsd-arm64": "4.60.3",
"@rollup/rollup-freebsd-x64": "4.60.3",
"@rollup/rollup-linux-arm-gnueabihf": "4.60.3",
"@rollup/rollup-linux-arm-musleabihf": "4.60.3",
"@rollup/rollup-linux-arm64-gnu": "4.60.3",
"@rollup/rollup-linux-arm64-musl": "4.60.3",
"@rollup/rollup-linux-loong64-gnu": "4.60.3",
"@rollup/rollup-linux-loong64-musl": "4.60.3",
"@rollup/rollup-linux-ppc64-gnu": "4.60.3",
"@rollup/rollup-linux-ppc64-musl": "4.60.3",
"@rollup/rollup-linux-riscv64-gnu": "4.60.3",
"@rollup/rollup-linux-riscv64-musl": "4.60.3",
"@rollup/rollup-linux-s390x-gnu": "4.60.3",
"@rollup/rollup-linux-x64-gnu": "4.60.3",
"@rollup/rollup-linux-x64-musl": "4.60.3",
"@rollup/rollup-openbsd-x64": "4.60.3",
"@rollup/rollup-openharmony-arm64": "4.60.3",
"@rollup/rollup-win32-arm64-msvc": "4.60.3",
"@rollup/rollup-win32-ia32-msvc": "4.60.3",
"@rollup/rollup-win32-x64-gnu": "4.60.3",
"@rollup/rollup-win32-x64-msvc": "4.60.3",
"fsevents": "~2.3.2"
}
},
"node_modules/rollup/node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"license": "MIT"
},
"node_modules/sax": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
@@ -4587,9 +4597,9 @@
}
},
"node_modules/semver": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
"integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -5197,9 +5207,9 @@
}
},
"node_modules/vite": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz",
"integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==",
"version": "7.3.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz",
"integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==",
"license": "MIT",
"dependencies": {
"esbuild": "^0.27.0",
@@ -5465,12 +5475,6 @@
"npm": ">=7.0.0"
}
},
"node_modules/vscode-json-languageservice/node_modules/jsonc-parser": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
"integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
"license": "MIT"
},
"node_modules/vscode-jsonrpc": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
@@ -5578,9 +5582,9 @@
}
},
"node_modules/yaml": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz",
"integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
@@ -5681,9 +5685,9 @@
}
},
"node_modules/zod": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.2.tgz",
"integrity": "sha512-IynmDyxsEsb9RKzO3J9+4SxXnl2FTFSzNBaKKaMV6tsSk0rw9gYw9gs+JFCq/qk2LCZ78KDwyj+Z289TijSkUw==",
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "class-anniversary",
"version": "0.3.0",
"version": "1.2.0",
"private": true,
"type": "module",
"scripts": {
+1
View File
@@ -0,0 +1 @@
Binary file not shown.
+2 -1
View File
@@ -3,7 +3,8 @@ export const examIntro = {
eyebrow: "Class 612 Exam",
description:
"一份写给 2024 届 612 班的特别试卷。网页保留正文、插图与公式,原始版式可下载 Word 原卷查看。",
downloadHref: "/assets/exam/2024-exam.docx"
downloadHref: "https://s3.biss.click/OFFICE/exam-2024.pdf",
previewHref: "https://file.biss.click/onlinePreview?url=aHR0cHM6Ly9zMy5iaXNzLmNsaWNrL09GRklDRS9leGFtLTIwMjQucGRm&watermarkTxt=%E4%BB%85%E4%BE%9B%E9%A2%84%E8%A7%88"
};
export const examMath: Record<string, string> = {
+14 -14
View File
@@ -7,29 +7,29 @@ export const classroomTopic: PhotoTopic = {
cover: "",
photos: [
{
title: "窗边的座位",
caption: "把真实照片放到 public/photos/classroom/window-seat.jpg 后,再把 image 改成对应路径。",
image: ""
title: "窗边",
caption: "走廊尽头的窗户",
image: "https://pic.biss.click/image/d4aa5275-9581-4d43-8d7e-ef3f44f8c497.jpg"
},
{
title: "黑板角落",
caption: "适合放倒计时、值日表、板书和课代表留下的提醒。",
image: ""
caption: "倒计时、值日表、板书和课代表留下的提醒。",
image: "https://pic.biss.click/image/049b8074-fde1-423c-b9b5-b89cfe4430e9.jpg"
},
{
title: "堆满书的桌面",
caption: "那些看起来很乱、后来又很想念的普通一天。",
image: ""
title: "黑板上的一句话",
caption: "",
image: "https://pic.biss.click/image/d37b224b-81ea-40cf-87aa-1dfa02312ba7.jpg"
},
{
title: "晚自习灯光",
caption: "可以放教室灯亮着、窗外天色暗下来的照片。",
image: ""
title: "高考加油",
caption: "",
image: "https://pic.biss.click/image/d06e370e-39a7-497e-a47d-eed7a759a67a.jpg"
},
{
title: "课间十分钟",
caption: "不用太正式,越像随手拍越有高中味道。",
image: ""
title: "询问老师",
caption: "课后向老师请教问题",
image: "https://pic.biss.click/image/95c03bd4-d0d3-4c38-9855-3342fd582080.jpg"
}
]
};
+1 -1
View File
@@ -21,7 +21,7 @@ export const contactLinks = [
},
{
label: "微信公众号",
href: "#",
href: "https://pic.biss.click/image/44a5e576-5cf3-4752-bae2-70d74619324f.webp",
icon: "fa-brands fa-weixin",
qrImage: "https://pic.biss.click/image/44a5e576-5cf3-4752-bae2-70d74619324f.webp"
}
+164
View File
@@ -0,0 +1,164 @@
---
import "../styles/anniversary.css";
const memoryCards = [
{
kicker: "2021",
title: "把名字写进同一张名单",
text: "从陌生的座位、军训的队列,到第一次一起等铃声响起,班级的故事从那时开始慢慢有了形状。"
},
{
kicker: "2022",
title: "普通日子也有回声",
text: "网课、考试、活动、晚自习,很多当时只觉得匆忙的片段,后来都变成了可以反复想起的证据。"
},
{
kicker: "2023",
title: "高三把我们推向同一个方向",
text: "倒计时、试卷、誓师和一次次模拟,把每个人的步伐压得很紧,也把彼此留得更深。"
},
{
kicker: "2024",
title: "毕业不是散场",
text: "离开校门以后,我们去了不同的地方,但那些一起走过的清晨和黄昏,仍然在这里被好好保存。"
}
];
const gallery = [
"/assets/campus-hero.png",
"/assets/exam/image1.png",
"/assets/exam/image3.jpg",
"/assets/exam/image4.jpeg",
"/assets/exam/image5.jpg",
"/assets/exam/image6.jpg"
];
const backgroundMusic = "/assets/anniversary/background-music.mp3";
const anniversaryVideo = "/assets/anniversary/anniversary-video.mp4";
const videoPoster = "/assets/campus-hero.png";
---
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>2024届12班周年专题</title>
<meta
name="description"
content="2024届12班周年专题页,收下那些毕业之后仍然清晰的瞬间。"
/>
</head>
<body>
<main class="anniversary-page">
<section class="hero" aria-labelledby="hero-title">
<img class="hero-media" src="/assets/campus-hero.png" alt="校园记忆" />
<div class="hero-shade" aria-hidden="true"></div>
<nav class="topbar" aria-label="周年专题导航">
<a class="home-link" href="/">2024届12班</a>
<div class="topbar-links">
<a href="#memory">时间切片</a>
<a href="#gallery">影像回放</a>
<a href="#letter">写给我们</a>
</div>
</nav>
<div class="hero-content">
<p class="eyebrow">毕业周年专题</p>
<h1 id="hero-title">我们仍在同一段青春里相遇</h1>
<p class="hero-copy">
从 2024 年夏天出发,到今天再次回望。这里不急着总结人生,只把一起经过的日子重新点亮。
</p>
<div class="hero-actions" aria-label="页面入口">
<a class="primary-action" href="#memory">开始回望</a>
<a class="secondary-action" href="/gallery/">去照片墙</a>
</div>
</div>
<aside class="music-player" aria-label="背景音乐">
<span class="music-mark" aria-hidden="true">♪</span>
<div class="music-copy">
<strong>背景乐</strong>
<span>替换 public/assets/anniversary/background-music.mp3</span>
</div>
<audio controls preload="metadata" loop>
<source src={backgroundMusic} type="audio/mpeg" />
</audio>
</aside>
<div class="hero-count">
<strong>2</strong>
<span>周年纪念</span>
</div>
</section>
<section class="ticker" aria-label="纪念短句">
<span>铃声响过</span>
<span>操场还亮着</span>
<span>试卷翻页</span>
<span>合照定格</span>
<span>名字仍被记得</span>
</section>
<section class="memory-section" id="memory" aria-labelledby="memory-title">
<div class="section-heading">
<p class="eyebrow">Time Slices</p>
<h2 id="memory-title">把三年拆成几束光</h2>
</div>
<div class="memory-grid">
{
memoryCards.map((card) => (
<article class="memory-card">
<span>{card.kicker}</span>
<h3>{card.title}</h3>
<p>{card.text}</p>
</article>
))
}
</div>
</section>
<section class="gallery-section" id="gallery" aria-labelledby="gallery-title">
<div class="section-heading">
<p class="eyebrow">Replay</p>
<h2 id="gallery-title">一些会自己发光的画面</h2>
</div>
<div class="video-feature" aria-label="周年视频">
<div class="video-frame">
<video controls preload="metadata" poster={videoPoster}>
<source src={anniversaryVideo} type="video/mp4" />
</video>
</div>
<div class="video-caption">
<p class="eyebrow">Film</p>
<h3>周年视频</h3>
<p>
替换 public/assets/anniversary/anniversary-video.mp4,这里会显示为专题视频播放区。
</p>
</div>
</div>
<div class="photo-strip">
{
gallery.map((src, index) => (
<figure class={`photo-card photo-card-${index + 1}`}>
<img src={src} alt={`周年纪念影像 ${index + 1}`} loading={index === 0 ? "eager" : "lazy"} />
</figure>
))
}
</div>
</section>
<section class="letter-section" id="letter" aria-labelledby="letter-title">
<div class="letter-panel">
<p class="eyebrow">For Us</p>
<h2 id="letter-title">写给毕业后的我们</h2>
<p>
后来的我们会遇见新的城市、新的课程、新的工作和新的自己。可只要有人再次提起那间教室、那次考试、那张合照,
2024届12班就会短暂地重新集合。
</p>
<p>
愿每一次回到这里,都不是为了停在过去,而是确认:那些一起认真生活过的日子,已经成为继续往前走的底气。
</p>
<a href="/messages/">留下新的近况</a>
</div>
</section>
</main>
</body>
</html>
+55 -2
View File
@@ -69,8 +69,7 @@ let questionNumber = 0;
<h1>{examIntro.title}</h1>
<p>{examIntro.description}</p>
<div class="hero-actions">
<a class="button primary" href={examIntro.downloadHref} download>下载原卷</a>
<a class="button" href="#paper">阅读试卷</a>
<a class="button primary" href={examIntro.previewHref} target="_blank" rel="noreferrer">预览原卷</a>
</div>
</div>
</section>
@@ -228,6 +227,16 @@ let questionNumber = 0;
}
</article>
<button
class="score-fab"
type="button"
aria-controls="scorer"
aria-expanded="false"
aria-label="打开答题卡"
data-score-toggle
>
</button>
<aside class="score-sidebar" id="scorer" aria-label="答题卡">
<form class="score-panel" id="exam-scorer">
<div class="score-sidebar-head">
@@ -357,6 +366,8 @@ let questionNumber = 0;
}}
>
const scorer = document.querySelector("#exam-scorer");
const scoreSidebar = document.querySelector("#scorer");
const scoreToggle = document.querySelector("[data-score-toggle]");
const candidateName = document.querySelector("#candidate-name");
const admissionNumber = document.querySelector("#admission-number");
const seatNumber = document.querySelector("#seat-number");
@@ -365,6 +376,16 @@ let questionNumber = 0;
const cardSeatNumber = document.querySelector("#card-seat-number");
const draftStorageKey = "examDraft";
const setScoreMenuOpen = (isOpen) => {
scoreSidebar?.classList.toggle("is-open", isOpen);
if (scoreToggle) {
scoreToggle.setAttribute("aria-expanded", String(isOpen));
scoreToggle.setAttribute("aria-label", isOpen ? "关闭答题卡" : "打开答题卡");
scoreToggle.textContent = isOpen ? "×" : "答";
}
};
const normalizeAnswer = (value) =>
String(value || "")
.trim()
@@ -386,6 +407,27 @@ let questionNumber = 0;
return Math.min(Math.max(score, 0), max);
};
const clampManualScoreInput = (input) => {
const value = input.value.trim();
if (!value) {
return;
}
const max = Number(input.dataset.points || input.max || 0);
const score = Number(value);
if (!Number.isFinite(score)) {
return;
}
const clampedScore = clampScore(score, max);
if (score !== clampedScore) {
input.value = String(clampedScore);
}
};
const getDraft = () => ({
candidate: {
name: candidateName?.value ?? "",
@@ -464,6 +506,7 @@ let questionNumber = 0;
if (draft.manualScores?.[questionNumber] != null) {
input.value = draft.manualScores[questionNumber];
clampManualScoreInput(input);
}
});
};
@@ -742,6 +785,7 @@ let questionNumber = 0;
});
scorer?.querySelectorAll("[data-manual-score]").forEach((input) => {
input.addEventListener("input", () => {
clampManualScoreInput(input);
updateAnswerCardStates();
saveDraft();
});
@@ -754,8 +798,17 @@ let questionNumber = 0;
behavior: "smooth",
block: "start"
});
setScoreMenuOpen(false);
});
});
scoreToggle?.addEventListener("click", () => {
setScoreMenuOpen(!scoreSidebar?.classList.contains("is-open"));
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
setScoreMenuOpen(false);
}
});
admissionNumber?.addEventListener("input", () => {
admissionNumber.value = admissionNumber.value.replace(/\D/g, "").slice(0, admissionNumber.maxLength);
+1 -1
View File
@@ -26,7 +26,7 @@ import { site } from "../../data/site";
<div class="result-content" id="result-content" hidden>
<div class="result-head">
<div>
<p class="eyebrow">综合素质检测模拟卷</p>
<p class="eyebrow">普通高中毕业班综合测试~综合素质检测</p>
<h2 id="result-title">成绩单</h2>
</div>
<button class="score-submit" type="button" id="download-share">下载分享图</button>
+575
View File
@@ -0,0 +1,575 @@
:root {
color: #24170f;
background: #f7efe3;
font-family:
"Inter", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", system-ui,
sans-serif;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
min-width: 320px;
background:
linear-gradient(90deg, rgba(36, 23, 15, 0.05) 1px, transparent 1px),
linear-gradient(180deg, rgba(36, 23, 15, 0.05) 1px, transparent 1px),
#f7efe3;
background-size: 42px 42px;
}
a {
color: inherit;
text-decoration: none;
}
.anniversary-page {
overflow: hidden;
}
.hero {
position: relative;
min-height: 92vh;
display: grid;
align-items: end;
padding: 28px clamp(18px, 5vw, 72px) 64px;
color: #fff9ed;
isolation: isolate;
}
.hero-media,
.hero-shade {
position: absolute;
inset: 0;
z-index: -2;
}
.hero-media {
width: 100%;
height: 100%;
object-fit: cover;
filter: saturate(0.96) contrast(1.04);
}
.hero-shade {
z-index: -1;
background:
linear-gradient(90deg, rgba(22, 12, 7, 0.86), rgba(22, 12, 7, 0.34) 58%, rgba(22, 12, 7, 0.52)),
linear-gradient(0deg, rgba(22, 12, 7, 0.9), transparent 44%);
}
.topbar {
position: absolute;
top: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
gap: 24px;
align-items: center;
padding: 24px clamp(18px, 5vw, 72px);
}
.home-link,
.topbar-links a {
border: 1px solid rgba(255, 249, 237, 0.42);
background: rgba(255, 249, 237, 0.1);
backdrop-filter: blur(14px);
}
.home-link {
padding: 12px 16px;
font-weight: 800;
}
.topbar-links {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
.topbar-links a {
padding: 10px 13px;
font-size: 14px;
}
.hero-content {
width: min(900px, 100%);
padding-top: 96px;
}
.eyebrow {
margin: 0 0 14px;
color: #c75f2a;
font-size: 13px;
font-weight: 900;
letter-spacing: 0;
text-transform: uppercase;
}
.hero .eyebrow {
color: #ffd36c;
}
h1,
h2,
h3,
p {
margin-top: 0;
}
h1 {
max-width: 980px;
margin-bottom: 22px;
font-size: clamp(46px, 8vw, 118px);
line-height: 0.96;
letter-spacing: 0;
text-wrap: balance;
}
.hero-copy {
max-width: 720px;
margin-bottom: 32px;
color: rgba(255, 249, 237, 0.84);
font-size: clamp(18px, 2vw, 24px);
line-height: 1.7;
}
.hero-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.primary-action,
.secondary-action,
.letter-panel a {
display: inline-flex;
min-height: 48px;
align-items: center;
justify-content: center;
padding: 0 22px;
font-weight: 900;
}
.primary-action,
.letter-panel a {
background: #ffd36c;
color: #24170f;
}
.secondary-action {
border: 1px solid rgba(255, 249, 237, 0.5);
color: #fff9ed;
}
.music-player {
position: fixed;
right: clamp(14px, 3vw, 34px);
bottom: clamp(14px, 3vw, 34px);
z-index: 20;
width: min(420px, calc(100vw - 28px));
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 12px 14px;
align-items: center;
padding: 14px;
border: 1px solid rgba(255, 249, 237, 0.34);
background: rgba(20, 35, 29, 0.46);
backdrop-filter: blur(18px);
box-shadow: 0 18px 50px rgba(22, 12, 7, 0.24);
}
.music-mark {
display: grid;
place-items: center;
width: 42px;
aspect-ratio: 1;
border-radius: 50%;
background: #ffd36c;
color: #24170f;
font-size: 24px;
font-weight: 900;
}
.music-copy {
display: grid;
gap: 3px;
min-width: 0;
}
.music-copy strong,
.music-copy span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.music-copy strong {
font-size: 15px;
}
.music-copy span {
color: rgba(255, 249, 237, 0.66);
font-size: 12px;
}
.music-player audio {
grid-column: 1 / -1;
width: 100%;
height: 38px;
}
.hero-count {
position: absolute;
right: clamp(18px, 5vw, 72px);
bottom: 42px;
display: grid;
place-items: center;
width: clamp(108px, 14vw, 172px);
aspect-ratio: 1;
border: 1px solid rgba(255, 249, 237, 0.4);
border-radius: 50%;
background: rgba(255, 249, 237, 0.12);
backdrop-filter: blur(16px);
}
.hero-count strong {
font-size: clamp(42px, 7vw, 82px);
line-height: 0.9;
}
.hero-count span {
font-size: 13px;
font-weight: 800;
}
.ticker {
display: flex;
gap: 12px;
overflow-x: auto;
padding: 18px clamp(18px, 5vw, 72px);
color: #fff9ed;
background: #24170f;
scrollbar-width: none;
}
.ticker span {
flex: 0 0 auto;
padding: 8px 16px;
border: 1px solid rgba(255, 249, 237, 0.25);
border-radius: 999px;
color: rgba(255, 249, 237, 0.82);
font-size: 14px;
}
.memory-section,
.gallery-section,
.letter-section {
padding: clamp(64px, 9vw, 120px) clamp(18px, 5vw, 72px);
}
.section-heading {
display: grid;
grid-template-columns: minmax(0, 0.42fr) minmax(0, 0.58fr);
gap: 28px;
align-items: end;
margin-bottom: 34px;
}
.section-heading h2,
.letter-panel h2 {
margin-bottom: 0;
color: #24170f;
font-size: clamp(34px, 5vw, 72px);
line-height: 1.04;
letter-spacing: 0;
}
.memory-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
border: 1px solid #24170f;
background: #24170f;
gap: 1px;
}
.memory-card {
min-height: 360px;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 24px;
background: #f7efe3;
}
.memory-card span {
color: #c75f2a;
font-size: 46px;
font-weight: 950;
line-height: 1;
}
.memory-card h3 {
margin-bottom: 16px;
font-size: 25px;
line-height: 1.18;
letter-spacing: 0;
}
.memory-card p,
.letter-panel p {
color: rgba(36, 23, 15, 0.72);
font-size: 16px;
line-height: 1.9;
}
.gallery-section {
color: #fff9ed;
background: #14231d;
}
.gallery-section .section-heading h2 {
color: #fff9ed;
}
.video-feature {
display: grid;
grid-template-columns: minmax(0, 0.68fr) minmax(260px, 0.32fr);
gap: clamp(18px, 4vw, 42px);
align-items: end;
margin-bottom: clamp(28px, 5vw, 58px);
}
.video-frame {
position: relative;
overflow: hidden;
aspect-ratio: 16 / 9;
border: 1px solid rgba(255, 249, 237, 0.18);
background:
linear-gradient(135deg, rgba(255, 211, 108, 0.22), transparent),
rgba(255, 249, 237, 0.08);
}
.video-frame video {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
.video-caption {
padding-bottom: 10px;
}
.video-caption h3 {
margin-bottom: 14px;
color: #fff9ed;
font-size: clamp(28px, 4vw, 52px);
line-height: 1.08;
}
.video-caption p:last-child {
margin-bottom: 0;
color: rgba(255, 249, 237, 0.7);
font-size: 16px;
line-height: 1.8;
}
.photo-strip {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: 86px;
gap: 14px;
}
.photo-card {
margin: 0;
min-height: 180px;
overflow: hidden;
background: rgba(255, 249, 237, 0.1);
}
.photo-card img {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
.photo-card-1 {
grid-column: span 5;
grid-row: span 5;
}
.photo-card-2 {
grid-column: span 3;
grid-row: span 3;
}
.photo-card-3 {
grid-column: span 4;
grid-row: span 4;
}
.photo-card-4 {
grid-column: span 4;
grid-row: span 3;
}
.photo-card-5 {
grid-column: span 3;
grid-row: span 4;
}
.photo-card-6 {
grid-column: span 5;
grid-row: span 3;
}
.letter-section {
display: grid;
min-height: 76vh;
align-items: center;
background:
linear-gradient(135deg, rgba(199, 95, 42, 0.16), transparent 36%),
#f7efe3;
}
.letter-panel {
width: min(820px, 100%);
margin-inline: auto;
border-left: 6px solid #c75f2a;
padding: 12px 0 12px clamp(24px, 5vw, 56px);
}
.letter-panel h2 {
margin-bottom: 24px;
}
.letter-panel a {
margin-top: 14px;
}
@media (max-width: 900px) {
.hero {
min-height: 88vh;
padding-bottom: 42px;
}
.topbar {
align-items: flex-start;
}
.topbar-links {
max-width: 190px;
}
.hero-count {
position: static;
margin-top: 38px;
}
.music-player {
width: min(420px, calc(100vw - 28px));
}
.section-heading {
grid-template-columns: 1fr;
gap: 8px;
}
.memory-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.photo-strip {
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: 72px;
}
.video-feature {
grid-template-columns: 1fr;
}
.photo-card-1,
.photo-card-3,
.photo-card-6 {
grid-column: span 6;
}
.photo-card-2,
.photo-card-4,
.photo-card-5 {
grid-column: span 3;
}
}
@media (max-width: 560px) {
.topbar {
position: relative;
padding: 0 0 42px;
flex-direction: column;
}
.topbar-links {
max-width: none;
justify-content: flex-start;
}
.hero {
min-height: auto;
padding-top: 18px;
}
h1 {
font-size: 44px;
}
.hero-copy {
font-size: 17px;
}
.music-player {
grid-template-columns: auto minmax(0, 1fr);
padding: 12px;
}
.music-mark {
width: 38px;
}
.music-copy span {
display: none;
}
.memory-grid {
grid-template-columns: 1fr;
}
.memory-card {
min-height: 280px;
}
.photo-strip {
display: flex;
overflow-x: auto;
padding-bottom: 10px;
}
.photo-card {
flex: 0 0 78%;
height: 320px;
}
.letter-panel {
border-left-width: 4px;
}
}
+94 -10
View File
@@ -1178,6 +1178,10 @@ h2 {
z-index: -1;
}
.score-fab {
display: none;
}
.score-panel {
display: grid;
gap: 12px;
@@ -1780,7 +1784,7 @@ h2 {
@media (max-width: 820px) {
body:has(.score-sidebar) {
padding-bottom: min(52vh, 540px);
padding-bottom: 86px;
}
.site-header {
@@ -1873,16 +1877,60 @@ h2 {
padding-right: 0;
}
.score-fab {
position: fixed;
right: 18px;
bottom: 18px;
z-index: 30;
width: 58px;
height: 58px;
display: grid;
place-items: center;
border: 1px solid rgba(255, 253, 247, 0.62);
border-radius: 50%;
background: var(--green);
color: #fffdf7;
box-shadow: 0 16px 38px rgba(13, 20, 19, 0.28);
font: inherit;
font-size: 22px;
font-weight: 900;
line-height: 1;
cursor: pointer;
transition:
background 180ms ease,
transform 180ms ease,
box-shadow 180ms ease;
}
.score-fab[aria-expanded="true"] {
background: var(--coral);
transform: scale(1.04);
}
.score-sidebar {
position: fixed;
top: auto;
left: 12px;
right: 12px;
bottom: 12px;
bottom: 88px;
width: auto;
max-height: min(46vh, 500px);
max-height: min(64vh, 560px);
border-radius: 10px;
background: rgba(255, 253, 247, 0.96);
box-shadow: 0 18px 44px rgba(13, 20, 19, 0.22);
opacity: 0;
pointer-events: none;
transform: translateY(14px) scale(0.98);
transform-origin: bottom right;
transition:
opacity 180ms ease,
transform 180ms ease;
}
.score-sidebar.is-open {
opacity: 1;
pointer-events: auto;
transform: translateY(0) scale(1);
}
.score-panel {
@@ -1890,7 +1938,12 @@ h2 {
}
.score-sidebar-head {
padding: 14px 14px 0;
position: sticky;
top: 0;
z-index: 1;
padding: 12px 14px 8px;
border-bottom: 1px solid var(--line);
background: rgba(255, 253, 247, 0.98);
}
.score-sidebar-head h2 {
@@ -1903,6 +1956,12 @@ h2 {
font-size: 12px;
}
.score-sidebar-head p:not(.eyebrow),
.answer-card-profile,
.score-total-note {
display: none;
}
.score-group {
padding: 12px;
}
@@ -1933,12 +1992,20 @@ h2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.score-total {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.score-total > div {
border-right: 0;
border-right: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.score-total > div:last-child {
.score-total > div:nth-child(even) {
border-right: 0;
}
.score-total > div:nth-last-child(-n + 2) {
border-bottom: 0;
}
@@ -2037,11 +2104,13 @@ h2 {
}
.exam-paper {
padding: 16px;
padding: 14px;
border-radius: 0;
}
.exam-paper p {
font-size: 15px;
line-height: 1.78;
}
.exam-paper h2 {
@@ -2053,8 +2122,9 @@ h2 {
}
.exam-question {
grid-template-columns: 32px minmax(0, 1fr);
grid-template-columns: 30px minmax(0, 1fr);
gap: 8px;
margin-top: 18px !important;
}
.exam-question-number {
@@ -2065,9 +2135,15 @@ h2 {
.exam-options {
grid-template-columns: 1fr;
gap: 8px;
margin-left: 0;
}
.exam-option {
min-height: 42px;
padding: 8px 10px;
}
.exam-fill-answer {
grid-template-columns: 1fr;
margin-left: 0;
@@ -2075,6 +2151,7 @@ h2 {
.name-fill-grid {
grid-template-columns: 1fr 1fr;
gap: 7px;
margin-left: 0;
padding: 10px;
}
@@ -2103,8 +2180,15 @@ h2 {
.score-sidebar {
left: 8px;
right: 8px;
bottom: 8px;
max-height: 50vh;
bottom: 82px;
max-height: min(66vh, 520px);
}
.score-fab {
right: 14px;
bottom: 14px;
width: 56px;
height: 56px;
}
.score-group h3 {