em dashes out of skeleton copy (titles use ' - ', prose reworded); split hardening after review: poll errors name the failing repo, failed release is not retried until a new commit, link-content checks all three dirs, editor write-access note, two-repo unit descriptions and comments
This commit is contained in:
@@ -14,8 +14,9 @@ const news = defineCollection({
|
||||
date: z.coerce.date(),
|
||||
category: z.string().default('news'),
|
||||
author: z.string().default('CTAO'),
|
||||
// Public-path string, e.g. "/uploads/foo.jpg" — Sveltia uploads media to
|
||||
// public/uploads, which Astro's image() helper can't validate (src/ only).
|
||||
// Public-path string, e.g. "/uploads/foo.jpg" — media lives in the
|
||||
// content repo's uploads/, overlaid to public/uploads at build time,
|
||||
// which Astro's image() helper can't validate (src/ only).
|
||||
cover: z.string().optional(),
|
||||
// BCP-47 tag when an article is not in English (e.g. "pl") — set as lang
|
||||
// on the <article> element so screen readers pick the right voice.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import '../styles/global.css';
|
||||
// `ambient` opts a page into the whole-page drifting brand wash (home only — see DESIGN.md)
|
||||
// `type`/`image` feed the social meta: articles pass type="article" + their cover.
|
||||
const { title = 'CTAO Science Portal', description = 'CTAO Science Portal — demo', ambient = false, type = 'website', image } = Astro.props;
|
||||
const { title = 'CTAO Science Portal', description = 'CTAO Science Portal demo', ambient = false, type = 'website', image } = Astro.props;
|
||||
// Absolute URLs for canonical/OG/RSS (head pattern from the official Astro
|
||||
// blog template). `site` comes from astro.config.mjs and is always set.
|
||||
const site = Astro.site;
|
||||
@@ -43,7 +43,7 @@ const links = [
|
||||
<meta property="og:url" content={canonical} />
|
||||
<meta property="og:image" content={ogImage} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<link rel="alternate" type="application/rss+xml" title="CTAO Science Portal — News" href={new URL('/rss.xml', site)} />
|
||||
<link rel="alternate" type="application/rss+xml" title="CTAO Science Portal News" href={new URL('/rss.xml', site)} />
|
||||
<link rel="sitemap" href="/sitemap.xml" />
|
||||
<link rel="icon" href="/brand/CTAO_Logo_positive.svg" type="image/svg+xml" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
@@ -59,7 +59,7 @@ const links = [
|
||||
<a class="skip" href="#main">Skip to content</a>
|
||||
<header class="site-header">
|
||||
<div class="container nav">
|
||||
<a class="brand" href="/" aria-label="CTAO Science Portal — home">
|
||||
<a class="brand" href="/" aria-label="CTAO Science Portal, home">
|
||||
<img src="/brand/AAFF_CTAO_Logo_RGB_Monochrome-negative.svg" alt="CTAO" />
|
||||
<span class="brand-sub">Science Portal</span>
|
||||
</a>
|
||||
@@ -164,7 +164,7 @@ const links = [
|
||||
<div class="container">
|
||||
<div class="foot-top">
|
||||
<img src="/brand/AAFF_CTAO_Logo_RGB_Monochrome-negative.svg" alt="CTAO" />
|
||||
<p>CTAO Science Portal — demo by Cyfronet (SUSS-PORT team).</p>
|
||||
<p>CTAO Science Portal demo by Cyfronet (SUSS-PORT team).</p>
|
||||
</div>
|
||||
{/* Order: action/utility first, legal middle, meta last (GOV.UK/NN-g
|
||||
footer anatomy). Spec §3.3.1 requires the five items, not an order. */}
|
||||
@@ -183,7 +183,7 @@ const links = [
|
||||
{/* The real brand flash — path taken from the official logo SVG (BRAND D.4).
|
||||
Sole decorative accent in this view; static by design. */}
|
||||
<svg class="flash" viewBox="85.3 15 15 15" aria-hidden="true"><path fill="currentColor" d="M94.7,23.8c1-1.4,3.3-2.1,5.2-2.7c-2,0.1-4.4,0.3-5.8-0.6c-1.4-1-2.1-3.3-2.7-5.2c0.1,2,0.3,4.4-0.6,5.8c-1,1.4-3.3,2.1-5.2,2.7c2-0.1,4.4-0.3,5.8,0.6c1.4,1,2.1,3.3,2.7,5.2C93.9,27.6,93.7,25.2,94.7,23.8z"/></svg>
|
||||
<span>© 2026 CTAO — demonstration, not an official service.</span>
|
||||
<span>© 2026 CTAO. Demonstration, not an official service.</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import Base from '../layouts/Base.astro';
|
||||
---
|
||||
<Base title="CTAO Science Portal — Page not found" description="This page does not exist">
|
||||
<Base title="CTAO Science Portal - Page not found" description="This page does not exist">
|
||||
{/* Document archetype (DESIGN.md): the document IS the page — h1, one line,
|
||||
recovery links, and a real GET search form as the way forward. */}
|
||||
<div class="container article-layout">
|
||||
@@ -10,8 +10,8 @@ import Base from '../layouts/Base.astro';
|
||||
<div class="prose">
|
||||
{/* Keep "the <a>" on one line: the compiler drops the whitespace at a
|
||||
line break before a tag, which glued "the" to the link text. */}
|
||||
<p>The address may be mistyped or the page may have moved —
|
||||
go to the <a href="/">home page</a> or browse <a href="/news">all news</a>.</p>
|
||||
<p>The address may be mistyped or the page may have moved.
|
||||
Go to the <a href="/">home page</a> or browse <a href="/news">all news</a>.</p>
|
||||
</div>
|
||||
<form class="search-form" role="search" action="/search" method="get">
|
||||
<label class="sr-only" for="nf-q">Search news</label>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>CTAO — Content Editor</title>
|
||||
<title>CTAO Content Editor</title>
|
||||
<meta name="theme-color" content="#00004A" />
|
||||
<link rel="icon" href="/brand/CTAO_Logo_positive.svg" type="image/svg+xml" />
|
||||
<style>
|
||||
|
||||
@@ -4,7 +4,7 @@ import Base from '../layouts/Base.astro';
|
||||
// and help-desk tickets. No integrations exist yet, so panels show empty
|
||||
// states instead of fabricated sample rows (source-documents-only rule).
|
||||
---
|
||||
<Base title="CTAO Science Portal — Dashboard" description="User dashboard (mock)">
|
||||
<Base title="CTAO Science Portal - Dashboard" description="User dashboard (mock)">
|
||||
<section class="band--moon">
|
||||
<header class="container page-head">
|
||||
<h1>Dashboard</h1>
|
||||
|
||||
@@ -25,9 +25,9 @@ const services = [
|
||||
icon: '<circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4"/><path d="m5.7 5.7 3.5 3.5m5.6 0 3.5-3.5m0 12.6-3.5-3.5m-5.6 0-3.5 3.5"/>' },
|
||||
// Two subdued planned tiles complete the 2×3 grid (an orphan 4th tile in a
|
||||
// 3-col grid reads broken); the remaining TBD services stay on the quiet line.
|
||||
{ title: 'Software', planned: true, desc: 'Landing page for CTAO software — planned.',
|
||||
{ title: 'Software', planned: true, desc: 'Landing page for CTAO software (planned).',
|
||||
icon: '<rect x="3" y="4.5" width="18" height="15" rx="2"/><path d="m7 9.5 3 2.5-3 2.5M12.5 15H17"/>' },
|
||||
{ title: 'Documentation', planned: true, desc: 'CTAO user documentation — planned.',
|
||||
{ title: 'Documentation', planned: true, desc: 'CTAO user documentation (planned).',
|
||||
icon: '<path d="M12 6.7C10.6 5.2 8.6 4.5 5.7 4.5H4v13.6h1.7c2.9 0 4.9.7 6.3 2.2 1.4-1.5 3.4-2.2 6.3-2.2H20V4.5h-1.7c-2.9 0-4.9.7-6.3 2.2z"/><path d="M12 6.7v13.6"/>' },
|
||||
];
|
||||
const planned = ['Scheduling', 'Science alerts'];
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
import Base from '../layouts/Base.astro';
|
||||
---
|
||||
<Base title="CTAO Science Portal — Sign in" description="Sign in via CTAO AAI (mock)">
|
||||
<Base title="CTAO Science Portal - Sign in" description="Sign in via CTAO AAI (mock)">
|
||||
<section class="auth-band">
|
||||
<div class="band-bg" aria-hidden="true"></div>
|
||||
<div class="auth-card">
|
||||
<img class="auth-logo" src="/brand/CTAO_Logo_positive.svg" alt="CTAO" />
|
||||
<h1>Sign in</h1>
|
||||
{/* Auth pages are scanned, not read — one line, no reassurance prose */}
|
||||
<p class="muted">Use your CTAO account — single sign-on via CTAO AAI.</p>
|
||||
<p class="muted">Use your CTAO account (single sign-on via CTAO AAI).</p>
|
||||
<button class="btn btn-wide" type="button">Continue with your CTAO account</button>
|
||||
<p class="notice">No account? <a>Register via CTAO AAI</a></p>
|
||||
</div>
|
||||
|
||||
@@ -45,8 +45,8 @@ for (let n = 1; n <= page.lastPage; n++) {
|
||||
const hrefFor = (n) => (n === 1 ? '/news' : `/news/${n}`);
|
||||
---
|
||||
<Base
|
||||
title={first ? 'CTAO Science Portal — News' : `CTAO Science Portal — News, page ${page.currentPage}`}
|
||||
description={first ? 'News and announcements of the CTAO' : `News and announcements of the CTAO — page ${page.currentPage} of ${page.lastPage}`}
|
||||
title={first ? 'CTAO Science Portal - News' : `CTAO Science Portal - News, page ${page.currentPage}`}
|
||||
description={first ? 'News and announcements of the CTAO' : `News and announcements of the CTAO, page ${page.currentPage} of ${page.lastPage}`}
|
||||
>
|
||||
{/* Section-landing archetype: white head, display Galaxy h1 + standfirst
|
||||
(the navy band is reserved for / and /login — DESIGN.md). */}
|
||||
@@ -56,7 +56,7 @@ const hrefFor = (n) => (n === 1 ? '/news' : `/news/${n}`);
|
||||
</header>
|
||||
|
||||
<section class="container page">
|
||||
<h2 class="sr-only">{first ? 'All news' : `All news — page ${page.currentPage}`}</h2>
|
||||
<h2 class="sr-only">{first ? 'All news' : `All news, page ${page.currentPage}`}</h2>
|
||||
<div class="grid">
|
||||
{page.data.map((post, i) => <NewsCard post={post} featured={first && i === 0} />)}
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@ const { Content, headings } = await render(post);
|
||||
const toc = headings.filter((h) => h.depth === 2 || h.depth === 3);
|
||||
const readMin = readMinOf(post);
|
||||
---
|
||||
<Base title={`${post.data.title} — CTAO`} description={post.data.description} type="article" image={post.data.cover && encodeURI(post.data.cover)}>
|
||||
<Base title={`${post.data.title} - CTAO`} description={post.data.description} type="article" image={post.data.cover && encodeURI(post.data.cover)}>
|
||||
{/* Reading progress (scroll-driven CSS, no JS) — styled only where
|
||||
animation-timeline is supported; elsewhere it stays an empty div. */}
|
||||
<div class="read-progress" aria-hidden="true"></div>
|
||||
|
||||
@@ -10,7 +10,7 @@ export async function getStaticPaths() {
|
||||
const { page } = Astro.props;
|
||||
const { Content } = await render(page);
|
||||
---
|
||||
<Base title={`${page.data.title} — CTAO Science Portal`} description={page.data.description}>
|
||||
<Base title={`${page.data.title} - CTAO Science Portal`} description={page.data.description}>
|
||||
{/* Same wrapper pattern as news/[slug] (never .container and .article on
|
||||
one element — both set max-width and would depend on rule order). */}
|
||||
<div class="container article-layout">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import Base from '../layouts/Base.astro';
|
||||
---
|
||||
<Base title="CTAO Science Portal — Proposals" description="Observation proposals — Proposal Handling System integration (planned)">
|
||||
<Base title="CTAO Science Portal - Proposals" description="Observation proposals: Proposal Handling System integration (planned)">
|
||||
<section class="band--moon">
|
||||
<header class="container page-head">
|
||||
<h1>Observation proposals</h1>
|
||||
@@ -13,15 +13,15 @@ import Base from '../layouts/Base.astro';
|
||||
hand-off instead of imitating their submission UI. */}
|
||||
<div class="panel panel--narrow">
|
||||
<h2 class="panel-title">Proposal Handling System</h2>
|
||||
<p>Submitting observation proposals — including Target of Opportunity (ToO)
|
||||
and multi-wavelength (MWL) requests — happens in the Proposal Handling
|
||||
System, built by the APC team and integrated into this portal.</p>
|
||||
<p>Submitting observation proposals, including Target of Opportunity (ToO)
|
||||
and multi-wavelength (MWL) requests, happens in the Proposal Handling
|
||||
System. That system is built by the APC team and integrated into this portal.</p>
|
||||
<p>What the portal contributes:</p>
|
||||
<ul class="panel-list">
|
||||
<li>This menu entry, with a single sign-on hand-off (CTAO AAI).</li>
|
||||
<li>Proposal status feedback in your <a href="/dashboard">Dashboard</a>.</li>
|
||||
</ul>
|
||||
<button class="btn" type="button" disabled>Open the Proposal Handling System — integration planned</button>
|
||||
<button class="btn" type="button" disabled>Open the Proposal Handling System (integration planned)</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -29,7 +29,7 @@ export async function GET(context) {
|
||||
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>CTAO Science Portal — News</title>
|
||||
<title>CTAO Science Portal News</title>
|
||||
<link>${new URL('/news', site).href}</link>
|
||||
<description>News and announcements of the Cherenkov Telescope Array Observatory</description>
|
||||
<language>en</language>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import Base from '../layouts/Base.astro';
|
||||
---
|
||||
<Base title="CTAO Science Portal — Search" description="Search CTAO news and announcements">
|
||||
<Base title="CTAO Science Portal - Search" description="Search CTAO news and announcements">
|
||||
{/* Utility archetype: ONE surface per page — Moon canvas from the landing
|
||||
head down (borderless cards/panels pop against it); editorial pages stay
|
||||
all-white. No mid-page surface seams (DESIGN.md). */}
|
||||
|
||||
@@ -8,7 +8,7 @@ const channels = [
|
||||
{ title: 'Mailing lists', desc: 'Announcements and topical mailing lists.' },
|
||||
];
|
||||
---
|
||||
<Base title="CTAO Science Portal — Support" description="User support: help desk, FAQ, forum, mailing lists (mock)">
|
||||
<Base title="CTAO Science Portal - Support" description="User support: help desk, FAQ, forum, mailing lists (mock)">
|
||||
<section class="band--moon">
|
||||
<header class="container page-head">
|
||||
<h1>User Support</h1>
|
||||
|
||||
Reference in New Issue
Block a user