|
| 1 | +import { Link } from 'react-router-dom' |
| 2 | + |
| 3 | +export default function WhyPage() { |
| 4 | + return ( |
| 5 | + <> |
| 6 | + {/* Hero */} |
| 7 | + <section className="pt-32 pb-16 px-6"> |
| 8 | + <div className="max-w-5xl mx-auto"> |
| 9 | + <h1 className="text-4xl md:text-5xl font-bold tracking-tight text-gray-900 mb-6"> |
| 10 | + The Architecture Documentation Problem |
| 11 | + </h1> |
| 12 | + <p className="text-xl text-gray-600 max-w-3xl leading-relaxed"> |
| 13 | + Every organization struggles with the same challenge: keeping architecture |
| 14 | + documentation accurate, up-to-date, and useful. SCP solves this with a |
| 15 | + simple principle — <strong>define once in code, generate everything else</strong>. |
| 16 | + </p> |
| 17 | + </div> |
| 18 | + </section> |
| 19 | + |
| 20 | + {/* The Problem */} |
| 21 | + <section className="py-16 px-6 bg-gray-50"> |
| 22 | + <div className="max-w-5xl mx-auto"> |
| 23 | + <h2 className="text-2xl font-semibold mb-6">The Problem: Scattered Information</h2> |
| 24 | + |
| 25 | + <div className="grid md:grid-cols-2 gap-8 mb-8"> |
| 26 | + <div> |
| 27 | + <p className="text-gray-600 mb-6 leading-relaxed"> |
| 28 | + Architecture knowledge lives in too many places. Teams maintain |
| 29 | + separate sources of truth that inevitably fall out of sync: |
| 30 | + </p> |
| 31 | + <ul className="space-y-3"> |
| 32 | + <ProblemItem>CMDB databases with stale service entries</ProblemItem> |
| 33 | + <ProblemItem>Wiki pages that haven't been updated in months</ProblemItem> |
| 34 | + <ProblemItem>Diagram tools with outdated dependency maps</ProblemItem> |
| 35 | + <ProblemItem>Tribal knowledge locked in people's heads</ProblemItem> |
| 36 | + <ProblemItem>Alert configurations missing ownership info</ProblemItem> |
| 37 | + </ul> |
| 38 | + </div> |
| 39 | + <div className="bg-white rounded-xl p-6 border border-red-200"> |
| 40 | + <h3 className="font-medium text-red-800 mb-4 flex items-center gap-2"> |
| 41 | + <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 42 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /> |
| 43 | + </svg> |
| 44 | + The Result |
| 45 | + </h3> |
| 46 | + <ul className="space-y-2 text-gray-600 text-sm"> |
| 47 | + <li>• Incident responders can't find the right team to call</li> |
| 48 | + <li>• Change requests miss critical dependencies</li> |
| 49 | + <li>• New engineers spend weeks understanding the system</li> |
| 50 | + <li>• Auditors get inconsistent answers about data flow</li> |
| 51 | + <li>• AI tools can't reason about your architecture</li> |
| 52 | + </ul> |
| 53 | + </div> |
| 54 | + </div> |
| 55 | + </div> |
| 56 | + </section> |
| 57 | + |
| 58 | + {/* The Solution */} |
| 59 | + <section className="py-16 px-6"> |
| 60 | + <div className="max-w-5xl mx-auto"> |
| 61 | + <h2 className="text-2xl font-semibold mb-6">The SCP Solution: Hub and Spoke</h2> |
| 62 | + |
| 63 | + <p className="text-gray-600 mb-10 max-w-3xl leading-relaxed"> |
| 64 | + SCP flips the model. Instead of maintaining multiple sources of truth, |
| 65 | + you define your system architecture once — in a simple <code className="bg-gray-100 px-1.5 py-0.5 rounded text-sm">scp.yaml</code> file |
| 66 | + that lives alongside your code. Everything else is <strong>generated</strong> from this single source. |
| 67 | + </p> |
| 68 | + |
| 69 | + {/* Hub and Spoke Diagram */} |
| 70 | + <div className="bg-gradient-to-br from-indigo-50 to-white rounded-2xl p-8 mb-10 border border-indigo-100"> |
| 71 | + <div className="flex flex-col items-center"> |
| 72 | + {/* Many scp.yaml inputs */} |
| 73 | + <div className="flex flex-wrap justify-center gap-3 mb-4"> |
| 74 | + <div className="px-3 py-1.5 bg-gray-100 rounded-lg text-sm font-mono text-gray-600 border border-gray-200">payment-service/scp.yaml</div> |
| 75 | + <div className="px-3 py-1.5 bg-gray-100 rounded-lg text-sm font-mono text-gray-600 border border-gray-200">user-service/scp.yaml</div> |
| 76 | + <div className="px-3 py-1.5 bg-gray-100 rounded-lg text-sm font-mono text-gray-600 border border-gray-200">gateway/scp.yaml</div> |
| 77 | + <div className="px-3 py-1.5 bg-gray-100 rounded-lg text-sm font-mono text-gray-600 border border-gray-200">...</div> |
| 78 | + </div> |
| 79 | + |
| 80 | + <p className="text-gray-500 text-sm mb-4">↓ Aggregate into ↓</p> |
| 81 | + |
| 82 | + {/* Hub - Unified Model */} |
| 83 | + <div className="relative"> |
| 84 | + <div className="w-44 h-44 bg-indigo-600 rounded-full flex items-center justify-center shadow-lg shadow-indigo-200"> |
| 85 | + <div className="text-center text-white px-4"> |
| 86 | + <div className="font-bold text-lg">Unified Model</div> |
| 87 | + <div className="text-indigo-200 text-xs mt-1">Complete architecture graph</div> |
| 88 | + </div> |
| 89 | + </div> |
| 90 | + <div className="absolute -top-2 -right-2 w-8 h-8 bg-white rounded-full border-2 border-indigo-600 flex items-center justify-center"> |
| 91 | + <span className="text-indigo-600 font-bold text-xs">Hub</span> |
| 92 | + </div> |
| 93 | + </div> |
| 94 | + |
| 95 | + <p className="text-gray-500 text-sm mt-4 mb-4">↓ Generate outputs ↓</p> |
| 96 | + |
| 97 | + {/* Spokes */} |
| 98 | + <div className="grid grid-cols-2 md:grid-cols-5 gap-4 w-full"> |
| 99 | + <SpokeCard |
| 100 | + title="CSDM" |
| 101 | + description="ServiceNow, Jira Service Management" |
| 102 | + color="blue" |
| 103 | + /> |
| 104 | + <SpokeCard |
| 105 | + title="C4 Diagrams" |
| 106 | + description="Architecture visualizations" |
| 107 | + color="green" |
| 108 | + /> |
| 109 | + <SpokeCard |
| 110 | + title="Alerts" |
| 111 | + description="PagerDuty, Opsgenie enrichment" |
| 112 | + color="amber" |
| 113 | + /> |
| 114 | + <SpokeCard |
| 115 | + title="Docs" |
| 116 | + description="Auto-generated system maps" |
| 117 | + color="purple" |
| 118 | + /> |
| 119 | + <SpokeCard |
| 120 | + title="LLMs" |
| 121 | + description="AI-assisted troubleshooting" |
| 122 | + color="pink" |
| 123 | + /> |
| 124 | + </div> |
| 125 | + |
| 126 | + <p className="text-center text-gray-500 text-sm mt-6"> |
| 127 | + <strong>Many-to-Many:</strong> Multiple scp.yaml files → Unified Model → Multiple outputs |
| 128 | + </p> |
| 129 | + </div> |
| 130 | + </div> |
| 131 | + </div> |
| 132 | + </section> |
| 133 | + |
| 134 | + {/* Why This Works */} |
| 135 | + <section className="py-16 px-6 bg-gray-50"> |
| 136 | + <div className="max-w-5xl mx-auto"> |
| 137 | + <h2 className="text-2xl font-semibold mb-8">Why This Works</h2> |
| 138 | + |
| 139 | + <div className="grid md:grid-cols-2 gap-6"> |
| 140 | + <BenefitCard |
| 141 | + title="Define Once, Generate Everywhere" |
| 142 | + description="Update your scp.yaml once, and all downstream systems update automatically. No more manual syncing between tools." |
| 143 | + icon={ |
| 144 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" /> |
| 145 | + } |
| 146 | + /> |
| 147 | + <BenefitCard |
| 148 | + title="Always Up-to-Date" |
| 149 | + description="Architecture lives with your code. When you change the system, you update the manifest in the same PR." |
| 150 | + icon={ |
| 151 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> |
| 152 | + } |
| 153 | + /> |
| 154 | + <BenefitCard |
| 155 | + title="Developer-Friendly" |
| 156 | + description="No portal switching or separate databases to maintain. It's just a YAML file in your repo — review it like any other code." |
| 157 | + icon={ |
| 158 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /> |
| 159 | + } |
| 160 | + /> |
| 161 | + <BenefitCard |
| 162 | + title="Machine-Readable" |
| 163 | + description="Enables automation: CI validation, auto-discovery, LLM reasoning, blast radius analysis, and more." |
| 164 | + icon={ |
| 165 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /> |
| 166 | + } |
| 167 | + /> |
| 168 | + </div> |
| 169 | + </div> |
| 170 | + </section> |
| 171 | + |
| 172 | + {/* Comparison */} |
| 173 | + <section className="py-16 px-6"> |
| 174 | + <div className="max-w-5xl mx-auto"> |
| 175 | + <h2 className="text-2xl font-semibold mb-8">Traditional vs SCP Approach</h2> |
| 176 | + |
| 177 | + <div className="grid md:grid-cols-2 gap-8"> |
| 178 | + <div className="bg-red-50 rounded-xl p-6 border border-red-200"> |
| 179 | + <h3 className="font-semibold text-red-800 mb-4 flex items-center gap-2"> |
| 180 | + <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 181 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /> |
| 182 | + </svg> |
| 183 | + Traditional Approach |
| 184 | + </h3> |
| 185 | + <ul className="space-y-3 text-gray-600 text-sm"> |
| 186 | + <li className="flex gap-2"> |
| 187 | + <span className="text-red-400">✗</span> |
| 188 | + Maintain CMDB separately from code |
| 189 | + </li> |
| 190 | + <li className="flex gap-2"> |
| 191 | + <span className="text-red-400">✗</span> |
| 192 | + Update diagrams manually in Lucidchart/Miro |
| 193 | + </li> |
| 194 | + <li className="flex gap-2"> |
| 195 | + <span className="text-red-400">✗</span> |
| 196 | + Configure alert ownership in each tool |
| 197 | + </li> |
| 198 | + <li className="flex gap-2"> |
| 199 | + <span className="text-red-400">✗</span> |
| 200 | + Document dependencies in wiki pages |
| 201 | + </li> |
| 202 | + <li className="flex gap-2"> |
| 203 | + <span className="text-red-400">✗</span> |
| 204 | + Information drifts out of sync over time |
| 205 | + </li> |
| 206 | + </ul> |
| 207 | + </div> |
| 208 | + |
| 209 | + <div className="bg-green-50 rounded-xl p-6 border border-green-200"> |
| 210 | + <h3 className="font-semibold text-green-800 mb-4 flex items-center gap-2"> |
| 211 | + <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 212 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /> |
| 213 | + </svg> |
| 214 | + SCP Approach |
| 215 | + </h3> |
| 216 | + <ul className="space-y-3 text-gray-600 text-sm"> |
| 217 | + <li className="flex gap-2"> |
| 218 | + <span className="text-green-500">✓</span> |
| 219 | + Define system in scp.yaml alongside code |
| 220 | + </li> |
| 221 | + <li className="flex gap-2"> |
| 222 | + <span className="text-green-500">✓</span> |
| 223 | + Generate C4/Mermaid diagrams automatically |
| 224 | + </li> |
| 225 | + <li className="flex gap-2"> |
| 226 | + <span className="text-green-500">✓</span> |
| 227 | + Push ownership to PagerDuty/Opsgenie via integration |
| 228 | + </li> |
| 229 | + <li className="flex gap-2"> |
| 230 | + <span className="text-green-500">✓</span> |
| 231 | + Dependencies are code-reviewed in PRs |
| 232 | + </li> |
| 233 | + <li className="flex gap-2"> |
| 234 | + <span className="text-green-500">✓</span> |
| 235 | + Single source of truth stays current |
| 236 | + </li> |
| 237 | + </ul> |
| 238 | + </div> |
| 239 | + </div> |
| 240 | + </div> |
| 241 | + </section> |
| 242 | + |
| 243 | + {/* CTA */} |
| 244 | + <section className="py-16 px-6 bg-indigo-600"> |
| 245 | + <div className="max-w-5xl mx-auto text-center"> |
| 246 | + <h2 className="text-2xl font-semibold text-white mb-4">Ready to Get Started?</h2> |
| 247 | + <p className="text-indigo-200 mb-8 max-w-2xl mx-auto"> |
| 248 | + Add an scp.yaml to your repository and start generating |
| 249 | + documentation, diagrams, and integrations automatically. |
| 250 | + </p> |
| 251 | + <div className="flex justify-center gap-4"> |
| 252 | + <Link |
| 253 | + to="/spec" |
| 254 | + className="inline-flex items-center px-5 py-2.5 bg-white text-indigo-600 font-medium rounded-lg hover:bg-indigo-50 transition-colors" |
| 255 | + > |
| 256 | + View Specification |
| 257 | + </Link> |
| 258 | + <Link |
| 259 | + to="/integrations" |
| 260 | + className="inline-flex items-center px-5 py-2.5 border border-white text-white font-medium rounded-lg hover:bg-indigo-700 transition-colors" |
| 261 | + > |
| 262 | + Explore Integrations |
| 263 | + </Link> |
| 264 | + </div> |
| 265 | + </div> |
| 266 | + </section> |
| 267 | + </> |
| 268 | + ) |
| 269 | +} |
| 270 | + |
| 271 | +function ProblemItem({ children }) { |
| 272 | + return ( |
| 273 | + <li className="flex items-start gap-3"> |
| 274 | + <svg className="w-5 h-5 text-red-400 mt-0.5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 275 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> |
| 276 | + </svg> |
| 277 | + <span className="text-gray-600">{children}</span> |
| 278 | + </li> |
| 279 | + ) |
| 280 | +} |
| 281 | + |
| 282 | +function SpokeCard({ title, description, color }) { |
| 283 | + const colors = { |
| 284 | + blue: 'bg-blue-50 border-blue-200 text-blue-800', |
| 285 | + green: 'bg-green-50 border-green-200 text-green-800', |
| 286 | + amber: 'bg-amber-50 border-amber-200 text-amber-800', |
| 287 | + purple: 'bg-purple-50 border-purple-200 text-purple-800', |
| 288 | + pink: 'bg-pink-50 border-pink-200 text-pink-800', |
| 289 | + } |
| 290 | + |
| 291 | + return ( |
| 292 | + <div className={`rounded-lg p-4 border text-center ${colors[color]}`}> |
| 293 | + <div className="font-semibold text-sm mb-1">{title}</div> |
| 294 | + <div className="text-xs opacity-75">{description}</div> |
| 295 | + </div> |
| 296 | + ) |
| 297 | +} |
| 298 | + |
| 299 | +function BenefitCard({ title, description, icon }) { |
| 300 | + return ( |
| 301 | + <div className="p-6 bg-white border border-gray-200 rounded-xl hover:border-gray-300 transition-colors"> |
| 302 | + <div className="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center mb-4"> |
| 303 | + <svg className="w-5 h-5 text-indigo-600" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 304 | + {icon} |
| 305 | + </svg> |
| 306 | + </div> |
| 307 | + <h3 className="font-semibold text-gray-900 mb-2">{title}</h3> |
| 308 | + <p className="text-gray-600 text-sm leading-relaxed">{description}</p> |
| 309 | + </div> |
| 310 | + ) |
| 311 | +} |
0 commit comments