Three pieces of one session's work. They are in one commit because home.tsx
and _page-kit/copy.ts carry hunks from all three and splitting them by hand
would have meant committing intermediate states of those two files that were
never built or served.
THE THIRD DESIGN DROP
Only Home.dc.html and SiteFooter.dc.html differ from the second drop; the
other nine page drafts are byte-identical to what already ships.
The home page stops opening on a launch announcement dated to one day in
June. New headline, lead and primary call to action ("See open calls"), and
the launch band becomes "A nationwide project, delivered locally" -
launchEyebrow/Heading/Lead renamed approach*, LaunchShots renamed
GalleryShots, since the band is no longer about an event. Its Arabic reuses
the About page's already-approved wording for the coverage line and the body
heading; the new lead and headline are ar-draft like the rest of the Arabic
home copy and still want client sign-off.
Five motion classes in _page-kit/motion.css, tokens only, each with its RTL
form where the property has no logical one: sh-wipe (the headline uncovered
from the inline start), sh-pan (the hero picture on a view timeline), sh-zoom
(a picture closing in inside its frame), sh-rule-top (an accent rule drawn
across a hovered tile) and sh-marquee (the logo wall). sh-wipe fills
`backwards`, not `both`, so the clip is gone at rest - inset(0) would shave a
descender or an Arabic mark off a tight heading line - and it is removed
outright under prefers-reduced-motion, because a clip does not fade a
headline, it hides it.
The marquee carries each logo twice and slides exactly half the track, so its
spacing is a margin on the tile rather than a gap on the row: with a row gap
the seam lands half a gap short. The second half is aria-hidden with no link,
so the wall is neither read out nor tabbed through twice; it pauses on hover
and focus (WCAG 2.2.2) and unwraps to a plain row under reduced motion. Below
eight partners the wall stays a grid, because a half-track narrower than its
frame drifts a short row across empty space instead of looping.
SEEDING THE CMS
`pnpm seed` writes content through the document service. It opens no port, so
it runs happily beside `pnpm dev:cms`, and every write is matched on a slug
and written over the same document, so a second run changes nothing but the
fields the seed owns.
src/seed/approved.ts is transcribed from docs/ in both languages and is safe
to publish: site settings, the three consortium members, the topic taxonomy,
the five activity streams with their implementing partners, the launch
article in full, and the four pages. What docs/ withholds is not written -
no statistics, no project email, no Facebook URL, no consortium addresses,
all of which the source writes as bracketed placeholders. Two fields are
judgement calls and say so at the line: activityStatus, which the schema
requires and the source never states, and the launch article's year, which is
derived - the source says "Tuesday, June 30" and within December 2025 to
December 2027 that is 2026 and no other year.
src/seed/demo.ts is invented and kept apart three ways: opt-in behind --demo,
refused outright when NODE_ENV=production, and tagged in the data itself with
a demo- slug prefix that shows in every URL and is how --demo --clean finds
them again, with nothing remembered between runs.
Two things the Strapi 5 document service does not do by itself, both of which
leave Arabic rows behind that the next run then collides with on the unique
slug: delete({ documentId }) with no locale removes the DEFAULT locale only,
not the document, and findMany({ locale }) answers for one locale, so a
document whose English half has gone is invisible to a search in English. The
first --clean left six Arabic orphans and failed the next run partway.
deleteMatching now pools documentIds across both locales and deletes with
locale: '*'.
Knex aborts its pending pool acquisitions on teardown, and each abort rejects
a promise nothing awaits, so it arrives as an unhandled rejection rather than
as an error a try/catch would see. scripts/seed.js absorbs exactly that, for
the length of the shutdown only: a seed that worked must not report itself as
a seed that failed.
THE FIGURES BAND, AND THE BAND THAT REPLACED IT
The third draft deletes the figures band, so shared.stat and blocks.stats-grid
are deleted with it, home-page.stats is dropped, and blocks.stats-grid comes
out of all six dynamic zones. On the web side that takes CmsStat, StatsRow,
CountUpValue, StatStrip and Card.Stat - the last two were already dead, but
they existed only to draw figures. No approved document carries a number, so
there is now nowhere for one to be typed in, which is the point.
The "nationwide project, delivered locally" band was half editable and half
not: its pictures came from an image-gallery block down the Blocks dynamic
zone, and its words came from bundled fallback copy with no CMS field at all.
The new page.band-intro component (eyebrow, heading, lead, images) on
home-page.approach puts the whole band in one place in the admin. The page
still falls back to the bundled copy when the fields are empty, and still
reads an image-gallery block after the component's own images, so a gallery
built in Blocks keeps rendering.
VERIFIED
pnpm typecheck and both builds pass. Both rule greps are clean: no raw hex or
tier-1 token in components/ or routes/, no physical-direction utility in
apps/web/app.
Against a seeded CMS on the built server: / redirects 302 with
Vary: Accept-Language, and all ten sections plus the detail routes return 200
in both locales with lang/dir correct in the first bytes. The home page draws
the marquee from twelve partners, the hero pan, the three hovered card rules
and the status pill, and carries no figures band.
The seed is idempotent - two identical --demo runs give identical counts,
balanced across locales - and a clean/re-seed cycle leaves nothing behind.
The approach band was proved editable end to end: heading, eyebrow, lead and
images changed through the CMS all came through on /en while /ar stayed on
its own Arabic, then the seeded copy was restored.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
707 lines
33 KiB
TypeScript
707 lines
33 KiB
TypeScript
/* ============================================================================
|
||
SEED - APPROVED CONTENT
|
||
----------------------------------------------------------------------------
|
||
Everything in this file is transcribed from docs/, in both languages, and
|
||
nothing in it is invented. That is the whole point of keeping it apart from
|
||
demo.ts: this content is safe to publish.
|
||
|
||
SOURCES
|
||
docs/SHARPER_Website_Draft_Section_EN_AR.docx sections 1-9, EN and AR
|
||
columns, which is why no
|
||
Arabic string here is a
|
||
machine translation
|
||
docs/SHARPER Home Page .docx the launch article, EN/AR
|
||
docs/UEC_SHARPER_Website_TOR V3.docx the consortium and the
|
||
project's purpose
|
||
|
||
WHAT docs/ DOES NOT SUPPLY, AND IS THEREFORE NOT HERE
|
||
* Figures. Every number in the draft is bracketed and marked "TBD ... must
|
||
not be published until confirmed". There is no figures band on the site
|
||
and no `stats` component in the CMS - both were removed rather than left
|
||
as an empty invitation to fill one in.
|
||
* The project email. The draft writes it "[project email - e.g.
|
||
info@sharper.ly]", an example rather than an address, so
|
||
`contact-page.generalEmail` is left empty.
|
||
* The Facebook URL and the SHARP-legacy link. Both are bracketed
|
||
placeholders, and `shared.link` requires an href, so neither link is
|
||
written at all rather than written to nowhere.
|
||
* Consortium postal addresses - "[addresses/contacts TBD]".
|
||
* Any CSO partner, event, resource or question. The draft's examples are
|
||
all written "[CSO Name]", "[Date]", "[Report title]". Those live in
|
||
demo.ts and are opt-in.
|
||
|
||
THE TWO JUDGEMENT CALLS, BOTH FLAGGED AT THEIR FIELD
|
||
* `activityStatus` is required by the schema and the draft states no
|
||
status per activity stream.
|
||
* The launch article's year is derived, not given.
|
||
========================================================================= */
|
||
|
||
import type { Localised, SeedData } from './upsert';
|
||
|
||
/** Slug -> content, for the collection types the approved set writes. */
|
||
export type SeedEntries = ReadonlyArray<{
|
||
readonly slug: string;
|
||
readonly data: Localised<SeedData>;
|
||
}>;
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
SITE SETTINGS
|
||
------------------------------------------------------------------------ */
|
||
|
||
export const SITE_SETTINGS: Localised<SeedData> = {
|
||
en: {
|
||
siteName: 'SHARP-ER',
|
||
tagline: 'Shared Action on Rule of Law Progress – Exit Route',
|
||
euFundingStatement: 'Funded by the European Union',
|
||
implementedByLabel: 'Implemented by',
|
||
},
|
||
ar: {
|
||
siteName: 'SHARP-ER',
|
||
tagline: 'العمل المشترك لتعزيز سيادة القانون – مسار الخروج',
|
||
euFundingStatement: 'بتمويل من الاتحاد الأوروبي',
|
||
implementedByLabel: 'ينفّذه',
|
||
},
|
||
};
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
THE CONSORTIUM
|
||
----------------------------------------------------------------------------
|
||
Draft section 1 writes each member as "<name> - <role> - <deliverable>".
|
||
The Latin names are kept in the Arabic column exactly as the draft keeps
|
||
them. No website is seeded: the draft names none.
|
||
------------------------------------------------------------------------ */
|
||
|
||
export const CONSORTIUM: SeedEntries = [
|
||
{
|
||
slug: 'acted',
|
||
data: {
|
||
en: {
|
||
name: 'Acted',
|
||
slug: 'acted',
|
||
partnerRole: 'consortium-lead',
|
||
description:
|
||
'Lead implementing partner — overall project management and civil society sub-projects.',
|
||
},
|
||
ar: {
|
||
name: 'Acted',
|
||
slug: 'acted',
|
||
partnerRole: 'consortium-lead',
|
||
description: 'الشريك المنفّذ الرئيسي — الإدارة العامة للمشروع والمشاريع الفرعية لمنظمات المجتمع المدني.',
|
||
},
|
||
},
|
||
},
|
||
{
|
||
slug: 'united-efforts-consultancy',
|
||
data: {
|
||
en: {
|
||
name: 'United Efforts Consultancy (UEC)',
|
||
slug: 'united-efforts-consultancy',
|
||
partnerRole: 'consortium-partner',
|
||
description: 'Network strengthening, dialogue, and peer-learning.',
|
||
},
|
||
ar: {
|
||
name: 'United Efforts Consultancy (UEC)',
|
||
slug: 'united-efforts-consultancy',
|
||
partnerRole: 'consortium-partner',
|
||
description: 'تعزيز الشبكة، والحوار، والتعلّم بين الأقران.',
|
||
},
|
||
},
|
||
},
|
||
{
|
||
slug: 'stichting-bureau-ensemble',
|
||
data: {
|
||
en: {
|
||
name: 'Stichting Bureau Ensemble (SBE)',
|
||
slug: 'stichting-bureau-ensemble',
|
||
partnerRole: 'consortium-partner',
|
||
description: 'Research, perception data, and knowledge publications.',
|
||
},
|
||
ar: {
|
||
name: 'Stichting Bureau Ensemble (SBE)',
|
||
slug: 'stichting-bureau-ensemble',
|
||
partnerRole: 'consortium-partner',
|
||
description: 'البحث، وبيانات الاستطلاع، والمنشورات المعرفية.',
|
||
},
|
||
},
|
||
},
|
||
];
|
||
|
||
/** Slugs, so later steps can wire relations without repeating the strings. */
|
||
export const PARTNER_SLUGS = {
|
||
acted: 'acted',
|
||
uec: 'united-efforts-consultancy',
|
||
sbe: 'stichting-bureau-ensemble',
|
||
} as const;
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
TOPICS
|
||
----------------------------------------------------------------------------
|
||
The taxonomy the site filters by. Each name and description is one of the
|
||
draft's own area headings - the three pillars of section 1 and two of the
|
||
five activity streams of section 3 - so the vocabulary is the project's,
|
||
not one this seed made up.
|
||
------------------------------------------------------------------------ */
|
||
|
||
export const TOPICS: SeedEntries = [
|
||
{
|
||
slug: 'rule-of-law',
|
||
data: {
|
||
en: {
|
||
name: 'Rule of Law',
|
||
slug: 'rule-of-law',
|
||
description:
|
||
'Supporting local institutions to improve access to justice and transparency.',
|
||
},
|
||
ar: {
|
||
name: 'سيادة القانون',
|
||
slug: 'rule-of-law',
|
||
description: 'دعم المؤسسات المحلية لتحسين الوصول إلى العدالة وتعزيز الشفافية.',
|
||
},
|
||
},
|
||
},
|
||
{
|
||
slug: 'civil-society',
|
||
data: {
|
||
en: {
|
||
name: 'Civil Society',
|
||
slug: 'civil-society',
|
||
description:
|
||
'Building the capacity of CSOs to strengthen their role in oversight and accountability.',
|
||
},
|
||
ar: {
|
||
name: 'المجتمع المدني',
|
||
slug: 'civil-society',
|
||
description: 'بناء قدرات منظمات المجتمع المدني لتعزيز دورها في الرقابة والمساءلة.',
|
||
},
|
||
},
|
||
},
|
||
{
|
||
slug: 'local-governance',
|
||
data: {
|
||
en: {
|
||
name: 'Local Governance',
|
||
slug: 'local-governance',
|
||
description:
|
||
'Enhancing collaboration between municipalities and local actors to improve service delivery.',
|
||
},
|
||
ar: {
|
||
name: 'الحوكمة المحلية',
|
||
slug: 'local-governance',
|
||
description: 'تعزيز التعاون بين البلديات والجهات الفاعلة المحلية لتحسين تقديم الخدمات.',
|
||
},
|
||
},
|
||
},
|
||
{
|
||
slug: 'dialogue',
|
||
data: {
|
||
en: {
|
||
name: 'Dialogue',
|
||
slug: 'dialogue',
|
||
description:
|
||
'SUQ dialogues and Civil Society Law Sessions that bring civic and government actors to the same table.',
|
||
},
|
||
ar: {
|
||
name: 'الحوار',
|
||
slug: 'dialogue',
|
||
description: 'حوارات SUQ وجلسات قانون المجتمع المدني التي تجمع الفاعلين المدنيين والحكوميين حول طاولة واحدة.',
|
||
},
|
||
},
|
||
},
|
||
{
|
||
slug: 'human-security',
|
||
data: {
|
||
en: {
|
||
name: 'Human Security',
|
||
slug: 'human-security',
|
||
description: 'Sub-projects designed to foster human security at the community level.',
|
||
},
|
||
ar: {
|
||
name: 'الأمن البشري',
|
||
slug: 'human-security',
|
||
description: 'مشاريع فرعية مصمَّمة لتعزيز الأمن البشري على المستوى المجتمعي.',
|
||
},
|
||
},
|
||
},
|
||
];
|
||
|
||
export const TOPIC_SLUGS = {
|
||
ruleOfLaw: 'rule-of-law',
|
||
civilSociety: 'civil-society',
|
||
localGovernance: 'local-governance',
|
||
dialogue: 'dialogue',
|
||
humanSecurity: 'human-security',
|
||
} as const;
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
ACTIVITIES - draft section 3
|
||
----------------------------------------------------------------------------
|
||
Five streams, and the draft names all five along with the partner that
|
||
implements each. They map one-to-one onto the `activityStream` enum, which
|
||
is where that enum came from.
|
||
|
||
`activityStatus` is the one field with no source. The schema requires it and
|
||
the draft states no status per stream, so every activity is seeded
|
||
`ongoing`: the draft heads the section "here's where the project stands
|
||
today" and describes all five in the present tense. It is a default for
|
||
editors to correct, not a claim from docs/.
|
||
------------------------------------------------------------------------ */
|
||
|
||
const activity = (
|
||
slug: string,
|
||
stream: string,
|
||
partners: readonly string[],
|
||
topics: readonly string[],
|
||
en: { title: string; summary: string },
|
||
ar: { title: string; summary: string }
|
||
) => ({
|
||
slug,
|
||
partners,
|
||
topics,
|
||
data: {
|
||
en: {
|
||
title: en.title,
|
||
slug,
|
||
summary: en.summary,
|
||
activityStream: stream,
|
||
activityStatus: 'ongoing',
|
||
},
|
||
ar: {
|
||
title: ar.title,
|
||
slug,
|
||
summary: ar.summary,
|
||
activityStream: stream,
|
||
activityStatus: 'ongoing',
|
||
},
|
||
} satisfies Localised<SeedData>,
|
||
});
|
||
|
||
export const ACTIVITIES = [
|
||
activity(
|
||
'the-sharp-network',
|
||
'sharp-network',
|
||
[PARTNER_SLUGS.uec],
|
||
[TOPIC_SLUGS.civilSociety],
|
||
{
|
||
title: 'The SHARP Network',
|
||
summary:
|
||
'Regional meetings, international events, and peer-to-peer learning that keep the civil society network connected.',
|
||
},
|
||
{
|
||
title: 'شبكة SHARP',
|
||
summary: 'اجتماعات إقليمية وفعاليات دولية وتعلّم بين الأقران تُبقي شبكة المجتمع المدني على تواصل.',
|
||
}
|
||
),
|
||
activity(
|
||
'cso-sub-projects-and-policy-to-rights',
|
||
'cso-subprojects-p2r',
|
||
[PARTNER_SLUGS.acted],
|
||
[TOPIC_SLUGS.civilSociety, TOPIC_SLUGS.ruleOfLaw],
|
||
{
|
||
title: 'CSO Sub-Projects & Policy-to-Rights',
|
||
summary:
|
||
'Collective sub-projects selected through open Calls for Expression of Interest, fostering cross-country cooperation, plus Policy-to-Rights (P2R) projects.',
|
||
},
|
||
{
|
||
title: 'المشاريع الفرعية لمنظمات المجتمع المدني ومشاريع P2R',
|
||
summary:
|
||
'مشاريع فرعية جماعية تُختار عبر دعوات مفتوحة للتعبير عن الاهتمام لتعزيز التعاون العابر للمناطق، إضافة إلى مشاريع “من السياسة إلى الحقوق”.',
|
||
}
|
||
),
|
||
activity(
|
||
'suq-dialogues-and-civil-society-law-sessions',
|
||
'suq-dialogues',
|
||
[PARTNER_SLUGS.uec, PARTNER_SLUGS.acted],
|
||
[TOPIC_SLUGS.dialogue, TOPIC_SLUGS.ruleOfLaw],
|
||
{
|
||
title: 'SUQ Dialogues & Civil Society Law Sessions',
|
||
summary:
|
||
'Search, Understand, Question (SUQ) dialogues driven by local needs, dialogue-facilitation training, and joint sessions with the Commission on Civil Society (CCS).',
|
||
},
|
||
{
|
||
title: 'حوارات SUQ وجلسات قانون المجتمع المدني',
|
||
summary:
|
||
'حوارات “ابحث، افهم، اسأل” (SUQ) مدفوعة باحتياجات محلية، وتدريب على تيسير الحوار، وجلسات مشتركة مع لجنة المجتمع المدني (CCS).',
|
||
}
|
||
),
|
||
activity(
|
||
'human-security-initiatives',
|
||
'human-security',
|
||
[PARTNER_SLUGS.uec],
|
||
[TOPIC_SLUGS.humanSecurity],
|
||
{
|
||
title: 'Human Security Initiatives',
|
||
summary:
|
||
'16 individual sub-projects designed to foster human security at the community level.',
|
||
},
|
||
{
|
||
title: 'مبادرات الأمن البشري',
|
||
summary: '16 مشروعًا فرديًا فرعيًا مصمَّمًا لتعزيز الأمن البشري على المستوى المجتمعي.',
|
||
}
|
||
),
|
||
activity(
|
||
'research-and-perception-data',
|
||
'research',
|
||
[PARTNER_SLUGS.sbe],
|
||
[TOPIC_SLUGS.localGovernance],
|
||
{
|
||
title: 'Research & Perception Data',
|
||
summary: 'Nationwide perception-based data collection, analysis, and dissemination.',
|
||
},
|
||
{
|
||
title: 'البحث وبيانات الاستطلاع',
|
||
summary: 'جمع بيانات استطلاعية على المستوى الوطني وتحليلها ونشرها.',
|
||
}
|
||
),
|
||
] as const;
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
THE LAUNCH ARTICLE - docs/SHARPER Home Page .docx
|
||
----------------------------------------------------------------------------
|
||
The one piece of real news the project has handed over, written out in full
|
||
in both languages.
|
||
|
||
THE DATE: the document says "Tuesday, June 30" and gives no year. Within the
|
||
project's own window - December 2025 to December 2027 - 30 June falls on a
|
||
Tuesday in 2026 and in no other year, so 2026-06-30 is derived from the
|
||
source rather than chosen.
|
||
|
||
The source's closing line ("Visit the SHARP-ER website and follow our social
|
||
media channels...") is left out: it addresses a reader on social media and
|
||
asks them to come to this site, which is not something to print on it.
|
||
|
||
No `authorOrganisation`: the document attributes the article to no one, and
|
||
a byline is not a thing to guess at.
|
||
------------------------------------------------------------------------ */
|
||
|
||
const LAUNCH_SLUG = 'sharp-er-project-officially-launches-in-libya';
|
||
|
||
export const LAUNCH_ARTICLE = {
|
||
slug: LAUNCH_SLUG,
|
||
topics: [TOPIC_SLUGS.civilSociety, TOPIC_SLUGS.ruleOfLaw],
|
||
data: {
|
||
en: {
|
||
title: 'SHARP-ER Project Officially Launches in Libya',
|
||
slug: LAUNCH_SLUG,
|
||
category: 'sharper-news',
|
||
publishDate: '2026-06-30',
|
||
featured: true,
|
||
excerpt:
|
||
'The launch brought together the European Union Delegation, three ministries, civil society organisations, partners and stakeholders from across Libya, and opened the Expression of Interest.',
|
||
body: [
|
||
'On Tuesday, June 30, the SHARP-ER project officially launched, bringing together representatives from the European Union Delegation, the Ministry of Youth, the Ministry of Local Governance, the Ministry of Women’s Affairs, civil society organizations, partners, and stakeholders from across Libya.',
|
||
'The event marked an important start for the project, including the launch of the SHARP-ER website and the opening of the Expression of Interest (EOI). Participants also learned more about the project’s objectives, upcoming opportunities, and activities focused on strengthening collaboration, partnerships, and local capacities.',
|
||
'Thank you to everyone who joined us and contributed to this milestone. We look forward to working together to support locally driven initiatives and create meaningful, lasting impact across Libya.',
|
||
'This project is funded by the European Union in Libya.',
|
||
].join('\n\n'),
|
||
},
|
||
ar: {
|
||
title: 'انطلاق مشروع SHARP-ER رسميًا في ليبيا',
|
||
slug: LAUNCH_SLUG,
|
||
category: 'sharper-news',
|
||
publishDate: '2026-06-30',
|
||
featured: true,
|
||
excerpt:
|
||
'جمعت فعالية الإطلاق بعثة الاتحاد الأوروبي وثلاث وزارات ومنظمات المجتمع المدني والشركاء وأصحاب المصلحة من مختلف أنحاء ليبيا، وشهدت فتح باب التعبير عن الاهتمام.',
|
||
body: [
|
||
'انطلقت يوم الثلاثاء 30 يونيو رسميًا فعاليات مشروع SHARP-ER خلال حدث الإطلاق الذي جمع ممثلين عن بعثة الاتحاد الأوروبي، ووزارة الشباب، ووزارة الحكم المحلي، ووزارة شؤون المرأة، إلى جانب منظمات المجتمع المدني والشركاء والجهات الفاعلة من مختلف أنحاء ليبيا.',
|
||
'وشكّل الحدث بداية مهمة للمشروع، حيث تم إطلاق الموقع الإلكتروني الرسمي، والإعلان عن فتح باب التعبير عن الاهتمام (EOI)، إلى جانب استعراض أهداف المشروع والفرص والأنشطة القادمة. وتركّز هذه الأنشطة على تعزيز التعاون والشراكات وبناء القدرات على المستوى المحلي.',
|
||
'نتوجه بالشكر إلى جميع المشاركين على حضورهم ومساهماتهم القيّمة. ونتطلع إلى العمل معًا خلال المرحلة المقبلة لدعم المبادرات المحلية وتحقيق أثر مستدام في مختلف أنحاء ليبيا.',
|
||
'المشروع ممول من الاتحاد الأوروبي في ليبيا.',
|
||
].join('\n\n'),
|
||
},
|
||
} satisfies Localised<SeedData>,
|
||
};
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
PAGES
|
||
----------------------------------------------------------------------------
|
||
The single types. Each hero, body and component list below is the draft's
|
||
own wording for that section; the home page's hero is the Claude Design
|
||
draft's, which is the same content the web app bundles as its fallback, so
|
||
the CMS and the fallback say the same thing rather than drifting apart.
|
||
------------------------------------------------------------------------ */
|
||
|
||
export const HOME_PAGE: Localised<SeedData> = {
|
||
en: {
|
||
hero: {
|
||
/* No `eyebrow`. The design draws a status pill reading "Now open -
|
||
Funding calls for Libyan organisations"; whether a call is open on any
|
||
given day is a fact about the project, not about the design, so the
|
||
pill stays unwritten until an editor writes it. */
|
||
headline: 'Advancing Justice and Accountability, Led by Libyan Communities',
|
||
subheading:
|
||
'SHARP-ER — Shared Action on Rule of Law Progress, Exit Route — works with civil society organisations, municipalities, and community leaders across Libya to strengthen access to justice, accountability, and local governance. Funded by the European Union, running to December 2027.',
|
||
},
|
||
/* The band under the hero. Seeded so an editor opening Home Page finds the
|
||
words already in a field they can change, rather than wondering where
|
||
the page is getting them from - the web app still falls back to the
|
||
bundled draft copy if this is ever emptied. `images` is left alone: the
|
||
seed uploads nothing. */
|
||
approach: {
|
||
eyebrow: 'Nationwide, Libya',
|
||
heading: 'A nationwide project, delivered locally',
|
||
lead: 'Local organisations lead the design and delivery of the work. SHARP-ER partners with Libyan civil society, municipalities, and community leaders — through funded sub-projects, training, and open dialogue between communities and the institutions that serve them.',
|
||
},
|
||
partnersHeadline: 'The consortium',
|
||
seo: {
|
||
metaTitle: 'SHARP-ER — Shared Action on Rule of Law Progress, Exit Route',
|
||
metaDescription:
|
||
'A nationwide initiative supporting Libya’s civil society, local institutions, and communities in advancing justice, accountability, and good governance.',
|
||
},
|
||
},
|
||
ar: {
|
||
hero: {
|
||
headline: 'تعزيز العدالة والمساءلة بقيادة المجتمعات الليبية',
|
||
subheading:
|
||
'يعمل SHARP-ER — العمل المشترك لتعزيز سيادة القانون، مسار الخروج — مع منظمات المجتمع المدني والبلديات وقادة المجتمعات في مختلف أنحاء ليبيا على تعزيز الوصول إلى العدالة والمساءلة والحوكمة المحلية. بتمويل من الاتحاد الأوروبي، ويستمر حتى ديسمبر 2027.',
|
||
},
|
||
approach: {
|
||
eyebrow: 'على مستوى ليبيا بأكملها',
|
||
heading: 'مشروع وطني يُنفَّذ محليًا',
|
||
lead: 'تتولّى المنظمات المحلية تصميم العمل وتنفيذه. ويعمل SHARP-ER بالشراكة مع المجتمع المدني الليبي والبلديات وقادة المجتمعات، من خلال المشاريع الفرعية المموَّلة، والتدريب، والحوار المفتوح بين المجتمعات والمؤسسات التي تخدمها.',
|
||
},
|
||
partnersHeadline: 'الائتلاف المنفّذ',
|
||
seo: {
|
||
metaTitle: 'SHARP-ER — العمل المشترك لتعزيز سيادة القانون، مسار الخروج',
|
||
metaDescription:
|
||
'مبادرة وطنية تدعم المجتمع المدني والمؤسسات المحلية والمجتمعات في ليبيا في تعزيز العدالة والمساءلة والحوكمة الرشيدة.',
|
||
},
|
||
},
|
||
};
|
||
|
||
/**
|
||
* The About page. `consortium` is built in index.ts, where the partner
|
||
* documentIds are known; everything else is here.
|
||
*/
|
||
export const ABOUT_PAGE: Localised<SeedData> = {
|
||
en: {
|
||
hero: {
|
||
eyebrow: 'About the project',
|
||
headline: 'Strengthening the Rule of Law, Together',
|
||
subheading:
|
||
'SHARP-ER (Shared Action on Rule of Law Progress – Exit Route) is a nationwide initiative supporting Libya’s civil society, local institutions, and communities in advancing justice, accountability, and good governance.',
|
||
},
|
||
body: [
|
||
'Running from December 2025 to December 2027, SHARP-ER is implemented by Acted, in consortium with United Efforts Consultancy (UEC) and Stichting Bureau Ensemble (SBE), and funded by the European Union. The project works nationwide across Libya, partnering with civil society organisations, municipalities, and community leaders to strengthen access to justice, build the capacity of civil society to hold institutions accountable, and improve local governance and service delivery.',
|
||
].join('\n\n'),
|
||
pillars: [
|
||
{
|
||
title: 'Strengthening Rule of Law',
|
||
description:
|
||
'Supporting local institutions to improve access to justice and transparency.',
|
||
},
|
||
{
|
||
title: 'Empowering Civil Society',
|
||
description:
|
||
'Building the capacity of CSOs to strengthen their role in oversight and accountability.',
|
||
},
|
||
{
|
||
title: 'Supporting Local Governance',
|
||
description:
|
||
'Enhancing collaboration between municipalities and local actors to improve service delivery.',
|
||
},
|
||
],
|
||
legacyHeadline: 'SHARP I and II (2019–2024)',
|
||
legacyBody:
|
||
'SHARP-ER builds on the foundation of SHARP I and II (2019–2024), carrying its network of civil society partners and its dialogue practice into a new phase focused on sustainability and exit.',
|
||
/* No `legacyLink`: the draft marks the target "[link: read about the SHARP
|
||
legacy]" and gives no URL, and `shared.link` requires an href. */
|
||
seo: {
|
||
metaTitle: 'About SHARP-ER',
|
||
metaDescription:
|
||
'SHARP-ER is implemented by Acted with United Efforts Consultancy and Stichting Bureau Ensemble, and funded by the European Union, from December 2025 to December 2027.',
|
||
},
|
||
},
|
||
ar: {
|
||
hero: {
|
||
eyebrow: 'عن المشروع',
|
||
headline: 'نحو تعزيز سيادة القانون، معًا',
|
||
subheading:
|
||
'SHARP-ER (العمل المشترك لتعزيز سيادة القانون – مسار الخروج) هو مبادرة وطنية تدعم المجتمع المدني والمؤسسات المحلية والمجتمعات الليبية في تعزيز العدالة والمساءلة والحوكمة الرشيدة.',
|
||
},
|
||
body: [
|
||
'يمتد المشروع من ديسمبر 2025 إلى ديسمبر 2027، ويُنفَّذ من قِبل منظمة Acted بالشراكة مع United Efforts Consultancy (UEC) وStichting Bureau Ensemble (SBE)، وبتمويل من الاتحاد الأوروبي. يعمل المشروع على مستوى ليبيا بأكملها، بالتعاون مع منظمات المجتمع المدني والبلديات والقيادات المجتمعية، من أجل تحسين الوصول إلى العدالة، وبناء قدرات المجتمع المدني على مساءلة المؤسسات، وتحسين الحوكمة المحلية وتقديم الخدمات.',
|
||
].join('\n\n'),
|
||
pillars: [
|
||
{
|
||
title: 'تعزيز سيادة القانون',
|
||
description: 'دعم المؤسسات المحلية لتحسين الوصول إلى العدالة وتعزيز الشفافية.',
|
||
},
|
||
{
|
||
title: 'تمكين المجتمع المدني',
|
||
description: 'بناء قدرات منظمات المجتمع المدني لتعزيز دورها في الرقابة والمساءلة.',
|
||
},
|
||
{
|
||
title: 'دعم الحوكمة المحلية',
|
||
description: 'تعزيز التعاون بين البلديات والجهات الفاعلة المحلية لتحسين تقديم الخدمات.',
|
||
},
|
||
],
|
||
legacyHeadline: 'مشروعا SHARP الأول والثاني (2019–2024)',
|
||
legacyBody:
|
||
'يبني SHARP-ER على الأساس الذي أرساه مشروعا SHARP الأول والثاني (2019–2024)، حاملًا معه شبكة الشركاء من المجتمع المدني وممارسة الحوار إلى مرحلة جديدة تركّز على الاستدامة ومسار الخروج.',
|
||
seo: {
|
||
metaTitle: 'عن مشروع SHARP-ER',
|
||
metaDescription:
|
||
'يُنفَّذ SHARP-ER من قِبل Acted بالشراكة مع United Efforts Consultancy وStichting Bureau Ensemble، وبتمويل من الاتحاد الأوروبي، من ديسمبر 2025 إلى ديسمبر 2027.',
|
||
},
|
||
},
|
||
};
|
||
|
||
/** The role chip and its line on the About page's consortium cards. */
|
||
export const CONSORTIUM_ROLES: Readonly<
|
||
Record<string, Localised<{ role: string; roleDescription: string }>>
|
||
> = {
|
||
[PARTNER_SLUGS.acted]: {
|
||
en: {
|
||
role: 'Lead implementing partner',
|
||
roleDescription: 'Overall project management and civil society sub-projects.',
|
||
},
|
||
ar: {
|
||
role: 'الشريك المنفّذ الرئيسي',
|
||
roleDescription: 'الإدارة العامة للمشروع والمشاريع الفرعية لمنظمات المجتمع المدني.',
|
||
},
|
||
},
|
||
[PARTNER_SLUGS.uec]: {
|
||
en: {
|
||
role: 'Consortium partner',
|
||
roleDescription: 'Network strengthening, dialogue, and peer-learning.',
|
||
},
|
||
ar: {
|
||
role: 'شريك في الائتلاف',
|
||
roleDescription: 'تعزيز الشبكة، والحوار، والتعلّم بين الأقران.',
|
||
},
|
||
},
|
||
[PARTNER_SLUGS.sbe]: {
|
||
en: {
|
||
role: 'Consortium partner',
|
||
roleDescription: 'Research, perception data, and knowledge publications.',
|
||
},
|
||
ar: {
|
||
role: 'شريك في الائتلاف',
|
||
roleDescription: 'البحث، وبيانات الاستطلاع، والمنشورات المعرفية.',
|
||
},
|
||
},
|
||
};
|
||
|
||
export const WHAT_WE_DO_PAGE: Localised<SeedData> = {
|
||
en: {
|
||
hero: {
|
||
headline: 'A Participatory Approach to Justice and Governance',
|
||
subheading: 'We work directly with civil society, municipalities, and communities — not around them.',
|
||
},
|
||
intro: 'SHARP-ER is organised around four connected areas of work.',
|
||
workstreams: [
|
||
{
|
||
title: 'Capacity Building',
|
||
description:
|
||
'Training civil society organisations and local actors on governance, justice, and management, and equipping the SHARP network with peer-to-peer learning.',
|
||
},
|
||
{
|
||
title: 'Institutional Support',
|
||
description:
|
||
'Strengthening the systems, procedures, and dialogue channels that connect local institutions with the people they serve.',
|
||
},
|
||
{
|
||
title: 'Community Initiatives',
|
||
description:
|
||
'Funding and supporting CSO-led sub-projects, Policy-to-Rights (P2R) projects, and human-security initiatives designed and driven by local actors.',
|
||
},
|
||
{
|
||
title: 'Dialogue and Coordination',
|
||
description:
|
||
'Running SUQ (Search, Understand, Question) dialogues and Civil Society Law Sessions that bring civic and government actors to the same table.',
|
||
},
|
||
],
|
||
/* The four clauses of the draft's "Our approach rests on four
|
||
principles..." sentence, and nothing else: the design gives each tile an
|
||
explanatory line that appears in no approved document. */
|
||
principles: [
|
||
{ title: 'Working with local actors' },
|
||
{ title: 'Promoting sustainable — not one-off — solutions' },
|
||
{ title: 'Connecting civil society with institutions' },
|
||
{ title: 'Supporting gradual, realistic institutional reform' },
|
||
],
|
||
guidingValues: [
|
||
'Dialogue',
|
||
'Community Leadership',
|
||
'Learning',
|
||
'Inclusion',
|
||
'Responsibility & Accountability',
|
||
],
|
||
seo: {
|
||
metaTitle: 'What We Do — SHARP-ER',
|
||
metaDescription:
|
||
'Capacity building, institutional support, community initiatives, and dialogue and coordination: the four connected areas of work behind SHARP-ER.',
|
||
},
|
||
},
|
||
ar: {
|
||
hero: {
|
||
headline: 'نهج تشاركي في العدالة والحوكمة',
|
||
subheading: 'نعمل مباشرة مع المجتمع المدني والبلديات والمجتمعات المحلية، لا من حولها.',
|
||
},
|
||
intro: 'يقوم عمل SHARP-ER على أربعة محاور مترابطة.',
|
||
workstreams: [
|
||
{
|
||
title: 'بناء القدرات',
|
||
description:
|
||
'تدريب منظمات المجتمع المدني والجهات المحلية على الحوكمة والعدالة والإدارة، وتزويد شبكة SHARP بالتعلّم بين الأقران.',
|
||
},
|
||
{
|
||
title: 'الدعم المؤسسي',
|
||
description: 'تعزيز الأنظمة والإجراءات وقنوات الحوار التي تربط المؤسسات المحلية بالمجتمعات التي تخدمها.',
|
||
},
|
||
{
|
||
title: 'المبادرات المجتمعية',
|
||
description:
|
||
'تمويل ودعم مشاريع فرعية تقودها منظمات المجتمع المدني، ومشاريع “من السياسة إلى الحقوق” (P2R)، ومبادرات الأمن البشري التي يصممها الفاعلون المحليون ويقودونها.',
|
||
},
|
||
{
|
||
title: 'الحوار والتنسيق',
|
||
description:
|
||
'تنظيم حوارات SUQ (ابحث، افهم، اسأل) وجلسات قانون المجتمع المدني التي تجمع الفاعلين المدنيين والحكوميين حول طاولة واحدة.',
|
||
},
|
||
],
|
||
principles: [
|
||
{ title: 'العمل مع الفاعلين المحليين' },
|
||
{ title: 'تعزيز الحلول المستدامة لا الآنية' },
|
||
{ title: 'الربط بين المجتمع المدني والمؤسسات' },
|
||
{ title: 'دعم إصلاح مؤسسي تدريجي وواقعي' },
|
||
],
|
||
guidingValues: ['الحوار', 'القيادة المجتمعية', 'التعلّم', 'الشمول', 'المساءلة والمسؤولية'],
|
||
seo: {
|
||
metaTitle: 'ماذا نفعل — SHARP-ER',
|
||
metaDescription:
|
||
'بناء القدرات، والدعم المؤسسي، والمبادرات المجتمعية، والحوار والتنسيق: المحاور الأربعة المترابطة التي يقوم عليها عمل SHARP-ER.',
|
||
},
|
||
},
|
||
};
|
||
|
||
export const CONTACT_PAGE: Localised<SeedData> = {
|
||
en: {
|
||
hero: {
|
||
headline: 'Get in Touch',
|
||
subheading: 'Questions about SHARP-ER, a partnership, or a specific activity? Reach out.',
|
||
},
|
||
intro: 'Questions about SHARP-ER, a partnership, or a specific activity? Reach out.',
|
||
websiteLabel: 'sharper.ly',
|
||
/* No `generalEmail`, no `socialLinks`, no `consortiumContacts`: the draft
|
||
writes all three as bracketed placeholders. */
|
||
seo: {
|
||
metaTitle: 'Contact SHARP-ER',
|
||
metaDescription: 'Get in touch with the SHARP-ER consortium about the project, a partnership, or a specific activity.',
|
||
},
|
||
},
|
||
ar: {
|
||
hero: {
|
||
headline: 'تواصل معنا',
|
||
subheading: 'لديك استفسار حول SHARP-ER، أو شراكة محتملة، أو نشاط معيّن؟ راسلنا.',
|
||
},
|
||
intro: 'لديك استفسار حول SHARP-ER، أو شراكة محتملة، أو نشاط معيّن؟ راسلنا.',
|
||
websiteLabel: 'sharper.ly',
|
||
seo: {
|
||
metaTitle: 'تواصل مع SHARP-ER',
|
||
metaDescription: 'تواصل مع ائتلاف SHARP-ER بشأن المشروع، أو شراكة محتملة، أو نشاط معيّن.',
|
||
},
|
||
},
|
||
};
|