Skip to content

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

  1. Executive Summary
  2. What Changed (v6.1 → v6.4)
  3. What Changed (v6.0 → v6.1)
  4. What Changed (v5.5 → v6.0)
  5. Technical Specifications
  6. Delivery Frequency Logic
  7. Box Recommendation Logic
  8. Alternative Box Display Logic
  9. Smaller First Delivery Option
  10. Pricing Display Strategy
  11. Freezer Guidance
  12. Visual Identity Alignment
  13. Testing & Validation
  14. Implementation Checklist
  15. Files & Code Reference
  16. 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_box and first_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:

  1. HTML (line 411-418): New first-delivery-option div reusing existing alternative-option-subtle class. Zero new CSS required.

  2. 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.

  3. updateResults(): Shows/hides the first delivery element and builds the product page URL with optimal_box=12kg and first_order_downsize=true parameters.

  4. 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:

Smaller first delivery? Start with 8kg, then move to 12kg from Box 2

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:

24 trays (500g each) - 12kg Box
Lasts approximately 32 days
Fits approximately 1.5 freezer drawers

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)

RER = 70 × (bodyWeight in kg)^0.75

2. Maintenance Energy Requirement (MER)

For Adults:

MER = RER × MER_FACTORS[activity][neuteredStatus] × BCS_MULTIPLIERS[bodyCondition]

For Seniors:

MER = RER × SENIOR_MER_FACTORS[activity][neuteredStatus] × BCS_MULTIPLIERS[bodyCondition]

3. Daily Grams

dailyGrams = Math.round(MER / 1.9)  // 1900 kcal/kg = 1.9 kcal/g

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-subtle styling (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_MAP constant
  • [ ] Update PRICING constant to use trays instead of pouches
  • [ ] Add freezer guidance DOM update in updateResults()
  • [ ] Update all "pouch" text to "tray"
  • [ ] Fix --col-cream to #F9F7F4
  • [ ] Change .portion-unit colour to Taupe
  • [ ] Change .badge-content p colour to Taupe
  • [ ] Change .price-period-hero colour to Taupe
  • [ ] Add .box-freezer CSS 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