<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sundas Naeem</title>
    <description>The latest articles on DEV Community by Sundas Naeem (@sundas_naeem_6f4864a7c69d).</description>
    <link>https://dev.to/sundas_naeem_6f4864a7c69d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4142782%2F8ae75bd2-6e29-4226-9296-300cdd7b280d.png</url>
      <title>DEV Community: Sundas Naeem</title>
      <link>https://dev.to/sundas_naeem_6f4864a7c69d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sundas_naeem_6f4864a7c69d"/>
    <language>en</language>
    <item>
      <title>Vibe Canvas: A Spatial AI-Themed Landing Page an Owner Can Reshape from Sanity Studio</title>
      <dc:creator>Sundas Naeem</dc:creator>
      <pubDate>Sun, 04 Oct 2026 16:00:33 +0000</pubDate>
      <link>https://dev.to/sundas_naeem_6f4864a7c69d/vibe-canvas-a-spatial-ai-themed-landing-page-an-owner-can-reshape-from-sanity-studio-58ll</link>
      <guid>https://dev.to/sundas_naeem_6f4864a7c69d/vibe-canvas-a-spatial-ai-themed-landing-page-an-owner-can-reshape-from-sanity-studio-58ll</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/sanity-2026-09-16"&gt;Sanity Challenge, Path Two: Vibe-Code Something Strange&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Vibe Canvas is a landing page builder for a solo creator/small brand that&lt;br&gt;
wants a distinctive, animated "spatial" hero page — floating nodes, custom&lt;br&gt;
theme presets (Cyberpunk, Vaporwave, Zen Minimal, Aurora Glitch), and a&lt;br&gt;
live-tunable color palette — without touching code. The owner edits&lt;br&gt;
everything from Sanity Studio: theme, colors, layout (floating grid /&lt;br&gt;
circular orbit / 3D card stack), heading copy, and up to several&lt;br&gt;
interactive "nodes" with their own label, description and position.&lt;/p&gt;

&lt;p&gt;It's built for someone who wants their landing page to feel alive and&lt;br&gt;
on-brand, and who needs a lightweight editorial workflow (draft → review →&lt;br&gt;
approved → live) before anything goes public — useful for a small team&lt;br&gt;
where one person writes copy and another approves before it's published.&lt;/p&gt;

&lt;p&gt;I built this to explore how far Sanity's Studio customization can go: a&lt;br&gt;
genuinely useful custom input component (not just a demo), a real&lt;br&gt;
multi-step editorial workflow modeled as document fields, and Visual&lt;br&gt;
Editing wired end-to-end so clicking an empty field on the live page jumps&lt;br&gt;
straight into Studio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Live site: &lt;a href="https://vibe-canvas-production.up.railway.app" rel="noopener noreferrer"&gt;https://vibe-canvas-production.up.railway.app&lt;/a&gt;&lt;br&gt;
Studio: &lt;a href="https://vibe-canvas-production.up.railway.app/studio" rel="noopener noreferrer"&gt;https://vibe-canvas-production.up.railway.app/studio&lt;/a&gt;&lt;br&gt;
video demo:&lt;a href="https://drive.google.com/file/d/1ZKCCdWzNjrtkRFo0FXqKb09ZVV0ir4UF/view?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/file/d/1ZKCCdWzNjrtkRFo0FXqKb09ZVV0ir4UF/view?usp=sharing&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sundanaeem-systems/vibe-canvas" rel="noopener noreferrer"&gt;https://github.com/sundanaeem-systems/vibe-canvas&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Build Process
&lt;/h2&gt;

&lt;p&gt;I built this with an AI coding assistant on Next.js 15 + Sanity Studio v3,&lt;br&gt;
deployed to Railway.&lt;/p&gt;

&lt;p&gt;What worked well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A custom Studio input component (ColorPalettePicker) that computes real
WCAG 2.1 contrast ratios (relative luminance math) against black/white
and shows AA/AAA/Fail badges live as the editor picks a color — this
went well beyond a cosmetic color swatch.&lt;/li&gt;
&lt;li&gt;A custom document action ("Deploy Vibe") that publishes and calls an
external revalidate API in one click, with toast feedback at each step.&lt;/li&gt;
&lt;li&gt;A full editorial workflow modeled as data next to the content:
reviewStatus (draft/in-review/approved/live), an append-only
reviewHistory audit trail (actor + timestamp per transition), and
custom document actions (Submit for Review, Approve, Send Back to
Draft, Go Live) that only appear for the document's current stage.
"Deploy Vibe" itself is gated — disabled until a document reaches
Approved/Live — and a custom Studio structure splits documents into
Needs Review / Approved / Live / All Drafts sidebar views, so an
approver's inbox is just a click away.&lt;/li&gt;
&lt;li&gt;Presentation + Visual Editing: the public page highlights empty fields
and lets an editor click straight into Studio from the live page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where I got stuck:&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;Deployment surfaced real issues a local dev server hides: a stray
trailing space in an env variable broke Sanity client initialization
with a cryptic "&lt;code&gt;projectId&lt;/code&gt; can only contain a-z, 0-9 and dashes"
error; a stale lockfile pinned Next.js to a version with known
security advisories and Railway's build scanner blocked the build
until I regenerated it; and NEXT_PUBLIC_* variables had to be present
&lt;em&gt;before&lt;/em&gt; the build step, not just at runtime, since Next.js inlines
them at build time.&lt;/li&gt;

&lt;li&gt;Sanity's Studio owns its own internal router, so a Next.js  into
/studio left the Studio shell blank — swapping it for a plain &lt;a&gt; tag&lt;br&gt;
(forcing a full page load) fixed it.&lt;/a&gt;
&lt;/li&gt;
&lt;a&gt;&lt;br&gt;
&lt;/a&gt;
&lt;/ul&gt;
&lt;a&gt;

&lt;p&gt;I didn't reach the App SDK or Workflows-as-a-plugin in this build; the&lt;br&gt;
editorial workflow here is modeled directly as schema fields and document&lt;br&gt;
actions rather than the dedicated Workflows feature, which is the next&lt;br&gt;
thing I'd explore.&lt;/p&gt;

&lt;/a&gt;&lt;h2&gt;
&lt;a&gt;&lt;br&gt;
  &lt;/a&gt;&lt;br&gt;
  &lt;br&gt;
  Sanity Project Details&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Sanity Project ID: lvf6oqo1&lt;br&gt;
Dataset: production&lt;/p&gt;

&lt;p&gt;Schema: a single &lt;code&gt;vibeCanvas&lt;/code&gt; document type with theme/color/layout&lt;br&gt;
fields, an &lt;code&gt;interactiveNodes&lt;/code&gt; array, and the editorial fields&lt;br&gt;
(reviewStatus, reviewNotes, reviewHistory) described above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Session
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5wjmy3psabue9wfdsbwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5wjmy3psabue9wfdsbwb.png" alt=" " width="799" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>sanitychallenge</category>
      <category>sanity</category>
      <category>ai</category>
    </item>
    <item>
      <title>ChronoGraph: An Autonomous Breaking-Change Sentinel Powered by Sanity Context</title>
      <dc:creator>Sundas Naeem</dc:creator>
      <pubDate>Sun, 04 Oct 2026 11:52:15 +0000</pubDate>
      <link>https://dev.to/sundas_naeem_6f4864a7c69d/chronograph-an-autonomous-breaking-change-sentinel-powered-by-sanity-context-1db0</link>
      <guid>https://dev.to/sundas_naeem_6f4864a7c69d/chronograph-an-autonomous-breaking-change-sentinel-powered-by-sanity-context-1db0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/sanity-2026-09-16"&gt;Sanity Challenge, Path One: Ship an Agent That Queries Real Content&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;ChronoGraph is a breaking-change sentinel for microservice teams. You paste&lt;br&gt;
an API diff, and it tells you — before merge — which downstream services and&lt;br&gt;
squads it will break, using multi-hop dependency traversal over a live&lt;br&gt;
Sanity dataset. On top of the deterministic AST analysis, a Gemini-powered&lt;br&gt;
agent independently queries a Sanity Context MCP endpoint backed by a&lt;br&gt;
Knowledge Base of OpenAPI specs, consumer changelogs and on-call runbooks.&lt;br&gt;
When the dataset and the documentation disagree about a field's contract —&lt;br&gt;
nullability, type, deprecation status — the agent surfaces both claims side&lt;br&gt;
by side with their sources instead of picking one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Live app: &lt;a href="https://ai-agent-production-0558.up.railway.app/" rel="noopener noreferrer"&gt;https://ai-agent-production-0558.up.railway.app/&lt;/a&gt;&lt;br&gt;
Demo video:&lt;a href="https://drive.google.com/file/d/1Cu4TBtItlFaiB4IAgMoAFFanlpAdlZwn/view?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/file/d/1Cu4TBtItlFaiB4IAgMoAFFanlpAdlZwn/view?usp=sharing&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sundanaeem-systems/AI-agent" rel="noopener noreferrer"&gt;https://github.com/sundanaeem-systems/AI-agent&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Sanity
&lt;/h2&gt;

&lt;p&gt;I pointed Sanity Context at a Knowledge Base built from three documents I&lt;br&gt;
wrote: an OpenAPI spec for the billing service, a consumer changelog from&lt;br&gt;
the mobile client, and an on-call runbook — all intentionally containing&lt;br&gt;
contract details that conflict with the live dataset (e.g. the dataset says&lt;br&gt;
a field is optional, the OpenAPI spec says it became required). The agent&lt;br&gt;
connects to two Sanity Context MCP endpoints: one serving the live dataset&lt;br&gt;
(GROQ mode) and one serving the Knowledge Base, calling&lt;br&gt;
docs_&lt;em&gt;initial_context and docs&lt;/em&gt;_knowledge_base_search to retrieve real&lt;br&gt;
content before reasoning. Every tool call is shown live in an "Agent Trace"&lt;br&gt;
panel, and detected contradictions render as a card with both sourced&lt;br&gt;
claims — a human can rule on the contradiction, and that ruling is written&lt;br&gt;
back to Sanity as a contractDecision document so future runs don't re-ask.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity Project Details
&lt;/h2&gt;

&lt;p&gt;Sanity Project ID: d7ujf5vw&lt;br&gt;
Dataset: production&lt;/p&gt;

&lt;p&gt;The service/endpoint graph (services, apiEndpoint contracts with&lt;br&gt;
fieldContracts and consumer bindings) lives in this dataset and is seeded&lt;br&gt;
from lib/sanity/sanityData.ts via scripts/seed.ts. The Knowledge Base used&lt;br&gt;
by the agent (billing-openapi-v3.md, consumer-changelog-mobile-bff.md,&lt;br&gt;
runbook-billing-oncall.md) is built from the files in kb-content/ in the&lt;br&gt;
repo, served through a separate Sanity Context Knowledge Base endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Session
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk25asgq52ww216my9hov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk25asgq52ww216my9hov.png" alt=" " width="799" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>sanitychallenge</category>
      <category>sanity</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
