> ## Documentation Index
> Fetch the complete documentation index at: https://docs.morada.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Ask for a visual explanation of a plan

> Turn steps and dependencies into something your team can explore, understand, and discuss.

export const planArtifact = {
  filename: "plano-lancamento-6-semanas.html",
  sha256: "8f86c2852b229ab2d7699eccf40e5d0d92b95dd94f85ad790d32dbc104d5b26c",
  html: ["<!doctype html>\n<html lang=\"pt-BR\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>Plano interativo de lançamento — 6 semanas</title>\n  <style>\n    :root {\n      --bg: #f4f7fb;\n      --surface: #ffffff;\n      --surface-soft: #f8fafc;\n      --ink: #172033;\n      --muted: #5e6b82;\n      --line: #dbe3ef;\n      --navy: #21385b;\n      --blue: #3478d4;\n      --teal: #168b83;\n      --orange: #e47a2e;\n      --violet: #7357c7;\n      --wait: #8a95a8;\n      --shadow: 0 16px 44px rgba(31, 53, 86, .09);\n      --radius: 18px;\n      --radius-sm: 12px;\n    }\n\n    * { box-sizing: border-box; }\n    html { scroll-behavior: smooth; }\n    body {\n      margin: 0;\n      color: var(--ink);\n      background:\n        radial-gradient(circle at 10% 0%, rgba(52, 120, 212, .10), transparent 28rem),\n        var(--bg);\n      font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n      line-height: 1.5;\n    }\n\n    button, input { font: inherit; }\n    button { -webkit-tap-highlight-color: transparent; }\n    a { color: inherit; }\n\n    .shell { width: min(1120px, calc(100% - 32px)); margin: 0 auto; }\n\n    .hero { padding: 54px 0 28px; }\n    .eyebrow {\n      display: inline-flex;\n      align-items: center;\n      gap: 8px;\n      margin: 0 0 14px;\n      color: var(--blue);\n      font-size: .79rem;\n      font-weight: 800;\n      letter-spacing: .09em;\n      text-transform: uppercase;\n    }\n    .eyebrow::before {\n      content: \"\";\n      width: 22px;\n      height: 3px;\n      border-radius: 999px;\n      background: currentColor;\n    }\n    h1 {\n      max-width: 850px;\n      margin: 0;\n      font-size: clamp(2rem, 5vw, 4rem);\n      line-height: 1.03;\n      letter-spacing: -.045em;\n    }\n    .hero-copy {\n      max-width: 760px;\n      margin: 20px 0 0;\n      color: var(--muted);\n      font-size: clamp(1rem, 2vw, 1.16rem);\n    }\n\n    .simulator {\n      margin: 22px 0 24px;\n      padding: 22px;\n      border: 1px solid rgba(52, 120, 212, .18);\n      border-radius: var(--radius);\n      background: linear-gradient(145deg, #fff, #f7faff);\n      box-shadow: var(--shadow);\n    }\n    .sim-grid {\n      display: grid;\n      grid-template-columns: minmax(0, 1.45fr) minmax(280px, .8fr);\n      gap: 24px;\n      align-items: center;\n    }\n    .control-title {\n      display: flex;\n      justify-content: space-between;\n      align-items: baseline;\n      gap: 16px;\n      margin-bottom: 14px;\n    }\n    .control-title label { font-weight: 800; font-size: 1.05rem; }\n    .delay-readout { color: var(--blue); font-weight: 850; white-space: nowrap; }\n    .range-wrap { position: relative; padding: 8px 0 2px; }\n    input[type=\"range\"] {\n      width: 100%;\n      height: 28px;\n      margin: 0;\n      appearance: none;\n      background: transparent;\n      cursor: pointer;\n    }\n    input[type=\"range\"]::-webkit-slider-runnable-track {\n      height: 8px;\n      border-radius: 999px;\n      background: linear-gradient(90deg, var(--blue) var(--fill, 0%), #dfe7f2 var(--fill, 0%));\n    }\n    input[type=\"range\"]::-moz-range-track {\n      height: 8px;\n      border-radius: 999px;\n      background: #dfe7f2;\n    }\n    input[type=\"range\"]::-moz-range-progress {\n      height: 8px;\n      border-radius: 999px;\n      background: var(--blue);\n    }\n    input[type=\"range\"]::-webkit-slider-thumb {\n      width: 26px;\n      height: 26px;\n      margin-top: -9px;\n      appearance: none;\n      border: 4px solid #fff;\n      border-radius: 50%;\n      background: var(--blue);\n      box-shadow: 0 2px 12px rgba(52, 120, 212, .35);\n    }\n    input[type=\"range\"]::-moz-range-thumb {\n      width: 20px;\n      height: 20px;\n      border: 4px solid #fff;\n      border-radius: 50%;\n      background: var(--blue);\n      box-shadow: 0 2px 12px rgba(52, 120, 212, .35);\n    }\n    input[type=\"range\"]:focus-visible { outline: 3px solid rgba(52, 120, 212, .3); outline-offset: 4px; }\n    .range-labels {\n      display: flex;\n      justify-c", "ontent: space-between;\n      padding: 0 4px;\n      color: var(--muted);\n      font-size: .78rem;\n      font-weight: 700;\n    }\n    .quick-buttons { display: flex; gap: 8px; margin-top: 14px; }\n    .quick-buttons button {\n      min-width: 44px;\n      min-height: 44px;\n      padding: 0 12px;\n      border: 1px solid var(--line);\n      border-radius: 11px;\n      color: var(--muted);\n      background: var(--surface);\n      font-weight: 800;\n      cursor: pointer;\n    }\n    .quick-buttons button:hover { border-color: #9ebbe1; color: var(--blue); }\n    .quick-buttons button[aria-pressed=\"true\"] {\n      border-color: var(--blue);\n      color: #fff;\n      background: var(--blue);\n    }\n    .quick-buttons button:focus-visible { outline: 3px solid rgba(52, 120, 212, .3); outline-offset: 2px; }\n\n    .launch-result {\n      min-height: 164px;\n      padding: 22px;\n      border-radius: 16px;\n      color: #fff;\n      background: var(--navy);\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n    }\n    .result-label { color: #c7d7ee; font-size: .82rem; font-weight: 750; text-transform: uppercase; letter-spacing: .08em; }\n    .result-main { margin: 3px 0 7px; font-size: clamp(2.3rem, 7vw, 4.6rem); font-weight: 900; line-height: 1; letter-spacing: -.055em; }\n    .result-detail { margin: 0; color: #e4edf8; }\n\n    .premise {\n      display: grid;\n      grid-template-columns: auto 1fr;\n      gap: 14px;\n      margin: 0 0 26px;\n      padding: 18px 20px;\n      border-left: 5px solid var(--orange);\n      border-radius: 4px var(--radius-sm) var(--radius-sm) 4px;\n      background: #fff7ee;\n    }\n    .premise-mark {\n      display: grid;\n      place-items: center;\n      width: 34px;\n      height: 34px;\n      border-radius: 10px;\n      color: #fff;\n      background: var(--orange);\n      font-weight: 900;\n    }\n    .premise h2 { margin: 0 0 4px; font-size: 1rem; }\n    .premise p { margin: 0; color: #6d533f; }\n\n    .section { padding: 26px 0; }\n    .section-head {\n      display: flex;\n      align-items: end;\n      justify-content: space-between;\n      gap: 20px;\n      margin-bottom: 16px;\n    }\n    .section-kicker { margin: 0 0 4px; color: var(--blue); font-size: .77rem; font-weight: 850; letter-spacing: .09em; text-transform: uppercase; }\n    .section h2 { margin: 0; font-size: clamp(1.45rem, 3vw, 2.1rem); line-height: 1.15; letter-spacing: -.025em; }\n    .section-note { max-width: 500px; margin: 0; color: var(--muted); font-size: .92rem; }\n\n    .overview-grid {\n      display: grid;\n      grid-template-columns: repeat(4, 1fr);\n      gap: 12px;\n    }\n    .metric {\n      padding: 18px;\n      border: 1px solid var(--line);\n      border-radius: 15px;\n      background: var(--surface);\n    }\n    .metric-label { display: block; color: var(--muted); font-size: .78rem; font-weight: 750; }\n    .metric-value { display: block; margin-top: 4px; font-size: clamp(1.25rem, 3vw, 1.8rem); font-weight: 900; letter-spacing: -.03em; }\n    .metric small { display: block; margin-top: 3px; color: var(--muted); }\n\n    .timeline-card {\n      padding: 18px;\n      border: 1px solid var(--line);\n      border-radius: var(--radius);\n      background: var(--surface);\n      box-shadow: 0 8px 28px rgba(31, 53, 86, .06);\n    }\n    .scroll-hint { display: none; color: var(--muted); font-size: .78rem; margin: 0 0 8px; }\n    .timeline-scroll { overflow-x: auto; overscroll-behavior-inline: contain; padding-bottom: 4px; }\n    .timeline {\n      min-width: 840px;\n      display: grid;\n      grid-template-columns: 150px repeat(10, minmax(58px, 1fr));\n      grid-auto-rows: 48px;\n      gap: 7px;\n      align-items: stretch;\n    }\n    .tl-corner, .week-head, .row-label, .week-cell, .bar { border-radius: 9px; }\n    .tl-corner {\n      display: flex;\n      align-items: center;\n      padding: 0 12px;\n      color: var(--muted);\n      background: var(--surface-soft);\n      font-size: .75rem;\n      font-weight: 800;\n      text-transform: uppercase;\n      letter-spacing: .06em;\n    }\n", "    .week-head {\n      display: grid;\n      place-items: center;\n      color: var(--muted);\n      background: var(--surface-soft);\n      font-size: .76rem;\n      font-weight: 850;\n    }\n    .week-head.active { color: var(--ink); background: #edf3fb; }\n    .row-label {\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n      padding: 0 12px;\n      border: 1px solid var(--line);\n      font-size: .82rem;\n      font-weight: 800;\n      background: #fff;\n    }\n    .row-label span { color: var(--muted); font-size: .69rem; font-weight: 650; }\n    .week-cell { border: 1px dashed #e5eaf2; background: #fbfcfe; }\n    .bar {\n      z-index: 2;\n      align-self: stretch;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      padding: 0 8px;\n      color: #fff;\n      font-size: .78rem;\n      font-weight: 850;\n      text-align: center;\n      box-shadow: 0 5px 15px rgba(31, 53, 86, .13);\n    }\n    .bar.diag { background: var(--blue); }\n    .bar.proto { background: var(--teal); }\n    .bar.wait { color: #435064; background: repeating-linear-gradient(135deg, #e6ebf2 0 8px, #d9e0e9 8px 16px); box-shadow: none; border: 1px dashed #9ba6b7; }\n    .bar.pilot { background: var(--orange); }\n    .bar.launch { background: var(--violet); }\n\n    .mobile-plan { display: none; }\n\n    .stage-grid {\n      display: grid;\n      grid-template-columns: repeat(4, 1fr);\n      gap: 14px;\n      counter-reset: etapa;\n    }\n    .stage-card {\n      position: relative;\n      overflow: hidden;\n      min-height: 220px;\n      padding: 20px;\n      border: 1px solid var(--line);\n      border-radius: var(--radius);\n      background: var(--surface);\n      counter-increment: etapa;\n    }\n    .stage-card::after {\n      content: counter(etapa, decimal-leading-zero);\n      position: absolute;\n      right: 13px;\n      bottom: -15px;\n      color: rgba(33, 56, 91, .06);\n      font-size: 5.5rem;\n      font-weight: 950;\n      line-height: 1;\n    }\n    .stage-top { display: flex; justify-content: space-between; gap: 10px; align-items: start; }\n    .stage-dot { width: 12px; height: 12px; margin-top: 5px; border-radius: 50%; background: var(--stage-color); box-shadow: 0 0 0 6px color-mix(in srgb, var(--stage-color) 13%, transparent); }\n    .fixed-badge { padding: 5px 8px; border-radius: 999px; color: var(--muted); background: #f0f3f7; font-size: .68rem; font-weight: 800; white-space: nowrap; }\n    .stage-card h3 { margin: 18px 0 4px; font-size: 1.18rem; }\n    .stage-week { color: var(--stage-color); font-size: .9rem; font-weight: 850; }\n    .stage-card p { position: relative; z-index: 1; margin: 14px 0 0; color: var(--muted); font-size: .92rem; }\n    .diag-card { --stage-color: var(--blue); }\n    .proto-card { --stage-color: var(--teal); }\n    .pilot-card { --stage-color: var(--orange); }\n    .launch-card { --stage-color: var(--violet); }\n\n    .dependency-card {\n      padding: 26px;\n      border: 1px solid var(--line);\n      border-radius: var(--radius);\n      background: var(--surface);\n    }\n    .flow {\n      display: grid;\n      grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr;\n      gap: 10px;\n      align-items: center;\n    }\n    .flow-node {\n      min-height: 112px;\n      padding: 16px;\n      border: 1px solid var(--line);\n      border-top: 5px solid var(--node-color);\n      border-radius: 13px;\n      background: var(--surface-soft);\n    }\n    .flow-node strong { display: block; font-size: .96rem; }\n    .flow-node span { display: block; margin-top: 6px; color: var(--muted); font-size: .79rem; }\n    .flow-arrow { color: #a1adbe; font-size: 1.45rem; font-weight: 900; }\n    .dependency-list {\n      display: grid;\n      grid-template-columns: repeat(3, 1fr);\n      gap: 12px;\n      margin: 18px 0 0;\n      padding: 0;\n      list-style: none;\n    }\n    .dependency-list li {\n      padding: 14px 15px;\n      border-radius: 12px;\n      color: #48566d;\n      background: #f2f5f9;\n      font-size: .86rem;\n    }\n    .dependency-list stron", "g { color: var(--ink); }\n\n    .formula {\n      margin: 24px 0 54px;\n      padding: 22px;\n      border-radius: var(--radius);\n      color: #fff;\n      background: linear-gradient(135deg, #233b61, #1c2f4c);\n    }\n    .formula h2 { margin: 0 0 12px; font-size: 1.2rem; }\n    .formula-line {\n      display: flex;\n      flex-wrap: wrap;\n      align-items: center;\n      gap: 9px;\n      font-weight: 800;\n    }\n    .formula-chip { padding: 8px 11px; border: 1px solid rgba(255,255,255,.18); border-radius: 9px; background: rgba(255,255,255,.08); }\n    .formula-result { color: #fff0ad; }\n    .formula-note { margin: 12px 0 0; color: #c9d6e8; font-size: .86rem; }\n\n    footer { padding: 0 0 36px; color: var(--muted); font-size: .78rem; }\n\n    @media (max-width: 920px) {\n      .sim-grid { grid-template-columns: 1fr; }\n      .overview-grid { grid-template-columns: repeat(2, 1fr); }\n      .stage-grid { grid-template-columns: repeat(2, 1fr); }\n      .flow { grid-template-columns: 1fr; }\n      .flow-node { min-height: auto; }\n      .flow-arrow { justify-self: center; transform: rotate(90deg); }\n      .dependency-list { grid-template-columns: 1fr; }\n    }\n\n    @media (max-width: 640px) {\n      .shell { width: min(100% - 22px, 1120px); }\n      .hero { padding: 34px 0 16px; }\n      .hero-copy { margin-top: 14px; }\n      .simulator { padding: 17px; margin-top: 14px; }\n      .control-title { align-items: start; flex-direction: column; gap: 2px; }\n      .quick-buttons { justify-content: space-between; }\n      .quick-buttons button { flex: 1; padding: 0; }\n      .launch-result { min-height: 140px; }\n      .premise { grid-template-columns: 1fr; padding: 16px; }\n      .section { padding: 21px 0; }\n      .section-head { align-items: start; flex-direction: column; gap: 8px; }\n      .overview-grid, .stage-grid { grid-template-columns: 1fr; }\n      .metric { padding: 15px; }\n      .timeline-card { display: none; }\n      .mobile-plan { display: grid; gap: 10px; }\n      .mobile-row {\n        display: grid;\n        grid-template-columns: 12px 1fr auto;\n        gap: 12px;\n        align-items: center;\n        padding: 14px;\n        border: 1px solid var(--line);\n        border-radius: 14px;\n        background: #fff;\n      }\n      .mobile-color { width: 12px; height: 42px; border-radius: 999px; background: var(--m-color); }\n      .mobile-row strong { display: block; }\n      .mobile-row span { display: block; color: var(--muted); font-size: .8rem; }\n      .mobile-week { color: var(--ink) !important; font-weight: 850; text-align: right; white-space: nowrap; }\n      .stage-card { min-height: 190px; }\n      .dependency-card { padding: 17px; }\n      .formula { margin-bottom: 36px; }\n    }\n\n    @media (prefers-reduced-motion: reduce) {\n      html { scroll-behavior: auto; }\n      *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }\n    }\n  </style>\n</head>\n<body>\n  <header class=\"hero\">\n    <div class=\"shell\">\n      <p class=\"eyebrow\">Plano de lançamento interativo</p>\n      <h1>Seis semanas de trabalho, com o impacto do atraso visível.</h1>\n      <p class=\"hero-copy\">Ajuste o atraso antes do piloto. O plano preserva a duração de todas as etapas e recalcula, na hora, a semana do lançamento.</p>\n\n      <section class=\"simulator\" aria-labelledby=\"sim-title\">\n        <div class=\"sim-grid\">\n          <div>\n            <div class=\"control-title\">\n              <label id=\"sim-title\" for=\"delay\">Atraso antes do piloto</label>\n              <output class=\"delay-readout\" id=\"delayOutput\" for=\"delay\">0 semanas</output>\n            </div>\n            <div class=\"range-wrap\">\n              <input id=\"delay\" type=\"range\" min=\"0\" max=\"4\" step=\"1\" value=\"0\" aria-describedby=\"premise-text\">\n              <div class=\"range-labels\" aria-hidden=\"true\"><span>0</span><span>1</span><span>2</span><span>3</span><span>4 semanas</span></div>\n            </div>\n            <div class=\"quick-buttons\" aria-label=\"Escolha rápida do atraso\">\n           ", "   <button type=\"button\" data-delay=\"0\" aria-pressed=\"true\">0</button>\n              <button type=\"button\" data-delay=\"1\" aria-pressed=\"false\">1</button>\n              <button type=\"button\" data-delay=\"2\" aria-pressed=\"false\">2</button>\n              <button type=\"button\" data-delay=\"3\" aria-pressed=\"false\">3</button>\n              <button type=\"button\" data-delay=\"4\" aria-pressed=\"false\">4</button>\n            </div>\n          </div>\n          <div class=\"launch-result\" aria-live=\"polite\" aria-atomic=\"true\">\n            <span class=\"result-label\">Lançamento recalculado</span>\n            <strong class=\"result-main\" id=\"launchWeek\">Semana 6</strong>\n            <p class=\"result-detail\" id=\"resultDetail\">Piloto nas semanas 4 e 5 · plano total de 6 semanas</p>\n          </div>\n        </div>\n      </section>\n\n      <aside class=\"premise\" id=\"premise-text\">\n        <div class=\"premise-mark\" aria-hidden=\"true\">!</div>\n        <div>\n          <h2>Premissa do simulador</h2>\n          <p><strong>O atraso é uma espera adicionada antes do piloto.</strong> Ele desloca o piloto e o lançamento pelo mesmo número de semanas. Diagnóstico e protótipo não mudam; as durações continuam fixas em 1, 2, 2 e 1 semana.</p>\n        </div>\n      </aside>\n    </div>\n  </header>\n\n  <main>\n    <section class=\"section\" aria-labelledby=\"overview-title\">\n      <div class=\"shell\">\n        <div class=\"section-head\">\n          <div>\n            <p class=\"section-kicker\">Visão geral</p>\n            <h2 id=\"overview-title\">O que muda e o que permanece</h2>\n          </div>\n          <p class=\"section-note\">O cenário-base tem seis semanas. Somente a espera antes do piloto amplia o calendário total.</p>\n        </div>\n        <div class=\"overview-grid\">\n          <article class=\"metric\">\n            <span class=\"metric-label\">Trabalho planejado</span>\n            <strong class=\"metric-value\">6 semanas</strong>\n            <small>Permanece fixo</small>\n          </article>\n          <article class=\"metric\">\n            <span class=\"metric-label\">Espera adicionada</span>\n            <strong class=\"metric-value\" id=\"delayMetric\">0 semanas</strong>\n            <small>Variável de 0 a 4</small>\n          </article>\n          <article class=\"metric\">\n            <span class=\"metric-label\">Calendário total</span>\n            <strong class=\"metric-value\" id=\"totalMetric\">6 semanas</strong>\n            <small>Trabalho + espera</small>\n          </article>\n          <article class=\"metric\">\n            <span class=\"metric-label\">Semana de lançamento</span>\n            <strong class=\"metric-value\" id=\"launchMetric\">Semana 6</strong>\n            <small>Resultado do cenário</small>\n          </article>\n        </div>\n      </div>\n    </section>\n\n    <section class=\"section\" aria-labelledby=\"timeline-title\">\n      <div class=\"shell\">\n        <div class=\"section-head\">\n          <div>\n            <p class=\"section-kicker\">Linha do tempo</p>\n            <h2 id=\"timeline-title\">Plano recalculado</h2>\n          </div>\n          <p class=\"section-note\" id=\"timelineNote\">Sem atraso: as etapas seguem sem intervalo adicional.</p>\n        </div>\n\n        <div class=\"timeline-card\">\n          <p class=\"scroll-hint\">Deslize a linha do tempo para o lado.</p>\n          <div class=\"timeline-scroll\" tabindex=\"0\" aria-label=\"Linha do tempo por semana\">\n            <div class=\"timeline\" id=\"timeline\"></div>\n          </div>\n        </div>\n\n        <div class=\"mobile-plan\" id=\"mobilePlan\" aria-label=\"Plano por etapa para celular\"></div>\n      </div>\n    </section>\n\n    <section class=\"section\" aria-labelledby=\"stages-title\">\n      <div class=\"shell\">\n        <div class=\"section-head\">\n          <div>\n            <p class=\"section-kicker\">Etapas</p>\n            <h2 id=\"stages-title\">Quatro blocos, durações fixas</h2>\n          </div>\n          <p class=\"section-note\">A semana pode mudar para piloto e lançamento, mas o tempo gasto em cada etapa permanece igual.</p>\n        </div>\n        <div class=", "\"stage-grid\">\n          <article class=\"stage-card diag-card\">\n            <div class=\"stage-top\"><span class=\"stage-dot\" aria-hidden=\"true\"></span><span class=\"fixed-badge\">1 semana · fixa</span></div>\n            <h3>Diagnóstico</h3>\n            <div class=\"stage-week\">Semana 1</div>\n            <p>Organizar o ponto de partida e esclarecer o que precisa ser validado antes de criar a solução.</p>\n          </article>\n          <article class=\"stage-card proto-card\">\n            <div class=\"stage-top\"><span class=\"stage-dot\" aria-hidden=\"true\"></span><span class=\"fixed-badge\">2 semanas · fixas</span></div>\n            <h3>Protótipo</h3>\n            <div class=\"stage-week\">Semanas 2 e 3</div>\n            <p>Transformar o diagnóstico em uma primeira versão e refiná-la antes do teste controlado.</p>\n          </article>\n          <article class=\"stage-card pilot-card\">\n            <div class=\"stage-top\"><span class=\"stage-dot\" aria-hidden=\"true\"></span><span class=\"fixed-badge\">2 semanas · fixas</span></div>\n            <h3>Piloto</h3>\n            <div class=\"stage-week\" id=\"pilotStageWeek\">Semanas 4 e 5</div>\n            <p>Testar em escala limitada. O atraso escolhido muda o início desta etapa, não sua duração.</p>\n          </article>\n          <article class=\"stage-card launch-card\">\n            <div class=\"stage-top\"><span class=\"stage-dot\" aria-hidden=\"true\"></span><span class=\"fixed-badge\">1 semana · fixa</span></div>\n            <h3>Lançamento</h3>\n            <div class=\"stage-week\" id=\"launchStageWeek\">Semana 6</div>\n            <p>Colocar a versão de lançamento em circulação assim que o piloto de duas semanas terminar.</p>\n          </article>\n        </div>\n      </div>\n    </section>\n\n    <section class=\"section\" aria-labelledby=\"dependencies-title\">\n      <div class=\"shell\">\n        <div class=\"section-head\">\n          <div>\n            <p class=\"section-kicker\">Dependências</p>\n            <h2 id=\"dependencies-title\">Uma etapa libera a próxima</h2>\n          </div>\n          <p class=\"section-note\">A espera variável entra em um único ponto: entre o fim do protótipo e o começo do piloto.</p>\n        </div>\n        <div class=\"dependency-card\">\n          <div class=\"flow\" role=\"img\" aria-label=\"Diagnóstico leva ao protótipo, que leva ao piloto após a espera escolhida, e o piloto leva ao lançamento\">\n            <div class=\"flow-node\" style=\"--node-color: var(--blue)\"><strong>Diagnóstico</strong><span>Termina na semana 1</span></div>\n            <div class=\"flow-arrow\" aria-hidden=\"true\">→</div>\n            <div class=\"flow-node\" style=\"--node-color: var(--teal)\"><strong>Protótipo</strong><span>Começa após o diagnóstico</span></div>\n            <div class=\"flow-arrow\" aria-hidden=\"true\">→</div>\n            <div class=\"flow-node\" style=\"--node-color: var(--orange)\"><strong>Piloto</strong><span id=\"pilotDependency\">Começa após o protótipo, sem espera adicional</span></div>\n            <div class=\"flow-arrow\" aria-hidden=\"true\">→</div>\n            <div class=\"flow-node\" style=\"--node-color: var(--violet)\"><strong>Lançamento</strong><span>Começa quando o piloto termina</span></div>\n          </div>\n          <ul class=\"dependency-list\">\n            <li><strong>Diagnóstico → Protótipo:</strong> o protótipo só começa depois da primeira semana.</li>\n            <li><strong>Protótipo → Piloto:</strong> é aqui que o atraso de 0 a 4 semanas é aplicado.</li>\n            <li><strong>Piloto → Lançamento:</strong> o lançamento avança na mesma proporção do atraso.</li>\n          </ul>\n        </div>\n      </div>\n    </section>\n\n    <section class=\"shell formula\" aria-labelledby=\"formula-title\">\n      <h2 id=\"formula-title\">Regra simples do cenário</h2>\n      <div class=\"formula-line\" aria-live=\"polite\">\n        <span class=\"formula-chip\">Semana-base do lançamento: 6</span>\n        <span aria-hidden=\"true\">+</span>\n        <span class=\"formula-chip\" id=\"formulaDelay\">Atraso: 0</span>\n        <span aria-hidden=\"true\">=</span>\n        ", "<span class=\"formula-chip formula-result\" id=\"formulaResult\">Lançamento: semana 6</span>\n      </div>\n      <p class=\"formula-note\">Não há datas de calendário nem responsáveis neste plano. As semanas são posições relativas a partir do início do trabalho.</p>\n    </section>\n  </main>\n\n  <footer>\n    <div class=\"shell\">Plano visual de referência · cenário ajustável de 0 a 4 semanas de atraso antes do piloto.</div>\n  </footer>\n\n  <script>\n    (function () {\n      'use strict';\n\n      const slider = document.getElementById('delay');\n      const quickButtons = Array.from(document.querySelectorAll('[data-delay]'));\n      const timeline = document.getElementById('timeline');\n      const mobilePlan = document.getElementById('mobilePlan');\n\n      const elements = {\n        delayOutput: document.getElementById('delayOutput'),\n        launchWeek: document.getElementById('launchWeek'),\n        resultDetail: document.getElementById('resultDetail'),\n        delayMetric: document.getElementById('delayMetric'),\n        totalMetric: document.getElementById('totalMetric'),\n        launchMetric: document.getElementById('launchMetric'),\n        timelineNote: document.getElementById('timelineNote'),\n        pilotStageWeek: document.getElementById('pilotStageWeek'),\n        launchStageWeek: document.getElementById('launchStageWeek'),\n        pilotDependency: document.getElementById('pilotDependency'),\n        formulaDelay: document.getElementById('formulaDelay'),\n        formulaResult: document.getElementById('formulaResult')\n      };\n\n      function plural(value, singular, pluralForm) {\n        return value === 1 ? singular : pluralForm;\n      }\n\n      function makeElement(tag, className, text) {\n        const element = document.createElement(tag);\n        if (className) element.className = className;\n        if (text !== undefined) element.textContent = text;\n        return element;\n      }\n\n      function addGridItem(parent, item, column, row, span) {\n        item.style.gridColumn = column + ' / span ' + (span || 1);\n        item.style.gridRow = String(row);\n        parent.appendChild(item);\n      }\n\n      function renderTimeline(delay) {\n        timeline.textContent = '';\n        const pilotStart = 4 + delay;\n        const launch = 6 + delay;\n        const activeLastWeek = launch;\n\n        addGridItem(timeline, makeElement('div', 'tl-corner', 'Etapa'), 1, 1, 1);\n        for (let week = 1; week <= 10; week += 1) {\n          const header = makeElement('div', 'week-head' + (week <= activeLastWeek ? ' active' : ''), 'S' + week);\n          header.setAttribute('aria-label', 'Semana ' + week);\n          addGridItem(timeline, header, week + 1, 1, 1);\n        }\n\n        const rows = [\n          { name: 'Diagnóstico', duration: '1 semana fixa', row: 2, start: 1, span: 1, className: 'diag', label: 'S1' },\n          { name: 'Protótipo', duration: '2 semanas fixas', row: 3, start: 2, span: 2, className: 'proto', label: 'S2–S3' },\n          { name: 'Espera', duration: delay === 0 ? 'nenhuma' : delay + ' ' + plural(delay, 'semana', 'semanas'), row: 4, start: 4, span: delay, className: 'wait', label: delay === 0 ? '' : 'Atraso' },\n          { name: 'Piloto', duration: '2 semanas fixas', row: 5, start: pilotStart, span: 2, className: 'pilot', label: 'S' + pilotStart + '–S' + (pilotStart + 1) },\n          { name: 'Lançamento', duration: '1 semana fixa', row: 6, start: launch, span: 1, className: 'launch', label: 'S' + launch }\n        ];\n\n        rows.forEach(function (config) {\n          const rowLabel = makeElement('div', 'row-label');\n          rowLabel.appendChild(makeElement('strong', '', config.name));\n          rowLabel.appendChild(makeElement('span', '', config.duration));\n          addGridItem(timeline, rowLabel, 1, config.row, 1);\n\n          for (let week = 1; week <= 10; week += 1) {\n            addGridItem(timeline, makeElement('div', 'week-cell'), week + 1, config.row, 1);\n          }\n\n          if (config.span > 0) {\n            const bar = makeEle", "ment('div', 'bar ' + config.className, config.label);\n            const accessibleLabel = config.name + ': ' + (config.span === 1 ? 'semana ' + config.start : 'semanas ' + config.start + ' a ' + (config.start + config.span - 1));\n            bar.setAttribute('aria-label', accessibleLabel);\n            addGridItem(timeline, bar, config.start + 1, config.row, config.span);\n          }\n        });\n      }\n\n      function renderMobilePlan(delay) {\n        mobilePlan.textContent = '';\n        const pilotStart = 4 + delay;\n        const launch = 6 + delay;\n        const stages = [\n          { name: 'Diagnóstico', detail: '1 semana fixa', week: 'Semana 1', color: 'var(--blue)' },\n          { name: 'Protótipo', detail: '2 semanas fixas', week: 'Semanas 2–3', color: 'var(--teal)' }\n        ];\n\n        if (delay > 0) {\n          const waitEnd = 3 + delay;\n          stages.push({\n            name: 'Espera antes do piloto',\n            detail: delay + ' ' + plural(delay, 'semana adicionada', 'semanas adicionadas'),\n            week: delay === 1 ? 'Semana 4' : 'Semanas 4–' + waitEnd,\n            color: 'var(--wait)'\n          });\n        }\n\n        stages.push(\n          { name: 'Piloto', detail: '2 semanas fixas', week: 'Semanas ' + pilotStart + '–' + (pilotStart + 1), color: 'var(--orange)' },\n          { name: 'Lançamento', detail: '1 semana fixa', week: 'Semana ' + launch, color: 'var(--violet)' }\n        );\n\n        stages.forEach(function (stage) {\n          const row = makeElement('article', 'mobile-row');\n          const color = makeElement('span', 'mobile-color');\n          color.style.setProperty('--m-color', stage.color);\n          color.setAttribute('aria-hidden', 'true');\n          const text = makeElement('div', '');\n          text.appendChild(makeElement('strong', '', stage.name));\n          text.appendChild(makeElement('span', '', stage.detail));\n          const week = makeElement('span', 'mobile-week', stage.week);\n          row.appendChild(color);\n          row.appendChild(text);\n          row.appendChild(week);\n          mobilePlan.appendChild(row);\n        });\n      }\n\n      function update(value) {\n        const delay = Math.max(0, Math.min(4, Number(value) || 0));\n        const pilotStart = 4 + delay;\n        const pilotEnd = 5 + delay;\n        const launch = 6 + delay;\n        const total = 6 + delay;\n        const delayText = delay + ' ' + plural(delay, 'semana', 'semanas');\n        const totalText = total + ' ' + plural(total, 'semana', 'semanas');\n\n        slider.value = String(delay);\n        slider.style.setProperty('--fill', (delay / 4 * 100) + '%');\n        elements.delayOutput.textContent = delayText;\n        elements.launchWeek.textContent = 'Semana ' + launch;\n        elements.resultDetail.textContent = 'Piloto nas semanas ' + pilotStart + ' e ' + pilotEnd + ' · plano total de ' + totalText;\n        elements.delayMetric.textContent = delayText;\n        elements.totalMetric.textContent = totalText;\n        elements.launchMetric.textContent = 'Semana ' + launch;\n        elements.pilotStageWeek.textContent = 'Semanas ' + pilotStart + ' e ' + pilotEnd;\n        elements.launchStageWeek.textContent = 'Semana ' + launch;\n        elements.formulaDelay.textContent = 'Atraso: ' + delay;\n        elements.formulaResult.textContent = 'Lançamento: semana ' + launch;\n\n        if (delay === 0) {\n          elements.timelineNote.textContent = 'Sem atraso: as etapas seguem sem intervalo adicional.';\n          elements.pilotDependency.textContent = 'Começa após o protótipo, sem espera adicional';\n        } else {\n          elements.timelineNote.textContent = 'Com ' + delayText + ' de espera, o piloto começa na semana ' + pilotStart + ' e o lançamento vai para a semana ' + launch + '.';\n          elements.pilotDependency.textContent = 'Começa após o protótipo + ' + delayText + ' de espera';\n        }\n\n        quickButtons.forEach(function (button) {\n          button.setAttribute('aria-pressed', String(Number(button.dataset.dela", "y) === delay));\n        });\n\n        renderTimeline(delay);\n        renderMobilePlan(delay);\n      }\n\n      slider.addEventListener('input', function (event) { update(event.target.value); });\n      quickButtons.forEach(function (button) {\n        button.addEventListener('click', function () { update(button.dataset.delay); });\n      });\n\n      update(0);\n    }());\n  </script>\n</body>\n</html>\n"].join("")
};

export const GeneratedArtifact = ({example, source, language = "pt"}) => {
  const [artifact, setArtifact] = useState(null);
  const [expanded, setExpanded] = useState(false);
  const [canExpand, setCanExpand] = useState(false);
  const [expandFailed, setExpandFailed] = useState(false);
  const id = `generated-artifact-${example}`;
  const labels = language === "en" ? {
    loading: "Opening the generated example…",
    expand: "Enlarge example",
    restore: "Exit full screen",
    download: "Download original file",
    title: "Complete generated example",
    expandError: "Full screen is unavailable in this browser. You can still explore the example below or download it.",
    note: "Complete file generated in a Morada OS test conversation with fictional data. Scroll inside the example to explore the whole page."
  } : {
    loading: "Abrindo o exemplo gerado…",
    expand: "Ampliar exemplo",
    restore: "Sair da tela cheia",
    download: "Baixar arquivo original",
    title: "Exemplo completo gerado",
    expandError: "Não foi possível ampliar neste navegador. Você pode explorar o exemplo abaixo ou baixar o arquivo.",
    note: "Arquivo completo gerado em uma conversa de teste do Morada OS, com dados fictícios. Role dentro do exemplo para explorar a página inteira."
  };
  useEffect(() => {
    setExpandFailed(false);
    const escapes = {
      "&": "&amp;",
      '"': "&quot;",
      "<": "&lt;",
      ">": "&gt;"
    };
    const html = source.html.replace(/[&"<>]/g, character => escapes[character]);
    const policy = "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:; font-src data:; connect-src 'none'; base-uri 'none'; form-action 'none'; frame-src 'none'; worker-src 'none'; webrtc 'block'";
    const srcDoc = `<!doctype html><html><head><meta charset="utf-8"><base href="about:srcdoc"><meta http-equiv="Content-Security-Policy" content="${policy}"><meta name="referrer" content="no-referrer"><style>html,body{height:100%;margin:0}iframe{display:block;width:100%;height:100%;border:0}</style></head><body><iframe title="${language === "en" ? "Generated content" : "Conteúdo gerado"}" sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer" srcdoc="${html}"></iframe></body></html>`;
    setArtifact({
      filename: source.filename,
      html: source.html,
      srcDoc
    });
  }, [source.html, source.filename, language]);
  useEffect(() => {
    setCanExpand(Boolean(document.fullscreenEnabled));
    const changed = () => setExpanded(document.fullscreenElement?.id === id);
    document.addEventListener("fullscreenchange", changed);
    return () => document.removeEventListener("fullscreenchange", changed);
  }, [id]);
  const download = () => {
    if (!artifact) return;
    const url = URL.createObjectURL(new Blob([artifact.html], {
      type: "text/html;charset=utf-8"
    }));
    const anchor = document.createElement("a");
    anchor.href = url;
    anchor.download = artifact.filename;
    document.body.appendChild(anchor);
    anchor.click();
    anchor.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  };
  const enlarge = () => {
    setExpandFailed(false);
    const action = expanded ? document.exitFullscreen() : document.getElementById(id)?.requestFullscreen();
    action?.catch(() => setExpandFailed(true));
  };
  const css = `
.mo-artifact { --artifact-bg:#f8fafc; --artifact-ink:#1e293b; --artifact-line:#cbd5e1; --artifact-hover:#e2e8f0; margin:24px 0; border:1px solid var(--artifact-line); border-radius:16px; overflow:hidden; background:var(--artifact-bg); color:var(--artifact-ink); }
.dark .mo-artifact { --artifact-bg:#18212e; --artifact-ink:#f1f5f9; --artifact-line:#475569; --artifact-hover:#334155; }
.mo-artifact:fullscreen { width:100vw; height:100dvh; border:0; border-radius:0; margin:0; display:flex; flex-direction:column; }
.mo-artifact .artifact-toolbar { display:flex; align-items:center; flex-wrap:wrap; gap:8px; padding:12px; border-bottom:1px solid var(--artifact-line); flex-shrink:0; }
.mo-artifact .artifact-name { flex:1 1 180px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px; }
.mo-artifact button { min-height:44px; padding:8px 12px; border:1px solid var(--artifact-line); border-radius:8px; color:var(--artifact-ink); background:transparent; cursor:pointer; font:inherit; font-size:12px; }
.mo-artifact button:hover { background:var(--artifact-hover); }
.mo-artifact button:active { box-shadow:inset 0 0 0 2px var(--artifact-ink); }
.mo-artifact button:focus-visible { outline:3px solid #2683eb; outline-offset:2px; }
.mo-artifact button:disabled { cursor:default; opacity:.5; }
.mo-artifact > iframe { display:block; width:100%; height:720px; border:0; background:white; }
.mo-artifact:fullscreen > iframe { flex:1; min-height:0; height:100%; }
.mo-artifact .artifact-status { padding:24px; font-size:14px; }
.mo-artifact .artifact-note { margin:0; padding:12px; font-size:12px; line-height:1.6; color:var(--artifact-ink); border-top:1px solid var(--artifact-line); }
.mo-artifact:fullscreen .artifact-note { display:none; }
@media(max-width:600px) { .mo-artifact > iframe { height:640px; } .mo-artifact .artifact-name { flex-basis:100%; } }
`;
  return <section id={id} className="mo-artifact" aria-label={labels.title}>
      <style>{css}</style>
      <div className="artifact-toolbar">
        <span className="artifact-name" title={artifact?.filename}>
          {artifact?.filename || labels.title}
        </span>
        {canExpand && <button type="button" onClick={enlarge} disabled={!artifact}>
            {expanded ? labels.restore : labels.expand}
          </button>}
        <button type="button" onClick={download} disabled={!artifact}>
          {labels.download}
        </button>
      </div>
      {artifact ? <iframe title={labels.title} srcDoc={artifact.srcDoc} sandbox="allow-scripts allow-forms" referrerPolicy="no-referrer" /> : <div className="artifact-status" role="status">
          {labels.loading}
        </div>}
      {expandFailed && <p className="artifact-note" role="status">
          {labels.expandError}
        </p>}
      <p className="artifact-note">{labels.note}</p>
    </section>;
};

**You need:** a plan, idea, or explanation already in the conversation · **Example:** a launch over six weeks

You received a long plan and understand the steps, but you still cannot explain how they connect. Ask the assistant: **"Explain this to me visually."** It can organize the overview, show dependencies, and let you explore a change. To receive a page you can open, add: **"Deliver it as an interactive file here in the conversation."**

## Try a meeting question

"What if the pilot is delayed by one week?" Move the control and watch the launch move from week 6 to week 7. The example keeps each stage's duration and does not assume the team can make up for the delay.

<GeneratedArtifact example="plan" source={planArtifact} language="en" />

<Note>This complete file was generated by Morada OS from the Portuguese version of the prompt below; its content remains in Portuguese. The schedule is an example, not an estimate of effort or the team's actual availability.</Note>

## Copy this prompt

```text wrap theme={null}
Explain a six-week launch plan to me visually: discovery in week 1, prototype in weeks 2 and 3, pilot in weeks 4 and 5, and launch in week 6. Organize the overview, stages, and dependencies in plain language. I want to change the pilot's delay from 0 to 4 weeks and see the launch week change while keeping the duration of each stage. Show this assumption clearly. Do not invent owners or calendar dates. Make it work well on a phone and deliver it as an interactive file I can open in this conversation.
```

If the plan is already in the conversation, just refer to it: "Turn the plan we just discussed into a visual explanation with stages and dependencies." You do not need to write everything again.

## Use the visual to answer questions

**Click the .html file card** and open **Visualização** (Preview). Explore the stages and try the control. Use **Expandir visualização** (Expand preview) to show the team and **Baixar arquivo** (Download file) to keep the original explanation.

Continue in the same conversation:

> "Explain the pilot stage with a concrete example for someone who has never taken part in a launch."

> "Show what could happen in parallel, but mark it as an alternative we need to validate."

> "Remove the simulator and turn the page into a reading guide with questions and answers for each stage."

The same approach helps explain a customer service process, compare two proposals, or present a decision. **There does not have to be a calculation:** the benefit may come from organizing information and revealing details at the right moment. If a paragraph or a simple diagram is enough, ask for that shorter version.

[See how to open, expand, and save your file](/morada-os/en/use-cases/create-visual-experiences).
