Synaplan
開源 AI 平台,供企業使用:自行託管的 AI 代理、符合 GDPR 的聊天機器人小工具、RAG 知識庫、WhatsApp 與 Outlook AI、MCP、多模型路由。Docker、Kubernetes 或託管於 Germ
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
The public marketing site for Peekaboo — the nursery operating system by
Educore Systems & Technologies, Dubai.
Built with Astro and Sanity, and brand-matched to the live
Peekaboo Care portal and the Peekaboo Parent
mobile app.
Intended repository: peekaboo-website.
The repo contains two website concepts sharing one design system, content
layer and set of product visuals:
Concept B additionally has a light/dark theme switch using the portal's own
dark palette. To promote either concept to the main site, rename its page file
to index.astro.檢視完整 README ↗The public marketing site for Peekaboo — the nursery operating system by Educore Systems & Technologies, Dubai.
Built with Astro and Sanity, and brand-matched to the live Peekaboo Care portal and the Peekaboo Parent mobile app.
Intended repository: peekaboo-website.
The repo contains two website concepts sharing one design system, content layer and set of product visuals:
| Route | Shape | |
|---|---|---|
| Concept A | / | Multi-page — home plus /features, /solutions, /peekaboo-care, /peekaboo-parent, /about |
| Concept B | /v2 | Single-page guided scroll — the whole story in one page, following the existing site's Plans → Our App → Features → Improve → About → Why Us → Curriculum → Contact journey |
Concept B additionally has a light/dark theme switch using the portal's own
dark palette. To promote either concept to the main site, rename its page file
to index.astro.
| Concern | Choice |
|---|---|
| Framework | Astro — static-first; only /api/contact runs on demand |
| Language | TypeScript, strict |
| Styling | Tailwind CSS v4, design tokens in src/styles/global.css |
| CMS | Sanity (standalone Studio in studio/) |
| Validation | Zod (shared between client and server) |
| Icons | @lucide/astro |
| Hosting | Vercel (@astrojs/vercel) |
The site ships zero JavaScript bundles. The three interactive pieces (mobile nav, platform explorer, contact form) are small inline scripts that progressively enhance working HTML.
npm install
cp .env.example .env
npm run dev # http://localhost:4321
The site runs fully populated without any Sanity project configured. Every
query falls back to bundled content in src/lib/content/, so you can develop
the design before content exists — and a CMS outage in production degrades to
slightly stale copy rather than a broken page.
None are required to run locally. See .env.example.
| Variable | Purpose |
|---|---|
SANITY_PROJECT_ID, SANITY_DATASET, SANITY_API_VERSION | Connect a Sanity project. Unset ⇒ bundled content. |
RESEND_API_KEY, CONTACT_TO_EMAIL | Email delivery for the demo request form. Unset ⇒ submissions validate and succeed but are logged to the server console instead of sent. |
Never commit .env. Only .env.example (placeholders) is tracked.
| Command | Action |
|---|---|
npm run dev | Dev server on localhost:4321 |
npm run build | astro check then production build to dist/ |
npm run preview | Preview the production build |
npm run astro check | Type-check only |
src/
├── pages/ # one file per route
│ ├── index.astro / homepage
│ ├── features.astro /features all seven platform areas
│ ├── solutions.astro /solutions the three adoption models
│ ├── peekaboo-care.astro /peekaboo-care staff portal
│ ├── peekaboo-parent.astro /peekaboo-parent parent app
│ ├── about.astro, contact.astro, privacy.astro, terms.astro, 404.astro
│ └── api/contact.ts POST endpoint for the demo form
├── layouts/
│ ├── BaseLayout.astro <head>, SEO, OG, JSON-LD, skip link
│ └── PageLayout.astro header + footer shell
├── components/
│ ├── ui/ Button, Card, Badge, Section, Container, Logo…
│ ├── nav/ Header (+ mobile menu), Footer
│ ├── product/ portal & parent-app UI recreations
│ └── sections/ Hero, ModuleExplorer, Curriculum, Solutions…
├── lib/
│ ├── content/ typed content: site, modules, solutions, marketing
│ ├── sanity/ client, image builder, GROQ queries
│ ├── validations/ Zod schemas
│ └── seo.ts per-page SEO + structured data
└── styles/global.css design tokens + font faces
studio/ standalone Sanity Studio
This is the most important thing to understand before editing.
In code (src/lib/content/) — the product's capability structure: the
seven platform areas and their capabilities, the three adoption models, the
Peekaboo Care / Peekaboo Parent product definitions, curriculum steps and
contact details. This describes what the software actually does, so it's
version-controlled and reviewed rather than editable into drift.
In Sanity — editorial copy: the hero headline and buttons, site navigation and footer, the About/Privacy/Terms pages, FAQs, testimonials, and per-page SEO.
That split is deliberate. A fully generic page builder would let an editor accidentally dismantle the design or claim a feature that doesn't exist; this gives editors real control over messaging with guardrails around product truth.
cd studio
npm install
cp .env.example .env # add SANITY_STUDIO_PROJECT_ID
npm run dev # http://localhost:3333
Create a project at sanity.io/manage or via
npx sanity@latest init. Use a new, dedicated project for the website
rather than the one behind the portal, so marketing content and product data
stay decoupled.
Document types: siteSettings and homePage are singletons (pinned at the
top of the Studio); page, faq and testimonial are collections.
Testimonials are intentionally empty. The section is hidden on the site until at least one real, attributable customer quote exists. Please don't add invented quotes to fill it.
Marketing copy on this site is deliberately constrained to what can be verified against the product:
src/lib/content/modules.ts maps
to a real module in the Peekaboo Care portal.If a claim can't be verified, it isn't on the site.
Tokens in src/styles/global.css are taken from the portal's own
src/index.css — the same sky/gold/coral/mint/violet palette, the Baloo 2 +
Manrope pairing, and the 1.45rem-based radius scale — so the website and the
product visibly belong together.
One deliberate deviation: the portal's button gradient (#2fc5f7 → #1cb6ea)
gives white text a 2.35:1 contrast ratio, well below the 4.5:1 WCAG AA
requires. The website's primary button uses the same hue deepened to
#0e7fa8 → #0e77a1 (4.55:1) so the label is actually readable. The bright
brand blue is retained everywhere it isn't sitting behind text. Several
secondary text tokens were darkened for the same reason — each is annotated in
global.css.
The single-page concept can switch between light and dark, using the exact
palette from the portal's own .dark block — so a visitor who toggles the
website and then signs into the portal sees the same deep navy and warm
off-white.
Only a small set of semantic tokens change between themes: --color-canvas,
--color-surface, --color-line, the three text levels, and the accent
"ink" colours. The fixed scales (ink-*, brand-*) don't move, which is what
keeps surfaces that are deliberately dark in both themes — portal previews,
the footer, CTA banners — looking identical either way.
Components opt in by using bg-surface / text-body / text-muted /
border-line instead of bg-white / text-ink-900. Anything still using the
fixed scale stays put by design.
The theme is applied by a .dark class on <html>, set by a small inline
script in <head> before first paint so there's no flash of the wrong theme.
A stored choice wins over the OS setting; with no stored choice we follow
prefers-color-scheme. All dark-theme text was contrast-checked numerically,
including alpha-composited chip backgrounds.
The portal and app visuals in src/components/product/ are reproduced in
markup, not screenshots. Layout, navigation grouping, terminology and colours
come from the real product, but rendering them as HTML means they stay crisp at
any resolution, reflow on mobile, add no image weight, and carry clean demo
data — the live environment's seed data contains lorem ipsum and malformed
timestamps that would otherwise appear on the marketing site.
tabindex and
arrow/Home/End key supportaria-invalid + aria-describedby, and focus
moves to the first invalid field or to the result banner*-onDark status tokensprefers-reduced-motion disables animation and smooth scrollingConfigured for Vercel. Set the environment variables above in the project
settings and deploy — nine pages prerender to static HTML; only
/api/contact runs as a function.
Astro's checkOrigin protection is active, so POST /api/contact rejects
cross-site submissions. Same-origin browser requests are unaffected.
The architecture supports it without rework: add a post document type in
studio/schemaTypes/, a query in src/lib/sanity/queries.ts, and
src/pages/blog/[slug].astro. It's deliberately not scaffolded now — an empty
blog route is a placeholder, and this site doesn't ship placeholders.