diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9f47642..4b0e437 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,31 +1,59 @@ name: Deploy Website +# Builds the Hugo site and publishes it with GitHub Pages' official deployment +# action. Pull requests only verify that the site builds. +# +# One-time repo setting: Settings > Pages > Build and deployment > Source must +# be "GitHub Actions" (not "Deploy from a branch"). + on: push: branches: - hugo + pull_request: + branches: + - hugo + workflow_dispatch: + +permissions: + contents: read + +# Never cancel a deployment that is already running; superseded pull request +# builds are cancelled. +concurrency: + group: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'pages' }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: - deploy: - runs-on: macos-latest + build: + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - with: - submodules: true # Fetch Hugo themes - fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod + - uses: actions/checkout@v7 - name: Setup Hugo - uses: peaceiris/actions-hugo@v2 + uses: peaceiris/actions-hugo@v3 with: - hugo-version: '0.68.3' - # extended: true + hugo-version: '0.135.0' - name: Build - run: hugo --minify + run: hugo --minify --gc - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + - name: Upload site + uses: actions/upload-pages-artifact@v5 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./public - publish_branch: master \ No newline at end of file + path: ./public + + deploy: + if: github.event_name != 'pull_request' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 diff --git a/.gitignore b/.gitignore index f3347ea..9611f42 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,7 @@ _site/ .jekyll-cache/ .jekyll-metadata -.hugo_build.lock \ No newline at end of file +# Hugo +public/ +resources/ +.hugo_build.lock diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index de5b0b3..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "themes/interimm"] - path = themes/interimm - url = git@github.com:InterImm/hugo-interimm-template.git diff --git a/README.md b/README.md new file mode 100644 index 0000000..081edfa --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# interimm.org + +Source for [interimm.org](https://interimm.org), a bilingual (中文 / English) [Hugo](https://gohugo.io) site. + +## Develop + +Install Hugo (tested with 0.135.0) and run: + +```sh +hugo server +``` + +The site is self-contained: layouts, styles and data live in this repository (there is no theme submodule). + +## Where things live + +| Path | What | +| --- | --- | +| `hugo.yaml` | Site config, including the navigation menu for each language | +| `content/{cn,en}/` | Pages. `cn` is the default language and is served from `/` | +| `data/*.yml` | Content for the home page, archives, activities, institutes and footer, keyed by language | +| `i18n/` | Small UI strings (menu label, 404 text, ...) | +| `layouts/` | Templates | +| `assets/` | CSS and JS, minified and fingerprinted by Hugo at build time | +| `static/` | Files served as-is (images, video, favicons) | + +## Deploy + +Pushing to the `hugo` branch builds the site in GitHub Actions and publishes it with GitHub Pages' official +deployment action. Pull requests against `hugo` only check that the site builds, and the workflow can also be +run by hand from the Actions tab. + +This needs the repository's Pages source set to **GitHub Actions** (Settings > Pages > Build and deployment). + +Analytics is off: the old Universal Analytics property no longer collects data. To enable Google Analytics 4, +uncomment the `services.googleAnalytics.id` block in `hugo.yaml`. diff --git a/assets/css/main.css b/assets/css/main.css new file mode 100644 index 0000000..bfb0e9b --- /dev/null +++ b/assets/css/main.css @@ -0,0 +1,345 @@ +/* InterImm site styles. + Hand-written, no framework. Colours are tokens on :root and switch with the + visitor's system light/dark preference. The home hero is always "space". */ + +/* ---------- tokens ---------- */ +:root { + color-scheme: light dark; + + --bg: #f5f7fb; + --bg-alt: #e9eef7; + --surface: #ffffff; + --text: #121a2b; + --muted: #526078; + --border: #d3dbea; + --link: #1f4fd8; + --focus: #1f4fd8; + --accent: #f5b301; + --accent-hover: #ffc72e; + --accent-text: #1a1300; + --shadow: 0 1px 2px rgb(16 24 40 / 0.06), 0 10px 28px rgb(16 24 40 / 0.07); + + --space-bg: #070b18; + --space-text: #eef2ff; + --space-muted: #b6c2e4; + + --radius: 1rem; + --wrap: 72rem; + --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", + "Microsoft YaHei", "Noto Sans CJK SC", "Noto Sans SC", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Noto Color Emoji"; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg: #0b1020; + --bg-alt: #0f1730; + --surface: #141c33; + --text: #e8edf8; + --muted: #a3afc8; + --border: #26304d; + --link: #8fb4ff; + --focus: #8fb4ff; + --shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 10px 28px rgb(0 0 0 / 0.35); + } + .brand-mark { filter: invert(1); } +} + +/* ---------- base ---------- */ +*, *::before, *::after { box-sizing: border-box; } + +html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; } + +body { + margin: 0; + min-height: 100vh; + min-height: 100dvh; + display: flex; + flex-direction: column; + font-family: var(--font); + font-size: 1.0625rem; + line-height: 1.7; + color: var(--text); + background: var(--bg); +} +main { flex: 1; } + +h1, h2, h3 { line-height: 1.25; margin: 0 0 0.6em; text-wrap: balance; } +p { margin: 0 0 1em; text-wrap: pretty; } +img, video, svg { max-width: 100%; height: auto; } +a { color: var(--link); text-underline-offset: 0.2em; } +a:hover { text-decoration-thickness: 2px; } +ul, ol { margin: 0 0 1em; } + +:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 0.25rem; } + +.wrap { width: min(100% - 2rem, var(--wrap)); margin-inline: auto; } + +.sr-only { + position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; + overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; +} + +.skip-link { + position: absolute; left: 1rem; top: -4rem; z-index: 100; + padding: 0.6rem 1rem; border-radius: 0.6rem; + background: var(--accent); color: var(--accent-text); font-weight: 600; text-decoration: none; +} +.skip-link:focus { top: 1rem; } + +.text-center { text-align: center; } + +/* ---------- header ---------- */ +.site-header { + position: sticky; top: 0; z-index: 50; + background: color-mix(in srgb, var(--bg) 86%, transparent); + -webkit-backdrop-filter: saturate(1.4) blur(12px); + backdrop-filter: saturate(1.4) blur(12px); + border-bottom: 1px solid var(--border); +} +.header-inner { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem 1rem; min-height: 3.75rem; padding-block: 0.5rem; } + +.brand { + display: inline-flex; align-items: center; gap: 0.6rem; + font-weight: 700; font-size: 1.1rem; color: var(--text); text-decoration: none; +} +.brand-mark { border-radius: 0.4rem; } + +.site-nav { display: flex; flex: 1; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.25rem 1rem; } +.nav-list { display: flex; flex-wrap: wrap; align-items: center; gap: 0.15rem; list-style: none; margin: 0; padding: 0; } + +.nav-link, .dropdown > summary { + display: inline-flex; align-items: center; gap: 0.4rem; + padding: 0.45rem 0.75rem; border-radius: 0.6rem; + color: var(--text); font-weight: 500; text-decoration: none; cursor: pointer; +} +.nav-link:hover, .dropdown > summary:hover, .dropdown[open] > summary { background: var(--bg-alt); } +.nav-link[aria-current="page"], .dropdown[data-current] > summary { color: var(--link); font-weight: 600; } +.lang-link { border: 1px solid var(--border); } + +.dropdown { position: relative; } +.dropdown > summary { list-style: none; } +.dropdown > summary::-webkit-details-marker { display: none; } +.dropdown > summary::after { + content: ""; width: 0.4em; height: 0.4em; margin-top: -0.2em; + border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); +} +.dropdown-menu { + position: absolute; top: calc(100% + 0.4rem); left: 0; z-index: 60; + min-width: min(19rem, 90vw); margin: 0; padding: 0.4rem; list-style: none; + background: var(--surface); border: 1px solid var(--border); border-radius: 0.8rem; box-shadow: var(--shadow); +} +.dropdown-menu a { + display: block; padding: 0.5rem 0.75rem; border-radius: 0.5rem; + color: var(--text); text-decoration: none; +} +.dropdown-menu a:hover { background: var(--bg-alt); } +.dropdown-menu a[aria-current="page"] { color: var(--link); font-weight: 600; } + +.nav-toggle { + display: none; margin-left: auto; padding: 0.4rem; border: 1px solid var(--border); border-radius: 0.6rem; + background: transparent; color: var(--text); cursor: pointer; +} + +@media (max-width: 56rem) { + .js .nav-toggle { display: inline-flex; } + .js .site-nav { display: none; flex-basis: 100%; padding-bottom: 0.75rem; } + .js .site-nav.is-open { display: flex; flex-direction: column; align-items: stretch; } + .nav-list { flex-direction: column; align-items: stretch; } + .nav-tools { flex-direction: row; flex-wrap: wrap; padding-top: 0.5rem; border-top: 1px solid var(--border); } + .dropdown-menu { position: static; min-width: 0; margin: 0.2rem 0 0.4rem 0.75rem; box-shadow: none; } +} + +/* ---------- buttons, chips, pills ---------- */ +.btn { + display: inline-flex; align-items: center; justify-content: center; gap: 0.5ch; + padding: 0.55rem 1.15rem; border: 1px solid var(--border); border-radius: 999px; + background: var(--surface); color: var(--text); font: inherit; font-weight: 600; line-height: 1.4; + text-decoration: none; transition: background 0.15s, border-color 0.15s, transform 0.15s; +} +.btn:hover { border-color: var(--link); text-decoration: none; } +.btn-primary { background: var(--accent); border-color: transparent; color: var(--accent-text); } +.btn-primary:hover { background: var(--accent-hover); border-color: transparent; transform: translateY(-1px); } +.btn-lg { padding: 0.85rem 1.75rem; font-size: 1.15rem; } + +.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; list-style: none; margin: 0 0 1.25rem; padding: 0; } +.chips li { + padding: 0.15rem 0.85rem; border: 1px solid currentColor; border-radius: 999px; + font-size: 0.9rem; line-height: 1.6; opacity: 0.85; +} +.chips-small li { padding: 0.05rem 0.65rem; font-size: 0.8rem; color: var(--muted); border-color: var(--border); opacity: 1; } + +.pills { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; list-style: none; margin: 0; padding: 0; } +.pills a { + display: inline-block; padding: 0.4rem 1rem; border: 1px solid var(--border); border-radius: 999px; + background: var(--surface); color: var(--text); text-decoration: none; transition: border-color 0.15s, transform 0.15s; +} +.pills a:hover { border-color: var(--link); color: var(--link); transform: translateY(-1px); } + +/* ---------- home hero ---------- */ +.hero { + position: relative; overflow: hidden; color: var(--space-text); + background: + radial-gradient(48rem 26rem at 88% -8%, rgb(255 122 69 / 0.28), transparent 62%), + radial-gradient(40rem 30rem at -5% 105%, rgb(99 102 241 / 0.32), transparent 62%), + var(--space-bg); +} +/* a cheap, static starfield: a few tiny radial gradients tiled */ +.hero::before { + content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.7; + background-image: + radial-gradient(1.2px 1.2px at 12% 22%, #fff, transparent), + radial-gradient(1px 1px at 31% 71%, #fff, transparent), + radial-gradient(1.4px 1.4px at 52% 14%, #fff, transparent), + radial-gradient(1px 1px at 68% 58%, #fff, transparent), + radial-gradient(1.2px 1.2px at 83% 33%, #fff, transparent), + radial-gradient(1px 1px at 93% 82%, #fff, transparent), + radial-gradient(1px 1px at 22% 92%, #fff, transparent); + background-size: 360px 300px; +} +.hero-inner { + position: relative; display: grid; align-items: center; gap: 2rem 3rem; + grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); + padding-block: clamp(3rem, 8vw, 6rem); +} +.hero h1 { font-size: clamp(2.4rem, 1.2rem + 5vw, 4.25rem); letter-spacing: -0.01em; margin-bottom: 0.3em; } +.hero .lede { font-size: clamp(1.1rem, 1rem + 0.6vw, 1.4rem); color: var(--space-muted); margin-bottom: 1.25rem; } +.hero .chips { margin-bottom: 1.75rem; } +.hero-art { justify-self: center; width: min(100%, 28rem); filter: drop-shadow(0 20px 40px rgb(0 0 0 / 0.45)); } + +@media (max-width: 52rem) { + .hero-inner { grid-template-columns: 1fr; text-align: center; } + .hero .chips { justify-content: center; } + .hero-art { grid-row: 1; width: min(70%, 18rem); } +} + +/* "latest" banner under the hero */ +.latest { background: var(--bg-alt); border-bottom: 1px solid var(--border); font-size: 0.95rem; } +.latest .wrap { display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 0.4rem 0.9rem; padding-block: 0.75rem; } +.badge { + padding: 0.05rem 0.7rem; border-radius: 999px; + background: var(--accent); color: var(--accent-text); font-size: 0.8rem; font-weight: 700; +} +.latest time { color: var(--muted); font-variant-numeric: tabular-nums; } + +/* ---------- sections and cards ---------- */ +.section { padding-block: clamp(2.5rem, 6vw, 4.5rem); } +.section-alt { background: var(--bg-alt); } +.section-title { text-align: center; font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.1rem); margin-bottom: 1.5rem; } + +.card-grid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); } +.card-grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13.5rem), 1fr)); } + +.card { + position: relative; display: flex; flex-direction: column; + padding: 1.5rem; background: var(--surface); border: 1px solid var(--border); + border-radius: var(--radius); box-shadow: var(--shadow); +} +.card > :last-child { margin-bottom: 0; } +.card-title { font-size: 1.25rem; margin-bottom: 0.5rem; } +.card-plain { box-shadow: none; } +.card-action { margin-top: auto; padding-top: 0.75rem; } +.card-icon { margin: 0 0 0.5rem; font-size: 2.25rem; line-height: 1; } +.card-cta { margin: auto 0 0; padding-top: 0.75rem; color: var(--link); font-weight: 600; } +.card-cta span { display: inline-block; transition: transform 0.15s; } +.card-wide { max-width: 52rem; margin-inline: auto; width: 100%; } + +/* whole card is clickable through its title link */ +.card-link-wrap { transition: transform 0.15s, border-color 0.15s; } +.card-link-wrap:hover { transform: translateY(-2px); border-color: var(--link); } +.card-link-wrap:hover .card-cta span { transform: translateX(3px); } +.card-link { color: var(--text); text-decoration: none; } +.card-link::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius); } +.card-link:focus-visible { outline: none; } +.card-link:focus-visible::after { outline: 3px solid var(--focus); outline-offset: 2px; } + +.card-media { padding: 0; overflow: hidden; } +.card-media .card-image { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--bg-alt); } +.card-media .card-body { padding: 1.25rem 1.5rem 1.5rem; } + +.stack { display: grid; gap: 1.5rem; } +.figure { margin: 1rem 0 0; padding: 1rem; background: #fff; border-radius: 0.75rem; text-align: center; } +.figure img { max-height: 32rem; width: auto; margin-inline: auto; } + +/* ---------- inner pages ---------- */ +.page-hero { + padding-block: clamp(2.5rem, 7vw, 4.5rem); text-align: center; + background: linear-gradient(180deg, var(--bg-alt), var(--bg)); + border-bottom: 1px solid var(--border); +} +.page-hero h1 { font-size: clamp(1.9rem, 1.2rem + 3vw, 3rem); margin-bottom: 0.3em; } +.page-hero .lede { max-width: 42rem; margin: 0 auto 1rem; color: var(--muted); font-size: 1.15rem; } +.page-hero .chips { justify-content: center; margin: 0.75rem 0 0; color: var(--muted); } + +.prose { max-width: 46rem; } +.prose > * { margin-inline: 0; } +.prose h2 { margin-top: 2em; font-size: 1.6rem; } +.prose h3 { margin-top: 1.6em; font-size: 1.25rem; } +.prose img, .prose video { border-radius: 0.75rem; } +.prose-wide { max-width: 64rem; } +.prose-wide > p, .prose-wide > h2, .prose-wide > h3, .prose-wide > ul, .prose-wide > ol { max-width: 46rem; margin-inline: auto; } +.wrap.prose { margin-inline: auto; } +:lang(zh) { line-height: 1.85; } +:lang(zh) .card p, :lang(zh) .timeline p { line-height: 1.75; } + +/* about page: media + text side by side */ +.split { display: grid; gap: 2rem 3rem; align-items: center; grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); margin-top: 2rem; } +.split-media { margin: 0; } +.split-media video { display: block; width: 100%; aspect-ratio: 16 / 9; background: #000; border-radius: var(--radius); box-shadow: var(--shadow); } +.lede-strong { padding-left: 1rem; border-left: 4px solid var(--accent); font-size: 1.2rem; font-weight: 700; } + +.embed { aspect-ratio: 16 / 9; min-height: 18rem; } +.embed iframe { width: 100%; height: 100%; border: 0; border-radius: var(--radius); background: var(--bg-alt); } + +/* ---------- activity timeline ---------- */ +.timeline { position: relative; max-width: 46rem; margin: 0 auto; padding: 0 0 0 3.25rem; list-style: none; } +.timeline::before { content: ""; position: absolute; left: 1.2rem; top: 0.5rem; bottom: 0.5rem; width: 2px; background: var(--border); } +.timeline-item { position: relative; padding-bottom: 2.25rem; } +.timeline-item:last-child { padding-bottom: 0; } +.timeline-icon { + position: absolute; left: -3.25rem; top: 0; width: 2.5rem; height: 2.5rem; + display: grid; place-items: center; font-size: 1.25rem; + background: var(--surface); border: 2px solid var(--border); border-radius: 50%; +} +.timeline-date { margin: 0; color: var(--muted); font-size: 0.9rem; font-variant-numeric: tabular-nums; } +.timeline-title { margin: 0.1rem 0 0.35rem; font-size: 1.2rem; } +.timeline-title a { color: var(--text); text-decoration-color: var(--border); } +.timeline-title a:hover { color: var(--link); } +.timeline-item p:last-child { margin-bottom: 0; } + +/* ---------- image map (city plans) ---------- */ +.imagemap { margin: 0 0 2rem; } +.imagemap-canvas { height: min(70vh, 34rem); border: 1px solid var(--border); border-radius: var(--radius); background: var(--space-bg); } +.imagemap figcaption { margin-top: 0.5rem; color: var(--muted); font-size: 0.9rem; text-align: center; } +.map-pin { background: none; border: 0; } +.map-pin svg { filter: drop-shadow(0 2px 3px rgb(0 0 0 / 0.5)); } +.leaflet-popup-content { font-family: var(--font); line-height: 1.5; } +.leaflet-popup-content h3 { margin: 0 0 0.35rem; font-size: 1rem; color: #121a2b; } +.leaflet-popup-content p { margin: 0 0 0.5rem; color: #2b364d; } +.leaflet-popup-content a { color: #1f4fd8; word-break: break-all; } + +/* ---------- footer ---------- */ +.site-footer { margin-top: 2rem; padding-block: 2.5rem 1.5rem; background: var(--bg-alt); border-top: 1px solid var(--border); color: var(--muted); font-size: 0.95rem; } +.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); } +.footer-col h2 { margin-bottom: 0.6rem; font-size: 1rem; color: var(--text); } +.footer-col ul { margin: 0; padding: 0; list-style: none; } +.footer-col li { margin-bottom: 0.3rem; } +.footer-col a { color: var(--muted); } +.footer-col a:hover { color: var(--link); } +.footer-legal { margin: 2rem 0 0; padding-top: 1rem; border-top: 1px solid var(--border); font-size: 0.85rem; } + +/* ---------- 404 ---------- */ +.not-found { min-height: 55vh; display: grid; place-items: center; background: none; border: 0; } +.not-found .code { margin: 0; font-size: clamp(4.5rem, 18vw, 10rem); font-weight: 800; line-height: 1; color: var(--accent); } + +/* ---------- motion and print ---------- */ +@media (prefers-reduced-motion: reduce) { + html { scroll-behavior: auto; } + *, *::before, *::after { transition: none !important; animation: none !important; } +} + +@media print { + .site-header, .site-footer, .skip-link, .latest { display: none; } + body { background: #fff; color: #000; } + .hero { background: none; color: #000; } +} diff --git a/assets/js/imagemap.js b/assets/js/imagemap.js new file mode 100644 index 0000000..9b9afce --- /dev/null +++ b/assets/js/imagemap.js @@ -0,0 +1,55 @@ +// Renders the `imagemap` shortcode: a Leaflet map over a flat image with +// clickable markers. Marker data comes from the page's front matter. +(() => { + const el = document.getElementById('imagemap'); + const source = document.getElementById('imagemap-markers'); + if (!el || !source || !window.L) return; + + const markers = JSON.parse(source.textContent); + const width = Number(el.dataset.width); + const height = Number(el.dataset.height); + const bounds = [[0, 0], [height, width]]; + + const map = L.map(el, { + crs: L.CRS.Simple, + attributionControl: false, + scrollWheelZoom: false, // don't hijack page scrolling until the map is focused + }); + L.imageOverlay(el.dataset.image, bounds, { alt: el.dataset.alt }).addTo(map); + map.fitBounds(bounds); + map.on('focus', () => map.scrollWheelZoom.enable()); + map.on('blur', () => map.scrollWheelZoom.disable()); + + const pin = L.divIcon({ + className: 'map-pin', + html: '', + iconSize: [28, 28], + iconAnchor: [14, 14], + popupAnchor: [0, -14], + }); + + const popupFor = (m) => { + const box = document.createElement('div'); + const title = document.createElement('h3'); + title.textContent = m.name; + const text = document.createElement('p'); + text.textContent = m.description; + box.append(title, text); + if (m.link) { + const a = document.createElement('a'); + a.href = m.link; + a.target = '_blank'; + a.rel = 'noopener'; + a.textContent = m.link.replace(/^\w+:\/\//, '').replace(/\/$/, ''); + a.setAttribute('aria-label', `${a.textContent} ${el.dataset.newTab}`); + box.append(a); + } + return box; + }; + + markers.forEach((m) => { + L.marker(m.position, { icon: pin, title: m.name, alt: m.name, riseOnHover: true }) + .bindPopup(popupFor(m), { maxWidth: 320 }) + .addTo(map); + }); +})(); diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..b583b9d --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,40 @@ +// Progressive enhancement for the site header. Without JavaScript the menu is +// simply always visible and the dropdowns are native
elements. +(() => { + const toggle = document.querySelector('.nav-toggle'); + const nav = document.getElementById('site-nav'); + const dropdowns = Array.from(document.querySelectorAll('.dropdown')); + + const setMenu = (open) => { + toggle.setAttribute('aria-expanded', String(open)); + nav.classList.toggle('is-open', open); + }; + + if (toggle && nav) { + toggle.addEventListener('click', () => { + setMenu(toggle.getAttribute('aria-expanded') !== 'true'); + }); + } + + const closeDropdowns = (except) => { + dropdowns.forEach((d) => { if (d !== except) d.open = false; }); + }; + + // One dropdown open at a time; close on outside click and on Escape. + dropdowns.forEach((d) => { + d.addEventListener('toggle', () => { if (d.open) closeDropdowns(d); }); + }); + document.addEventListener('click', (e) => { + if (!e.target.closest('.dropdown')) closeDropdowns(); + }); + document.addEventListener('keydown', (e) => { + if (e.key !== 'Escape') return; + const open = dropdowns.find((d) => d.open); + closeDropdowns(); + if (open) open.querySelector('summary').focus(); + else if (toggle && toggle.getAttribute('aria-expanded') === 'true') { + setMenu(false); + toggle.focus(); + } + }); +})(); diff --git a/config.yaml b/config.yaml deleted file mode 100644 index 96e9e7f..0000000 --- a/config.yaml +++ /dev/null @@ -1,149 +0,0 @@ -baseurl: "/" # Controls base URL -languageCode: "cn" # Controls html lang attribute -title: "星际移民中心" # Homepage title and page title suffix -paginate: 12 # Number of posts to show before paginating -theme: "interimm" # to use as default theme -IsMultiLingual: true - -DefaultContentLanguage: "cn" - -enableRobotsTXT: true # Suggested, it generates a robots.txt -googleAnalytics: "UA-50146153-1" # Optional, add tracking Id for analytics -disqusShortname: "" # Optional, add Disqus shortname for comments -# SectionPagesMenu: "main" # Enable menu system for lazy bloggers - -taxonomies: - category: categories - keyword: keywords - -menu: - main: - - name: more - weight: 1 - identifier: more - url: "#" - children: - - name: 机构 - url: /institutes/ - -languages: - en: - title: InterImm - contentDir: content/en - params: - description: "by Interplanetary Immigration Agency" - splash: "/images/home/undraw_Taken_if77.svg" - home: - primary_button: - title: Welcome on Board - link: /guide - tags: - - "Developing Spacefaring Civilization" - - "Connecting Mars and Earth" - menu: - topleft: - - name: Archives - url: /archives/ - children: - - name: The Book of Interplanetary Civilization - url: http://book.interimm.org/ - - name: The Book of Exoplanets - url: http://exoplanets.interimm.org/ - - name: Space Yellow Page - url: http://interimm.org/hub/ - - name: More - url: /en/archives - - name: Planetary University - url: http://planiversity.interimm.org/ - topright: - - name: - icon: fa fa-calendar-check - url: "/en/activities" - - name: - url: http://interimm.org/mars-map/ - icon: fa fa-map-marked-alt - - name: - icon: fas fa-th - url: "#" - children: - - name: Institutes - url: /en/institutes/ - - name: Timeline - url: http://timeline.interimm.org/ - - name: Magazine - url: http://magazine.interimm.org/ - - listings: - title: "Archives" - github: "interimm/hugo-interimm-template" - editURL: "https://github.com/InterImm/hugo-interimm-template/edit/master/content/" - cn: - contentDir: content/cn - -params: - theme_variant: "lux" # possible value for the theme_variant `cerulean,cosmo,cyborg,darkly,flatly,journal,litera,lumen,lux,materia,minty,pulse,sandstone,simplex,slate,solar,spacelab,superhero,united,yeti` - description: "星际移民中心直属" - splash: "/images/home/undraw_Taken_if77.svg" - home: - primary_button: - title: 欢迎登船 - link: /archives/ - tags: - - "星际开发研究" - - "火星移民服务" - menu: - topleft: - - name: 档案馆 - url: /archives/ - children: - - name: 星际移民之书 - url: http://book.interimm.org/ - - name: 系外行星文档 - url: http://exoplanets.interimm.org/ - - name: 太空企业 - url: http://interimm.org/hub/ - - name: 更多 - url: /archives - - name: 行星大学 - url: http://planiversity.interimm.org/ - topright: - - name: - icon: fa fa-calendar-check - url: "/activities" - - name: - url: http://interimm.org/mars-map/ - icon: fa fa-map-marked-alt - - name: - icon: fas fa-th - url: "#" - children: - - name: 机构 - url: /institutes/ - - name: 时间线 - url: http://timeline.interimm.org/ - - name: 星海航纪 - url: http://magazine.interimm.org/ - - listings: - title: "档案馆" - powered_by: "love" # Optional, controls name display on footer - hide_author: false # Optional, set true to hide author name on posts - images: # Suggested, controls default OpenGraph images controls author name display on meta tag - github: "interimm" # Optional, to display link to github account in menu bar - twitter: "" # Optional, to display link to twitter account in menu bar - author: "InterImm" - editURL: "https://github.com/InterImm/interimm.github.io/edit/master/content/" - - -outputFormats: - Data: - baseName: "data" - isPlainText: true - mediaType: "application/json" - notAlternative: true - -outputs: - home: - - "HTML" - - "RSS" - - "Data" diff --git a/content/cn/about.md b/content/cn/about.md index 165b983..333a8ae 100644 --- a/content/cn/about.md +++ b/content/cn/about.md @@ -1,24 +1,25 @@ --- title: 关于星际移民中心 +description: 星际移民中心是星际移民局的核心机构,致力于太阳系开发的研究和服务。 +wide: true tags: - 人类太空文明 - 火星开发 - 开源科幻和科普 -layout: about --- {{< rawhtml >}} -

星际移民中心是星际移民局的核心机构

+

星际移民中心是星际移民局的核心机构

-
-
-