EMBED-CUSTOMIZATION.md (6280B)
1 # Customização visual do embed MyMusics 2 3 Este guia descreve como sites que embutem o player MyMusics podem personalizar cores, tipografia e layout **sem injetar CSS no iframe**. 4 5 ## Por que não dá para usar CSS externo? 6 7 O embed roda em um **iframe cross-origin**. Por causa da Same-Origin Policy, a página pai **não consegue** alterar estilos dentro do iframe. A abordagem correta — usada por SoundCloud, Spotify e widgets SaaS — é o MyMusics expor **parâmetros de URL** e **mensagens postMessage** que definem tokens CSS (`--mm-*`) dentro do documento do embed. 8 9 ### O que você pode customizar (v1) 10 11 - Presets nomeados (`light`, `dark`, `midnight`, `minimal`, …) 12 - Cores individuais (accent, fundo, painel, texto, texto secundário) 13 - Raio de borda (`radius`) 14 - Família tipográfica (`system`, `sans`, `serif`) 15 - Layout compacto (`theme=compact`) 16 - Tema em tempo real via `postMessage` 17 18 ### O que não está no escopo v1 19 20 - Arquivo CSS externo (`?stylesheet=`) 21 - Fontes arbitrárias por URL 22 - `@import` ou CSS livre do embedder 23 24 --- 25 26 ## Início rápido 27 28 ### Preset claro 29 30 ```html 31 <iframe 32 src="https://mymusics.murad.gg/embed?preset=light&brand=0" 33 title="MyMusics" 34 width="380" 35 height="420" 36 style="border:0" 37 allow="autoplay" 38 ></iframe> 39 ``` 40 41 ### Marca do site (accent laranja, layout compacto) 42 43 ```html 44 <iframe 45 src="https://mymusics.murad.gg/embed?preset=minimal&accent=e64a19&theme=compact" 46 title="MyMusics" 47 width="380" 48 height="320" 49 style="border:0" 50 allow="autoplay" 51 ></iframe> 52 ``` 53 54 ### Midnight com fonte serifada 55 56 ```html 57 <iframe 58 src="https://mymusics.murad.gg/embed?preset=midnight&font=serif" 59 title="MyMusics" 60 width="380" 61 height="540" 62 style="border:0" 63 allow="autoplay" 64 ></iframe> 65 ``` 66 67 --- 68 69 ## Parâmetros de URL 70 71 | Param | Exemplo | Efeito | 72 |-------|---------|--------| 73 | `preset` | `light` | Preset base de cores | 74 | `accent` | `fbc02d` ou `%23fbc02d` | Cor de destaque (botão play, highlights) | 75 | `bg` | `0f172a` | Fundo da página embed | 76 | `panel` | `1e293b` | Fundo de cards / player | 77 | `text` | `f8fafc` | Texto principal | 78 | `fgMuted` | `94a3b8` | Texto secundário (artista, hints) | 79 | `radius` | `12` | Border-radius em px (0–24) | 80 | `font` | `serif` | `system`, `sans` ou `serif` | 81 | `theme` | `compact` | Layout compacto | 82 | `autoplay` | `0` | Desliga autoplay / auto-advance | 83 | `start` | `12345` | ID da faixa inicial | 84 | `brand` | `0` | Oculta logo MyMusics | 85 | `muted` | `1` | Inicia mudo (**áudio**, não cor) | 86 87 **Convenções de cor** 88 89 - Hex com ou sem `#`; valores inválidos são ignorados (fallback ao preset). 90 - Use `fgMuted` para cor secundária. O param `muted=1` é **somente boolean** de áudio. 91 92 --- 93 94 ## Presets 95 96 | Preset | Descrição | 97 |--------|-----------| 98 | `default` | Visual MyMusics padrão (azul profundo, accent amarelo) | 99 | `light` | Fundo claro, texto escuro, accent laranja | 100 | `dark` | Neutro escuro (#121212), menos saturado que o default | 101 | `midnight` | Azul profundo de marca, accent ciano | 102 | `minimal` | Painéis flat, sombra reduzida, bordas suaves | 103 104 Params individuais **sobrescreem** tokens do preset escolhido. 105 106 --- 107 108 ## Tokens CSS (`--mm-*`) 109 110 Aplicados em `document.documentElement` quando a rota `/embed` está ativa. Úteis ao inspecionar o iframe no DevTools. 111 112 | Token | Uso | 113 |-------|-----| 114 | `--mm-bg` | Fundo | 115 | `--mm-bg-panel` | Cards / shell do player | 116 | `--mm-text` | Títulos e labels | 117 | `--mm-text-muted` | Artista, hints | 118 | `--mm-accent` | Botão play, destaques | 119 | `--mm-accent-secondary` | Links, progresso | 120 | `--mm-border` | Bordas e divisores | 121 | `--mm-radius` | Border-radius | 122 | `--mm-shadow` | Sombra do card | 123 | `--mm-font-body` | Corpo | 124 | `--mm-font-display` | Título da faixa | 125 126 --- 127 128 ## postMessage 129 130 ### Iframe → parent (existentes) 131 132 Payload: `{ source: "mymusics", type, ... }` 133 134 - `mymusics:ready` — `{ trackCount }` 135 - `mymusics:track` — `{ id, title, artist, streamUrl }` 136 - `mymusics:state` — `{ state: "playing" | "paused" | "buffering" | "error" }` 137 - `mymusics:error` — `{ code, message }` 138 - `mymusics:theme-applied` — `{ tokens: { "--mm-bg": "#...", ... } }` (debug) 139 140 ### Parent → iframe — comandos (existentes) 141 142 ```javascript 143 iframe.contentWindow.postMessage( 144 { source: "mymusics-host", type: "mymusics:command", command: "play" }, 145 "*" 146 ); 147 ``` 148 149 Comandos: `play`, `pause`, `next`. 150 151 ### Parent → iframe — tema (novo) 152 153 ```javascript 154 iframe.contentWindow.postMessage( 155 { 156 source: "mymusics-host", 157 type: "mymusics:theme", 158 theme: { preset: "light", accent: "#e64a19" }, 159 }, 160 "*" 161 ); 162 ``` 163 164 Campos aceitos em `theme`: `preset`, `accent`, `bg`, `panel`, `text`, `fgMuted` (ou `textMuted`), `radius`, `font`. Mesma validação que a URL. 165 166 O iframe responde com `mymusics:theme-applied` contendo os tokens CSS efetivos. 167 168 ### Tema dinâmico conforme dark mode do site 169 170 ```javascript 171 const iframe = document.querySelector("iframe.mymusics-embed"); 172 173 function syncEmbedTheme() { 174 const isDark = document.documentElement.classList.contains("dark"); 175 iframe?.contentWindow?.postMessage( 176 { 177 source: "mymusics-host", 178 type: "mymusics:theme", 179 theme: { preset: isDark ? "dark" : "light" }, 180 }, 181 "*" 182 ); 183 } 184 185 const observer = new MutationObserver(syncEmbedTheme); 186 observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] }); 187 syncEmbedTheme(); 188 ``` 189 190 --- 191 192 ## oEmbed 193 194 A API oEmbed repassa a query string da URL embed: 195 196 ``` 197 GET /api/oembed?url=https://mymusics.murad.gg/embed?preset=light&accent=fbc02d 198 ``` 199 200 --- 201 202 ## Gerador de snippet 203 204 As páginas **Home** e **About** incluem um gerador com preset, accent, fonte, radius e preview ao vivo. 205 206 --- 207 208 ## Limitações e roadmap 209 210 | Limitação v1 | Roadmap | 211 |--------------|---------| 212 | Sem CSS externo | Possível helper JS (`embed.js`) estilo SoundCloud Widget | 213 | Contraste não validado automaticamente | Recomenda-se WCAG manualmente | 214 | `accentSecondary` não exposto por URL | Pode ser adicionado em versão futura | 215 216 --- 217 218 ## Referências 219 220 - [SoundCloud Widget API](https://developers.soundcloud.com/docs/api/html5-widget) 221 - [Spotify Embed](https://developer.spotify.com/documentation/embeds) 222 - [MDN: Using CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)