Skill: Telly interaktivní report
Návod pro AI (Claude, Cursor, ChatGPT…), jak vyrobit interaktivní HTML report nebo prezentaci v Telly brandu. Jeden samostatný soubor: boční menu, grafy, přepínače zobrazení, tisk do PDF. Zkopíruj celý dokument do své AI spolu s daty a popiš, co má report ukázat.
Jak skill použít (pro tebe, ne pro AI)
- Připrav data (export z dotazníku, tabulka výsledků, čísla kampaně)
- Vlož do AI tento celý dokument + data + zadání, např.: „Vyrob interaktivní Telly report podle přiloženého skillu. Data v příloze. Segmenty porovnej po krajích.”
- Výstup je jeden HTML soubor. Otevři v prohlížeči, pošli přílohou, nebo dej Honzovi na marketing hub.
Instrukce pro AI
Report negeneruj ručně jako jeden dlouhý HTML string v hlavě. Postav Python generátor (data → HTML), aby šel report přegenerovat při změně dat. Čísla ber vždy z agregovaných dat (JSON/CSV), nikdy je nepiš do šablony ručně — ruční přepis je nejčastější zdroj chyb v číslech.
Workflow:
- Data: agregace do JSON (počty, procenta, po segmentech). Zvlášť drž metadata (n, období sběru).
- Generátor: Python skript skládá HTML z komponent (níže). Ulož ho vedle dat, je součást deliverable.
- Ověření: otevři výsledek v prohlížeči a proklikej interaktivitu (menu, přepínače, koláče, tisk). Neodevzdávej bez ověření.
- Předání: soubor funguje jako příloha (vše inline). Google Drive HTML nerenderuje — upozorni na to.
Brand (zdroj: brand manuál Telly, viz Marketingová knihovna)
| Token | Hodnota | Použití |
|---|---|---|
| Telly Blue | #1e1ec8 | primární — sidebar, nadpisy, hlavní data |
| Azure Blue | #0096fa | sekundární datová řada (např. SAT vs OTT) |
| Telly Black | #111111 | text, řada „Celkem” |
| Pink Red | #ff005a | zvýraznění, čísla doporučení, rizika |
| Yellow | #ffd60b | CTA tlačítka, aktivní stav, citace |
| Turquoise | #00c8a0 | sport, pozitivní zjištění |
- Font:
"Neue Haas Grotesk Display Pro","Helvetica Neue",Helvetica,Arial,sans-serif(brand fallback řetězec — Neue Haas je jen v Adobe Fonts, web ho mít nebude) - Tvary: zaoblený levý horní a pravý dolní roh (
border-radius:18px 5px 18px 5px) — poznávací prvek Telly, použij na karty, tlačítka, chipy - Logo: inline SVG z oficiálního SVG loga (academy.telly.cz/academy-telly-logo.svg, nebo si ho vyžádej). Pravidlo z manuálu: tmavý podklad = bílé logo.
- Žádné dlouhé pomlčky v textech (em dash je LLM tell). Citace zákazníků doslovně.
Struktura reportu
┌──────────┬──────────────────────────────┐
│ sidebar │ hero (Telly Blue, titulek, │
│ (fixed, │ meta-chipy s n) │
│ 264px, ├──────────────────────────────┤
│ Telly │ Klíčová zjištění (karty) │
│ Blue) │ Sekce s grafy per otázka │
│ │ Souvislosti (cross-analýzy) │
│ logo │ Citace / otevřené odpovědi │
│ nav │ Doporučení (číslované) │
│ přepínač │ Metodika │
│ PDF btn │ footer (logo + datum) │
└──────────┴──────────────────────────────┘
Pořadí vyprávění: zjištění → důkazy → souvislosti → doporučení. Manažer čte jen karty zjištění; analytik si rozklikne detaily. Doporučení vždy akční (co udělat), ne popisná.
Komponenty
Hotové ověřené CSS/JS bloky jsou v v sekci „Komponenty: hotový kód” níže. Obsahuje:
- Sidebar + scrollspy — fixní menu, aktivní sekce přes IntersectionObserver/scroll handler, mobil = hamburger (pozor: logo posunout doprava, ať ho hamburger nepřekrývá)
- Přepínač zobrazení dat — globální
body[data-view]+ CSS skrývání řad; standardně režimy Porovnání segmentů / Jen celkem / Vše - Pruhové grafy — řádek per segment, animace šířky přes IntersectionObserver (
data-w→ width),beforeprintvše naplno - Koláče (donuty) — inline SVG, kruhy se stroke-dasharray; jen pro jednovýběrové otázky (podíly se sčítají do 100 %). U vícevýběrových koláč lže — nech jen pruhy. Přepínač pruhy/koláč per karta.
- Rozklikávací detaily —
<details class="expand">pro dlouhé tabulky (všichni poskytovatelé…) a otevřené odpovědi - Citace —
<blockquote>se žlutým okrajem, doslovné, s označením segmentu - Tisk do PDF — tlačítko
window.print(),@media printskryje sidebar,break-inside:avoid-page,print-color-adjust:exact
Datová poctivost
- U každého grafu uveď bázi (n=…), zvlášť když se liší od celku (filtrovaná podotázka)
- Samovýběrový vzorek = napiš metodickou poznámku, ať čísla nikdo nečte jako reprezentativní
- Procenta + absolutní čísla vedle sebe:
58 % (334) - Vícevýběrové otázky: podíl z respondentů, ne z odpovědí — a řekni to v popisku
Časté chyby (z praxe)
scroll-behavior:smoothnefunguje v headless preview — ověřuj scroll sbehavior:'instant', smooth nech pro uživatele- Screenshot v Claude Preview po scrollu bývá prázdný (render bug) — posouvej obsah přes
transform:translateY()na.main, screenshot pak funguje; transform před měřením pozic resetuj - Koláč u vícevýběrové otázky (součet > 100 %) — nikdy
- Čísla psaná ručně do šablony místo z dat — vždy generuj
Komponenty Telly interaktivního reportu
Ověřené bloky z reportu „Vylaďte 2026” (plný funkční příklad: interaktivní report výzkumu na marketing.telly.cz/vyzkumy). Bloky jsou k převzetí, přizpůsob názvy segmentů a sekcí konkrétnímu reportu.
Obsah
- Kostra stránky + CSS proměnné
- Sidebar + scrollspy + mobil
- Přepínač zobrazení dat
- Pruhové grafy s animací
- Koláče (SVG donuty)
- Karta s přepínačem pruhy/koláč
- Rozklikávací detail + tabulka
- Karty zjištění, citace, doporučení
- Tisk do PDF
1. Kostra
:root { --blue:#1e1ec8; --azure:#0096fa; --pink:#ff005a; --turq:#00c8a0; --yellow:#ffd60b; --black:#111111; }
* { margin:0; padding:0; box-sizing:border-box; }
html { scroll-behavior:smooth; }
body { font-family:"Neue Haas Grotesk Display Pro","Helvetica Neue",Helvetica,Arial,sans-serif;
color:#111; background:#f4f4fa; line-height:1.5; }
.main { margin-left:264px; }
.wrap { max-width:1000px; margin:0 auto; padding:0 32px 64px; }
.card { background:#fff; border-radius:18px 5px 18px 5px; padding:28px 30px;
box-shadow:0 2px 10px rgba(30,30,200,.06); margin-bottom:20px; }
Hero hlavička: Telly Blue pozadí, H1 bílý 2.1rem/800, pod ním meta-chipy
(border-radius:14px 4px 14px 4px, rgba(255,255,255,.12); zvýrazněný chip --yellow + černý text).
2. Sidebar
.sidebar { position:fixed; top:0; left:0; bottom:0; width:264px; background:var(--blue);
color:#fff; display:flex; flex-direction:column; padding:28px 0 20px; z-index:50; overflow-y:auto; }
.sidebar .logo { width:96px; margin:0 28px 8px; } /* inline SVG bílé logo */
.sidebar nav a { color:#fff; text-decoration:none; font-size:.92rem; padding:9px 28px;
border-left:4px solid transparent; opacity:.78; transition:all .15s; display:block; }
.sidebar nav a.active { opacity:1; background:rgba(255,255,255,.12);
border-left-color:var(--yellow); font-weight:700; }
.burger { display:none; position:fixed; top:14px; left:14px; z-index:60; width:44px; height:44px;
border:none; background:var(--blue); color:#fff; border-radius:12px 4px 12px 4px;
font-size:1.3rem; cursor:pointer; }
@media (max-width:900px) {
.sidebar { transform:translateX(-100%); transition:transform .25s; width:280px; }
.sidebar.open { transform:translateX(0); box-shadow:4px 0 24px rgba(0,0,0,.25); }
.burger { display:block; }
.sidebar .logo { margin-left:84px; } /* ať hamburger nepřekrývá logo */
.main { margin-left:0; }
}
// scrollspy — bez knihoven
var links = [].slice.call(document.querySelectorAll('#nav a'));
var secs = links.map(function (l) { return document.getElementById(l.dataset.sec); });
function spy() {
var pos = window.scrollY + 120, act = secs[0];
secs.forEach(function (s) { if (s && s.offsetTop <= pos) act = s; });
links.forEach(function (l) { l.classList.toggle('active', l.dataset.sec === act.id); });
}
window.addEventListener('scroll', spy, { passive: true }); spy();
// mobil menu
burger.addEventListener('click', function () { sidebar.classList.toggle('open'); });
sidebar.addEventListener('click', function (e) { if (e.target.closest('a')) sidebar.classList.remove('open'); });
Sekce potřebují scroll-margin-top:24px, odkazy <a href="#id" data-sec="id">.
3. Přepínač zobrazení dat
Globální režim na <body data-view="...">, řady grafů mají třídy row-cel/row-ott/row-sat
(analogicky koláče pie-cel/...). CSS jen skrývá:
body[data-view="porovnani"] .row-cel { display:none; }
body[data-view="celkem"] .row-ott, body[data-view="celkem"] .row-sat { display:none; }
/* data-view="vse" nechává všechno */
sw.addEventListener('click', function (e) {
var btn = e.target.closest('button'); if (!btn) return;
document.body.dataset.view = btn.dataset.view;
sw.querySelectorAll('button').forEach(function (b) { b.classList.toggle('active', b === btn); });
animateVisible(); // doanimovat pruhy, které se právě odkryly
});
Tlačítka v sidebaru: border-radius:12px 4px 12px 4px, aktivní = bílé pozadí + modrý text.
4. Pruhy
<div class="bp"><div class="bp-label">Netflix</div><div class="bp-bars">
<div class="bp-row row-ott"><span class="bp-seg">OTT</span>
<div class="bp-track"><div class="bp-fill ott" data-w="41.2"></div></div>
<span class="bp-val">41 % <small>(237)</small></span></div>
...
</div></div>
.bp-track { flex:1; background:#ececf6; border-radius:6px 2px 6px 2px; height:16px; overflow:hidden; }
.bp-fill { height:100%; width:0; border-radius:6px 2px 6px 2px;
transition:width .8s cubic-bezier(.25,.8,.35,1); }
.bp-fill.cel { background:var(--black); } .bp-fill.ott { background:var(--blue); }
.bp-fill.sat { background:var(--azure); }
// animace při vstupu do viewportu
var fills = [].slice.call(document.querySelectorAll('.bp-fill'));
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (en) { if (en.isIntersecting) {
en.target.style.width = en.target.dataset.w + '%'; io.unobserve(en.target); } });
}, { threshold: 0.1 });
fills.forEach(function (f) { io.observe(f); });
// helper pro přepínače (odkryté řady mimo IO):
function animateVisible() { fills.forEach(function (f) {
var r = f.getBoundingClientRect();
if (r.top < window.innerHeight && r.bottom > 0 && f.offsetParent !== null)
f.style.width = f.dataset.w + '%'; }); }
5. Koláče
Jen jednovýběrové otázky (součet = 100 %). Generuj v Pythonu:
PALETTE = ['#1e1ec8', '#0096fa', '#00c8a0', '#ffd60b', '#ff005a', '#111111', '#9a9ab0']
CIRC = 2 * math.pi * 40
def donut(seg_label, items, n): # items: (label, count, color)
parts, legend, offset = [], [], 0.0
for label, cnt, color in items:
frac = cnt / n if n else 0
dash = frac * CIRC
parts.append(f'<circle cx="60" cy="60" r="40" fill="none" stroke="{color}" stroke-width="22" '
f'stroke-dasharray="{dash:.2f} {CIRC - dash:.2f}" stroke-dashoffset="{-offset:.2f}" />')
legend.append(f'<li><i style="background:{color}"></i>{label} <b>{100*frac:.0f} %</b> <small>({cnt})</small></li>')
offset += dash
svg = (f'<svg viewBox="0 0 120 120" class="donut"><g transform="rotate(-90 60 60)">{"".join(parts)}</g>'
f'<text x="60" y="56" text-anchor="middle" class="d-seg">{seg_label}</text>'
f'<text x="60" y="72" text-anchor="middle" class="d-n">n={n}</text></svg>')
return f'<div class="pie-row"><div class="pie-chart">{svg}</div><ul class="pie-legend">{"".join(legend)}</ul></div>'
Kategorií navíc nad paletu → slož zbytek do „Ostatní” (poslední barva palety).
Tři donuty per otázka (celkem/segment A/segment B) ve wrapperech pie-cel/pie-ott/pie-sat,
viditelnost řídí stejný body[data-view] mechanismus jako u pruhů.
6. Karta s přepínačem pruhy/koláč
def chart_card(title, bars_html, pies_html, extra=''):
return f'''<div class="card chart-card">
<div class="chart-head"><h3>{title}</h3>
<div class="chart-toggle"><button class="t-bar active">▮▮ pruhy</button><button class="t-pie">◔ koláč</button></div></div>
<div class="chart-bars">{bars_html}</div>
<div class="chart-pies">{pies_html}</div>
{extra}</div>'''
.chart-card.mode-pie .chart-bars { display:none; }
.chart-card:not(.mode-pie) .chart-pies { display:none; }
JS: klik na toggle → card.classList.toggle('mode-pie', btn.classList.contains('t-pie')) + animateVisible().
7. Rozklikávací detail
.expand { margin-top:16px; border-top:1px solid #ececf6; padding-top:12px; }
.expand summary { cursor:pointer; font-weight:600; color:var(--blue); list-style:none; }
.expand summary::before { content:"▸ "; } .expand[open] summary::before { content:"▾ "; }
.dtable th { text-align:left; background:var(--blue); color:#fff; padding:7px 12px; }
.dtable td { padding:5px 12px; border-bottom:1px solid #ececf6; }
.dtable tbody tr:nth-child(even) { background:#f7f7fc; }
Použij na: kompletní seznamy (všichni poskytovatelé), otevřené odpovědi, metodické detaily.
V summary vždy řekni, co a kolik toho uvnitř je („Zobrazit všechny poskytovatele (68)“).
8. Obsahové komponenty
/* karty zjištění — barevný horní proužek podle typu (modrá neutrální, pink riziko, turq příležitost) */
.finding { background:#fff; border-radius:18px 5px 18px 5px; padding:22px 24px;
border-top:4px solid var(--blue); }
.finding .big { font-size:1.9rem; font-weight:800; display:block; } /* hlavní číslo */
/* citace — doslovné, se segmentem */
blockquote { border-left:4px solid var(--yellow); background:#fffdf0; padding:12px 16px;
border-radius:0 12px 0 12px; font-style:italic; }
/* doporučení — číslovaná pink kostka přes CSS counter */
.reco { counter-reset:reco; }
.reco .card::before { counter-increment:reco; content:counter(reco); background:var(--pink);
color:#fff; font-weight:800; min-width:44px; height:44px; display:flex; align-items:center;
justify-content:center; border-radius:14px 4px 14px 4px; }
9. Tisk
@media print {
.sidebar, .burger { display:none; }
.main { margin-left:0; }
section { break-inside:avoid-page; }
.bp-fill { transition:none; }
* { -webkit-print-color-adjust:exact; print-color-adjust:exact; }
}
window.addEventListener('beforeprint', function () {
fills.forEach(function (f) { f.style.width = f.dataset.w + '%'; });
});
Tlačítko v sidebaru: žluté (--yellow, černý text), onclick="window.print()",
text „Vytisknout / uložit PDF”.