> **PromptEye Brand Book & Design Language** · Co-branded reports · EN (translation of the Polish source; the Polish file wins on conflict) · state 28.10.2026
> For people: https://brand.prompteye.com/en/co-branded-reports/ · Polish source: https://brand.prompteye.com/pl/raport-z-partnerem.md · index for agents: https://brand.prompteye.com/llms.txt
> File paths are relative to https://brand.prompteye.com/ds/ (e.g. `tokens/colors.css` → https://brand.prompteye.com/ds/tokens/colors.css); `*.md` references resolve to https://brand.prompteye.com/ds/docs/en/ (translations) or https://brand.prompteye.com/ds/docs/ (Polish source). Outside Claude Design load `styles.css` and the scripts `js/pe-light.js`, `js/pe-pl.js`, `js/pe-raster.js`, `js/pe-motyw.js` (in this order) instead of `_ds_bundle.js`.

# Data: tables, charts, partner

Exact patterns: `guidelines/dane.html` (T4 minimal table, T3 complex table for desktop and phone, T3 with sorting and a model filter `#t3f`, W3 line over time, W4 bars, W5 spread, W6 structure; each light and dark), `guidelines/typografia.html` (A1 and A2 table in an article, B1–B3 shareable graphics), `guidelines/partner.html` (P1 co-branded table). Copy a block from the sheet (e.g. `#t3`, `#w3`) and replace the data. Data is linear, without motif dots.

## Figure

```html
<figure class="t2fig">
  <div class="t2fig-h"><div><small>Tabela 1 · Nad morze</small><h4>Top 10 miejsc nad morzem w rekomendacjach AI</h4><p>Widoczność: odsetek odpowiedzi, w których AI poleca miejsce. Marzec 2026.</p></div><img src="assets/logo/svg/prompteye-logo-color-on-light.svg" alt="PromptEye"></div>
  <table class="dt">…</table>
  <div class="t2fig-f"><span>Źródło: PromptEye, raport …</span><b>prompteye.com/raporty</b></div>
</figure>
```

## Tables

You build every table from the same blocks: start with the minimal table and add layers, each for a specific reason. The lower bound is T4 (`#t4`, rows and columns only), the upper bound is T3 (`#t3`, almost all layers). The same complex table in an article column: `guidelines/typografia.html` A1 and A2, `templates/artykul`, `templates/rozdzial-raportu`. With a partner: `guidelines/partner.html` P1. Shareable: B1.

### Layers

| Layer | What it adds (classes) | When |
|---|---|---|
| 1. Table | rows, columns, headers, numbers (`table.dt`, `th.rk`/`td.rk`, `td.pc`, `.n` with `.lv`) | always |
| 2. Figure | label, title, description of measures, logo, footer (`figure.t2fig`, `.t2fig-h`, `.t2fig-f`) | when the table stands alone: report, article, graphic |
| 3. Main measure | header `th.mg` with a second line and a 2 px line under it, bar `.vb` | when one measure says the most (e.g. visibility) |
| 4. Entity | logo `.co` in the name (`.pn`), type in a `td.ty` column or under the name (`<small>`) | when rows are companies or brands; places and things have no logo |
| 5. Column group | label `.gx` above the group, frame `.gk`, model marks `img.zm` | when several columns are the same measure in different models |
| 6. Heat map | `td.hm` with `.hm1`–`.hm5`, `.bx`, switch `input.hm-sw` + `label.hm-tg`, legend `.hm-lg` | when a group has several columns of the same measure |
| 7. Leader and changes | `tr.ld`, `span.mk`, "▲1" / "▼1", `.dn` | when you show a ranking or a change over time |
| 8. Partner | shared header P1–P3, footer "PromptEye × Partner" | a co-branded report (below) |
| 9. Sorting and filter | toolbar `.dt-tb` (view `.dt-seg`, model list `.dt-dd`), `.so` buttons in the headers, `table.dt.srt`, chart view `.dt.wk` (`#t3f`) | only on the report page, where a script runs (below) |

Do not add a layer without a reason. A table in the body of an article often needs nothing beyond layer 1.

### Title

- **A conclusion as the title** when the table carries one message ("Pięć pierwszych miejsc zajmują sieci handlowe").
- **A descriptive title** when the table is a listing to browse ("Widoczność sklepów z elektroniką w AI, marzec 2026").
- **No title and no figure** when the table stands in text that introduces it. The text then gives the source.
- A figure always has a footer: source, sample (n), period, address. The description under the title says what the measures are.

### Columns

- **Order:** who (#, entity, type) | the main measure | supporting measures (e.g. position on the list) | the breakdown by AI model. From the general to the detail.
- **Rank `#`:** `th.rk` / `td.rk`, 40–52 px, the number in bold (`<b>`) in a table with layer 7, regular in the minimal one. A tie (the same value after rounding to the displayed decimal place): the same rank, and the next one skips it (1, 2, 2, 4). Tied rows in alphabetical order; with a tie for 1st place both get the leader circle.
- **Entity:** `td.pc`, text left-aligned, wraps to 2–3 lines, never cut. A second line (type, region) in `<small>`.
- **Type, category:** a separate `td.ty` column (Inter 14, secondary colour) when there is room; in a narrow table a second line under the name.
- **Number:** `.n`, centred, in a fixed-width `.lv` field aligned right, so the decimal commas line up (`.lv.lz` for numbers without %). Tabular figures. One decimal place across the whole column, or whole numbers across the whole column.
- **A percent sign next to every percentage value** ("61,1 %", with a non-breaking space). The header does not repeat it. Only what is not a percentage has no unit (average position).
- **Change:** "+2,4" / "−0,6" in percentage points (p.p. in the header, because it is not a percentage), a decrease `.dn` in grey. A rank change "▲1" / "▼1" next to the number, only when it changed.
- **Text** (e.g. the most frequent source): left-aligned, Inter 14, secondary colour.
- **No data:** "—" in grey (`td.na`), never "0".
- **The main measure** (e.g. visibility): a header in the text colour with a second line saying what it is counted from (`th.mg` and `<small>wszystkie modele</small>`), a bar `.vb` (an 80 px track = 100 %, the leader in cobalt), the number left-aligned right after the bar, a 2 px line under the header. No vertical line after the column: the line under the header is the same one sorting uses to mark the active column, and the table is sorted by the main measure by default. Visibility is the share of all answers, not an average of the models, so do not call it an "average".

### Widths

- The sum of the columns = the table width: 1210 px in a report across the full body width (T3), 896 px in an article block (A1), 972 px for a table without a figure in an article block (T4), 588 px on a phone with scrolling (690 px with sorting: visibility 74, average position 68, models 80 each), 350 px on a phone without scrolling.
- Fixed columns first: # 40–52, a number 86–108 (a field for "61,1 %"), a model 85–100. The entity gets the rest.
- When space runs out, in this order: the type under the name, a shorter header, the phone layout with scrolling. Do not reduce the font size: rows 15 (phone 14), headers 12 (phone 11).
- Put the widths in `style` on the header cells. Place the group label `.gx` above the table with `margin-left` = the sum of the columns before the group and `width` = the sum of the group's columns. This works both in plain HTML and in Claude Design (`.dc.html`), whose engine drops `<colgroup>`.

### Headers

- Inter 500 12 in the metadata colour, aligned like the values below. A two-word header has one word per line (`span.sl`). The main measure: the text colour and a second line.
- **Column group:** a `.gx` label with a line; the line is the top of the frame, and the frame sides (`.gk` on the last column before the group and on the last column of the group) run down to the end of the table, 20 px above the model marks.
- **Model marks in colour** above the name: `<img class="zm" src="assets/llm/<model>.svg" alt="">`. On black, ChatGPT and Grok in the light version (`gpt-jasny.svg`, `grok-jasny.svg`). The colour of a mark is identification, not a data colour.

### Colour, lines, emphasis

- Data in cobalt: the bar `--bar`, the leader's bar `--pe-kobalt-500`, the heat map in 5 steps. Text in text colours, never in cobalt.
- **Orange only for the leader:** the circle `.mk` next to the name, on a phone next to the rank number.
- **No red and green:** the sign carries the meaning, an increase in the heading colour, a decrease in grey, a rank gain in cobalt.
- **Emphasis:** the main measure (weight 500, a bar, a line under the header), the best in a row (500), the leader (circle). Nothing is heavier than 500. Without the heat map only the best in a row has the heading colour.
- Horizontal lines: `--ln2` between rows, `--ln` under the header. Vertical lines only `.gk` on the sides of a column group. Under the header of the main measure (or of the column you sort by) a 2 px line in the heading colour.
- **The entity logo:** a 28 px square `.co` (phone `.co.cm`, 24 px) with a line, the logo inside at 20 px (`<img>`). Without a logo, the first letter of the name (`.co.bz`).

### Heat map

- 5 cobalt steps (`.hm1`–`.hm5`) with a 2 px gap; you choose the thresholds for the data and give them in the legend with "%". Legend swatches have an outline.
- On by default. The reader turns it off with a switch in the legend: `<input type="checkbox" class="hm-sw" id="…" checked>` before the table (and before `.gx`) and `<label class="hm-tg" for="…">Mapa ciepła</label>` in `.hm-lg`, no script. Off: cells without a fill, with row lines.
- In PDF and shareable graphics it is always on, without a switch.

### Behaviour

- The row under the cursor: an `--hv` overlay on the whole row, the heat map cells included. The first column is indented 12 px (phone 8 px), so the number does not sit on the edge of the highlight.
- **A table without sorting** (PDF, graphic, article, a page without a script) is sorted descending by the main measure, the rank `#` follows from that sorting, and the description under the title says what the ranking is by.

### Sorting and filter (layer 9)

Pattern `#t3f` in `guidelines/dane.html`: the default state, a model switched off with the list open, the chart view, dark, phone. Only on the report page: the page script orders the rows and recalculates, CSS gives the look and the states.

```html
<div class="dt-tb">
  <div class="dt-seg" role="group" aria-label="Widok"><button type="button" aria-pressed="true">Tabela</button><button type="button" aria-pressed="false">Wykres</button></div>
  <div class="dt-dd">
    <button type="button" class="dt-dd-t" aria-expanded="false" aria-controls="t1-modele">Modele AI <span>wszystkie</span><i></i></button>
    <div class="dt-dd-p" id="t1-modele" role="group" aria-label="Modele AI" hidden>
      <label class="dt-dd-o"><input type="checkbox" checked><b></b><img src="assets/llm/gpt.svg" alt=""><span>ChatGPT</span></label>
      …
      <div class="dt-dd-f"><button type="button">Zaznacz wszystkie</button></div>
    </div>
  </div>
</div>
<!-- a header you can sort by; active: class="s-dn" (descending) or "s-up" and aria-sort -->
<th class="n mg s-dn" aria-sort="descending" style="width:190px"><button type="button" class="so">Widoczność<small>wszystkie <span class="so-t">modele<span class="so-i" aria-hidden="true"></span></span></small></button></th>
<th class="n" style="width:108px"><button type="button" class="so"><span class="sl">Średnia</span><span class="sl"><span class="so-t">pozycja<span class="so-i" aria-hidden="true"></span></span></span></button></th>
```

- **Toolbar above the table** (`.dt-tb`, between the figure header and the table): the view switch Tabela | Wykres (`.dt-seg`) and the "Modele AI" list with checkboxes (`.dt-dd`). Both in the tone of the b2 button, the active segment on the card colour. The list label says how many models are on ("wszystkie", "3 z 4"). The list closes on a click outside and on Esc; "Zaznacz wszystkie" returns to the full table. The last model cannot be switched off.
- **Sort marker:** the header is a `.so` button, and the `.so-i` marker hangs after the last word of the header (in `.so-t`), 4 px from the text, 3 px on a phone. It takes no space, so the name stays centred under the model mark, and the markers of all columns stand in one row. Drawing: two thin chevrons, like the arrow of the model list, in the metadata colour.
- **Active column:** `th.s-dn` (descending) or `th.s-up` (ascending) and `aria-sort`: one chevron in the heading colour and a 2 px line under the header. There is one line: when you sort by another column, it disappears from under the main measure.
- **What you can sort by:** the name and every column with a number. Not the rank `#` (it follows from the main measure) or the type. By default descending by the main measure. First click: numbers descending, the name and the average position ascending (best at the top); the second click reverses the direction.
- **A model switched off:** the column is dimmed, without the heat map (`.wyl` on `th` and `td`), and you cannot sort by it (`disabled`). Visibility is recalculated from the models that are on (an average weighted by each model's number of answers), and with it the rank `#`, the bars, the leader and the best in a row. The second header line says from how many models ("3 z 4 modeli").
- **Measures counted from all models** (average position, opens the list) are dimmed when a model is off (`.wyg`, `disabled`), because they cannot be recalculated without per-model data. The `.dt-nt` note under the toolbar says why. When the data has these measures per model, recalculate them like visibility and dim nothing. If the sort was on a measure that gets dimmed, it returns to the main measure.
- **Chart view** (`table.dt.srt.wk`): #, entity, type and the main measure as a long bar (a 560 px track = 100 %, 108 px on a phone), without the model breakdown. Sort by the name or by the measure; any other sort returns to the measure when you switch to the chart. The model filter works the same way.
- **Phone:** the same toolbar (smaller buttons), the `.dt.srt` table has wider columns (690 px), so the scroll hint is `.dmx-cue.srt`.

### Phone

- The table fits in 350 px (e.g. T4, five columns): no scrolling, names wrap.
- It does not fit (T3, A2): the entity and the main measure are frozen (`.stk`, `.stk2`), the rest scrolls sideways (`.dmx` > `.dmx-s`). The hint "Przewiń w bok →" with a bar (`.dmx-cue`) stands above the scrolling part, right after the frozen columns. The bar and the fade on the right follow the scroll through `animation-timeline`, with no script; an older browser shows the bar at the start. The widths (164 + 64 frozen, 588 in total) and the bar are set for 390 px; in another layout set them again.
- The entity type under the name, the leader dot next to the rank number.

### Partner

- A co-branded table: a shared header in place of the logo (P1, `guidelines/partner.html`), the footer "Źródło: PromptEye × Partner".
- The partner colour only as the second data series (rules below), never in headers, lines, the frame or the heat map. The heat map stays cobalt.

### Formats

- Light and dark: the same markup in a `.t2f` or `.t2f.dk` frame.
- A shareable graphic (B1, 1080 × 1350): `table.dt.xl`, rows 24, headers 18, a 160 px bar. No breakdown by model: four model columns in a graphic in a feed would be about 8 px on a phone screen.
- Model icons in data cells (e.g. presence in models): one colour, in the text colour. A missing model = a dimmed icon (`.mic.off`), the legend below the header. Source: the sprite `assets/llm/sprite.svg` (symbols `llm-gpt`, `llm-gemini`, `llm-perplexity`, `llm-ai-overview`, `llm-claude`, `llm-grok`, `llm-deepseek`). Paste it into the page once, then `<svg class="mic" width="18" height="18" viewBox="0 0 24 24"><use href="#llm-gpt" width="24" height="24"/></svg>`. Without the sprite the icons are empty.

## Charts

**Which chart to choose:**

| The reader’s question | Chart | Pattern |
|---|---|---|
| How does the score change over time? | line over time | W3 |
| Who gained and who lost against the previous period? | bars with the previous month | W4 |
| How much do AI models differ in their assessment? | spread (min–max band and average) | W5 |
| How are positions in the answer list distributed? | 100% structure | W6 |
| Many items across many models at once | a table with a model group and a heat map | T3 |

- One series highlighted in cobalt, comparison series in grey, the rest as a light grey background. No multicolour legends.
- Labels at the ends of lines (value and change) instead of a legend.
- Grid: solid 1 px lines (`--pe-dzien-linia-2`, on black #1E2027), the zero line stronger. No dotted lines.
- The value axis starts at zero, the unit next to the tick. Axes Inter 13, tabular figures, metadata colour.
- **The title is a conclusion** ("Sopot grows the fastest"), the subtitle gives the measure and period, the footer the sample, source and address.
- Spread = a band from minimum to maximum, without ticks for individual models.
- Orange only for the leader (circle).
- On white: the leader is a cobalt bar (`--pe-kobalt-500`), the others `--pe-kobalt-100` (#C7D1FF); on black in navy.

## Data colours

The only exception to the `--pe-*` tokens: variables in `css/dane.css`, set on the `.t2f` frame, separately on white and on black (`.t2f.dk`). Do not type them in by hand, use the classes; the frame picks the version.

| Variable, class | Used for |
|---|---|
| `--q1` … `--q4` (`.q1`–`.q4`) | 100% structure (W6), segments from the most important |
| `--hm1` … `--hm5` (`.hm1`–`.hm5`) | heat map in tables, 5 steps from the lowest value |
| `--up` (`.up`) | increase and rank gain (▲) |
| `--rb`, `--rb1` (`.rb`, `.rb1`) | spread band (W5): others and highlighted |
| `--ctx` (`.ctx`) | background series in a line chart (W3) |
| `--sea` (`.sea`) | season band (W3) |
| `--base` | axis baseline |
| `--hv` | row highlight under the cursor (T3) |

## Shareable graphics

Formats: 1080 × 1350 (table), 1600 × 900 (chart, presentation), 1080 × 1080 (social). The logo, title, source and address are part of the graphic. The logo in the top left corner. Footer: source on the left, address on the right, a 1 px line above it.

## Partner (co-branded reports)

- Written as: **PromptEye × Partner**. Our logo first, "×" in the metadata colour. The partner's logo in one colour, optically equal to ours.
- P1 shared header: cover, shareable graphics, the first table. P2 report bar: the first graphic of a chapter. P3 partner in the footer: the other graphics.
- Footer: "Source: PromptEye × Partner", the address on our domain. One partner per graphic; with several, only in the footer.

**The partner's colour in data (10 rules):**
1. Always the second series. The first in cobalt, the rest grey. Line weight and labels keep the hierarchy.
2. A single series, a heat map and a one-colour scale stay in cobalt.
3. Partner data (Google, traffic, sales) = the second series; the colour indicates the source.
4. Only in data (bars, lines, points, legend swatches). Never in text, titles, headings, frames, backgrounds or buttons.
5. Never as a meaning (increase, decrease, warning).
6. The original colour if it has at least 3 : 1 against the background; if not, change only the lightness to 3 : 1.
7. Distinguishability test against cobalt: ΔE OKLab ≥ 0.10 (protanopia, deuteranopia), ≥ 0.05 (tritanopia).
8. Collisions: close to cobalt → the partner's second colour or graphite; close to orange → the leader as a graphite circle; red only after testing.
9. The partner's colour only with a single partner.
10. Orange stays ours: it marks only the leader.
