Protocol Raw Feed Calculator v6.4 - Final Documentation¶
Created: November 10, 2025
Updated: February 3, 2026
Status: ✅ Production Ready
Version: 6.4 FINAL
Table of Contents¶
- Executive Summary
- What Changed (v6.1 → v6.4)
- What Changed (v6.0 → v6.1)
- What Changed (v5.5 → v6.0)
- Technical Specifications
- Delivery Frequency Logic
- Box Recommendation Logic
- Alternative Box Display Logic
- Smaller First Delivery Option
- Pricing Display Strategy
- Freezer Guidance
- Visual Identity Alignment
- Testing & Validation
- Implementation Checklist
- Files & Code Reference
- Version History
Executive Summary¶
What This Is¶
The Protocol Raw Feed Calculator v6.0 is a life-stage-aware personalised feeding plan calculator that converts raw-curious premium dog owners into committed Protocol Raw customers.
It uses: - Veterinary-standard RER × MER methodology for adult/senior dogs - Senior-specific MER factors (~10% reduction reflecting metabolic slowdown) - Puppy-specific multipliers (3.0×, 2.0×, 1.8× based on age) - Lab-verified 1900 kcal/kg formula for precise gram calculations - Smart box recommendations with value-optimised alternatives - 5 frequency options (2, 3, 4, 5, 6 weeks) ensuring optimal delivery timing - "Per box" pricing display that prevents confusing maths - Freezer guidance addressing pre-purchase anxiety without creating friction
Key Metrics¶
- 15kg adult anchor: £24/week ✅
- Box-2 retention target: >70%
- Calculator completion rate: >60%
v6.4 Highlights¶
- ✅ "Smaller first delivery" option for 12kg customers (start with 8kg, move to 12kg from Box 2)
- ✅ New URL parameters:
optimal_boxandfirst_order_downsize - ✅ Treat adjustment correctly hides/restores first delivery option
v6.1 Highlights¶
- ✅ Added buffer/flexibility line to product page calculator banner
- ✅ Shows calculated days supply with subscription flexibility messaging
v6.0 Highlights¶
- ✅ Added freezer guidance as integrated line in box details
- ✅ Changed "pouches" to "trays" throughout
- ✅ Fixed Cream colour (#FEFDF7 → #F9F7F4) per Visual Identity Guide v2.2
- ✅ Fixed Warm Gray → Taupe for three text elements (better readability)
What Changed (v6.1 → v6.4)¶
1. Smaller First Delivery Option¶
Purpose: Allow 12kg customers to start with an 8kg first delivery to ease freezer space anxiety, then transition to their optimal 12kg box from Box 2 onwards.
Trigger: Only appears when recommendedBox === '12kg' && alternativeBox === '16kg' (medium-consumption dogs, roughly 250-470g/day).
Implementation: Four code changes to feed-calculator.liquid:
-
HTML (line 411-418): New
first-delivery-optiondiv reusing existingalternative-option-subtleclass. Zero new CSS required. -
calculateBoxRecommendation(): Calculates first delivery data (box, days supply, weeks, weekly price) only when the trigger condition is met. Returns five new properties in the plan object.
-
updateResults(): Shows/hides the first delivery element and builds the product page URL with
optimal_box=12kgandfirst_order_downsize=trueparameters. -
recalculateWithTreats(): Hides the first delivery option when treat adjustment flips the alternative from 16kg value to 8kg convenience (avoids duplicate 8kg links). Restores it when the original alternative remains valid.
Display: Subtle text link below the existing alternative box option:
Copy rationale: "Smaller first delivery?" is a question (not a recommendation). "Start with 8kg, then move to 12kg from Box 2" makes the transition explicit. Never framed as "trial" or "sample".
Design principle applied: Practical logistics, not emotional hand-holding. Same philosophy as freezer guidance — answer the concern without creating a decision problem.
2. New URL Parameters¶
Two new parameters added to the first delivery CTA link:
| Parameter | Value | Purpose |
|---|---|---|
optimal_box |
12kg |
Calculator's actual recommendation |
first_order_downsize |
true |
Flags this as a downsized first order |
These are consumed by the product page (Workstream 2, pending) and stored in the subscription record to trigger the post-Box-1 upgrade email.
What Changed (v6.0 → v6.1)¶
1. Product Page Buffer/Flexibility Line¶
Purpose: Show customers how long their box lasts and that they have full subscription flexibility, reducing purchase hesitation at the point of commitment.
Implementation: Single line added below the data grid in the product page calculator banner (main-product.liquid):
BOX SIZE 16KG
DAILY FEED 475g
DELIVERY Every 4 weeks
Lasts approximately 33 days · skip, pause or change frequency anytime
Calculation: Math.floor(boxGrams[boxSize] / parseInt(dailyGrams))
Design decisions:
- Information only, no link or decision point
- Uses Taupe colour (#6B6360) at 13px — same visual weight as freezer guidance in calculator
- Separated from data grid by subtle 1px border-top
- Hidden by default (display:none), shown only when calculator URL params are present
- Displays for both single-pet and multi-pet views
Copy rationale: "Lasts approximately X days" makes the buffer self-evident (e.g. 33 days vs 28-day cadence = 5 days spare). "Skip, pause or change frequency anytime" gives three concrete actions that neutralise lock-in anxiety. No mention of "portal" (customers don't know what that is pre-purchase).
Design principle applied: Information without friction. Same philosophy as calculator freezer guidance.
CSS:
.calc-buffer-line {
font-family: 'Inter', sans-serif;
font-size: 13px;
color: var(--col-taupe, #6B6360);
margin: 12px 0 0 0;
padding-top: 12px;
border-top: 1px solid rgba(43, 37, 35, 0.08);
line-height: 1.4;
}
What Changed (v5.5 → v6.0)¶
1. Freezer Guidance Added¶
Purpose: Address pre-purchase anxiety about freezer space without creating a decision point.
Implementation: Simple third line in box details block:
Design decisions:
- Information only, no link or alternative suggestion
- Same visual weight as duration line (secondary info)
- Uses Taupe colour (#6B6360) - not highlighted
- Drawer estimates: 8kg = 1, 12kg = 1.5, 16kg = 2
Rationale: Customers who can't accommodate the freezer space aren't our customers. This line answers the question calmly without framing it as a problem or offering a workaround that adds friction.
Design principle applied: Information without friction. Freezer guidance answers the question without creating a decision point.
2. Terminology: "Pouches" → "Trays"¶
All references to packaging updated to reflect actual product format:
| Location | Old | New |
|---|---|---|
| Example anchor | "24 pouches" | "24 trays" |
| Box contents | "24 pouches (500g each)" | "24 trays (500g each)" |
| Portion card | "pouch per day" | "tray per day" |
| PRICING constant | pouches: 24 |
trays: 24 |
3. Visual Identity Alignment¶
Cream colour corrected:
/* Was (incorrect) */
--col-cream: #FEFDF7;
/* Now (per Visual Identity Guide v2.2) */
--col-cream: #F9F7F4;
Warm Gray → Taupe for better readability:
Per Visual Identity Guide: "Warm Gray #918A85 only for meta/secondary elements. Espresso #2B2523 for body text (NOT Warm Gray)."
Changed three instances where Warm Gray was used for readable content:
| Element | Old | New |
|---|---|---|
.portion-unit |
--col-warm-gray |
--col-taupe |
.badge-content p |
--col-warm-gray |
--col-taupe |
.price-period-hero |
--col-warm-gray |
--col-taupe |
Technical Specifications¶
Core Calculations¶
1. Resting Energy Requirement (RER)¶
2. Maintenance Energy Requirement (MER)¶
For Adults:
For Seniors:
3. Daily Grams¶
4. Weekly Price (Consumption-Based)¶
const boxGrams = { '8kg': 8000, '12kg': 12000, '16kg': 16000 };
const daysSupply = Math.floor(boxGrams[boxSize] / dailyGrams);
const actualWeeks = daysSupply / 7;
const weeklyPrice = Math.round(boxPrice / actualWeeks);
MER Multipliers¶
ADULTS:
| Activity | Neutered | Intact |
|---|---|---|
| Low | 1.2× | 1.4× |
| Moderate | 1.33× [ANCHOR] | 1.6× |
| High | 1.6× | 1.8× |
SENIORS (7+ years):
| Activity | Neutered | Intact |
|---|---|---|
| Low | 1.1× | 1.3× |
| Moderate | 1.2× | 1.45× |
| High | 1.45× | 1.65× |
Body Condition Score (BCS) Multipliers¶
| BCS | Multiplier | Description |
|---|---|---|
| Underweight | 1.1× | Visible ribs, no fat cover |
| Ideal | 1.0× | Ribs easily felt, waist visible |
| Overweight | 0.9× | Ribs difficult to feel, minimal waist |
Puppy Multipliers (Age-Based)¶
| Age | Multiplier | Notes |
|---|---|---|
| 0-4 months | 3.0× | High growth phase |
| 4-12 months | 2.0× | Continued growth |
| 12-24 months | 1.8× | Approaching adult size |
Delivery Frequency Logic¶
Available Frequencies¶
| Weeks | Days | Typical Use Case |
|---|---|---|
| 6 | 42 | Very small dogs (Chihuahuas, toy breeds) |
| 5 | 35 | Small dogs (Cavaliers, small Cockapoos) |
| 4 | 28 | Medium dogs (Spaniels, Beagles) - default |
| 3 | 21 | Large dogs (Labradors, Goldens) |
| 2 | 14 | Giant dogs (Great Danes, Mastiffs) |
Selection Algorithm¶
function getOptimalFrequency(daysSupply) {
const frequencies = [6, 5, 4, 3, 2]; // weeks, longest first
const minBuffer = 3; // minimum days buffer before running out
for (const weeks of frequencies) {
const deliveryDays = weeks * 7;
if (daysSupply >= deliveryDays + minBuffer) {
return weeks;
}
}
return 2; // fallback to minimum frequency
}
Selection Logic Explained¶
The algorithm picks the longest viable frequency (to minimise delivery frequency and handling) while ensuring the customer never runs out (minimum 3-day buffer).
Example: 200g/day dog with 8kg box - Days supply: 8000 ÷ 200 = 40 days - Check 6 weeks: 40 ≥ 42 + 3? No (40 < 45) - Check 5 weeks: 40 ≥ 35 + 3? Yes (40 ≥ 38) ✓ - Result: 5 weeks
Complete Frequency Mapping¶
| Days Supply | 6wk (45+) | 5wk (38+) | 4wk (31+) | 3wk (24+) | 2wk (17+) | Selected |
|---|---|---|---|---|---|---|
| 53 days | ✓ | - | - | - | - | 6 weeks |
| 45 days | ✓ | - | - | - | - | 6 weeks |
| 40 days | ✗ | ✓ | - | - | - | 5 weeks |
| 38 days | ✗ | ✓ | - | - | - | 5 weeks |
| 35 days | ✗ | ✗ | ✓ | - | - | 4 weeks |
| 32 days | ✗ | ✗ | ✓ | - | - | 4 weeks |
| 25 days | ✗ | ✗ | ✗ | ✓ | - | 3 weeks |
| 17 days | ✗ | ✗ | ✗ | ✗ | ✓ | 2 weeks |
Box Recommendation Logic¶
Algorithm¶
function calculateBoxRecommendation(dailyGrams, totalCalories) {
const boxOptions = [
{ size: '8kg', grams: 8000, price: 89 },
{ size: '12kg', grams: 12000, price: 109 },
{ size: '16kg', grams: 16000, price: 129 }
];
// Find smallest box that lasts at least 2 weeks with 3-day buffer
for (const box of boxOptions) {
const daysSupply = Math.floor(box.grams / dailyGrams);
if (daysSupply >= 17) { // 14 days + 3 day buffer
return {
recommendedBox: box.size,
daysSupply: daysSupply,
frequency: getOptimalFrequency(daysSupply),
trays: box.grams / 500,
// ... other properties
};
}
}
// Fallback: largest box with 2-week frequency
return { recommendedBox: '16kg', frequency: 2, ... };
}
Box Selection Matrix¶
| Daily Grams | 8kg Days | 12kg Days | 16kg Days | Recommended |
|---|---|---|---|---|
| ≤200g | 40+ | 60+ | 80+ | 8kg |
| 201-300g | 26-39 | 40-59 | 53-79 | 8kg or 12kg |
| 301-470g | 17-26 | 25-39 | 34-52 | 12kg |
| 471-940g | <17 | 12-25 | 17-33 | 16kg |
| >940g | <17 | <17 | <17 | 16kg (2wk) |
Alternative Box Display Logic¶
The Rules¶
if (recommendedBox === '8kg') {
// Small dogs: show 12kg PROMINENTLY as better value
alternativeBox = '12kg';
alternativeType = 'value';
showProminently = true;
} else if (recommendedBox === '12kg') {
// Medium dogs: show 16kg SUBTLY as better value (if viable)
if (daysSupply16kg <= 56) { // Less than 8 weeks
alternativeBox = '16kg';
alternativeType = 'value';
showProminently = false;
} else {
// 16kg would last too long, show 8kg as convenience
alternativeBox = '8kg';
alternativeType = 'convenience';
showProminently = false;
}
} else {
// Large dogs (16kg): show 12kg subtly as convenience
alternativeBox = '12kg';
alternativeType = 'convenience';
showProminently = false;
}
Display Rationale¶
| Recommended | Alternative | Type | Prominent? | Reasoning |
|---|---|---|---|---|
| 8kg | 12kg | Value | Yes | Better £/g, encourage upsell |
| 12kg | 16kg | Value | No | Don't overwhelm medium dogs |
| 12kg | 8kg | Convenience | No | If 16kg too long-lasting |
| 16kg | 12kg | Convenience | No | Already optimal size |
Smaller First Delivery Option¶
Eligibility¶
Only available when all conditions are met: - Calculator recommends 12kg box - Alternative box is 16kg (value type) - 16kg box lasts ≤ 56 days (8 weeks)
Logic in calculateBoxRecommendation()¶
let showFirstDeliveryOption = false;
let firstDeliveryBox = null;
if (recommendedBox === '12kg' && alternativeBox === '16kg') {
showFirstDeliveryOption = true;
firstDeliveryBox = '8kg';
firstDeliveryDaysSupply = daysSupply8kg;
firstDeliveryWeeks = getOptimalFrequency(daysSupply8kg);
firstDeliveryWeeklyPrice = Math.round(PRICING.box8kg.firstDelivery / (daysSupply8kg / 7));
}
Treat Adjustment Interaction¶
| Treat Level | 16kg Days Supply | Alt Still Valid? | First Delivery Shown? |
|---|---|---|---|
| None | ≤ 45 days | Yes (16kg value) | ✅ Yes |
| Some | May exceed 45 days | Depends | Depends |
| Lots | Likely > 45 days | No → flips to 8kg convenience | ⌠Hidden |
When treats cause the 16kg alternative to exceed the 45-day maximum (altMaxDays = 6 * 7 + 3), the alternative flips from 16kg value to 8kg convenience. The first delivery option hides because the 8kg convenience link already serves the same purpose.
When the customer changes back to a treat level where the 16kg alternative is valid again, the first delivery option reappears.
Display Matrix (Updated)¶
| Recommended | Alternative | Type | Prominent? | First Delivery? | Reasoning |
|---|---|---|---|---|---|
| 8kg | 12kg | Value | Yes | No | Already smallest box |
| 12kg | 16kg | Value | No | Yes (8kg) | Practical freezer step-down |
| 12kg | 8kg | Convenience | No | No | Alt already points to 8kg |
| 16kg | 12kg | Convenience | No | No | 8kg would be two steps down |
Pricing Display Strategy¶
The Core Insight¶
The phrasing determines which mental calculation customers perform:
| Display | Customer Calculates | Result |
|---|---|---|
| "£89 every 4 weeks" | 4 weeks × £18/week = £72 | ≠ £89 → doubt |
| "£89 per box" | £89 ÷ 5 weeks = £18/week | ✓ correct |
Price Anchoring Strategy¶
Calculator: Shows weekly price (consumption-based) + "per box" total
Product Page: Leads with ongoing price, discount as bonus
Pricing Constants¶
PRICING: {
box8kg: { regular: 89, firstDelivery: 69, trays: 16 },
box12kg: { regular: 109, firstDelivery: 89, trays: 24 },
box16kg: { regular: 129, firstDelivery: 109, trays: 32 },
traySize: 500
}
Freezer Guidance¶
Data Structure¶
FREEZER_DRAWER_MAP: {
'8kg': { trays: 16, drawers: '1' },
'12kg': { trays: 24, drawers: '1.5' },
'16kg': { trays: 32, drawers: '2' }
}
Display Implementation¶
// FREEZER GUIDANCE - integrated into box details
const freezerInfo = PROTOCOL_RAW_V3_1.FREEZER_DRAWER_MAP[plan.recommendedBox];
document.getElementById('box-freezer').textContent =
`Fits approximately ${freezerInfo.drawers} freezer drawers`;
HTML Structure¶
<div class="box-details">
<p class="box-contents" id="box-contents">24 trays (500g each) - 12kg Box</p>
<p class="box-duration" id="box-duration">Lasts approximately 32 days</p>
<p class="box-freezer" id="box-freezer">Fits approximately 1.5 freezer drawers</p>
</div>
CSS¶
.box-freezer {
font-family: 'Inter', sans-serif;
font-size: 14px;
color: var(--col-taupe);
margin: 4px 0 0 0;
}
/* Mobile */
@media (max-width: 768px) {
.box-freezer {
font-size: 13px;
}
}
Visual Identity Alignment¶
Colour Corrections (v6.0)¶
| Variable | Old Value | New Value | Reference |
|---|---|---|---|
--col-cream |
#FEFDF7 | #F9F7F4 | Visual Identity Guide v2.2 |
.portion-unit |
--col-warm-gray |
--col-taupe |
Readability fix |
.badge-content p |
--col-warm-gray |
--col-taupe |
Readability fix |
.price-period-hero |
--col-warm-gray |
--col-taupe |
Readability fix |
Colour Reference¶
| Name | Hex | Usage |
|---|---|---|
| Cream | #F9F7F4 | Calculator background |
| Taupe | #6B6360 | Secondary text (readable) |
| Warm Gray | #918A85 | Meta/timestamps only |
| Espresso | #2B2523 | Body text |
Testing & Validation¶
Test 1: 15kg Adult Anchor (MUST PASS)¶
Input: Adult, 15kg, neutered, moderate, ideal
Expected: - Daily grams: 375g ✅ - Recommended box: 12kg ✅ - Days supply: 32 days ✅ - Frequency: 4 weeks ✅ - Weekly price: £24 ✅ - Freezer guidance: "Fits approximately 1.5 freezer drawers" ✅
Test 2: 200g/day Dog (5-Week Cadence)¶
Input: Adult, ~9kg dog, neutered, moderate, ideal → 200g/day
Expected: - Daily grams: 200g ✅ - Recommended box: 8kg ✅ - Days supply: 40 days ✅ - Frequency: 5 weeks ✅ (NOT 4 weeks) - Buffer: 5 days ✅ - Weekly price: £16 ✅ (89 ÷ 5.7 weeks) - Freezer guidance: "Fits approximately 1 freezer drawers" ✅
Test 3: 8kg Cavalier (225g/day)¶
Input: Adult, 8kg, neutered, moderate, ideal
Expected: - Daily grams: 225g ✅ - Recommended box: 8kg ✅ - Days supply: 35 days ✅ - Frequency: 4 weeks ✅ (35 < 38 threshold for 5wk) - Buffer: 7 days ✅ - Weekly price: £18 ✅
Test 4: Very Small Dog (150g/day)¶
Input: Adult, 5kg, neutered, low activity, ideal → ~150g/day
Expected: - Daily grams: 150g ✅ - Recommended box: 8kg ✅ - Days supply: 53 days ✅ - Frequency: 6 weeks ✅ - Buffer: 11 days ✅ - Weekly price: £12 ✅
Test 5: 30kg Golden (Large Dog)¶
Input: Adult, 30kg, neutered, moderate, ideal
Expected: - Daily grams: 625g ✅ - Recommended box: 16kg ✅ - Days supply: 25 days ✅ - Frequency: 3 weeks ✅ - Buffer: 4 days ✅ - Weekly price: £36 ✅ - Freezer guidance: "Fits approximately 2 freezer drawers" ✅
Test 6: 50kg Giant Dog¶
Input: Adult, 50kg, neutered, moderate, ideal
Expected: - Daily grams: 925g ✅ - Recommended box: 16kg ✅ - Days supply: 17 days ✅ - Frequency: 2 weeks ✅ - Buffer: 3 days ✅ - Weekly price: £53 ✅
Test 7: All Frequencies Have Adequate Buffer¶
| Frequency | Min Days Supply | Buffer |
|---|---|---|
| 6 weeks | 45 days | ≥3 days ✅ |
| 5 weeks | 38 days | ≥3 days ✅ |
| 4 weeks | 31 days | ≥3 days ✅ |
| 3 weeks | 24 days | ≥3 days ✅ |
| 2 weeks | 17 days | ≥3 days ✅ |
Complete Frequency Test Matrix¶
| Daily Grams | Box | Days Supply | Frequency | Buffer | Weekly £ |
|---|---|---|---|---|---|
| 150g | 8kg | 53 | 6 weeks | 11 days | £12 |
| 175g | 8kg | 45 | 6 weeks | 3 days | £14 |
| 200g | 8kg | 40 | 5 weeks | 5 days | £16 |
| 225g | 8kg | 35 | 4 weeks | 7 days | £18 |
| 275g | 12kg | 43 | 6 weeks | 1 day | £18 |
| 300g | 12kg | 40 | 5 weeks | 5 days | £19 |
| 375g | 12kg | 32 | 4 weeks | 4 days | £24 |
| 500g | 16kg | 32 | 4 weeks | 4 days | £28 |
| 625g | 16kg | 25 | 3 weeks | 4 days | £36 |
| 925g | 16kg | 17 | 2 weeks | 3 days | £53 |
v6.4 Specific Testing Checklist¶
- [ ] 12kg recommended + 16kg value alt → "Smaller first delivery?" link appears
- [ ] 8kg recommended → first delivery option hidden
- [ ] 16kg recommended → first delivery option hidden
- [ ] 12kg recommended + 8kg convenience alt → first delivery option hidden
- [ ] First delivery link points to 8kg product page with
optimal_box=12kg&first_order_downsize=true - [ ] Treat "Lots" flips alt to 8kg convenience → first delivery option hides
- [ ] Treat "None" restores 16kg value alt → first delivery option reappears
- [ ] First delivery option uses
alternative-option-subtlestyling (consistent with existing alt) - [ ] Multi-pet calculation: first delivery option still works correctly
v6.0 Specific Testing Checklist¶
- [ ] 15kg anchor dog shows "Fits approximately 1.5 freezer drawers"
- [ ] 8kg box shows "Fits approximately 1 freezer drawers"
- [ ] 16kg box shows "Fits approximately 2 freezer drawers"
- [ ] All "pouch" references now say "tray"
- [ ] Cream background matches
#F9F7F4 - [ ] Portion unit text is readable (Taupe, not Warm Gray)
- [ ] Method badge description is readable (Taupe, not Warm Gray)
- [ ] "per week" text is readable (Taupe, not Warm Gray)
v6.1 Specific Testing Checklist¶
- [ ] 15kg anchor shows buffer line: "Lasts approximately 32 days · skip, pause or change frequency anytime"
- [ ] 475g/day (16kg box) shows: "Lasts approximately 33 days"
- [ ] 200g/day (8kg box) shows: "Lasts approximately 40 days"
- [ ] 925g/day (16kg box) shows: "Lasts approximately 17 days"
- [ ] Buffer line hidden when no calculator URL params present
- [ ] Buffer line displays correctly in multi-pet view
- [ ] Buffer line uses Taupe colour (#6B6360) at 13px
Implementation Checklist¶
Calculator Code (v6.0)¶
- [ ] Add
FREEZER_DRAWER_MAPconstant - [ ] Update
PRICINGconstant to usetraysinstead ofpouches - [ ] Add freezer guidance DOM update in
updateResults() - [ ] Update all "pouch" text to "tray"
- [ ] Fix
--col-creamto#F9F7F4 - [ ] Change
.portion-unitcolour to Taupe - [ ] Change
.badge-content pcolour to Taupe - [ ] Change
.price-period-herocolour to Taupe - [ ] Add
.box-freezerCSS styles
Seal Subscriptions¶
- [ ] Verify 5-week interval exists (Seal ID:
712350990711) - [ ] Verify interval appears in customer portal
- [ ] Test subscription creation with all frequencies
Product Page¶
- [ ] Verify frequency dropdown includes all options (2-6 weeks)
- [ ] Test checkout flow with each frequency
- [ ] Verify Seal frequency sync from URL parameter
- [ ] Buffer line displays correct days supply for all box/grams combinations
- [ ] Buffer line hidden when visiting product page without calculator params
Files & Code Reference¶
Files Changed (v6.4)¶
| File | Changes |
|---|---|
sections/feed-calculator.liquid |
First delivery HTML, JS logic, treat interaction |
sections/feed-calculator-minimal.liquid |
Same changes (keep in sync — pending) |
Files Changed (v6.1)¶
| File | Changes |
|---|---|
sections/main-product.liquid |
Added buffer/flexibility line (HTML, CSS, JS) |
Files Changed (v6.0)¶
| File | Changes |
|---|---|
sections/feed-calculator.liquid |
All v6.0 changes (freezer, trays, colours) |
sections/feed-calculator-minimal.liquid |
Same changes (keep in sync) |
Files Changed (v5.5)¶
| File | Changes |
|---|---|
sections/feed-calculator.liquid |
JS frequency logic (5-week) |
sections/feed-calculator-minimal.liquid |
JS frequency logic (5-week) |
sections/main-product.liquid |
Seal frequency sync |
Seal Subscriptions Frequency IDs¶
const sealFrequencyMap = {
'2': '712286208375',
'3': '712286241143',
'4': '712286175607',
'5': '712350990711',
'6': '712286273911',
'7': '712351023479',
'8': '712286306679'
};
Seal Frequency Sync Code¶
// ============================================================
// SET SEAL SUBSCRIPTIONS FREQUENCY FROM URL PARAMETER
// ============================================================
function setSealFrequency() {
const sealSelect = document.querySelector('select.sls-select');
if (!sealSelect || !weeks) return;
const sealFrequencyMap = {
'2': '712286208375',
'3': '712286241143',
'4': '712286175607',
'5': '712350990711',
'6': '712286273911',
'7': '712351023479',
'8': '712286306679'
};
const targetValue = sealFrequencyMap[weeks];
if (targetValue && sealSelect.value !== targetValue) {
sealSelect.value = targetValue;
sealSelect.dispatchEvent(new Event('change', { bubbles: true }));
console.log(`[Protocol Raw] Set Seal frequency to ${weeks} weeks (ID: ${targetValue})`);
}
}
if (document.querySelector('select.sls-select')) {
setSealFrequency();
} else {
const sealObserver = new MutationObserver((mutations, obs) => {
if (document.querySelector('select.sls-select')) {
setSealFrequency();
obs.disconnect();
}
});
sealObserver.observe(document.body, { childList: true, subtree: true });
setTimeout(setSealFrequency, 2000);
}
Version History¶
v6.4 - February 3, 2026 (CURRENT)¶
Changes:
✅ "Smaller first delivery" option for 12kg customers
✅ Calculates 8kg first-delivery data when 12kg recommended + 16kg value alternative
✅ New URL parameters: optimal_box and first_order_downsize passed to product page
✅ Treat adjustment hides first delivery when alternative flips to 8kg convenience
✅ Treat adjustment restores first delivery when original 16kg alternative remains valid
Purpose: Reduce freezer anxiety for medium-dog customers by offering a practical one-step-down first delivery, with clear messaging about the Box-2 transition to their optimal size.
Design principle applied: Practical logistics, not emotional hand-holding. Framed as a freezer convenience choice, never as a trial.
Files Modified:
- sections/feed-calculator.liquid
v6.1 - February 3, 2026 (SUPERSEDED)¶
Changes:
✅ Added buffer/flexibility line to product page calculator banner
✅ Shows "Lasts approximately X days · skip, pause or change frequency anytime"
Purpose: Reduce purchase hesitation by making the delivery buffer visible and subscription flexibility explicit at the point of commitment.
Design principle applied: Information without friction. Same philosophy as calculator freezer guidance.
Files Modified:
- sections/main-product.liquid
v6.0 - January 27, 2026 (SUPERSEDED)¶
Changes:
✅ Added freezer guidance as integrated line in box details
✅ Changed "pouches" to "trays" throughout
✅ Fixed Cream colour (#FEFDF7 → #F9F7F4)
✅ Fixed Warm Gray → Taupe for three text elements
Design principle applied: Information without friction. Freezer guidance answers the question without creating a decision point.
Files Modified:
- sections/feed-calculator.liquid
- sections/feed-calculator-minimal.liquid
v5.5 - November 29, 2025 (SUPERSEDED)¶
Changes:
✅ Added 5-week delivery cadence option
✅ Updated getOptimalFrequency to include 5-week threshold
✅ Small/medium dogs now get optimal delivery timing
✅ All test cases passing including new 5-week scenarios
Impact: - 15kg anchor unchanged (£24/week) ✅ - 200g/day dogs now get 5-week delivery (was 4-week) - Reduces customer "paying too early" friction - Better alignment between food consumption and billing
Files Modified:
- sections/feed-calculator.liquid (JS frequency logic)
- sections/feed-calculator-minimal.liquid (JS frequency logic)
- sections/main-product.liquid (Seal frequency sync)
- Seal Subscriptions settings (5-week interval already exists)
v5.4 - November 28, 2025 (SUPERSEDED)¶
Changes:
✅ Fixed pricing display: "£X per box" instead of "£X every Y weeks"
✅ Fixed missing DOM updates (box-contents, box-duration, human-readable)
✅ Fixed product page weekly price calculation (consumption-based)
✅ Restructured product page to lead with regular price, discount as bonus
v5.3 - November 28, 2025 (SUPERSEDED)¶
Changes:
✅ Fixed alternative box logic (small dogs get prominent 12kg value option)
✅ Fixed frequency fallback (return 2, not 4)
✅ Removed puppy email optin (handled by Customer.io post-purchase)
✅ Added showProminently and alternativeType to box recommendation
v5.2 - November 27, 2025 (SUPERSEDED)¶
- Mobile optimizations v2.0
- Multipet support refinements
- Various bug fixes
v3.1 - November 24, 2025 (SUPERSEDED)¶
- Senior-specific MER factors implemented
- calculateMER accepts lifeStage parameter
v3.0 - November 10, 2025 (SUPERSEDED)¶
- Life stage system (Puppy/Adult/Senior)
- Puppy age-based multipliers
- Educational content
- Email opt-in system (removed in v5.3)
v2.1 - October 30, 2025 (SUPERSEDED)¶
- MER multipliers corrected
- 15kg anchor = £24/week established
Documentation complete. v6.4 ready to deploy. 🚀¶
Smaller first delivery, buffer line, and freezer guidance answer questions without creating friction. £24/week anchor preserved.
END OF DOCUMENTATION