[{"data":1,"prerenderedAt":395},["ShallowReactive",2],{"$fBS_61en-ZDudV0AGnEOwBIeP_1iOEf4zGc7fV3pjBOQ":3},{"newThing":4,"project":5,"cycle":8,"sections":21,"threads":368,"otherDocs":369,"images":370,"archiveItems":385,"links":394},null,{"id":6,"label":7,"liveBase":4},"design","Design",{"id":9,"num":10,"dir":11,"name":12,"title":13,"focus":4,"status":14,"statusNote":4,"created":15,"completed":4,"mode":4,"recordless":16,"thumbnail":17,"imageCount":18,"artifactCount":19,"lastActivity":20,"hasPickup":16,"hasInitialPrompt":16},"c21",21,"c21.policy-skin-extraction","policy-skin-extraction","Policy Skin Extraction","archived","March 2026",false,"\u002Fcycles\u002Fdesign\u002Fc21-policy-skin.png",4,0,"2026-09-11",[22,36,55,124,340],{"key":23,"title":24,"empty":16,"ast":25},"why","Why",{"type":26,"children":27},"root",[28],{"type":29,"tag":30,"props":31,"children":32},"element","p",{},[33],{"type":34,"value":35},"text","The security policy page needs cards for whitelisted apps, datastores, and vendors that share PolicyCard's visual treatment (colored border, shadow, rounded corners, ribbon badge) but with completely different content inside. The visual wrapper was baked into PolicyCard alongside domain-specific stats and sparklines, preventing reuse.",{"key":37,"title":38,"empty":16,"ast":39},"objective","Objective",{"type":26,"children":40},[41],{"type":29,"tag":30,"props":42,"children":43},{},[44,46,53],{"type":34,"value":45},"Extract PolicyCard's visual wrapper into a standalone ",{"type":29,"tag":47,"props":48,"children":50},"code",{"className":49},[],[51],{"type":34,"value":52},"SecurityPolicySkin",{"type":34,"value":54}," component so any card content can adopt the policy visual language.",{"key":56,"title":57,"empty":16,"ast":58},"scope","Scope",{"type":26,"children":59},[60],{"type":29,"tag":61,"props":62,"children":63},"ul",{},[64,85,98,119],{"type":29,"tag":65,"props":66,"children":67},"li",{},[68,70,75,77,83],{"type":34,"value":69},"New ",{"type":29,"tag":47,"props":71,"children":73},{"className":72},[],[74],{"type":34,"value":52},{"type":34,"value":76}," component in the layer (",{"type":29,"tag":47,"props":78,"children":80},{"className":79},[],[81],{"type":34,"value":82},"components\u002Fsecurity\u002FPolicySkin.vue",{"type":34,"value":84},")",{"type":29,"tag":65,"props":86,"children":87},{},[88,90,96],{"type":34,"value":89},"Refactor ",{"type":29,"tag":47,"props":91,"children":93},{"className":92},[],[94],{"type":34,"value":95},"SecurityPolicyCard",{"type":34,"value":97}," to use PolicySkin internally (zero visual change)",{"type":29,"tag":65,"props":99,"children":100},{},[101,103,109,111,117],{"type":34,"value":102},"Extend ",{"type":29,"tag":47,"props":104,"children":106},{"className":105},[],[107],{"type":34,"value":108},"SecurityPolicyRibbon",{"type":34,"value":110}," to support the new ",{"type":29,"tag":47,"props":112,"children":114},{"className":113},[],[115],{"type":34,"value":116},"white-list",{"type":34,"value":118}," state",{"type":29,"tag":65,"props":120,"children":121},{},[122],{"type":34,"value":123},"Design site registry entry and demo page",{"key":125,"title":126,"empty":16,"ast":127},"key-changes","Key Changes",{"type":26,"children":128},[129,136,141,238,243,249,261,297,303],{"type":29,"tag":130,"props":131,"children":133},"h3",{"id":132},"new-securitypolicyskin",[134],{"type":34,"value":135},"New: SecurityPolicySkin",{"type":29,"tag":30,"props":137,"children":138},{},[139],{"type":34,"value":140},"Wrapper component with three props:",{"type":29,"tag":61,"props":142,"children":143},{},[144,202,220],{"type":29,"tag":65,"props":145,"children":146},{},[147,153,155,161,163,169,171,177,179,185,187,193,195,201],{"type":29,"tag":47,"props":148,"children":150},{"className":149},[],[151],{"type":34,"value":152},"state",{"type":34,"value":154}," — ",{"type":29,"tag":47,"props":156,"children":158},{"className":157},[],[159],{"type":34,"value":160},"'cool'",{"type":34,"value":162}," (green) | ",{"type":29,"tag":47,"props":164,"children":166},{"className":165},[],[167],{"type":34,"value":168},"'hot'",{"type":34,"value":170}," (red) | ",{"type":29,"tag":47,"props":172,"children":174},{"className":173},[],[175],{"type":34,"value":176},"'warm'",{"type":34,"value":178}," (amber) | ",{"type":29,"tag":47,"props":180,"children":182},{"className":181},[],[183],{"type":34,"value":184},"'default'",{"type":34,"value":186}," (purple) | ",{"type":29,"tag":47,"props":188,"children":190},{"className":189},[],[191],{"type":34,"value":192},"'white-list'",{"type":34,"value":194}," (light blue ",{"type":29,"tag":47,"props":196,"children":198},{"className":197},[],[199],{"type":34,"value":200},"#84CAFF",{"type":34,"value":84},{"type":29,"tag":65,"props":203,"children":204},{},[205,211,213,219],{"type":29,"tag":47,"props":206,"children":208},{"className":207},[],[209],{"type":34,"value":210},"maxWidth",{"type":34,"value":212}," — CSS max-width (default ",{"type":29,"tag":47,"props":214,"children":216},{"className":215},[],[217],{"type":34,"value":218},"350px",{"type":34,"value":84},{"type":29,"tag":65,"props":221,"children":222},{},[223,229,231,237],{"type":29,"tag":47,"props":224,"children":226},{"className":225},[],[227],{"type":34,"value":228},"ribbon",{"type":34,"value":230}," — show\u002Fhide ribbon badge (default ",{"type":29,"tag":47,"props":232,"children":234},{"className":233},[],[235],{"type":34,"value":236},"true",{"type":34,"value":84},{"type":29,"tag":30,"props":239,"children":240},{},[241],{"type":34,"value":242},"Default slot for arbitrary card content.",{"type":29,"tag":130,"props":244,"children":246},{"id":245},"updated-securitypolicyribbon",[247],{"type":34,"value":248},"Updated: SecurityPolicyRibbon",{"type":29,"tag":30,"props":250,"children":251},{},[252,254,259],{"type":34,"value":253},"Extended palette to support ",{"type":29,"tag":47,"props":255,"children":257},{"className":256},[],[258],{"type":34,"value":116},{"type":34,"value":260}," state:",{"type":29,"tag":61,"props":262,"children":263},{},[264,277,287,292],{"type":29,"tag":65,"props":265,"children":266},{},[267,269,275],{"type":34,"value":268},"White badge with ",{"type":29,"tag":47,"props":270,"children":272},{"className":271},[],[273],{"type":34,"value":274},"#DFDFDF",{"type":34,"value":276}," grey stroke",{"type":29,"tag":65,"props":278,"children":279},{},[280,285],{"type":29,"tag":47,"props":281,"children":283},{"className":282},[],[284],{"type":34,"value":200},{"type":34,"value":286}," blue checkmark",{"type":29,"tag":65,"props":288,"children":289},{},[290],{"type":34,"value":291},"White tail with grey stroke",{"type":29,"tag":65,"props":293,"children":294},{},[295],{"type":34,"value":296},"Stroke applied to both badge circle and ribbon tail SVG paths",{"type":29,"tag":130,"props":298,"children":300},{"id":299},"refactored-securitypolicycard",[301],{"type":34,"value":302},"Refactored: SecurityPolicyCard",{"type":29,"tag":30,"props":304,"children":305},{},[306,308,314,316,322,324,330,332,338],{"type":34,"value":307},"Replaced the manual card wrapper (",{"type":29,"tag":47,"props":309,"children":311},{"className":310},[],[312],{"type":34,"value":313},"\u003Cdiv class=\"relative py-4 px-6 bg-white border ...\">",{"type":34,"value":315},") and inline ",{"type":29,"tag":47,"props":317,"children":319},{"className":318},[],[320],{"type":34,"value":321},"\u003CSecurityPolicyRibbon>",{"type":34,"value":323}," with ",{"type":29,"tag":47,"props":325,"children":327},{"className":326},[],[328],{"type":34,"value":329},"\u003CSecurityPolicySkin :state=\"state\">",{"type":34,"value":331},". Removed ",{"type":29,"tag":47,"props":333,"children":335},{"className":334},[],[336],{"type":34,"value":337},"borderColor",{"type":34,"value":339}," computed. All external behavior unchanged.",{"key":341,"title":342,"empty":16,"ast":343},"outcome","Outcome",{"type":26,"children":344},[345],{"type":29,"tag":61,"props":346,"children":347},{},[348,358,363],{"type":29,"tag":65,"props":349,"children":350},{},[351,356],{"type":29,"tag":47,"props":352,"children":354},{"className":353},[],[355],{"type":34,"value":52},{"type":34,"value":357}," available as a standalone wrapper for any card needing the policy visual treatment",{"type":29,"tag":65,"props":359,"children":360},{},[361],{"type":34,"value":362},"5 states cover all current use cases: compliance (cool\u002Fhot\u002Fwarm), brand (default), and allow-list (white-list)",{"type":29,"tag":65,"props":364,"children":365},{},[366],{"type":34,"value":367},"PolicyCard is now a composition of PolicySkin + domain content, not a monolith",[],[],[371,374,378,381],{"src":17,"kind":372,"order":373},"hero",4999,{"src":375,"kind":376,"order":377},"\u002Fcycles\u002Fdesign\u002Fc21-policy-skin-2.png","slice",2,{"src":379,"kind":376,"order":380},"\u002Fcycles\u002Fdesign\u002Fc21-policy-skin-3.png",3,{"src":382,"kind":383,"order":384},"\u002Fcycles\u002Fdesign\u002Fc21-policy-skin-full.png","full",9000,[386],{"path":387,"title":388,"image":17,"gallery":389},"archive\u002F2026-q3\u002F2026-03-17-c21-policy-skin","Policy Skin",[390,392],{"src":17,"alt":391},"SecurityPolicySkin demo with ribbon states.",{"src":382,"alt":393},"Policy Skin — full demo page",[],1789151089241]