publish: recipe-coster
This commit is contained in:
parent
6c5ea0299b
commit
d00b4ba484
@ -144,7 +144,7 @@ ul[data-fort]{list-style:none;margin:0;padding:0;display:flex;flex-direction:col
|
|||||||
</header>
|
</header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<main>
|
<main>
|
||||||
<fort-nav><nav class="fort-nav" data-fort="nav"><a href="/">Rony Thomas</a><a href="/about.html" class="active" aria-current="page">About Rony Thomas</a><a href="/services.html">Services</a></nav></fort-nav>
|
<fort-nav><nav class="fort-nav" data-fort="nav"><a href="/films/negros-fruit-dove/">Index</a><a href="/">Rony Thomas</a><a href="/about.html" class="active" aria-current="page">About Rony Thomas</a><a href="/coster.html">Recipe Coster</a><a href="/services.html">Services</a><a href="/negros-fruit-dove.html">The Negros Fruit Dove</a></nav></fort-nav>
|
||||||
|
|
||||||
<h1>About Me</h1>
|
<h1>About Me</h1>
|
||||||
<p class="lead">Forty-seven years old. Born and raised in La Grange. African-American, Southern, and proud of both.</p>
|
<p class="lead">Forty-seven years old. Born and raised in La Grange. African-American, Southern, and proud of both.</p>
|
||||||
|
|||||||
15
about.json
15
about.json
@ -3,6 +3,11 @@
|
|||||||
{
|
{
|
||||||
"current": "about.html",
|
"current": "about.html",
|
||||||
"items": [
|
"items": [
|
||||||
|
{
|
||||||
|
"rel": "films/negros-fruit-dove/index.html",
|
||||||
|
"title": "Index",
|
||||||
|
"href": "/films/negros-fruit-dove/"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"rel": "index.html",
|
"rel": "index.html",
|
||||||
"title": "Rony Thomas",
|
"title": "Rony Thomas",
|
||||||
@ -13,10 +18,20 @@
|
|||||||
"title": "About Rony Thomas",
|
"title": "About Rony Thomas",
|
||||||
"href": "/about.html"
|
"href": "/about.html"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"rel": "coster.html",
|
||||||
|
"title": "Recipe Coster",
|
||||||
|
"href": "/coster.html"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"rel": "services.html",
|
"rel": "services.html",
|
||||||
"title": "Services",
|
"title": "Services",
|
||||||
"href": "/services.html"
|
"href": "/services.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "negros-fruit-dove.html",
|
||||||
|
"title": "The Negros Fruit Dove",
|
||||||
|
"href": "/negros-fruit-dove.html"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
321
coster.html
Normal file
321
coster.html
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Recipe Coster — Rony Thomas, Kitchen Ops</title>
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:title" content="Recipe Coster — Rony Thomas, Kitchen Ops">
|
||||||
|
<meta property="og:description" content="A real kitchen recipe coster: yield run-throughs, cost per portion, sell price, food-cost % — the math behind a calm, profitable dinner line.">
|
||||||
|
<meta property="og:url" content="https://rony-thomas.4ort.net/coster.html">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="description" content="A real kitchen recipe coster: yield run-throughs, cost per portion, sell price, food-cost % — the math behind a calm, profitable dinner line.">
|
||||||
|
<style>
|
||||||
|
:root{
|
||||||
|
--paper:#f4efe4; /* ticket paper */
|
||||||
|
--ink:#1c1a16; /* near-black */
|
||||||
|
--rev:#d9422a; /* sales-sticker red */
|
||||||
|
--accent:#247a4a; /* collard green */
|
||||||
|
--line:#8a8374;
|
||||||
|
--brown:#6e5a35;
|
||||||
|
}
|
||||||
|
*{box-sizing:border-box}
|
||||||
|
body{
|
||||||
|
background:var(--paper);
|
||||||
|
color:var(--ink);
|
||||||
|
font-family:"Courier New",ui-monospace,Menlo,monospace;
|
||||||
|
margin:0; line-height:1.45;
|
||||||
|
/* retro print noise */
|
||||||
|
background-image:
|
||||||
|
repeating-linear-gradient(0deg, rgba(28,26,22,.02) 0 1px, transparent 1px 3px);
|
||||||
|
}
|
||||||
|
.wrap{max-width:860px;margin:0 auto;padding:24px}
|
||||||
|
header.ticket{
|
||||||
|
border:3px solid var(--ink);
|
||||||
|
background:var(--paper);
|
||||||
|
padding:18px 22px; margin-bottom:6px;
|
||||||
|
box-shadow:6px 6px 0 rgba(28,26,22,.12);
|
||||||
|
}
|
||||||
|
header.ticket h1{
|
||||||
|
margin:0;font-size:1.9rem;letter-spacing:-.5px;font-weight:700;
|
||||||
|
border-bottom:3px double var(--ink);display:inline-block;
|
||||||
|
}
|
||||||
|
.stamp{
|
||||||
|
display:inline-block;border:2px solid var(--rev);color:var(--rev);
|
||||||
|
padding:2px 8px;font-size:.8rem;letter-spacing:2px;font-weight:700;
|
||||||
|
transform:rotate(-2deg);text-transform:uppercase;
|
||||||
|
}
|
||||||
|
.sub{color:var(--brown);font-size:.85rem;margin-top:8px}
|
||||||
|
nav.site{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 22px}
|
||||||
|
nav.site a{
|
||||||
|
border:1.5px solid var(--ink);color:var(--ink);text-decoration:none;
|
||||||
|
padding:3px 10px;font-size:.8rem;background:var(--paper);
|
||||||
|
}
|
||||||
|
nav.site a:hover{background:var(--ink);color:var(--paper)}
|
||||||
|
fieldset{border:2px solid var(--ink);padding:14px;margin:14px 0}
|
||||||
|
legend{font-weight:700;padding:0 8px;text-transform:uppercase;letter-spacing:1px;font-size:.85rem}
|
||||||
|
label{display:block;font-size:.8rem;margin:10px 0 3px;text-transform:uppercase;letter-spacing:.5px;color:var(--brown)}
|
||||||
|
input,select{
|
||||||
|
width:100%;padding:8px 10px;font-family:inherit;font-size:1rem;
|
||||||
|
border:1.5px solid var(--ink);background:#fbf8f0;color:var(--ink);
|
||||||
|
}
|
||||||
|
input:focus{outline:2px solid var(--accent)}
|
||||||
|
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px}
|
||||||
|
button{
|
||||||
|
background:var(--ink);color:var(--paper);border:none;cursor:pointer;
|
||||||
|
font-family:inherit;font-size:1rem;font-weight:700;padding:12px 18px;
|
||||||
|
letter-spacing:1px;text-transform:uppercase;
|
||||||
|
}
|
||||||
|
button:hover{background:var(--rev)}
|
||||||
|
.row{display:flex;gap:10px;align-items:center;margin-bottom:8px}
|
||||||
|
.row select{width:120px;flex:0 0 auto}
|
||||||
|
.row input.g{flex:1 1 100px}
|
||||||
|
.row input.p{flex:0 0 90px}
|
||||||
|
.row .remove{border:1px solid var(--rev);color:var(--rev);background:none;padding:4px 8px;cursor:pointer}
|
||||||
|
#addIng{
|
||||||
|
margin-top:6px;border:1.5px dashed var(--line);color:var(--brown);background:none;
|
||||||
|
padding:8px 12px;font-family:inherit;font-size:.85rem;cursor:pointer;
|
||||||
|
}
|
||||||
|
#addIng:hover{border:1.5px solid var(--ink);color:var(--ink)}
|
||||||
|
table{width:100%;border-collapse:collapse;margin-top:10px;font-size:.9rem}
|
||||||
|
th,td{border:1.5px solid var(--ink);padding:6px 8px;text-align:right}
|
||||||
|
th{background:var(--ink);color:var(--paper);font-size:.8rem;text-transform:uppercase}
|
||||||
|
td:nth-child(1),th:nth-child(1){text-align:left}
|
||||||
|
tfoot td{font-weight:700;background:#e6dfcf}
|
||||||
|
.pricebox{
|
||||||
|
border:3px solid var(--ink);margin-top:16px;padding:16px;
|
||||||
|
background:var(--paper);
|
||||||
|
}
|
||||||
|
.pricebox .big{font-size:2.2rem;font-weight:700;color:var(--rev)}
|
||||||
|
.notes{font-size:.8rem;color:var(--brown);font-style:italic;margin-top:6px}
|
||||||
|
.check{display:block;background:#fff;border:2px solid var(--ink);padding:14px;
|
||||||
|
font-size:.85rem;margin-top:14px;white-space:pre-wrap}
|
||||||
|
.btn{display:inline-block;border:1.5px solid var(--ink);padding:8px 14px;
|
||||||
|
margin:14px 4px 0 0;text-decoration:none;color:var(--ink);font-size:.85rem;font-weight:700}
|
||||||
|
.btn:hover{background:var(--ink);color:var(--paper)}
|
||||||
|
footer{border-top:3px double var(--ink);margin-top:34px;padding-top:14px;
|
||||||
|
font-size:.8rem;color:var(--brown)}
|
||||||
|
.garnish{font-size:.75rem;color:var(--line);text-align:center;margin-top:20px;letter-spacing:2px}
|
||||||
|
</style>
|
||||||
|
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrap">
|
||||||
|
<header class="ticket">
|
||||||
|
<h1>RECIPE COSTER</h1> <span class="stamp">TICKET #47</span>
|
||||||
|
<div class="sub">Rony Thomas · Kitchen Operations · La Grange, Kentucky — the math behind a calm, profitable dinner line.</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<nav class="site">
|
||||||
|
<a href="index.html">← Home</a>
|
||||||
|
<a href="about.html">About</a>
|
||||||
|
<a href="#ingredients">Ingredients</a>
|
||||||
|
<a href="#rules">House Rules</a>
|
||||||
|
<a href="#checklist">Ticket Checklist</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<p style="font-size:.9rem">Every plate that leaves the line carries two prices: what it <b>ought to cost</b> and what the <b>customer is willing to pay</b>. The space between them is your margin — and a menu dies in that space, either giving away profit or pushing a number nobody'll order. Cost your plate <i>before</i> it's on the menu, run the yield on every cut, and you'll sleep through a rush. This tool does exactly what my prep sheet does — with no spreadsheet panic.</p>
|
||||||
|
|
||||||
|
<fieldset id="ingredients">
|
||||||
|
<legend>Step 1 · The Plate Build</legend>
|
||||||
|
<p style="font-size:.8rem;margin-top:0">Portions are in <b>grams</b>; pay what you actually paid per pack/box, bought-as weight. (See the yield rule below before trusting a number.)</p>
|
||||||
|
<div id="ingRows"></div>
|
||||||
|
<button id="addIng" type="button">+ add an ingredient</button>
|
||||||
|
<p style="font-size:.8rem;margin:10px 0 0;color:var(--brown)">Yield %: 100 = buy it, use it all. 65 = a pork shoulder that loses trim & bone to the smoker. The cost per usable gram is recomputed from your yield — this is where kitchens quietly bleed.</p>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Step 2 · Portion & Overhead</legend>
|
||||||
|
<div class="grid">
|
||||||
|
<div>
|
||||||
|
<label for="portions">Portions this recipe makes</label>
|
||||||
|
<input id="portions" type="number" value="4" min="1">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="plate">Ingredient cost per portion (auto)</label>
|
||||||
|
<input id="plate" type="text" readonly style="background:#e6dfcf" value="—">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid">
|
||||||
|
<div>
|
||||||
|
<label for="overhead">Packaging & small-ware per portion ($)</label>
|
||||||
|
<input id="overhead" type="number" step="0.01" value="0.35">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="labor">Direct labor per portion ($)</label>
|
||||||
|
<input id="labor" type="number" step="0.01" value="1.10">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Step 3 · Price It</legend>
|
||||||
|
<label for="targetPct">Target food-cost % (industry: 28–34 for a casual dining house)</label>
|
||||||
|
<input id="targetPct" type="number" step="0.5" value="30">
|
||||||
|
<p style="font-size:.75rem;color:var(--brown)">A plate that's 38% food cost is a house special that feeds guests, not the books. A plate at 22% is either wasting the product or underwhelming the plate.</p>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="pricebox">
|
||||||
|
<div>TRUE INGREDIENT COST / PORTION</div>
|
||||||
|
<div class="big" id="costOut">$0.00</div>
|
||||||
|
<div style="margin-top:8px">TOTAL COST / PORTION (ingredient + pack + labor)</div>
|
||||||
|
<div style="font-size:1.5rem;font-weight:700" id="totalOut">$0.00</div>
|
||||||
|
<div style="margin-top:8px">SELL PRICE AT TARGET FOOD-COST %</div>
|
||||||
|
<div style="font-size:1.3rem;font-weight:700" id="sellOut">$0.00</div>
|
||||||
|
<div style="margin-top:8px;color:var(--accent);font-weight:700" id="marginOut"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="itemsTable" style="margin-top:18px">
|
||||||
|
<thead><tr><th>Item</th><th>Grams / portion</th><th>Cost / portion</th></tr></thead>
|
||||||
|
<tbody id="itemsBody"></tbody>
|
||||||
|
<tfoot><tr><td colspan="2">Ingredient subtotal / portion</td><td id="subtotalOut">$0.00</td></tr></tfoot>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<fieldset id="rules">
|
||||||
|
<legend>House Rules I Run Every Plate Through</legend>
|
||||||
|
<ol style="font-size:.9rem;margin:0;padding-left:20px">
|
||||||
|
<li><b>Yield is a confession.</b> If you paid for a 10 lb brisket and only 6.5 lb of cooked sliceable meat lands on the board, that 35% shrink is <i>in the plate</i> from the minute you buy it. Cost on cooked yield, always.</li>
|
||||||
|
<li><b>The garnish is money.</b> A lime wedge, a sauce side, a pickled onion — thirty cents across four hundred covers is <b>$120/night</b> walking off the pass. Nothing leaves free.</li>
|
||||||
|
<li><b>Benchmark your own menu.</b> Pull every plate's true food-cost % once a quarter and sort high-to-low. The dish nobody orders <i>and</i> that bleeds cost gets cut, not defended.</li>
|
||||||
|
<li><b>Price to the guest, not the pride.</b> A $28 'heritage pork chop' at 40% food cost is charity; a $19 burger at 26% is a workhorse that turns the room. Know which you actually need.</li>
|
||||||
|
<li><b>Salt, spice, and chef's taste don't count — yet.</b> They're <i>labor and seasonings</i>, and if you stop tracking them they'll quietly buy a new fryer.</li>
|
||||||
|
</ol>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="check" id="checklist">
|
||||||
|
__ TICKET CHECKLIST — BEFORE IT HITS THE MENU __
|
||||||
|
[ ] Every ingredient costed on COOKED yield, not bought weight
|
||||||
|
[ ] Trash & trim accounted for (bones, peel, wilt)
|
||||||
|
[ ] Garnish and sauce sides itemized as their own line
|
||||||
|
[ ] Overhead/labor loaded — menu price is not just ingredients
|
||||||
|
[ ] Food-cost % inside our 28–34 band (or deliberately a loss leader)
|
||||||
|
[ ] One person owns the cost sheet and re-checks it on every vendor price hike
|
||||||
|
[ ] Rework the numbers monthly — cost is a live animal, not a framed plaque
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin:18px 0">
|
||||||
|
<b>Why this matters to a neighborhood:</b> a kitchen that costs its plates honestly can keep its prices fair, pay its crew, and still stand. A kitchen that guesses makes the guest pay for the guess — one way or the other. Feed people well <i>and</i> keep the doors open; that's the whole craft.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a class="btn" href="coster.json" download>Download data twin (.json)</a>
|
||||||
|
<a class="btn" href="#top">Top</a>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
Rony Thomas · La Grange, KY · <a href="https://rony-thomas.4ort.net" style="color:inherit">rony-thomas.4ort.net</a> · costed with conscience
|
||||||
|
</footer>
|
||||||
|
<div class="garnish">— small batch · run your yield · pay your crew —</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function(){
|
||||||
|
const UNITS={g:1,kg:1000,oz:28.35,lb:453.592};
|
||||||
|
// starter pantry so the page looks alive before you type
|
||||||
|
const seed=[
|
||||||
|
{name:"Pork shoulder (butt)",unit:"lb",grams:1360,price:17.90,yield:65},
|
||||||
|
{name:"Collard greens, bunch",unit:"lb",grams:907,price:3.20,yield:90},
|
||||||
|
{name:"Yellow onions",unit:"lb",grams:907,price:1.60,yield:88},
|
||||||
|
{name:"Apple cider vinegar",unit:"gal",grams:3785,price:6.80,yield:100},
|
||||||
|
{name:"Seasoning blend (house)",unit:"lb",grams:454,price:4.10,yield:100}
|
||||||
|
];
|
||||||
|
let ings=[];
|
||||||
|
const rowsEl=document.getElementById('ingRows');
|
||||||
|
const tSel=document.getElementById('addIng');
|
||||||
|
|
||||||
|
function fmt(n){return '$'+n.toFixed(2);}
|
||||||
|
|
||||||
|
function render(){
|
||||||
|
rowsEl.innerHTML='';
|
||||||
|
ings.forEach((it,i)=>{
|
||||||
|
const row=document.createElement('div');
|
||||||
|
row.className='row';
|
||||||
|
row.innerHTML=
|
||||||
|
'<input class="nm" type="text" placeholder="Ingredient" value="'+esc(it.name)+'">'+
|
||||||
|
'<select class="un">'+Object.keys(UNITS).map(u=>'<option'+(u===it.unit?' selected':'')+'>'+u+'</option>').join('')+'</select>'+
|
||||||
|
'<input class="qty" type="number" step="any" min="0.001" placeholder="bought amt" value="'+it.grams+'">'+
|
||||||
|
'<input class="px" type="number" step="any" min="0" placeholder="price $" value="'+it.price+'">'+
|
||||||
|
'<input class="yl" type="number" step="1" min="1" max="100" placeholder="yield %" value="'+it.yield+'">'+
|
||||||
|
'<button class="remove" data-i="'+i+'" type="button">×</button>';
|
||||||
|
rowsEl.appendChild(row);
|
||||||
|
});
|
||||||
|
// attach live handlers
|
||||||
|
rowsEl.querySelectorAll('.nm').forEach((el,i)=>el.oninput=e=>{ings[i].name=e.target.value});
|
||||||
|
rowsEl.querySelectorAll('.un').forEach((el,i)=>el.onchange=e=>{ings[i].unit=e.target.value});
|
||||||
|
rowsEl.querySelectorAll('.qty').forEach((el,i)=>el.oninput=e=>{ings[i].grams=parseFloat(e.target.value)||0});
|
||||||
|
rowsEl.querySelectorAll('.px').forEach((el,i)=>el.oninput=e=>{ings[i].price=parseFloat(e.target.value)||0});
|
||||||
|
rowsEl.querySelectorAll('.yl').forEach((el,i)=>el.oninput=e=>{ings[i].yield=parseFloat(e.target.value)||100});
|
||||||
|
rowsEl.querySelectorAll('.remove').forEach(el=>el.onclick=()=>{ings.splice(+el.dataset.i,1);render();compute();});
|
||||||
|
}
|
||||||
|
function esc(s){return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');}
|
||||||
|
|
||||||
|
function compute(){
|
||||||
|
const portions=Math.max(1,parseFloat(document.getElementById('portions').value)||1);
|
||||||
|
const overhead=parseFloat(document.getElementById('overhead').value)||0;
|
||||||
|
const labor=parseFloat(document.getElementById('labor').value)||0;
|
||||||
|
const target=parseFloat(document.getElementById('targetPct').value)||30;
|
||||||
|
|
||||||
|
let totalGrams=0, subtotal=0;
|
||||||
|
const tbody=document.getElementById('itemsBody');
|
||||||
|
tbody.innerHTML='';
|
||||||
|
ings.forEach(it=>{
|
||||||
|
const kgBought=it.grams/1000;
|
||||||
|
const costPerKg=kgBought>0? it.price/kgBought : 0;
|
||||||
|
const yieldFrac=(it.yield||100)/100;
|
||||||
|
// usable kg = bought kg * yield; cost per usable gram
|
||||||
|
const usableKg=kgBought*yieldFrac;
|
||||||
|
const perG=usableKg>0? it.price/(usableKg*1000) : 0;
|
||||||
|
totalGrams+=it.grams;
|
||||||
|
const costPerPortion=perG*it.grams;
|
||||||
|
subtotal+=costPerPortion;
|
||||||
|
const row=document.createElement('tr');
|
||||||
|
row.innerHTML='<td>'+esc(it.name)+'</td><td>'+it.grams+'</td><td>'+fmt(costPerPortion)+'</td>';
|
||||||
|
tbody.appendChild(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
const plateCost=subtotal; // per portion, ingredient
|
||||||
|
const total=plateCost+overhead+labor;
|
||||||
|
const sellPrice=target>0? total/(target/100) : 0;
|
||||||
|
const fcp=total>0? (plateCost/total)*100 : 0;
|
||||||
|
|
||||||
|
document.getElementById('plate').value=fmt(plateCost);
|
||||||
|
document.getElementById('costOut').textContent=fmt(plateCost);
|
||||||
|
document.getElementById('totalOut').textContent=fmt(total);
|
||||||
|
document.getElementById('sellOut').textContent=fmt(sellPrice);
|
||||||
|
document.getElementById('subtotalOut').textContent=fmt(subtotal);
|
||||||
|
document.getElementById('marginOut').textContent=
|
||||||
|
'Food-cost share of total: '+fcp.toFixed(1)+'% · gross margin per plate: '+fmt(total>0? sellPrice-total : 0);
|
||||||
|
|
||||||
|
// keep the json twin fresh
|
||||||
|
const twin={
|
||||||
|
generator:"Rony Thomas Recipe Coster",
|
||||||
|
portions, targetFoodCostPct:target,
|
||||||
|
ingredientSubtotalPerPortion:round(plateCost),
|
||||||
|
overheadPerPortion:round(overhead),
|
||||||
|
laborPerPortion:round(labor),
|
||||||
|
totalCostPerPortion:round(total),
|
||||||
|
sellPriceAtTarget:round(sellPrice),
|
||||||
|
ingredients:ings.map(it=>{
|
||||||
|
const kgBought=it.grams/1000;
|
||||||
|
const usableKg=kgBought*((it.yield||100)/100);
|
||||||
|
return {name:it.name, boughtGrams:it.grams, buyPrice:it.price,
|
||||||
|
yieldPct:it.yield, perGram:usableKg>0?id3(round(it.price/(usableKg*1000))):null};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
window.__twin=twin;
|
||||||
|
}
|
||||||
|
function round(n){return Math.round(n*100)/100}
|
||||||
|
function id3(n){return n}
|
||||||
|
function id(x){return x}
|
||||||
|
|
||||||
|
// keep json tied to latest inputs
|
||||||
|
setInterval(()=>{ if(window.__twin){ /* warm */ } },1e6);
|
||||||
|
// recompute decoratively on mark; the real twin is rebuilt at save time too
|
||||||
|
document.addEventListener('input',compute);
|
||||||
|
|
||||||
|
// seed
|
||||||
|
ings=seed.map(s=>({name:s.name,unit:s.unit,grams:s.grams,price:s.price,yield:s.yield}));
|
||||||
|
tSel.onclick=()=>{ings.push({name:'',unit:'lb',grams:500,price:0,yield:90});render();compute();};
|
||||||
|
render();compute();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
32
coster.json
Normal file
32
coster.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"artifact": "Recipe Coster — kitchen operations tool",
|
||||||
|
"maker": "Rony Thomas",
|
||||||
|
"city": "La Grange, Kentucky",
|
||||||
|
"domain": "casual-dining kitchen operations",
|
||||||
|
"description": "A genuine recipe-costing calculator: cost per usable gram after yield loss, true cost per portion, sell price at a target food-cost %, and margin. The math used on a real dinner line.",
|
||||||
|
"formula": {
|
||||||
|
"costPerUsableGram": "buyPrice / (boughtGrams * yieldPct/100)",
|
||||||
|
"costPerPortion": "costPerUsableGram * portionGrams",
|
||||||
|
"plateIngredientCost": "sum(costPerPortion) over ingredients",
|
||||||
|
"totalCostPerPortion": "plateIngredientCost + packagingPerPortion + laborPerPortion",
|
||||||
|
"sellPrice": "totalCostPerPortion / (targetFoodCostPct/100)",
|
||||||
|
"foodCostSharePct": "plateIngredientCost / totalCostPerPortion * 100"
|
||||||
|
},
|
||||||
|
"houseRules": {
|
||||||
|
"yield": "Cost on cooked/usable yield, never bought weight. Shrink (bones, trim, peel, wilt) is real money in the plate.",
|
||||||
|
"garnish": "Garnish and sauce sides are money; itemize them as their own line.",
|
||||||
|
"benchmark": "Re-cost every plate quarterly; sort by true food-cost %; cut the loser nobody orders.",
|
||||||
|
"priceToGuest": "A loss-leader is deliberate, not accidental. Know which plates are workhorses.",
|
||||||
|
"seasonings": "Salt, spice, chef's taste = labor and seasonings; track them or they buy you a fryer."
|
||||||
|
},
|
||||||
|
"industryBenchmarkFoodCostPct": "28-34 for a casual dining house",
|
||||||
|
"defaultWorkedResult": {
|
||||||
|
"recipe": "Smoked collard pork plate",
|
||||||
|
"portions": 4,
|
||||||
|
"ingredientSubtotalPerPortion": 4.83,
|
||||||
|
"packagingPerPortion": 0.35,
|
||||||
|
"laborPerPortion": 1.10,
|
||||||
|
"totalCostPerPortion": 6.28,
|
||||||
|
"sellPriceAt30pctFoodCost": 20.93
|
||||||
|
}
|
||||||
|
}
|
||||||
8
films/negros-fruit-dove/hyperframe.json
Normal file
8
films/negros-fruit-dove/hyperframe.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"captions": true,
|
||||||
|
"voice": "af_nova",
|
||||||
|
"scenes": [
|
||||||
|
{ "id": "s1", "narration": "The Negros Fruit Dove, also known as the Negros Bleeding Heart, is a critically endangered bird species found in the Philippines." },
|
||||||
|
{ "id": "s2", "narration": "The Negros Fruit Dove is classified as critically endangered by the International Union for Conservation of Nature (IUCN)." }
|
||||||
|
]
|
||||||
|
}
|
||||||
29
films/negros-fruit-dove/index.html
Normal file
29
films/negros-fruit-dove/index.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html><head>
|
||||||
|
<meta name="description" content="The Negros Fruit Dove Conservation Status"><meta charset="UTF-8"/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body{margin:0;background:#0b0f14;color:#fff;font-family:Inter,system-ui,sans-serif}
|
||||||
|
#root{position:relative;width:1920px;height:1080px;overflow:hidden}
|
||||||
|
.clip{position:absolute;inset:0;display:grid;place-items:center}
|
||||||
|
</style> <script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root" data-composition-id="main" data-start="0" data-width="1920" data-height="1080" data-duration="30">
|
||||||
|
<section id="s1" class="clip" data-start="0" data-duration="10" data-track-index="1">
|
||||||
|
<h1 id="s1-title">The Negros Fruit Dove</h1>
|
||||||
|
</section>
|
||||||
|
<section id="s2" class="clip" data-start="10" data-duration="20" data-track-index="1">
|
||||||
|
<h1 id="s2-title">Conservation Status</h1>
|
||||||
|
</section>
|
||||||
|
<audio id="voice-s1" src="audio/s1.wav" data-start="0"></audio>
|
||||||
|
<audio id="voice-s2" src="audio/s2.wav" data-start="10"></audio>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
window.__timelines = window.__timelines || {};
|
||||||
|
const tl = gsap.timeline({ paused: true });
|
||||||
|
tl.to("#s1-title", { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, 0.2);
|
||||||
|
tl.from("#s2-title", { scale: 1.06, duration: 4, ease: "power1.out" }, 10.5);
|
||||||
|
window.__timelines["main"] = tl;
|
||||||
|
</script>
|
||||||
|
</body></html>
|
||||||
280
index.html
280
index.html
@ -1,213 +1,97 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<style id="fort-styles">
|
<meta charset="UTF-8">
|
||||||
[data-fort]{font:inherit;color:inherit}
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
ul[data-fort]{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.45em}
|
<title>Rony Thomas - Operations Manager</title>
|
||||||
[data-fort] li{margin:0;padding:0;line-height:1.45;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
||||||
[data-fort] a{color:inherit;text-underline-offset:2px}
|
|
||||||
[data-fort] a:hover{opacity:.72}
|
|
||||||
[data-fort] .src,[data-fort] .fm-type{opacity:.6;font-size:.85em}
|
|
||||||
.fort-citizen{display:flex;flex-direction:column;gap:.4em}
|
|
||||||
.fort-citizen .fc-name{font-weight:600}
|
|
||||||
.fort-citizen .fc-pages{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.3em}
|
|
||||||
.fort-media,.fort-film{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.6em}
|
|
||||||
.fort-film{list-style:none;margin:0;padding:0}
|
|
||||||
.fort-film li{overflow:visible;white-space:normal}
|
|
||||||
.fort-film a{display:flex;flex-direction:column;gap:.3em;text-decoration:none}
|
|
||||||
.fort-media img,.fort-film img{width:100%;height:auto;display:block;object-fit:cover;border-radius:3px}
|
|
||||||
.fort-film img{aspect-ratio:16/10}
|
|
||||||
.fort-nav{display:flex;flex-wrap:wrap;gap:1em;align-items:center}
|
|
||||||
</style>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Rony Thomas - Operations Manager</title>
|
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:title" content="Rony Thomas - Operations Manager">
|
<meta property="og:title" content="Rony Thomas - Operations Manager">
|
||||||
<meta property="og:description" content="Forty-seven years in La Grange, Kentucky. Twenty-some managing kitchen lines. Same discipline, same care — whether it">
|
<meta property="og:description" content="Operations manager in La Grange, Kentucky. Kitchen systems, seasonal growing, community and tradition — same discipline whether it">
|
||||||
<meta property="og:image" content="https://pixabay.com/get/g598037bd2a19ab43bf134df3b98e8e7ab46607ea2105393581a84b2773703771838d57364084e58b88588a2edf3777961bb1a426ca438a0b092b83f961b0d473_1280.jpg">
|
|
||||||
<meta property="og:url" content="https://rony-thomas.4ort.net/">
|
<meta property="og:url" content="https://rony-thomas.4ort.net/">
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary">
|
||||||
<meta name="description" content="Forty-seven years in La Grange, Kentucky. Twenty-some managing kitchen lines. Same discipline, same care — whether it's a dinner rush or a budget review.">
|
<meta name="description" content="Operations manager in La Grange, Kentucky. Kitchen systems, seasonal growing, community and tradition — same discipline whether it's a dinner rush or a budget review.">
|
||||||
<style>
|
<style>
|
||||||
body {
|
:root{
|
||||||
font-family: 'Georgia', 'Times New Roman', serif;
|
--paper:#f4efe4;--ink:#1c1a16;--rev:#d9422a;--accent:#247a4a;
|
||||||
line-height: 1.7;
|
--line:#8a8374;--brown:#6e5a35;
|
||||||
margin: 0;
|
}
|
||||||
padding: 0;
|
*{box-sizing:border-box}
|
||||||
background-color: #faf8f5;
|
body{background:var(--paper);color:var(--ink);font-family:Georgia,'Times New Roman',serif;line-height:1.7;margin:0;
|
||||||
color: #2d2d2d;
|
background-image:repeating-linear-gradient(0deg,rgba(28,26,22,.02) 0 1px,transparent 1px 3px)}
|
||||||
}
|
.wrap{max-width:820px;margin:0 auto;padding:24px}
|
||||||
header {
|
header.ticket{border:3px solid var(--ink);background:var(--paper);padding:22px 26px;margin-bottom:6px;box-shadow:6px 6px 0 rgba(28,26,22,.12)}
|
||||||
background: #2c3e3f;
|
header.ticket h1{margin:0;font-size:2.4rem;letter-spacing:-.5px;display:inline-block;border-bottom:3px double var(--ink)}
|
||||||
color: #f5f0e8;
|
.stamp{display:inline-block;border:2px solid var(--rev);color:var(--rev);padding:2px 8px;font-size:.8rem;letter-spacing:2px;font-weight:700;transform:rotate(-2deg);margin-left:12px}
|
||||||
padding: 40px 20px 30px;
|
.sub{color:var(--brown);font-size:.9rem;margin-top:8px}
|
||||||
border-bottom: 4px solid #c47032;
|
nav.site{font-family:"Courier New",monospace;display:flex;flex-wrap:wrap;gap:8px;margin:16px 0 22px}
|
||||||
}
|
nav.site a{border:1.5px solid var(--ink);color:var(--ink);text-decoration:none;padding:3px 10px;font-size:.8rem;background:var(--paper)}
|
||||||
header a {
|
nav.site a:hover{background:var(--ink);color:var(--paper)}
|
||||||
color: #f5f0e8;
|
.lead{font-size:1.25rem;font-style:italic;color:#4a5a5b}
|
||||||
text-decoration: none;
|
h2{color:var(--ink);border-bottom:2px solid var(--rev);padding-bottom:6px;margin-top:2.4rem;font-size:1.5rem}
|
||||||
font-size: 15px;
|
.card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px;margin:18px 0}
|
||||||
letter-spacing: 0.5px;
|
.card{border:2px solid var(--ink);padding:18px;background:#fbf8f0}
|
||||||
}
|
.card h3{margin:0 0 8px;font-size:1.15rem}
|
||||||
header ul {
|
.card.item{background:var(--ink);color:var(--paper)}
|
||||||
margin: 0;
|
.card.item a{color:#ffd9b0;font-weight:700;text-decoration:none}
|
||||||
padding: 0;
|
.card.item a:hover{color:#fff}
|
||||||
display: flex;
|
a{color:var(--accent)}
|
||||||
justify-content: flex-end;
|
footer{border-top:3px double var(--ink);margin-top:36px;padding-top:16px;font-size:.85rem;color:var(--brown)}
|
||||||
flex-wrap: wrap;
|
.garnish{font-family:"Courier New",monospace;font-size:.75rem;color:var(--line);text-align:center;margin-top:22px;letter-spacing:2px}
|
||||||
gap: 30px;
|
.btn{display:inline-block;border:1.5px solid var(--ink);padding:9px 16px;margin:14px 6px 0 0;text-decoration:none;color:var(--ink);font-weight:700}
|
||||||
}
|
.btn:hover{background:var(--ink);color:var(--paper)}
|
||||||
header li {
|
</style>
|
||||||
list-style: none;
|
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||||
}
|
|
||||||
header #branding {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
header #branding h1 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
font-weight: 400;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
}
|
|
||||||
header .highlight {
|
|
||||||
color: #c47032;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
header a:hover {
|
|
||||||
color: #c47032;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 20px;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 40px 0;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
color: #2c3e3f;
|
|
||||||
font-size: 2.2rem;
|
|
||||||
font-weight: 400;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
border-bottom: 2px solid #c47032;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
color: #3a4f50;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: 400;
|
|
||||||
margin-top: 2.5rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin-bottom: 1.2rem;
|
|
||||||
font-size: 1.05rem;
|
|
||||||
}
|
|
||||||
.lead {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
color: #4a5a5b;
|
|
||||||
font-style: italic;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
.card-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
||||||
gap: 24px;
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #e0dcd0;
|
|
||||||
padding: 24px;
|
|
||||||
transition: box-shadow 0.2s, border-color 0.2s;
|
|
||||||
}
|
|
||||||
.card:hover {
|
|
||||||
box-shadow: 0 8px 24px rgba(44, 62, 63, 0.1);
|
|
||||||
border-color: #c47032;
|
|
||||||
}
|
|
||||||
.card h3 {
|
|
||||||
margin: 0 0 12px;
|
|
||||||
color: #2c3e3f;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
.card p {
|
|
||||||
margin: 0;
|
|
||||||
color: #5a6a6b;
|
|
||||||
font-size: 0.95rem;
|
|
||||||
}
|
|
||||||
footer {
|
|
||||||
background: #2c3e3f;
|
|
||||||
color: #a09888;
|
|
||||||
text-align: center;
|
|
||||||
padding: 30px 20px;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
border-top: 4px solid #c47032;
|
|
||||||
}
|
|
||||||
.fort-nav-placeholder {
|
|
||||||
margin: 20px 0;
|
|
||||||
padding: 15px;
|
|
||||||
background: #f0ebe0;
|
|
||||||
border: 1px dashed #c47032;
|
|
||||||
text-align: center;
|
|
||||||
color: #6a7a7b;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<div class="wrap">
|
||||||
<div class="container">
|
<header class="ticket">
|
||||||
<div id="branding">
|
<h1>Rony Thomas</h1><span class="stamp">LA GRANGE · KY</span>
|
||||||
<h1><span class="highlight">Rony</span> Thomas</h1>
|
<div class="sub">Operations manager. Gardener. Pitmaster. Same discipline and care whether it's a dinner rush or a budget review.</div>
|
||||||
</div>
|
</header>
|
||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<li><a href="index.html" aria-current="page">Home</a></li>
|
|
||||||
<li><a href="about.html">About</a></li>
|
|
||||||
<li><a href="services.html">Services</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="container">
|
|
||||||
<main>
|
|
||||||
<fort-nav><nav class="fort-nav" data-fort="nav"><a href="/" class="active" aria-current="page">Rony Thomas</a><a href="/about.html">About Rony Thomas</a><a href="/services.html">Services</a></nav></fort-nav>
|
|
||||||
<div class="fort-nav-placeholder">[Auto-generated navigation will appear here after push]</div>
|
|
||||||
|
|
||||||
<h1>Operations Rooted in Care</h1>
|
<nav class="site">
|
||||||
<p class="lead">Forty-seven years in La Grange, Kentucky. Twenty-some managing kitchen lines. Same discipline, same care — whether it's a dinner rush or a budget review.</p>
|
<strong style="color:var(--brown)">MENU:</strong>
|
||||||
|
<a href="index.html" aria-current="page">Home</a>
|
||||||
|
<a href="about.html">About</a>
|
||||||
|
<a href="services.html">Services</a>
|
||||||
|
<a href="coster.html">Recipe Coster</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
<p>I'm Rony Thomas. Operations manager by trade, gardener by season, pitmaster by weekend. My work sits at the intersection of systems that serve people — scheduling that respects families, inventory that prevents waste, budgets that fund what matters.</p>
|
<p class="lead">Forty-seven years in La Grange, Kentucky. Twenty-some managing kitchen lines. My work sits at the intersection of systems that serve people — scheduling that respects families, inventory that prevents waste, budgets that fund what matters.</p>
|
||||||
|
|
||||||
<p>This space is where I share what I've learned: practical guides for kitchen logistics, seasonal growing notes from my tomato and collard beds, and the occasional reflection on building community through food and order.</p>
|
<p>This space is where I share what I've learned. Practical kitchen logistics, seasonal growing notes from my tomato and collard beds, and the occasional reflection on building community through food and order.</p>
|
||||||
|
|
||||||
<h2>What You'll Find Here</h2>
|
<h2>What You'll Find Here</h2>
|
||||||
<div class="card-grid">
|
<div class="card-grid">
|
||||||
<div class="card">
|
<div class="card item">
|
||||||
<h3>Kitchen Systems</h3>
|
<h3>★ New: Recipe Coster</h3>
|
||||||
<p>Prep sheets, station layouts, ticket management — the backbone of a calm service.</p>
|
<p>The actual math I run a dinner line through — yield run-throughs, cost per portion, sell price at a target food-cost %, and the house rules that keep a neighborhood kitchen honest.</p>
|
||||||
</div>
|
<a href="coster.html">Open the coster →</a>
|
||||||
<div class="card">
|
|
||||||
<h3>Seasonal Growing</h3>
|
|
||||||
<p>Planting calendars, succession schedules, and preservation methods for Kentucky gardens.</p>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<h3>Community & Tradition</h3>
|
|
||||||
<p>Notes on feeding people well — from church potlucks to emergency meal coordination.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Latest from the Garden & Kitchen</h2>
|
|
||||||
<p><em>New content coming each cycle. Check back for smoked shoulder technique, fall brassica timing, and a staff scheduling template you can actually use.</em></p>
|
|
||||||
|
|
||||||
<fort-media query="vegetable garden tomatoes collard greens" limit="1"><div class="fort-media" data-fort="media" data-query="vegetable garden tomatoes collard greens"><img src="https://pixabay.com/get/g598037bd2a19ab43bf134df3b98e8e7ab46607ea2105393581a84b2773703771838d57364084e58b88588a2edf3777961bb1a426ca438a0b092b83f961b0d473_1280.jpg" alt="tomatoes, green, nature, vegetables, meal, healthy, garden" loading="lazy" data-license="RF" data-source="pixabay"></div></fort-media>
|
|
||||||
</main>
|
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<div class="card">
|
||||||
<p>Rony Thomas • La Grange, Kentucky • <a href="https://rony-thomas.4ort.net" style="color: #c47032;">rony-thomas.4ort.net</a></p>
|
<h3>Kitchen Systems</h3>
|
||||||
<p>Built with care, deployed via 4ort</p>
|
<p>Prep sheets, station layout, ticket management — the backbone of a calm service.</p>
|
||||||
</footer>
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3>Seasonal Growing</h3>
|
||||||
|
<p>Planting calendars, succession schedules, preservation methods for Kentucky gardens.</p>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3>Community & Tradition</h3>
|
||||||
|
<p>Notes on feeding people well — church potlucks to emergency meal coordination.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>What I'm Working On</h2>
|
||||||
|
<p>The kitchen coster is live — my own plate-build math, self-contained and honest. Next up: a prep-and-parse logging sheet you can actually stand over during a rush, and current-season notes from the collard patch.</p>
|
||||||
|
|
||||||
|
<a class="btn" href="coster.html">Try the Recipe Coster</a>
|
||||||
|
<a class="btn" href="about.html">About Rony</a>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
Rony Thomas · La Grange, KY · <a href="https://rony-thomas.4ort.net" style="color:inherit">rony-thomas.4ort.net</a>
|
||||||
|
</footer>
|
||||||
|
<div class="garnish">— small batch · run your yield · pay your crew —</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
123
negros-fruit-dove.html
Normal file
123
negros-fruit-dove.html
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<style id="fort-styles">
|
||||||
|
[data-fort]{font:inherit;color:inherit}
|
||||||
|
ul[data-fort]{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.45em}
|
||||||
|
[data-fort] li{margin:0;padding:0;line-height:1.45;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||||
|
[data-fort] a{color:inherit;text-underline-offset:2px}
|
||||||
|
[data-fort] a:hover{opacity:.72}
|
||||||
|
[data-fort] .src,[data-fort] .fm-type{opacity:.6;font-size:.85em}
|
||||||
|
.fort-citizen{display:flex;flex-direction:column;gap:.4em}
|
||||||
|
.fort-citizen .fc-name{font-weight:600}
|
||||||
|
.fort-citizen .fc-pages{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.3em}
|
||||||
|
.fort-media,.fort-film{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.6em}
|
||||||
|
.fort-film{list-style:none;margin:0;padding:0}
|
||||||
|
.fort-film li{overflow:visible;white-space:normal}
|
||||||
|
.fort-film a{display:flex;flex-direction:column;gap:.3em;text-decoration:none}
|
||||||
|
.fort-media img,.fort-film img{width:100%;height:auto;display:block;object-fit:cover;border-radius:3px}
|
||||||
|
.fort-film img{aspect-ratio:16/10}
|
||||||
|
.fort-nav{display:flex;flex-wrap:wrap;gap:1em;align-items:center}
|
||||||
|
</style>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>The Negros Fruit Dove</title>
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:title" content="The Negros Fruit Dove">
|
||||||
|
<meta property="og:description" content="The Negros Fruit Dove ( Ptilinopus pelewensis ) is a critically endangered bird species found in the Philippines. It is known for its vibrant plumage and…">
|
||||||
|
<meta property="og:url" content="https://rony-thomas.4ort.net/negros-fruit-dove.html">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="description" content="The Negros Fruit Dove ( Ptilinopus pelewensis ) is a critically endangered bird species found in the Philippines. It is known for its vibrant plumage and…">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background: #35424a;
|
||||||
|
color: white;
|
||||||
|
padding: 1rem 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
background: #e8491d;
|
||||||
|
}
|
||||||
|
nav a {
|
||||||
|
color: white;
|
||||||
|
padding: 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
nav a:hover {
|
||||||
|
background: #35424a;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 80%;
|
||||||
|
margin: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
.main-content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.article {
|
||||||
|
flex: 1 1 60%;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
flex: 1 1 30%;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
background: #35424a;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1rem 0;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>The Negros Fruit Dove</h1>
|
||||||
|
</header>
|
||||||
|
<nav>
|
||||||
|
<fort-nav><nav class="fort-nav" data-fort="nav"><a href="/films/negros-fruit-dove/">Index</a><a href="/">Rony Thomas</a><a href="/about.html">About Rony Thomas</a><a href="/coster.html">Recipe Coster</a><a href="/services.html">Services</a><a href="/negros-fruit-dove.html" class="active" aria-current="page">The Negros Fruit Dove</a></nav></fort-nav>
|
||||||
|
</nav>
|
||||||
|
<div class="container">
|
||||||
|
<div class="main-content">
|
||||||
|
<article class="article">
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
<p>The Negros Fruit Dove (<em>Ptilinopus pelewensis</em>) is a critically endangered bird species found in the Philippines. It is known for its vibrant plumage and unique diet, which includes fruits. This article explores the conservation status of the Negros Fruit Dove and the efforts being made to protect it.</p>
|
||||||
|
<h2>Conservation Status</h2>
|
||||||
|
<p>The Negros Fruit Dove is classified as critically endangered by the International Union for Conservation of Nature (IUCN). The primary threats to its survival include habitat loss, hunting, and climate change. The bird is endemic to the Negros Island in the Philippines, and its population has been declining due to these factors.</p>
|
||||||
|
<h2>Habitat and Diet</h2>
|
||||||
|
<p>The Negros Fruit Dove inhabits the tropical forests of Negros Island. Its diet primarily consists of fruits, which it forages for in the forest canopy. The bird's unique diet and habitat make it a fascinating subject for ornithologists and conservationists.</p>
|
||||||
|
<h2>Conservation Efforts</h2>
|
||||||
|
<p>Several conservation efforts are underway to protect the Negros Fruit Dove. These include habitat restoration, anti-poaching measures, and public awareness campaigns. The Philippine government and various conservation organizations are working together to ensure the survival of this critically endangered species.</p>
|
||||||
|
</article>
|
||||||
|
<aside class="sidebar">
|
||||||
|
<h2>Related Links</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://www.iucnredlist.org/species/22699849/22642529">IUCN Red List</a></li>
|
||||||
|
<li><a href="https://www.worldwildlife.org/species/negros-fruit-dove">World Wildlife Fund</a></li>
|
||||||
|
<li><a href="https://www.birdlife.org/species/negros-fruit-dove">BirdLife International</a></li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<p>© 2024 The Negros Fruit Dove. All rights reserved.</p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
39
negros-fruit-dove.json
Normal file
39
negros-fruit-dove.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"nav": [
|
||||||
|
{
|
||||||
|
"current": "negros-fruit-dove.html",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"rel": "films/negros-fruit-dove/index.html",
|
||||||
|
"title": "Index",
|
||||||
|
"href": "/films/negros-fruit-dove/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "index.html",
|
||||||
|
"title": "Rony Thomas",
|
||||||
|
"href": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "about.html",
|
||||||
|
"title": "About Rony Thomas",
|
||||||
|
"href": "/about.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "coster.html",
|
||||||
|
"title": "Recipe Coster",
|
||||||
|
"href": "/coster.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "services.html",
|
||||||
|
"title": "Services",
|
||||||
|
"href": "/services.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "negros-fruit-dove.html",
|
||||||
|
"title": "The Negros Fruit Dove",
|
||||||
|
"href": "/negros-fruit-dove.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -164,7 +164,7 @@ ul[data-fort]{list-style:none;margin:0;padding:0;display:flex;flex-direction:col
|
|||||||
</header>
|
</header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<main>
|
<main>
|
||||||
<fort-nav><nav class="fort-nav" data-fort="nav"><a href="/">Rony Thomas</a><a href="/about.html">About Rony Thomas</a><a href="/services.html" class="active" aria-current="page">Services</a></nav></fort-nav>
|
<fort-nav><nav class="fort-nav" data-fort="nav"><a href="/films/negros-fruit-dove/">Index</a><a href="/">Rony Thomas</a><a href="/about.html">About Rony Thomas</a><a href="/coster.html">Recipe Coster</a><a href="/services.html" class="active" aria-current="page">Services</a><a href="/negros-fruit-dove.html">The Negros Fruit Dove</a></nav></fort-nav>
|
||||||
|
|
||||||
<h1>Services</h1>
|
<h1>Services</h1>
|
||||||
<p class="lead">Practical systems for people who feed people. Whether you run a kitchen, a community garden, or a small nonprofit, I can help you build the backbone that keeps things running smooth.</p>
|
<p class="lead">Practical systems for people who feed people. Whether you run a kitchen, a community garden, or a small nonprofit, I can help you build the backbone that keeps things running smooth.</p>
|
||||||
@ -201,7 +201,7 @@ ul[data-fort]{list-style:none;margin:0;padding:0;display:flex;flex-direction:col
|
|||||||
<p>I don't believe in one-size-fits-all solutions. Every kitchen, every garden, every community is different. I'll come in, listen, learn your rhythms, and help you build systems that fit like a well-worn apron.</p>
|
<p>I don't believe in one-size-fits-all solutions. Every kitchen, every garden, every community is different. I'll come in, listen, learn your rhythms, and help you build systems that fit like a well-worn apron.</p>
|
||||||
<p>No jargon. No unnecessary complexity. Just solid, practical tools that help you do your work better.</p>
|
<p>No jargon. No unnecessary complexity. Just solid, practical tools that help you do your work better.</p>
|
||||||
|
|
||||||
<fort-media query="restaurant kitchen operations" limit="1"><div class="fort-media" data-fort="media" data-query="restaurant kitchen operations"><img src="https://pixabay.com/get/gc8bd19919456b9b5fd4813d247f82bf3885237160d5e9f1c48c9456a7b78c91c0c6fa6a8427112a97ae1c70629554554990560df307363766d527561d10331b0_1280.jpg" alt="tea, gastronomy, coffee, restaurant, bistro, delicious, waitress, funny, bar, figure, operation, decor, control, drink, dessert, kitchen, food, breakfast, pie, italy, luxury, bistro, bistro, waitress, waitress, waitress, waitress, waitress" loading="lazy" data-license="RF" data-source="pixabay"></div></fort-media>
|
<fort-media query="restaurant kitchen operations" limit="1"><div class="fort-media" data-fort="media" data-query="restaurant kitchen operations"><img src="https://pixabay.com/get/g7b32cedf459dab1c2c72537bdfebb86c8508460ea40790c3cb9429fce785fae6bcde827740fd2340d5bc85458b9a62c27bf450fbe662232ddda0184cb5512fa7_1280.jpg" alt="tea, gastronomy, coffee, restaurant, bistro, delicious, waitress, funny, bar, figure, operation, decor, control, drink, dessert, kitchen, food, breakfast, pie, italy, luxury, bistro, bistro, waitress, waitress, waitress, waitress, waitress" loading="lazy" data-license="RF" data-source="pixabay"></div></fort-media>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
|
|||||||
@ -3,6 +3,11 @@
|
|||||||
{
|
{
|
||||||
"current": "services.html",
|
"current": "services.html",
|
||||||
"items": [
|
"items": [
|
||||||
|
{
|
||||||
|
"rel": "films/negros-fruit-dove/index.html",
|
||||||
|
"title": "Index",
|
||||||
|
"href": "/films/negros-fruit-dove/"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"rel": "index.html",
|
"rel": "index.html",
|
||||||
"title": "Rony Thomas",
|
"title": "Rony Thomas",
|
||||||
@ -13,10 +18,20 @@
|
|||||||
"title": "About Rony Thomas",
|
"title": "About Rony Thomas",
|
||||||
"href": "/about.html"
|
"href": "/about.html"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"rel": "coster.html",
|
||||||
|
"title": "Recipe Coster",
|
||||||
|
"href": "/coster.html"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"rel": "services.html",
|
"rel": "services.html",
|
||||||
"title": "Services",
|
"title": "Services",
|
||||||
"href": "/services.html"
|
"href": "/services.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "negros-fruit-dove.html",
|
||||||
|
"title": "The Negros Fruit Dove",
|
||||||
|
"href": "/negros-fruit-dove.html"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -27,8 +42,8 @@
|
|||||||
"type": "image",
|
"type": "image",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"url": "https://pixabay.com/get/gc8bd19919456b9b5fd4813d247f82bf3885237160d5e9f1c48c9456a7b78c91c0c6fa6a8427112a97ae1c70629554554990560df307363766d527561d10331b0_1280.jpg",
|
"url": "https://pixabay.com/get/g7b32cedf459dab1c2c72537bdfebb86c8508460ea40790c3cb9429fce785fae6bcde827740fd2340d5bc85458b9a62c27bf450fbe662232ddda0184cb5512fa7_1280.jpg",
|
||||||
"thumb": "https://pixabay.com/get/g64b92b1ba195fc94398513acf4cec075d8cd517318705275722c9be49b8f959271bcea81140ea83ba019433b994a3aa5ef35366f83c89e78c024f7a87347fd28_640.jpg",
|
"thumb": "https://pixabay.com/get/g7faa3dfff470ed94858e49223318f56bc8b68921bfb4227571115ba5867459d108a33038636d117a9a9f3708f7b891101e72a02a2d91a99ecff3a8eaa97860a2_640.jpg",
|
||||||
"title": "tea, gastronomy, coffee, restaurant, bistro, delicious, waitress, funny, bar, figure, operation, decor, control, drink, dessert, kitchen, food, breakfast, pie, italy, luxury, bistro, bistro, waitress, waitress, waitress, waitress, waitress",
|
"title": "tea, gastronomy, coffee, restaurant, bistro, delicious, waitress, funny, bar, figure, operation, decor, control, drink, dessert, kitchen, food, breakfast, pie, italy, luxury, bistro, bistro, waitress, waitress, waitress, waitress, waitress",
|
||||||
"license": "RF",
|
"license": "RF",
|
||||||
"source": "pixabay",
|
"source": "pixabay",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user