[{"data":1,"prerenderedAt":398},["ShallowReactive",2],{"$feZceERWenNxF__k3sYY-UctxG1xSnp4LWnhBEeKP6QA":3},{"newThing":4,"project":5,"cycle":8,"sections":22,"threads":373,"otherDocs":374,"images":375,"archiveItems":396,"links":397},null,{"id":6,"label":7,"liveBase":4},"design","Design",{"id":9,"num":10,"dir":11,"name":12,"title":13,"focus":14,"status":15,"statusNote":4,"created":16,"completed":4,"mode":4,"recordless":17,"thumbnail":18,"imageCount":19,"artifactCount":20,"lastActivity":21,"hasPickup":17,"hasInitialPrompt":17},"c15",15,"c15.figma-to-vue-workflow","figma-to-vue-workflow","Figma-to-Vue Workflow","Establish a repeatable workflow for extracting Figma designs into Vue SFCs that integrate with the q-nuxt-layer design system.","archived","2026-03-11",false,"\u002Fcycles\u002Fdesign\u002Fc15-policy-card.png",6,0,"2026-09-11",[23,37,47,86,223,355],{"key":24,"title":25,"empty":17,"ast":26},"why","Why",{"type":27,"children":28},"root",[29],{"type":30,"tag":31,"props":32,"children":33},"element","p",{},[34],{"type":35,"value":36},"text","We have Figma designs and a Figma MCP server available, but no established workflow for turning Figma components into functional Vue components in the design system. This is an experiment to validate the end-to-end pipeline.",{"key":38,"title":39,"empty":17,"ast":40},"objective","Objective",{"type":27,"children":41},[42],{"type":30,"tag":31,"props":43,"children":44},{},[45],{"type":35,"value":46},"Establish a repeatable workflow for extracting Figma designs into Vue SFCs that integrate with the q-nuxt-layer design system. Validate Code Connect mappings as a force multiplier for future extractions.",{"key":48,"title":49,"empty":17,"ast":50},"scope","Scope",{"type":27,"children":51},[52],{"type":30,"tag":53,"props":54,"children":55},"ul",{},[56,71,76,81],{"type":30,"tag":57,"props":58,"children":59},"li",{},[60,62,69],{"type":35,"value":61},"Use the Figma MCP ",{"type":30,"tag":63,"props":64,"children":66},"code",{"className":65},[],[67],{"type":35,"value":68},"get_design_context",{"type":35,"value":70}," tool on real Figma components",{"type":30,"tag":57,"props":72,"children":73},{},[74],{"type":35,"value":75},"Adapt React+Tailwind output to Vue SFC + layer conventions",{"type":30,"tag":57,"props":77,"children":78},{},[79],{"type":35,"value":80},"Test Code Connect mappings to link Figma components to existing layer components",{"type":30,"tag":57,"props":82,"children":83},{},[84],{"type":35,"value":85},"Document what works, what needs manual cleanup, and what to automate",{"key":87,"title":88,"empty":17,"ast":89},"key-changes","Key Changes",{"type":27,"children":90},[91],{"type":30,"tag":53,"props":92,"children":93},{},[94,122,127,180,192,211],{"type":30,"tag":57,"props":95,"children":96},{},[97,99,104,106,112,114,120],{"type":35,"value":98},"Called ",{"type":30,"tag":63,"props":100,"children":102},{"className":101},[],[103],{"type":35,"value":68},{"type":35,"value":105}," on Figma node ",{"type":30,"tag":63,"props":107,"children":109},{"className":108},[],[110],{"type":35,"value":111},"6419:28548",{"type":35,"value":113}," (PolicyListingItem, ",{"type":30,"tag":63,"props":115,"children":117},{"className":116},[],[118],{"type":35,"value":119},"app.qpoint.io---4.1.filter",{"type":35,"value":121},")",{"type":30,"tag":57,"props":123,"children":124},{},[125],{"type":35,"value":126},"Converted React+Tailwind reference output to Vue SFC using layer conventions",{"type":30,"tag":57,"props":128,"children":129},{},[130,132,138,140,146],{"type":35,"value":131},"Created ",{"type":30,"tag":63,"props":133,"children":135},{"className":134},[],[136],{"type":35,"value":137},"q-nuxt-layer\u002Fcomponents\u002Fsecurity\u002FPolicyCard.vue",{"type":35,"value":139}," → auto-imported as ",{"type":30,"tag":63,"props":141,"children":143},{"className":142},[],[144],{"type":35,"value":145},"\u003CSecurityPolicyCard>",{"type":30,"tag":53,"props":147,"children":148},{},[149,154,175],{"type":30,"tag":57,"props":150,"children":151},{},[152],{"type":35,"value":153},"4 sizes (big\u002Fmed\u002Fsmall\u002Fmicro), 2 states (cool\u002Fhot)",{"type":30,"tag":57,"props":155,"children":156},{},[157,159,165,167,173],{"type":35,"value":158},"Uses ",{"type":30,"tag":63,"props":160,"children":162},{"className":161},[],[163],{"type":35,"value":164},"DataMetricValue",{"type":35,"value":166}," + ",{"type":30,"tag":63,"props":168,"children":170},{"className":169},[],[171],{"type":35,"value":172},"DataMetricSpark",{"type":35,"value":174}," for stats and sparklines",{"type":30,"tag":57,"props":176,"children":177},{},[178],{"type":35,"value":179},"Inline SVG ribbon, border color driven by state prop",{"type":30,"tag":57,"props":181,"children":182},{},[183,184,190],{"type":35,"value":131},{"type":30,"tag":63,"props":185,"children":187},{"className":186},[],[188],{"type":35,"value":189},"design\u002Fapp\u002Fpages\u002Fcomponents\u002F_demos\u002FSecurityPolicyCard.vue",{"type":35,"value":191}," with full adminProps",{"type":30,"tag":57,"props":193,"children":194},{},[195,197,203,205],{"type":35,"value":196},"Added ",{"type":30,"tag":63,"props":198,"children":200},{"className":199},[],[201],{"type":35,"value":202},"security",{"type":35,"value":204}," group to ",{"type":30,"tag":63,"props":206,"children":208},{"className":207},[],[209],{"type":35,"value":210},"design\u002Fapp\u002Fdata\u002Fcomponent-registry.ts",{"type":30,"tag":57,"props":212,"children":213},{},[214,215,221],{"type":35,"value":131},{"type":30,"tag":63,"props":216,"children":218},{"className":217},[],[219],{"type":35,"value":220},"design\u002Fapp\u002Fdata\u002Fpolicy-cards.json",{"type":35,"value":222}," — 9 policies sourced from bob-wire wireframes\n(policy-compliance-v1, policies-v1, policies-v2)",{"key":224,"title":225,"empty":17,"ast":226},"outcome","Outcome",{"type":27,"children":227},[228,233],{"type":30,"tag":31,"props":229,"children":230},{},[231],{"type":35,"value":232},"Workflow validated. The Figma MCP → Vue SFC pipeline works well for domain-specific components.\nKey learnings:",{"type":30,"tag":53,"props":234,"children":235},{},[236,255,265,275,298,330],{"type":30,"tag":57,"props":237,"children":238},{},[239,245,247,253],{"type":30,"tag":240,"props":241,"children":242},"strong",{},[243],{"type":35,"value":244},"Figma output quality:",{"type":35,"value":246}," React+Tailwind reference is useful but noisy — hundreds of ",{"type":30,"tag":63,"props":248,"children":250},{"className":249},[],[251],{"type":35,"value":252},"data-node-id",{"type":35,"value":254}," attributes, image assets for sparklines\u002Fribbons, and inline style overrides require manual cleanup",{"type":30,"tag":57,"props":256,"children":257},{},[258,263],{"type":30,"tag":240,"props":259,"children":260},{},[261],{"type":35,"value":262},"What transfers cleanly:",{"type":35,"value":264}," layout structure, size variants, conditional rendering logic, color values",{"type":30,"tag":57,"props":266,"children":267},{},[268,273],{"type":30,"tag":240,"props":269,"children":270},{},[271],{"type":35,"value":272},"What needs replacing:",{"type":35,"value":274}," any image assets (sparklines, decorative elements) must be swapped for real components",{"type":30,"tag":57,"props":276,"children":277},{},[278,283,285,290,291,296],{"type":30,"tag":240,"props":279,"children":280},{},[281],{"type":35,"value":282},"Data-machine fit:",{"type":35,"value":284}," ",{"type":30,"tag":63,"props":286,"children":288},{"className":287},[],[289],{"type":35,"value":164},{"type":35,"value":166},{"type":30,"tag":63,"props":292,"children":294},{"className":293},[],[295],{"type":35,"value":172},{"type":35,"value":297}," are a natural fit for stat columns — no custom number formatting needed",{"type":30,"tag":57,"props":299,"children":300},{},[301,306,308,314,316,322,324],{"type":30,"tag":240,"props":302,"children":303},{},[304],{"type":35,"value":305},"Naming:",{"type":35,"value":307}," domain-specific components don't belong in ",{"type":30,"tag":63,"props":309,"children":311},{"className":310},[],[312],{"type":35,"value":313},"ux\u002F",{"type":35,"value":315}," — a ",{"type":30,"tag":63,"props":317,"children":319},{"className":318},[],[320],{"type":35,"value":321},"security\u002F",{"type":35,"value":323}," subdirectory auto-prefixes correctly as ",{"type":30,"tag":63,"props":325,"children":327},{"className":326},[],[328],{"type":35,"value":329},"Security*",{"type":30,"tag":57,"props":331,"children":332},{},[333,338,339,345,347,353],{"type":30,"tag":240,"props":334,"children":335},{},[336],{"type":35,"value":337},"Code Connect opportunity:",{"type":35,"value":284},{"type":30,"tag":63,"props":340,"children":342},{"className":341},[],[343],{"type":35,"value":344},"PolicyListingItem",{"type":35,"value":346}," → ",{"type":30,"tag":63,"props":348,"children":350},{"className":349},[],[351],{"type":35,"value":352},"SecurityPolicyCard",{"type":35,"value":354}," mapping not yet registered — follow-on task for c13",{"key":356,"title":357,"empty":17,"ast":358},"extra","Out of Scope",{"type":27,"children":359},[360],{"type":30,"tag":53,"props":361,"children":362},{},[363,368],{"type":30,"tag":57,"props":364,"children":365},{},[366],{"type":35,"value":367},"Building net-new components not already designed in Figma",{"type":30,"tag":57,"props":369,"children":370},{},[371],{"type":35,"value":372},"Publishing to the layer tarball (that's a follow-on cycle)",[],[],[376,379,383,386,389,392],{"src":18,"kind":377,"order":378},"hero",4999,{"src":380,"kind":381,"order":382},"\u002Fcycles\u002Fdesign\u002Fc15-policy-card-2.png","slice",2,{"src":384,"kind":381,"order":385},"\u002Fcycles\u002Fdesign\u002Fc15-policy-card-3.png",3,{"src":387,"kind":381,"order":388},"\u002Fcycles\u002Fdesign\u002Fc15-policy-card-4.png",4,{"src":390,"kind":381,"order":391},"\u002Fcycles\u002Fdesign\u002Fc15-policy-card-5.png",5,{"src":393,"kind":394,"order":395},"\u002Fcycles\u002Fdesign\u002Fc15-policy-card-full.png","full",9000,[],[],1789151089400]