# Recipe DAG — matcha white chocolate cookies
# Source: Edd Kimber, "Small Batch Cookies" (instructions paraphrased; quantities as published)
#
# Schema notes:
#   - Steps transform products; the dependency graph is implied by inputs/outputs.
#   - `hold` lives on the product. Attention is modelled as bursts. Scaling limits
#     attach to vessels via `fits`; steps only say how their time scales.
#   - Scales in whole batches of 6 (one egg each, 6 to a tray); more trays bake together.
#     Bicarb and baking powder scale with the batch too.
#   - Durations: "15s", "5m", "1h", or {min, expected, max}.

recipe:
  id: matcha_white_choc_cookies
  code: matcha-cookies   # short URL: /matcha-cookies
  category: Sweet
  title: Matcha & white chocolate cookies
  yield: { servings: 6, unit: cookie, options: [6, 12, 18] }

derived:
  trays: "=ceil(n / 6)"

resources:
  cook:        { kind: cook,   capacity: 1 }
  oven:        { kind: oven,   capacity: 1, state: { key: temperature, setup: 12m } }
  bowl:        { kind: vessel, capacity: 1 }
  hand_mixer:  { kind: tool,   capacity: 1 }
  board:       { kind: tool,   capacity: 1 }
  knife:       { kind: tool,   capacity: 1 }
  baking_tray: { kind: vessel, capacity: 1, fits: { amount: 6, unit: cookie } }
  fridge:      { kind: fridge, capacity: 1 }
  wire_rack:   { kind: rack,   capacity: 1, fits: { amount: 12, unit: cookie } }

products:
  butter:          { kind: ingredient, qty: { amount: 60, unit: g, scale: linear }, name: "unsalted butter, room temp" }
  caster_sugar:    { kind: ingredient, qty: { amount: 40, unit: g, scale: linear } }
  brown_sugar:     { kind: ingredient, qty: { amount: 40, unit: g, scale: linear }, name: light brown sugar }
  matcha:          { kind: ingredient, qty: { amount: 1, unit: tbsp, scale: linear }, name: matcha powder (culinary grade) }
  egg:             { kind: ingredient, qty: { amount: 1, unit: large, scale: linear } }
  vanilla:         { kind: ingredient, qty: { amount: 0.25, unit: tsp, scale: linear }, name: vanilla bean paste }
  flour:           { kind: ingredient, qty: { amount: 125, unit: g, scale: linear }, name: plain flour }
  bicarb:          { kind: ingredient, qty: { amount: 0.25, unit: tsp, scale: linear }, name: bicarbonate of soda }
  baking_powder:   { kind: ingredient, qty: { amount: 0.125, unit: tsp, scale: linear } }
  salt:            { kind: ingredient, qty: { amount: 0.25, unit: tsp, scale: linear }, name: fine sea salt }
  white_chocolate: { kind: ingredient, qty: { amount: 50, unit: g, scale: linear } }

  chocolate_chopped: { kind: intermediate, state: roughly chopped, hold: { max: 4h } }
  creamed_base:      { kind: intermediate, state: light and fluffy, vessel: bowl, hold: { max: 15m, then: butter starts to separate } }
  wet_mix:           { kind: intermediate, state: matcha, egg and vanilla beaten in, vessel: bowl, hold: { max: 15m } }
  dough:             { kind: intermediate, state: evenly mixed dough, vessel: bowl, hold: { max: 10m } }
  dough_studded:     { kind: intermediate, state: chocolate folded through, vessel: bowl, hold: { max: 10m } }
  dough_chilled:     { kind: intermediate, state: firm, chilled, vessel: bowl, hold: { max: 24h, then: still fine; longer chill deepens flavour } }
  oven_ready:        { kind: intermediate, state: 180°C / 160°C fan / gas 4 }
  tray_lined:        { kind: intermediate, state: lined with parchment, vessel: baking_tray, hold: { max: 24h } }
  dough_balls:       { kind: intermediate, state: 6 balls, 5 cm apart, vessel: baking_tray, hold: { max: 20m, then: dough softens and spreads more } }
  cookies_baked:     { kind: intermediate, state: edges lightly browned, centre soft, vessel: baking_tray, hold: { max: 2m, then: carryover bake continues } }
  cookies_set:       { kind: intermediate, state: firm enough to lift, vessel: baking_tray, hold: { max: 10m } }
  cookies:           { kind: final, state: cooled completely, vessel: wire_rack }

steps:
  chop_chocolate:
    title: Chop the chocolate
    text: Roughly chop the white chocolate into chunks.
    inputs: [white_chocolate]
    outputs: [chocolate_chopped]
    phases: [{ kind: active, duration: 2m }]
    uses: [board, knife]
    time_scale: linear

  cream:
    title: Cream butter and sugars
    text: Beat the butter and both sugars with the hand mixer until pale and fluffy.
    inputs: [butter, caster_sugar, brown_sugar]
    outputs: [creamed_base]
    phases: [{ kind: active, duration: { min: 4m, expected: 5m, max: 6m } }]
    done_when: noticeably paler and fluffy
    uses: [bowl, hand_mixer]
    time_scale: fixed

  add_wet:
    title: Add matcha, egg, vanilla
    text: Beat in the matcha, egg and vanilla until fully combined.
    inputs: [creamed_base, matcha, egg, vanilla]
    outputs: [wet_mix]
    phases: [{ kind: active, duration: 1m }]
    done_when: batter is uniformly green, no streaks of egg or vanilla
    uses: [hand_mixer]
    time_scale: fixed

  add_dry:
    title: Add the dry ingredients
    text: Mix in the flour, bicarbonate of soda, baking powder and salt until an even dough forms.
    inputs: [wet_mix, flour, bicarb, baking_powder, salt]
    outputs: [dough]
    phases: [{ kind: active, duration: 1m }]
    done_when: no dry streaks of flour
    uses: [hand_mixer]
    time_scale: fixed

  add_chocolate:
    title: Fold in the chocolate
    text: Mix briefly, just until the chunks are evenly distributed.
    inputs: [dough, chocolate_chopped]
    outputs: [dough_studded]
    phases: [{ kind: active, duration: 30s }]
    done_when: chocolate chunks evenly distributed through the dough
    time_scale: fixed

  chill:
    title: Chill the dough
    text: Cover the bowl and refrigerate.
    inputs: [dough_studded]
    outputs: [dough_chilled]
    phases:
      - { kind: active, duration: 1m }
      - { kind: passive, duration: 1h, timer: true }
    done_when: dough is cold and firm to the touch
    uses: [fridge]
    time_scale: fixed

  preheat:
    title: Preheat the oven
    text: Set the oven to 180°C (160°C fan) / gas mark 4.
    outputs: [oven_ready]
    phases:
      - { kind: active, duration: 15s }
      - { kind: passive, duration: 12m }
    uses: [{ resource: oven, requires: { temperature: 180 } }]
    time_scale: fixed

  line_tray:
    title: Line the tray
    text: Line $trays baking tray(s) with parchment.
    outputs: [tray_lined]
    phases: [{ kind: active, duration: 1m }]
    uses: [baking_tray]
    time_scale: fixed

  shape:
    title: Shape the cookies
    text: Divide the dough into $n equal piece(s), roll into balls and space them 5 cm apart, 6 to a tray.
    inputs: [dough_chilled, tray_lined]
    outputs: [dough_balls]
    phases: [{ kind: active, duration: 4m }]
    time_scale: linear

  bake:
    title: Bake
    text: Bake until the edges are just lightly browned. If you have more than one tray, bake them together.
    inputs: [dough_balls, oven_ready]
    outputs: [cookies_baked]
    phases:
      - { kind: active, duration: 30s }
      - { kind: passive, duration: { min: 14m, expected: 14m, max: 15m }, timer: true }
    done_when: edges just lightly browned, centres still soft
    uses: [{ resource: oven, requires: { temperature: 180 } }]
    time_scale: fixed

  set_on_tray:
    title: Set on the tray
    text: Leave the cookies on the tray to firm up before moving them.
    inputs: [cookies_baked]
    outputs: [cookies_set]
    phases: [{ kind: passive, duration: 5m, timer: true }]
    done_when: firm enough to lift without breaking
    time_scale: fixed

  cool:
    title: Cool on a rack
    text: Transfer to a wire rack and cool completely.
    inputs: [cookies_set]
    outputs: [cookies]
    phases:
      - { kind: active, duration: 1m }
      - { kind: passive, duration: { min: 15m, expected: 20m, max: 30m } }
    done_when: cool to the touch
    uses: [wire_rack]
    time_scale: fixed
