{"id":"tide-writes-flow","title":"The tide writes FLOW","category":"Typography","prompt":"Water as typography. Deep teal background with a waves generator across the lower half. The word 'FLOW' huge in the center as display lettering with a gradient from white to cyan, distorted by a wave that travels through the letters (wave_through relation). A sparkle effect drifting over the crest line. Nothing else — let the word and the water carry it.","designedBy":{"provider":"anthropic","model":"claude-fable-5","inference":{"inputTokens":0,"outputTokens":0,"costUsd":0,"inPerMTokUsd":10,"outPerMTokUsd":50,"interactive":true}},"render":{"jobId":"rnd_1788538019137_f1fhln","credits":2,"priceUsd":0.03,"format":"gif","renderMs":12002,"frameCount":80,"bytes":2588814,"seed":1264941116,"engineVersion":"v0.5.6","width":960,"height":720,"fps":20,"durationSeconds":4},"howToReproduce":{"renderApi":"POST /v1/renders with `renderRequest` below as the body (Authorization: Bearer <your pp_sa_… key>).","editor":"/gallery/tide-writes-flow/editor opens this piece live in the studio.","codeConsole":"/gallery/tide-writes-flow.js is this piece as PinePaper code — paste it into the editor's AI code console."},"renderRequest":{"scene":{"canvas":{"width":800,"height":600},"items":[],"relations":[],"generators":[],"media":[],"skeletons":[],"background":"#02222b","engineOps":[{"tool":"execute_custom_code","args":{"description":"Original sea: four sampled sine bands on individual swells, crest foam, and FLOW bobbing letter by letter","code":"function prng(seed){var t=seed>>>0;return function(){t+=0x6D2B79F5;var r=Math.imul(t^(t>>>15),1|t);r^=r+Math.imul(r^(r>>>7),61|r);return((r^(r>>>14))>>>0)/4294967296;}}\nvar r = prng(3141592);\n// Four translucent wave bands, back to front, each its own path.\nvar bands = [\n  { base: 355, amp: 12, wl: 190, color: '#0d4f5c', op: 0.55, drift: 0.10 },\n  { base: 395, amp: 16, wl: 150, color: '#12707f', op: 0.6, drift: 0.14 },\n  { base: 440, amp: 20, wl: 120, color: '#1897a5', op: 0.65, drift: 0.2 },\n  { base: 490, amp: 24, wl: 95, color: '#22b8cf', op: 0.7, drift: 0.28 }\n];\nfor (var b = 0; b < bands.length; b++) {\n  var band = bands[b];\n  var pts = [];\n  for (var sx = -40; sx <= 840; sx += 14) {\n    pts.push([sx, band.base + Math.sin((sx / band.wl) * Math.PI * 2 + b * 1.7) * band.amp]);\n  }\n  pts.push([840, 640]); pts.push([-40, 640]); // close under the canvas\n  var id = PinePaper.create('path', { points: pts, closed: true, fillColor: band.color, opacity: band.op });\n  PinePaper.addRelation(id, null, 'wiggle', { frequency: band.drift, amplitude: 7 + b * 3, seed: 42 + b });\n}\n// Foam: 18 tiny white sparks popping along the top band's crest line.\nfor (var f = 0; f < 18; f++) {\n  var fx = 20 + r() * 760;\n  var fy = 352 + Math.sin((fx / 190) * Math.PI * 2) * 12 - 2;\n  var foam = PinePaper.create('circle', { x: fx, y: fy, radius: 1.2 + r() * 1.8, fillColor: '#e0fbff', opacity: 0.8 });\n  PinePaper.animate(foam, { animationType: 'fade', speed: 0.5 + r() * 1.6 });\n}\n// FLOW — four letters riding the water, bobbing out of phase.\n// A FIXED 96px advance is not letterspacing, it is luck: at 150px Roboto\n// Bold the caps measure F 86, L 84, O 118, W 148, so a constant step left\n// a hole after the F and drove the O and the W into each other — the word\n// rendered as 'F LOW'. Set each letter down at the centre of its OWN\n// measured box and advance by that width plus one tracking value, which is\n// what a type case does and what makes the spacing survive a font change.\nvar letters = ['F', 'L', 'O', 'W'], TRACK = 20;\nvar glyphs = [], widths = [], total = 0;\nfor (var L = 0; L < 4; L++) {\n  var lid = PinePaper.create('text', {\n    x: 400, y: 235, content: letters[L], fontSize: 150, fontWeight: 'bold',\n    fillColor: { type: 'linear', stops: [ { color: '#f8fdff' }, { color: '#7dd3fc' }, { color: '#0e7490' } ], angle: 90 }\n  });\n  var wv = 90; try { wv = lid.bounds.width; } catch (e) {}\n  glyphs.push(lid); widths.push(wv); total += wv;\n}\ntotal += TRACK * (letters.length - 1);\nvar penX = 400 - total / 2;\nfor (var L = 0; L < glyphs.length; L++) {\n  PinePaper.modifyItem(glyphs[L], { x: penX + widths[L] / 2 });\n  penX += widths[L] + TRACK;\n  PinePaper.addRelation(glyphs[L], null, 'wiggle', { frequency: 0.22 + L * 0.05, amplitude: 6, seed: 100 + L });\n}"}},{"tool":"execute_custom_code","args":{"description":"Caption","code":"var c = PinePaper.create('text', { x: 400, y: 320, content: '', fontSize: 18, fillColor: '#bfe6f2' });\nPinePaper.modifyItem(c, { animationType: 'keyframe', duration: 4, keyframes: [{ time: 0, properties: { content: '' } }, { time: 0.30, properties: { content: '' } }, { time: 0.355, properties: { content: 't' } }, { time: 0.410, properties: { content: 'th' } }, { time: 0.465, properties: { content: 'the' } }, { time: 0.520, properties: { content: 'the ' } }, { time: 0.575, properties: { content: 'the g' } }, { time: 0.630, properties: { content: 'the gr' } }, { time: 0.685, properties: { content: 'the gra' } }, { time: 0.740, properties: { content: 'the grap' } }, { time: 0.795, properties: { content: 'the graph' } }, { time: 0.850, properties: { content: 'the graph ' } }, { time: 0.905, properties: { content: 'the graph i' } }, { time: 0.960, properties: { content: 'the graph is' } }, { time: 1.015, properties: { content: 'the graph is ' } }, { time: 1.070, properties: { content: 'the graph is t' } }, { time: 1.125, properties: { content: 'the graph is th' } }, { time: 1.180, properties: { content: 'the graph is the' } }, { time: 1.235, properties: { content: 'the graph is the ' } }, { time: 1.290, properties: { content: 'the graph is the t' } }, { time: 1.345, properties: { content: 'the graph is the ti' } }, { time: 1.400, properties: { content: 'the graph is the tid' } }, { time: 1.455, properties: { content: 'the graph is the tide' } }, { time: 4.00, properties: { content: 'the graph is the tide' } }] });"}}]},"exportProfile":{"format":"gif","resolution":"1080p","fps":30,"durationSeconds":6},"source":{"prompt":"Water as typography. Deep teal background with a waves generator across the lower half. The word 'FLOW' huge in the center as display lettering with a gradient from white to cyan, distorted by a wave that travels through the letters (wave_through relation). A sparkle effect drifting over the crest line. Nothing else — let the word and the water carry it.","provider":"anthropic","model":"claude-fable-5","app":"gallery-reproduction"}},"ops":[{"tool":"pinepaper_set_background_color","args":{"color":"#02222b"}},{"tool":"pinepaper_execute_custom_code","args":{"description":"Original sea: four sampled sine bands on individual swells, crest foam, and FLOW bobbing letter by letter","code":"function prng(seed){var t=seed>>>0;return function(){t+=0x6D2B79F5;var r=Math.imul(t^(t>>>15),1|t);r^=r+Math.imul(r^(r>>>7),61|r);return((r^(r>>>14))>>>0)/4294967296;}}\nvar r = prng(3141592);\n// Four translucent wave bands, back to front, each its own path.\nvar bands = [\n  { base: 355, amp: 12, wl: 190, color: '#0d4f5c', op: 0.55, drift: 0.10 },\n  { base: 395, amp: 16, wl: 150, color: '#12707f', op: 0.6, drift: 0.14 },\n  { base: 440, amp: 20, wl: 120, color: '#1897a5', op: 0.65, drift: 0.2 },\n  { base: 490, amp: 24, wl: 95, color: '#22b8cf', op: 0.7, drift: 0.28 }\n];\nfor (var b = 0; b < bands.length; b++) {\n  var band = bands[b];\n  var pts = [];\n  for (var sx = -40; sx <= 840; sx += 14) {\n    pts.push([sx, band.base + Math.sin((sx / band.wl) * Math.PI * 2 + b * 1.7) * band.amp]);\n  }\n  pts.push([840, 640]); pts.push([-40, 640]); // close under the canvas\n  var id = PinePaper.create('path', { points: pts, closed: true, fillColor: band.color, opacity: band.op });\n  PinePaper.addRelation(id, null, 'wiggle', { frequency: band.drift, amplitude: 7 + b * 3, seed: 42 + b });\n}\n// Foam: 18 tiny white sparks popping along the top band's crest line.\nfor (var f = 0; f < 18; f++) {\n  var fx = 20 + r() * 760;\n  var fy = 352 + Math.sin((fx / 190) * Math.PI * 2) * 12 - 2;\n  var foam = PinePaper.create('circle', { x: fx, y: fy, radius: 1.2 + r() * 1.8, fillColor: '#e0fbff', opacity: 0.8 });\n  PinePaper.animate(foam, { animationType: 'fade', speed: 0.5 + r() * 1.6 });\n}\n// FLOW — four letters riding the water, bobbing out of phase.\n// A FIXED 96px advance is not letterspacing, it is luck: at 150px Roboto\n// Bold the caps measure F 86, L 84, O 118, W 148, so a constant step left\n// a hole after the F and drove the O and the W into each other — the word\n// rendered as 'F LOW'. Set each letter down at the centre of its OWN\n// measured box and advance by that width plus one tracking value, which is\n// what a type case does and what makes the spacing survive a font change.\nvar letters = ['F', 'L', 'O', 'W'], TRACK = 20;\nvar glyphs = [], widths = [], total = 0;\nfor (var L = 0; L < 4; L++) {\n  var lid = PinePaper.create('text', {\n    x: 400, y: 235, content: letters[L], fontSize: 150, fontWeight: 'bold',\n    fillColor: { type: 'linear', stops: [ { color: '#f8fdff' }, { color: '#7dd3fc' }, { color: '#0e7490' } ], angle: 90 }\n  });\n  var wv = 90; try { wv = lid.bounds.width; } catch (e) {}\n  glyphs.push(lid); widths.push(wv); total += wv;\n}\ntotal += TRACK * (letters.length - 1);\nvar penX = 400 - total / 2;\nfor (var L = 0; L < glyphs.length; L++) {\n  PinePaper.modifyItem(glyphs[L], { x: penX + widths[L] / 2 });\n  penX += widths[L] + TRACK;\n  PinePaper.addRelation(glyphs[L], null, 'wiggle', { frequency: 0.22 + L * 0.05, amplitude: 6, seed: 100 + L });\n}"}},{"tool":"pinepaper_execute_custom_code","args":{"description":"Caption","code":"var c = PinePaper.create('text', { x: 400, y: 320, content: '', fontSize: 18, fillColor: '#bfe6f2' });\nPinePaper.modifyItem(c, { animationType: 'keyframe', duration: 4, keyframes: [{ time: 0, properties: { content: '' } }, { time: 0.30, properties: { content: '' } }, { time: 0.355, properties: { content: 't' } }, { time: 0.410, properties: { content: 'th' } }, { time: 0.465, properties: { content: 'the' } }, { time: 0.520, properties: { content: 'the ' } }, { time: 0.575, properties: { content: 'the g' } }, { time: 0.630, properties: { content: 'the gr' } }, { time: 0.685, properties: { content: 'the gra' } }, { time: 0.740, properties: { content: 'the grap' } }, { time: 0.795, properties: { content: 'the graph' } }, { time: 0.850, properties: { content: 'the graph ' } }, { time: 0.905, properties: { content: 'the graph i' } }, { time: 0.960, properties: { content: 'the graph is' } }, { time: 1.015, properties: { content: 'the graph is ' } }, { time: 1.070, properties: { content: 'the graph is t' } }, { time: 1.125, properties: { content: 'the graph is th' } }, { time: 1.180, properties: { content: 'the graph is the' } }, { time: 1.235, properties: { content: 'the graph is the ' } }, { time: 1.290, properties: { content: 'the graph is the t' } }, { time: 1.345, properties: { content: 'the graph is the ti' } }, { time: 1.400, properties: { content: 'the graph is the tid' } }, { time: 1.455, properties: { content: 'the graph is the tide' } }, { time: 4.00, properties: { content: 'the graph is the tide' } }] });"}}],"license":"CC0-1.0"}