Files
Sanctification/spikes/branding-concepts-astra-medium/build-review.cjs

52 lines
5.7 KiB
JavaScript

const fs=require('fs'),path=require('path'),cp=require('child_process');
const root=__dirname,meta=require('./metadata.json'),repo=path.resolve(root,'../..');
const font=path.join(repo,'fonts/P052-Bold.otf'),medium=path.join(repo,'fonts/SanctificationP052-Medium.otf');
const mag=(...args)=>cp.execFileSync('magick',args.map(String),{stdio:'inherit'});
const cream='#f4ead4',teal='#263f50';
const title=(input,text,x,y,size,color,out,face=font)=>mag(input,'-font',face,'-pointsize',size,'-fill',color,'-gravity','NorthWest','-annotate','+'+x+'+'+y,text,out);
const notes=[
['Lighted Window','Architectural / contemplative','Cross and glass are immediate. Tall proportions reduce favicon presence.'],
['Renewing Flame','Growth / transformation','Expressive silhouette. Rough cross cutout needs a careful redraw.'],
['Rose of Grace','Sacred / compact','Best square silhouette. Simplify small gold details for production.']
];
for(let i=0;i<meta.concepts.length;i++){
const c=meta.concepts[i],dir=path.join(root,c.slug);fs.mkdirSync(dir,{recursive:true});
const source=path.join(root,'sources',c.slug+'.png');if(!fs.existsSync(source)) fs.copyFileSync(c.generated_path,source);
mag(source,'-trim','+repage','-resize','432x432','-gravity','center','-background','none','-extent','512x512',path.join(dir,'mark-512.png'));
mag('-size','512x512','xc:none','-fill',cream,'-draw','roundrectangle 0,0 511,511 80,80',path.join(dir,'mark-512.png'),'-compose','over','-composite',path.join(dir,'icon-tile-512.png'));
for(const n of [16,32,64]){
mag(path.join(dir,'icon-tile-512.png'),'-filter','Lanczos','-resize',n+'x'+n,path.join(dir,'favicon-'+n+'.png'));
mag(path.join(dir,'mark-512.png'),'-filter','Lanczos','-resize',n+'x'+n,path.join(dir,'transparent-mark-'+n+'.png'));
}
mag(path.join(dir,'favicon-16.png'),path.join(dir,'favicon-32.png'),path.join(dir,'favicon-64.png'),path.join(dir,'favicon-exploration.ico'));
for(const [theme,bg,fg] of [['light',cream,teal],['dark',teal,cream]]){
const out=path.join(dir,'logo-'+theme+'.png');
mag('-size','1300x280','xc:'+bg,'(',path.join(dir,'icon-tile-512.png'),'-resize','190x190',')','-geometry','+42+45','-composite',out);
title(out,'Sanctification',268,79,102,fg,out);
title(out,'TRADING CARD GAME',272,193,22,fg,out,medium);
}
}
const sheet=path.join(root,'comparison.png');
mag('-size','1800x1280','xc:'+cream,sheet);
title(sheet,'Sanctification | Three identity directions',60,34,46,teal,sheet);
title(sheet,'Astra Medium art direction / AI-generated raster marks + deterministic P052 typography',62,98,23,teal,sheet,medium);
title(sheet,'Explorations only. Originals preserved; no app assets replaced.',62,134,23,teal,sheet,medium);
for(let i=0;i<3;i++){
const c=meta.concepts[i],dir=path.join(root,c.slug),x=60+i*580;
title(sheet,String(i+1).padStart(2,'0')+' '+notes[i][0],x,205,34,teal,sheet);
title(sheet,notes[i][1],x,251,23,teal,sheet,medium);
mag(sheet,'(',path.join(dir,'icon-tile-512.png'),'-resize','270x270',')','-geometry','+'+(x+120)+'+301','-composite',sheet);
mag(sheet,'(',path.join(dir,'logo-light.png'),'-resize','530x',')','-geometry','+'+x+'+595','-composite',sheet);
mag(sheet,'(',path.join(dir,'logo-dark.png'),'-resize','530x',')','-geometry','+'+x+'+725','-composite',sheet);
title(sheet,'Actual pixels: 16 / 32 / 64',x,876,23,teal,sheet,medium);
for(const [j,n] of [16,32,64].entries()){
mag(sheet,'-fill',teal,'-draw','roundrectangle '+(x+j*120)+',918 '+(x+j*120+100)+',1017 8,8','(',path.join(dir,'favicon-'+n+'.png'),')','-geometry','+'+(x+j*120+(100-n)/2)+'+'+(918+(100-n)/2),'-composite',sheet);
title(sheet,n+' px',x+j*120+24,1030,20,teal,sheet,medium);
}
const lines=[notes[i][2].slice(0,notes[i][2].indexOf('. ')+1),notes[i][2].slice(notes[i][2].indexOf('. ')+2)];
for(let k=0;k<lines.length;k++)title(sheet,lines[k],x,1100+k*34,20,teal,sheet,medium);
}
title(sheet,'Review at 100% zoom for pixel sizes. Cream icon tiles preserve contrast on dark UI.',62,1210,24,teal,sheet,medium);
let html='<!doctype html><meta charset="utf-8"><title>Sanctification branding concepts</title><style>@font-face{font-family:P052;src:url(../../fonts/P052-Bold.otf)}body{background:#f4ead4;color:#263f50;margin:40px;font-family:system-ui}h1,h2{font-family:P052}section{margin:32px 0;border-top:1px solid #a7aaa0;padding:16px 0}.themes{display:flex;gap:20px}.theme{padding:20px;flex:1}.dark{background:#263f50;color:#f4ead4}.light{background:#fff;color:#263f50}.icons{display:flex;gap:32px;align-items:center;height:90px}.sample{display:flex;align-items:center;gap:10px}img.logo{width:100%;max-width:650px}p{max-width:900px}</style><h1>Sanctification: three identity directions</h1><p>Review raster explorations by Astra Medium. Marks generated with built-in image_gen; lettering uses shared P052. PNG icons below have intrinsic 16, 32, and 64 pixel dimensions. Use browser zoom 100% to assess CSS pixel size. Cream tiles deliberately preserve contrast on either theme.</p><p><a href="comparison.png">Comparison sheet</a> · <a href="README.md">Review and limitations</a></p>';
for(let i=0;i<3;i++){const c=meta.concepts[i];html+='<section><h2>'+notes[i][0]+'</h2><p>'+notes[i][2]+'</p><div class="themes">';for(const theme of ['light','dark']){html+='<div class="theme '+theme+'"><img class="logo" src="'+c.slug+'/logo-'+theme+'.png"><p>Favicon tile — actual dimensions</p><div class="icons">';for(const n of [16,32,64])html+='<div class="sample"><img src="'+c.slug+'/favicon-'+n+'.png" width="'+n+'" height="'+n+'">'+n+' px</div>';html+='</div><p>Raw transparent mark — contrast diagnostic</p><div class="icons">';for(const n of [16,32,64])html+='<div class="sample"><img src="'+c.slug+'/transparent-mark-'+n+'.png" width="'+n+'" height="'+n+'">'+n+' px</div>';html+='</div></div>';}html+='</div></section>';}fs.writeFileSync(path.join(root,'index.html'),html);