Przewodnik po stylowaniu kart w CSS

CSS karty nadaje karcie postaci lub persony własny wygląd na czacie. Kod CSS wpisujesz w pole Creator Notes (notatki twórcy) na karcie, a Marinara stosuje go do wiadomości tej postaci. Może zmieniać wyłącznie wygląd czatu, nigdy reszty aplikacji. Ten przewodnik jest przeznaczony dla twórców kart.

Zanim zaczniesz

Pojęcia używane w tym przewodniku:

Szybki start

Oto blok na początek, do wklejenia w kroku 2:

Najpierw dodajesz CSS do karty, a potem włączasz go na czacie.

  1. Otwórz postać w edytorze postaci (Character Editor) i znajdź pole Creator Notes. Persony mają to samo pole w edytorze persony (Persona Editor).
  2. Wklej blok startowy w pole Creator Notes i zapisz kartę.
  3. Otwórz czat z tą postacią.
  4. Otwórz Chat Settings, a potem Characters (w trybie Game Party).
  5. W sekcji Card Theming wybierz Exclusive albo Chat. Na starcie ustawienie to Disabled (wyłączone).

Wiadomości postaci od razu zmieniają wygląd.

Jeśli to nie zadziałało: przyciski Disabled, Exclusive i Chat pojawiają się tylko wtedy, gdy aktywna postać w czacie ma kod CSS w polu Creator Notes. Sam CSS persony ich nie wywoła, więc motyw persony też wymaga w czacie jednej postaci z blokiem `


Tryb Game Mode ma wsparcie podstawowe. W trybie **Chat** CSS karty sięga całej powierzchni gry, więc `[data-card-css]` nadaje styl obszarowi gry. Gra ma własny układ i nie ma dymków wiadomości, więc celuj szeroko, na przykład w tło obszaru. Stylowanie narracji w grze osobno dla każdej postaci (tryb **Exclusive**) nie jest jeszcze dostępne.

## Co da się ostylować

Tryby Roleplay i Conversation mają ten sam szkielet. Trzymaj się klas `mari-*` i atrybutów `data-*` wymienionych niżej. Inne klasy zmieniają się między wersjami.

| Selektor | Co obejmuje |
| --- | --- |
| `[data-card-css]` | Cały wiersz wiadomości (element wyznaczający zakres). Dobry do akcentów przy krawędzi, a w trybie **Chat** do obszaru czatu. |
| `[data-card-css] .mari-message-bubble` | Widoczny dymek: tło, obramowanie, narożniki, cień. W układzie **Bubbles** i w trybie Roleplay. |
| `[data-card-css] .mari-message-content` | W układzie **Bubbles** sam element dymka. W układzie **Linear** wyłącznie tekst wiadomości. |
| `[data-card-css] .mari-message-name` | Wyświetlana nazwa postaci. |
| `[data-card-css] .mari-message-meta` | Wiersz nagłówka z nazwą i znacznikiem czasu. |
| `[data-card-css] .mari-message-timestamp` | Znacznik czasu. |
| `[data-card-css] .mari-message-avatar` | Kolumna z awatarem. |
| `[data-card-css] .mari-message-narrator` | Wiadomości narratora (tryb Roleplay). |
| `[data-card-css] .mari-message-user` | Wiadomości użytkownika. Do wiadomości postaci użyj `.mari-message-assistant`. |
| `[data-card-css] p`, `[data-card-css] span` | Akapity i elementy span w tekście. |
| `[data-grouped]` | Kolejne wiadomości tej samej postaci. Tylko w trybie Conversation. Do pierwszej wiadomości w grupie użyj `[data-card-css]:not([data-grouped])`. |

Żeby zmienić układ, otwórz **Settings → Appearance → Conversation** (ustawienia, wygląd, Conversation), potem **Conversation Display**, a potem **Chat Layout** (układ czatu). W układzie **Linear** styluj `.mari-message-content` (tekst) i `[data-card-css]` (wiersz), bo nie ma tam dymka.

Ostylowany dymek:

[data-card-css] .mari-message-bubble { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); border: 1px solid rgba(100, 149, 237, 0.35); border-radius: 1rem; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35); } [data-card-css] .mari-message-name { color: #6495ed; text-shadow: 0 0 8px rgba(100, 149, 237, 0.5); } [data-card-css] .mari-message-content { font-family: Georgia, serif; }


### Wskaźnik pisania

W układzie **Linear** trybu Conversation wiersz "(name) is typing..." jest widoczny, gdy postać pisze.

| Selektor | Co obejmuje |
| --- | --- |
| `[data-card-css] .mari-typing-text` | Napis. |
| `[data-card-css] .mari-typing-dots span` | Animowane kropki. |
| `[data-card-css] .mari-typing-indicator` | Wiersz. Niesie nazwę w atrybucie `data-typing-name`. |

[data-card-css] .mari-typing-text { color: #ff66cc; font-style: italic; } [data-card-css] .mari-typing-dots span { background: #ff66cc; }


### Awatar

Awatar jest domyślnie kółkiem. Przykład obejmuje klikalny przycisk awatara. Do awatara, który nie jest klikalny, użyj `.mari-message-avatar > div`. W trybie Roleplay przycisk siedzi dodatkowo w elemencie `div` z poświatą. Wypłaszcz ten element, jeśli chcesz zostawić tylko własną obwódkę.

[data-card-css] .mari-message-avatar button { border-radius: 6px; / 0 for sharp corners, 50% for a circle / box-shadow: 0 0 0 2px #ff66cc; } @chat-mode roleplay { [data-card-css] .mari-message-avatar > div { box-shadow: none; } }


### Panel profilu About Me (tylko tryb Conversation)

W trybie Conversation kliknięcie awatara otwiera panel podręczny profilu z sekcją "about me". Karty postaci i persony mogą ostylować własny panel. Nie istnieje on w trybach Roleplay ani Game, więc zamknij te reguły w `@chat-mode conversation`, jeśli karta obsługuje też inne tryby.

Karta panelu jest elementem wyznaczającym zakres. Obejmij ją zapisem `[data-card-css].mari-about-me-popout` (bez spacji, ten sam element), a jej elementy podrzędne selektorami potomka. W trybie **Chat** możesz pisać wprost `.mari-about-me-name`.

| Selektor | Co obejmuje |
| --- | --- |
| `[data-card-css].mari-about-me-popout` | Karta panelu: tło, obramowanie, kształt. |
| `[data-card-css] .mari-about-me-banner` | Górny pasek banera (domyślnie w kolorze nazwy). |
| `[data-card-css] .mari-about-me-avatar` | Element obejmujący powiększony awatar. Do kółka użyj `... > div`. |
| `[data-card-css] .mari-about-me-status` | Kropka statusu obecności (tylko postacie). |
| `[data-card-css] .mari-about-me-name` | Nagłówek z wyświetlaną nazwą. |
| `[data-card-css] .mari-about-me-handle` | Dodatkowa linia z @nazwą, widoczna, gdy nazwa wyświetlana w trybie Convo jest inna. |
| `[data-card-css] .mari-about-me-presence` | Linia statusu lub aktywności (tylko postacie). |
| `[data-card-css] .mari-about-me-box` | Ramka z treścią About Me. |
| `[data-card-css] .mari-about-me-label` | Podpis "ABOUT ME". |
| `[data-card-css] .mari-about-me-badge` | Plakietka Default lub Chat-specific. |
| `[data-card-css] .mari-about-me-text` | Treść sekcji about me. |

@chat-mode conversation { [data-card-css].mari-about-me-popout { background: radial-gradient(120% 120% at 50% 0%, #241a3a 0%, #14101f 70%); border: 1px solid rgba(180, 120, 255, 0.45); border-radius: 1.25rem; } [data-card-css] .mari-about-me-banner { background: linear-gradient(90deg, #b478ff, #ff77c6); } [data-card-css] .mari-about-me-name { color: #e9d8ff; } }


<a id="what-you-cannot-style"></a>

## Czego nie da się ostylować

Filtr oczyszczający usuwa te rzeczy ze względów bezpieczeństwa.

| Zablokowane | Dlaczego |
| --- | --- |
| `url(https://...)` | Żadnych zapytań sieciowych, żeby nie dało się śledzić użytkownika ani wyprowadzać danych. Dozwolone jest tylko `url(data:...)`, do obrazów i krojów pisma osadzonych w kodzie. |
| `@font-face` z zewnętrznymi adresami URL | Zostają wyłącznie źródła krojów pisma w formie `data:`. Nazwa rodziny zostaje zmieniona, żeby nie mogła nadpisać krojów aplikacji. |
| `@import` | Żadnego wczytywania zewnętrznych arkuszy stylów. |
| selektory `:has()` | Nie mogą badać elementów spoza czatu. |
| Zagnieżdżone reguły i selektory zaczynające się od `~` lub `+` | Usuwane, żeby CSS karty nie mógł sięgnąć poza swój zakres. Pisz zwykłe selektory. |
| HTML w `content:` | Tekst ozdobny jest dozwolony, ale znaki `<` i `>` są usuwane, a długość tekstu ograniczona do 200 znaków. Zapisy `attr()` i `counter()` są dozwolone. |
| `position: fixed` | Zamieniane na `position: absolute`, więc nie da się przykryć całego ekranu. |
| `!important` | Usuwane, więc CSS karty nie może na siłę nadpisać stylów aplikacji. |
| Tokeny motywu aplikacji | Tokeny takie jak `--primary` czy `--background` są usuwane, więc CSS karty nie przemaluje interfejsu aplikacji. |

CSS karty ma pierwszeństwo przed własnymi stylami wiadomości w aplikacji przy kolorach, tłach, obramowaniach i krojach pisma wewnątrz czatu. Nie przebije tego, co usuwa filtr oczyszczający, niczego poza czatem ani stylów, które aplikacja nakłada w linii albo z `!important`. Przykładem są globalny kolor i rozmiar czcionki czatu ustawione w **Settings**.

Własny krój pisma osadź jako identyfikator `data:` w kodowaniu base64 albo użyj zestawu krojów systemowych.

@font-face { font-family: "MyFont"; src: url(data:font/woff2;base64,d09GMgAB...) format("woff2"); }


## Wskazówki

1. Dymek styluj przez `.mari-message-bubble`, a nie `[data-card-css]`. Wiersz ma pełną szerokość, więc tło na nim jest zwykle prawie niewidoczne.
2. Używaj kolorów `rgba()`, żeby wtapiały się w motyw jasny i ciemny.
3. Zachowaj umiar w animacjach. Na słabszych urządzeniach lepiej sprawdza się `transition` niż ciężka `animation`. Animuj `opacity`, a nie `box-shadow`, który wymusza ponowne rysowanie w każdej klatce.
4. Do telefonów użyj `@media (max-width: 768px)`.
5. Nie opieraj się na klasach pomocniczych. Stabilne są tylko udokumentowane punkty zaczepienia `mari-*`.

## Przykład popisowy: Eldritch Grimoire

Ten przykład sięga po główne punkty zaczepienia w każdym trybie: świecące nazwy, klimatyczny tekst szeryfowy, awatar z obwódką, animowany dymek w trybie Roleplay z runą w rogu, dymek w trybie Conversation, niepokojący wskaźnik pisania i powierzchnię gry. Wklej go w pole **Creator Notes**, a potem wybierz tryb Card Theming w **Chat Settings → Characters** (w trybie Game **Party**). Dla powierzchni gry ustaw **Chat**. Podmień kolory, znak w `content` i kroje pisma, żeby karta stała się twoja.

## Tworzenie CSS karty z pomocą asystenta AI

Żeby nie pisać CSS ręcznie, przekaż asystentowi AI ten prompt. Uzupełnij zaznaczone miejsce koncepcją swojej postaci.

I'm creating a character card for Marinara Engine (an AI chat app). The card has a "Creator Notes" field where I can embed <style> blocks. Write CSS that themes the character's messages.

Character concept: [describe the aesthetic]

Technical constraints:

use normal class selectors for things inside it.

corners / shadow); [data-card-css] .mari-message-content = the text; [data-card-css] .mari-message-name = the display name; [data-card-css] .mari-message-avatar button = the clickable avatar (non-clickable fallback: .mari-message-avatar > div; in roleplay the button sits under an extra glow-wrapper div).

[data-card-css] .mari-typing-dots span.

[data-card-css].mari-about-me-popout (the card), the banner via .mari-about-me-banner, the avatar via .mari-about-me-avatar > div, the name via .mari-about-me-name, the box via .mari-about-me-box, and the body via .mari-about-me-text. Wrap these in @chat-mode conversation { ... }.

@chat-mode conversation { ... }; CSS outside applies everywhere.

(--primary, etc.). position: fixed becomes absolute. Use url(data:...) and rgba() colors.

(roleplay rows never carry it); there, use [data-card-css]:not([data-grouped]) for first-in-group.

Output a single <style> block I can paste into Creator Notes.


## Powiązane przewodniki

- [Ustawienia wyglądu](appearance-settings.md)
- [Własne motywy CSS (Theme Library)](custom-css-themes.md)
- [Tworzenie i edycja postaci](../characters/creating-and-editing-characters.md)