Repository navigation
Say what we do in words people already use - #25
Open
drmowinckels wants to merge 22 commits into
Open
drmowinckels wants to merge 22 commits into
drmowinckels wants to merge 22 commits into
Conversation
|
✅ Preview deployed at https://25--capro-uio.netlify.app |
drmowinckels
force-pushed
the
service-copy
branch
from
October 16, 2026 18:11
d6be710 to
32ce500
Compare
✅ Accessibility: no issuesaxe-core over 19 routes × 2 viewports (one page per layout), plus 69 manual checks. All 69 manual checks passed. Automated tooling catches roughly a third of accessibility problems. A clean run is a floor, not a ceiling. |
drmowinckels
force-pushed
the
service-copy
branch
from
October 16, 2026 20:02
32ce500 to
5f75afb
Compare
The old entries described a category. A researcher reading one could not tell whether their problem was in it, whether we would do the work or advise on it, or what they would end up holding. Each of the seven now leads with the problem the reader arrived with, lists the situations that produce it, and says what you get. The category name stays as a secondary label, so someone who does know the term can still find it. Named systems do a lot of the work: someone who has never heard "data engineering" knows what "I have a Nettskjema and can't get the data out" means. Every name used already appears elsewhere on the site. Also fixes a pre-existing inconsistency where the English list had Workshops but no Data capture, and the Norwegian had Datafangst but no separate processing entry. The two languages advertised different services; both now carry the same seven. Drops the duplicated skipToContent block in both i18n files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"Data flow and processing 90%, Registry data handling 55%" told a reader nothing they could act on, and the numbers were not sourced from anything. A visitor trying to work out whether we can help them cannot use a percentage. It is now three plain lists — the languages and tools we use, the UiO and national systems we work inside, and the kinds of data we handle. Someone with MRI data on TSD can now recognise themselves on the page, which is the whole point. Drops the now-unused progress bar CSS. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
People kept arriving unsure whether we could help them, and the copy was a large part of why. The site described itself in terms a reader only understands if they already know what we do: "data engineering", "data science team", "FAIR principles", "containerization", "integrated solutions", "standardized data output". Hero and contact: the hero now names the concrete things we do — tidy up messy data, set up collection, make analyses run twice, get jobs onto university servers, teach groups to do it themselves — rather than "capture, process, manage and analyse". Contact says you do not need to know the technical name for your problem, because that is the actual barrier. Feature section: "Integrated Solutions / Standardized Data Output / Customization on Demand" said nothing a reader could act on. It now answers what working with us is like — we use systems UiO already pays for, you own what we build, we can teach instead of doing, and you can start with a single hour. Pricing: explains that the rate depends on how close you are to the department, and that computing time is applied for separately. The bullets describe what you get rather than listing line items. CTA, portfolio, team and testimonials follow the same rule: ordinary words, concrete claims, and an explicit invitation to ask even if your problem is not on the list. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
drmowinckels
force-pushed
the
service-copy
branch
from
October 19, 2026 10:09
5f75afb to
254bb17
Compare
Five lines of body copy over a photographic background is hard to read, and the list of services below it already carries the detail. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"What you get" was a hard-coded h4 under a problem heading that is an h2 on /services/, so every item skipped h3. axe flagged 28 instances across the two language versions. The label now tracks the item level the same way the problem heading does, so the pair stays one step apart whichever level the section sits at. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The copy claimed "anyone at UiO can ask", which told a public agency or a company that the site was not for them — while the pricing table has had non-commercial and commercial rates all along. The two contradicted each other, and the copy was the wrong one. UiO stays the primary audience, since that is where most of the work comes from, but the hero, services intro, contact, CTA and pricing now all say plainly that public agencies and private companies can hire us. "We use what UiO already pays for" also assumed a UiO reader; it now covers working inside whatever systems you already have. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The hero ended on who we do and don't work for, and the contact and CTA both ended on who gets charged. Neither is what someone reads those for, and the "free for some, billed for others" construction read as a disclaimer rather than an invitation. Getting in touch is free for everyone, so saying otherwise next to the contact form was also just wrong. The rates live on the pricing page, which is where someone goes looking for them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Seven identically shaped blocks down the left half of the page, with the right 40% empty, gave a reader nothing to navigate by and no sense of where one item ended and the next began. Each item is now a two-column grid: the problem, its category and a numeral on the left, the evidence and the payoff on the right. The numeral is decorative and aria-hidden — the items are not a sequence and nothing refers to them by number; it is there to give the eye something to count. "What you get" picks up an accent rule, since that is what a reader is scanning for. Collapses to one column below 900px. Also fixes the h1 promotion under `hugo server`. section-title.html marks the page's h1 as used via Scratch, which outlives a render, so after the first rebuild the flag stayed set and no page emitted an h1 again. Production builds render each page once and were unaffected, so this only ever showed up locally. baseof.html now clears it where each render starts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"Real projects, and what we actually did on each one. If something here looks like your situation, say so when you get in touch." read as client case studies. Everything listed is open source or openly released science that anyone can pick up without hiring us, which is a stronger thing to say and happens to be true. The nav label "Our work" carried the same wrong implication; it is now "Open source". ggseg becomes ggsegverse, covering the whole family of packages rather than the one entry point. /portfolio/ggseg/ redirects to the new URL. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
--color-primary (#c04545) is a background fill. Used as a foreground it lands at 2.68:1 on the grey sections — under the 3:1 WCAG asks for meaningful non-text content, and nowhere near the 4.5:1 for text. The palette already carries --color-primary-text (#e57575, 4.58:1) for exactly this. axe does not catch it: it has no text node to measure on an <i> icon, which is how all five instances were styled. Found by walking every rendered element and comparing its computed colour against its resolved background. Feature and contact icons, the testimonial quote mark and two team links move across. The quote mark also goes from opacity-40 to 60, since 40% of an already-dim red was close to invisible. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
og:image was the site logo resized to 512px tall, paired with twitter:card=summary_large_image. Platforms crop that to roughly 1.91:1 and render it large, so a transparent mark arrived floating on whatever background the platform chose, at the wrong aspect ratio. Every page now composes its own 1200x630 card on the brand's dark ground: the page's own image when it has one — a team portrait, a package logo, a post's figure — and the CAPRO mark when it does not. Remote images are skipped deliberately, so a build never depends on someone else's host being reachable. Also adds what was missing around it: og:site_name, image width/height and alt, og:locale:alternate for the other language, article published and modified times, and explicit twitter:title/description rather than leaving them to fall back. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every card's call to action reads "Read more", so tabbing through the news or portfolio list gives no way to tell them apart. The post title now follows it in a screen-reader-only span. The card image was built at 300px and stretched to roughly 400 by w-full, so it was upscaled on every screen and soft on high-density ones. It now ships 1x and 2x sources with sizes, plus width and height so the card stops reflowing when the image lands. Lighthouse on /news/: SEO 92 to 100. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
axe-core passes clean on all 58 pages, but it reports colour-contrast as "incomplete" wherever text sits over a photograph, and it cannot see focus indicators at all. Measuring those by hand found four AA failures: 1.4.11 Non-text contrast. The focus ring was the fill red, which is 1.00:1 against the skip link, 1.06:1 against .btn-primary and 2.68:1 against the page. On the two most important targets on the site it was invisible. White with a dark halo clears 3:1 on every surface the ring lands on, including Leaflet's white map controls. `.btn` also used `transition: all`, which animated the ring in over 200ms, so the first frame of focus was the browser default; the transition now names its properties. 1.4.3 Contrast. The CTA band composites its photo at 70% rather than 60%, matching what banner.html already did. The paragraph measured 3.85:1 with 42% of its area below AA; it now measures 5.67:1 with none. 3.2.2 On Input. The language `<select onchange="location=this.value">` fired on every arrow key, so a keyboard user could never reach the second language. It is now two links, which also drops an inline-JS dependency and carries hreflang. Ordered by site.Languages, since AllTranslations is not sorted and the pair swapped between pages. 2.5.8 Target size. Nav links, the nav group button and the team social links measured 20-28px tall; all now have a 24px floor. The byte work is the same kind of gap. banner.html resized its background to 1600px webp; feature.html and cta.html emitted .RelPermalink, so /services/ transferred the 3500px originals — 8.2 MB. Leaflet was gated on site.Params.map, a site-wide param, so 144 KiB of JS shipped to all 58 pages for a map on one. The hero preload fired on every page although baseof.html renders the banner only on the home page. The logo was a 1624x599 PNG served at 130x48 with width="auto", which is not a valid HTML width. FontAwesome imported a 'regular' weight no glyph on the site uses. Favicon declarations were a PNG labelled image/x-icon under the legacy relation, leaving /favicon.ico to 404 — the only thing costing best-practices points. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With the oversized photographs gone, the header logo is what Lighthouse now picks as the largest contentful paint on most interior pages, and it flagged the missing priority hint. LCP there is bound by render-blocking CSS rather than bytes, so this is a small effect; the local score is bimodal between 2.6s and 4.6s either way. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three placeholders that had been rendering literally.
Every team page announced "About Member" in 36px, and its two section
headings read "Posts by Member" / "Publications by Member". All three came
from `index (split .Params.single " ") 1` against the team section's
`single: About Member`. The person's name was meanwhile buried at text-xl
inside the figcaption. The name is now the page's h1, styled like every
other page's section title, with `text-transform: none` so that CSS
`capitalize` does not rewrite "José-Luis Alatorre-Warren" at the hyphen.
The portrait's alt is now empty because the name sits immediately above it;
repeating it made a screen reader say the name twice.
The footer said "Copyright © 2022" on every page of a site whose newest
post is from 2025. The year now comes from site.Lastmod rather than from a
translated string, so it tracks content instead of drifting. CI checks out
with fetch-depth 0, so enableGitInfo gives a real date there.
The home help grid drew its hairlines by painting the container and letting
the cards cover it, so seven items in three columns left cells 8 and 9
filled — a slab that read as a missing card. The hairlines move onto the
cards; empty cells now fall back to the page.
The same grid also broke the hero's promise. It headed each card with
`name` ("Large-scale computing") immediately after a hero saying you do not
need to know the technical name, while `problem` ("The analysis is too big
for your laptop.") sat unused in the same data file — the line /services/
already uses as its headline. Cards now lead with `problem` and demote
`name` to a subtitle. Not another tracked-uppercase label: the theme has
six of those already.
While in team/single.html: the social links derived their aria-label from
the last hyphen-segment of the icon class, so "ti-twitter-alt" announced as
"alt". They now name the person and the host.
axe-core still passes 0 violations across 120 runs, and every page still
has exactly one h1.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
**Contact.** The step the site exists to produce read value-then-label, sat on the same bg-dark as the team section above it, and said nothing about what you get for writing. The note moves above the address, the section moves to bg-grey so it has its own ground, and three reassurances sit under it. Each is sourced from copy already on the site — the first conversation is priced at 0 for UiO in content/pricing, and "someone who does the work, not an account manager" is the team page's own line. No reply-time commitment: that would be inventing a promise. **Stable ordering.** people.html, team.html and testimonial.html all ranged `| shuffle`, so the home strip never matched /team/ and the order changed on every deploy. Now weight, then title. **The heading split.** section-title.html cut every title after word one, which broke the compound in "Open | Source we have built" and left a lone grey "R" on a tag page with an empty accent span beside it. The split point is now a caller option (portfolio passes 2), and a single-word title is accented in full. **Term pages.** Headed by the bare term, no count, no way out. Now "Tagged R" / "Filed under MRI" with a post count and a link to all news. **Portfolio.** The filters had no group label, no pressed state and no announcement, so pressing one silently removed cards; they now carry role=group, aria-pressed and a live count, and their styling keys off aria-pressed rather than a parallel Alpine :class that could drift. The hover overlay held a second link to the same URL that was invisible on touch and focusable while transparent — it is decorative now, the title carries the link, and the overlay also reveals on :focus-within. Descriptions were `truncate 120`, cutting mid-clause; they take the first sentence instead. **Testimonials.** The nav buttons sat at left/right: -20px, on top of the first and last card's text below ~1480px. They move above the track, they disable at the ends instead of scrolling into nothing, and the step is measured from a real card rather than a hardcoded 392px. **Hierarchy.** .section-title h1 and h2 were the same size, so page title and section title were indistinguishable. Prose h2/h3/h4 now differ in size and colour and carry top margin; they were all teal and glued to the paragraph above. **The chart.** content/skill/growth.png was six curves over dashed gridlines with no axes, labels or units, beside the list of tools we actually use, on a site whose product is trustworthy data. Removed; the list takes the full width in three columns. **Side-stripe.** .svc__deliver was a 2px red left border, the one genuine instance of the pattern in the theme. It is a bordered, tinted callout now. (.icon-box keeps its 2px sides — those are the hexagon's edges, not an accent stripe.) **English on a bilingual site.** 404.html and the whole ORCID publications UI were hardcoded English. Both translated; 404 also stops being a dead end and leads with the message rather than the status code. **Card images.** `img.w-full` stretched a 262x302 source across a 400px card. Capped at the intrinsic width. axe-core: 0 violations across 120 runs. Every page has exactly one h1. Desktop Lighthouse 99-100 across performance, a11y, best practices and SEO. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The services answer "can you help with my problem". They do not answer "do you do the specific thing I came for", and that is how most would-be clients arrive — asking about MR-based research, or about Nettskjema, by name. CAPRO_services.docx frames GOAT, MRI, statistical analysis and Bevex as four pillars. They are not a service taxonomy: two are named products, one is a research domain, and one is already the "Processing and analysis" service under a different name. Making them the spine would leave work that fits none of the four homeless. So they go in as a second layer instead. The seven problems stay the spine; a short block under them names the things a visitor already has a word for, on both the landing page and /services/. Nettskjema is in that block although the document does not mention it, because it is the one name clients were reported to ask about most. Two of the document's claims are not ours to make yet, and are not made here: - We do not offer MR scanning. The document describes collection through LCBC's MRI-trained staff at Oslo University Hospital; that is their capacity, not a CAPRO service. The card starts from data that already exists, whoever collected it. - Bevex is not advertised. It is in testing, beta is expected in spring 2027, and a site should not sell what it cannot deliver. The card describes what we can do today — build browser-based experiments in JavaScript — and mentions the platform as in development, with no date. Also fixes a bug in this branch's own CSS: markdownify returns text without its wrapping <p>, so `.svc__deliver p` never matched and "What you get" rendered unstyled. The paragraph is now written in the template. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The page said "Open source we have built" and listed four things. The organisation has twelve worth showing: uiothemes, tsdrtools, neuromat, ebrains.kg and nva in R, jsPsych Studio and the Nettskjema data inspector on the web, and the R project-management workshop materials. Someone judging whether we work in the open was judging us on a third of the evidence. The reason the rest were missing is that the card template required a local image resource, and only one of the new entries ships a logo. Rather than hunt for or invent logos, the image panel goes: each card is now the categories, the linked name and a sentence. The filter chips above already carried the same categories, so they are not new information — they are the anchor the card lost with the logo. Two new categories, Web apps and Teaching, since R-packages and Analyses did not cover what was being added. Four logo files are deleted with the panel. Nothing referenced them any more, and this branch has already been removing bytes that ship without being used. Also fixes the blurb fallback: .Plain returns the rendered HTML's entities, so "Norway's" reached the card as the literal "’" once an entry had an apostrophe in it. None of the original four did. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`--panicOnWarning` turns the Hugo 0.156 deprecation of `.Site.Languages` into a hard error, so the strict build in CI fails before it renders the taxonomy pages. Both language switchers used it, for one property: the ordering by configured weight, which `AllTranslations` does not give. `hugo.Sites` is ordered the same way, so the walk is unchanged apart from reaching the code through `.Language.Lang`. Verified the switcher still renders English before Norsk on both language trees, with `aria-current` on the right entry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two sections sat on pages whose subject they did not match. The testimonials were the closing section of /portfolio/, under the heading "Open source we have built". The quotes are about working with us on projects — a database built over fifteen years of collection, workshops, a data structure someone can finally use — not about released code. They move to /services/, straight after "What working with us is like", where they are the evidence for the claim immediately above them. The CTA asks "Not sure your problem is on the list?" and invites you to describe the problem in ordinary words. On /services/ that list is right there. On /pricing/ there is no list, and the page already closes on its own ask — "You can always ask what something would cost before committing to anything" — so the block was both a non sequitur and a second ask. It goes. /portfolio/ now ends on the projects, which is what a reader came to that page for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Same mismatch as /pricing/: "Not sure your problem is on the list?" after a page about who works here, where there is no list. The skills section already closes on its own invitation — "If something you use is not on this list, ask anyway" — so the page keeps an ask, and a better-aimed one. The CTA now appears only on /services/, which is the page its copy was written for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The page was flat for structural reasons, not stylistic ones. Seven items rendered with identical geometry, one hairline between each, nothing larger than 1.9rem and nothing smaller than 0.72rem, and in seven screens of scroll the only colour was a red icon and a 7%-red box. Three things were scaffolding rather than information: - The numbers. The old comment said it outright — "the number is rhythm, not information, the items are not a sequence and nothing refers to them by number". Rhythm is what this commit gets from the layout instead. - The "What you get" label. Seven of them, and the box under each made the heaviest element on the page also the most repetitive, so the emphasis stopped registering as emphasis. - The tracked-uppercase category. Two eyebrows per item, fourteen down the page. The category stays, in sentence case, for the reader who knows the term; it no longer competes with the problem above it. What replaces them: - The problem statement is the one piece of scale, up to 3.25rem, with the measure capped at 19ch so it breaks into two or three lines and reads as a statement rather than a table row. - Items alternate which edge they sit on above 900px, and the hairline under each is only as wide as the item, so the stagger is visible before any of the text is read. - The payoff is the largest body text in the item and the only teal on the page, marked with an arrow rather than a label and a filled box. Gold (`--color-tertiary`) stays unused. It is defined in the tokens and appears nowhere on the site; introducing it on one page would orphan it. Checked at 1280 and 390, both languages. Contrast holds: the symptom text is 4.9:1 on the section background, the teal payoff and the category well above. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
People arrive unsure whether we can help them, and the copy is a large part of
why. The site described itself in terms a reader only understands if they
already know what we do — "data engineering", "data science team", "FAIR
principles", "containerization", "integrated solutions", "standardized data
output", "registry data handling 55%".
This rewrites the language across the whole site so a researcher can recognise
their own situation without knowing what any of it is called.
What changed
Services — now problem-led. Each of the seven leads with the problem the
reader arrived with, lists the situations that produce it, and says what you
get. The category name stays as a small secondary label, so someone who does
know the term can still find it.
The named systems do a lot of the work. Someone who has never heard "data
engineering" knows exactly what "I have a Nettskjema and can't get the data
out" means. Every name used (Nettskjema, TSD, Educloud, Saga, Quarto) already
appeared elsewhere on the site.
Hero and contact. The hero now names the concrete things we do instead of
"capture, process, manage and analyse". Contact says explicitly that you do not
need to know the technical name for your problem, because that is the real
barrier.
Feature section. "Integrated Solutions / Standardized Data Output /
Customization on Demand" is replaced by what working with us is actually like:
we use systems UiO already pays for, you own what we build, we can teach rather
than do, and you can start with a single hour.
Skills. The percentage bars are gone. "Registry data handling 55%" is not
something a visitor can act on, and the numbers were not sourced from anything.
They are replaced by three plain lists — languages and tools, UiO and national
systems, kinds of data — so someone with MRI data on TSD recognises themselves.
Pricing. Explains that the rate depends on how close you are to the
department and that computing time is applied for and paid for separately. The
bullets describe what you get rather than listing line items.
CTA, portfolio, team, testimonials. Same rule throughout: ordinary words,
concrete claims, and an explicit invitation to ask even if your problem is not
on the list.
Also fixed
Datafangst but no separate processing entry. The two languages advertised
different services. Both now carry the same seven.
skipToContentblock in both i18n files..progress-bar-track/.progress-bar-fillCSS, now that the bars aregone.
Notes
durationfield from the earlier draft of this PR is dropped, notleft blank — engagement length varies too much to state honestly.
mainafter Strip landing page to essentials, move detail to sub-pages #23 renamedcontent/service/to
content/services/.Test plan
CI covers prettier, the content accessibility check, a strict Hugo build and the
CSS bundle freshness. What it cannot check:
best reconstruction from the services, portfolio and testimonials — you
have the real record in the booking notes and inbox.
practical:lines describe how you work, and I inferred them from thesite and testimonials (e.g. working alongside a student comes from the
DRCMR quote about "daily sparring and guidance sessions"). Check them.
en datahåndteringsplan" in particular — is that how a Norwegian funder
context would phrase it?
Add anything missing, remove anything we don't really do.
cheaper" as plain English for the multiplier table. Confirm that is a fair
description of the policy.
Since the first review round
Barbara's note was that the page held too much information and felt scattered,
and suggested structuring it around the four pillars in
CAPRO_services.docx.Those four — GOAT, MRI, statistical analysis, Bevex — are not a service
taxonomy. Two are named products, one is a research domain, and one is already
the "Processing and analysis" service under another name. Making them the spine
would leave work that fits none of the four homeless.
So they go in as a second layer instead. The seven problems stay the spine
and answer can you help with my problem. A short block under them, on both the
landing page and
/services/, names the things a visitor already has a wordfor, and answers do you do the specific thing I came for — which is how the
would-be clients in Barbara's account actually arrive.
What we run and support — GOAT, Nettskjema, MRI, behavioural experiments.
Nettskjema is in there although the document never mentions it, because it is
the one name clients were reported to ask about most.
Two of the document's claims are deliberately not made:
MRI-trained staff at Oslo University Hospital. That is their capacity, not a
CAPRO service. The card starts from scans that already exist, whoever
collected them.
and the site should not sell what it cannot deliver. The card describes what
we can do today — build browser-based experiments in JavaScript with
tachisto, exportable to Cognition.run, Pavlovia or JATOS — and mentions theUiO platform as in development, with no date.
Open source page
It said "Open source we have built" and listed four things. The organisation has
twelve worth showing. Someone judging whether we work in the open was judging us
on a third of the evidence.
Added:
tachisto,uiothemes,tsdrtools,neuromat,ebrains.kg,nva,the Nettskjema data inspector, and the R project-management workshop materials.
Two new categories, Web apps and Teaching.
The reason the rest were missing is that the card template required a local
image resource, and almost none of them ship a logo. The image panel is gone:
each card is now the categories, the linked name and a sentence. Four orphaned
logo files are deleted with it.
Accessibility and performance
Four WCAG failures fixed, 8.5 MB of unused bytes dropped, the logo hinted as the
LCP element, card images no longer upscaled, a real social card instead of a bare
logo, and card links that name their destination.
Bugs found while building this
.svc__deliver pnever matched:markdownifyreturns text without itswrapping
<p>, so every "What you get" box rendered unstyled. The CSS wasadded earlier in this same PR.
.Plain, which carries the renderer'sentities, so "Norway's" rendered as the literal
’. None of theoriginal four entries had an apostrophe, so it had never surfaced.
Still to do before merge
the source of truth.
content/offerings/_index.no.mdis two revisionsbehind its English twin — its experiments card has neither the platform
list nor the
tachistomention.tachistolinks point at the old URL.capro.dev/tachisto/andgithub.com/capro-uio/tachistoare both 404;capro.dev/jspsych-studio/is the only URL that resolves, so that is what the two
link:lines use.Note that renaming the repo redirects the repo URL but not the GitHub
Pages project path —
capro.dev/jspsych-studio/will 404 once the repomoves, so those links have to change in the same sitting as the rename.
phrase in the block an outside reader will not parse. Keep only if it
earns its place on credibility.
CI fix carried here
themes/capro-tw/layouts/partials/nav.htmlwalkedsite.Languages, deprecatedin Hugo 0.156. Under
--panicOnWarningthat is a hard error, and the strictbuild in CI failed on it on the first push of this branch. Both language
switchers now walk
hugo.Sites, which carries the same weight ordering.It is unrelated to the copy work, but it blocked this PR, so it is fixed here
rather than in a follow-up.
🤖 Generated with Claude Code