# Kindergarten theme — codeless .bnp manifest (WO-TF-019, Wave A). # Synthesized into manifest.pb by `ninja plugin build` (no plugin.wasm). theme_presets: presets.json bundled_fonts: fonts.json master_pages: master_pages.json required_icon_packs: ["lucide", "simple-icons"] system_templates: - key: kindergarten title: Kindergarten description: "Preschool / daycare theme — crayon-drawn borders, sticker badges, confetti, and a bouncing-mascot canvas hero. Warm, safe, and playful, in a bright classroom by day and a quiet-time navy by night." page_templates: - system: kindergarten key: default title: Default description: "Standard rounded page — dotted-paper background, header, main, footer" slots: [header, main, footer] - system: kindergarten key: full-width title: Full Width description: "Edge-to-edge classroom / gallery showcase, no max-width" slots: [header, main, footer] - system: kindergarten key: landing title: Landing description: "Bouncing-mascot canvas hero, sticker feature cards, big confetti CTA" slots: [header, main, footer] - system: kindergarten key: article title: Story Page description: "Picture-book reading layout — prose column plus a sticker note aside" slots: [header, main, aside, footer] - system: kindergarten key: blog-index title: Blog Index description: "Story-wall feed of rounded post cards" slots: [header, main, footer] - system: kindergarten key: contact title: Contact description: "Friendly enrol / contact page — form card plus a contact sticker card" slots: [header, main, footer] - system: kindergarten key: auth title: Auth description: "Centered rounded sign-in card for login / register / reset" slots: [header, main, footer] # All 49 mandatory-tier builtin overrides (OVERRIDE-CONTRACT §1), dashed keys. template_overrides: # Chrome (4) - { template: kindergarten, block: navbar } - { template: kindergarten, block: footer } - { template: kindergarten, block: utility-bar } - { template: kindergarten, block: announcement-bar } # Marketing (12) - { template: kindergarten, block: hero } - { template: kindergarten, block: feature-grid } - { template: kindergarten, block: rich-section } - { template: kindergarten, block: stats } - { template: kindergarten, block: testimonial } - { template: kindergarten, block: logo-strip } - { template: kindergarten, block: pricing } - { template: kindergarten, block: team } - { template: kindergarten, block: faq } - { template: kindergarten, block: timeline } - { template: kindergarten, block: cta } - { template: kindergarten, block: countdown } # Primitives (11) - { template: kindergarten, block: heading } - { template: kindergarten, block: text } - { template: kindergarten, block: rich-text } - { template: kindergarten, block: image } - { template: kindergarten, block: quote } - { template: kindergarten, block: divider } - { template: kindergarten, block: button } - { template: kindergarten, block: card } - { template: kindergarten, block: gallery } - { template: kindergarten, block: video-embed } - { template: kindergarten, block: audio-embed } # Commerce / local (6) - { template: kindergarten, block: menu-list } - { template: kindergarten, block: event-list } - { template: kindergarten, block: contact-form } - { template: kindergarten, block: contact-card } - { template: kindergarten, block: hours-location } - { template: kindergarten, block: social-links } # Blog family (12) - { template: kindergarten, block: blog-hero } - { template: kindergarten, block: featured-posts } - { template: kindergarten, block: related-posts } - { template: kindergarten, block: popular-posts } - { template: kindergarten, block: category-list } - { template: kindergarten, block: post-hero } - { template: kindergarten, block: post-metadata } - { template: kindergarten, block: author-bio } - { template: kindergarten, block: author-bio-hero } - { template: kindergarten, block: newsletter-signup } - { template: kindergarten, block: breadcrumbs } - { template: kindergarten, block: sidebar-nav } # Auth surface (3) - { template: kindergarten, block: auth-form } - { template: kindergarten, block: password-reset-form } - { template: kindergarten, block: auth-status } # System (1) - { template: kindergarten, block: page-suggestions } email_wrappers: - kindergarten css: input_css_append: | /* ============================================================ Kindergarten — Preschool / daycare theme (WO-TF-019, Wave A). Crayon borders, sticker badges, confetti, primary-colour joy, and a GO-BIG bouncing-mascot canvas hero (hero/landing only). Every colour goes through hsl(var(--token)); every font-family goes through var(--font-{heading|body|mono}, ). No hardcoded hex / rgb / named colours. ============================================================ */ /* ---- Typography -------------------------------------------- */ /* Families flow through the admin-bound CSS variables; the fallback leads with the bundled OFL family so the intended look survives before the admin assigns a slot. @font-face for the bundled families is auto-emitted from fonts.json. */ .kg-body { font-family: var(--font-body, "Quicksand", "Nunito", system-ui, -apple-system, "Segoe UI", sans-serif); } .kg-display { font-family: var(--font-heading, "Baloo 2", "Fredoka", "Quicksand", system-ui, sans-serif); font-weight: 700; letter-spacing: -0.01em; } .kg-mono { font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace); } .kg-prose, .kg-prose p, .kg-prose li { font-family: var(--font-body, "Quicksand", "Nunito", sans-serif); line-height: 1.75; } .kg-prose code { color: hsl(var(--primary)); background-color: hsl(var(--muted)); padding: 0.125rem 0.4rem; border-radius: 0.5rem; font-family: var(--font-mono, ui-monospace, Menlo, monospace); font-size: 0.875em; } /* Friendly kicker: rounded, bold, primary — carries enough on its own that it is never a silent no-op used alone. */ .kg-eyebrow { font-family: var(--font-heading, "Baloo 2", "Quicksand", sans-serif); font-weight: 700; font-size: 0.85rem; letter-spacing: 0.02em; color: hsl(var(--primary)); display: inline-flex; align-items: center; gap: 0.4rem; } /* ---- Crayon underline (decorative heading accent) ---------- */ .kg-crayon-underline { position: relative; display: inline-block; } .kg-crayon-underline::after { content: ""; position: absolute; left: 0; right: 0; bottom: -6px; height: 8px; background: linear-gradient(90deg, hsl(var(--primary)) 0 26%, hsl(var(--accent)) 26% 52%, hsl(var(--secondary)) 52% 78%, hsl(var(--primary)) 78% 100%); border-radius: 6px; transform: rotate(-1deg); z-index: -1; } /* ---- Crayon / sticker primitives (drop-in surface chrome) -- */ /* kg-crayon-shadow: chunky hand-cut offset shadow + playful lift. Pairs with Tailwind border-* / rounded-* on the same element. */ .kg-crayon-shadow { box-shadow: 0 4px 0 0 hsl(var(--foreground) / 0.12); transition: transform 160ms ease, box-shadow 160ms ease; } .kg-crayon-shadow:hover, .kg-crayon-shadow:focus-within { transform: translateY(-2px); box-shadow: 0 8px 0 0 hsl(var(--foreground) / 0.14); } /* kg-drop: chunky flat button shadow (the crayon "sticker" edge). */ .kg-drop { box-shadow: 0 4px 0 0 hsl(var(--foreground) / 0.15); } /* kg-pop: playful hover bounce for buttons / interactive chips. */ .kg-pop { transition: transform 140ms cubic-bezier(0.34, 1.56, 0.64, 1); } .kg-pop:hover, .kg-pop:focus-visible { transform: translateY(-2px) scale(1.03); } .kg-pop:active { transform: translateY(1px) scale(0.98); } /* kg-sticker: peel-sticker badge — rounded, chunky, slight tilt. */ .kg-sticker { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.3rem 0.85rem; border-radius: 9999px; font-family: var(--font-heading, "Baloo 2", "Quicksand", sans-serif); font-weight: 700; font-size: 0.8rem; background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground)); box-shadow: 0 3px 0 0 hsl(var(--foreground) / 0.12); transform: rotate(-2deg); } /* Global focus-visible ring (accessibility). */ .kg-page a:focus-visible, .kg-page button:focus-visible, .kg-page input:focus-visible, .kg-page textarea:focus-visible, .kg-page select:focus-visible { outline: 3px solid hsl(var(--ring)); outline-offset: 2px; } /* ---- Page shell ------------------------------------------- */ .kg-page { font-family: var(--font-body, "Quicksand", "Nunito", system-ui, sans-serif); line-height: 1.7; background-color: hsl(var(--background)); color: hsl(var(--foreground)); } .kg-page h1, .kg-page h2, .kg-page h3, .kg-page h4, .kg-page h5, .kg-page h6 { font-family: var(--font-heading, "Baloo 2", "Quicksand", sans-serif); font-weight: 700; letter-spacing: -0.01em; } .kg-container { max-width: 72rem; margin-inline: auto; padding-inline: 1.5rem; } .kg-empty { text-align: center; padding: 2rem; border-radius: 1.5rem; border: 3px dashed hsl(var(--border)); color: hsl(var(--muted-foreground)); font-family: var(--font-body, "Quicksand", sans-serif); } /* Dotted-paper page background layer. */ .kg-dotted-paper { background-color: hsl(var(--background)); background-image: radial-gradient(circle, hsl(var(--muted-foreground) / 0.14) 1px, transparent 1.6px); background-size: 26px 26px; } /* ---- Persona-block furniture ------------------------------ */ .kg-hero-panel { border-radius: 2.5rem; padding: clamp(2rem, 6vw, 4rem); position: relative; overflow: hidden; background-color: hsl(var(--accent) / 0.15); } .kg-card { border-radius: 2rem; background-color: hsl(var(--card)); color: hsl(var(--card-foreground)); padding: 2rem; border: 3px solid hsl(var(--border)); position: relative; overflow: hidden; } /* ---- Robust responsive layout ------------------------------ */ /* The host Tailwind JIT scans rendered BUILT-IN html and lags on theme-only classes, so every layout-critical grid, section rhythm, and hero size is driven by these compiled-every-build rules — never by responsive Tailwind utilities in the theme templates (which are dropped on a cold provision). All are mobile-first: 1 column by default, widening at breakpoints. */ .kg-section { padding-block: clamp(2rem, 5vw, 3rem); } .kg-sect { padding-block: clamp(2.25rem, 5vw, 3.5rem); position: relative; } .kg-cols { display: grid; grid-template-columns: 1fr; gap: 1.5rem; } @media (min-width: 640px) { .kg-cols-2, .kg-cols-3, .kg-cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (min-width: 1024px) { .kg-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .kg-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } } /* Hero — full sizing + type in CSS so it never depends on the (unreliable) min-h-screen / responsive Tailwind in the template. */ .kg-hero { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: center; min-height: clamp(24rem, 58vh, 38rem); padding-block: clamp(2.5rem, 7vw, 4.5rem); background-color: hsl(var(--accent) / 0.15); color: hsl(var(--foreground)); } .kg-hero-media { position: absolute; inset: 0; z-index: 0; } .kg-hero-media > img { width: 100%; height: 100%; object-fit: cover; } .kg-hero-overlay { position: absolute; inset: 0; background-color: hsl(var(--foreground) / 0.4); } .kg-hero-mascot { position: absolute; left: 50%; bottom: -0.25rem; transform: translateX(-50%); width: clamp(88px, 16vw, 150px); pointer-events: none; } .kg-hero-mascot svg { width: 100%; height: auto; display: block; } .kg-hero-inner { position: relative; z-index: 10; width: 100%; max-width: 56rem; margin-inline: auto; padding-inline: 1.5rem; } .kg-hero--center { text-align: center; } .kg-hero-title { margin-top: 1rem; font-size: clamp(2.25rem, 6vw, 3.75rem); line-height: 1.06; } .kg-hero-abc { display: inline-flex; gap: 0.35rem; margin-top: 1.1rem; font-size: clamp(1.5rem, 4vw, 2rem); } .kg-hero-abc .kg-wiggle-letter:nth-child(1) { color: hsl(var(--primary)); } .kg-hero-abc .kg-wiggle-letter:nth-child(2) { color: hsl(var(--secondary)); } .kg-hero-abc .kg-wiggle-letter:nth-child(3) { color: hsl(var(--accent)); } .kg-hero-sub { margin-top: 1rem; font-size: clamp(1.125rem, 2.5vw, 1.5rem); color: hsl(var(--muted-foreground)); max-width: 42rem; } .kg-hero-desc { margin-top: 0.75rem; color: hsl(var(--muted-foreground)); max-width: 36rem; line-height: 1.6; } .kg-hero--center .kg-hero-sub, .kg-hero--center .kg-hero-desc { margin-inline: auto; } .kg-hero-cta { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 2rem; } .kg-hero--center .kg-hero-cta { justify-content: center; } .kg-hero-trust { margin-top: 2.5rem; } .kg-hero-logos { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; margin-top: 0.75rem; } .kg-hero--center .kg-hero-logos { justify-content: center; } /* Chunky rounded buttons (crayon sticker edge). */ .kg-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; border-radius: 9999px; padding: 0.85rem 1.75rem; font-family: var(--font-heading, "Baloo 2", "Quicksand", sans-serif); font-weight: 700; font-size: 1.05rem; line-height: 1.1; text-decoration: none; } .kg-btn-primary { background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); box-shadow: 0 4px 0 0 hsl(var(--foreground) / 0.15); } .kg-btn-outline { background-color: hsl(var(--background)); color: hsl(var(--primary)); border: 3px solid hsl(var(--primary)); } /* Alphabet strip (persona block). */ .kg-alphabet-strip { display: flex; flex-wrap: nowrap; gap: 0.6rem; padding: 0.6rem 1rem; overflow-x: auto; scrollbar-width: thin; -webkit-overflow-scrolling: touch; } .kg-alphabet-letter { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 56px; height: 56px; border-radius: 1.25rem; font-family: var(--font-heading, "Baloo 2", "Quicksand", sans-serif); font-weight: 700; font-size: 1.5rem; box-shadow: 0 4px 0 0 hsl(var(--foreground) / 0.12); } .kg-alphabet-letter:nth-child(4n+1) { background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); } .kg-alphabet-letter:nth-child(4n+2) { background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); } .kg-alphabet-letter:nth-child(4n+3) { background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground)); } .kg-alphabet-letter:nth-child(4n+4) { background-color: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); } .kg-alphabet-mono .kg-alphabet-letter { background-color: hsl(var(--muted)); color: hsl(var(--muted-foreground)); } .kg-alphabet-primary .kg-alphabet-letter { background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); } /* Day schedule (persona block). */ .kg-schedule-item { display: grid; grid-template-columns: auto 1fr auto; gap: 1rem; align-items: center; padding: 1rem 1.25rem; border-radius: 1.5rem; background-color: hsl(var(--card)); border: 3px solid hsl(var(--border)); margin-bottom: 0.75rem; } .kg-schedule-time { display: inline-flex; align-items: center; justify-content: center; padding: 0.25rem 0.85rem; border-radius: 9999px; background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground)); font-family: var(--font-mono, ui-monospace, monospace); font-weight: 700; } .kg-schedule-activity { color: hsl(var(--foreground)); } .kg-schedule-icon { color: hsl(var(--primary)); } /* Art-wall polaroid (persona block). */ .kg-gallery-grid { display: grid; grid-template-columns: 1fr; gap: 1.5rem; } @media (min-width: 640px) { .kg-gallery-grid { grid-template-columns: repeat(2, 1fr); } } @media (min-width: 1024px) { .kg-gallery-grid { grid-template-columns: repeat(3, 1fr); } } .kg-polaroid { background-color: hsl(var(--card)); border-radius: 1rem; padding: 12px 12px 36px; box-shadow: 0 6px 24px hsl(var(--foreground) / 0.12); transform: rotate(-1.5deg); transition: transform 200ms ease; } .kg-polaroid:nth-child(2n) { transform: rotate(1.5deg); } .kg-polaroid:nth-child(3n) { transform: rotate(-0.5deg); } .kg-polaroid:hover { transform: rotate(0deg); } .kg-polaroid > img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 0.5rem; background-color: hsl(var(--muted)); } /* Empty-media graceful state: a compact, playful crayon wash — NOT a ballooning blank square. Shorter aspect + capped height so three imageless polaroids never dominate the page. */ .kg-polaroid > .kg-polaroid-image { display: block; width: 100%; aspect-ratio: 4 / 3; max-height: 220px; border-radius: 0.5rem; background-color: hsl(var(--accent) / 0.16); background-image: radial-gradient(circle at 50% 46%, hsl(var(--primary) / 0.38) 0 9%, transparent 10%), radial-gradient(circle, hsl(var(--foreground) / 0.10) 1.5px, transparent 2px); background-size: 100% 100%, 20px 20px; background-position: center center, center center; background-repeat: no-repeat, repeat; } .kg-polaroid-caption { text-align: center; margin-top: 0.75rem; font-family: var(--font-heading, "Baloo 2", "Quicksand", sans-serif); color: hsl(var(--foreground)); } /* Story-time open book (persona block). */ .kg-storybook { display: grid; grid-template-columns: 1fr; gap: 2rem; padding: 2rem; border-radius: 2rem; background-color: hsl(var(--card)); border: 3px solid hsl(var(--border)); } @media (min-width: 768px) { .kg-storybook { grid-template-columns: 1fr 1fr; align-items: center; } } .kg-storybook-quote { font-family: var(--font-heading, "Baloo 2", "Quicksand", sans-serif); font-size: clamp(1.25rem, 3vw, 2rem); line-height: 1.4; color: hsl(var(--foreground)); } .kg-storybook-illustration { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 1.25rem; background-color: hsl(var(--muted)); } /* ---- GO-BIG motion: bouncing mascot + wiggling letters ----- */ /* The canvas confetti/mascot showpiece lives ONLY on the hero override (hero/landing). It lazy-inits on view, honours prefers-reduced-motion, and degrades to a static confetti wash with JS off. No canvas anywhere else in the theme. */ .kg-mascot { display: inline-block; transform-origin: center bottom; animation: kg-bounce 2.4s ease-in-out infinite; } @keyframes kg-bounce { 0%, 100% { transform: translateY(0) rotate(-1deg); } 50% { transform: translateY(-16px) rotate(1deg); } } .kg-wiggle-letter { display: inline-block; animation: kg-wiggle 2.2s ease-in-out infinite; } .kg-wiggle-letter:nth-child(2n) { animation-delay: 0.15s; } .kg-wiggle-letter:nth-child(3n) { animation-delay: 0.3s; } .kg-wiggle-letter:nth-child(4n) { animation-delay: 0.45s; } @keyframes kg-wiggle { 0%, 100% { transform: rotate(-5deg); } 50% { transform: rotate(5deg); } } /* Confetti canvas + static no-JS fallback. */ .kg-confetti-wrap { position: absolute; inset: 0; overflow: hidden; pointer-events: none; } .kg-confetti-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; } .kg-confetti-fallback { position: absolute; inset: 0; pointer-events: none; background-image: radial-gradient(circle, hsl(var(--primary) / 0.55) 8px, transparent 9px), radial-gradient(circle, hsl(var(--secondary) / 0.55) 6px, transparent 7px), radial-gradient(circle, hsl(var(--accent) / 0.6) 5px, transparent 6px); background-size: 90px 90px, 60px 60px, 40px 40px; background-position: 12% 18%, 72% 28%, 42% 78%; opacity: 0.55; } /* ---- Reduced motion: freeze everything -------------------- */ @media (prefers-reduced-motion: reduce) { .kg-mascot, .kg-wiggle-letter, .kg-confetti-canvas { animation: none !important; } .kg-confetti-canvas { display: none; } .kg-pop:hover, .kg-pop:focus-visible, .kg-crayon-shadow:hover, .kg-crayon-shadow:focus-within { transform: none; } }