Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -144,17 +144,17 @@ BREED_INFO = {
|
|
| 144 |
"Ross 308": {
|
| 145 |
"description": "Big chest, thick legs, very fast growth. Excellent for meat production.",
|
| 146 |
"available_at": "Agrited, Sayed, Valentine",
|
| 147 |
-
"color": "#
|
| 148 |
},
|
| 149 |
"Cobb 500": {
|
| 150 |
"description": "Good early growth, strong legs, solid feed conversion.",
|
| 151 |
"available_at": "Chikun, Zartech",
|
| 152 |
-
"color": "#
|
| 153 |
},
|
| 154 |
"Arbor Acres": {
|
| 155 |
"description": "Balanced growth, hardy and adaptable. Great survival rate.",
|
| 156 |
"available_at": "Supreme, CHI, GS, Vertex, Fidan, Cascada, Orobor, Sunchi, Farm Support, Ajila",
|
| 157 |
-
"color": "#
|
| 158 |
}
|
| 159 |
}
|
| 160 |
|
|
@@ -571,7 +571,7 @@ def get_share_links(app_url="https://howmuchfeed.com"):
|
|
| 571 |
|
| 572 |
|
| 573 |
# ============================================================
|
| 574 |
-
# FEED CALCULATION -
|
| 575 |
# ============================================================
|
| 576 |
|
| 577 |
def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_code, breed, request: gr.Request):
|
|
@@ -645,7 +645,7 @@ def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_c
|
|
| 645 |
# Generate share links
|
| 646 |
share_links = get_share_links()
|
| 647 |
|
| 648 |
-
# Output HTML -
|
| 649 |
starter_bags_display = f"{starter_bags:.1f}"
|
| 650 |
finisher_bags_display = f"{finisher_bags:.1f}"
|
| 651 |
|
|
@@ -656,21 +656,23 @@ def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_c
|
|
| 656 |
html = f"""
|
| 657 |
<div style="
|
| 658 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
| 659 |
-
font-size:
|
| 660 |
line-height: 1.5;
|
| 661 |
-
color: #
|
| 662 |
-
background: #
|
| 663 |
border-radius: 12px;
|
| 664 |
-
padding:
|
| 665 |
-
border: 1px solid #
|
| 666 |
width: 100%;
|
|
|
|
| 667 |
box-sizing: border-box;
|
|
|
|
| 668 |
">
|
| 669 |
|
| 670 |
<!-- RESULTS CARD -->
|
| 671 |
<div style="
|
| 672 |
-
background: #
|
| 673 |
-
border: 2px solid #
|
| 674 |
border-radius: 10px;
|
| 675 |
padding: 14px 16px;
|
| 676 |
margin-bottom: 14px;
|
|
@@ -678,155 +680,168 @@ def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_c
|
|
| 678 |
<div style="
|
| 679 |
font-size: 12px;
|
| 680 |
font-weight: 700;
|
| 681 |
-
color: #
|
| 682 |
text-transform: uppercase;
|
| 683 |
letter-spacing: 0.5px;
|
| 684 |
-
margin-bottom:
|
| 685 |
">π Your Feed Estimate</div>
|
| 686 |
|
| 687 |
-
<!-- Total Feed -
|
| 688 |
-
<div style="
|
| 689 |
-
|
| 690 |
-
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
Total Feed
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
</div>
|
| 700 |
-
<div style="
|
| 701 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
</div>
|
| 703 |
</div>
|
| 704 |
|
| 705 |
<!-- Birds Info -->
|
| 706 |
-
<div style="font-size:
|
| 707 |
-
For <strong>{birds:,}</strong> {breed} broilers Β· <strong>{age_text}
|
| 708 |
</div>
|
| 709 |
|
| 710 |
-
<!-- Buy Recommendation -
|
| 711 |
<div style="
|
| 712 |
background: #FFF8E1;
|
| 713 |
border: 2px solid #FFB800;
|
| 714 |
border-radius: 8px;
|
| 715 |
-
padding:
|
| 716 |
-
margin-top:
|
| 717 |
">
|
| 718 |
-
<
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 729 |
</div>
|
| 730 |
</div>
|
| 731 |
|
| 732 |
<!-- FEED BREAKDOWN TABLE -->
|
| 733 |
<div style="margin-bottom: 12px;">
|
| 734 |
-
<div style="font-size: 12px; font-weight: 700; color: #
|
| 735 |
<table style="
|
| 736 |
width: 100%;
|
| 737 |
border-collapse: collapse;
|
| 738 |
-
font-size:
|
| 739 |
-
background: #
|
| 740 |
-
border: 1px solid #
|
| 741 |
border-radius: 8px;
|
| 742 |
overflow: hidden;
|
| 743 |
">
|
| 744 |
<thead>
|
| 745 |
-
<tr style="background: #
|
| 746 |
-
<th style="padding: 8px 10px; text-align: left; font-weight: 600; color: #
|
| 747 |
-
<th style="padding: 8px 10px; text-align: right; font-weight: 600; color: #
|
| 748 |
-
<th style="padding: 8px 10px; text-align: right; font-weight: 600; color: #
|
| 749 |
</tr>
|
| 750 |
</thead>
|
| 751 |
<tbody>
|
| 752 |
-
<tr style="border-bottom: 1px solid #
|
| 753 |
-
<td style="padding: 8px 10px; color: #
|
| 754 |
-
<td style="padding: 8px 10px; text-align: right; color: #
|
| 755 |
-
<td style="padding: 8px 10px; text-align: right; font-weight: 700; color: #
|
| 756 |
</tr>
|
| 757 |
-
<tr style="border-bottom: 1px solid #
|
| 758 |
-
<td style="padding: 8px 10px; color: #
|
| 759 |
-
<td style="padding: 8px 10px; text-align: right; color: #
|
| 760 |
-
<td style="padding: 8px 10px; text-align: right; font-weight: 700; color: #
|
| 761 |
</tr>
|
| 762 |
-
<tr style="background: #
|
| 763 |
-
<td style="padding: 8px 10px; color: #
|
| 764 |
-
<td style="padding: 8px 10px; text-align: right; color: #
|
| 765 |
-
<td style="padding: 8px 10px; text-align: right; font-weight: 800; font-size:
|
| 766 |
</tr>
|
| 767 |
</tbody>
|
| 768 |
</table>
|
| 769 |
</div>
|
| 770 |
|
| 771 |
-
<!-- FEED COST -
|
| 772 |
<div style="
|
| 773 |
-
background: #
|
| 774 |
-
border: 2px solid #
|
| 775 |
-
border-radius:
|
| 776 |
padding: 12px 16px;
|
| 777 |
margin-bottom: 12px;
|
| 778 |
">
|
| 779 |
-
<div style="font-size:
|
| 780 |
<div style="display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; font-size: 14px;">
|
| 781 |
-
<span style="color: #
|
| 782 |
<span style="
|
| 783 |
display: inline-block;
|
| 784 |
-
background: #
|
| 785 |
-
color: #
|
| 786 |
border-radius: 6px;
|
| 787 |
padding: 2px 12px;
|
| 788 |
font-size: 18px;
|
| 789 |
font-weight: 700;
|
| 790 |
">{rounded_bags}</span>
|
| 791 |
-
<span style="color: #
|
| 792 |
</div>
|
| 793 |
-
<div style="font-size:
|
| 794 |
{currency_symbol}{total_cost:,.0f}
|
| 795 |
</div>
|
| 796 |
</div>
|
| 797 |
|
| 798 |
<!-- EXPECTED PERFORMANCE -->
|
| 799 |
<div style="
|
| 800 |
-
border-top: 1px solid #
|
| 801 |
padding-top: 10px;
|
| 802 |
-
margin-bottom:
|
| 803 |
">
|
| 804 |
-
<div style="font-size:
|
| 805 |
-
<div style="display: flex; gap: 16px; flex-wrap: wrap; font-size:
|
| 806 |
<div>
|
| 807 |
-
Body
|
| 808 |
</div>
|
| 809 |
<div>
|
| 810 |
-
Flock
|
| 811 |
</div>
|
| 812 |
</div>
|
| 813 |
</div>
|
| 814 |
|
| 815 |
<!-- SHARE BUTTONS -->
|
| 816 |
<div style="
|
| 817 |
-
border-top: 1px solid #
|
| 818 |
-
padding-top:
|
| 819 |
">
|
| 820 |
-
<div style="font-size:
|
| 821 |
-
<div style="display: flex; gap:
|
| 822 |
<a href="{share_links['whatsapp']}" target="_blank" style="text-decoration: none;">
|
| 823 |
<span style="
|
| 824 |
display: inline-block;
|
| 825 |
-
background: #
|
| 826 |
-
color: #
|
| 827 |
-
padding:
|
| 828 |
border-radius: 6px;
|
| 829 |
-
font-size:
|
| 830 |
font-weight: 600;
|
| 831 |
cursor: pointer;
|
| 832 |
">WhatsApp</span>
|
|
@@ -834,11 +849,11 @@ def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_c
|
|
| 834 |
<a href="{share_links['email']}" target="_blank" style="text-decoration: none;">
|
| 835 |
<span style="
|
| 836 |
display: inline-block;
|
| 837 |
-
background: #
|
| 838 |
-
color: #
|
| 839 |
-
padding:
|
| 840 |
border-radius: 6px;
|
| 841 |
-
font-size:
|
| 842 |
font-weight: 600;
|
| 843 |
cursor: pointer;
|
| 844 |
">Email</span>
|
|
@@ -846,11 +861,11 @@ def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_c
|
|
| 846 |
<a href="{share_links['facebook']}" target="_blank" style="text-decoration: none;">
|
| 847 |
<span style="
|
| 848 |
display: inline-block;
|
| 849 |
-
background: #
|
| 850 |
-
color: #
|
| 851 |
-
padding:
|
| 852 |
border-radius: 6px;
|
| 853 |
-
font-size:
|
| 854 |
font-weight: 600;
|
| 855 |
cursor: pointer;
|
| 856 |
">Facebook</span>
|
|
@@ -858,31 +873,31 @@ def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_c
|
|
| 858 |
<a href="{share_links['twitter']}" target="_blank" style="text-decoration: none;">
|
| 859 |
<span style="
|
| 860 |
display: inline-block;
|
| 861 |
-
background: #
|
| 862 |
-
color: #
|
| 863 |
-
padding:
|
| 864 |
border-radius: 6px;
|
| 865 |
-
font-size:
|
| 866 |
font-weight: 600;
|
| 867 |
cursor: pointer;
|
| 868 |
-
">Twitter
|
| 869 |
</a>
|
| 870 |
</div>
|
| 871 |
</div>
|
| 872 |
|
| 873 |
<div style="
|
| 874 |
-
margin-top:
|
| 875 |
-
font-size:
|
| 876 |
-
color: #
|
| 877 |
-
border-top: 1px solid #
|
| 878 |
-
padding-top:
|
| 879 |
">
|
| 880 |
-
β οΈ
|
| 881 |
</div>
|
| 882 |
</div>
|
| 883 |
"""
|
| 884 |
|
| 885 |
-
return html, f"β
|
| 886 |
|
| 887 |
|
| 888 |
# ============================================================
|
|
@@ -1096,112 +1111,136 @@ def export_calculations_wrapper():
|
|
| 1096 |
|
| 1097 |
|
| 1098 |
# ============================================================
|
| 1099 |
-
# CSS -
|
| 1100 |
# ============================================================
|
| 1101 |
|
| 1102 |
CSS = """
|
| 1103 |
/* ============================================================
|
| 1104 |
-
|
| 1105 |
============================================================ */
|
| 1106 |
|
| 1107 |
-
/* GLOBAL TOKENS - 60% Dominant Neutrals */
|
| 1108 |
:root {
|
| 1109 |
-
--
|
| 1110 |
-
--
|
| 1111 |
-
--
|
| 1112 |
-
--
|
| 1113 |
-
--
|
|
|
|
|
|
|
| 1114 |
}
|
| 1115 |
|
| 1116 |
-
/*
|
| 1117 |
-
:root {
|
| 1118 |
-
--color-brand-primary: #1E4620;
|
| 1119 |
-
--color-brand-secondary: #386F3E;
|
| 1120 |
-
}
|
| 1121 |
-
|
| 1122 |
-
/* 10% Accent Colors */
|
| 1123 |
-
:root {
|
| 1124 |
-
--color-accent-gold: #FFB800;
|
| 1125 |
-
--color-feed-brown: #8D6E63;
|
| 1126 |
-
--color-cost-red: #C62828;
|
| 1127 |
-
--color-yield-green: #2E7D32;
|
| 1128 |
-
}
|
| 1129 |
-
|
| 1130 |
-
/* Apply to body */
|
| 1131 |
body, .gradio-container, .gradio-row, .gradio-column, .gradio-group {
|
| 1132 |
-
background-color: var(--
|
| 1133 |
-
color: var(--
|
| 1134 |
}
|
| 1135 |
|
| 1136 |
.gradio-container {
|
| 1137 |
max-width: 100% !important;
|
| 1138 |
-
padding: 6px
|
| 1139 |
}
|
| 1140 |
|
| 1141 |
-
/*
|
| 1142 |
.main-title {
|
| 1143 |
text-align: center;
|
| 1144 |
-
padding:
|
| 1145 |
}
|
| 1146 |
.main-title h1 {
|
| 1147 |
-
font-size:
|
| 1148 |
margin-bottom: 2px;
|
| 1149 |
-
color: var(--
|
| 1150 |
}
|
| 1151 |
.main-title p {
|
| 1152 |
-
font-size:
|
| 1153 |
-
color: var(--
|
| 1154 |
}
|
| 1155 |
|
| 1156 |
-
/*
|
| 1157 |
.answer-box {
|
| 1158 |
-
background: var(--
|
| 1159 |
-
border-radius:
|
| 1160 |
-
padding: 8px
|
| 1161 |
-
border: 1px solid var(--
|
| 1162 |
}
|
| 1163 |
|
| 1164 |
-
/*
|
| 1165 |
.email-box {
|
| 1166 |
-
border: 2px solid var(--
|
| 1167 |
-
border-radius:
|
| 1168 |
-
padding:
|
| 1169 |
-
background: #
|
| 1170 |
}
|
| 1171 |
|
| 1172 |
-
/*
|
| 1173 |
button {
|
| 1174 |
-
min-height:
|
| 1175 |
-
background-color: var(--
|
| 1176 |
color: #FFFFFF !important;
|
| 1177 |
font-weight: 600 !important;
|
| 1178 |
border: none !important;
|
| 1179 |
-
border-radius:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1180 |
}
|
| 1181 |
|
| 1182 |
button:hover {
|
| 1183 |
-
background-color: #
|
|
|
|
| 1184 |
}
|
| 1185 |
|
| 1186 |
-
/*
|
| 1187 |
.admin-login {
|
| 1188 |
-
border: 2px solid var(--
|
| 1189 |
-
border-radius:
|
| 1190 |
-
padding:
|
| 1191 |
background: #FFF8E1 !important;
|
| 1192 |
}
|
| 1193 |
|
| 1194 |
-
/*
|
| 1195 |
-
|
| 1196 |
-
background
|
| 1197 |
-
color: var(--
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1198 |
}
|
| 1199 |
|
| 1200 |
-
/*
|
| 1201 |
-
@media screen and (
|
| 1202 |
-
.gradio-container {
|
| 1203 |
-
|
| 1204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1205 |
}
|
| 1206 |
"""
|
| 1207 |
|
|
@@ -1214,14 +1253,15 @@ with gr.Blocks(title=APP_NAME, css=CSS, theme=gr.themes.Default()) as demo:
|
|
| 1214 |
gr.HTML("""
|
| 1215 |
<div class="main-title">
|
| 1216 |
<h1>π How Much Feed?</h1>
|
| 1217 |
-
<p>
|
| 1218 |
</div>
|
| 1219 |
""")
|
| 1220 |
|
| 1221 |
-
|
|
|
|
| 1222 |
|
| 1223 |
# LEFT COLUMN: INPUTS
|
| 1224 |
-
with gr.Column(scale=1, min_width=
|
| 1225 |
|
| 1226 |
with gr.Group():
|
| 1227 |
gr.Markdown("## π Breed & Birds")
|
|
@@ -1247,11 +1287,13 @@ with gr.Blocks(title=APP_NAME, css=CSS, theme=gr.themes.Default()) as demo:
|
|
| 1247 |
choices=list(range(0, 21)),
|
| 1248 |
value=8,
|
| 1249 |
label="Weeks",
|
|
|
|
| 1250 |
)
|
| 1251 |
days = gr.Dropdown(
|
| 1252 |
choices=list(range(0, 7)),
|
| 1253 |
value=0,
|
| 1254 |
-
label="
|
|
|
|
| 1255 |
)
|
| 1256 |
|
| 1257 |
gr.Markdown("## πΎ Feed Details")
|
|
@@ -1261,11 +1303,13 @@ with gr.Blocks(title=APP_NAME, css=CSS, theme=gr.themes.Default()) as demo:
|
|
| 1261 |
choices=[10, 20, 25, 50, 100],
|
| 1262 |
value=25,
|
| 1263 |
label="Bag size (kg)",
|
|
|
|
| 1264 |
)
|
| 1265 |
price = gr.Number(
|
| 1266 |
value=24000,
|
| 1267 |
label="Price per bag (β¦)",
|
| 1268 |
minimum=0,
|
|
|
|
| 1269 |
)
|
| 1270 |
|
| 1271 |
gr.Markdown("## π Your Location")
|
|
@@ -1281,14 +1325,14 @@ with gr.Blocks(title=APP_NAME, css=CSS, theme=gr.themes.Default()) as demo:
|
|
| 1281 |
|
| 1282 |
country_code_state = gr.State(detected_country)
|
| 1283 |
|
| 1284 |
-
gr.Markdown("## π§ Your Email")
|
| 1285 |
|
| 1286 |
email = gr.Textbox(
|
| 1287 |
label="",
|
| 1288 |
placeholder="farmer@example.com",
|
| 1289 |
type="email",
|
| 1290 |
elem_classes=["email-box"],
|
| 1291 |
-
info="We
|
| 1292 |
)
|
| 1293 |
|
| 1294 |
calculate_btn = gr.Button(
|
|
@@ -1297,17 +1341,23 @@ with gr.Blocks(title=APP_NAME, css=CSS, theme=gr.themes.Default()) as demo:
|
|
| 1297 |
size="lg",
|
| 1298 |
)
|
| 1299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1300 |
save_status = gr.Markdown("")
|
| 1301 |
|
| 1302 |
# RIGHT COLUMN: RESULTS
|
| 1303 |
-
with gr.Column(scale=1, min_width=
|
| 1304 |
-
gr.Markdown("## π Quick Answer")
|
| 1305 |
result = gr.HTML(
|
| 1306 |
value="""
|
| 1307 |
-
<div style="font-size:
|
| 1308 |
-
<div style="font-size:
|
| 1309 |
<div>Enter your details and click <strong>Calculate</strong></div>
|
| 1310 |
-
<div style="font-size:
|
| 1311 |
</div>
|
| 1312 |
""",
|
| 1313 |
elem_classes=["answer-box"],
|
|
|
|
| 144 |
"Ross 308": {
|
| 145 |
"description": "Big chest, thick legs, very fast growth. Excellent for meat production.",
|
| 146 |
"available_at": "Agrited, Sayed, Valentine",
|
| 147 |
+
"color": "#00A86B"
|
| 148 |
},
|
| 149 |
"Cobb 500": {
|
| 150 |
"description": "Good early growth, strong legs, solid feed conversion.",
|
| 151 |
"available_at": "Chikun, Zartech",
|
| 152 |
+
"color": "#00A86B"
|
| 153 |
},
|
| 154 |
"Arbor Acres": {
|
| 155 |
"description": "Balanced growth, hardy and adaptable. Great survival rate.",
|
| 156 |
"available_at": "Supreme, CHI, GS, Vertex, Fidan, Cascada, Orobor, Sunchi, Farm Support, Ajila",
|
| 157 |
+
"color": "#00A86B"
|
| 158 |
}
|
| 159 |
}
|
| 160 |
|
|
|
|
| 571 |
|
| 572 |
|
| 573 |
# ============================================================
|
| 574 |
+
# FEED CALCULATION - MINT GREEN & EGG YELLOW DESIGN
|
| 575 |
# ============================================================
|
| 576 |
|
| 577 |
def calculate_feed(birds, weeks, days, bag_size, price_per_bag, email, country_code, breed, request: gr.Request):
|
|
|
|
| 645 |
# Generate share links
|
| 646 |
share_links = get_share_links()
|
| 647 |
|
| 648 |
+
# Output HTML - MINT GREEN & EGG YELLOW DESIGN
|
| 649 |
starter_bags_display = f"{starter_bags:.1f}"
|
| 650 |
finisher_bags_display = f"{finisher_bags:.1f}"
|
| 651 |
|
|
|
|
| 656 |
html = f"""
|
| 657 |
<div style="
|
| 658 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
| 659 |
+
font-size: 14px;
|
| 660 |
line-height: 1.5;
|
| 661 |
+
color: #0B3022;
|
| 662 |
+
background: #FFFFFF;
|
| 663 |
border-radius: 12px;
|
| 664 |
+
padding: 14px 16px;
|
| 665 |
+
border: 1px solid #D6E0DB;
|
| 666 |
width: 100%;
|
| 667 |
+
max-width: 100%;
|
| 668 |
box-sizing: border-box;
|
| 669 |
+
overflow-wrap: break-word;
|
| 670 |
">
|
| 671 |
|
| 672 |
<!-- RESULTS CARD -->
|
| 673 |
<div style="
|
| 674 |
+
background: #F4F7F5;
|
| 675 |
+
border: 2px solid #00A86B;
|
| 676 |
border-radius: 10px;
|
| 677 |
padding: 14px 16px;
|
| 678 |
margin-bottom: 14px;
|
|
|
|
| 680 |
<div style="
|
| 681 |
font-size: 12px;
|
| 682 |
font-weight: 700;
|
| 683 |
+
color: #00A86B;
|
| 684 |
text-transform: uppercase;
|
| 685 |
letter-spacing: 0.5px;
|
| 686 |
+
margin-bottom: 6px;
|
| 687 |
">π Your Feed Estimate</div>
|
| 688 |
|
| 689 |
+
<!-- Total Feed - Dual Column -->
|
| 690 |
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 6px 0;">
|
| 691 |
+
<div style="
|
| 692 |
+
background: #FFFFFF;
|
| 693 |
+
border-radius: 8px;
|
| 694 |
+
padding: 10px 12px;
|
| 695 |
+
border: 1px solid #D6E0DB;
|
| 696 |
+
">
|
| 697 |
+
<div style="font-size: 11px; color: #5A6E65; font-weight: 600;">Total Feed</div>
|
| 698 |
+
<div style="font-size: 26px; font-weight: 800; color: #00A86B;">
|
| 699 |
+
{total_feed_kg:,.1f} kg
|
| 700 |
+
</div>
|
| 701 |
</div>
|
| 702 |
+
<div style="
|
| 703 |
+
background: #FFFFFF;
|
| 704 |
+
border-radius: 8px;
|
| 705 |
+
padding: 10px 12px;
|
| 706 |
+
border: 1px solid #D6E0DB;
|
| 707 |
+
">
|
| 708 |
+
<div style="font-size: 11px; color: #5A6E65; font-weight: 600;">Exact Bags</div>
|
| 709 |
+
<div style="font-size: 26px; font-weight: 800; color: #0B3022;">
|
| 710 |
+
{total_bags:.1f}
|
| 711 |
+
</div>
|
| 712 |
</div>
|
| 713 |
</div>
|
| 714 |
|
| 715 |
<!-- Birds Info -->
|
| 716 |
+
<div style="font-size: 13px; color: #0B3022; margin-bottom: 8px;">
|
| 717 |
+
For <strong>{birds:,}</strong> {breed} broilers Β· <strong>{age_text}</strong>
|
| 718 |
</div>
|
| 719 |
|
| 720 |
+
<!-- Buy Recommendation - Egg Yellow Frame -->
|
| 721 |
<div style="
|
| 722 |
background: #FFF8E1;
|
| 723 |
border: 2px solid #FFB800;
|
| 724 |
border-radius: 8px;
|
| 725 |
+
padding: 10px 14px;
|
| 726 |
+
margin-top: 4px;
|
| 727 |
">
|
| 728 |
+
<div style="display: flex; align-items: center; gap: 8px; flex-wrap: wrap;">
|
| 729 |
+
<span style="font-size: 13px; font-weight: 600; color: #0B3022;">Buy</span>
|
| 730 |
+
<span style="
|
| 731 |
+
display: inline-block;
|
| 732 |
+
background: #FFB800;
|
| 733 |
+
color: #0B3022;
|
| 734 |
+
border-radius: 6px;
|
| 735 |
+
padding: 2px 14px;
|
| 736 |
+
font-size: 20px;
|
| 737 |
+
font-weight: 800;
|
| 738 |
+
">{rounded_bags}</span>
|
| 739 |
+
<span style="font-size: 13px; color: #5A6E65;">bags (rounded up for safety)</span>
|
| 740 |
+
</div>
|
| 741 |
+
<div style="font-size: 12px; color: #5A6E65; margin-top: 2px;">
|
| 742 |
+
This ensures enough feed for the full growing period.
|
| 743 |
+
</div>
|
| 744 |
</div>
|
| 745 |
</div>
|
| 746 |
|
| 747 |
<!-- FEED BREAKDOWN TABLE -->
|
| 748 |
<div style="margin-bottom: 12px;">
|
| 749 |
+
<div style="font-size: 12px; font-weight: 700; color: #00A86B; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px;">πΎ Feed Breakdown</div>
|
| 750 |
<table style="
|
| 751 |
width: 100%;
|
| 752 |
border-collapse: collapse;
|
| 753 |
+
font-size: 13px;
|
| 754 |
+
background: #FFFFFF;
|
| 755 |
+
border: 1px solid #D6E0DB;
|
| 756 |
border-radius: 8px;
|
| 757 |
overflow: hidden;
|
| 758 |
">
|
| 759 |
<thead>
|
| 760 |
+
<tr style="background: #F4F7F5; border-bottom: 2px solid #00A86B;">
|
| 761 |
+
<th style="padding: 8px 10px; text-align: left; font-weight: 600; color: #0B3022; font-size: 12px;">Stage</th>
|
| 762 |
+
<th style="padding: 8px 10px; text-align: right; font-weight: 600; color: #0B3022; font-size: 12px;">Feed (kg)</th>
|
| 763 |
+
<th style="padding: 8px 10px; text-align: right; font-weight: 600; color: #0B3022; font-size: 12px;">Bags</th>
|
| 764 |
</tr>
|
| 765 |
</thead>
|
| 766 |
<tbody>
|
| 767 |
+
<tr style="border-bottom: 1px solid #D6E0DB;">
|
| 768 |
+
<td style="padding: 8px 10px; color: #0B3022; font-size: 12px;"><strong>π± Starter (0-4 wks)</strong></td>
|
| 769 |
+
<td style="padding: 8px 10px; text-align: right; color: #0B3022; font-size: 12px;">{starter_kg:,.1f}</td>
|
| 770 |
+
<td style="padding: 8px 10px; text-align: right; font-weight: 700; color: #0B3022; font-size: 12px;">{starter_bags_display}</td>
|
| 771 |
</tr>
|
| 772 |
+
<tr style="border-bottom: 1px solid #D6E0DB;">
|
| 773 |
+
<td style="padding: 8px 10px; color: #0B3022; font-size: 12px;"><strong>π½ Finisher (4-8 wks)</strong></td>
|
| 774 |
+
<td style="padding: 8px 10px; text-align: right; color: #0B3022; font-size: 12px;">{finisher_kg:,.1f}</td>
|
| 775 |
+
<td style="padding: 8px 10px; text-align: right; font-weight: 700; color: #0B3022; font-size: 12px;">{finisher_bags_display}</td>
|
| 776 |
</tr>
|
| 777 |
+
<tr style="background: #F4F7F5; font-weight: 700;">
|
| 778 |
+
<td style="padding: 8px 10px; color: #0B3022; font-size: 13px;">TOTAL</td>
|
| 779 |
+
<td style="padding: 8px 10px; text-align: right; color: #0B3022; font-size: 13px;">{total_feed_kg:,.1f}</td>
|
| 780 |
+
<td style="padding: 8px 10px; text-align: right; font-weight: 800; font-size: 15px; color: #00A86B;">{total_bags:.1f}</td>
|
| 781 |
</tr>
|
| 782 |
</tbody>
|
| 783 |
</table>
|
| 784 |
</div>
|
| 785 |
|
| 786 |
+
<!-- FEED COST - EGG YELLOW CARD -->
|
| 787 |
<div style="
|
| 788 |
+
background: #FFF8E1;
|
| 789 |
+
border: 2px solid #FFB800;
|
| 790 |
+
border-radius: 8px;
|
| 791 |
padding: 12px 16px;
|
| 792 |
margin-bottom: 12px;
|
| 793 |
">
|
| 794 |
+
<div style="font-size: 11px; font-weight: 700; color: #5A6E65; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px;">π° Feed Cost</div>
|
| 795 |
<div style="display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; font-size: 14px;">
|
| 796 |
+
<span style="color: #0B3022;">~</span>
|
| 797 |
<span style="
|
| 798 |
display: inline-block;
|
| 799 |
+
background: #FFB800;
|
| 800 |
+
color: #0B3022;
|
| 801 |
border-radius: 6px;
|
| 802 |
padding: 2px 12px;
|
| 803 |
font-size: 18px;
|
| 804 |
font-weight: 700;
|
| 805 |
">{rounded_bags}</span>
|
| 806 |
+
<span style="color: #0B3022;">Γ {currency_symbol}{price_per_bag:,.0f}</span>
|
| 807 |
</div>
|
| 808 |
+
<div style="font-size: 24px; font-weight: 800; color: #0B3022; margin-top: 2px;">
|
| 809 |
{currency_symbol}{total_cost:,.0f}
|
| 810 |
</div>
|
| 811 |
</div>
|
| 812 |
|
| 813 |
<!-- EXPECTED PERFORMANCE -->
|
| 814 |
<div style="
|
| 815 |
+
border-top: 1px solid #D6E0DB;
|
| 816 |
padding-top: 10px;
|
| 817 |
+
margin-bottom: 10px;
|
| 818 |
">
|
| 819 |
+
<div style="font-size: 11px; font-weight: 700; color: #00A86B; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px;">π Expected Performance</div>
|
| 820 |
+
<div style="display: flex; gap: 16px; flex-wrap: wrap; font-size: 13px;">
|
| 821 |
<div>
|
| 822 |
+
Body: <span style="font-weight: 700; color: #0B3022;">{expected_weight:.3f} kg</span>
|
| 823 |
</div>
|
| 824 |
<div>
|
| 825 |
+
Flock: <span style="font-weight: 700; color: #0B3022;">{flock_weight:,.1f} kg</span>
|
| 826 |
</div>
|
| 827 |
</div>
|
| 828 |
</div>
|
| 829 |
|
| 830 |
<!-- SHARE BUTTONS -->
|
| 831 |
<div style="
|
| 832 |
+
border-top: 1px solid #D6E0DB;
|
| 833 |
+
padding-top: 10px;
|
| 834 |
">
|
| 835 |
+
<div style="font-size: 11px; font-weight: 700; color: #00A86B; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px;">π€ Share Results</div>
|
| 836 |
+
<div style="display: flex; gap: 6px; flex-wrap: wrap;">
|
| 837 |
<a href="{share_links['whatsapp']}" target="_blank" style="text-decoration: none;">
|
| 838 |
<span style="
|
| 839 |
display: inline-block;
|
| 840 |
+
background: #00A86B;
|
| 841 |
+
color: #FFFFFF;
|
| 842 |
+
padding: 5px 12px;
|
| 843 |
border-radius: 6px;
|
| 844 |
+
font-size: 12px;
|
| 845 |
font-weight: 600;
|
| 846 |
cursor: pointer;
|
| 847 |
">WhatsApp</span>
|
|
|
|
| 849 |
<a href="{share_links['email']}" target="_blank" style="text-decoration: none;">
|
| 850 |
<span style="
|
| 851 |
display: inline-block;
|
| 852 |
+
background: #00A86B;
|
| 853 |
+
color: #FFFFFF;
|
| 854 |
+
padding: 5px 12px;
|
| 855 |
border-radius: 6px;
|
| 856 |
+
font-size: 12px;
|
| 857 |
font-weight: 600;
|
| 858 |
cursor: pointer;
|
| 859 |
">Email</span>
|
|
|
|
| 861 |
<a href="{share_links['facebook']}" target="_blank" style="text-decoration: none;">
|
| 862 |
<span style="
|
| 863 |
display: inline-block;
|
| 864 |
+
background: #00A86B;
|
| 865 |
+
color: #FFFFFF;
|
| 866 |
+
padding: 5px 12px;
|
| 867 |
border-radius: 6px;
|
| 868 |
+
font-size: 12px;
|
| 869 |
font-weight: 600;
|
| 870 |
cursor: pointer;
|
| 871 |
">Facebook</span>
|
|
|
|
| 873 |
<a href="{share_links['twitter']}" target="_blank" style="text-decoration: none;">
|
| 874 |
<span style="
|
| 875 |
display: inline-block;
|
| 876 |
+
background: #00A86B;
|
| 877 |
+
color: #FFFFFF;
|
| 878 |
+
padding: 5px 12px;
|
| 879 |
border-radius: 6px;
|
| 880 |
+
font-size: 12px;
|
| 881 |
font-weight: 600;
|
| 882 |
cursor: pointer;
|
| 883 |
+
">Twitter</span>
|
| 884 |
</a>
|
| 885 |
</div>
|
| 886 |
</div>
|
| 887 |
|
| 888 |
<div style="
|
| 889 |
+
margin-top: 8px;
|
| 890 |
+
font-size: 10px;
|
| 891 |
+
color: #5A6E65;
|
| 892 |
+
border-top: 1px solid #D6E0DB;
|
| 893 |
+
padding-top: 6px;
|
| 894 |
">
|
| 895 |
+
β οΈ Based on {breed} benchmark. Actual results may vary.
|
| 896 |
</div>
|
| 897 |
</div>
|
| 898 |
"""
|
| 899 |
|
| 900 |
+
return html, f"β
Saved for {email.strip().lower()}."
|
| 901 |
|
| 902 |
|
| 903 |
# ============================================================
|
|
|
|
| 1111 |
|
| 1112 |
|
| 1113 |
# ============================================================
|
| 1114 |
+
# CSS - MINT GREEN & EGG YELLOW DESIGN SYSTEM
|
| 1115 |
# ============================================================
|
| 1116 |
|
| 1117 |
CSS = """
|
| 1118 |
/* ============================================================
|
| 1119 |
+
MINT GREEN & EGG YELLOW DESIGN SYSTEM
|
| 1120 |
============================================================ */
|
| 1121 |
|
|
|
|
| 1122 |
:root {
|
| 1123 |
+
--app-bg-main: #F4F7F5;
|
| 1124 |
+
--app-card-surface: #FFFFFF;
|
| 1125 |
+
--brand-primary-mint: #00A86B;
|
| 1126 |
+
--brand-dark-charcoal: #0B3022;
|
| 1127 |
+
--brand-accent-yellow: #FFB800;
|
| 1128 |
+
--ui-border-muted: #D6E0DB;
|
| 1129 |
+
--text-helper: #5A6E65;
|
| 1130 |
}
|
| 1131 |
|
| 1132 |
+
/* GLOBAL */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1133 |
body, .gradio-container, .gradio-row, .gradio-column, .gradio-group {
|
| 1134 |
+
background-color: var(--app-bg-main) !important;
|
| 1135 |
+
color: var(--brand-dark-charcoal) !important;
|
| 1136 |
}
|
| 1137 |
|
| 1138 |
.gradio-container {
|
| 1139 |
max-width: 100% !important;
|
| 1140 |
+
padding: 4px 6px !important;
|
| 1141 |
}
|
| 1142 |
|
| 1143 |
+
/* MAIN TITLE */
|
| 1144 |
.main-title {
|
| 1145 |
text-align: center;
|
| 1146 |
+
padding: 6px 4px 4px 4px;
|
| 1147 |
}
|
| 1148 |
.main-title h1 {
|
| 1149 |
+
font-size: 22px;
|
| 1150 |
margin-bottom: 2px;
|
| 1151 |
+
color: var(--brand-dark-charcoal) !important;
|
| 1152 |
}
|
| 1153 |
.main-title p {
|
| 1154 |
+
font-size: 13px;
|
| 1155 |
+
color: var(--text-helper) !important;
|
| 1156 |
}
|
| 1157 |
|
| 1158 |
+
/* ANSWER BOX */
|
| 1159 |
.answer-box {
|
| 1160 |
+
background: var(--app-card-surface) !important;
|
| 1161 |
+
border-radius: 10px !important;
|
| 1162 |
+
padding: 6px 8px !important;
|
| 1163 |
+
border: 1px solid var(--ui-border-muted) !important;
|
| 1164 |
}
|
| 1165 |
|
| 1166 |
+
/* EMAIL BOX */
|
| 1167 |
.email-box {
|
| 1168 |
+
border: 2px solid var(--brand-primary-mint) !important;
|
| 1169 |
+
border-radius: 8px !important;
|
| 1170 |
+
padding: 6px !important;
|
| 1171 |
+
background: #F4F7F5 !important;
|
| 1172 |
}
|
| 1173 |
|
| 1174 |
+
/* BUTTONS */
|
| 1175 |
button {
|
| 1176 |
+
min-height: 40px !important;
|
| 1177 |
+
background-color: var(--brand-primary-mint) !important;
|
| 1178 |
color: #FFFFFF !important;
|
| 1179 |
font-weight: 600 !important;
|
| 1180 |
border: none !important;
|
| 1181 |
+
border-radius: 6px !important;
|
| 1182 |
+
font-size: 14px !important;
|
| 1183 |
+
padding: 8px 16px !important;
|
| 1184 |
+
width: 100% !important;
|
| 1185 |
+
transition: all 0.2s ease !important;
|
| 1186 |
}
|
| 1187 |
|
| 1188 |
button:hover {
|
| 1189 |
+
background-color: #008F5A !important;
|
| 1190 |
+
transform: scale(1.02) !important;
|
| 1191 |
}
|
| 1192 |
|
| 1193 |
+
/* ADMIN LOGIN */
|
| 1194 |
.admin-login {
|
| 1195 |
+
border: 2px solid var(--brand-accent-yellow) !important;
|
| 1196 |
+
border-radius: 8px !important;
|
| 1197 |
+
padding: 10px !important;
|
| 1198 |
background: #FFF8E1 !important;
|
| 1199 |
}
|
| 1200 |
|
| 1201 |
+
/* DROPDOWNS */
|
| 1202 |
+
select, input, textarea {
|
| 1203 |
+
background: #FFFFFF !important;
|
| 1204 |
+
color: var(--brand-dark-charcoal) !important;
|
| 1205 |
+
border: 1px solid var(--ui-border-muted) !important;
|
| 1206 |
+
border-radius: 6px !important;
|
| 1207 |
+
}
|
| 1208 |
+
|
| 1209 |
+
select:focus, input:focus, textarea:focus {
|
| 1210 |
+
border-color: var(--brand-primary-mint) !important;
|
| 1211 |
+
box-shadow: 0 0 0 3px rgba(0, 168, 107, 0.2) !important;
|
| 1212 |
+
}
|
| 1213 |
+
|
| 1214 |
+
/* TABLES */
|
| 1215 |
+
table {
|
| 1216 |
+
font-size: 12px !important;
|
| 1217 |
+
}
|
| 1218 |
+
|
| 1219 |
+
th, td {
|
| 1220 |
+
padding: 4px 6px !important;
|
| 1221 |
}
|
| 1222 |
|
| 1223 |
+
/* DESKTOP */
|
| 1224 |
+
@media screen and (min-width: 769px) {
|
| 1225 |
+
.gradio-container {
|
| 1226 |
+
padding: 8px 16px !important;
|
| 1227 |
+
max-width: 1200px !important;
|
| 1228 |
+
margin: 0 auto !important;
|
| 1229 |
+
}
|
| 1230 |
+
|
| 1231 |
+
.main-title h1 {
|
| 1232 |
+
font-size: 28px !important;
|
| 1233 |
+
}
|
| 1234 |
+
|
| 1235 |
+
button {
|
| 1236 |
+
width: auto !important;
|
| 1237 |
+
}
|
| 1238 |
+
}
|
| 1239 |
+
|
| 1240 |
+
/* DARK MODE OVERRIDE */
|
| 1241 |
+
.dark, .dark * {
|
| 1242 |
+
background-color: var(--app-bg-main) !important;
|
| 1243 |
+
color: var(--brand-dark-charcoal) !important;
|
| 1244 |
}
|
| 1245 |
"""
|
| 1246 |
|
|
|
|
| 1253 |
gr.HTML("""
|
| 1254 |
<div class="main-title">
|
| 1255 |
<h1>π How Much Feed?</h1>
|
| 1256 |
+
<p>Broiler Feed Calculator β Know exactly how much feed you need for your birds.</p>
|
| 1257 |
</div>
|
| 1258 |
""")
|
| 1259 |
|
| 1260 |
+
# Mobile-first: Stack vertically on mobile, side by side on desktop
|
| 1261 |
+
with gr.Row(equal_height=True, variant="default"):
|
| 1262 |
|
| 1263 |
# LEFT COLUMN: INPUTS
|
| 1264 |
+
with gr.Column(scale=1, min_width=280):
|
| 1265 |
|
| 1266 |
with gr.Group():
|
| 1267 |
gr.Markdown("## π Breed & Birds")
|
|
|
|
| 1287 |
choices=list(range(0, 21)),
|
| 1288 |
value=8,
|
| 1289 |
label="Weeks",
|
| 1290 |
+
scale=1,
|
| 1291 |
)
|
| 1292 |
days = gr.Dropdown(
|
| 1293 |
choices=list(range(0, 7)),
|
| 1294 |
value=0,
|
| 1295 |
+
label="Days",
|
| 1296 |
+
scale=1,
|
| 1297 |
)
|
| 1298 |
|
| 1299 |
gr.Markdown("## πΎ Feed Details")
|
|
|
|
| 1303 |
choices=[10, 20, 25, 50, 100],
|
| 1304 |
value=25,
|
| 1305 |
label="Bag size (kg)",
|
| 1306 |
+
scale=1,
|
| 1307 |
)
|
| 1308 |
price = gr.Number(
|
| 1309 |
value=24000,
|
| 1310 |
label="Price per bag (β¦)",
|
| 1311 |
minimum=0,
|
| 1312 |
+
scale=1,
|
| 1313 |
)
|
| 1314 |
|
| 1315 |
gr.Markdown("## π Your Location")
|
|
|
|
| 1325 |
|
| 1326 |
country_code_state = gr.State(detected_country)
|
| 1327 |
|
| 1328 |
+
gr.Markdown("## π§ Your Email (Required)")
|
| 1329 |
|
| 1330 |
email = gr.Textbox(
|
| 1331 |
label="",
|
| 1332 |
placeholder="farmer@example.com",
|
| 1333 |
type="email",
|
| 1334 |
elem_classes=["email-box"],
|
| 1335 |
+
info="We never share your email. It is used only to save your results.",
|
| 1336 |
)
|
| 1337 |
|
| 1338 |
calculate_btn = gr.Button(
|
|
|
|
| 1341 |
size="lg",
|
| 1342 |
)
|
| 1343 |
|
| 1344 |
+
gr.Markdown("""
|
| 1345 |
+
<div style="font-size: 11px; color: #5A6E65; margin-top: 4px;">
|
| 1346 |
+
β οΈ Why email is required? We send your calculation to your email so you can access it anytime.
|
| 1347 |
+
</div>
|
| 1348 |
+
""")
|
| 1349 |
+
|
| 1350 |
save_status = gr.Markdown("")
|
| 1351 |
|
| 1352 |
# RIGHT COLUMN: RESULTS
|
| 1353 |
+
with gr.Column(scale=1, min_width=280):
|
| 1354 |
+
gr.Markdown("## π Your Quick Answer")
|
| 1355 |
result = gr.HTML(
|
| 1356 |
value="""
|
| 1357 |
+
<div style="font-size: 13px; color: #5A6E65; text-align: center; padding: 20px 10px; background: #FFFFFF; border-radius: 10px; border: 1px solid #D6E0DB;">
|
| 1358 |
+
<div style="font-size: 36px; margin-bottom: 8px;">π</div>
|
| 1359 |
<div>Enter your details and click <strong>Calculate</strong></div>
|
| 1360 |
+
<div style="font-size: 12px; margin-top: 4px; color: #5A6E65;">Your feed estimate appears here</div>
|
| 1361 |
</div>
|
| 1362 |
""",
|
| 1363 |
elem_classes=["answer-box"],
|