Răsfoiți Sursa

first commit

bobyuxinyang 1 lună în urmă
părinte
comite
ff258f771a
91 a modificat fișierele cu 3963 adăugiri și 0 ștergeri
  1. 39 0
      .gitignore
  2. 12 0
      brand/.gitignore
  3. 48 0
      brand/README.md
  4. 13 0
      brand/logo-chinese-dark.svg
  5. 13 0
      brand/logo-chinese-light-bg.svg
  6. 12 0
      brand/logo-chinese-light.svg
  7. 15 0
      brand/logo-chinese-slogan-dark.svg
  8. 15 0
      brand/logo-chinese-slogan-light-bg.svg
  9. 14 0
      brand/logo-chinese-slogan-light.svg
  10. 14 0
      brand/logo-chinese-slogan.svg
  11. 12 0
      brand/logo-chinese.svg
  12. 14 0
      brand/logo-less-and-cosmos-dark.svg
  13. 14 0
      brand/logo-less-and-cosmos-light-bg.svg
  14. 13 0
      brand/logo-less-and-cosmos-light.svg
  15. 13 0
      brand/logo-less-and-cosmos-mono.svg
  16. 13 0
      brand/logo-less-and-cosmos.svg
  17. 9 0
      brand/logo-mark-dark.svg
  18. 9 0
      brand/logo-mark-light-bg.svg
  19. 8 0
      brand/logo-mark-light.svg
  20. 8 0
      brand/logo-mark-mono.svg
  21. 8 0
      brand/logo-mark.svg
  22. 472 0
      brand/logo-preview.html
  23. 32 0
      brand/png/README.md
  24. BIN
      brand/png/logo-chinese-dark-1x.png
  25. BIN
      brand/png/logo-chinese-dark-2x.png
  26. BIN
      brand/png/logo-chinese-light-bg-1x.png
  27. BIN
      brand/png/logo-chinese-light-bg-2x.png
  28. BIN
      brand/png/logo-chinese-light-transparent-1x.png
  29. BIN
      brand/png/logo-chinese-light-transparent-2x.png
  30. BIN
      brand/png/logo-chinese-slogan-dark-1x.png
  31. BIN
      brand/png/logo-chinese-slogan-dark-2x.png
  32. BIN
      brand/png/logo-chinese-slogan-light-bg-1x.png
  33. BIN
      brand/png/logo-chinese-slogan-light-bg-2x.png
  34. BIN
      brand/png/logo-chinese-slogan-light-transparent-1x.png
  35. BIN
      brand/png/logo-chinese-slogan-light-transparent-2x.png
  36. BIN
      brand/png/logo-chinese-slogan-transparent-1x.png
  37. BIN
      brand/png/logo-chinese-slogan-transparent-2x.png
  38. BIN
      brand/png/logo-chinese-transparent-1x.png
  39. BIN
      brand/png/logo-chinese-transparent-2x.png
  40. BIN
      brand/png/logo-full-dark-1x.png
  41. BIN
      brand/png/logo-full-dark-2x.png
  42. BIN
      brand/png/logo-full-light-bg-1x.png
  43. BIN
      brand/png/logo-full-light-bg-2x.png
  44. BIN
      brand/png/logo-full-light-transparent-1x.png
  45. BIN
      brand/png/logo-full-light-transparent-2x.png
  46. BIN
      brand/png/logo-full-mono-transparent-1x.png
  47. BIN
      brand/png/logo-full-mono-transparent-2x.png
  48. BIN
      brand/png/logo-full-transparent-1x.png
  49. BIN
      brand/png/logo-full-transparent-2x.png
  50. BIN
      brand/png/logo-mark-dark-1x.png
  51. BIN
      brand/png/logo-mark-dark-2x.png
  52. BIN
      brand/png/logo-mark-light-bg-1x.png
  53. BIN
      brand/png/logo-mark-light-bg-2x.png
  54. BIN
      brand/png/logo-mark-light-transparent-1x.png
  55. BIN
      brand/png/logo-mark-light-transparent-2x.png
  56. BIN
      brand/png/logo-mark-mono-transparent-1x.png
  57. BIN
      brand/png/logo-mark-mono-transparent-2x.png
  58. BIN
      brand/png/logo-mark-transparent-1x.png
  59. BIN
      brand/png/logo-mark-transparent-2x.png
  60. 19 0
      case-timeline/.gitignore
  61. 34 0
      case-timeline/README.md
  62. 203 0
      case-timeline/app.js
  63. 174 0
      case-timeline/case-data.js
  64. 106 0
      case-timeline/index.html
  65. 394 0
      case-timeline/styles.css
  66. 30 0
      website/.gitignore
  67. 8 0
      website/.oxlintrc.json
  68. 16 0
      website/README.md
  69. 23 0
      website/deploy.sh
  70. 16 0
      website/index.html
  71. 31 0
      website/nginx.conf
  72. 1332 0
      website/package-lock.json
  73. 23 0
      website/package.json
  74. 14 0
      website/public/brand/logo-chinese-slogan.svg
  75. 8 0
      website/public/brand/logo-mark.svg
  76. 0 0
      website/public/favicon.svg
  77. 24 0
      website/public/icons.svg
  78. 15 0
      website/scp_cmd.exp
  79. 19 0
      website/src/App.jsx
  80. BIN
      website/src/assets/hero.png
  81. 0 0
      website/src/assets/vite.svg
  82. 34 0
      website/src/components/Accounts.jsx
  83. 10 0
      website/src/components/Footer.jsx
  84. 15 0
      website/src/components/Hero.jsx
  85. 46 0
      website/src/components/Nav.jsx
  86. 88 0
      website/src/components/StarsCanvas.jsx
  87. 8 0
      website/src/data/accounts.js
  88. 390 0
      website/src/index.css
  89. 10 0
      website/src/main.jsx
  90. 14 0
      website/ssh_cmd.exp
  91. 39 0
      website/vite.config.js

+ 39 - 0
.gitignore

@@ -0,0 +1,39 @@
+# macOS
+.DS_Store
+**/.DS_Store
+
+# Node.js dependencies
+node_modules/
+
+# Build output and caches
+dist/
+build/
+.vite/
+.cache/
+coverage/
+
+# Environment files (keep examples in Git)
+.env
+.env.*
+!.env.example
+!.env.*.example
+
+# Logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor and IDE settings
+.idea/
+.vscode/*
+!.vscode/extensions.json
+!.vscode/settings.json
+*.swp
+*.swo
+
+# Temporary files
+*.tmp
+*.temp
+*~

+ 12 - 0
brand/.gitignore

@@ -0,0 +1,12 @@
+# macOS and editor files
+.DS_Store
+.idea/
+.vscode/
+*.swp
+*.swo
+
+# Temporary and generated exports
+*.tmp
+*.temp
+*~
+

+ 48 - 0
brand/README.md

@@ -0,0 +1,48 @@
+# Less and Cosmos Visual Identity
+
+## Core Lockup
+
+- English wordmark: `less and cosmos.`
+- Chinese slogan: `一念纯粹,万里星辰。`
+- Symbol: a small spark dot followed by a thin orbital arc.
+- Style: no gradients, no shadows, no decorative noise.
+
+## Palette
+
+| Name | HEX | Use |
+| --- | --- | --- |
+| 纯粹之境 / Absolute Void | `#0B0C10` | Primary background, hardware surface, website base |
+| 寂静星云 / Muted Nebula | `#1F2833` | Secondary background, modules, cards |
+| 星光极白 / Cosmos White | `#F5F5F7` | Main text, fine lines, chart strokes |
+| 智慧水星 / Mercury Silver | `#C5C6C7` | Secondary labels, borders, metadata |
+| 一念微光 / The Spark Gold | `#E6C687` | Rare emphasis, badges, primary spark |
+
+## Files
+
+- `logo-less-and-cosmos.svg`: full horizontal lockup.
+- `logo-less-and-cosmos-dark.svg`: full horizontal lockup on Absolute Void.
+- `logo-less-and-cosmos-light.svg`: full horizontal lockup tuned for white or light backgrounds.
+- `logo-less-and-cosmos-light-bg.svg`: light-background full horizontal lockup on Cosmos White.
+- `logo-mark.svg`: standalone visual symbol.
+- `logo-mark-dark.svg`: standalone visual symbol on Absolute Void.
+- `logo-mark-light.svg`: standalone visual symbol tuned for white or light backgrounds.
+- `logo-mark-light-bg.svg`: light-background standalone visual symbol on Cosmos White.
+- `logo-chinese.svg`: symbol with `纯粹星辰`.
+- `logo-chinese-dark.svg`: symbol with `纯粹星辰` on Absolute Void.
+- `logo-chinese-light.svg`: symbol with `纯粹星辰` tuned for white or light backgrounds.
+- `logo-chinese-light-bg.svg`: symbol with `纯粹星辰` on Cosmos White.
+- `logo-chinese-slogan.svg`: symbol with `纯粹星辰` and `一念纯粹,万里星辰。`.
+- `logo-chinese-slogan-dark.svg`: symbol with Chinese name and slogan on Absolute Void.
+- `logo-chinese-slogan-light.svg`: symbol with Chinese name and slogan tuned for white or light backgrounds.
+- `logo-chinese-slogan-light-bg.svg`: symbol with Chinese name and slogan on Cosmos White.
+- `logo-less-and-cosmos-mono.svg`: monochrome full lockup for engraving, watermarking, and simple print.
+- `logo-mark-mono.svg`: monochrome standalone symbol.
+- `logo-preview.html`: local preview for background and palette checks.
+- `png/`: exported website-ready PNG versions in 1x and 2x sizes.
+
+## Usage Notes
+
+- Keep the mark small and quiet. It should feel engraved or suspended, not loud.
+- Use the gold dot sparingly; it represents the single pure intention.
+- Prefer spacious layouts and wide tracking around the Chinese slogan.
+- For production typography, use Inter Light or Helvetica Neue Ultra Light for English, and a thin modern Chinese sans such as Source Han Sans SC Light or Noto Sans SC Light.

+ 13 - 0
brand/logo-chinese-dark.svg

@@ -0,0 +1,13 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo on dark background</title>
+  <desc id="desc">The Less and Cosmos symbol with the Chinese brand name 纯粹星辰 on Absolute Void background.</desc>
+  <rect width="960" height="240" fill="#0B0C10"/>
+  <g transform="translate(78 72)">
+    <circle cx="12" cy="36" r="4" fill="#E6C687"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="388" y="122" fill="#F5F5F7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="44" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <text x="392" y="158" fill="#C5C6C7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="15" font-weight="200" letter-spacing="5.4">less and cosmos.</text>
+</svg>

+ 13 - 0
brand/logo-chinese-light-bg.svg

@@ -0,0 +1,13 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo on light background</title>
+  <desc id="desc">The Less and Cosmos symbol with the Chinese brand name on Cosmos White background.</desc>
+  <rect width="960" height="240" fill="#F5F5F7"/>
+  <g transform="translate(78 72)">
+    <circle cx="12" cy="36" r="4" fill="#B89652"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+    <circle cx="268" cy="45" r="1.35" fill="#0B0C10" opacity="0.76"/>
+  </g>
+  <text x="388" y="122" fill="#0B0C10" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="44" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <text x="392" y="158" fill="#59616A" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="15" font-weight="200" letter-spacing="5.4">less and cosmos.</text>
+</svg>

+ 12 - 0
brand/logo-chinese-light.svg

@@ -0,0 +1,12 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo for light background</title>
+  <desc id="desc">The Less and Cosmos symbol with the Chinese brand name tuned for white or light backgrounds.</desc>
+  <g transform="translate(78 72)">
+    <circle cx="12" cy="36" r="4" fill="#B89652"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+    <circle cx="268" cy="45" r="1.35" fill="#0B0C10" opacity="0.76"/>
+  </g>
+  <text x="388" y="122" fill="#0B0C10" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="44" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <text x="392" y="158" fill="#59616A" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="15" font-weight="200" letter-spacing="5.4">less and cosmos.</text>
+</svg>

+ 15 - 0
brand/logo-chinese-slogan-dark.svg

@@ -0,0 +1,15 @@
+<svg width="1120" height="280" viewBox="0 0 1120 280" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo with slogan on dark background</title>
+  <desc id="desc">The Less and Cosmos symbol with Chinese brand name and slogan on Absolute Void background.</desc>
+  <rect width="1120" height="280" fill="#0B0C10"/>
+  <g transform="translate(88 82)">
+    <circle cx="12" cy="36" r="4" fill="#E6C687"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="398" y="125" fill="#F5F5F7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="46" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <line x1="400" y1="150" x2="796" y2="150" stroke="#1F2833" stroke-width="1"/>
+  <text x="404" y="190" fill="#C5C6C7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="20" font-weight="300" letter-spacing="10">一念纯粹,万里星辰。</text>
+  <text x="407" y="222" fill="#C5C6C7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="14" font-weight="200" letter-spacing="4.8" opacity="0.74">less and cosmos.</text>
+</svg>

+ 15 - 0
brand/logo-chinese-slogan-light-bg.svg

@@ -0,0 +1,15 @@
+<svg width="1120" height="280" viewBox="0 0 1120 280" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo with slogan on light background</title>
+  <desc id="desc">The Less and Cosmos symbol with Chinese brand name and slogan on Cosmos White background.</desc>
+  <rect width="1120" height="280" fill="#F5F5F7"/>
+  <g transform="translate(88 82)">
+    <circle cx="12" cy="36" r="4" fill="#B89652"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+    <circle cx="268" cy="45" r="1.35" fill="#0B0C10" opacity="0.76"/>
+  </g>
+  <text x="398" y="125" fill="#0B0C10" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="46" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <line x1="400" y1="150" x2="796" y2="150" stroke="#D8DADF" stroke-width="1"/>
+  <text x="404" y="190" fill="#59616A" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="20" font-weight="300" letter-spacing="10">一念纯粹,万里星辰。</text>
+  <text x="407" y="222" fill="#59616A" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="14" font-weight="200" letter-spacing="4.8" opacity="0.8">less and cosmos.</text>
+</svg>

+ 14 - 0
brand/logo-chinese-slogan-light.svg

@@ -0,0 +1,14 @@
+<svg width="1120" height="280" viewBox="0 0 1120 280" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo with slogan for light background</title>
+  <desc id="desc">The Less and Cosmos symbol with Chinese brand name and slogan tuned for white or light backgrounds.</desc>
+  <g transform="translate(88 82)">
+    <circle cx="12" cy="36" r="4" fill="#B89652"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+    <circle cx="268" cy="45" r="1.35" fill="#0B0C10" opacity="0.76"/>
+  </g>
+  <text x="398" y="125" fill="#0B0C10" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="46" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <line x1="400" y1="150" x2="796" y2="150" stroke="#D8DADF" stroke-width="1"/>
+  <text x="404" y="190" fill="#59616A" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="20" font-weight="300" letter-spacing="10">一念纯粹,万里星辰。</text>
+  <text x="407" y="222" fill="#59616A" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="14" font-weight="200" letter-spacing="4.8" opacity="0.8">less and cosmos.</text>
+</svg>

+ 14 - 0
brand/logo-chinese-slogan.svg

@@ -0,0 +1,14 @@
+<svg width="1120" height="280" viewBox="0 0 1120 280" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo with slogan</title>
+  <desc id="desc">The Less and Cosmos symbol with Chinese brand name and slogan.</desc>
+  <g transform="translate(88 82)">
+    <circle cx="12" cy="36" r="4" fill="#E6C687"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="398" y="125" fill="#F5F5F7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="46" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <line x1="400" y1="150" x2="796" y2="150" stroke="#1F2833" stroke-width="1"/>
+  <text x="404" y="190" fill="#C5C6C7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="20" font-weight="300" letter-spacing="10">一念纯粹,万里星辰。</text>
+  <text x="407" y="222" fill="#C5C6C7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="14" font-weight="200" letter-spacing="4.8" opacity="0.74">less and cosmos.</text>
+</svg>

+ 12 - 0
brand/logo-chinese.svg

@@ -0,0 +1,12 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo</title>
+  <desc id="desc">The Less and Cosmos symbol with the Chinese brand name 纯粹星辰.</desc>
+  <g transform="translate(78 72)">
+    <circle cx="12" cy="36" r="4" fill="#E6C687"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="388" y="122" fill="#F5F5F7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="44" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <text x="392" y="158" fill="#C5C6C7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="15" font-weight="200" letter-spacing="5.4">less and cosmos.</text>
+</svg>

+ 14 - 0
brand/logo-less-and-cosmos-dark.svg

@@ -0,0 +1,14 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos logo on dark background</title>
+  <desc id="desc">The Less and Cosmos full logo lockup on Absolute Void background.</desc>
+  <rect width="960" height="240" fill="#0B0C10"/>
+  <g transform="translate(72 72)">
+    <circle cx="12" cy="36" r="4" fill="#E6C687"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="374" y="105" fill="#F5F5F7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="42" font-weight="200" letter-spacing="5.6">less and cosmos.</text>
+  <text x="379" y="151" fill="#C5C6C7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="300" letter-spacing="9">一念纯粹,万里星辰。</text>
+  <line x1="374" y1="126" x2="840" y2="126" stroke="#1F2833" stroke-width="1"/>
+</svg>

+ 14 - 0
brand/logo-less-and-cosmos-light-bg.svg

@@ -0,0 +1,14 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos logo on light background</title>
+  <desc id="desc">The Less and Cosmos full logo lockup on Cosmos White background.</desc>
+  <rect width="960" height="240" fill="#F5F5F7"/>
+  <g transform="translate(72 72)">
+    <circle cx="12" cy="36" r="4" fill="#B89652"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+    <circle cx="268" cy="45" r="1.35" fill="#0B0C10" opacity="0.76"/>
+  </g>
+  <text x="374" y="105" fill="#0B0C10" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="42" font-weight="200" letter-spacing="5.6">less and cosmos.</text>
+  <text x="379" y="151" fill="#59616A" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="300" letter-spacing="9">一念纯粹,万里星辰。</text>
+  <line x1="374" y1="126" x2="840" y2="126" stroke="#D8DADF" stroke-width="1"/>
+</svg>

+ 13 - 0
brand/logo-less-and-cosmos-light.svg

@@ -0,0 +1,13 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos logo for light background</title>
+  <desc id="desc">The Less and Cosmos full logo lockup tuned for white or light backgrounds.</desc>
+  <g transform="translate(72 72)">
+    <circle cx="12" cy="36" r="4" fill="#B89652"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+    <circle cx="268" cy="45" r="1.35" fill="#0B0C10" opacity="0.76"/>
+  </g>
+  <text x="374" y="105" fill="#0B0C10" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="42" font-weight="200" letter-spacing="5.6">less and cosmos.</text>
+  <text x="379" y="151" fill="#59616A" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="300" letter-spacing="9">一念纯粹,万里星辰。</text>
+  <line x1="374" y1="126" x2="840" y2="126" stroke="#D8DADF" stroke-width="1"/>
+</svg>

+ 13 - 0
brand/logo-less-and-cosmos-mono.svg

@@ -0,0 +1,13 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos monochrome logo</title>
+  <desc id="desc">The Less and Cosmos wordmark with a minimal single-color dot and orbit symbol and Chinese slogan.</desc>
+  <g transform="translate(72 72)">
+    <circle cx="12" cy="36" r="4" fill="#F5F5F7"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#F5F5F7" stroke-width="1.15" stroke-linecap="round" opacity="0.86"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.34"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="374" y="105" fill="#F5F5F7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="42" font-weight="200" letter-spacing="5.6">less and cosmos.</text>
+  <text x="379" y="151" fill="#F5F5F7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="300" letter-spacing="9" opacity="0.72">一念纯粹,万里星辰。</text>
+  <line x1="374" y1="126" x2="840" y2="126" stroke="#F5F5F7" stroke-width="1" opacity="0.12"/>
+</svg>

+ 13 - 0
brand/logo-less-and-cosmos.svg

@@ -0,0 +1,13 @@
+<svg width="960" height="240" viewBox="0 0 960 240" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos logo</title>
+  <desc id="desc">The Less and Cosmos wordmark with a minimal dot and orbit symbol and Chinese slogan.</desc>
+  <g transform="translate(72 72)">
+    <circle cx="12" cy="36" r="4" fill="#E6C687"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="374" y="105" fill="#F5F5F7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="42" font-weight="200" letter-spacing="5.6">less and cosmos.</text>
+  <text x="379" y="151" fill="#C5C6C7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="300" letter-spacing="9">一念纯粹,万里星辰。</text>
+  <line x1="374" y1="126" x2="840" y2="126" stroke="#1F2833" stroke-width="1"/>
+</svg>

+ 9 - 0
brand/logo-mark-dark.svg

@@ -0,0 +1,9 @@
+<svg width="320" height="96" viewBox="0 0 320 96" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos logo mark on dark background</title>
+  <desc id="desc">A minimal spark dot followed by a thin orbital arc on Absolute Void background.</desc>
+  <rect width="320" height="96" fill="#0B0C10"/>
+  <circle cx="46" cy="50" r="4" fill="#E6C687"/>
+  <path d="M72 57C110 25 176 15 238 29C262 35 283 45 300 58" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+  <path d="M100 63C151 45 221 42 280 59" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+  <circle cx="302" cy="59" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+</svg>

+ 9 - 0
brand/logo-mark-light-bg.svg

@@ -0,0 +1,9 @@
+<svg width="320" height="96" viewBox="0 0 320 96" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos mark on light background</title>
+  <desc id="desc">A minimal dot and orbit symbol on Cosmos White background.</desc>
+  <rect width="320" height="96" fill="#F5F5F7"/>
+  <circle cx="46" cy="50" r="4" fill="#B89652"/>
+  <path d="M72 57C110 25 176 15 238 29C262 35 283 45 300 58" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+  <path d="M100 63C151 45 221 42 280 59" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+  <circle cx="302" cy="59" r="1.35" fill="#0B0C10" opacity="0.76"/>
+</svg>

+ 8 - 0
brand/logo-mark-light.svg

@@ -0,0 +1,8 @@
+<svg width="320" height="96" viewBox="0 0 320 96" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos mark for light background</title>
+  <desc id="desc">A minimal dot and orbit symbol tuned for white or light backgrounds.</desc>
+  <circle cx="46" cy="50" r="4" fill="#B89652"/>
+  <path d="M72 57C110 25 176 15 238 29C262 35 283 45 300 58" stroke="#4E5862" stroke-width="1.15" stroke-linecap="round" opacity="0.78"/>
+  <path d="M100 63C151 45 221 42 280 59" stroke="#0B0C10" stroke-width="0.62" stroke-linecap="round" opacity="0.26"/>
+  <circle cx="302" cy="59" r="1.35" fill="#0B0C10" opacity="0.76"/>
+</svg>

+ 8 - 0
brand/logo-mark-mono.svg

@@ -0,0 +1,8 @@
+<svg width="320" height="96" viewBox="0 0 320 96" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos monochrome logo mark</title>
+  <desc id="desc">A minimal single-color dot followed by a thin orbital arc.</desc>
+  <circle cx="46" cy="50" r="4" fill="#F5F5F7"/>
+  <path d="M72 57C110 25 176 15 238 29C262 35 283 45 300 58" stroke="#F5F5F7" stroke-width="1.15" stroke-linecap="round" opacity="0.86"/>
+  <path d="M100 63C151 45 221 42 280 59" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.34"/>
+  <circle cx="302" cy="59" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+</svg>

+ 8 - 0
brand/logo-mark.svg

@@ -0,0 +1,8 @@
+<svg width="320" height="96" viewBox="0 0 320 96" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos logo mark</title>
+  <desc id="desc">A minimal spark dot followed by a thin orbital arc.</desc>
+  <circle cx="46" cy="50" r="4" fill="#E6C687"/>
+  <path d="M72 57C110 25 176 15 238 29C262 35 283 45 300 58" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+  <path d="M100 63C151 45 221 42 280 59" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+  <circle cx="302" cy="59" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+</svg>

+ 472 - 0
brand/logo-preview.html

@@ -0,0 +1,472 @@
+<!doctype html>
+<html lang="zh-CN">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Less and Cosmos Visual Identity</title>
+  <style>
+    :root {
+      --absolute-void: #0B0C10;
+      --muted-nebula: #1F2833;
+      --cosmos-white: #F5F5F7;
+      --mercury-silver: #C5C6C7;
+      --spark-gold: #E6C687;
+      --page-bg: #0B0C10;
+      --page-fg: #F5F5F7;
+      --page-muted: #C5C6C7;
+      --panel-bg: rgba(31, 40, 51, 0.46);
+      --panel-border: rgba(197, 198, 199, 0.16);
+      --meta-border: rgba(197, 198, 199, 0.12);
+      --light-stage: #F5F5F7;
+      --light-grid: rgba(11, 12, 16, 0.07);
+    }
+
+    [data-theme="light"] {
+      --page-bg: #F5F5F7;
+      --page-fg: #0B0C10;
+      --page-muted: #59616A;
+      --panel-bg: #FFFFFF;
+      --panel-border: rgba(31, 40, 51, 0.14);
+      --meta-border: rgba(31, 40, 51, 0.1);
+      --light-stage: #F5F5F7;
+      --light-grid: rgba(31, 40, 51, 0.08);
+    }
+
+    * {
+      box-sizing: border-box;
+    }
+
+    body {
+      margin: 0;
+      min-height: 100vh;
+      color: var(--page-fg);
+      background: var(--page-bg);
+      font-family: Inter, "Helvetica Neue", Helvetica, Arial, "PingFang SC", sans-serif;
+      transition: background 180ms ease, color 180ms ease;
+    }
+
+    main {
+      width: min(1120px, calc(100vw - 48px));
+      margin: 0 auto;
+      padding: 64px 0;
+    }
+
+    .topbar {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      gap: 18px;
+      margin-bottom: 32px;
+    }
+
+    .brand-kicker {
+      margin: 0;
+      color: var(--page-muted);
+      font-size: 12px;
+      letter-spacing: 0.2em;
+      text-transform: uppercase;
+    }
+
+    .theme-toggle {
+      display: inline-grid;
+      grid-template-columns: 1fr 1fr;
+      gap: 3px;
+      padding: 3px;
+      border: 1px solid var(--panel-border);
+      background: var(--panel-bg);
+    }
+
+    .theme-toggle button {
+      min-width: 72px;
+      min-height: 32px;
+      border: 0;
+      color: var(--page-muted);
+      background: transparent;
+      font: inherit;
+      font-size: 12px;
+      letter-spacing: 0.08em;
+      cursor: pointer;
+    }
+
+    .theme-toggle button[aria-pressed="true"] {
+      color: var(--cosmos-white);
+      background: var(--absolute-void);
+    }
+
+    [data-theme="dark"] .theme-toggle button[aria-pressed="true"] {
+      color: var(--absolute-void);
+      background: var(--cosmos-white);
+    }
+
+    .preview {
+      display: grid;
+      gap: 28px;
+    }
+
+    .section-title {
+      margin: 56px 0 18px;
+      color: var(--page-muted);
+      font-size: 13px;
+      font-weight: 400;
+      letter-spacing: 0.18em;
+      text-transform: uppercase;
+    }
+
+    .surface {
+      min-height: 260px;
+      display: grid;
+      place-items: center;
+      border: 1px solid var(--panel-border);
+      background: var(--absolute-void);
+    }
+
+    .surface.nebula {
+      background: var(--muted-nebula);
+    }
+
+    .surface.compact {
+      min-height: 180px;
+    }
+
+    .png-grid {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 18px;
+    }
+
+    .png-card {
+      border: 1px solid var(--panel-border);
+      background: var(--panel-bg);
+    }
+
+    .png-stage {
+      min-height: 190px;
+      display: grid;
+      place-items: center;
+      padding: 28px;
+      background: var(--absolute-void);
+    }
+
+    .png-stage.nebula {
+      background: var(--muted-nebula);
+    }
+
+    .png-stage.checker {
+      background-color: var(--absolute-void);
+      background-image:
+        linear-gradient(45deg, rgba(197, 198, 199, 0.08) 25%, transparent 25%),
+        linear-gradient(-45deg, rgba(197, 198, 199, 0.08) 25%, transparent 25%),
+        linear-gradient(45deg, transparent 75%, rgba(197, 198, 199, 0.08) 75%),
+        linear-gradient(-45deg, transparent 75%, rgba(197, 198, 199, 0.08) 75%);
+      background-position: 0 0, 0 10px, 10px -10px, -10px 0;
+      background-size: 20px 20px;
+    }
+
+    [data-theme="light"] .png-stage.checker {
+      background-color: var(--absolute-void);
+    }
+
+    .png-stage.light-checker {
+      background-color: var(--light-stage);
+      background-image:
+        linear-gradient(45deg, var(--light-grid) 25%, transparent 25%),
+        linear-gradient(-45deg, var(--light-grid) 25%, transparent 25%),
+        linear-gradient(45deg, transparent 75%, var(--light-grid) 75%),
+        linear-gradient(-45deg, transparent 75%, var(--light-grid) 75%);
+      background-position: 0 0, 0 10px, 10px -10px, -10px 0;
+      background-size: 20px 20px;
+    }
+
+    .light-mode-ink {
+      filter: brightness(0) saturate(100%) invert(4%) sepia(11%) saturate(1045%) hue-rotate(176deg) brightness(94%) contrast(95%);
+    }
+
+    .png-meta {
+      min-height: 46px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      flex-wrap: wrap;
+      gap: 12px;
+      padding: 12px 14px;
+      border-top: 1px solid var(--meta-border);
+      color: var(--page-muted);
+      font-size: 12px;
+      letter-spacing: 0.04em;
+    }
+
+    .png-meta span {
+      overflow-wrap: anywhere;
+      text-align: right;
+    }
+
+    .png-meta strong {
+      color: var(--page-fg);
+      font-size: 12px;
+      font-weight: 400;
+      letter-spacing: 0.08em;
+    }
+
+    img {
+      display: block;
+      max-width: min(86vw, 820px);
+      height: auto;
+    }
+
+    .mark {
+      max-width: 360px;
+    }
+
+    .png-card img {
+      width: min(100%, 560px);
+      max-height: 180px;
+      object-fit: contain;
+    }
+
+    .png-card .mark-png {
+      max-width: 320px;
+    }
+
+    .palette {
+      display: grid;
+      grid-template-columns: repeat(5, minmax(120px, 1fr));
+      gap: 12px;
+      margin-top: 28px;
+    }
+
+    .swatch {
+      min-height: 112px;
+      padding: 14px;
+      border: 1px solid rgba(197, 198, 199, 0.14);
+      display: flex;
+      flex-direction: column;
+      justify-content: flex-end;
+      gap: 5px;
+      color: var(--cosmos-white);
+      font-size: 12px;
+      letter-spacing: 0.08em;
+    }
+
+    .swatch strong {
+      font-size: 13px;
+      font-weight: 400;
+      letter-spacing: 0.1em;
+    }
+
+    .void { background: var(--absolute-void); }
+    .nebula-color { background: var(--muted-nebula); }
+    .white { background: var(--cosmos-white); color: var(--absolute-void); }
+    .silver { background: var(--mercury-silver); color: var(--absolute-void); }
+    .gold { background: var(--spark-gold); color: var(--absolute-void); }
+
+    @media (max-width: 760px) {
+      main {
+        width: min(100vw - 28px, 560px);
+        padding: 32px 0;
+      }
+
+      .surface {
+        min-height: 190px;
+      }
+
+      .palette {
+        grid-template-columns: 1fr;
+      }
+
+      .png-grid {
+        grid-template-columns: 1fr;
+      }
+
+      .png-stage {
+        min-height: 150px;
+        padding: 18px;
+      }
+
+      .topbar {
+        align-items: flex-start;
+        flex-direction: column;
+      }
+    }
+  </style>
+</head>
+<body data-theme="dark">
+  <main>
+    <header class="topbar">
+      <p class="brand-kicker">Less and Cosmos Visual Identity</p>
+      <div class="theme-toggle" aria-label="Theme switcher">
+        <button type="button" data-theme-value="light" aria-pressed="false">Light</button>
+        <button type="button" data-theme-value="dark" aria-pressed="true">Dark</button>
+      </div>
+    </header>
+
+    <h2 class="section-title">SVG master</h2>
+    <section class="preview" aria-label="Less and Cosmos logo preview">
+      <div class="surface">
+        <img src="./logo-less-and-cosmos.svg" alt="less and cosmos. 一念纯粹,万里星辰。">
+      </div>
+      <div class="surface nebula">
+        <img src="./logo-less-and-cosmos.svg" alt="less and cosmos. 一念纯粹,万里星辰。">
+      </div>
+      <div class="surface compact">
+        <img class="mark" src="./logo-mark.svg" alt="Less and Cosmos symbol">
+      </div>
+      <div class="surface nebula compact">
+        <img class="mark" src="./logo-mark-mono.svg" alt="Less and Cosmos monochrome symbol">
+      </div>
+    </section>
+
+    <h2 class="section-title">PNG exports</h2>
+    <section class="png-grid" aria-label="Website PNG logo exports">
+      <article class="png-card">
+        <div class="png-stage checker">
+          <img src="./png/logo-full-transparent-2x.png" alt="less and cosmos. transparent PNG">
+        </div>
+        <div class="png-meta"><strong>英文完整透明底</strong><span>logo-full-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage">
+          <img src="./png/logo-full-dark-2x.png" alt="less and cosmos. dark PNG">
+        </div>
+        <div class="png-meta"><strong>英文完整深色底</strong><span>logo-full-dark-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage checker">
+          <img class="mark-png" src="./png/logo-mark-transparent-2x.png" alt="Less and Cosmos mark transparent PNG">
+        </div>
+        <div class="png-meta"><strong>图腾透明底</strong><span>logo-mark-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage">
+          <img class="mark-png" src="./png/logo-mark-dark-2x.png" alt="Less and Cosmos mark dark PNG">
+        </div>
+        <div class="png-meta"><strong>图腾深色底</strong><span>logo-mark-dark-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage checker">
+          <img src="./png/logo-chinese-transparent-2x.png" alt="纯粹星辰 transparent PNG">
+        </div>
+        <div class="png-meta"><strong>中文品牌透明底</strong><span>logo-chinese-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage">
+          <img src="./png/logo-chinese-dark-2x.png" alt="纯粹星辰 dark PNG">
+        </div>
+        <div class="png-meta"><strong>中文品牌深色底</strong><span>logo-chinese-dark-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage checker">
+          <img src="./png/logo-chinese-slogan-transparent-2x.png" alt="纯粹星辰 with slogan transparent PNG">
+        </div>
+        <div class="png-meta"><strong>中文加 Slogan 透明底</strong><span>logo-chinese-slogan-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage">
+          <img src="./png/logo-chinese-slogan-dark-2x.png" alt="纯粹星辰 with slogan dark PNG">
+        </div>
+        <div class="png-meta"><strong>中文加 Slogan 深色底</strong><span>logo-chinese-slogan-dark-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img src="./png/logo-full-light-transparent-2x.png" alt="less and cosmos. light transparent PNG">
+        </div>
+        <div class="png-meta"><strong>英文完整白底透明版</strong><span>logo-full-light-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img src="./png/logo-full-light-bg-2x.png" alt="less and cosmos. light background PNG">
+        </div>
+        <div class="png-meta"><strong>英文完整自带白底</strong><span>logo-full-light-bg-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img class="mark-png" src="./png/logo-mark-light-transparent-2x.png" alt="Less and Cosmos mark light transparent PNG">
+        </div>
+        <div class="png-meta"><strong>图腾白底透明版</strong><span>logo-mark-light-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img class="mark-png" src="./png/logo-mark-light-bg-2x.png" alt="Less and Cosmos mark light background PNG">
+        </div>
+        <div class="png-meta"><strong>图腾自带白底</strong><span>logo-mark-light-bg-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img src="./png/logo-chinese-light-transparent-2x.png" alt="纯粹星辰 light transparent PNG">
+        </div>
+        <div class="png-meta"><strong>中文品牌白底透明版</strong><span>logo-chinese-light-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img src="./png/logo-chinese-light-bg-2x.png" alt="纯粹星辰 light background PNG">
+        </div>
+        <div class="png-meta"><strong>中文品牌自带白底</strong><span>logo-chinese-light-bg-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img src="./png/logo-chinese-slogan-light-transparent-2x.png" alt="纯粹星辰 with slogan light transparent PNG">
+        </div>
+        <div class="png-meta"><strong>中文加 Slogan 白底透明版</strong><span>logo-chinese-slogan-light-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img src="./png/logo-chinese-slogan-light-bg-2x.png" alt="纯粹星辰 with slogan light background PNG">
+        </div>
+        <div class="png-meta"><strong>中文加 Slogan 自带白底</strong><span>logo-chinese-slogan-light-bg-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img class="light-mode-ink" src="./png/logo-full-mono-transparent-2x.png" alt="less and cosmos. monochrome transparent PNG">
+        </div>
+        <div class="png-meta"><strong>英文单色浅底预览</strong><span>logo-full-mono-transparent-2x.png</span></div>
+      </article>
+
+      <article class="png-card">
+        <div class="png-stage light-checker">
+          <img class="mark-png light-mode-ink" src="./png/logo-mark-mono-transparent-2x.png" alt="Less and Cosmos mark monochrome transparent PNG">
+        </div>
+        <div class="png-meta"><strong>图腾单色浅底预览</strong><span>logo-mark-mono-transparent-2x.png</span></div>
+      </article>
+    </section>
+
+    <h2 class="section-title">Color system</h2>
+    <section class="palette" aria-label="Cosmic Morandi color palette">
+      <div class="swatch void"><strong>纯粹之境</strong><span>#0B0C10</span></div>
+      <div class="swatch nebula-color"><strong>寂静星云</strong><span>#1F2833</span></div>
+      <div class="swatch white"><strong>星光极白</strong><span>#F5F5F7</span></div>
+      <div class="swatch silver"><strong>智慧水星</strong><span>#C5C6C7</span></div>
+      <div class="swatch gold"><strong>一念微光</strong><span>#E6C687</span></div>
+    </section>
+  </main>
+  <script>
+    const root = document.body;
+    const buttons = Array.from(document.querySelectorAll("[data-theme-value]"));
+
+    function setTheme(theme) {
+      root.dataset.theme = theme;
+      buttons.forEach((button) => {
+        button.setAttribute("aria-pressed", String(button.dataset.themeValue === theme));
+      });
+    }
+
+    buttons.forEach((button) => {
+      button.addEventListener("click", () => setTheme(button.dataset.themeValue));
+    });
+  </script>
+</body>
+</html>

+ 32 - 0
brand/png/README.md

@@ -0,0 +1,32 @@
+# PNG Logo Exports
+
+All PNG files are exported from the SVG sources in `brand/`.
+
+## Recommended Website Use
+
+- `logo-full-transparent-2x.png`: default website header logo on dark or custom backgrounds.
+- `logo-full-dark-2x.png`: ready-to-use dark-background image block.
+- `logo-mark-transparent-2x.png`: favicon-style mark, app header mark, social avatar base.
+- `logo-mark-dark-2x.png`: mark with Absolute Void background.
+- `logo-chinese-transparent-2x.png`: mark with `纯粹星辰`.
+- `logo-chinese-dark-2x.png`: mark with `纯粹星辰` on dark background.
+- `logo-chinese-slogan-transparent-2x.png`: mark with `纯粹星辰` and `一念纯粹,万里星辰。`.
+- `logo-chinese-slogan-dark-2x.png`: slogan lockup on dark background.
+- `logo-full-light-transparent-2x.png`: English lockup for white or light website backgrounds.
+- `logo-full-light-bg-2x.png`: English lockup with built-in Cosmos White background.
+- `logo-mark-light-transparent-2x.png`: standalone mark for white or light website backgrounds.
+- `logo-mark-light-bg-2x.png`: standalone mark with built-in Cosmos White background.
+- `logo-chinese-light-transparent-2x.png`: `纯粹星辰` lockup for white or light backgrounds.
+- `logo-chinese-light-bg-2x.png`: `纯粹星辰` lockup with built-in Cosmos White background.
+- `logo-chinese-slogan-light-transparent-2x.png`: Chinese name and slogan for white or light backgrounds.
+- `logo-chinese-slogan-light-bg-2x.png`: Chinese name and slogan with built-in Cosmos White background.
+
+## File Naming
+
+- `transparent`: transparent background.
+- `dark`: Absolute Void `#0B0C10` background.
+- `light`: ink and orbit colors tuned for white or light backgrounds.
+- `light-bg`: built-in Cosmos White `#F5F5F7` background.
+- `mono`: one-color version for engraving, watermarking, simple print, and restrained UI use.
+- `1x`: standard pixel density.
+- `2x`: high-density display use.

BIN
brand/png/logo-chinese-dark-1x.png


BIN
brand/png/logo-chinese-dark-2x.png


BIN
brand/png/logo-chinese-light-bg-1x.png


BIN
brand/png/logo-chinese-light-bg-2x.png


BIN
brand/png/logo-chinese-light-transparent-1x.png


BIN
brand/png/logo-chinese-light-transparent-2x.png


BIN
brand/png/logo-chinese-slogan-dark-1x.png


BIN
brand/png/logo-chinese-slogan-dark-2x.png


BIN
brand/png/logo-chinese-slogan-light-bg-1x.png


BIN
brand/png/logo-chinese-slogan-light-bg-2x.png


BIN
brand/png/logo-chinese-slogan-light-transparent-1x.png


BIN
brand/png/logo-chinese-slogan-light-transparent-2x.png


BIN
brand/png/logo-chinese-slogan-transparent-1x.png


BIN
brand/png/logo-chinese-slogan-transparent-2x.png


BIN
brand/png/logo-chinese-transparent-1x.png


BIN
brand/png/logo-chinese-transparent-2x.png


BIN
brand/png/logo-full-dark-1x.png


BIN
brand/png/logo-full-dark-2x.png


BIN
brand/png/logo-full-light-bg-1x.png


BIN
brand/png/logo-full-light-bg-2x.png


BIN
brand/png/logo-full-light-transparent-1x.png


BIN
brand/png/logo-full-light-transparent-2x.png


BIN
brand/png/logo-full-mono-transparent-1x.png


BIN
brand/png/logo-full-mono-transparent-2x.png


BIN
brand/png/logo-full-transparent-1x.png


BIN
brand/png/logo-full-transparent-2x.png


BIN
brand/png/logo-mark-dark-1x.png


BIN
brand/png/logo-mark-dark-2x.png


BIN
brand/png/logo-mark-light-bg-1x.png


BIN
brand/png/logo-mark-light-bg-2x.png


BIN
brand/png/logo-mark-light-transparent-1x.png


BIN
brand/png/logo-mark-light-transparent-2x.png


BIN
brand/png/logo-mark-mono-transparent-1x.png


BIN
brand/png/logo-mark-mono-transparent-2x.png


BIN
brand/png/logo-mark-transparent-1x.png


BIN
brand/png/logo-mark-transparent-2x.png


+ 19 - 0
case-timeline/.gitignore

@@ -0,0 +1,19 @@
+# macOS and editor files
+.DS_Store
+.idea/
+.vscode/
+*.swp
+*.swo
+
+# Local dependencies and build output (if tooling is added later)
+node_modules/
+dist/
+build/
+.cache/
+
+# Logs and temporary files
+*.log
+*.tmp
+*.temp
+*~
+

+ 34 - 0
case-timeline/README.md

@@ -0,0 +1,34 @@
+# 商业案例时间线
+
+这是一个独立的静态网页,不需要安装依赖。
+
+## 预览
+
+直接打开 `index.html`,或用任意静态网页服务打开本文件夹。
+
+## 页面编辑与主题
+
+- 点击右上角“编辑”,即可直接修改标题、核心数字、时间线、参与方和思维模型文字。
+- 修改内容会自动保存在当前浏览器,无需手动保存。
+- 编辑模式中的“恢复原稿”可清除本机修改。
+- 点击右上角“Light / Dark”可切换明暗主题,选择会自动记忆。
+
+## 更换案例
+
+1. 复制整个 `case-timeline` 文件夹并重命名。
+2. 编辑 `case-data.js` 中的 `window.CASE_DATA`。
+3. `metrics` 是首屏四个核心数字。
+4. `categories` 是阅读视角筛选器。
+5. `chapters` 是左侧章节导航。
+6. `events` 是时间线事件;`featured: true` 会突出关键转折。
+7. `model` 是结尾的三维思维模型。
+
+事件分类默认支持:
+
+- `market`:市场格局
+- `operation`:物理微观
+- `capital`:资本宏观
+- `policy`:政治主权
+- `evolution`:企业进化
+
+如需新增或改名分类,同时修改 `case-data.js` 的 `categories` 和 `styles.css` 中相应的颜色规则即可。

+ 203 - 0
case-timeline/app.js

@@ -0,0 +1,203 @@
+(function () {
+  const data = window.CASE_DATA;
+  const timeline = document.querySelector("#timeline");
+  const filters = document.querySelector("#filters");
+  let activeFilter = "all";
+  let timelineView = "compact";
+  let editing = false;
+  const editStoreKey = "saigon-leverage-edits-v1";
+  const themeStoreKey = "saigon-leverage-theme";
+
+  document.querySelector("#episodeLabel").textContent = `CASE TIMELINE · ${data.episode}`;
+  document.querySelector("#heroEyebrow").textContent = data.eyebrow;
+  document.querySelector("#caseTitle").innerHTML = `${data.title.split(":")[0]}:<br><span>${data.title.split(":").slice(1).join(":")}</span>`;
+  document.querySelector("#heroDeck").textContent = data.deck;
+  document.querySelector("#heroDeck").dataset.edit = "hero-deck";
+
+  document.querySelector("#heroMetrics").innerHTML = data.metrics.map((metric) => `
+    <div class="metric"><strong data-edit="metric-${metric.label}-value">${metric.value}</strong><span data-edit="metric-${metric.label}-label">${metric.label}</span></div>
+  `).join("");
+
+  document.querySelector("#participantsGrid").innerHTML = data.participants.map((party) => `
+    <article class="participant-card">
+      <div class="participant-title"><span aria-hidden="true">${party.mark}</span><div><h3 data-edit="party-${party.mark}-name">${party.name}</h3><p data-edit="party-${party.mark}-role">${party.role}</p></div></div>
+      <p data-edit="party-${party.mark}-stance">${party.stance}</p>
+      <strong data-edit="party-${party.mark}-asset">${party.asset}</strong>
+    </article>
+  `).join("");
+
+  function applyTimelineView() {
+    timeline.classList.toggle("compact", timelineView === "compact");
+    document.querySelectorAll("[data-view]").forEach((button) => {
+      const active = button.dataset.view === timelineView;
+      button.classList.toggle("active", active);
+      button.setAttribute("aria-pressed", String(active));
+    });
+  }
+
+  function renderFilters() {
+    filters.innerHTML = data.categories.map((item) => `
+      <button type="button" class="filter ${item.id === activeFilter ? "active" : ""}" data-filter="${item.id}">
+        <i aria-hidden="true"></i>${item.label}
+      </button>
+    `).join("");
+  }
+
+  function renderTimeline() {
+    const visible = activeFilter === "all" ? data.events : data.events.filter((event) => event.category === activeFilter);
+    timeline.innerHTML = visible.map((event, position) => `
+      <article class="event ${event.featured ? "featured" : ""}" id="${event.id}" data-category="${event.category}" style="--delay:${position * 35}ms">
+        <div class="event-date"><span data-edit="event-${event.id}-date">${event.date}</span><small>${event.index}</small></div>
+        <button class="event-card" type="button" aria-expanded="false" aria-controls="detail-${event.id}">
+          <div class="event-card-top"><span class="tag">${categoryLabel(event.category)}</span><span class="expand-icon" aria-hidden="true">+</span></div>
+          <h3 data-edit="event-${event.id}-title">${event.title}</h3>
+          <p data-edit="event-${event.id}-summary">${event.summary}</p>
+          <strong class="event-stat" data-edit="event-${event.id}-stat">${event.stat}</strong>
+          <div class="event-detail" id="detail-${event.id}">
+            <div><span>商业含义</span><p data-edit="event-${event.id}-detail">${event.detail}</p></div>
+            <div><span>关键影响</span><p data-edit="event-${event.id}-impact">${event.impact}</p></div>
+          </div>
+        </button>
+      </article>
+    `).join("");
+    bindCards();
+    applyTimelineView();
+    restoreEdits();
+    if (editing) setEditing(true);
+  }
+
+  function categoryLabel(id) {
+    return data.categories.find((item) => item.id === id)?.label || id;
+  }
+
+  function bindCards() {
+    document.querySelectorAll(".event-card").forEach((card) => {
+      card.addEventListener("click", () => {
+        if (editing) return;
+        const expanded = card.getAttribute("aria-expanded") === "true";
+        card.setAttribute("aria-expanded", String(!expanded));
+        card.closest(".event").classList.toggle("open", !expanded);
+      });
+    });
+  }
+
+  filters.addEventListener("click", (event) => {
+    const button = event.target.closest("[data-filter]");
+    if (!button) return;
+    activeFilter = button.dataset.filter;
+    renderFilters();
+    renderTimeline();
+  });
+
+  document.querySelector(".view-switch").addEventListener("click", (event) => {
+    const button = event.target.closest("[data-view]");
+    if (!button) return;
+    timelineView = button.dataset.view;
+    applyTimelineView();
+  });
+
+  document.querySelector("#chapterNav").innerHTML = data.chapters.map((chapter) => {
+    const target = data.events.find((event) => event.chapter === chapter.id)?.id;
+    return `<a href="#${target}"><span>${chapter.label.slice(0, 2)}</span>${chapter.label.slice(3)}</a>`;
+  }).join("");
+
+  document.querySelector("#modelGrid").innerHTML = data.model.map((item) => `
+    <article class="model-card ${item.category}"><span>${item.num}</span><h3 data-edit="model-${item.num}-title">${item.title}</h3><strong data-edit="model-${item.num}-subtitle">${item.subtitle}</strong><p data-edit="model-${item.num}-body">${item.body}</p></article>
+  `).join("");
+
+  function storedEdits() {
+    try { return JSON.parse(localStorage.getItem(editStoreKey)) || {}; } catch (_) { return {}; }
+  }
+
+  function restoreEdits() {
+    const saved = storedEdits();
+    document.querySelectorAll("[data-edit]").forEach((element) => {
+      if (saved[element.dataset.edit] !== undefined) element.innerHTML = saved[element.dataset.edit];
+    });
+  }
+
+  function saveEdit(element) {
+    const saved = storedEdits();
+    saved[element.dataset.edit] = element.innerHTML;
+    localStorage.setItem(editStoreKey, JSON.stringify(saved));
+  }
+
+  function setEditing(next) {
+    editing = next;
+    document.body.classList.toggle("is-editing", editing);
+    const editButton = document.querySelector("#editToggle");
+    editButton.querySelector(".icon-glyph").textContent = editing ? "✓" : "✎";
+    editButton.setAttribute("aria-label", editing ? "完成编辑" : "编辑页面内容");
+    editButton.title = editing ? "完成编辑" : "编辑页面内容";
+    document.querySelectorAll("[data-edit]").forEach((element) => {
+      element.contentEditable = editing ? "true" : "false";
+      element.spellcheck = editing;
+    });
+  }
+
+  document.addEventListener("input", (event) => {
+    const editable = event.target.closest("[data-edit]");
+    if (editing && editable) saveEdit(editable);
+  });
+
+  document.querySelector("#editToggle").addEventListener("click", () => setEditing(!editing));
+  document.querySelector("#resetEdits").addEventListener("click", () => {
+    if (!confirm("确定恢复全部原稿吗?当前编辑内容将被清除。")) return;
+    localStorage.removeItem(editStoreKey);
+    location.reload();
+  });
+
+  function setTheme(theme) {
+    document.documentElement.dataset.theme = theme;
+    const themeButton = document.querySelector("#themeToggle");
+    const nextTheme = theme === "dark" ? "浅色" : "深色";
+    themeButton.querySelector(".icon-glyph").textContent = theme === "dark" ? "☼" : "☾";
+    themeButton.setAttribute("aria-label", `切换至${nextTheme}模式`);
+    themeButton.title = `切换至${nextTheme}模式`;
+    document.querySelectorAll("img[data-dark-src]").forEach((image) => {
+      image.src = theme === "dark" ? image.dataset.darkSrc : image.dataset.lightSrc;
+    });
+    localStorage.setItem(themeStoreKey, theme);
+  }
+
+  document.querySelector("#themeToggle").addEventListener("click", () => {
+    setTheme(document.documentElement.dataset.theme === "dark" ? "light" : "dark");
+  });
+
+  document.querySelector("#copyLink").addEventListener("click", async (event) => {
+    const button = event.currentTarget;
+    try {
+      await navigator.clipboard.writeText(location.href);
+      button.classList.add("is-copied");
+      button.querySelector(".icon-glyph").textContent = "✓";
+      button.setAttribute("aria-label", "链接已复制");
+      button.title = "链接已复制";
+      setTimeout(() => {
+        button.classList.remove("is-copied");
+        button.querySelector(".icon-glyph").textContent = "⤴";
+        button.setAttribute("aria-label", "复制当前页面链接");
+        button.title = "复制当前页面链接";
+      }, 1600);
+    } catch (_) {
+      button.querySelector(".icon-glyph").textContent = "!";
+      button.setAttribute("aria-label", "复制失败");
+      button.title = "复制失败";
+    }
+  });
+
+  function updateProgress() {
+    const story = document.querySelector("#story");
+    const start = story.offsetTop;
+    const distance = Math.max(story.offsetHeight - innerHeight, 1);
+    const percent = Math.max(0, Math.min(100, ((scrollY - start) / distance) * 100));
+    document.querySelector("#progressBar").style.width = `${percent}%`;
+    document.querySelector("#progressText").textContent = `${Math.round(percent)}%`;
+  }
+
+  addEventListener("scroll", updateProgress, { passive: true });
+  renderFilters();
+  renderTimeline();
+  restoreEdits();
+  setTheme(localStorage.getItem(themeStoreKey) || "dark");
+  updateProgress();
+})();

+ 174 - 0
case-timeline/case-data.js

@@ -0,0 +1,174 @@
+/*
+ * 新案例只需复制本文件并替换 window.CASE_DATA。
+ * category 可用值:market / operation / capital / policy / evolution
+ */
+window.CASE_DATA = {
+  episode: "EP.01",
+  eyebrow: "一场用债务撬动国家级资产的资本豪赌",
+  title: "西贡杠杆:一场用债务撬动国家级资产的豪赌",
+  deck: "48 亿美元,几乎全部来自银行借款;一笔企业收购,让越南短期外债激增 73%。七年后账面价值暴跌 72%,但十万个销售终端仍在源源不断地产生现金流。真正被撬动的,究竟是一家公司,还是一个国家的规则?",
+  metrics: [
+    { value: "US$ 48 亿", label: "收购价格" },
+    { value: "−72%", label: "七年账面跌幅" },
+    { value: "10 万家", label: "末端销售网点" },
+    { value: "90%", label: "2031 年目标税率" }
+  ],
+  participants: [
+    {
+      mark: "S", name: "西贡啤酒", role: "被收购方 · 越南国民品牌",
+      stance: "守住大众市场,同时完成高端化与无酒精转型。",
+      asset: "10 万个末端网点 · 145 年品牌心智"
+    },
+    {
+      mark: "T", name: "ThaiBev", role: "收购方 · 泰国酒业集团",
+      stance: "突破泰国增长天花板,把越南变成东盟扩张入口。",
+      asset: "资本杠杆 · 管理与供应链改造"
+    },
+    {
+      mark: "H", name: "喜力", role: "竞争方 · 高端市场霸主",
+      stance: "守住城市高端渠道,并向大众市场下沉。",
+      asset: "高端品牌力 · 夜店与酒店渠道"
+    },
+    {
+      mark: "V", name: "越南政府", role: "规则制定方 · 主权力量",
+      stance: "控制外债与酒精消费风险,重新分配行业利润。",
+      asset: "监管权 · 税收权 · 市场准入"
+    },
+    {
+      mark: "B", name: "跨国银行", role: "资金提供方 · 债权人",
+      stance: "为收购提供杠杆,并要求稳定现金流覆盖债务。",
+      asset: "48 亿美元融资 · 债权约束"
+    },
+    {
+      mark: "C", name: "越南消费者", role: "需求方 · 最终裁判",
+      stance: "在价格、场景和国民品牌情感之间做选择。",
+      asset: "消费习惯 · 价格接受度"
+    }
+  ],
+  categories: [
+    { id: "all", label: "全部事件" },
+    { id: "market", label: "市场格局" },
+    { id: "operation", label: "物理微观" },
+    { id: "capital", label: "资本宏观" },
+    { id: "policy", label: "政治主权" },
+    { id: "evolution", label: "企业进化" }
+  ],
+  chapters: [
+    { id: "stage", label: "01 双雄格局" },
+    { id: "buyout", label: "02 豪赌入场" },
+    { id: "surgery", label: "03 刮骨疗毒" },
+    { id: "shock", label: "04 政策反噬" },
+    { id: "future", label: "05 生死进化" }
+  ],
+  events: [
+    {
+      id: "market-map", chapter: "stage", date: "收购前", category: "market", index: "01",
+      title: "越南啤酒的“空中堡垒”与“地面长城”",
+      summary: "喜力控制大城市高档场景;西贡啤酒扎进 10 万家路边摊与杂货铺。",
+      detail: "喜力卖的是中产阶级的面子与情调,西贡啤酒卖的是三元一瓶的日常刚需。两套渠道、两种价格、两种消费身份,构成了一场长期的立体竞争。",
+      impact: "渠道结构决定了双方后来面对政策冲击时完全不同的命运。",
+      stat: "85% 高档场景 vs. 10 万末端网点"
+    },
+    {
+      id: "thai-ceiling", chapter: "buyout", date: "2017—2018", category: "capital", index: "02",
+      title: "ThaiBev 撞上泰国市场天花板",
+      summary: "本土份额见顶,向东盟扩张成为唯一出口,越南则是最重要的闸门。",
+      detail: "对 ThaiBev 而言,收购不是简单买品牌,而是一次地理增长权的购买。西贡啤酒覆盖全国的末端网络,是无法用短期营销预算复制的稀缺资产。",
+      impact: "收购逻辑从“买啤酒厂”升级为“买进入越南消费市场的基础设施”。",
+      stat: "复制网络至少需要 10 年"
+    },
+    {
+      id: "deal", chapter: "buyout", date: "2018", category: "capital", index: "03", featured: true,
+      title: "48 亿美元强行买下国民啤酒",
+      summary: "一场轰动亚洲金融圈的跨国“蛇吞象”,也把百年品牌推上资本赌桌。",
+      detail: "ThaiBev 通过越南本地公司完成收购:泰国银行贷款 30.5 亿美元,国际银团贷款 19.5 亿美元。资本来源在境外,债务风险却落入越南统计口径。",
+      impact: "越南短期国家外债因此激增 73%,企业交易上升为国家金融安全问题。",
+      stat: "30.5 亿 + 19.5 亿美元贷款"
+    },
+    {
+      id: "value-drop", chapter: "buyout", date: "2018—2025", category: "capital", index: "04",
+      title: "账面价值七年缩水 72%",
+      summary: "资本市场给出残酷判决:300 多亿人民币进场,最后只剩一个零头。",
+      detail: "但账面价格只描述了筹码此刻值多少钱,并不能解释买方究竟获得了什么。真正的资产,是十万个无法快速复制的销售触点,以及由此形成的消费习惯。",
+      impact: "“浮亏”与“战略价值”出现巨大背离,案例的核心矛盾由此形成。",
+      stat: "−72%"
+    },
+    {
+      id: "logistics", chapter: "surgery", date: "整合期 · 第一刀", category: "operation", index: "05",
+      title: "砍物流:切除臃肿分销网络",
+      summary: "关闭低效仓库,用智能系统重新规划配送路线。",
+      detail: "国企时代的西贡啤酒拥有强大渠道,却被低效仓储和分销层级堵住经络。第一刀先处理物流浪费,让规模真正转化为现金。",
+      impact: "每年节省约 1.2 万亿越南盾,相当于每天增加近百万元人民币。",
+      stat: "年省 1.2 万亿越南盾"
+    },
+    {
+      id: "can-factory", chapter: "surgery", date: "整合期 · 第二刀", category: "operation", index: "06",
+      title: "建厂自给:摆脱铝罐价格卡脖子",
+      summary: "自建易拉罐产能,把包装材料自给率推至 80% 以上。",
+      detail: "低价啤酒利润薄如刀片,任何原材料波动都会吞噬收益。向上游延伸,让企业获得成本控制权,也降低国际商品价格的传导风险。",
+      impact: "供应链从被动采购转为可控生产,再省下数千亿越南盾。",
+      stat: "自给率 > 80%"
+    },
+    {
+      id: "inventory", chapter: "surgery", date: "整合期 · 第三刀", category: "operation", index: "07",
+      title: "数字化库存:让啤酒快转 15 天",
+      summary: "智能仓储压缩库存周期,把沉睡在仓库里的资金释放出来。",
+      detail: "对快消品而言,周转速度就是现金流速度。数字化不是展示技术感,而是让十万个毛细血管更快、更准确地供血。",
+      impact: "运营效率成为抵抗低毛利和未来税负的第一道防线。",
+      stat: "库存周转加快 15 天"
+    },
+    {
+      id: "drink-driving", chapter: "shock", date: "2019", category: "policy", index: "08", featured: true,
+      title: "酒驾“零容忍”法令劈下惊雷",
+      summary: "高档餐厅和夜店销量被腰斩,渠道优势第一次发生逆转。",
+      detail: "喜力的高空堡垒首当其冲,而西贡啤酒的路边摊与社区杂货铺反而成了避风港:消费者从堂饮转向买回家喝。",
+      impact: "政策没有平均地打击市场,而是重写了不同渠道的价值。",
+      stat: "高档场景销量跌逾 50%"
+    },
+    {
+      id: "channel-war", chapter: "shock", date: "2020—2026", category: "market", index: "09",
+      title: "两座堡垒开始相向进攻",
+      summary: "喜力以便宜货向下俯冲,西贡则带着高端新品向上突围。",
+      detail: "渠道可以下沉,品牌认知却很难一夜改变。喜力短期建不起十万个地摊,西贡也无法立刻洗掉“地摊货”的刻板印象。",
+      impact: "双方进入谁也无法快速终结对手的持久战。",
+      stat: "高端 vs. 大众的双向渗透"
+    },
+    {
+      id: "tax-rise", chapter: "future", date: "2027—2031", category: "policy", index: "10", featured: true,
+      title: "特别消费税走向 90% 灰犀牛",
+      summary: "计划自 2027 年起每年提高 5 个百分点,直到 2031 年触及 90%。",
+      detail: "这不只是成本变量,更是主权对利润重分配规则的重新掌控。企业必须在内部消化税负与向消费者转嫁价格之间做残酷选择。",
+      impact: "内部消化可能压缩至少 10 个百分点毛利;提价则要赌大众消费者不会离场。",
+      stat: "+5pct / 年 → 90%"
+    },
+    {
+      id: "cash-shield", chapter: "future", date: "风暴前夜", category: "evolution", index: "11",
+      title: "20 万亿越南盾筑起现金防空洞",
+      summary: "现金占总资产 64%,既是税收风暴缓冲垫,也是债权人的安全感。",
+      detail: "巨额现金让企业获得时间,但防御不能代替增长。它只能延缓冲击,不能回答西贡啤酒最终要成为一家什么样的公司。",
+      impact: "充足弹药换来转型窗口,真正的倒计时仍指向 2027 年。",
+      stat: "现金占总资产 64%"
+    },
+    {
+      id: "premium", chapter: "future", date: "正在发生", category: "evolution", index: "12",
+      title: "高端化:从 22% 向 30% 以上推进",
+      summary: "用产品结构升级,争取更厚的毛利来吸收税收冲击。",
+      detail: "高端化不是简单涨价,而是重做品牌、场景与渠道。它要求西贡啤酒跨过自己最强渠道资产所固化的大众认知。",
+      impact: "企业开始从“生产更多啤酒”转向“经营更高价值的品牌组合”。",
+      stat: "22% → 30%+"
+    },
+    {
+      id: "alcohol-free", chapter: "future", date: "未来五年", category: "evolution", index: "13",
+      title: "无酒精产品成为制度创新",
+      summary: "Sagota 无酒精啤酒营收占比已达 4.8%,目标五年突破 10%。",
+      detail: "抽掉酒精,也就抽掉了高额消费税的主要征税基础。产品创新在这里不只是迎合健康趋势,更是在规则内重构利润模型。",
+      impact: "企业尝试从适应政策,走向利用产品定义绕开旧约束。",
+      stat: "4.8% → 10%"
+    }
+  ],
+  model: [
+    { num: "01", category: "operation", title: "物理微观", subtitle: "企业的生存下限", body: "供应链效率、降本增效,以及十万个杂货铺组成的毛细血管。" },
+    { num: "02", category: "capital", title: "资本宏观", subtitle: "企业的扩张动力", body: "债务结构、资金来源,以及企业被跨国资本推上赌桌时的筹码属性。" },
+    { num: "03", category: "policy", title: "政治主权", subtitle: "企业的隐形天花板", body: "监管警惕、税收重分配与行政力量对核心资产的权力回收。" }
+  ]
+};

+ 106 - 0
case-timeline/index.html

@@ -0,0 +1,106 @@
+<!doctype html>
+<html lang="zh-CN">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="西贡杠杆:一场横跨资本、渠道与主权的商业案例时间线" />
+    <title>西贡杠杆 Saigon Leverage|纯粹星辰</title>
+    <link rel="stylesheet" href="./styles.css?v=202607141015" />
+  </head>
+  <body>
+    <header class="topbar">
+      <a class="brand" href="#top" aria-label="返回顶部">
+        <img class="brand-mark" src="../brand/logo-mark.svg" data-dark-src="../brand/logo-mark.svg" data-light-src="../brand/logo-mark-light.svg" alt="" />
+        <span class="brand-copy"><strong>纯粹星辰</strong><em>less and cosmos.</em></span>
+      </a>
+      <div class="topbar-actions">
+        <span class="episode" id="episodeLabel">CASE TIMELINE · EP.01</span>
+        <button class="icon-button" id="themeToggle" type="button" aria-label="切换至浅色模式" title="切换至浅色模式"><span class="icon-glyph" aria-hidden="true">☼</span></button>
+        <button class="icon-button edit-button" id="editToggle" type="button" aria-label="编辑页面内容" title="编辑页面内容"><span class="icon-glyph" aria-hidden="true">✎</span></button>
+        <button class="icon-button" id="copyLink" type="button" aria-label="复制当前页面链接" title="复制当前页面链接"><span class="icon-glyph" aria-hidden="true">⤴</span></button>
+      </div>
+    </header>
+    <div class="editbar" id="editbar" aria-live="polite">
+      <span><i></i> 编辑模式:直接点击文字修改,内容会自动保存在本机</span>
+      <button type="button" id="resetEdits">恢复原稿</button>
+    </div>
+
+    <main id="top">
+      <section class="hero" aria-labelledby="caseTitle">
+        <div class="hero-orbit" aria-hidden="true"></div>
+        <div class="leverage-word" aria-hidden="true">LEVERAGE</div>
+        <div class="hero-copy">
+          <p class="case-slug">SAIGON—LEVERAGE / 西贡杠杆</p>
+          <p class="eyebrow" id="heroEyebrow" data-edit="hero-eyebrow">48 亿美元的资本豪赌</p>
+          <h1 id="caseTitle" data-edit="case-title">西贡杠杆<br /><span>一场用债务撬动国家级资产的豪赌</span></h1>
+          <p class="hero-deck" id="heroDeck">300 多亿人民币入场,七年账面价值暴跌 72%。这是跨国战略误判,还是一场必须放进政治经济学里理解的长期博弈?</p>
+        </div>
+        <div class="hero-metrics" id="heroMetrics" aria-label="案例核心数字"></div>
+        <a class="scroll-cue" href="#story">沿时间线阅读 <span>↓</span></a>
+      </section>
+
+      <section class="story" id="story">
+        <aside class="story-rail" aria-label="案例导航">
+          <div class="rail-sticky">
+            <p class="rail-label">阅读视角</p>
+            <div class="filters" id="filters"></div>
+            <div class="progress-block">
+              <div class="progress-meta"><span>故事进度</span><strong id="progressText">0%</strong></div>
+              <div class="progress-track"><span id="progressBar"></span></div>
+            </div>
+            <nav class="chapter-nav" id="chapterNav" aria-label="章节跳转"></nav>
+          </div>
+        </aside>
+
+        <div class="timeline-wrap">
+          <div class="timeline-head">
+            <div>
+              <p class="section-kicker">CHRONICLE</p>
+              <h2 data-edit="timeline-title">一根杠杆,三层战场</h2>
+            </div>
+            <div class="timeline-tools">
+              <span>点击事件展开商业含义</span>
+              <div class="view-switch" aria-label="时间线浏览密度">
+                <button type="button" data-view="compact">速览</button>
+                <button type="button" data-view="detail">详细</button>
+              </div>
+            </div>
+          </div>
+          <div class="timeline" id="timeline"></div>
+          <section class="participants" aria-labelledby="participantsTitle">
+            <div class="participants-head">
+              <div>
+                <p class="section-kicker">THE PLAYERS</p>
+                <h2 id="participantsTitle" data-edit="participants-title">谁在这场牌局里</h2>
+              </div>
+              <p>参与方 · 立场 · 核心筹码</p>
+            </div>
+            <div class="participants-grid" id="participantsGrid"></div>
+          </section>
+        </div>
+      </section>
+
+      <section class="model" id="model" aria-labelledby="modelTitle">
+        <p class="section-kicker">THINKING MODEL</p>
+        <h2 id="modelTitle" data-edit="model-title">商业三维天平</h2>
+        <p class="model-intro" data-edit="model-intro">任何脱离政治经济学的纯经营分析,都只是纸面模型。看懂一家企业,需要同时放上三个砝码。</p>
+        <div class="model-grid" id="modelGrid"></div>
+        <blockquote data-edit="model-quote">“物理微观决定你能活多久,资本宏观决定你能跑多快,而政治主权决定你挣到的钱究竟属于谁。”</blockquote>
+      </section>
+
+      <section class="ending">
+        <p>THE QUESTION REMAINS</p>
+        <h2 data-edit="ending-question">它会成为跨国资本的“还债绞肉机”,<br />还是完成进化的消费品巨头?</h2>
+        <span data-edit="ending-answer">时间会给出答案。</span>
+      </section>
+    </main>
+
+    <footer>
+      <img src="../brand/logo-chinese-slogan-dark.svg" data-dark-src="../brand/logo-chinese-slogan-dark.svg" data-light-src="../brand/logo-chinese-slogan-light-bg.svg" alt="纯粹星辰,一念纯粹,万里星辰" />
+      <p>理解政治,看懂经济,听见资本与权力最真实的呼吸。</p>
+    </footer>
+
+    <script src="./case-data.js?v=202607141015"></script>
+    <script src="./app.js?v=202607141015"></script>
+  </body>
+</html>

+ 394 - 0
case-timeline/styles.css

@@ -0,0 +1,394 @@
+:root {
+  --void: #0b0c10;
+  --ink: #111319;
+  --panel: #151820;
+  --panel-2: #1b1f28;
+  --white: #f5f5f7;
+  --silver: #a6abb3;
+  --muted: #747b85;
+  --gold: #e6c687;
+  --gold-deep: #b89652;
+  --line: rgba(197, 198, 199, .14);
+  --operation: #85a9a3;
+  --capital: #e6c687;
+  --policy: #ce7c70;
+  --market: #8198bd;
+  --evolution: #9a88b8;
+}
+
+* { box-sizing: border-box; }
+html { scroll-behavior: smooth; }
+body {
+  margin: 0;
+  font-size: 16px;
+  color: var(--white);
+  background: var(--void);
+  font-family: Inter, "PingFang SC", "Microsoft YaHei", sans-serif;
+  -webkit-font-smoothing: antialiased;
+}
+button, a { font: inherit; }
+a { color: inherit; text-decoration: none; }
+button { color: inherit; }
+::selection { color: var(--void); background: var(--gold); }
+
+.topbar {
+  position: fixed;
+  z-index: 20;
+  inset: 0 0 auto;
+  height: 88px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 clamp(20px, 4vw, 64px);
+  border-bottom: 1px solid var(--line);
+  background: rgba(11, 12, 16, .82);
+  backdrop-filter: blur(18px);
+}
+.brand {
+  width: auto;
+  height: 64px;
+  display: flex;
+  align-items: center;
+  gap: 18px;
+}
+.brand-mark {
+  width: 86px;
+  height: auto;
+  display: block;
+}
+.brand-copy { display: grid; gap: 6px; white-space: nowrap; }
+.brand-copy strong {
+  color: var(--white);
+  font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
+  font-size: 27px;
+  font-weight: 300;
+  letter-spacing: .22em;
+  line-height: 1;
+}
+.brand-copy em {
+  color: var(--silver);
+  font-size: 11px;
+  font-style: normal;
+  font-weight: 300;
+  letter-spacing: .28em;
+}
+}
+.topbar-actions { display: flex; align-items: center; gap: 20px; }
+.episode { color: var(--muted); font-size: 13px; letter-spacing: .13em; }
+.icon-button {
+  width: 38px;
+  min-width: 38px;
+  height: 38px;
+  border: 1px solid var(--line);
+  border-radius: 2px;
+  background: transparent;
+  display: inline-grid;
+  place-items: center;
+  cursor: pointer;
+}
+.icon-glyph { font-size: 20px; line-height: 1; font-weight: 300; }
+.icon-button:hover { border-color: rgba(230, 198, 135, .55); color: var(--gold); }
+.edit-button { border-color: rgba(230, 198, 135, .38); color: var(--gold); }
+.icon-button.is-copied { color: #5fa77d; border-color: rgba(95,167,125,.55); }
+.editbar { position: fixed; z-index: 19; top: 88px; left: 0; right: 0; min-height: 46px; padding: 0 clamp(20px,4vw,64px); display: flex; align-items: center; justify-content: space-between; gap: 20px; background: var(--gold); color: var(--void); font-size: 14px; transform: translateY(-110%); transition: transform .22s ease; }
+.editbar span { display: flex; align-items: center; gap: 9px; }
+.editbar i { width: 6px; height: 6px; border-radius: 50%; background: #17834b; box-shadow: 0 0 0 4px rgba(23,131,75,.14); }
+.editbar button { border: 0; border-bottom: 1px solid currentColor; padding: 3px 0; background: none; cursor: pointer; }
+.is-editing .editbar { transform: translateY(0); }
+.is-editing [data-edit] { outline: 1px dashed rgba(230,198,135,.7); outline-offset: 4px; cursor: text; }
+.is-editing [data-edit]:focus { outline-style: solid; background: rgba(230,198,135,.09); }
+
+.hero {
+  position: relative;
+  min-height: 100svh;
+  overflow: hidden;
+  padding: 144px clamp(24px, 8vw, 128px) 70px;
+  display: grid;
+  grid-template-columns: minmax(0, 1fr) minmax(320px, 440px);
+  align-content: center;
+  gap: 72px;
+  background:
+    radial-gradient(circle at 76% 44%, rgba(230, 198, 135, .10), transparent 23%),
+    linear-gradient(180deg, #0b0c10, #0e1015);
+}
+.hero::before {
+  content: "";
+  position: absolute;
+  inset: 0;
+  opacity: .25;
+  pointer-events: none;
+  background-image: radial-gradient(rgba(245,245,247,.75) .55px, transparent .55px);
+  background-size: 43px 43px;
+  mask-image: linear-gradient(to bottom, black, transparent 84%);
+}
+.leverage-word { position: absolute; left: 4vw; top: 15%; color: transparent; -webkit-text-stroke: 1px rgba(230,198,135,.1); font-size: clamp(90px, 17vw, 260px); font-weight: 700; letter-spacing: -.08em; line-height: .8; white-space: nowrap; }
+.hero-orbit {
+  position: absolute;
+  width: min(56vw, 760px);
+  aspect-ratio: 1;
+  right: -13vw;
+  top: 5vh;
+  border: 1px solid rgba(230, 198, 135, .18);
+  border-radius: 50%;
+}
+.hero-orbit::after {
+  content: "";
+  position: absolute;
+  width: 8px; height: 8px;
+  left: 9%; top: 24%;
+  border-radius: 50%;
+  background: var(--gold);
+  box-shadow: 0 0 24px var(--gold);
+}
+.hero-copy, .hero-metrics { position: relative; z-index: 1; }
+.case-slug { margin: 0 0 42px; color: var(--muted); font-size: 13px; letter-spacing: .22em; }
+.eyebrow, .section-kicker {
+  margin: 0 0 24px;
+  color: var(--gold);
+  font-size: 14px;
+  letter-spacing: .28em;
+  text-transform: uppercase;
+}
+.hero h1 {
+  max-width: 860px;
+  margin: 0;
+  font-size: clamp(42px, 6.2vw, 92px);
+  line-height: 1.08;
+  letter-spacing: -.055em;
+  font-weight: 600;
+}
+.hero h1::first-line { color: var(--gold); }
+.hero h1 span { color: #b9bdc4; font-weight: 300; }
+.hero-deck {
+  max-width: 700px;
+  margin: 34px 0 0;
+  color: #aeb2b9;
+  font-size: clamp(16px, 1.5vw, 20px);
+  line-height: 1.9;
+  font-weight: 300;
+}
+.hero-metrics {
+  align-self: end;
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  border-top: 1px solid var(--line);
+  border-left: 1px solid var(--line);
+}
+.metric { min-height: 130px; padding: 26px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
+.metric strong { display: block; color: var(--gold); font-size: clamp(23px, 2.5vw, 34px); font-weight: 400; letter-spacing: -.03em; }
+.metric span { display: block; margin-top: 12px; color: var(--muted); font-size: 14px; letter-spacing: .06em; }
+.scroll-cue { position: absolute; z-index: 2; left: clamp(24px, 8vw, 128px); bottom: 30px; color: var(--muted); font-size: 14px; letter-spacing: .1em; }
+.scroll-cue span { display: inline-block; margin-left: 10px; color: var(--gold); animation: bob 1.7s ease-in-out infinite; }
+
+.story { display: grid; grid-template-columns: 260px minmax(0, 1fr); width: min(1320px, calc(100% - 48px)); margin: 0 auto; padding: 110px 0 150px; gap: 74px; }
+.rail-sticky { position: sticky; top: 100px; }
+.rail-label { color: var(--muted); margin: 0 0 16px; font-size: 14px; letter-spacing: .14em; }
+.filters { display: grid; gap: 3px; }
+.filter {
+  width: 100%; height: 40px; padding: 0 12px;
+  display: flex; align-items: center; gap: 10px;
+  border: 0; background: transparent; color: var(--muted);
+  text-align: left; font-size: 15px; cursor: pointer;
+}
+.filter i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
+.filter:hover { color: var(--white); }
+.filter.active { color: var(--gold); background: rgba(230, 198, 135, .07); }
+.progress-block { margin: 34px 0; padding-top: 24px; border-top: 1px solid var(--line); }
+.progress-meta { display: flex; justify-content: space-between; color: var(--muted); font-size: 14px; }
+.progress-meta strong { color: var(--gold); font-weight: 400; }
+.progress-track { height: 2px; margin-top: 12px; background: var(--line); }
+.progress-track span { display: block; width: 0; height: 100%; background: var(--gold); transition: width .12s linear; }
+.chapter-nav { display: grid; gap: 14px; }
+.chapter-nav a { color: var(--muted); font-size: 14px; transition: color .2s; }
+.chapter-nav a:hover { color: var(--white); }
+.chapter-nav span { display: inline-block; width: 34px; color: var(--gold-deep); font-size: 13px; }
+
+.participants { margin-top: 110px; padding-top: 80px; border-top: 1px solid var(--line); }
+.participants-head { display: flex; align-items: end; justify-content: space-between; margin-bottom: 26px; }
+.participants-head h2 { margin: 0; font-size: clamp(28px, 3vw, 42px); font-weight: 400; letter-spacing: -.04em; }
+.participants-head > p { margin: 0; color: var(--muted); font-size: 14px; letter-spacing: .08em; }
+.participants-grid { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
+.participant-card { min-height: 210px; padding: 23px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); background: rgba(21,24,32,.38); }
+.participant-title { display: flex; align-items: center; gap: 13px; }
+.participant-title > span { flex: 0 0 35px; height: 35px; display: grid; place-items: center; border: 1px solid rgba(230,198,135,.35); border-radius: 50%; color: var(--gold); font-family: Georgia, serif; font-size: 14px; }
+.participant-title h3 { margin: 0 0 4px; font-size: 16px; font-weight: 400; }
+.participant-title p { margin: 0; color: var(--muted); font-size: 13px; }
+.participant-card > p { margin: 23px 0 16px; color: #9da2aa; font-size: 15px; line-height: 1.75; }
+.participant-card > strong { color: var(--gold-deep); font-size: 13px; font-weight: 500; letter-spacing: .02em; }
+.timeline-head { display: flex; align-items: end; justify-content: space-between; margin-bottom: 66px; }
+.timeline-head h2, .model h2 { margin: 0; font-size: clamp(34px, 4vw, 58px); letter-spacing: -.04em; font-weight: 400; }
+.timeline-tools { display: flex; align-items: center; gap: 16px; }
+.timeline-tools > span { color: var(--muted); font-size: 14px; }
+.view-switch { display: flex; padding: 3px; border: 1px solid var(--line); background: rgba(21,24,32,.6); }
+.view-switch button { min-width: 58px; height: 34px; padding: 0 12px; border: 0; background: transparent; color: var(--muted); font-size: 14px; cursor: pointer; }
+.view-switch button.active { color: var(--void); background: var(--gold); }
+.timeline { position: relative; }
+.timeline::before { content: ""; position: absolute; left: 154px; top: 0; bottom: 0; width: 1px; background: linear-gradient(var(--gold), var(--line) 12%, var(--line) 90%, transparent); }
+.event { position: relative; display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 52px; padding-bottom: 28px; animation: reveal .45s both; animation-delay: var(--delay); }
+.event::before { content: ""; position: absolute; left: 150px; top: 30px; width: 9px; height: 9px; border: 2px solid var(--void); border-radius: 50%; background: var(--muted); }
+.event[data-category="operation"]::before { background: var(--operation); }
+.event[data-category="capital"]::before { background: var(--capital); }
+.event[data-category="policy"]::before { background: var(--policy); }
+.event[data-category="market"]::before { background: var(--market); }
+.event[data-category="evolution"]::before { background: var(--evolution); }
+.event-date { padding-top: 21px; text-align: right; }
+.event-date span { display: block; color: #aeb2b9; font-size: 15px; line-height: 1.5; }
+.event-date small { display: block; margin-top: 7px; color: #5c626b; font-size: 13px; letter-spacing: .08em; }
+.event-card {
+  width: 100%; padding: 25px 28px 26px; border: 1px solid var(--line); border-radius: 2px;
+  background: rgba(21, 24, 32, .58); text-align: left; cursor: pointer;
+  transition: background .25s, border-color .25s, transform .25s;
+}
+.event-card:hover { transform: translateY(-2px); border-color: rgba(230, 198, 135, .32); background: var(--panel); }
+.featured .event-card { background: linear-gradient(115deg, rgba(230,198,135,.08), rgba(21,24,32,.8) 52%); }
+.event-card-top { display: flex; justify-content: space-between; align-items: center; }
+.tag { color: var(--gold-deep); font-size: 13px; letter-spacing: .1em; }
+.expand-icon { color: var(--muted); font-size: 18px; font-weight: 200; transition: transform .25s; }
+.event.open .expand-icon { transform: rotate(45deg); }
+.event h3 { margin: 19px 0 10px; font-size: clamp(20px, 2.2vw, 28px); font-weight: 400; letter-spacing: -.02em; }
+.event-card > p { max-width: 750px; margin: 0; color: #989da6; font-size: 16px; line-height: 1.8; }
+.event-stat { display: block; margin-top: 22px; color: var(--gold); font-size: 14px; font-weight: 500; letter-spacing: .05em; }
+.event-detail { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .35s ease, opacity .25s ease, margin .35s; }
+.event-detail > div { overflow: hidden; }
+.event-detail > div:first-child { grid-row: 1; }
+.event-detail > div:last-child { grid-row: 1; visibility: hidden; }
+.event.open .event-detail { grid-template-rows: 1fr; opacity: 1; margin-top: 25px; border-top: 1px solid var(--line); padding-top: 22px; gap: 20px; }
+.event.open .event-detail { display: grid; grid-template-columns: 1fr 1fr; }
+.event.open .event-detail > div:last-child { grid-row: auto; visibility: visible; }
+.event-detail span { color: var(--muted); font-size: 13px; letter-spacing: .1em; }
+.event-detail p { margin: 8px 0 0; color: #b6bac1; font-size: 15px; line-height: 1.8; }
+.timeline.compact .event { padding-bottom: 10px; }
+.timeline.compact .event::before { top: 20px; }
+.timeline.compact .event-date { padding-top: 12px; }
+.timeline.compact .event-card { padding: 15px 20px 16px; }
+.timeline.compact .event-card-top { float: right; margin-left: 12px; }
+.timeline.compact .tag { display: none; }
+.timeline.compact .event h3 { margin: 0 0 8px; font-size: 21px; }
+.timeline.compact .event-card > p { display: none; }
+.timeline.compact .event-stat { margin-top: 0; font-size: 14px; }
+.timeline.compact .event.open .event-detail { margin-top: 15px; }
+
+.model { padding: 130px max(24px, calc((100vw - 1180px) / 2)); background: #f0f0f1; color: var(--ink); }
+.model .section-kicker { color: var(--gold-deep); }
+.model-intro { max-width: 670px; margin: 25px 0 55px; color: #676c74; line-height: 1.8; }
+.model-grid { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid #d1d3d7; border-left: 1px solid #d1d3d7; }
+.model-card { min-height: 310px; padding: 34px; border-right: 1px solid #d1d3d7; border-bottom: 1px solid #d1d3d7; }
+.model-card > span { color: var(--gold-deep); font-size: 14px; letter-spacing: .1em; }
+.model-card h3 { margin: 54px 0 8px; font-size: 29px; font-weight: 400; }
+.model-card strong { color: #777c84; font-size: 15px; font-weight: 400; }
+.model-card p { margin: 25px 0 0; color: #5e636a; font-size: 16px; line-height: 1.8; }
+.model blockquote { max-width: 900px; margin: 85px auto 0; font-family: Georgia, "Songti SC", serif; font-size: clamp(22px, 2.8vw, 37px); line-height: 1.6; text-align: center; }
+
+.ending { min-height: 72vh; display: grid; place-content: center; padding: 90px 24px; text-align: center; background: radial-gradient(circle at 50% 50%, rgba(230,198,135,.08), transparent 35%); }
+.ending p { color: var(--gold); font-size: 14px; letter-spacing: .2em; }
+.ending h2 { margin: 26px 0; font-size: clamp(30px, 4vw, 58px); line-height: 1.45; font-weight: 300; letter-spacing: -.04em; }
+.ending span { color: var(--muted); font-family: Georgia, "Songti SC", serif; font-size: 17px; }
+footer { min-height: 220px; padding: 55px max(24px, calc((100vw - 1180px) / 2)); display: flex; align-items: end; justify-content: space-between; gap: 30px; border-top: 1px solid var(--line); }
+footer img { width: 350px; max-width: 100%; }
+footer p { color: var(--muted); font-size: 14px; letter-spacing: .05em; }
+
+html[data-theme="light"] {
+  --void: #f5f5f7;
+  --ink: #0b0c10;
+  --panel: #ffffff;
+  --panel-2: #eceef1;
+  --white: #0b0c10;
+  --silver: #59616a;
+  --muted: #6f7780;
+  --gold: #76591f;
+  --gold-deep: #654916;
+  --line: #d8dadf;
+  color-scheme: light;
+}
+html[data-theme="light"] body { background: var(--void); }
+html[data-theme="light"] .topbar { background: rgba(245,245,247,.9); }
+html[data-theme="light"] .hero { background: radial-gradient(circle at 76% 44%, rgba(184,150,82,.11), transparent 23%), linear-gradient(180deg,#f5f5f7,#f1f2f4); }
+html[data-theme="light"] .hero::before { opacity: .16; background-image: radial-gradient(rgba(78,88,98,.7) .55px, transparent .55px); }
+html[data-theme="light"] .hero-orbit { border-color: rgba(78,88,98,.22); }
+html[data-theme="light"] .leverage-word { -webkit-text-stroke-color: rgba(78,88,98,.11); }
+html[data-theme="light"] .hero-orbit::after { background: #b89652; box-shadow: 0 0 20px rgba(184,150,82,.55); }
+html[data-theme="light"] .hero h1 span, html[data-theme="light"] .hero-deck { color: #59616a; }
+html[data-theme="light"] .case-slug, html[data-theme="light"] .episode { color: #737b84; }
+html[data-theme="light"] .participant-card, html[data-theme="light"] .event-card { background: rgba(255,255,255,.72); }
+html[data-theme="light"] .featured .event-card { background: linear-gradient(115deg,rgba(184,150,82,.12),rgba(255,255,255,.84) 52%); }
+html[data-theme="light"] .event-card:hover { background: #fff; border-color: rgba(184,150,82,.5); }
+html[data-theme="light"] .event-card > p, html[data-theme="light"] .event-detail p, html[data-theme="light"] .participant-card > p { color: #59616a; }
+html[data-theme="light"] .event-date span { color: #4e5862; }
+html[data-theme="light"] .event-date small { color: #9298a0; }
+html[data-theme="light"] .event::before { border-color: var(--void); }
+html[data-theme="light"] .view-switch { background: #eceef1; }
+html[data-theme="light"] .view-switch button.active { color: #f5f5f7; }
+html[data-theme="light"] .editbar { background: #76591f; color: #fff; }
+html[data-theme="light"] .model { background: #eceef1; color: #0b0c10; border-block: 1px solid #d8dadf; }
+html[data-theme="light"] .model-intro, html[data-theme="light"] .model-card p { color: #59616a; }
+html[data-theme="light"] .model-card strong { color: #737b84; }
+html[data-theme="light"] .model-grid, html[data-theme="light"] .model-card { border-color: #cfd2d7; }
+html[data-theme="light"] .ending { background: radial-gradient(circle at 50% 50%,rgba(184,150,82,.1),transparent 36%); }
+html[data-theme="light"] .story-rail { background-color: rgba(245,245,247,.92); }
+
+@keyframes bob { 50% { transform: translateY(5px); } }
+@keyframes reveal { from { opacity: 0; transform: translateY(10px); } }
+@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; animation: none !important; transition: none !important; } }
+
+@media (max-width: 900px) {
+  .hero { grid-template-columns: 1fr; gap: 48px; padding-top: 120px; }
+  .hero-metrics { width: 100%; }
+  .story { grid-template-columns: 1fr; gap: 50px; }
+  .rail-sticky { position: static; }
+  .filters { display: flex; overflow-x: auto; padding-bottom: 6px; }
+  .filter { width: auto; min-width: max-content; padding: 0 14px; border: 1px solid var(--line); }
+  .progress-block, .chapter-nav { display: none; }
+  .participants-grid { grid-template-columns: repeat(2, 1fr); }
+  .model-grid { grid-template-columns: 1fr; }
+}
+
+@media (max-width: 620px) {
+  .topbar { height: 74px; }
+  .brand { height: 52px; gap: 10px; }
+  .brand-mark { width: 58px; }
+  .brand-copy { gap: 4px; }
+  .brand-copy strong { font-size: 20px; letter-spacing: .15em; }
+  .brand-copy em { font-size: 9px; letter-spacing: .18em; }
+  .episode { display: none; }
+  .topbar-actions { gap: 7px; }
+  .icon-button { width: 38px; min-width: 38px; padding: 0; }
+  .editbar { top: 74px; padding: 10px 14px; }
+  .editbar span { line-height: 1.5; }
+  .hero { min-height: auto; padding: 104px 20px 54px; gap: 28px; }
+  .hero h1 { font-size: 42px; }
+  .case-slug { margin-bottom: 25px; }
+  .leverage-word { top: 17%; font-size: 24vw; }
+  .hero-deck { margin-top: 22px; font-size: 14px; line-height: 1.7; }
+  .hero-metrics { grid-template-columns: repeat(4, minmax(108px, 1fr)); overflow-x: auto; border-left: 0; border-top: 1px solid var(--line); scrollbar-width: none; }
+  .metric { min-height: 82px; padding: 14px 12px; border-left: 1px solid var(--line); }
+  .metric strong { font-size: 19px; white-space: nowrap; }
+  .metric span { margin-top: 7px; font-size: 13px; }
+  .scroll-cue { display: none; }
+  .story { width: calc(100% - 24px); padding-top: 34px; gap: 28px; }
+  .story-rail { position: sticky; z-index: 9; top: 74px; margin-inline: -12px; padding: 9px 12px; background: rgba(11,12,16,.92); backdrop-filter: blur(14px); border-bottom: 1px solid var(--line); }
+  .rail-label { display: none; }
+  .filters { padding-bottom: 0; }
+  .filter { height: 40px; font-size: 14px; }
+  .participants { margin-top: 62px; padding-top: 54px; }
+  .participants-head { margin-bottom: 18px; }
+  .participants-head > p { display: none; }
+  .participants-grid { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; border: 0; margin-right: -12px; padding-right: 12px; scrollbar-width: none; }
+  .participant-card { flex: 0 0 78vw; min-height: 176px; scroll-snap-align: start; border: 1px solid var(--line); border-right: 0; }
+  .participant-card:last-child { border-right: 1px solid var(--line); }
+  .timeline-head { display: block; margin-bottom: 40px; }
+  .timeline-tools { margin-top: 17px; justify-content: space-between; }
+  .timeline-tools > span { font-size: 13px; }
+  .timeline::before { left: 5px; }
+  .event { grid-template-columns: 1fr; gap: 10px; padding-left: 24px; }
+  .event::before { left: 1px; top: 8px; }
+  .event-date { padding: 0; text-align: left; display: flex; gap: 10px; align-items: center; }
+  .event-date small { margin: 0; }
+  .event-card { padding: 18px 16px; }
+  .event.open .event-detail { grid-template-columns: 1fr; }
+  .timeline.compact .event-card { padding: 12px 14px 13px; }
+  .timeline.compact .event h3 { font-size: 18px; line-height: 1.45; }
+  .timeline.compact .event-date { padding: 0; }
+  .timeline.compact .event::before { top: 8px; }
+  .model { padding-block: 90px; }
+  footer { align-items: flex-start; flex-direction: column; }
+}

+ 30 - 0
website/.gitignore

@@ -0,0 +1,30 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+# Environment files (keep examples in Git)
+.env
+.env.*
+!.env.example
+!.env.*.example
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 8 - 0
website/.oxlintrc.json

@@ -0,0 +1,8 @@
+{
+  "$schema": "./node_modules/oxlint/configuration_schema.json",
+  "plugins": ["react", "oxc"],
+  "rules": {
+    "react/rules-of-hooks": "error",
+    "react/only-export-components": ["warn", { "allowConstantExport": true }]
+  }
+}

+ 16 - 0
website/README.md

@@ -0,0 +1,16 @@
+# React + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some Oxlint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
+
+## React Compiler
+
+The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
+
+## Expanding the Oxlint configuration
+
+If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and Oxlint's TypeScript related rules in your project.

+ 23 - 0
website/deploy.sh

@@ -0,0 +1,23 @@
+#!/bin/bash
+set -e
+
+HOST="192.227.214.199"
+PASSWORD="2P4Eqo7inTQSOf13c0"
+
+echo "Building project..."
+npm run build
+
+echo "Creating deployment directory on server..."
+./ssh_cmd.exp $HOST $PASSWORD "mkdir -p /var/www/lessncosmos.ccdw.xyz"
+
+echo "Uploading files..."
+./scp_cmd.exp $HOST $PASSWORD dist /root/dist_temp
+./ssh_cmd.exp $HOST $PASSWORD "rm -rf /var/www/lessncosmos.ccdw.xyz/* && cp -r /root/dist_temp/* /var/www/lessncosmos.ccdw.xyz/ && rm -rf /root/dist_temp"
+
+echo "Uploading nginx config..."
+./scp_cmd.exp $HOST $PASSWORD nginx.conf /etc/nginx/sites-available/lessncosmos.ccdw.xyz
+
+echo "Enabling site and reloading nginx..."
+./ssh_cmd.exp $HOST $PASSWORD "ln -sf /etc/nginx/sites-available/lessncosmos.ccdw.xyz /etc/nginx/sites-enabled/ && nginx -t && systemctl reload nginx"
+
+echo "Deployment complete!"

+ 16 - 0
website/index.html

@@ -0,0 +1,16 @@
+<!doctype html>
+<html lang="zh-CN">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>纯粹星辰 | less and cosmos.</title>
+    <meta name="description" content="纯粹星辰 Less and Cosmos 官方品牌主页。">
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap" rel="stylesheet">
+  </head>
+  <body>
+    <div id="root"></div>
+    <script type="module" src="/src/main.jsx"></script>
+  </body>
+</html>

+ 31 - 0
website/nginx.conf

@@ -0,0 +1,31 @@
+server {
+    server_name lessncosmos.ccdw.xyz;
+
+    root /var/www/lessncosmos.ccdw.xyz;
+    index index.html;
+
+    location ^~ /slow-aplha/ {
+        return 404;
+    }
+
+    location / {
+        try_files $uri $uri/ /index.html;
+    }
+
+    listen 443 ssl;
+    ssl_certificate /etc/letsencrypt/live/lessncosmos.ccdw.xyz/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/lessncosmos.ccdw.xyz/privkey.pem;
+    include /etc/letsencrypt/options-ssl-nginx.conf;
+    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
+}
+
+server {
+    if ($host = lessncosmos.ccdw.xyz) {
+        return 301 https://$host$request_uri;
+    }
+
+    listen 80;
+    listen [::]:80;
+    server_name lessncosmos.ccdw.xyz;
+    return 404;
+}

+ 1332 - 0
website/package-lock.json

@@ -0,0 +1,1332 @@
+{
+  "name": "website",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "website",
+      "version": "0.0.0",
+      "dependencies": {
+        "react": "^19.2.7",
+        "react-dom": "^19.2.7"
+      },
+      "devDependencies": {
+        "@types/react": "^19.2.17",
+        "@types/react-dom": "^19.2.3",
+        "@vitejs/plugin-react": "^6.0.3",
+        "oxlint": "^1.71.0",
+        "vite": "^8.1.1"
+      }
+    },
+    "node_modules/@emnapi/core": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmmirror.com/@emnapi/core/-/core-1.11.1.tgz",
+      "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@emnapi/wasi-threads": "1.2.2",
+        "tslib": "^2.4.0"
+      }
+    },
+    "node_modules/@emnapi/runtime": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.11.1.tgz",
+      "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "tslib": "^2.4.0"
+      }
+    },
+    "node_modules/@emnapi/wasi-threads": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
+      "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "tslib": "^2.4.0"
+      }
+    },
+    "node_modules/@napi-rs/wasm-runtime": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
+      "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@tybys/wasm-util": "^0.10.3"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/Brooooooklyn"
+      },
+      "peerDependencies": {
+        "@emnapi/core": "^1.7.1",
+        "@emnapi/runtime": "^1.7.1"
+      }
+    },
+    "node_modules/@oxc-project/types": {
+      "version": "0.138.0",
+      "resolved": "https://registry.npmmirror.com/@oxc-project/types/-/types-0.138.0.tgz",
+      "integrity": "sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/Boshen"
+      }
+    },
+    "node_modules/@oxlint/binding-android-arm-eabi": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.72.0.tgz",
+      "integrity": "sha512-zhCmvn+1Mj3UchAc/90i99S0t7jJUsHmFVSPg4UWrjO8b8eaSGwscgO6QAUtvHBstkjQwBttQNswEnAF1mIQdA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-android-arm64": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-android-arm64/-/binding-android-arm64-1.72.0.tgz",
+      "integrity": "sha512-mtH+aY/ozv1eZoCUC2owjFAtyNBKHpJHygKeEu9zXXnQGW1Q2/qOpvx+I+Lf23+TvTz66F4iiXUbl2cGvoLPCQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-darwin-arm64": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.72.0.tgz",
+      "integrity": "sha512-EvnajNPDtfknB3ZieeOOyDTwJn9QXDiwfnF4ZDQqART6RG6hjY4WigQcZdGoK2dkB3e1vrmEzN9aYbQCUkh/gQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-darwin-x64": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.72.0.tgz",
+      "integrity": "sha512-ZkCdEa/G80A7vEHfeCDz/+L3m33DE73v32mDKhgOIgz8Uwf0DFcK7+uu6qC+7LEhmz5fpOe1osWKyjSNMydFIQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-freebsd-x64": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.72.0.tgz",
+      "integrity": "sha512-NroXv2vh+sxVY1uya/rM5pjhx1hm8BzlYpx9q67QP0Xhw5MH2bf5GJylpvLEC+781p1Xli/317EoV9AlGwViag==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-arm-gnueabihf": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.72.0.tgz",
+      "integrity": "sha512-0NDywYgfj279Ou/BcQuCYSj7NJwBfmWn5qc5uGO/Ny7fUWmXyIpvawqX/8acQlWG6IXelJsJhj+JAy6sjsKj0A==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-arm-musleabihf": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.72.0.tgz",
+      "integrity": "sha512-4vpXB06h65Ezsy4hRyrGjGrfa1SkVPii09yaajiYhmVpgsFiLD+KNxIx/BNAY+XiO+i1yqp9HHdwqM8VTqa5XQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-arm64-gnu": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.72.0.tgz",
+      "integrity": "sha512-immaN4g2ZGFiOkKrvRX9LvzZdd2GkQM5wR+UyzYyUuyhUTXGQ4HKUJH18xp4G8OfhCVaVAJfKZxwE1r8+4hhaQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-arm64-musl": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.72.0.tgz",
+      "integrity": "sha512-JGHS9Mnr7iWyyLDxgCv1MhzVpAckgptg00F2gnxt/GD7lQ2SW1BRcxHqhSTaSdDpjWRrBkBxMMh4+Hn3aVtExg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-ppc64-gnu": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.72.0.tgz",
+      "integrity": "sha512-AOYgBZqxNshrg83P9v0RYv+m8s10Cqkj4/PxXFDhcS3k7FqsIG5+CxErshZCIN7G8iy4Y+VGfAsuEdar8AcbBg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-riscv64-gnu": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.72.0.tgz",
+      "integrity": "sha512-QMybPS5ij3/vrKG67mqzHwW++91sYxK/PPUVi6SBtNCEzW4niS52fVBdXbQ6nou0wWbUPEpx8Sl/ZjtgE3clXA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-riscv64-musl": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.72.0.tgz",
+      "integrity": "sha512-gOc3W7JV0PXRpIL7stUlLe3Wa9Gp0Kdlup87IT3gHDvPKck2xNgMIl/Gs2lldYY2lyXZDC4rWi3hmoLUobkgbQ==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-s390x-gnu": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.72.0.tgz",
+      "integrity": "sha512-rpGxph+FjjHcYI5q6uxB3Az+tnfmEnDbSA8+PK9ZE/VzyUAkvBOMeuY7ZQMhu5mpZH7YQDsTdW6Cx4kV/msc6w==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-x64-gnu": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.72.0.tgz",
+      "integrity": "sha512-WND+uhf/Ko13SLqQMWQUgsZuLvYYEvL0ZKgg0tgGYfLqxG7l8Ju123fHDMJyYSDl5E3bUbpFUuii/OvMreFQzw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-linux-x64-musl": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.72.0.tgz",
+      "integrity": "sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-openharmony-arm64": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.72.0.tgz",
+      "integrity": "sha512-qkrsEn6NmgFKr7U/QnezQMb+q/vzAy0Dd9Y95gQGQTyjzDLN+HRZMuM5u70iyH4nBLCfKBzhjMsYCehKay2jyg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openharmony"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-win32-arm64-msvc": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.72.0.tgz",
+      "integrity": "sha512-LWR6ZlFZph+KPjXv8opgZsXRDCdrdQe8VL8Cg9zxCoBS73h6znzZpydVgmdnwj8mB9AuSM5jxEgDJDpQkjboeg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-win32-ia32-msvc": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.72.0.tgz",
+      "integrity": "sha512-yt6HEh7IsHvtjRWtmeZRX134eaXKHq5Gnqlf1xBJdJl1JtdoRUEJw3nAxpZoUDS860cX/foKbztO441anVBtVQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@oxlint/binding-win32-x64-msvc": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.72.0.tgz",
+      "integrity": "sha512-b2eKFD2hX7tIwmo/cyH6TDq8vzWRZ2qNHrzoGntUTmq0h3zQh/uX3eTSHCwI8OB/ADQfJCRelLItK8BsxuucDA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-android-arm64": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.4.tgz",
+      "integrity": "sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-darwin-arm64": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.4.tgz",
+      "integrity": "sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-darwin-x64": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.4.tgz",
+      "integrity": "sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-freebsd-x64": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.4.tgz",
+      "integrity": "sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.4.tgz",
+      "integrity": "sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-linux-arm64-gnu": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.4.tgz",
+      "integrity": "sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-linux-arm64-musl": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.4.tgz",
+      "integrity": "sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.4.tgz",
+      "integrity": "sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-linux-s390x-gnu": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.4.tgz",
+      "integrity": "sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-linux-x64-gnu": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.4.tgz",
+      "integrity": "sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-linux-x64-musl": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.4.tgz",
+      "integrity": "sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-openharmony-arm64": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.4.tgz",
+      "integrity": "sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openharmony"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-wasm32-wasi": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.4.tgz",
+      "integrity": "sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg==",
+      "cpu": [
+        "wasm32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@emnapi/core": "1.11.1",
+        "@emnapi/runtime": "1.11.1",
+        "@napi-rs/wasm-runtime": "^1.1.6"
+      },
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-win32-arm64-msvc": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.4.tgz",
+      "integrity": "sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/binding-win32-x64-msvc": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.4.tgz",
+      "integrity": "sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
+    "node_modules/@rolldown/pluginutils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+      "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@tybys/wasm-util": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
+      "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "tslib": "^2.4.0"
+      }
+    },
+    "node_modules/@types/react": {
+      "version": "19.2.17",
+      "resolved": "https://registry.npmmirror.com/@types/react/-/react-19.2.17.tgz",
+      "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "csstype": "^3.2.2"
+      }
+    },
+    "node_modules/@types/react-dom": {
+      "version": "19.2.3",
+      "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-19.2.3.tgz",
+      "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+      "dev": true,
+      "license": "MIT",
+      "peerDependencies": {
+        "@types/react": "^19.2.0"
+      }
+    },
+    "node_modules/@vitejs/plugin-react": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-6.0.3.tgz",
+      "integrity": "sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@rolldown/pluginutils": "^1.0.1"
+      },
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      },
+      "peerDependencies": {
+        "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0",
+        "babel-plugin-react-compiler": "^1.0.0",
+        "vite": "^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@rolldown/plugin-babel": {
+          "optional": true
+        },
+        "babel-plugin-react-compiler": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/csstype": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz",
+      "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/detect-libc": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz",
+      "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/fdir": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz",
+      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "picomatch": "^3 || ^4"
+      },
+      "peerDependenciesMeta": {
+        "picomatch": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/lightningcss": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.32.0.tgz",
+      "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+      "dev": true,
+      "license": "MPL-2.0",
+      "dependencies": {
+        "detect-libc": "^2.0.3"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      },
+      "optionalDependencies": {
+        "lightningcss-android-arm64": "1.32.0",
+        "lightningcss-darwin-arm64": "1.32.0",
+        "lightningcss-darwin-x64": "1.32.0",
+        "lightningcss-freebsd-x64": "1.32.0",
+        "lightningcss-linux-arm-gnueabihf": "1.32.0",
+        "lightningcss-linux-arm64-gnu": "1.32.0",
+        "lightningcss-linux-arm64-musl": "1.32.0",
+        "lightningcss-linux-x64-gnu": "1.32.0",
+        "lightningcss-linux-x64-musl": "1.32.0",
+        "lightningcss-win32-arm64-msvc": "1.32.0",
+        "lightningcss-win32-x64-msvc": "1.32.0"
+      }
+    },
+    "node_modules/lightningcss-android-arm64": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+      "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-darwin-arm64": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+      "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-darwin-x64": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+      "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-freebsd-x64": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+      "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-arm-gnueabihf": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+      "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-arm64-gnu": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+      "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-arm64-musl": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+      "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-x64-gnu": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+      "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-x64-musl": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+      "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-win32-arm64-msvc": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+      "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-win32-x64-msvc": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+      "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.15",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.15.tgz",
+      "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/oxlint": {
+      "version": "1.72.0",
+      "resolved": "https://registry.npmmirror.com/oxlint/-/oxlint-1.72.0.tgz",
+      "integrity": "sha512-1rhdZIP/EvoI91ABIwNU5Q8+bWf8mjrS5UzIOZld4d4bXxJvtlUhlQvaoTogIGin/qdErMOrwaIJvCSIAKTLhA==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "oxlint": "bin/oxlint"
+      },
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/Boshen"
+      },
+      "optionalDependencies": {
+        "@oxlint/binding-android-arm-eabi": "1.72.0",
+        "@oxlint/binding-android-arm64": "1.72.0",
+        "@oxlint/binding-darwin-arm64": "1.72.0",
+        "@oxlint/binding-darwin-x64": "1.72.0",
+        "@oxlint/binding-freebsd-x64": "1.72.0",
+        "@oxlint/binding-linux-arm-gnueabihf": "1.72.0",
+        "@oxlint/binding-linux-arm-musleabihf": "1.72.0",
+        "@oxlint/binding-linux-arm64-gnu": "1.72.0",
+        "@oxlint/binding-linux-arm64-musl": "1.72.0",
+        "@oxlint/binding-linux-ppc64-gnu": "1.72.0",
+        "@oxlint/binding-linux-riscv64-gnu": "1.72.0",
+        "@oxlint/binding-linux-riscv64-musl": "1.72.0",
+        "@oxlint/binding-linux-s390x-gnu": "1.72.0",
+        "@oxlint/binding-linux-x64-gnu": "1.72.0",
+        "@oxlint/binding-linux-x64-musl": "1.72.0",
+        "@oxlint/binding-openharmony-arm64": "1.72.0",
+        "@oxlint/binding-win32-arm64-msvc": "1.72.0",
+        "@oxlint/binding-win32-ia32-msvc": "1.72.0",
+        "@oxlint/binding-win32-x64-msvc": "1.72.0"
+      },
+      "peerDependencies": {
+        "oxlint-tsgolint": ">=0.22.1",
+        "vite-plus": "*"
+      },
+      "peerDependenciesMeta": {
+        "oxlint-tsgolint": {
+          "optional": true
+        },
+        "vite-plus": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/picomatch": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.5.tgz",
+      "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.5.16",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.16.tgz",
+      "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.12",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/react": {
+      "version": "19.2.7",
+      "resolved": "https://registry.npmmirror.com/react/-/react-19.2.7.tgz",
+      "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-dom": {
+      "version": "19.2.7",
+      "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-19.2.7.tgz",
+      "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
+      "license": "MIT",
+      "dependencies": {
+        "scheduler": "^0.27.0"
+      },
+      "peerDependencies": {
+        "react": "^19.2.7"
+      }
+    },
+    "node_modules/rolldown": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/rolldown/-/rolldown-1.1.4.tgz",
+      "integrity": "sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@oxc-project/types": "=0.138.0",
+        "@rolldown/pluginutils": "^1.0.0"
+      },
+      "bin": {
+        "rolldown": "bin/cli.mjs"
+      },
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      },
+      "optionalDependencies": {
+        "@rolldown/binding-android-arm64": "1.1.4",
+        "@rolldown/binding-darwin-arm64": "1.1.4",
+        "@rolldown/binding-darwin-x64": "1.1.4",
+        "@rolldown/binding-freebsd-x64": "1.1.4",
+        "@rolldown/binding-linux-arm-gnueabihf": "1.1.4",
+        "@rolldown/binding-linux-arm64-gnu": "1.1.4",
+        "@rolldown/binding-linux-arm64-musl": "1.1.4",
+        "@rolldown/binding-linux-ppc64-gnu": "1.1.4",
+        "@rolldown/binding-linux-s390x-gnu": "1.1.4",
+        "@rolldown/binding-linux-x64-gnu": "1.1.4",
+        "@rolldown/binding-linux-x64-musl": "1.1.4",
+        "@rolldown/binding-openharmony-arm64": "1.1.4",
+        "@rolldown/binding-wasm32-wasi": "1.1.4",
+        "@rolldown/binding-win32-arm64-msvc": "1.1.4",
+        "@rolldown/binding-win32-x64-msvc": "1.1.4"
+      }
+    },
+    "node_modules/scheduler": {
+      "version": "0.27.0",
+      "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.27.0.tgz",
+      "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+      "license": "MIT"
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/tinyglobby": {
+      "version": "0.2.17",
+      "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.17.tgz",
+      "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fdir": "^6.5.0",
+        "picomatch": "^4.0.4"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/SuperchupuDev"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "dev": true,
+      "license": "0BSD",
+      "optional": true
+    },
+    "node_modules/vite": {
+      "version": "8.1.3",
+      "resolved": "https://registry.npmmirror.com/vite/-/vite-8.1.3.tgz",
+      "integrity": "sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "lightningcss": "^1.32.0",
+        "picomatch": "^4.0.4",
+        "postcss": "^8.5.16",
+        "rolldown": "~1.1.3",
+        "tinyglobby": "^0.2.17"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "peerDependencies": {
+        "@types/node": "^20.19.0 || >=22.12.0",
+        "@vitejs/devtools": "^0.3.0",
+        "esbuild": "^0.27.0 || ^0.28.0",
+        "jiti": ">=1.21.0",
+        "less": "^4.0.0",
+        "sass": "^1.70.0",
+        "sass-embedded": "^1.70.0",
+        "stylus": ">=0.54.8",
+        "sugarss": "^5.0.0",
+        "terser": "^5.16.0",
+        "tsx": "^4.8.1",
+        "yaml": "^2.4.2"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "@vitejs/devtools": {
+          "optional": true
+        },
+        "esbuild": {
+          "optional": true
+        },
+        "jiti": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        },
+        "tsx": {
+          "optional": true
+        },
+        "yaml": {
+          "optional": true
+        }
+      }
+    }
+  }
+}

+ 23 - 0
website/package.json

@@ -0,0 +1,23 @@
+{
+  "name": "website",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "lint": "oxlint",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "react": "^19.2.7",
+    "react-dom": "^19.2.7"
+  },
+  "devDependencies": {
+    "@types/react": "^19.2.17",
+    "@types/react-dom": "^19.2.3",
+    "@vitejs/plugin-react": "^6.0.3",
+    "oxlint": "^1.71.0",
+    "vite": "^8.1.1"
+  }
+}

+ 14 - 0
website/public/brand/logo-chinese-slogan.svg

@@ -0,0 +1,14 @@
+<svg width="1120" height="280" viewBox="0 0 1120 280" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">纯粹星辰 logo with slogan</title>
+  <desc id="desc">The Less and Cosmos symbol with Chinese brand name and slogan.</desc>
+  <g transform="translate(88 82)">
+    <circle cx="12" cy="36" r="4" fill="#E6C687"/>
+    <path d="M38 43C76 11 142 1 204 15C228 21 249 31 266 44" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+    <path d="M66 49C117 31 187 28 246 45" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+    <circle cx="268" cy="45" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+  </g>
+  <text x="398" y="125" fill="#F5F5F7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="46" font-weight="300" letter-spacing="18">纯粹星辰</text>
+  <line x1="400" y1="150" x2="796" y2="150" stroke="#1F2833" stroke-width="1"/>
+  <text x="404" y="190" fill="#C5C6C7" font-family="'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="20" font-weight="300" letter-spacing="10">一念纯粹,万里星辰。</text>
+  <text x="407" y="222" fill="#C5C6C7" font-family="Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="14" font-weight="200" letter-spacing="4.8" opacity="0.74">less and cosmos.</text>
+</svg>

+ 8 - 0
website/public/brand/logo-mark.svg

@@ -0,0 +1,8 @@
+<svg width="320" height="96" viewBox="0 0 320 96" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
+  <title id="title">Less and Cosmos logo mark</title>
+  <desc id="desc">A minimal spark dot followed by a thin orbital arc.</desc>
+  <circle cx="46" cy="50" r="4" fill="#E6C687"/>
+  <path d="M72 57C110 25 176 15 238 29C262 35 283 45 300 58" stroke="#C5C6C7" stroke-width="1.15" stroke-linecap="round" opacity="0.82"/>
+  <path d="M100 63C151 45 221 42 280 59" stroke="#F5F5F7" stroke-width="0.62" stroke-linecap="round" opacity="0.28"/>
+  <circle cx="302" cy="59" r="1.35" fill="#F5F5F7" opacity="0.8"/>
+</svg>

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
website/public/favicon.svg


+ 24 - 0
website/public/icons.svg

@@ -0,0 +1,24 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <symbol id="bluesky-icon" viewBox="0 0 16 17">
+    <g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
+    <defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
+  </symbol>
+  <symbol id="discord-icon" viewBox="0 0 20 19">
+    <path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
+  </symbol>
+  <symbol id="documentation-icon" viewBox="0 0 21 20">
+    <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
+    <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
+    <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
+  </symbol>
+  <symbol id="github-icon" viewBox="0 0 19 19">
+    <path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
+  </symbol>
+  <symbol id="social-icon" viewBox="0 0 20 20">
+    <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
+    <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
+  </symbol>
+  <symbol id="x-icon" viewBox="0 0 19 19">
+    <path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
+  </symbol>
+</svg>

+ 15 - 0
website/scp_cmd.exp

@@ -0,0 +1,15 @@
+#!/usr/bin/expect -f
+set timeout -1
+set host [lindex $argv 0]
+set password [lindex $argv 1]
+set source [lindex $argv 2]
+set dest [lindex $argv 3]
+
+spawn scp -r -o StrictHostKeyChecking=no $source root@$host:$dest
+expect {
+    "password:" {
+        send "$password\r"
+        exp_continue
+    }
+    eof
+}

+ 19 - 0
website/src/App.jsx

@@ -0,0 +1,19 @@
+import StarsCanvas from "./components/StarsCanvas";
+import Nav from "./components/Nav";
+import Hero from "./components/Hero";
+import Accounts from "./components/Accounts";
+import Footer from "./components/Footer";
+
+export default function App() {
+  return (
+    <div className="site-shell">
+      <StarsCanvas />
+      <Nav />
+      <main id="top">
+        <Hero />
+        <Accounts />
+      </main>
+      <Footer />
+    </div>
+  );
+}

BIN
website/src/assets/hero.png


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
website/src/assets/vite.svg


+ 34 - 0
website/src/components/Accounts.jsx

@@ -0,0 +1,34 @@
+import { accounts } from "../data/accounts";
+
+function AccountCard({ name, mark, description, tags }) {
+  return (
+    <article className="account-card">
+      <div className="account-top">
+        <h3 className="account-name">{name}</h3>
+        <div className="account-mark" aria-hidden="true">{mark}</div>
+      </div>
+      <p className="account-desc">{description}</p>
+      <div className="account-meta">
+        {tags.map((tag) => (
+          <span key={tag}>{tag}</span>
+        ))}
+      </div>
+    </article>
+  );
+}
+
+export default function Accounts() {
+  return (
+    <section className="accounts" id="accounts" aria-labelledby="accounts-title">
+      <div className="accounts-inner">
+        <p className="section-kicker">Owned Media</p>
+        <h2 className="section-title" id="accounts-title">纯粹星辰旗下账号</h2>
+        <div className="account-grid" id="accountGrid">
+          {accounts.map((account) => (
+            <AccountCard key={account.name} {...account} />
+          ))}
+        </div>
+      </div>
+    </section>
+  );
+}

+ 10 - 0
website/src/components/Footer.jsx

@@ -0,0 +1,10 @@
+export default function Footer() {
+  return (
+    <footer className="footer">
+      <div className="footer-inner">
+        <span>PURE INTENTION. COSMIC DISTANCE.</span>
+        <span>LESS AND COSMOS.</span>
+      </div>
+    </footer>
+  );
+}

+ 15 - 0
website/src/components/Hero.jsx

@@ -0,0 +1,15 @@
+export default function Hero() {
+  return (
+    <section className="hero" aria-labelledby="brand-title">
+      <div className="hero-inner">
+        <img
+          className="hero-logo"
+          src="/brand/logo-chinese-slogan.svg"
+          alt="纯粹星辰,一念纯粹,万里星辰。"
+        />
+        <h1 className="sr-only" id="brand-title">纯粹星辰 less and cosmos.</h1>
+        <a className="hero-action" href="#accounts">探索纯粹厂牌</a>
+      </div>
+    </section>
+  );
+}

+ 46 - 0
website/src/components/Nav.jsx

@@ -0,0 +1,46 @@
+import { useEffect, useRef, useState } from "react";
+
+export default function Nav() {
+  const navRef = useRef(null);
+  const brandRef = useRef(null);
+  const [isScrolled, setIsScrolled] = useState(false);
+
+  useEffect(() => {
+    const hero = document.querySelector(".hero");
+
+    function updateNavLogo() {
+      if (!hero) return;
+      const revealPoint = hero.offsetHeight * 0.62;
+      const shouldShowLogo = window.scrollY > revealPoint;
+      setIsScrolled(shouldShowLogo);
+    }
+
+    updateNavLogo();
+    window.addEventListener("scroll", updateNavLogo, { passive: true });
+    window.addEventListener("resize", updateNavLogo, { passive: true });
+
+    return () => {
+      window.removeEventListener("scroll", updateNavLogo);
+      window.removeEventListener("resize", updateNavLogo);
+    };
+  }, []);
+
+  return (
+    <header className={`nav${isScrolled ? " is-scrolled" : ""}`} id="siteNav" ref={navRef}>
+      <div className="nav-inner">
+        <a
+          className="brand-mini"
+          href="#top"
+          aria-label="纯粹星辰首页"
+          aria-hidden={!isScrolled}
+          tabIndex={isScrolled ? 0 : -1}
+          ref={brandRef}
+        >
+          <img src="/brand/logo-mark.svg" alt="" />
+          <span>less and cosmos.</span>
+        </a>
+        <a className="join-link" href="mailto:hello@lessandcosmos.com">JOIN</a>
+      </div>
+    </header>
+  );
+}

+ 88 - 0
website/src/components/StarsCanvas.jsx

@@ -0,0 +1,88 @@
+import { useEffect, useRef } from "react";
+
+export default function StarsCanvas() {
+  const canvasRef = useRef(null);
+
+  useEffect(() => {
+    const canvas = canvasRef.current;
+    const context = canvas.getContext("2d");
+    const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
+
+    let stars = [];
+    let width = 0;
+    let height = 0;
+    let animationFrame = 0;
+
+    function resizeStars() {
+      const ratio = Math.min(window.devicePixelRatio || 1, 2);
+      width = window.innerWidth;
+      height = window.innerHeight;
+      canvas.width = Math.floor(width * ratio);
+      canvas.height = Math.floor(height * ratio);
+      canvas.style.width = `${width}px`;
+      canvas.style.height = `${height}px`;
+      context.setTransform(ratio, 0, 0, ratio, 0, 0);
+
+      const starCount = Math.min(180, Math.max(80, Math.floor((width * height) / 8200)));
+      stars = Array.from({ length: starCount }, (_, index) => ({
+        x: Math.random() * width,
+        y: Math.random() * height,
+        radius: index % 13 === 0 ? Math.random() * 1.8 + 0.8 : Math.random() * 1.1 + 0.2,
+        alpha: Math.random() * 0.7 + 0.18,
+        speed: Math.random() * 0.16 + 0.04,
+        drift: Math.random() * 0.12 - 0.06,
+      }));
+    }
+
+    function drawStars() {
+      context.clearRect(0, 0, width, height);
+
+      const glow = context.createRadialGradient(
+        width * 0.5, height * 0.18, 0,
+        width * 0.5, height * 0.18, Math.max(width, height) * 0.62
+      );
+      glow.addColorStop(0, "rgba(230, 198, 135, 0.08)");
+      glow.addColorStop(0.46, "rgba(31, 40, 51, 0.08)");
+      glow.addColorStop(1, "rgba(11, 12, 16, 0)");
+      context.fillStyle = glow;
+      context.fillRect(0, 0, width, height);
+
+      for (const star of stars) {
+        context.beginPath();
+        context.arc(star.x, star.y, star.radius, 0, Math.PI * 2);
+        context.fillStyle = `rgba(245, 245, 247, ${star.alpha})`;
+        context.fill();
+
+        if (!prefersReducedMotion) {
+          star.y += star.speed;
+          star.x += star.drift;
+          if (star.y > height + 4) star.y = -4;
+          if (star.x < -4) star.x = width + 4;
+          if (star.x > width + 4) star.x = -4;
+        }
+      }
+
+      if (!prefersReducedMotion) {
+        animationFrame = requestAnimationFrame(drawStars);
+      }
+    }
+
+    function handleResize() {
+      cancelAnimationFrame(animationFrame);
+      resizeStars();
+      drawStars();
+    }
+
+    resizeStars();
+    drawStars();
+
+    window.addEventListener("resize", handleResize, { passive: true });
+
+    return () => {
+      cancelAnimationFrame(animationFrame);
+      window.removeEventListener("resize", handleResize);
+    };
+  }, []);
+
+  return <canvas ref={canvasRef} className="stars" aria-hidden="true" />;
+}

+ 8 - 0
website/src/data/accounts.js

@@ -0,0 +1,8 @@
+export const accounts = [
+  {
+    name: "投资实战派",
+    mark: "投",
+    description: "面向真实市场的投资观察与实战复盘,保持克制、清醒、长期主义。",
+    tags: ["投资", "实战复盘", "长期主义"],
+  },
+];

+ 390 - 0
website/src/index.css

@@ -0,0 +1,390 @@
+:root {
+  --absolute-void: #0b0c10;
+  --muted-nebula: #1f2833;
+  --cosmos-white: #f5f5f7;
+  --mercury-silver: #c5c6c7;
+  --spark-gold: #e6c687;
+  --line: rgba(197, 198, 199, 0.16);
+  --glass: rgba(11, 12, 16, 0.52);
+  --panel: rgba(31, 40, 51, 0.28);
+  --panel-hover: rgba(31, 40, 51, 0.42);
+}
+
+* {
+  box-sizing: border-box;
+}
+
+html {
+  scroll-behavior: smooth;
+}
+
+body {
+  margin: 0;
+  min-height: 100vh;
+  color: var(--cosmos-white);
+  background: var(--absolute-void);
+  font-family: Inter, "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
+  letter-spacing: 0;
+}
+
+body::selection {
+  color: var(--absolute-void);
+  background: var(--spark-gold);
+}
+
+a {
+  color: inherit;
+  text-decoration: none;
+}
+
+/* ─── Site Shell ─── */
+
+.site-shell {
+  position: relative;
+  overflow: hidden;
+  min-height: 100vh;
+  background:
+    radial-gradient(circle at 50% 12%, rgba(230, 198, 135, 0.08), transparent 28rem),
+    linear-gradient(180deg, rgba(11, 12, 16, 0.2), var(--absolute-void) 74%);
+}
+
+/* ─── Stars Canvas ─── */
+
+.stars {
+  position: fixed;
+  inset: 0;
+  width: 100%;
+  height: 100%;
+  pointer-events: none;
+  opacity: 0.78;
+}
+
+/* ─── Navigation ─── */
+
+.nav {
+  position: fixed;
+  z-index: 5;
+  top: 0;
+  left: 0;
+  right: 0;
+  border-bottom: 1px solid var(--line);
+  background: var(--glass);
+  -webkit-backdrop-filter: blur(22px);
+  backdrop-filter: blur(22px);
+}
+
+.nav-inner {
+  width: min(1180px, calc(100vw - 40px));
+  min-height: 72px;
+  margin: 0 auto;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 24px;
+}
+
+.brand-mini {
+  display: flex;
+  align-items: center;
+  gap: 14px;
+  min-width: 0;
+  opacity: 0;
+  pointer-events: none;
+  transform: translateY(-6px);
+  transition: opacity 220ms ease, transform 220ms ease;
+}
+
+.nav.is-scrolled .brand-mini {
+  opacity: 1;
+  pointer-events: auto;
+  transform: translateY(0);
+}
+
+.brand-mini img {
+  width: 128px;
+  height: auto;
+  display: block;
+}
+
+.brand-mini span {
+  color: rgba(245, 245, 247, 0.72);
+  font-size: 12px;
+  font-weight: 300;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  white-space: nowrap;
+}
+
+.join-link {
+  min-height: 36px;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  border: 1px solid rgba(230, 198, 135, 0.4);
+  padding: 0 18px;
+  color: var(--spark-gold);
+  background: rgba(230, 198, 135, 0.04);
+  font-size: 12px;
+  font-weight: 400;
+  letter-spacing: 0.16em;
+  transition: border-color 180ms ease, background 180ms ease, transform 180ms ease;
+}
+
+.join-link:hover {
+  border-color: rgba(230, 198, 135, 0.8);
+  background: rgba(230, 198, 135, 0.1);
+  transform: translateY(-1px);
+}
+
+/* ─── Hero ─── */
+
+.hero {
+  position: relative;
+  z-index: 1;
+  min-height: 92vh;
+  display: grid;
+  place-items: center;
+  padding: 128px 20px 72px;
+}
+
+.hero-inner {
+  width: min(960px, 100%);
+  text-align: center;
+}
+
+.hero-logo {
+  width: min(680px, 88vw);
+  height: auto;
+  margin: 0 auto 28px;
+  display: block;
+  opacity: 0.98;
+}
+
+.hero-action {
+  margin-top: 44px;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  min-height: 46px;
+  border: 1px solid rgba(245, 245, 247, 0.24);
+  padding: 0 28px;
+  color: var(--cosmos-white);
+  background: rgba(245, 245, 247, 0.04);
+  font-size: 14px;
+  font-weight: 300;
+  letter-spacing: 0.18em;
+  transition: border-color 180ms ease, background 180ms ease, color 180ms ease, transform 180ms ease;
+}
+
+.hero-action:hover {
+  border-color: rgba(230, 198, 135, 0.68);
+  color: var(--spark-gold);
+  background: rgba(230, 198, 135, 0.08);
+  transform: translateY(-1px);
+}
+
+/* ─── Utilities ─── */
+
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* ─── Accounts Section ─── */
+
+.accounts {
+  position: relative;
+  z-index: 1;
+  border-top: 1px solid rgba(197, 198, 199, 0.12);
+  padding: 84px 20px 104px;
+  background: linear-gradient(180deg, rgba(11, 12, 16, 0.34), var(--absolute-void));
+}
+
+.accounts-inner {
+  width: min(1080px, 100%);
+  margin: 0 auto;
+}
+
+.section-kicker {
+  margin: 0 0 18px;
+  color: var(--spark-gold);
+  font-size: 12px;
+  font-weight: 300;
+  letter-spacing: 0.24em;
+  text-transform: uppercase;
+}
+
+.section-title {
+  margin: 0;
+  color: var(--cosmos-white);
+  font-size: clamp(28px, 4vw, 52px);
+  font-weight: 250;
+  line-height: 1.12;
+  letter-spacing: 0;
+}
+
+.account-grid {
+  margin-top: 42px;
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+  gap: 16px;
+}
+
+.account-card {
+  min-height: 220px;
+  border: 1px solid var(--line);
+  border-radius: 8px;
+  padding: 24px;
+  background: var(--panel);
+  -webkit-backdrop-filter: blur(16px);
+  backdrop-filter: blur(16px);
+  transition: border-color 180ms ease, background 180ms ease, transform 180ms ease;
+}
+
+.account-card:hover {
+  border-color: rgba(230, 198, 135, 0.34);
+  background: var(--panel-hover);
+  transform: translateY(-2px);
+}
+
+.account-top {
+  display: flex;
+  align-items: flex-start;
+  justify-content: space-between;
+  gap: 18px;
+}
+
+.account-name {
+  margin: 0;
+  color: var(--cosmos-white);
+  font-size: 24px;
+  font-weight: 300;
+  line-height: 1.2;
+}
+
+.account-mark {
+  width: 38px;
+  height: 38px;
+  flex: 0 0 auto;
+  border: 1px solid rgba(230, 198, 135, 0.28);
+  border-radius: 50%;
+  display: grid;
+  place-items: center;
+  color: var(--spark-gold);
+  font-size: 15px;
+  font-weight: 300;
+}
+
+.account-desc {
+  margin: 28px 0 0;
+  color: rgba(245, 245, 247, 0.68);
+  font-size: 15px;
+  font-weight: 300;
+  line-height: 1.8;
+}
+
+.account-meta {
+  margin-top: 28px;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.account-meta span {
+  border: 1px solid rgba(197, 198, 199, 0.14);
+  border-radius: 999px;
+  padding: 6px 10px;
+  color: rgba(197, 198, 199, 0.78);
+  font-size: 12px;
+  font-weight: 300;
+  line-height: 1;
+}
+
+/* ─── Footer ─── */
+
+.footer {
+  position: relative;
+  z-index: 1;
+  border-top: 1px solid rgba(197, 198, 199, 0.1);
+  padding: 28px 20px;
+  color: rgba(197, 198, 199, 0.5);
+  font-size: 12px;
+  font-weight: 300;
+  letter-spacing: 0.12em;
+}
+
+.footer-inner {
+  width: min(1080px, 100%);
+  margin: 0 auto;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 20px;
+  flex-wrap: wrap;
+}
+
+/* ─── Responsive ─── */
+
+@media (max-width: 680px) {
+  .nav-inner {
+    width: min(100vw - 28px, 1180px);
+    min-height: 64px;
+  }
+
+  .brand-mini img {
+    width: 92px;
+  }
+
+  .brand-mini span {
+    display: none;
+  }
+
+  .join-link {
+    min-height: 34px;
+    padding: 0 14px;
+  }
+
+  .hero {
+    min-height: 90vh;
+    padding-top: 108px;
+  }
+
+  .hero-logo {
+    width: min(520px, 92vw);
+    margin-bottom: 22px;
+  }
+
+  .hero-action {
+    width: min(100%, 280px);
+    padding: 0 18px;
+  }
+
+  .accounts {
+    padding: 68px 16px 84px;
+  }
+
+  .account-card {
+    min-height: 210px;
+    padding: 22px;
+  }
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html {
+    scroll-behavior: auto;
+  }
+
+  .join-link,
+  .hero-action,
+  .account-card,
+  .brand-mini {
+    transition: none;
+  }
+}

+ 10 - 0
website/src/main.jsx

@@ -0,0 +1,10 @@
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import "./index.css";
+import App from "./App";
+
+createRoot(document.getElementById("root")).render(
+  <StrictMode>
+    <App />
+  </StrictMode>
+);

+ 14 - 0
website/ssh_cmd.exp

@@ -0,0 +1,14 @@
+#!/usr/bin/expect -f
+set timeout -1
+set host [lindex $argv 0]
+set password [lindex $argv 1]
+set cmd [lindex $argv 2]
+
+spawn ssh -o StrictHostKeyChecking=no root@$host $cmd
+expect {
+    "password:" {
+        send "$password\r"
+        exp_continue
+    }
+    eof
+}

+ 39 - 0
website/vite.config.js

@@ -0,0 +1,39 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import { cp, mkdir } from 'node:fs/promises'
+import { resolve } from 'node:path'
+
+function includeCaseTimeline() {
+  return {
+    name: 'include-case-timeline',
+    apply: 'build',
+    async closeBundle() {
+      const projectRoot = process.cwd()
+      const workspaceRoot = resolve(projectRoot, '..')
+      const caseTarget = resolve(projectRoot, 'dist/slow-alpha/saigon-leverage')
+      const brandTarget = resolve(projectRoot, 'dist/slow-alpha/brand')
+
+      await mkdir(caseTarget, { recursive: true })
+      await mkdir(brandTarget, { recursive: true })
+      await cp(resolve(workspaceRoot, 'case-timeline'), caseTarget, { recursive: true })
+
+      for (const logo of [
+        'logo-chinese.svg',
+        'logo-chinese-light.svg',
+        'logo-mark.svg',
+        'logo-mark-light.svg',
+        'logo-chinese-slogan.svg',
+        'logo-chinese-slogan-light.svg',
+        'logo-chinese-slogan-dark.svg',
+        'logo-chinese-slogan-light-bg.svg',
+      ]) {
+        await cp(resolve(workspaceRoot, 'brand', logo), resolve(brandTarget, logo))
+      }
+    },
+  }
+}
+
+// https://vite.dev/config/
+export default defineConfig({
+  plugins: [react(), includeCaseTimeline()],
+})

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff