Website of the Tsinghua University Student Cluster Competition Team. Built with Astro 7 as a static site and deployed on Cloudflare Pages.
Preview: https://new.sc.team/ or https://scc-homepage.pages.dev/
- Node.js 24 (minimum 22.12.0; Astro 7 and Vite 7 need Node 22 features, do not downgrade)
- pnpm 11
The toolchain is pinned in mise.toml; with mise installed:
mise install
pnpm installpnpm dev # dev server at http://localhost:4321
pnpm build # static build to dist/
pnpm exec astro preview # serve dist/ locallyThe output is plain static HTML. Cloudflare Pages builds this branch and publishes dist/.
src/
├── styles/
│ ├── global.css ← design system: tokens, base styles, shared components, markdown prose
│ ├── fonts.css ← Newsreader @font-face
│ └── plex.css ← IBM Plex Mono @font-face
├── layouts/Base.astro ← HTML shell (head, header, footer)
├── components/
│ ├── SiteHeader.astro ← header and navigation (edit navLinks here)
│ ├── SiteFooter.astro ← footer with build time and commit
│ ├── ChampionTimeline.astro ← championship-years strip used on the home and competitions pages
│ ├── NewsList.astro ← dated news rows, shared by the home page and /news
│ ├── PageIntro.astro ← page title block (eyebrow / title / lead)
│ ├── ResultBadge.astro ← result chip
│ ├── PersonItem.astro ← member row
│ └── Logo.astro ← the team mark as a flat SVG
├── lib/
│ ├── competitions.ts ← typed competition data, statistics, latest results, number words
│ ├── members.ts ← typed member data, slugs, person → participation index
│ └── news.ts ← team posts merged with the press coverage held on each competition
├── data/ ← structured data, the source of truth
│ ├── competitions.json ← results grid by year
│ ├── competition-details.json ← one entry per event: team, problems, coverage, photos
│ ├── members.json ← advisors, current members, alumni
│ ├── news.json ← posts from the team's WeChat account
│ └── publications.json
├── content/pages/ ← markdown pages: collaboration, honors, join
├── assets/competition/<id>/ ← photographs (built into responsive WebP)
├── pages/ ← routes
└── scripts/ ← small vanilla TS: navigation, member dialog
public/
├── fonts/ ← self-hosted Newsreader and IBM Plex Mono (latin subsets)
└── img/ ← logo and favicon
- Add an entry to the year's column (
ASC,ISC,SCorOther) insrc/data/competitions.jsonwith anidsuch assc26. Thetypepicks the chip colour:champion,runner-up,linpack,eprize,special,place,notHeldorabsent. - Add the matching key to
src/data/competition-details.json. Every key becomes a/competition/<id>page. - Put photographs in
src/assets/competition/<id>/01.jpgand list them inphotosas/img/competition/<id>/01.jpg. The first photo becomes the page's opener.
The /news page and the home page's News section merge two sources:
-
Team posts in
src/data/news.json, newest first. One entry per WeChat post:{ "date": "2026-08-29", "title": "An English title, written for this site", "summary": "One or two sentences. Optional.", "url": "https://mp.weixin.qq.com/s/GU3ViQz13EZZ3KgKj0hJmQ", "source": "WeChat" }The team's account is THUSCC on WeChat. It has no public feed, so posts are added by hand: open the post in WeChat, copy its link, and translate the title. Keep the site's English-only rule, the whole entry is written in English.
-
Press coverage, taken automatically from the
newsarray of every entry incompetition-details.jsonand dated to that competition. The outlet is derived from the link's host, so nothing extra is needed when a result is added.
Edit src/data/members.json. Names must match the spelling used in the team lists of competition-details.json exactly, otherwise their competition record will not link up. Two members with the same romanized name are distinguished by class year in parentheses, for example Yang Zhang (2023). Each member gets an anchor such as /members#jidong-zhai.
Edit the file under src/content/pages/. Frontmatter:
---
kicker: Join us # small label above the title
title: Join the team
lead: One-sentence introduction.
---The body is Markdown with inline HTML allowed. Available classes: .cards / .cards-sm (card grid), .card, .card-tag, .card-title, .card-desc, .card-center, .placeholder.
- Create
src/content/pages/<slug>.md - Add it to
navLinksinsrc/components/SiteHeader.astro - Optionally add it to
sectionsinsrc/pages/index.astro
- Palette: plum and gold. Dark renders a plum ground with ivory text; light renders a violet-tinted ivory ground with plum ink. Gold is the accent in both, bright for fills and darker for small text in light so it stays legible, and championships always get a gold marker. The theme follows the system by default, with a light/dark choice in the header.
- Type: Newsreader (variable, optical sizes) for display and names, the system sans for running text, IBM Plex Mono for years, dates and small labels. Both web fonts are self-hosted latin subsets; nothing loads from third-party font hosts.
- Layout: a 1200 px content column, full-bleed photo openers, phone first.
| Branch | Status | Notes |
|---|---|---|
new-website-refactor |
active | 2026 redesign (English) |
new-website-astro |
previous | Astro version before the redesign |
new-website |
frozen | plain HTML/CSS/JS SPA |
master |
legacy | MkDocs version, retired |