Skip to content

Latest commit

 

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oto-studio — visuels de communication oto (LinkedIn)

Studio local de création de visuels dans la charte oto.cx : cartes « cas d'usage » animées, affiches « posts produit », plaquettes, bannières. Export MP4/GIF via Chrome headless + ffmpeg.

📍 Ce repo est la source de vérité du design Otomata. Palette, typo, logos, tokens, charte formelle : tout est dans brand/, et c'est là qu'on met à jour. Les autres emplacements (oto-websites/packages/ui, oto-dashboard/design-system, le Drive identite/) sont des consommateurs — ils appliquent la charte, ils ne la définissent pas. En cas de divergence, brand/ a raison.

Structure

cards/        # générateur de cartes cas d'usage (studio + batch)
posts/        # affiches riso animées, une par post produit
plaquettes/   # one-pagers imprimables (plaquette commerciale)
banners/      # bannières statiques (couvertures de profil / page)
assets/       # fonts.css, icons.json, logos/ (marques tierces)
tools/        # publication (publer_schedule.py)
brand/        # logos & charte Otomata/Oto (cache local ; voir brand/README.md)
out/          # exports (ignoré), en miroir des sources :
              #   cards/ · posts/ · plaquettes/ · banners/ · articles/<slug>/
.gen/         # HTML générés + frames intermédiaires (ignoré)

Cartes cas d'usage (cards/)

./run.sh                          # studio : formulaire + preview + export → http://localhost:7842
node cards/build-all.mjs [start count]   # batch : régénère les MP4+GIF des cas d'usage
  • cards/studio.html — l'UI (formulaire + preview + export)
  • cards/server.mjs — serveur (studio + endpoint /render)
  • cards/template-body.html — le gabarit animé de la carte (le design, figé)
  • cards/usecases.json — les cas d'usage (presets, chiffres = placeholders à remplacer par un vrai run oto)

Posts produit (posts/) — affiches riso animées

Affiches 1200×1500 (4:5 LinkedIn) dans la charte « riso » : tokens @otomata/ui THEME.md + grain papier (SVG feTurbulence), halo solaire saffran, ombres portées dures sans radius, décalage d'encrage saffran (titres, câbles), tampons/étiquettes désaxés.

node posts/build-post.mjs <slug>   # rend posts/<slug>.html → out/<slug>.mp4 + .gif
  • posts/otocx.html — post lancement oto.cx (« L'OS pour vous et votre agent »)
  • posts/connectors.html — post nouveaux connecteurs, en 2 actes : tuiles logos (grille→bandeau par morph) puis carte conversation façon cas d'usage ; les concepts oto (chips PROCÉDURE/TABLEAU, projet en ligne finale) encadrent les connecteurs — montrer l'apport d'oto, pas des connecteurs MCP « natifs »
  • posts/cross-session.html — post cross-session messaging : trois fenêtres de terminal reliées par des fils, contenu métier réel (sessions interrogées via SendMessage puis anonymisées)
  • Même pattern que les cartes : window.__seek(t) déterministe (styles calculés depuis t, pas de transitions CSS) + capture CDP + ffmpeg
  • Affiche statique one-shot : google-chrome-stable --headless=new --screenshot --window-size=1200,1500 --force-device-scale-factor=2
  • Direction éditoriale (validée) : une seule idée et une phrase clé par visuel ; pas de « slide de deck » ; les illustrations d'usage mobilisent procédures/tableaux/projets

La scène occupe tout, puis recule (pattern validé)

Sur une affiche animée qui finit par une phrase clé, réserver dès le départ la place de cette phrase laisse une zone morte visible pendant toute l'animation. Faire l'inverse :

  1. la scène occupe toute la hauteur disponible (scène + zone de chute) pendant l'animation ;
  2. juste avant la fin, elle reculetransform: scale(k) avec transform-origin: 50% 0%, k ≈ 0.76 ;
  3. la chute monte dans la place ainsi libérée, positionnée en absolute bottom d'un .stage commun.

transform n'affecte pas le layout, donc la chute doit être en position absolue dans le conteneur, pas dans le flux. Deux bénéfices : plus de zone morte, et les contenus sont plus gros pendant l'animation — décisif quand le visuel est lu au pouce sur un fil LinkedIn. Voir posts/cross-session.html (T.zoomOut, ZOOM).

Bannières (banners/) — couvertures statiques

Images fixes dans la même charte riso, pour les couvertures de profil et de page.

google-chrome-stable --headless=new --disable-gpu --hide-scrollbars --no-first-run \
  --user-data-dir=/tmp/oto-build-chrome-banner --virtual-time-budget=8000 \
  --force-device-scale-factor=2 --window-size=<W>,<H> \
  --screenshot=out/banners/<slug>.png "file://$PWD/banners/<slug>.html"
  • banners/linkedin.html — couverture de profil LinkedIn, 1584×396 (rendu 2× → 3168×792)
  • --virtual-time-budget est nécessaire : sans lui le screenshot part avant le chargement des fonts
  • Zones à respecter sur LinkedIn : la photo de profil recouvre le bas-gauche (rien d'important avant x≈300), et le rognage mobile mange les côtés — garder le texte porteur au centre

Logos de marques (assets/logos/)

  • cdn.simpleicons.org/<slug> : reddit (#FF4500), zoho (#E42527) — salesforce absent → SVG Wikimedia Commons ; LightOn → SVG du CDN de lighton.ai, livré fill="white" → recolorer en encre #2c2112
  • Le backend oto passe par logo.dev (token env LOGODEV_TOKEN) — non disponible localement, ne pas compter dessus ici

Pré-requis

google-chrome + ffmpeg (déjà présents sur ce poste).

Exports

Les exports sortent dans out/<famille>/out/cards/, out/posts/, out/plaquettes/, out/articles/<slug>/ (illustrations statiques d'articles, sources dans article-<slug>/). Les scripts créent leur sous-dossier eux-mêmes. LinkedIn : préférer le MP4 (le GIF natif y est souvent rendu statique).

Gotchas (rendu Chrome headless, cet environnement)

  • Toujours lancer Chrome avec un --user-data-dir isolé (ex. /tmp/oto-build-chrome). Sans ça, il partage le profil par défaut du navigateur GUI → ferme les fenêtres de l'utilisateur et fait échouer le rendu.
  • Target.createTarget : ne pas passer width/height (erreur « Target position can only be set for new windows » avec un profil isolé). Fixer la taille via Emulation.setDeviceMetricsOverride.
  • Le sandbox de l'agent tue les serveurs/process de fond longs (exit 144). Lancer server.mjs soi-même dans un terminal ; les batchs finis (build-all.mjs, build-post.mjs) passent en tâche de fond OK.

Publication

Publer (SaaS) — voir tools/publer_schedule.py. Connecteur oto à venir : otomata-tech/otomata-private#60. Gotcha : le plan Publer trial refuse la publication (job complete mais payload.failures) → plan payant requis.

Licence & marques

Code sous MIT. Les logos tiers (assets/logos/ : Salesforce, LightOn, Reddit, Zoho, Anthropic/Claude, OpenAI, Mistral, Google Gemini…) sont des marques de leurs propriétaires respectifs, utilisées ici à titre nominatif dans des visuels de communication — ils ne sont pas couverts par la licence MIT.

About

Générateur local de cartes cas d'usage animées (LinkedIn) — charte oto.cx

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages