Compare commits

..
2 Commits
541 changed files with 62 additions and 7795 deletions
+8
View File
@@ -2,3 +2,11 @@ node_modules/
dist/
.astro/
.DS_Store
# Content lives in the ctao/content repo (build overlays it; scripts/link-content.sh locally)
src/content/news/
src/content/pages/
public/uploads/
# Session scratch
.tmp/
-21
View File
@@ -1,21 +0,0 @@
<!doctype html>
<!-- Screenshot probe: headless Chrome clamps --window-size below ~500px, so a
fixed-width iframe gives a true narrow layout viewport. Copied into dist/
by shoot.sh; not part of the site. -->
<meta charset="utf-8">
<title>probe</title>
<style>html,body{margin:0;background:#b0b4c0}iframe{border:0;display:block}</style>
<script>
var q = new URLSearchParams(location.search);
var f = document.createElement('iframe');
f.src = q.get('p') || '/';
f.style.width = (q.get('w') || 390) + 'px';
f.style.height = (q.get('h') || 2000) + 'px';
f.onload = function () {
var s = +(q.get('s') || 0);
// behavior:instant — the site sets scroll-behavior:smooth, which would
// leave the screenshot mid-animation
if (s) f.contentWindow.scrollTo({ top: s, behavior: 'instant' });
};
document.addEventListener('DOMContentLoaded', function () { document.body.appendChild(f); });
</script>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 675 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 669 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 669 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 675 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

-45
View File
@@ -1,45 +0,0 @@
#!/bin/zsh
# Screenshot helper for the CSS polish pass. $1 = output dir (before|after)
# Narrow widths go through dist/__probe.html (a fixed-width iframe): headless
# Chrome clamps --window-size below ~500px, so 360/390/480 shots would silently
# be 500px-wide renders cropped to the window.
set -e
CH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
OUT="$(cd "$(dirname "$0")" && pwd)/$1"
mkdir -p "$OUT"
cp "$(dirname "$0")/__probe.html" "$ROOT/dist/__probe.html"
shot() { # name url w h
"$CH" --headless=new --disable-gpu --hide-scrollbars --window-size=$3,$4 \
--screenshot="$OUT/$1.png" "$2" >/dev/null 2>&1
}
wide() { shot "$1" "http://localhost:4330$2" $3 $4; } # name path w h
narrow() { # name path w h (h = iframe height)
shot "$1" "http://localhost:4330/__probe.html?w=$3&h=$4&p=$2" $(($3 + 20)) $(($4 + 10))
}
W='/news/ctao-and-cabildo-of-la-palma-organise-women-of-ctao-2026'
wide home "/" 1440 2600
narrow home-390 "/" 390 2200
wide news "/news" 1440 2600
narrow news-390 "/news" 390 2400
wide news-768 "/news" 768 2200
wide art6 "/news/6" 1440 2600
narrow art6-390 "/news/6" 390 2600
wide artwomen "$W" 1440 2600
narrow artwomen-390 "$W" 390 2600
wide artwomen-1280 "$W" 1280 2000
wide search "/search?q=lst" 1440 2000
narrow search-390 "/search?q=lst" 390 1800
wide support "/support" 1440 1800
narrow support-360 "/support" 360 1500
wide privacy "/pages/privacy" 1440 1400
narrow privacy-390 "/pages/privacy" 390 1500
wide nf "/404-nonexistent" 1440 1200
narrow nf-390 "/404-nonexistent" 390 1300
wide proposals "/proposals" 1440 1600
narrow proposals-390 "/proposals" 390 1700
wide dashboard "/dashboard" 1440 1600
narrow dashboard-480 "/dashboard" 480 1900
wide login "/login" 1440 1200
narrow login-390 "/login" 390 1100
echo "shots in $OUT"
+4
View File
@@ -65,6 +65,10 @@ missing). Everything else runs inside containers.
10. **[R]** Verify: `curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/`
and `journalctl --user -u ctao-portal-build -n 20` (shows measured build times).
Editor accounts need WRITE access to `ctao/content` (Gitea → repo →
Collaborators, or a team) — public read alone lets them sign in but every
save fails.
## CMS sign-in (Sveltia ↔ Gitea OAuth)
- Gitea OAuth2 app (PKCE, `confidential_client=false`, no secret) with
+13 -8
View File
@@ -43,18 +43,22 @@ head_of() {
code_sha=$(head_of "$CODE_REPO")
content_sha=$(head_of "$CONTENT_REPO")
# Gitea down/unreachable is a transient, not a unit failure — exit 0 quietly
# instead of painting the journal red every 10 s.
for sha in "$code_sha" "$content_sha"; do
if [[ ! "$sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "poll failed (gitea unreachable?) — skipping this tick"
exit 0
fi
done
# instead of painting the journal red every 10 s. Name the repo: a 404 here
# also means "repo/branch missing or renamed", not just "Gitea down".
[[ "$code_sha" =~ ^[0-9a-f]{40}$ ]] || { echo "poll failed for $CODE_REPO@$BRANCH (gitea down, or repo/branch missing) — skipping"; exit 0; }
[[ "$content_sha" =~ ^[0-9a-f]{40}$ ]] || { echo "poll failed for $CONTENT_REPO@$BRANCH (gitea down, or repo/branch missing) — skipping"; exit 0; }
release="${code_sha:0:12}-${content_sha:0:12}" # code+content pin the release
# Skip only if this pair is both recorded AND still present in releases/
# (a deleted release dir must trigger a rebuild, not an eternal skip).
[[ "$release" == "$(cat "$BASE/state/last-built" 2>/dev/null)" \
&& -d "$BASE/releases/$release" ]] && exit 0
# A release that already failed is not retried until either repo moves —
# otherwise one bad commit (e.g. broken frontmatter) turns into a full
# rebuild every 10 s on a shared VM. The failure is loud once, then quiet.
if [[ "$release" == "$(cat "$BASE/state/last-failed" 2>/dev/null)" ]]; then
echo "skipping $release — build failed before; push a fix to retry"
exit 0
fi
echo "building code=$code_sha content=$content_sha"
t0=$(date +%s)
@@ -106,7 +110,8 @@ podman run --rm --network="$BUILD_NETNS" --memory=1g \
npm run build
rm -rf "../releases/$RELEASE"
cp -a dist "../releases/$RELEASE"
'
' || { echo "$release" > "$BASE/state/last-failed"; echo "BUILD FAILED for $release (see above) — will not retry until a new commit"; exit 1; }
rm -f "$BASE/state/last-failed"
# --- 3. Atomic publish: symlink flip via rename(2) — no half-published moment.
# mv -T is GNU (the target host is Rocky); when testing on macOS put a
+1 -1
View File
@@ -4,7 +4,7 @@
# activate a service that is still running.
[Unit]
Description=CTAO portal demo — rebuild if the content repo has new commits
Description=CTAO portal demo — rebuild if the code or content repo has new commits
[Service]
Type=oneshot
+1 -1
View File
@@ -6,7 +6,7 @@
# OnBootSec covers reboot. Enable: systemctl --user enable --now ctao-portal-build.timer
[Unit]
Description=CTAO portal demo — poll the content repo every 10 s
Description=CTAO portal demo — poll the code and content repos every 10 s
[Timer]
OnActiveSec=5
+1 -1
View File
@@ -1,6 +1,6 @@
# Sveltia CMS config — backend: Gitea behind the Cyfronet ingress (HTTPS
# vhost). Editors log in via Gitea OAuth (PKCE, no client secret); edits are
# committed to the ctao/portal repo. Gitea's ROOT_URL and CORS are pinned to
# committed to the ctao/content repo. Gitea's ROOT_URL and CORS are pinned to
# these origins in deploy/ctao-demo-gitea.container.
backend:
name: gitea
+1 -1
View File
@@ -112,7 +112,7 @@
const unit = opts.unit || 'result';
status.textContent = hits.length
? hits.length + ' ' + unit + (hits.length === 1 ? '' : 's') + ' for “' + input.value.trim() + '”'
: 'No results for “' + input.value.trim() + '” — try a shorter or different term.';
: 'No results for “' + input.value.trim() + '”. Try a shorter or different term.';
// Off-DOM build + atomic swap (no transient page-height collapse)
const frag = document.createDocumentFragment();
for (const p of hits) {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Some files were not shown because too many files have changed in this diff Show More