* fix(web): build through turbo instead of rebuilding shared deps
The app build re-ran the logos-ui build, whose `tsup --clean` wiped
packages/ui/dist while logos-crm compiled against it in parallel. The deploy
now runs the same turbo build as CI, so only the ui task writes that dist.
`out/**` joins the build outputs since turbo owns the export now.
* docs(web): build the app through turbo
* fix(web): build on Vercel through turbo
Vercel ran the app build directly, which no longer builds
@acid-info/logos-ui and failed to resolve it. vercel.json pins the deploy to
the same turbo command Jenkins runs.
* refactor(civi-crm): remove case management pages and API
The Circle Case UI, its API routes and the CiviCRM query layer they used
are gone. Keeps the app shell out entirely: no pages remain, so the
layout, styles and UI dependencies go with them.
* refactor(civi-crm): drop CiviCRM write from the intake endpoint
Submissions now go to Notion and, for the steward form, n8n. The legacy
afformCircleContactForm name was CiviCRM-only and is no longer accepted;
the fields[] payload is ignored.
* chore(web): remove CiviCRM afform generator scripts
They fetched form definitions from the CiviCRM API, which is gone. The
generated files under lib/civicrm are hand-maintained from now on.
* refactor(web): trim funnel form definitions and move to lib/funnel-forms
Fields keep only what renders the form: formKey, label, inputType,
required, repeatable. The CiviCRM entity/join/fieldName plumbing and the
fields[] POST payload are gone, along with the unused circle contact
form.
country was marked required but exempt from validation through its
CiviCRM Address join, so it is now enforced like every other required
select.
* docs: rewrite civi-crm and funnel docs for the intake-only app
Drops the CiviCRM API guide and the case management architecture, and
updates the funnel reference to the Notion + n8n flow.
* docs: add page-copy single-source spec and implementation plan
* feat(content): add typed home section schemas and migrate home copy into content
Add 7 bespoke home* section schemas (+ techStack ctas) to the page section
union and populate content/pages/en/home.json with home copy moved verbatim
from messages.
* refactor(web): source home page copy from @repo/content; drop home namespace from messages
Feed every home section from content via findSection/data props (replacing
next-intl getTranslations), remove the home namespace from messages/en.json,
and add a regression guard plus content-based tests. Render output unchanged.
* docs: add get-started/movement page-copy dedup spec and plan
* feat(content): add get-started & movement section schemas and content docs
Move get-started/movement page copy verbatim into content/pages so it is
single-sourced in @repo/content.
* refactor(web): source get-started/movement copy from content; drop those namespaces from messages
Feed both pages from content via findSection/data props (replacing next-intl),
switch them to content-based metadata, delete pages.getStarted/movement from
messages, and add content-based tests + ownership guard. Render unchanged.
* docs: add navbar-pages CMS copy spec and plan
* feat(content): add navbar page section schemas + Pages docs (book, brand-kit, research, node-programme, lambda-prize, manifesto, media, podcast, broadcast, tech-stack explorer)
* refactor(web): source navbar pages copy from content; drop those namespaces from messages
Migrate book, brand-kit, research (incl. rich-text via a tagged-text renderer),
node-programme, lambda-prize, manifesto, media, podcast, logos-broadcast-network,
and the tech-stack explorer to read copy from content via findSection/data props
and content-based metadata; remove the migrated pages.* namespaces from messages;
update guards + contracts. Render output unchanged.
* feat(web): source activist/coalition pages copy from content (CMS title/description)
Migrate activistBuilder, activistLeaderSteward, and coalitionPartner page
metadata from next-intl messages.pages.* into @repo/content PageCopy JSON,
following the established bookCopy pattern.
- Add activistBuilderCopySectionSchema, activistLeaderStewardCopySectionSchema,
coalitionPartnerCopySectionSchema to packages/content/src/schemas/pages.ts
and wire them into the pageSectionSchema discriminated union
- Create content/pages/en/activist-builder.json,
activist-leader-steward.json, coalition-partner.json with verbatim
title/description/heading values from the old messages namespace
- Switch all three route pages from createTranslatedPageMetadata to
createPageMetadata(ROUTE), removing the NAMESPACE constant
- Remove activistBuilder, activistLeaderSteward, coalitionPartner from
apps/web/messages/en.json pages object
- Add schema parse tests, renderToStaticMarkup page tests, messages ownership
guards, and content-route contract entries for all three pages
* chore(web): remove dead faq (pages.faq + unused FaqSection components)
* fix: remove stale faq links
* fix: pass payload env through turbo build
* fix: preserve lambda prize support labels
* fix: preserve live copy after master rebase
* fix: address page copy review feedback
* refactor: move design guide copy to content
* feat: add schemas for home and page copy sections
- Introduced home section schemas including homeSocialProof, homeChoosePath, homeDecide, homeStartBuilding, homeAbout, homeUseCases, and homeBuilderPortal.
- Added page copy section schemas such as getStartedCopy, movementCopy, bookCopy, designGuideCopy, activistBuilderCopy, activistLeaderStewardCopy, coalitionPartnerCopy, researchCopy, nodeProgrammeCopy, lambdaPrizeCopy, mediaCopy, podcastCopy, broadcastCopy, and manifestoCopy.
- Created shared schema for section keys to maintain consistency across sections.
* chore(web): remove dead pages.faq from messages
* fix: resolve page copy migration conflicts
* fix: source connect form page copy from content
* fix: remove duplicated afform page copy exports
* fix: stop generating afform page copy exports
* fix(cms): require only server actions key
* fix(cms): load env files before build validation
* fix(cms): make env loader available during build
* fix(cms): load next env via require
* test(cms): isolate missing env validation
* feat: add homepage testnet highlight
* fix: restore lambda prize support links
* chore: add Notion evaluation template
Use the evaluation template for intake-created Notion pages and document the helper module.
* ci: authenticate build-time GitHub API calls
Pass the Actions GITHUB_TOKEN to the web build (via turbo passThroughEnv)
so RFP fetches in generateStaticParams() avoid the unauthenticated
60 req/hr limit that intermittently 403s and fails the static export.
* feat(ui): add LogosWordmark icon
SVG wordmark for the "Logos" brand name, using fill-current so color
is driven by surrounding text color -- matching the pattern of LogosMark.
* fix(web): align navbar brand lockup with Figma
- Shrink lambda mark from 14px to 11px (Figma: 8x11px vector)
- Tighten brand lockup gap from 6px to 4px
- Replace text label with LogosWordmark SVG; keep sr-only span for a11y
- Fix mobile brand link typography (was font-serif 18px, now text-eyebrow)
- Nudge wordmark down 1px to optically align with the lambda mark
* fix(ui): align overlay navbar brand lockup and typography with Figma
- Replace text logoLabel fallback with LogosMark + LogosWordmark SVGs
- Move logo top from md:top-1.5 to top-3.5 to align with panel tabs
- Remove tracking-[0.08em] and add font-semibold on panel tab buttons
- Increase CTA vertical padding from py-2 to py-2.5
* fix(web): align closed navbar brand lockup, typography, and layout with Figma
- Remove BrandLockup wrapper; inline LogosMark + LogosWordmark directly
- Remove tracking-[0.08em] and add font-semibold on nav link buttons
- Increase desktop CTA vertical padding from min-h-7 to py-2.5
- Restructure desktop bar to absolute positioning (relative container)
so logo, nav, and CTA positions mirror the overlay header exactly
- Mobile bar: add relative positioning; logo now uses absolute top-3.5 left-3
* fix(ui): vertically center overlay header elements
- Logo and close button: top-3.5/top-[14px] → top-1/2 -translate-y-1/2
(elements live inside the 42px OverlayHeader, so 50% resolves correctly)
- Nav tabs and CTA: top-3.5/top-1.5 → top-[22.5px]/top-[22px] -translate-y-1/2
(elements live in the outer 700px container, so a fixed value matching
the header mid-point is used instead of 50%)
- Nav tabs: items-start → items-center to match the centered position
* fix(web): vertically center navbar and fix mobile menu gap
- Mobile bar: replace 3-col grid with flat relative container; remove
dead-code nav/CTA shell that was never visible at mobile widths
- Mobile logo: top-3.5 → top-1/2 -translate-y-1/2 (true vertical center)
- Mobile hamburger: repositioned from grid col-2 (50% center) to
left-[62.5%] -translate-x-1/2 (matches overlay close button and
Figma spec), adding gap between logo and menu; add font-semibold
- Desktop logo, nav tabs, CTA: top-3.5/top-1.5 → top-1/2 -translate-y-1/2
* fix(ui): update arrow icon and add hover effects to button variants
- Replace ButtonArrowIcon SVG with filled 10x10 arrow, increase gap to 1.5
- Primary: hover:bg-accent-steel-teal (#5F797C)
- Secondary: hover:bg-gray-02 (#B8BDB8) with border cleared on hover
* fix(web): update download icon style
* fix(web): fit status CTA button to content width
* feat(ui): add dev watch mode for packages/ui
Adds a tsup --watch script to packages/ui so it rebuilds automatically
when sources change during pnpm dev:web. The turbo.json override ensures
the watch process only starts after the initial clean build completes.
* fix(nav-overlay): adjust mobile layout for better visibility and spacing
* fix: use canonical press reading times
* fix: reduce homepage motion intensity
* chore: build workspace packages before dev
apps/web (and civi-crm/cms) import @acid-info/logos-ui, which resolves
to packages/ui/dist via the package exports field. The previous
check-types task only depended on ^check-types, so on a clean checkout
(CI) packages/ui/dist did not exist when web#check-types ran and TS
emitted TS2307 for every logos-ui import. Locally it worked only
because a prior pnpm build had populated dist.
Add ^build to check-types#dependsOn so Turbo cascades upstream package
builds first. Verified by wiping packages/ui/dist plus all .next and
out directories, then running pnpm test:release end-to-end green.
* feat(civi-crm-cms): add project architecture documentation
* chore(civi-crm-cms): register app in mono-repo
Add civi-crm-cms env vars to turbo.json build.env. Update root AGENTS.md
with app entry (port 3002, arch doc link) and dev command. Update lockfile.
* chore(civi-crm-cms): scaffold app config and tooling
Next.js 16, Tailwind v4, Vitest, ESLint, PostCSS — matching apps/web
conventions. Path alias @/* → ./src/*. Port 3002. AGENTS.md links to
the architecture doc and documents doc-update rules and code conventions.
* feat(civi-crm-cms): add lib layer, view config, and domain type stubs
- views.ts: full ViewConfig types + circles_onboarding config + getActiveView()
- auth.ts: getCurrentUserEmail() — DEV_USER_EMAIL_MOCK override + Keycloak header
- civicrm/client.ts: CiviCRMClient skeleton with typed interface
- civicrm/scorecard.ts: computeScorecard() pure function (tested, 4 passing)
- civicrm/{cases,contacts,activities,relationships,coordinators}.ts: stubs
- activity-logger.ts: logActivity() stub
- constants/pagination.ts: PAGE_SIZE = 20
- types/{case,contact}.ts: placeholder stubs
* feat(civi-crm-cms): add app router skeleton
Root layout + redirect to /cases. Page stubs for list and detail views.
Server Actions stub (updateCase, updateContact, swapCoordinator).
API route stubs returning 501 for all planned endpoints:
GET /api/cases, GET+PATCH /api/cases/[id], GET /api/cases/[id]/activities,
PATCH /api/cases/[id]/coordinator, PATCH /api/contacts/[contactId],
GET /api/coordinators.
* feat(civi-crm-cms): add component stubs
AppNav, CasesTable, CasesFilters, CaseDetailShell, CaseFields,
ContactFields, Scorecard, ActivityLog — each returns null with a
TODO comment describing its role per the architecture doc.
* fix(civi-crm-cms): add assignedTo FieldDef backed by Relationship entity
Adds a missing FieldDef for the `assignedTo` listColumn so that
`getFieldDef()` no longer throws when rendering or building select[] for
that column. The field is `readonly` with a dedicated `Relationship`
UpdateTarget, reflecting that coordinator assignment goes through
CiviCRM's Relationship entity rather than a direct Case/Contact PATCH.
* chore(civi-crm-cms): update architecture docs
Remove mention of repo pending node & pnpm upgrade.
* docs(civi-crm-cms): align ActivityLog Server/Client boundary description
The table incorrectly said ActivityLog had no client-side fetching, but
the stub and the dedicated GET /api/cases/[id]/activities?page= route
both indicate it fetches on page change. Corrected to reflect that
ActivityLog is a client-fetching component, with a note that the Server
Component shell can pre-fetch page 1 to avoid a first-render waterfall.
* docs(civi-crm-cms): fix globals.css snippet to use Tailwind v4 import syntax
The snippet used `@tailwind utilities;` which is a v3 directive. Updated
to match the actual app file and apps/web pattern: `@import 'tailwindcss'`
plus the `@source` directive for the shared UI package. Added a note
clarifying that the v3 directives must not be used.
* fix(civi-crm-cms): guard DEV_USER_EMAIL_MOCK against production
* fix(civi-crm-cms): strengthen views and client stubs
- Add skipSelect flag to FieldDef; mark assignedTo so select[] builders
have a typed signal to exclude it rather than relying on comments
- Add assertViewIntegrity() called from getActiveView() to catch
scorecardFieldKeys referencing unknown or non-scorecard field keys at startup
- Add constructor to CiviCRMClient wiring CIVICRM_BASE_URL / CIVICRM_API_KEY
- Remove spurious blank lines in update() params
- Document null as a valid CiviWhere value for IS NULL / IS NOT NULL operators
* docs(civi-crm-cms): sync architecture doc with code fixes
- Fix /case/[id] → /cases/[id] route path in §1
- Add Relationship to UpdateTarget union in §5.2
- Add skipSelect to FieldDef snippet in §5.2
- Update auth.ts snippet in §8 to show NODE_ENV guard with explanation
- Add null to CiviWhere type in §6.1 with IS NULL / IS NOT NULL note
* refactor(civi-crm-cms): rename circles_onboarding view to movement_view
Renames the view ID, variable, label, and caseTypeName throughout:
- src/lib/views.ts: const + registry key + ACTIVE_VIEW default
- .env.local.example: ACTIVE_VIEW default value
- docs/civi-crm-cms-architecture.md: §5.1, §5.3, §13 snippets
* refactor(civi-crm): rename civi-crm-cms app
Align app naming, paths, and docs with its role as a CiviCRM web layer.
- Updated error messages for clarity in GitHub client and configuration files.
- Reformatted code for better alignment and readability in various files including mutations, loaders, and schemas.
- Enhanced error handling by including causes in error messages where applicable.
- Adjusted function signatures for consistency across loaders and schemas.
- Added missing dependencies in turbo.json for test command.