Binksy BrandOnline by binks design

Pour Claude Code, Codex et tout agent qui pilote un navigateur

Mode d’emploipour agents IA

Comment piloter le générateur de guide de marque avec l’API window.binksyGuide : importer, compléter, choisir un style, créditer, exporter et vérifier. Même contenu en Markdown : AGENTS.md.

Sommaire

Ce document s’adresse aux agents IA (Claude Code, Codex, ou tout agent qui pilote un navigateur via Playwright / CDP, ou qui exécute du JavaScript dans la page). Il explique comment utiliser le générateur de guide de marque (app.html) : importer un ou deux .binksy, partir de zéro, ajouter des assets, choisir un style, régler les crédits du graphiste et exporter le site, avec l’API publique window.binksyGuide.

Il existe en deux endroits, toujours identiques : AGENTS.md (Markdown, français puis anglais) et la page agent/index.html. Résumé court : llms.txt.

Points d’entrée découvrables sans JavaScript : index.html et docs.html déclarent <link rel="alternate" type="text/markdown" href="AGENTS.md">, <link rel="help" href="agent/"> et <link rel="alternate" type="text/plain" href="llms.txt">, contiennent un commentaire HTML et un <noscript> qui renvoient ici. robots.txt autorise tout et cite llms.txt et AGENTS.md.

01Règle fondamentale

Le générateur met en page ce que le graphiste fournit. Ce n’est pas un générateur de logos ni de contenus de marque.

  • N’invente jamais un logo, un symbole, une icône, une couleur de marque, une police ou un texte de marque (nom, slogan, présentation, valeurs). Ce que l’utilisateur fournit (fichiers .binksy, SVG, couleurs, polices, textes, assets) fait foi.
  • Ne redessine pas un SVG fourni et ne modifie pas sa géométrie. Ne remplace pas un fichier manquant par un fichier « approchant ».
  • Un titre ou une introduction que tu proposes reste une suggestion : fais-la valider avant de l’enregistrer avec setOptions.
  • Aucune clé API, aucun service en ligne. Le générateur n’embarque aucune IA ; c’est toi qui décides et vérifies. Ne demande jamais de clé à l’utilisateur.
  • Tout est local : lecture des fichiers, calculs et ZIP sont faits dans le navigateur. Rien n’est envoyé à un serveur. Les réglages sont mémorisés dans le stockage du navigateur.

Après chaque action : relis await binksyGuide.state(). Un appel ou un clic n’est pas une preuve de réussite.

02Démarrer

Lancer le générateur

Le site déployé (dossier dist/, produit par python3 build.py) contient : index.html (accueil), app.html (le générateur), docs.html (documentation), agent/index.html (cette page), AGENTS.md, llms.txt, robots.txt, demo/ (fichiers de démonstration) et assets/.

cd dist && python3 -m http.server 8000
# puis ouvrir http://127.0.0.1:8000/app.html
  • http:// recommandé : les fichiers de démo et les URL relatives (demo/avora.binksy) se chargent par fetch.
  • file:// marche aussi (ouvrir app.html directement), mais les navigateurs bloquent fetch sur file:// : passe alors les fichiers en File/Blob, ArrayBuffer, Uint8Array, data URL ou base64, pas en URL.
  • N’importe quel hébergement statique convient (Netlify, Vercel, GitHub Pages…).
  • Utilise un profil de navigateur dédié aux tests : les réglages (style, crédits…) sont mémorisés pour l’origine.

Deux façons de piloter

  1. API JavaScript (recommandé) : window.binksyGuide, dans app.html.
  2. Clics : les commandes clés portent un attribut stable data-agent (voir § 9).
await binksyGuide.ready();
binksyGuide.version;   // "2.0.0"
binksyGuide.help();    // [{name, signature, description}]
await binksyGuide.state();

03Conventions de l’API

  • Toutes les méthodes sont async (sauf version, help() et styles()) et renvoient du JSON simple.
  • Fichiers acceptés : File / Blob, ArrayBuffer, Uint8Array, data URL, base64, URL relative ou absolue (chargée par fetch) et, pour les SVG, le texte SVG lui-même.
  • Une erreur rejette la promesse avec un message explicite : lis-le, corrige l’appel, puis relis state().
  • Toujours commencer par await binksyGuide.ready().

04Référence de window.binksyGuide

await binksyGuide.ready();
binksyGuide.version;                 // "2.0.0"
binksyGuide.help();                  // [{name, signature, description}]
await binksyGuide.state();           // {brand, sources, versions, palette, fonts, missingFonts, assets, options, style, credits, sections, files}
await binksyGuide.importBinksy(file, 'logokit' | 'multiformats');  // kind facultatif : détecté sinon
await binksyGuide.startBlank({ brand: 'Nom' });                     // partir de zéro
await binksyGuide.addLogo(svg, { name: 'Horizontal', kind: 'horizontal'|'vertical'|'icon'|'wordmark'|'monogram'|'other' });
await binksyGuide.addColor({ hex: '#ff5500', name: 'Orange', role: 'accent' });   // rôles : primary, secondary, accent, text, background, surface, neutral, light, dark
await binksyGuide.removeColor('#ff5500');
await binksyGuide.addFont(file, { family: 'Inter', weight: 400, italic: false, licence: 'OFL', free: true });
await binksyGuide.addAsset(file, { category: 'mockup'|'social'|'print'|'web'|'other', title: 'Affiche', caption: '' }); // → {id}
await binksyGuide.removeAsset(id);
await binksyGuide.setOptions({ lang: 'fr'|'en', brand, title, intro, sections: { logo: true, formats: false, ... } });
await binksyGuide.setBrandText({ tagline, description, history, mission, vision, goals, values, audience, positioning, personality, tone, voice, voiceDont, keywords, activity });
binksyGuide.styles();                // [{id, name, description}]
await binksyGuide.setStyle('suisse');
await binksyGuide.setCredits({ name: 'Binks Design', email, instagram, website, phone, links: [{ label, url }], show: true });
await binksyGuide.exportSite({ download: true, base64: false });   // → {name, size, count, base64?}
await binksyGuide.reset();
Méthode Rôle
ready() Attend que le générateur soit prêt.
version / help() Version de l’API, liste des méthodes.
state() État complet : marque, sources, versions du logo, palette, polices, missingFonts (polices de la hiérarchie sans fichier), assets, options, style, crédits, sections, fichiers.
importBinksy(file, kind?) Importe un .binksy Binksy LogoKit (v2 ZIP ou ancien JSON V5) ou un .binksynext Binksy LogoNext (type détecté d’après le contenu : manifest + modules). Deux appels = fusion.
startBlank({brand}) Part de zéro avec un nom de marque.
addLogo(svg, {name, kind}) Ajoute un logo SVG fourni par l’utilisateur.
addColor({hex, name, role}) / removeColor(hex) Ajoute / retire une couleur.
addFont(file, {family, weight, italic, licence, free}) Ajoute une police (TTF, OTF, WOFF, WOFF2). free: true seulement si la licence est libre. Sert aussi à fournir une police listée dans missingFonts.
addAsset(file, {category, title, caption}) / removeAsset(id) Ajoute / retire un asset supplémentaire.
setOptions({lang, brand, title, intro, sections}) Langue du site, nom, titre, intro, sections affichées.
setBrandText({...}) Textes de la plateforme de marque (voir § 7 bis).
styles() / setStyle(id) Liste des 10 styles / choix du style.
setCredits({...}) Crédits du graphiste.
exportSite({download, base64}) Exporte le site en ZIP.
reset() Remet le générateur à zéro.

05Sources et fusion

Sources possibles, combinables :

  1. .binksy LogoKit (v2 ZIP ou ancien JSON V5) : versions du logo, règles (zone de protection, tailles minimales), palette, dégradés, typographies (fichiers + licences), hiérarchie, mauvais usages, brief et textes des pages du guide (plateforme de marque), mockups.
  2. .binksynext Binksy LogoNext (modules.multiformats, même format interne qu’un .binksy v2 ; type détecté d’après le contenu, l’extension ne départage que les cas ambigus) : versions, palette et rôles, QR code, formats coupés / actifs, fond.
  3. Sans .binksy (« Partir de zéro ») : nom de marque + logos SVG importés à la main + couleurs (HEX, nom, rôle) + polices (TTF / OTF / WOFF / WOFF2, avec licence libre ou non).
  4. Assets supplémentaires créés ailleurs : images (PNG, JPG, WebP, SVG, GIF) ou fichiers (PDF, etc.) rangés dans une catégorie : mockup (Applications), social (Réseaux sociaux), print (Imprimés), web, other (Autres). Titre et légende modifiables.

Site exporté : chaque déclinaison de couleur du logo en SVG, PNG (2000 px, transparent), PDF (vectoriel) et JPG (fond plein), rangée dans telechargements/logos/<version>/<svg|png|pdf|jpg>/ ; chaque fichier du site (formats, favicons, fichiers de palette, mockups, assets) a un aperçu, un bouton Copier (image ou code / texte) et un bouton Télécharger.

Fusion : LogoKit prioritaire (logo, typographies, guide, mockups) ; LogoNext ajoute ses formats et le QR code ; les ajouts manuels s’ajoutent à tout.

Démonstration (marque fictive AVORA) : demo/avora.binksy (LogoKit), demo/avora-ancien-logokit.binksy (ancien format LogoKit), demo/avora-logonext.binksynext (LogoNext). N’utilise la démo que pour tester ou si l’utilisateur la demande.

06Les 10 styles

id Nom En bref
editorial Éditorial grands titres, filets fins, colonnes
suisse Suisse grille stricte, fer à gauche
minimal Minimal beaucoup de blanc, un seul accent
noir Noir fond sombre, contrastes forts
magazine Magazine images en grand, titres superposés
brutal Brutaliste bordures épaisses, ombres franches
doux Doux coins arrondis, teintes douces
technique Technique grille de plan, cotes, monospace
aplat Aplat couleur de marque en grands aplats
classique Classique luxe, serif

binksyGuide.styles() fait foi pour les descriptions. Le style change la mise en page, pas l’identité.

07Sections du site

intro, marque, ton, logo, declinaisons, protection, tailles, interdits, couleurs, typographie, applications, assets, formats, ressources. Active ou désactive-les avec setOptions({ sections: { formats: false } }). La section des bons et mauvais usages a pour id interdits (pas usages).

7 bis. Plateforme de marque (setBrandText)

Textes affichés dans Introduction (signature tagline, présentation description, activité activity), La marque (marque : history histoire, mission, vision, goals objectifs, values valeurs, audience public, positioning positionnement) et Ton et voix (ton : personality personnalité, tone ton, keywords mots-clés, voice « on dit », voiceDont « on évite »). Panneau « Plateforme de marque » dans l’interface (data-agent="brand-text").

await binksyGuide.setBrandText({
  tagline: 'Texte fourni par l’utilisateur',
  values: 'Valeur 1\nValeur 2\nValeur 3',   // un élément par ligne : values, goals, keywords, voice, voiceDont
  vision: '',                                // chaîne vide = bloc masqué
  mission: null,                             // null / undefined = texte du .binksy rétabli
});
  • Les textes viennent du brief et des pages du guide d’un .binksy LogoKit, ou de l’utilisateur. Chaque bloc n’apparaît que s’il contient du texte.
  • N’écris jamais un texte de marque de ton cru : ne passe à setBrandText que des textes fournis ou validés par l’utilisateur. Pour masquer un texte, passe ''.

7 ter. Polices à importer (missingFonts)

Si la hiérarchie typographique utilise une police sans fichier, l’interface affiche « Polices à importer » (un bouton par famille) et state().missingFonts les liste. Demande le fichier à l’utilisateur puis appelle addFont(file, { family: 'Nom exact de la famille' }). Ne remplace jamais une police manquante par une autre.

08Exemple complet

Dans la page (JavaScript)

const g = window.binksyGuide;
await g.ready();
await g.reset();

// 1. Sources : la démo AVORA (LogoKit + LogoNext = fusion)
await g.importBinksy('demo/avora.binksy', 'logokit');
await g.importBinksy('demo/avora-logonext.binksynext', 'multiformats');
let s = await g.state();
console.assert(s.brand && s.versions.length > 0, 'aucune version de logo');

// 2. Un asset fourni par l’utilisateur (ici en data URL)
const { id } = await g.addAsset(posterDataUrl, { category: 'print', title: 'Affiche de lancement', caption: '' });

// 3. Réglages, style et crédits
await g.setOptions({ lang: 'fr', sections: { formats: true, ressources: true } });
await g.setStyle('suisse');
await g.setCredits({
  name: 'Binks Design',
  email: 'graphistedubinks@gmail.com',
  instagram: 'https://www.instagram.com/graphiste.binks/',
  show: true,
});

// 4. Vérifier
s = await g.state();
console.assert(s.style === 'suisse' || s.style?.id === 'suisse');
console.assert(s.assets.some((a) => a.id === id));

// 5. Exporter sans boîte de téléchargement
const out = await g.exportSite({ base64: true });   // {name, size, count, base64}

Depuis Playwright (Python)

import base64, pathlib
from playwright.sync_api import sync_playwright

poster = 'data:image/png;base64,' + base64.b64encode(pathlib.Path('affiche.png').read_bytes()).decode()  # fichier de l’utilisateur

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    errors = []
    page.on('pageerror', lambda e: errors.append(str(e)))
    page.goto('http://127.0.0.1:8000/app.html')
    page.wait_for_function('window.binksyGuide')
    out = page.evaluate('''async (poster) => {
      const g = window.binksyGuide;
      await g.ready(); await g.reset();
      await g.importBinksy('demo/avora.binksy', 'logokit');
      await g.importBinksy('demo/avora-logonext.binksynext', 'multiformats');
      await g.addAsset(poster, { category: 'print', title: 'Affiche de lancement', caption: '' });
      await g.setStyle('suisse');
      await g.setCredits({ name: 'Binks Design', email: 'graphistedubinks@gmail.com',
                           instagram: 'https://www.instagram.com/graphiste.binks/', show: true });
      const state = await g.state();
      const zip = await g.exportSite({ base64: true });
      return { state, zip };
    }''', poster)
    pathlib.Path(out['zip']['name']).write_bytes(base64.b64decode(out['zip']['base64']))
    print(out['zip']['count'], 'fichiers,', out['zip']['size'], 'octets', '| erreurs :', errors)
    browser.close()

Partir de zéro

await g.reset();
await g.startBlank({ brand: 'Nom fourni par l’utilisateur' });
await g.addLogo(svgTexteFourni, { name: 'Horizontal', kind: 'horizontal' });
await g.addColor({ hex: '#1d1d1b', name: 'Noir', role: 'primary' });
await g.addFont(fontBytes, { family: 'Inter', weight: 400, italic: false, licence: 'OFL', free: true });

09Repères data-agent

Attribut Commande
import-logokit Importer un .binksy LogoKit
import-multiformats Importer un .binksynext LogoNext
start-blank Partir de zéro
add-logo Ajouter un logo SVG
add-color Ajouter une couleur
add-font Ajouter une police
add-asset Ajouter un asset supplémentaire
brand-text Panneau « Plateforme de marque » (textes du site)
style-<id> Choisir un style (style-suisse, style-noir…)
export Exporter le site

Exemple Playwright : page.click('[data-agent="style-suisse"]'), page.set_input_files('[data-agent="import-logokit"] input[type=file], input[data-agent="import-logokit"]', 'avora.binksy') (selon que l’attribut est sur le bouton ou sur le champ fichier — vérifie dans le DOM).

10Vérifications avant de rendre le travail

  1. state().brand est le nom fourni par l’utilisateur (aucune faute, rien d’inventé).
  2. state().sources liste les sources attendues ; versions contient chaque version du logo fournie.
  3. palette : chaque couleur a un nom et un rôle corrects.
  4. fonts : free: true seulement pour une licence réellement libre (OFL, Apache…). Une police commerciale est affichée dans le site mais jamais téléchargeable.
  5. assets : bonne catégorie, titre et légende relus.
  6. options : langue, titre, intro (validés par l’utilisateur), sections. Textes de marque : uniquement ceux du .binksy ou de l’utilisateur ; missingFonts vide (ou signalé à l’utilisateur).
  7. style et credits comme demandé.
  8. exportSite({ base64: true }) renvoie count > 0 et size > 0. Décompresse le ZIP, ouvre index.html (http et file://) : aucune erreur console, logos visibles, chaque version de couleur présente dans telechargements/logos/<version>/{svg,png,pdf,jpg}/.
  9. Capture d’écran de l’aperçu ou du site exporté, en bureau et en mobile.

11Limites et erreurs

  • Formats non produits ici : tickets thermiques, étiquettes Zebra, vidéo, EPS, jeux complets d’icônes Android / macOS → ils restent dans Binksy LogoNext.
  • CMJN : conversion simple, sans profil ICC.
  • Polices non libres : affichées (intégrées) mais pas téléchargeables.
  • fetch impossible en file:// : passe les fichiers en octets, data URL ou base64.
  • Style inconnu : setStyle refuse un id hors de styles().
  • Catégorie d’asset inconnue : seules mockup, social, print, web, other sont acceptées.
  • Fichier qui n’est pas un .binksy : l’import échoue ; demande le bon fichier à l’utilisateur au lieu de reconstruire la marque.
  • Téléchargement bloqué (navigateur sans interface) : utilise exportSite({ base64: true }).

Si le comportement réel diffère de ce document, décris l’écart, fie-toi à binksyGuide.help() et à state(), et adapte-toi sans contourner les protections.

12Logique à suivre pour chaque tâche

  1. Comprendre la demande et ce que l’utilisateur a déjà fourni (ne redemande jamais une information donnée).
  2. await binksyGuide.ready() puis state().
  3. Poser en un seul message les questions vraiment nécessaires (fichiers manquants, style, crédits) ; ne jamais combler un manque en inventant.
  4. Agir par l’API (ou les repères data-agent).
  5. Vérifier state(), puis le rendu (aperçu, export).
  6. Exporter et rendre le ZIP avec un résumé : sources, style, sections, nombre de fichiers.

7 ter. Sections : ordre, textes, blocs et sections personnalisées

Chaque section (intégrée, reprise d’une page du guide LogoKit ou créée à la main) peut être renommée, recevoir un chapeau, être masquée, déplacée et enrichie de blocs. Les pages LogoKit sans équivalent (photographie, iconographie, réseaux sociaux, contact, construction, page vierge…) arrivent comme sections .binksy.

binksyGuide.sections();                                   // [{id, title, lead, enabled, builtin, from, blocks:[…]}]
await binksyGuide.setSection('logo', { title: 'Notre logo', lead: '…', enabled: true, index: 2 });
await binksyGuide.setSection('logo', { reset: true });     // textes et blocs d’origine
const s = await binksyGuide.addSection({ title: 'Motion', lead: '…', after: 'logo', blocks: [
  { type: 'video', file: videoFile, caption: 'Animation' },
  { type: 'embed', url: 'https://vimeo.com/…', caption: 'Making-of' },
  { type: 'text', title: 'Durée', text: '2 secondes, jamais plus.' }
]});
await binksyGuide.addBlock('couleurs', { type: 'image', file: imageFile, caption: 'Ambiance' });
await binksyGuide.updateBlock(s.id, blockId, { caption: '…' });
await binksyGuide.removeBlock(s.id, blockId);
await binksyGuide.moveSection(s.id, 0);
await binksyGuide.removeSection(s.id);                    // sections personnalisées seulement
  • Types de blocs : text (intertitre + texte, paragraphes séparés par une ligne vide), image (PNG, JPG, WebP, GIF, SVG, AVIF), video (MP4, WebM, MOV), embed (lien YouTube ou Vimeo, lu en ligne).
  • Images et vidéos sont copiées octet pour octet : téléchargement en résolution d’origine dans telechargements/sections/<section>/. Les mises en situation et assets ajoutés restent aussi à leur résolution d’origine.
  • Une section personnalisée sans chapeau ni bloc n’apparaît pas. Même règle : n’invente aucun texte.

This document is for AI agents (Claude Code, Codex, or any agent driving a browser through Playwright / CDP, or running JavaScript in the page). It explains how to use the brand guide generator (app.html): import one or two .binksy files, start from scratch, add assets, pick a style, set the designer credits and export the website, through the public window.binksyGuide API.

It lives in two places, always identical: AGENTS.md (Markdown, French then English) and the agent/index.html page. Short summary: llms.txt.

Entry points discoverable without JavaScript: index.html and docs.html declare <link rel="alternate" type="text/markdown" href="AGENTS.md">, <link rel="help" href="agent/"> and <link rel="alternate" type="text/plain" href="llms.txt">, and carry an HTML comment and a <noscript> pointing here. robots.txt allows everything and cites llms.txt and AGENTS.md.

01Golden rule

The generator lays out what the designer provides. It is not a logo or brand-copy generator.

  • Never invent a logo, symbol, icon, brand colour, typeface or brand text (name, tagline, description, values). What the user provides (.binksy files, SVGs, colours, fonts, copy, assets) is the source of truth.
  • Do not redraw a provided SVG or alter its geometry. Do not replace a missing file with a “close enough” one.
  • A title or intro you propose is a suggestion: get it approved before saving it with setOptions.
  • No API key, no online service. The generator embeds no AI; you decide and verify. Never ask the user for a key.
  • Everything is local: file reading, processing and ZIP creation happen in the browser. Nothing is sent to a server. Settings are remembered in browser storage.

After every action: re-read await binksyGuide.state(). A call or a click is not proof of success.

02Getting started

Run the generator

The deployed site (dist/ folder, produced by python3 build.py) contains: index.html (home), app.html (the generator), docs.html (documentation), agent/index.html (this page), AGENTS.md, llms.txt, robots.txt, demo/ (demo files) and assets/.

cd dist && python3 -m http.server 8000
# then open http://127.0.0.1:8000/app.html
  • http:// preferred: demo files and relative URLs (demo/avora.binksy) are loaded with fetch.
  • file:// also works (open app.html directly), but browsers block fetch on file://: pass files as File/Blob, ArrayBuffer, Uint8Array, data URL or base64, not as URLs.
  • Any static host works (Netlify, Vercel, GitHub Pages…).
  • Use a dedicated browser profile for tests: settings (style, credits…) are remembered per origin.

Two ways to drive it

  1. JavaScript API (recommended): window.binksyGuide, in app.html.
  2. Clicks: key controls carry a stable data-agent attribute (see § 9).
await binksyGuide.ready();
binksyGuide.version;   // "2.0.0"
binksyGuide.help();    // [{name, signature, description}]
await binksyGuide.state();

03API conventions

  • Every method is async (except version, help() and styles()) and returns plain JSON.
  • Accepted files: File / Blob, ArrayBuffer, Uint8Array, data URL, base64, relative or absolute URL (loaded with fetch) and, for SVGs, the SVG text itself.
  • An error rejects the promise with an explicit message: read it, fix the call, then re-read state().
  • Always start with await binksyGuide.ready().

04window.binksyGuide reference

await binksyGuide.ready();
binksyGuide.version;                 // "2.0.0"
binksyGuide.help();                  // [{name, signature, description}]
await binksyGuide.state();           // {brand, sources, versions, palette, fonts, missingFonts, assets, options, style, credits, sections, files}
await binksyGuide.importBinksy(file, 'logokit' | 'multiformats');  // kind optional: detected otherwise
await binksyGuide.startBlank({ brand: 'Name' });                    // start from scratch
await binksyGuide.addLogo(svg, { name: 'Horizontal', kind: 'horizontal'|'vertical'|'icon'|'wordmark'|'monogram'|'other' });
await binksyGuide.addColor({ hex: '#ff5500', name: 'Orange', role: 'accent' });   // roles: primary, secondary, accent, text, background, surface, neutral, light, dark
await binksyGuide.removeColor('#ff5500');
await binksyGuide.addFont(file, { family: 'Inter', weight: 400, italic: false, licence: 'OFL', free: true });
await binksyGuide.addAsset(file, { category: 'mockup'|'social'|'print'|'web'|'other', title: 'Poster', caption: '' }); // → {id}
await binksyGuide.removeAsset(id);
await binksyGuide.setOptions({ lang: 'fr'|'en', brand, title, intro, sections: { logo: true, formats: false, ... } });
await binksyGuide.setBrandText({ tagline, description, history, mission, vision, goals, values, audience, positioning, personality, tone, voice, voiceDont, keywords, activity });
binksyGuide.styles();                // [{id, name, description}]
await binksyGuide.setStyle('suisse');
await binksyGuide.setCredits({ name: 'Binks Design', email, instagram, website, phone, links: [{ label, url }], show: true });
await binksyGuide.exportSite({ download: true, base64: false });   // → {name, size, count, base64?}
await binksyGuide.reset();
Method Purpose
ready() Waits until the generator is ready.
version / help() API version, list of methods.
state() Full state: brand, sources, logo versions, palette, fonts, missingFonts (hierarchy fonts with no file), assets, options, style, credits, sections, files.
importBinksy(file, kind?) Imports a LogoKit .binksy (v2 ZIP or legacy JSON V5) or a Binksy LogoNext .binksynext (type detected from the content: manifest + modules). Two calls = merge.
startBlank({brand}) Starts from scratch with a brand name.
addLogo(svg, {name, kind}) Adds a logo SVG provided by the user.
addColor({hex, name, role}) / removeColor(hex) Adds / removes a colour.
addFont(file, {family, weight, italic, licence, free}) Adds a font (TTF, OTF, WOFF, WOFF2). free: true only for a genuinely free licence. Also fills a font listed in missingFonts.
addAsset(file, {category, title, caption}) / removeAsset(id) Adds / removes an extra asset.
setOptions({lang, brand, title, intro, sections}) Site language, name, title, intro, visible sections.
setBrandText({...}) Brand platform copy (see § 7 bis).
styles() / setStyle(id) List of the 10 styles / pick one.
setCredits({...}) Designer credits.
exportSite({download, base64}) Exports the website as a ZIP.
reset() Resets the generator.

05Sources and merging

Possible sources, combinable:

  1. LogoKit .binksy (v2 ZIP or legacy JSON V5): logo versions, rules (clear space, minimum sizes), palette, gradients, typefaces (files + licences), hierarchy, misuses, brief and guide-page copy (brand platform), mockups.
  2. Binksy LogoNext .binksynext (modules.multiformats, same internal format as .binksy v2): versions, palette and roles, QR code, cut / active formats, background.
  3. No .binksy (“Start from scratch”): brand name + hand-imported SVG logos + colours (HEX, name, role) + fonts (TTF / OTF / WOFF / WOFF2, free licence or not).
  4. Extra assets made elsewhere: images (PNG, JPG, WebP, SVG, GIF) or files (PDF, etc.) filed in a category: mockup (Applications), social (Social media), print (Print), web, other (Other). Editable title and caption.

Exported site: every logo colour version in SVG, PNG (2000 px, transparent), PDF (vector) and JPG (solid background), sorted in telechargements/logos/<version>/<svg|png|pdf|jpg>/; every file in the site (formats, favicons, palette files, mockups, assets) has a preview, a Copy button (image or code / text) and a Download button.

Merge: LogoKit wins (logo, typefaces, guide, mockups); LogoNext adds its formats and the QR code; manual additions are added on top of everything.

Demo (fictional brand AVORA): demo/avora.binksy (LogoKit), demo/avora-ancien-logokit.binksy (legacy Binksy LogoKit format), demo/avora-logonext.binksynext (LogoNext). Use the demo only for testing or when the user asks for it.

06The 10 styles

id Name In short
editorial Éditorial (Editorial) big headlines, hairlines, columns
suisse Suisse (Swiss) strict grid, flush left
minimal Minimal lots of white, one accent
noir Noir (Dark) dark background, strong contrast
magazine Magazine large images, overlapping titles
brutal Brutaliste (Brutalist) thick borders, hard shadows
doux Doux (Soft) rounded corners, soft tints
technique Technique (Technical) blueprint grid, dimensions, monospace
aplat Aplat (Flat colour) brand colour in large flat areas
classique Classique (Classic) luxury, serif

binksyGuide.styles() is authoritative for descriptions. A style changes the layout, not the identity.

07Site sections

intro, marque (the brand), ton (tone of voice), logo, declinaisons (colour variants), protection (clear space), tailles (minimum sizes), interdits (do’s and don’ts), couleurs (colours), typographie, applications, assets, formats, ressources (downloads). Toggle them with setOptions({ sections: { formats: false } }). The do’s and don’ts section id is interdits (not usages).

7 bis. Brand platform (setBrandText)

Copy shown in Introduction (tagline, description, activity), The brand (marque: history, mission, vision, goals, values, audience, positioning) and Tone of voice (ton: personality, tone, keywords, voice “we say”, voiceDont “we avoid”). “Plateforme de marque” panel in the UI (data-agent="brand-text").

await binksyGuide.setBrandText({
  tagline: 'Text provided by the user',
  values: 'Value 1\nValue 2\nValue 3',   // one item per line: values, goals, keywords, voice, voiceDont
  vision: '',                             // empty string = block hidden
  mission: null,                          // null / undefined = .binksy text restored
});
  • Copy comes from the brief and guide pages of a LogoKit .binksy, or from the user. Each block only appears if it has text.
  • Never write brand copy yourself: only pass text the user provided or approved to setBrandText. To hide a text, pass ''.

7 ter. Fonts to import (missingFonts)

If the type hierarchy uses a font with no file, the UI shows “Polices à importer” (one button per family) and state().missingFonts lists them. Ask the user for the file, then call addFont(file, { family: 'Exact family name' }). Never substitute another font.

08Complete example

In the page (JavaScript)

const g = window.binksyGuide;
await g.ready();
await g.reset();

// 1. Sources: the AVORA demo (LogoKit + LogoNext = merge)
await g.importBinksy('demo/avora.binksy', 'logokit');
await g.importBinksy('demo/avora-logonext.binksynext', 'multiformats');
let s = await g.state();
console.assert(s.brand && s.versions.length > 0, 'no logo version');

// 2. An asset provided by the user (here as a data URL)
const { id } = await g.addAsset(posterDataUrl, { category: 'print', title: 'Launch poster', caption: '' });

// 3. Settings, style and credits
await g.setOptions({ lang: 'en', sections: { formats: true, ressources: true } });
await g.setStyle('suisse');
await g.setCredits({
  name: 'Binks Design',
  email: 'graphistedubinks@gmail.com',
  instagram: 'https://www.instagram.com/graphiste.binks/',
  show: true,
});

// 4. Verify
s = await g.state();
console.assert(s.style === 'suisse' || s.style?.id === 'suisse');
console.assert(s.assets.some((a) => a.id === id));

// 5. Export without a download dialog
const out = await g.exportSite({ base64: true });   // {name, size, count, base64}

From Playwright (Python)

import base64, pathlib
from playwright.sync_api import sync_playwright

poster = 'data:image/png;base64,' + base64.b64encode(pathlib.Path('poster.png').read_bytes()).decode()  # the user's file

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    errors = []
    page.on('pageerror', lambda e: errors.append(str(e)))
    page.goto('http://127.0.0.1:8000/app.html')
    page.wait_for_function('window.binksyGuide')
    out = page.evaluate('''async (poster) => {
      const g = window.binksyGuide;
      await g.ready(); await g.reset();
      await g.importBinksy('demo/avora.binksy', 'logokit');
      await g.importBinksy('demo/avora-logonext.binksynext', 'multiformats');
      await g.addAsset(poster, { category: 'print', title: 'Launch poster', caption: '' });
      await g.setStyle('suisse');
      await g.setCredits({ name: 'Binks Design', email: 'graphistedubinks@gmail.com',
                           instagram: 'https://www.instagram.com/graphiste.binks/', show: true });
      const state = await g.state();
      const zip = await g.exportSite({ base64: true });
      return { state, zip };
    }''', poster)
    pathlib.Path(out['zip']['name']).write_bytes(base64.b64decode(out['zip']['base64']))
    print(out['zip']['count'], 'files,', out['zip']['size'], 'bytes', '| errors:', errors)
    browser.close()

Starting from scratch

await g.reset();
await g.startBlank({ brand: 'Name given by the user' });
await g.addLogo(providedSvgText, { name: 'Horizontal', kind: 'horizontal' });
await g.addColor({ hex: '#1d1d1b', name: 'Black', role: 'primary' });
await g.addFont(fontBytes, { family: 'Inter', weight: 400, italic: false, licence: 'OFL', free: true });

09data-agent hooks

Attribute Control
import-logokit Import a LogoKit .binksy
import-multiformats Import a LogoNext .binksynext
start-blank Start from scratch
add-logo Add an SVG logo
add-color Add a colour
add-font Add a font
add-asset Add an extra asset
brand-text “Plateforme de marque” panel (site copy)
style-<id> Pick a style (style-suisse, style-noir…)
export Export the website

Playwright example: page.click('[data-agent="style-suisse"]'), page.set_input_files('[data-agent="import-logokit"] input[type=file], input[data-agent="import-logokit"]', 'avora.binksy') (depending on whether the attribute sits on the button or on the file input — check the DOM).

10Checks before handing back

  1. state().brand is the name the user gave (no typo, nothing invented).
  2. state().sources lists the expected sources; versions holds every logo version provided.
  3. palette: every colour has a correct name and role.
  4. fonts: free: true only for a genuinely free licence (OFL, Apache…). A commercial font is displayed on the site but never downloadable.
  5. assets: right category, title and caption proof-read.
  6. options: language, title, intro (approved by the user), sections. Brand copy: only from the .binksy or the user; missingFonts empty (or reported to the user).
  7. style and credits as requested.
  8. exportSite({ base64: true }) returns count > 0 and size > 0. Unzip, open index.html (http and file://): no console error, logos visible, every colour version present in telechargements/logos/<version>/{svg,png,pdf,jpg}/.
  9. Screenshot of the preview or of the exported site, desktop and mobile.

11Limits and errors

  • Formats not produced here: thermal receipts, Zebra labels, video, EPS, full Android / macOS icon sets → they stay in Binksy LogoNext.
  • CMYK: simple conversion, no ICC profile.
  • Non-free fonts: displayed (embedded) but not downloadable.
  • fetch impossible on file://: pass files as bytes, data URL or base64.
  • Unknown style: setStyle rejects an id not listed by styles().
  • Unknown asset category: only mockup, social, print, web, other are accepted.
  • File that is not a .binksy: the import fails; ask the user for the right file instead of rebuilding the brand.
  • Download blocked (headless browser): use exportSite({ base64: true }).

If the actual behaviour differs from this document, describe the gap, trust binksyGuide.help() and state(), and adapt without bypassing safeguards.

12Logic for every task

  1. Understand the request and what the user already provided (never ask again for information already given).
  2. await binksyGuide.ready() then state().
  3. Ask, in a single message, only the questions that matter (missing files, style, credits); never fill a gap by inventing.
  4. Act through the API (or the data-agent hooks).
  5. Check state(), then the rendering (preview, export).
  6. Export and hand back the ZIP with a summary: sources, style, sections, file count.

7 ter. Sections: order, copy, blocks and custom sections

Every section (built-in, imported from a LogoKit guide page, or created by hand) can be renamed, given a lead, hidden, moved and extended with blocks. LogoKit pages with no built-in match (photography, icons, social, contact, construction, blank page…) arrive as .binksy sections.

binksyGuide.sections();
await binksyGuide.setSection('logo', { title, lead, enabled, index, reset });
await binksyGuide.addSection({ title, lead, after, blocks: [{ type: 'text' | 'image' | 'video' | 'embed', title, text, file, url, caption }] });
await binksyGuide.addBlock(sectionId, { type, file, caption, index });
await binksyGuide.updateBlock(sectionId, blockId, { ... });
await binksyGuide.removeBlock(sectionId, blockId);
await binksyGuide.moveSection(sectionId, index);
await binksyGuide.removeSection(sectionId);               // custom sections only
  • Images and videos are copied byte for byte and downloadable at their original resolution from telechargements/sections/<section>/.
  • A custom section with neither lead nor block is not shown. Never invent copy.