CREMACREATOR STUDIO
YOUR FOOD. YOUR VOICE. YOUR WORKSPACE.

Make something
worth sharing.

CREMA Creator Studio is your workspace for publishing food stories, sharing photo galleries, building your audience and managing creator tools—all in one place.

Fresh colorful food arranged for a recipePublish your work

Create food stories, text posts and photo galleries in a focused editor.

Bright modern kitchen workspaceBuild your audience

Share recipes, cooking knowledge and culinary creativity with your community.

Fresh ingredients ready for cookingCreator tools

Explore planning tools and estimate possible advertising budgets or creator earnings.

QUICK ESTIMATORS

Plan your next step.

Try these calculators before signing in. Estimates are for planning only—not guaranteed earnings or live ad quotes.

Creator earnings estimator

Estimate gross revenue from valid monetized impressions using your own assumed RPM.

Estimated gross revenue$10.00
Actual revenue depends on network reporting, geography, demand, invalid-traffic filtering and payout rules.

Advertiser budget estimator

Estimate how many impressions a budget might buy at your assumed CPM.

Estimated impressions5,000
Planning estimate only. Real delivery depends on targeting, available inventory and campaign settings.
+(views/1000*rpm).toLocaleString('en-US',{minimumFractionDigits:2,maximumFractionDigits:2});$('adResult').textContent=Math.floor(budget/cpm*1000).toLocaleString('en-US');} ['creatorViews','creatorRpm','adBudget','adCpm'].forEach(id=>$(id).addEventListener('input',updateCalculators));updateCalculators(); $('switchauth').onclick=()=>{ authMode=authMode==='signin'?'signup':'signin'; $('authheading').textContent=authMode==='signin'?'Welcome back':'Create your account'; $('authsubmit').textContent=authMode==='signin'?'Sign in to CREMA':'Create account'; $('switchauth').textContent=authMode==='signin'?'New to CREMA? Create an account':'Already registered? Sign in'; $('password').autocomplete=authMode==='signin'?'current-password':'new-password'; authmsg(''); }; async function refresh(){try{const r=await Promise.all([call('/api/creator/content'),call('/api/analytics?days=30'),call('/api/creator/earnings')]);items=r[0].items||[];analytics=r[1];earnings=r[2];if(page!=='create')render()}catch(e){msg(e.message)}} function stat(label,value,icon){return '
'+label+' '+icon+'
'+(value==null?'—':esc(typeof value==='number'?value.toLocaleString():value))+''+(value==null?'No recorded value available':'Recorded CREMA data')+'
'} function row(x){const published=String(x.status||'').toUpperCase()==='PUBLISHED',shareUrl=window.location.origin+'/post.html?id='+encodeURIComponent(x.id||'');return '
'+(x.image_url||x.imageUrl?'':'▤')+'
'+esc(x.title||'Untitled post')+''+esc(x.type||'post')+' · '+esc(x.created_at?new Date(x.created_at).toLocaleDateString():'date unavailable')+''+(published?'Open public post ↗':'')+'
'+esc(x.status||'status unavailable')+'
'} function empty(title,body,action){return '
✧
'+title+'

'+body+'

'+(action?'':'')+'
'} function head(kicker,title,desc,action){return '
'+kicker+'

'+title+'

'+desc+'

'+(action||'')+'
'} function render(){ $('crumb').textContent=({overview:'Overview',create:'Create a post',posts:'Your content',analytics:'Audience & analytics',earnings:'Earnings',connections:'Ad network connections',settings:'Studio settings',advertise:'Advertise'})[page];document.querySelectorAll('.navbtn[data-page]').forEach(b=>b.classList.toggle('active',b.dataset.page===page));let html=''; if(page==='overview'){html=head('YOUR CREATOR SPACE','Good to see you.','Manage your content, understand your audience and build your food brand.','');html+='
'+stat('Followers',analytics?.totals?.subscribers,'♙')+stat('Total views',analytics?.totals?.views,'◉')+stat('Valid views',analytics?.totals?.validViews,'✓')+stat('Unique viewers',analytics?.totals?.uniqueViewers,'▥')+'

Recent content

Posts and drafts returned by CREMA

'+(items.length?items.slice(0,5).map(row).join(''):empty('Your content starts here','Publish your first recipe, food photo or long-form story.','Create a post'))+'

Quick actions

Jump into your workspace

ⓘ Metrics are shown only when the connected CREMA backend has recorded data.

'} if(page==='posts'){html=head('PUBLISHING','Your content','Manage your food stories, photo galleries and articles.','');html+='

All content

'+items.length+' records returned by CREMA

'+items.length+' items
'+(items.length?items.map(row).join(''):empty('Nothing published yet','Your posts and drafts will appear here.','Create your first post'))+'
'} if(page==='analytics'){html=head('AUDIENCE INTELLIGENCE','Audience & analytics','Recorded CREMA activity, not sample statistics.','');html+='
'+stat('Followers',analytics?.totals?.subscribers,'♙')+stat('Total views',analytics?.totals?.views,'◉')+stat('Valid views',analytics?.totals?.validViews,'✓')+stat('Unique viewers',analytics?.totals?.uniqueViewers,'▥')+'

Top content

Posts with recorded analytics

30 days
'+((analytics?.topContent||[]).length?analytics.topContent.map(row).join(''):empty('Analytics will appear here','No top-content records were returned for this period.'))+'
'} if(page==='earnings'){html=head('CREATOR REVENUE','Earnings','Review earnings data reported for your account.','');html+='
'+stat('Available balance',earnings?.availableBalance??earnings?.available_balance,'$')+stat('Pending earnings',earnings?.pendingBalance??earnings?.pending_balance,'◷')+stat('Lifetime earnings',earnings?.totalEarnings??earnings?.total_earnings,'↗')+stat('Currency',earnings?.currency||null,'¤')+'

Revenue transparency

Only backend-reported earnings are displayed. Views and ad impressions do not automatically mean income. Confirmed revenue depends on valid activity, advertiser payments and recorded payout status.
';html+='

More ways food creators can earn

Monetization options to build into your CREMA creator journey

Open earnings calculator ↗
▤

Creator ad share

Potential share from verified eligible ad impressions, once live ad serving and payout records are connected.

✦

Sponsored food stories

Work with food, ingredient, cookware and kitchen brands on clearly disclosed campaigns.

▧

Paid recipes & classes

Offer premium recipe collections, meal plans, cooking guides or online lessons when checkout is supported.

♡

Fan support & memberships

A future option for audience tips or recurring supporter perks, subject to payment integration.

Planning note: these are monetization paths, not a claim that every payment feature is currently active. Only earnings returned by the connected backend appear in your balance.
'} if(page==='connections'){html=head('MONETIZATION SETUP','Ad network connections','Keep track of creator-side ad network setup. Connections are not verified until an official integration is completed.','');html+='

Add or update a network

Store your publisher reference only. Never enter passwords, API secrets or payment credentials here.

Your networks

Stored in your CREMA database account

'+(networks.length?networks.map(n=>'
'+esc(n.display_name)+''+esc(n.network_key.replaceAll('_',' '))+' · '+esc(n.publisher_reference||'No publisher reference')+'Setup status: '+esc(n.status)+' · '+esc(n.integration_method)+'
').join(''):empty('No networks saved','Add an ad network above to keep your setup details in one place.'))+'
Important: this currently saves account references and setup status only. It does not import revenue, display network ads, or automatically withdraw funds. Those features require each provider’s approved API/OAuth or payout integration.
'} if(page==='settings'){html=head('WORKSPACE PREFERENCES','Studio settings','Save personal defaults to your CREMA backend.','');const p=studioPrefs||{};html+='
Preferences are stored in the CREMA database. Dark theme is saved as a preference; the full visual theme switch is a separate UI enhancement.
'} if(page==='advertise'){html=head('CREMA ADVERTISING','Advertise','Advertising tools for food brands, businesses and creators.','');html+='
FOR FOOD BRANDS & BUSINESSES

Reach an audience that
cares about food.

Manage campaign setup and creative assets through CREMA advertising services. Delivery and budgets depend on your advertiser account and review status.

Open advertiser setup ↗

Campaigns

Records returned by the advertising backend

'+(campaigns.length?campaigns.map(c=>'
'+esc(c.name||c.title||'Untitled campaign')+''+esc(c.status||'Status unavailable')+'
'+esc(c.status||'—')+'
').join(''):empty('No campaign records to show','Sign in to an advertiser account or complete advertiser setup to manage campaigns.'))+'
'} if(page==='create'){html=head('PUBLISHING WORKSPACE','Create a post','Write a food story or create a photo gallery.','');html+='
Choose a category before publishing. Categories load from CREMA's database.
'+(postType!=='photo'?'
0 words
':'
'+photos.length+'/20 photos
'+photos.map((p,i)=>'
'+(i+1)+'
').join('')+'
')+'
✓ Save to CREMA to keep a draft or publish your work.
Long text is supported subject to browser, network and backend limits.
'} $('view').innerHTML=html;document.querySelectorAll('[data-goto]').forEach(b=>b.onclick=()=>go(b.dataset.goto));document.querySelectorAll('[data-type]').forEach(b=>b.onclick=()=>{postType=b.dataset.type;render()});const body=$('pbody');if(body)body.oninput=()=>{$('wordcount').textContent=(body.value.trim()?body.value.trim().split(/\s+/).length:0).toLocaleString()+' words'};if($('pickphotos'))$('pickphotos').onclick=()=>$('photoinput').click();if($('photoinput'))$('photoinput').onchange=e=>{const list=Array.from(e.target.files||[]);if(photos.length+list.length>20){$('postmsg').innerHTML='';return}if(list.some(f=>!f.type.startsWith('image/'))){$('postmsg').innerHTML='';return}photos=photos.concat(list.map(file=>({file,preview:URL.createObjectURL(file)})));render()};document.querySelectorAll('[data-remove]').forEach(b=>b.onclick=()=>{photos.splice(Number(b.dataset.remove),1);render()});if($('savedraft'))$('savedraft').onclick=()=>savePost(false);if($('publish'))$('publish').onclick=()=>savePost(true);if($('refreshbtn'))$('refreshbtn').onclick=refresh;if($('campaignrefresh'))$('campaignrefresh').onclick=loadCampaigns;if($('networkrefresh'))$('networkrefresh').onclick=loadNetworks;if($('savenetwork'))$('savenetwork').onclick=saveNetwork;if($('saveprefs'))$('saveprefs').onclick=savePrefs;document.querySelectorAll('[data-removenetwork]').forEach(b=>b.onclick=()=>removeNetwork(b.dataset.removenetwork));document.querySelectorAll('[data-copy-link]').forEach(b=>b.onclick=async()=>{try{await navigator.clipboard.writeText(b.dataset.copyLink);b.textContent='Copied!'}catch(e){const t=document.createElement('textarea');t.value=b.dataset.copyLink;document.body.append(t);t.select();document.execCommand('copy');t.remove();b.textContent='Copied!'}});} async function loadCategories(){try{const r=await call('/api/categories');categories=(r.items||[]).filter(c=>!c.parent_id&&c.status==='ACTIVE');const sel=$('pcategory');if(sel){const current=sel.value;sel.innerHTML=''+categories.map(c=>'').join('');if(current)sel.value=current;}}catch(e){const sel=$('pcategory');if(sel)sel.innerHTML='';msg('Could not load categories: '+e.message)}} async function loadNetworks(){try{const r=await call('/api/creator/networks');networks=r.items||[];if(page==='connections')render()}catch(e){msg(e.message)}} async function saveNetwork(){const key=$('networkkey')?.value,name=$('networkname')?.value.trim(),ref=$('publisherref')?.value.trim()||'';const m=$('networkmsg');if(!name){m.innerHTML='';return}const b=$('savenetwork');b.disabled=true;try{const r=await call('/api/creator/networks',{method:'POST',body:{networkKey:key,displayName:name,publisherReference:ref}});m.innerHTML='';await loadNetworks()}catch(e){m.innerHTML=''}finally{b.disabled=false}} async function removeNetwork(id){if(!confirm('Remove this saved network reference?'))return;try{await call('/api/creator/networks/'+encodeURIComponent(id),{method:'DELETE'});await loadNetworks()}catch(e){msg(e.message)}} async function loadPrefs(){try{const r=await call('/api/creator/studio-preferences');studioPrefs=r.item||{};if(page==='settings')render()}catch(e){msg(e.message)}} async function savePrefs(){const b=$('saveprefs');b.disabled=true;try{const r=await call('/api/creator/studio-preferences',{method:'PUT',body:{theme:$('pref-theme').value,defaultContentType:$('pref-type').value,analyticsRangeDays:Number($('pref-days').value),emailAlerts:$('pref-email').checked,payoutAlerts:$('pref-payout').checked}});studioPrefs=r.item;$('prefmsg').innerHTML=''}catch(e){$('prefmsg').innerHTML=''}finally{b.disabled=false}} async function loadCampaigns(){try{const r=await call('/api/advertiser/campaigns');campaigns=r.items||r.campaigns||[];render()}catch(e){msg(e.message)}} function go(next){page=next;msg('');if(next==='advertise')loadCampaigns();if(next==='connections')loadNetworks();if(next==='settings')loadPrefs();render();$('side').classList.remove('open');$('overlay').classList.add('hidden');window.scrollTo(0,0)} async function savePost(publish){const title=$('ptitle')?.value.trim()||'',body=$('pbody')?.value||'',summary=$('psummary')?.value.trim()||'',visibility=$('visibility')?.value||'PUBLIC',categoryId=$('pcategory')?.value||'';const pm=$('postmsg');if(!title){pm.innerHTML='';return}if(postType!=='photo'&&!body.trim()){pm.innerHTML='';return}if(postType==='photo'&&!photos.length){pm.innerHTML='';return}if(publish&&!categoryId){pm.innerHTML='';return}const draft=$('savedraft'),pub=$('publish');draft.disabled=pub.disabled=true;pub.textContent='Saving…';pm.innerHTML='';try{const creator=session.user;const name=creator.user_metadata?.full_name||creator.email?.split('@')[0]||'CREMA Creator';const made=await call('/api/content',{method:'POST',body:{type:postType==='photo'?'photo':postType,title,creatorId:creator.id,creatorName:name,description:summary,articleBody:postType==='photo'?'':body,categoryId:categoryId||undefined,visibility:visibility,shareTo:'CREMA',status:'DRAFT'}});const id=made.item?.id;if(!id)throw Error('CREMA did not return a content ID.');const imageUrls=[];for(let i=0;i