From 73efa6a4eb076a6105db4b60ad2bf26da9a7c620 Mon Sep 17 00:00:00 2001 From: Bendik Aagaard Lynghaug Date: Sun, 30 Aug 2026 14:39:58 +0200 Subject: [PATCH] Feature.link: a card's name may point elsewhere An https URL on a feature renders its name as an outbound link - an announcement's programme page, a venue. Validated on load. Co-Authored-By: Claude Fable 5 --- src/app.rs | 11 ++++++++++- src/content.rs | 15 +++++++++++++++ style/main.css | 11 +++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index ce345a7..93c3f7b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -945,7 +945,16 @@ fn AlternativeCard( let name = feature.name.clone(); move || !name.is_empty() }> -

{feature.name.clone()}

+

+ {match feature.link.clone() { + Some(href) => view! { + + {feature.name.clone()} + + }.into_any(), + None => feature.name.clone().into_any(), + }} +

, + /// An https URL the card's name links to - an announcement's + /// programme page, a venue. Plain-text descriptions can't carry + /// links, so this is the one place a card points elsewhere. + #[serde(default)] + pub link: Option, #[serde(default)] pub requirements: Vec, /// Live data this feature pulls in. Read-only unless `transitions` @@ -1017,6 +1022,16 @@ pub fn validate_questions( } } for alternative in &question.alternatives { + for feature in &alternative.features { + if let Some(link) = &feature.link { + if !link.starts_with("https://") { + anyhow::bail!( + "question {:?} feature {:?}: link {:?} must be an https:// URL", + question.id, feature.name, link + ); + } + } + } // A dangling action is a literal dead end: the submit // button navigates to "Nothing here". if let Some(action) = &alternative.action { diff --git a/style/main.css b/style/main.css index bca5bdd..3f79551 100644 --- a/style/main.css +++ b/style/main.css @@ -448,6 +448,17 @@ main.not-found { margin-bottom: 0.15em; } +.feature h3 a { + color: inherit; + text-decoration: none; + border-bottom: 0.06rem solid var(--line); +} + +.feature h3 a:hover { + color: var(--accent); + border-bottom-color: var(--accent); +} + .feature p { color: var(--ink-dim); font-size: 0.95rem;