Generator Briefu Strony
Stwórz kompletny, profesjonalny brief w kilka minut
Tworzenie strony internetowej potrafi być czasochłonne — trzeba zebrać wymagania, ustalić cele, opisać funkcje, a potem ułożyć to w spójną dokumentację. Właśnie dlatego powstała ta aplikacja.
Generator Briefu Strony to proste, szybkie i wyjątkowo szczegółowe narzędzie, które pomaga uporządkować wszystkie kluczowe elementy projektu i wygenerować gotowy dokument w formacie Markdown.
Do czego służy aplikacja?
Aplikacja pozwala łatwo stworzyć:
- profesjonalny brief dla projektanta, developera lub agencji,
- dokumentację projektową dla zespołu IT,
- specyfikację funkcjonalną i niefunkcjonalną strony internetowej,
- plan projektu uwzględniający cele, grupy odbiorców, technologie i zasoby,
- szablon, który można szybko powielać dla kolejnych realizacji.
Świetnie sprawdzi się zarówno przy małych stronach firmowych, landing page, jak i rozbudowanych serwisach czy portalach.
Jak działa?
- Wypełnij formularz — krok po kroku opisujesz wszystkie aspekty projektu: cele biznesowe, charakter strony, wymagania technologiczne, treści, funkcje, SEO, strukturę podstron i wiele więcej.
- Kliknij „Generuj brief” — aplikacja automatycznie tworzy spójny, czytelny dokument w formacie Markdown, który możesz:
- skopiować,
- pobrać jako plik
.md, - wykorzystać w dowolnym narzędziu do dokumentacji lub jako podstawę umowy projektowej.
- Korzystaj wielokrotnie — wypełnij brief dla nowych projektów, zapisuj swoje szablony i buduj własną bibliotekę specyfikacji.
Dlaczego warto?
- oszczędzasz czas,
- niczego nie pominiesz — formularz uwzględnia nawet zaawansowane aspekty projektu,
- dokument jest spójny i profesjonalny,
- zero logowania — wszystko działa lokalnie w Twojej przeglądarce,
- lekki, szybki i gotowy do użycia od razu.
Prywatność
Generator działa w pełni po stronie klienta — nic nie jest wysyłane na serwer.
Formularz briefu
Wypełnij pola i wygeneruj szczegółowy brief w formacie Markdown (.md).Wynik (Markdown)
Kod po stronie przeglądarki
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/codemirror.min.css">
<link rel="stylesheet" href="http://www.dariuszrorat.ugu.pl/assets/css/codemirror/theme/light.css">
<link rel="stylesheet" href="http://www.dariuszrorat.ugu.pl/assets/css/codemirror/themes.css">
<link type="text/css" href="http://www.dariuszrorat.ugu.pl/assets/css/bootstrap/wcag-outline.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/mode/clike/clike.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/mode/css/css.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/mode/xml/xml.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/mode/htmlmixed/htmlmixed.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/mode/meta.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/addon/edit/matchtags.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/addon/fold/xml-fold.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/addon/edit/closetag.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/mode/markdown/markdown.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/addon/edit/matchbrackets.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.7/addon/edit/closebrackets.min.js"></script>
<style>
body { padding: 1.25rem; }
.form-section { border-radius: .5rem; padding: 1rem; box-shadow: 0 2px 6px rgba(0,0,0,.06); }
pre.markdown-output { white-space: pre-wrap; word-wrap: break-word; }
.small-input { font-size:.9rem; padding:.45rem .6rem }
</style>
<div id="app">
<div class="d-flex align-items-center mb-3">
<div>
<h2 class="h4 mb-0">Formularz briefu</h2>
<small class="text-muted">Wypełnij pola i wygeneruj szczegółowy brief w formacie Markdown (.md).</small>
</div>
<div class="ms-auto">
<button id="loadExample" class="btn btn-outline-secondary btn-sm">Załaduj przykładowy brief</button>
</div>
</div>
<div class="row g-3">
<div class="col-lg-12">
<div class="form-section">
<form id="briefForm">
<h2 class="h6">Podstawowe</h2>
<div class="mb-3">
<label for="projectName" class="form-label">Nazwa projektu / strona</label>
<input type="text" id="projectName" class="form-control" placeholder="np. Sklep z rękodziełem" required>
</div>
<div class="mb-3 row">
<div class="col-6">
<label for="client" class="form-label">Klient / firma</label>
<input type="text" id="client" class="form-control small-input" placeholder="Nazwa firmy">
</div>
<div class="col-6">
<label for="contact" class="form-label">Kontakt (email / tel)</label>
<input type="text" id="contact" class="form-control small-input" placeholder="kontakt@firma.pl">
</div>
</div>
<div class="mb-3">
<label for="goal" class="form-label">Cel strony (krótko)</label>
<input type="text" id="goal" class="form-control" placeholder="np. Sprzedaż produktów, lead generation">
</div>
<div class="mb-3">
<label for="businessDesc" class="form-label">Krótki opis biznesowy</label>
<textarea id="businessDesc" class="form-control" rows="3" placeholder="Czym zajmuje się klient, co sprzedaje, wyróżniki"></textarea>
</div>
<h2 class="h6 mt-3">Użytkownicy i funkcje</h2>
<div class="mb-3">
<label for="audience" class="form-label">Grupa docelowa / persony</label>
<textarea id="audience" class="form-control" rows="3" placeholder="np. Persona A:...\nPersona B:..."></textarea>
<div class="small text-muted">Wymień persony lub grupy, po jednej na linię.</div>
</div>
<div class="mb-3">
<label for="userStories" class="form-label">User stories (najważniejsze)</label>
<textarea id="userStories" class="form-control" rows="4" placeholder="np. Jako użytkownik chcę móc dodać produkt do koszyka..."></textarea>
<div class="small text-muted">Jedna user story na linię.</div>
</div>
<div class="mb-3">
<label for="features" class="form-label">Zakres / kluczowe funkcje</label>
<textarea id="features" class="form-control" rows="4" placeholder="np. Sklep, blog, API integracje..."></textarea>
</div>
<div class="mb-3">
<label for="pages" class="form-label">Szczegółowy sitemap / podstrony</label>
<textarea id="pages" class="form-control" rows="3" placeholder="Jedna podstrona na linię: Home, Sklep > Produkt, Koszyk, Checkout, O nas, Kontakt"></textarea>
</div>
<div class="mb-3">
<label for="pageDetails" class="form-label">Szczegóły podstron (opcjonalnie)</label>
<textarea id="pageDetails" class="form-control" rows="3" placeholder="np. Strona Produkt: galeria, warianty, recenzje, cross-sell"></textarea>
<div class="small text-muted">Przykładowo: "Produkt: galeria, warianty, SKU, recenzje"</div>
</div>
<h2 class="h6 mt-3">Design i treści</h2>
<div class="mb-3">
<label for="tone" class="form-label">Ton komunikacji / styl</label>
<input type="text" id="tone" class="form-control" placeholder="Przyjazny, ekspercki...">
</div>
<div class="mb-3 row">
<div class="col-8">
<label for="colors" class="form-label">Paleta kolorów (hex)</label>
<input type="text" id="colors" class="form-control" placeholder="#0d6efd, #6c757d, #fff">
</div>
<div class="col-4">
<label for="typography" class="form-label">Typografika</label>
<input type="text" id="typography" class="form-control" placeholder="np. Inter, Roboto, sizes">
</div>
</div>
<div class="mb-3">
<label for="assets" class="form-label">Materiały / zasoby (logo, zdjęcia, copy)</label>
<textarea id="assets" class="form-control" rows="3" placeholder="np. Logo: logo.svg; Zdjęcia: folder /assets/photos/; Teksty: copy.docx"></textarea>
</div>
<h2 class="h6 mt-3">Technologie i wdrożenie</h2>
<div class="mb-3">
<label for="techStack" class="form-label">Preferowane technologie / stack</label>
<input type="text" id="techStack" class="form-control" placeholder="np. Next.js, React, Node.js, WP + WooCommerce, Laravel">
<div class="small text-muted">Jeśli brak preferencji, wpisz: brak. Można też wymienić opcje alternatywne.</div>
</div>
<div class="mb-3 row">
<div class="col-6">
<label for="cms" class="form-label">CMS / edycja treści</label>
<input type="text" id="cms" class="form-control" placeholder="np. WordPress, Strapi, headless">
</div>
<div class="col-6">
<label for="hosting" class="form-label">Hosting / środowiska</label>
<input type="text" id="hosting" class="form-control" placeholder="np. Vercel, AWS, DigitalOcean; staging + prod">
</div>
</div>
<div class="mb-3 row">
<div class="col-6">
<label for="backend" class="form-label">Baza danych / backend</label>
<input type="text" id="backend" class="form-control" placeholder="np. PostgreSQL, Firebase">
</div>
<div class="col-6">
<label for="integrations" class="form-label">Integracje / API</label>
<input type="text" id="integrations" class="form-control" placeholder="np. CRM, ERP, PayU, Stripe, Poczta Polska API">
</div>
</div>
<div class="mb-3">
<label for="analytics" class="form-label">Analityka i tracking</label>
<input type="text" id="analytics" class="form-control" placeholder="Google Analytics 4, Hotjar, Google Tag Manager">
</div>
<h2 class="h6 mt-3">E‑commerce (jeśli dotyczy)</h2>
<div class="mb-3 row">
<div class="col-6">
<label for="ecommercePlatform" class="form-label">Platforma sklepu</label>
<input type="text" id="ecommercePlatform" class="form-control" placeholder="WooCommerce, Shopify, custom">
</div>
<div class="col-6">
<label for="payments" class="form-label">Płatności i dostawy</label>
<input type="text" id="payments" class="form-control" placeholder="PayU, Przelewy24, Stripe; Kurier XYZ">
</div>
</div>
<div class="mb-3">
<label for="productMgmt" class="form-label">Zarządzanie produktami / warianty</label>
<input type="text" id="productMgmt" class="form-control" placeholder="SKU, warianty, stany magazynowe, integracja ERP">
</div>
<h2 class="h6 mt-3">Bezpieczeństwo, dostępność, prawo</h2>
<div class="mb-3">
<label for="security" class="form-label">Wymagania bezpieczeństwa</label>
<input type="text" id="security" class="form-control" placeholder="SSL, WAF, backupy, limit rate">
</div>
<div class="mb-3">
<label for="accessibility" class="form-label">Dostępność (WCAG)</label>
<input type="text" id="accessibility" class="form-control" placeholder="np. WCAG 2.1 AA">
</div>
<div class="mb-3">
<label for="legal" class="form-label">Wymagania prawne / RODO / cookies</label>
<input type="text" id="legal" class="form-control" placeholder="Polityka prywatności, regulamin, cookie banner">
</div>
<h2 class="h6 mt-3">Proces, terminy i budżet</h2>
<div class="mb-3 row">
<div class="col-6">
<label for="deadline" class="form-label">Termin (wstępny)</label>
<input type="date" id="deadline" class="form-control">
</div>
<div class="col-6">
<label for="budget" class="form-label">Budżet orientacyjny</label>
<input type="text" id="budget" class="form-control" placeholder="np. 12 000 PLN">
</div>
</div>
<div class="mb-3">
<label for="sla" class="form-label">Model współpracy / SLA</label>
<input type="text" id="sla" class="form-control" placeholder="np. 3 miesiące wsparcia, czas reakcji 24h">
</div>
<div class="mb-3">
<label for="testing" class="form-label">Kontrola jakości / testy</label>
<input type="text" id="testing" class="form-control" placeholder="Unit tests, E2E, manual QA, cross-browser">
</div>
<div class="mb-3">
<label for="team" class="form-label">Zespół i role</label>
<input type="text" id="team" class="form-control" placeholder="Project manager, dev, designer, copywriter">
</div>
<div class="mb-3">
<label for="migration" class="form-label">Migracja treści / produktów</label>
<input type="text" id="migration" class="form-control" placeholder="Ilość pozycji, format źródłowy, wymagania">
</div>
<div class="mb-3">
<label for="notes" class="form-label">Dodatkowe uwagi</label>
<textarea id="notes" class="form-control" rows="3" placeholder="Inne wymagania, ograniczenia lub priorytety"></textarea>
</div>
<div class="d-flex gap-2">
<button type="button" id="generateBtn" class="btn btn-primary">Generuj Markdown</button>
<button type="button" id="previewBtn" class="btn btn-outline-primary">Podgląd HTML</button>
<button type="button" id="clearBtn" class="btn btn-outline-danger">Wyczyść</button>
</div>
</form>
</div>
</div>
<div class="col-lg-12">
<div class="form-section h-100 d-flex flex-column">
<div class="d-flex mb-2">
<h2 class="h6 mb-0">Wynik (Markdown)</h2>
<div class="ms-auto btn-group" role="group">
<button id="downloadBtn" class="btn btn-sm btn-secondary">Pobierz .md</button>
<button id="toggleRendered" class="btn btn-sm btn-outline-secondary">Pokaż/ukryj render</button>
</div>
</div>
<textarea id="markdownOutput" class="form-control flex-grow-1 markdown-output" placeholder="Tu pojawi się wygenerowany markdown..." aria-label="Wygenerowany markdown"></textarea>
<div id="rendered" class="mt-3" style="display:none; overflow:auto; max-height:500px; padding: .75rem; border-radius: .5rem;"></div>
</div>
</div>
</div>
</div>
<script>
//CodeMirror for textarea
const myTextarea = document.getElementById('markdownOutput');
const editor = CodeMirror.fromTextArea(myTextarea, {
lineNumbers: true,
matchBrackets: true,
autoCloseTags: true,
autoCloseBrackets: true,
mode: "text/markdown",
indentUnit: 4,
indentWithTabs: false,
enterMode: "keep",
tabMode: "shift",
extraKeys: {
Tab: false,
"Shift-Tab": false
}
});
editor.setSize(null, 500);
editor.getWrapperElement().style["font-size"] = "14px";
editor.refresh();
// References
const ids = ['projectName', 'client', 'contact', 'goal', 'businessDesc', 'audience', 'userStories', 'features', 'pages', 'pageDetails', 'tone', 'colors', 'typography', 'assets', 'techStack', 'cms', 'hosting', 'backend', 'integrations', 'analytics', 'ecommercePlatform', 'payments', 'productMgmt', 'security', 'accessibility', 'legal', 'deadline', 'budget', 'sla', 'testing', 'team', 'migration', 'notes'];
const refs = {};
ids.forEach(id => refs[id] = document.getElementById(id));
const generateBtn = document.getElementById('generateBtn');
const previewBtn = document.getElementById('previewBtn');
const clearBtn = document.getElementById('clearBtn');
const downloadBtn = document.getElementById('downloadBtn');
const markdownOutput = document.getElementById('markdownOutput');
const rendered = document.getElementById('rendered');
const toggleRendered = document.getElementById('toggleRendered');
const loadExample = document.getElementById('loadExample');
function linesToList(text) {
if (!text) return '';
return text.split(/\r?\n|;/).map(s => s.trim()).filter(Boolean).map(i => `- ${i}`).join('\n');
}
function commaToList(text) {
if (!text) return '';
return text.split(/,|\r?\n/).map(s => s.trim()).filter(Boolean).map(i => `- ${i}`).join('\n');
}
function safe(s) {
return (s || '').trim();
}
function generateMarkdown() {
const md = [];
md.push(`# ${safe(refs.projectName.value) || 'Nazwa projektu'}\n`);
md.push(`**Klient:** ${safe(refs.client.value) || '-'} `);
md.push(`**Kontakt:** ${safe(refs.contact.value) || '-'} \n`);
if (refs.goal.value) md.push(`**Cel:** ${refs.goal.value} \n`);
if (refs.businessDesc.value) md.push(`**Opis biznesowy:** ${refs.businessDesc.value} \n`);
// Users
md.push('## Użytkownicy i persony\n');
md.push(linesToList(refs.audience.value) || '- Brak szczegółów');
md.push('\n');
md.push('## User stories\n');
md.push(linesToList(refs.userStories.value) || '- Brak');
md.push('\n');
md.push('## Zakres / funkcje\n');
md.push(linesToList(refs.features.value) || '- Brak');
md.push('\n');
md.push('## Sitemap / Podstrony\n');
md.push(linesToList(refs.pages.value) || '- Brak');
md.push('\n');
if (refs.pageDetails.value) {
md.push('## Szczegóły podstron\n');
md.push(refs.pageDetails.value + '\n');
}
md.push('## Design i treści\n');
if (refs.tone.value) md.push(`- Ton komunikacji: ${refs.tone.value}`);
if (refs.colors.value) md.push(`- Paleta kolorów:\n${commaToList(refs.colors.value)}`);
if (refs.typography.value) md.push(`- Typografika: ${refs.typography.value}`);
if (refs.assets.value) md.push(`- Materiały i zasoby:\n${refs.assets.value}`);
md.push('\n');
md.push('## Technologie i wdrożenie\n');
if (refs.techStack.value) md.push(`- Preferowany stack: ${refs.techStack.value}`);
if (refs.cms.value) md.push(`- CMS: ${refs.cms.value}`);
if (refs.hosting.value) md.push(`- Hosting / środowiska: ${refs.hosting.value}`);
if (refs.backend.value) md.push(`- Backend / DB: ${refs.backend.value}`);
if (refs.integrations.value) md.push(`- Integracje / API:\n${refs.integrations.value}`);
if (refs.analytics.value) md.push(`- Analityka / tracking: ${refs.analytics.value}`);
md.push('\n');
if (refs.ecommercePlatform.value || refs.payments.value || refs.productMgmt.value) {
md.push('## E‑commerce (szczegóły)\n');
if (refs.ecommercePlatform.value) md.push(`- Platforma sklepu: ${refs.ecommercePlatform.value}`);
if (refs.payments.value) md.push(`- Płatności / dostawy: ${refs.payments.value}`);
if (refs.productMgmt.value) md.push(`- Zarządzanie produktami: ${refs.productMgmt.value}`);
md.push('\n');
}
md.push('## Bezpieczeństwo, dostępność i prawo\n');
if (refs.security.value) md.push(`- Wymagania bezpieczeństwa: ${refs.security.value}`);
if (refs.accessibility.value) md.push(`- Dostępność: ${refs.accessibility.value}`);
if (refs.legal.value) md.push(`- Wymagania prawne: ${refs.legal.value}`);
md.push('\n');
md.push('## Proces, terminy i budżet\n');
if (refs.deadline.value) md.push(`- Termin: ${refs.deadline.value}`);
if (refs.budget.value) md.push(`- Budżet: ${refs.budget.value}`);
if (refs.sla.value) md.push(`- Model współpracy / SLA: ${refs.sla.value}`);
if (refs.testing.value) md.push(`- Testy / QA: ${refs.testing.value}`);
md.push('\n');
md.push('## Zespół, migracja i utrzymanie\n');
if (refs.team.value) md.push(`- Zespół: ${refs.team.value}`);
if (refs.migration.value) md.push(`- Migracja treści: ${refs.migration.value}`);
if (refs.notes.value) md.push(`- Dodatkowe uwagi: ${refs.notes.value}`);
md.push('\n');
md.push(`*Wygenerowano: ${new Date().toLocaleString()}*`);
return md.join('\n');
}
generateBtn.addEventListener('click', () => {
const md = generateMarkdown();
editor.setValue(md);
if (rendered.style.display !== 'none') rendered.innerHTML = marked.parse(md);
});
previewBtn.addEventListener('click', () => {
const md = markdownOutput.value || generateMarkdown();
rendered.style.display = rendered.style.display === 'none' ? 'block' : 'none';
rendered.innerHTML = marked.parse(md);
if (rendered.style.display !== 'none') rendered.scrollIntoView({
behavior: 'smooth'
});
});
toggleRendered.addEventListener('click', () => {
if (rendered.style.display === 'none') {
rendered.style.display = 'block';
rendered.innerHTML = marked.parse(editor.getValue() || generateMarkdown());
} else {
rendered.style.display = 'none';
}
});
downloadBtn.addEventListener('click', () => {
const md = editor.getValue() || generateMarkdown();
const blob = new Blob([md], {
type: 'text/markdown;charset=utf-8'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
const safeName = (refs.projectName.value || 'brief').trim().replace(/[^a-z0-9-_]/gi, '_').toLowerCase();
a.download = `${safeName || 'brief'}.md`;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
});
clearBtn.addEventListener('click', () => {
if (!confirm('Wyczyścić wszystkie pola?')) return;
document.getElementById('briefForm').reset();
editor.setValue('');
rendered.innerHTML = '';
rendered.style.display = 'none';
});
loadExample.addEventListener('click', () => {
refs.projectName.value = 'Sklep z rękodziełem "RękaDzieło"';
refs.client.value = 'RękaDzieło Sp. z o.o.';
refs.contact.value = 'kontakt@rekadzieło.pl';
refs.goal.value = 'Sprzedaż unikatowych produktów ręcznie robionych oraz budowanie społeczności klientów.';
refs.businessDesc.value = 'Firma sprzedaje rękodzieło wykonane lokalnie. USP: eco materiały, limitowane serie.';
refs.audience.value = 'Kobieta 25-45; Miłośnik rękodzieła; Klient premium';
refs.userStories.value = 'Jako klient chcę znaleźć produkt szybko\nJako admin chcę mieć prosty panel do dodawania produktów';
refs.features.value = 'Sklep online; Blog; Integracja newsletter; Panel klienta; Automatyczne powiadomienia e-mail';
refs.pages.value = 'Home\nSklep\nKategoria\nProdukt\nKoszyk\nCheckout\nO nas\nBlog\nKontakt';
refs.pageDetails.value = 'Produkt: galeria, warianty (rozmiar, kolor), opis SEO, recenzje\nCheckout: adres, płatność, VAT, polityka zwrotów';
refs.tone.value = 'Ciepły, lifestylowy';
refs.colors.value = '#A66F4A, #F6F1EB, #2B2B2B';
refs.typography.value = 'Inter (nagłówki), Roboto (body)';
refs.assets.value = 'Logo: logo.svg; Zdjęcia: /assets/photos/; Teksty: copy_v1.docx';
refs.techStack.value = 'Next.js + React (front), Node.js (API), PostgreSQL';
refs.cms.value = 'Headless CMS (Strapi)';
refs.hosting.value = 'Vercel (frontend), DigitalOcean (backend), staging+prod';
refs.backend.value = 'Node.js + PostgreSQL';
refs.integrations.value = 'Stripe (płatności), API kuriera, CRM: HubSpot';
refs.analytics.value = 'GA4, GTM, Hotjar';
refs.ecommercePlatform.value = 'Custom (headless)';
refs.payments.value = 'Stripe, PayPal; Kurier: DPD, InPost';
refs.productMgmt.value = 'SKU, warianty, stany magazynowe przez ERP';
refs.security.value = 'SSL, backup 24h, monitoring, WAF';
refs.accessibility.value = 'WCAG 2.1 AA';
refs.legal.value = 'Polityka prywatności, Regulamin sklepu, Cookie banner (zgoda)';
refs.deadline.value = '';
refs.budget.value = '20 000 PLN';
refs.sla.value = '3 miesiące wsparcia, reakcja 48h';
refs.testing.value = 'Manual QA, E2E tests (Cypress)';
refs.team.value = 'PM, 2 dev, 1 designer, copywriter';
refs.migration.value = 'Migracja 500 produktów z CSV';
refs.notes.value = 'Priorytet: mobile-first; SEO podstawowe; integracja z ERP.';
const md = generateMarkdown();
editor.setValue(md);
rendered.innerHTML = marked.parse(md);
rendered.style.display = 'block';
});
// auto-generate basic markdown on blur from last textarea
refs.notes.addEventListener('blur', () => {
editor.setValue(generateMarkdown());
});
</script>
Kod po stronie serwera
Brak kodu serwera
Ta aplikacja działa wyłącznie w przeglądarce i nie korzysta z kodu po stronie serwera.