{
  "id": "showcase-060-iphone-notes-typing",
  "css": "",
  "fps": 30,
  "html": "<div style=\"left:0px;top:0px;width:1080px;height:1920px;background:#FFFDF8;border-radius:0px\" data-jc-track=\"0\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"Notes warm white screen\" data-jc-kind=\"shape\" data-jc-clip=\"\" id=\"shape-1\"></div><div style=\"left:54px;top:18px;width:140px;height:64px;color:#171717;font-family:Inter;font-size:30px;font-weight:700;text-align:left;white-space:normal;background:transparent;display:grid;align-content:center\" data-jc-track=\"1\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"iOS status time\" data-jc-kind=\"text\" data-jc-clip=\"\" id=\"text-1\">9:41</div><div style=\"left:820px;top:18px;width:208px;height:64px;color:#171717;font-family:Inter;font-size:26px;font-weight:700;text-align:right;white-space:normal;background:transparent;display:grid;align-content:center\" data-jc-track=\"1\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"iOS network and battery status\" data-jc-kind=\"text\" data-jc-clip=\"\" id=\"text-2\">5G   87%</div><img src=\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23D59A00%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20class%3D%22lucide%20lucide-chevron-left%22%3E%3Cpath%20d%3D%22m15%2018-6-6%206-6%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E\" style=\"left:42px;top:100px;width:54px;height:54px;object-fit:contain\" data-jc-track=\"2\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"Library / Chevron Left\" data-jc-kind=\"image\" data-jc-clip=\"\" id=\"image-1\"><div style=\"left:92px;top:96px;width:160px;height:62px;color:#D59A00;font-family:Inter;font-size:34px;font-weight:500;text-align:left;white-space:normal;background:transparent;display:grid;align-content:center\" data-jc-track=\"2\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"Notes back label\" data-jc-kind=\"text\" data-jc-clip=\"\" id=\"text-3\">Notes</div><img src=\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23D59A00%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20class%3D%22lucide%20lucide-share%22%3E%3Cpath%20d%3D%22M12%202v13%22%3E%3C%2Fpath%3E%3Cpath%20d%3D%22m16%206-4-4-4%204%22%3E%3C%2Fpath%3E%3Cpath%20d%3D%22M4%2012v8a2%202%200%200%200%202%202h12a2%202%200%200%200%202-2v-8%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E\" style=\"left:850px;top:98px;width:58px;height:58px;object-fit:contain\" data-jc-track=\"2\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"Library / Share\" data-jc-kind=\"image\" data-jc-clip=\"\" id=\"image-2\"><img src=\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23D59A00%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20class%3D%22lucide%20lucide-circle-ellipsis%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%2210%22%3E%3C%2Fcircle%3E%3Cpath%20d%3D%22M17%2012h.01%22%3E%3C%2Fpath%3E%3Cpath%20d%3D%22M12%2012h.01%22%3E%3C%2Fpath%3E%3Cpath%20d%3D%22M7%2012h.01%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E\" style=\"left:962px;top:98px;width:58px;height:58px;object-fit:contain\" data-jc-track=\"2\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"Library / Circle Ellipsis\" data-jc-kind=\"image\" data-jc-clip=\"\" id=\"image-3\"><div style=\"left:120px;top:192px;width:840px;height:44px;color:#A6A5A1;font-family:Inter;font-size:24px;font-weight:500;text-align:center;white-space:normal;background:transparent;display:grid;align-content:center\" data-jc-track=\"2\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"Note edit timestamp\" data-jc-kind=\"text\" data-jc-clip=\"\" id=\"text-4\">3 September 2026 at 9:41</div><div style=\"left:68px;top:276px;width:944px;height:100px;color:#1C1C1E;font-family:Inter;font-size:58px;font-weight:700;text-align:left;white-space:normal;background:transparent;display:grid;align-content:center\" data-jc-track=\"3\" data-jc-duration=\"10\" data-jc-start=\"0\" data-jc-name=\"Editable Notes title\" data-jc-kind=\"text\" data-jc-clip=\"\" id=\"text-5\">Launch notes</div><div id=\"m60-typing-keyboard\" data-jc-clip=\"\" data-jc-kind=\"custom\" data-jc-name=\"Data-driven Notes typing and iPhone keyboard\" data-jc-start=\"0\" data-jc-duration=\"10\" data-jc-track=\"5\" style=\"left:0px;top:392px;width:1080px;height:1528px;background:transparent;overflow:hidden\"></div>",
  "name": "060 — Notes, As They Happen",
  "width": 1080,
  "format": "jsoncut-html",
  "height": 1920,
  "values": {},
  "version": 1,
  "duration": 10,
  "safeArea": {
    "top": 0,
    "left": 0,
    "right": 0,
    "bottom": 0
  },
  "variables": [],
  "customBlocks": [
    {
      "css": "\n#surface{position:relative;width:1080px;height:1528px;overflow:hidden;color:#1c1c1e;font-family:-apple-system,BlinkMacSystemFont,\"SF Pro Text\",\"Helvetica Neue\",Arial,sans-serif}\n#note-copy{position:absolute;left:68px;top:0;width:944px;height:650px;font-size:46px;line-height:1.22;font-weight:400;white-space:pre-wrap;letter-spacing:-.012em}\n#caret{display:inline-block;width:3px;height:49px;margin-left:3px;vertical-align:-8px;background:#1c1c1e;border-radius:2px}\n#keyboard{position:absolute;left:0;top:800px;width:1080px;height:728px;box-sizing:border-box;padding:22px 22px 0;background:linear-gradient(180deg,#d6d8dd,#cdd0d6);border-top:1px solid #b9bcc2;will-change:transform}\n.key-row{display:flex;gap:12px;height:106px;margin-bottom:18px;justify-content:center}\n.key-row.inset{padding:0 48px}\n.key{height:106px;min-width:0;flex:1;display:flex;align-items:center;justify-content:center;box-sizing:border-box;border-radius:13px;background:#fff;color:#111;font-size:34px;font-weight:400;box-shadow:0 3px 1px rgba(70,72,78,.42);transform-origin:50% 100%;transition:none}\n.key.utility{background:#aeb1b8;font-size:27px;font-weight:500}\n.key.active{background:#a5a8af;transform:translateY(5px) scale(.94);box-shadow:0 1px 0 rgba(70,72,78,.34)}\n#row-z .key.letter{flex:0 0 88px}\n#row-z .key.utility{flex:0 0 126px}\n#row-bottom{gap:22px}\n#row-bottom .numbers{flex:0 0 152px}\n#row-bottom .space{flex:1}\n#row-bottom .return{flex:0 0 148px}\n.keyboard-meta{position:absolute;left:30px;right:30px;top:510px;display:flex;justify-content:space-between;color:#77797f;font-size:28px}\n.home-indicator{position:absolute;left:397px;bottom:30px;width:286px;height:12px;border-radius:6px;background:#171717}\n#key-popup{position:absolute;display:none;z-index:4;width:104px;height:126px;border-radius:16px 16px 13px 13px;background:#fff;color:#111;font-size:50px;align-items:center;justify-content:center;box-shadow:0 5px 14px rgba(50,52,58,.28);transform:translate(-8px,-116px)}\n",
      "html": "<div id=\"surface\" data-jsoncut-surface><div id=\"note-copy\"><span id=\"typed-content\"></span><span id=\"caret\"></span></div><div id=\"keyboard\"><div id=\"row-q\" class=\"key-row\"></div><div id=\"row-a\" class=\"key-row inset\"></div><div id=\"row-z\" class=\"key-row\"></div><div id=\"row-bottom\" class=\"key-row bottom\"></div><div class=\"keyboard-meta\"><span>☺</span><span>⌕</span></div><div class=\"home-indicator\"></div><div id=\"key-popup\"></div></div></div>",
      "inputs": {
        "text": "The best ideas get clearer\nwhen you write them down.\n\nStart with the one thing\npeople should remember."
      },
      "adapter": "dom",
      "layerId": "m60-typing-keyboard",
      "javascript": "\nconst surface=document.getElementById('surface');\nconst typed=document.getElementById('typed-content');\nconst caret=document.getElementById('caret');\nconst keyboard=document.getElementById('keyboard');\nconst popup=document.getElementById('key-popup');\nconst input=String(jsoncut.inputs.text||'');\nconst keyNodes=new Map();\nconst addKey=(row,label,keyName,classes='letter')=>{\n  const node=document.createElement('div');\n  node.className='key '+classes;\n  node.textContent=label;\n  node.dataset.key=keyName;\n  row.appendChild(node);\n  keyNodes.set(keyName,node);\n  return node;\n};\nconst q=document.getElementById('row-q');\nconst a=document.getElementById('row-a');\nconst z=document.getElementById('row-z');\nconst bottom=document.getElementById('row-bottom');\nfor(const ch of 'qwertyuiop') addKey(q,ch.toUpperCase(),ch);\nfor(const ch of 'asdfghjkl') addKey(a,ch.toUpperCase(),ch);\naddKey(z,'⇧','shift','utility');\nfor(const ch of 'zxcvbnm') addKey(z,ch.toUpperCase(),ch);\naddKey(z,'⌫','backspace','utility');\naddKey(bottom,'123','numbers','utility numbers');\naddKey(bottom,'space','space','utility space');\naddKey(bottom,'return','return','utility return');\nconst pressKey=(character)=>{\n  if(character==='\\n') return 'return';\n  if(character===' '||character==='.'||character===',') return 'space';\n  const normalized=character.toLowerCase();\n  return keyNodes.has(normalized)?normalized:'';\n};\nconst clamp=(value,min,max)=>Math.max(min,Math.min(max,value));\nconst typingStart=1.05;\nconst typingEnd=8.55;\nconst typingSpan=Math.max(.1,typingEnd-typingStart);\nconst rate=Math.max(1,input.length/typingSpan);\njsoncut.onFrame(()=>{\n  const time=jsoncut.time;\n  const keyboardProgress=clamp((time-.12)/.62,0,1);\n  const keyboardEase=1-Math.pow(1-keyboardProgress,3);\n  keyboard.style.transform='translateY('+((1-keyboardEase)*728).toFixed(2)+'px)';\n  const exact=clamp((time-typingStart)*rate,0,input.length);\n  const count=Math.floor(exact);\n  typed.textContent=input.slice(0,count);\n  caret.style.opacity=time<typingStart||time>9.35?'0':(Math.floor(time*2)%2?'1':'.18');\n  for(const node of keyNodes.values()) node.classList.remove('active');\n  popup.style.display='none';\n  if(time>=typingStart&&count<input.length){\n    const phase=exact-count;\n    const character=input[count]||'';\n    const keyName=pressKey(character);\n    const node=keyNodes.get(keyName);\n    if(node&&phase<.58){\n      node.classList.add('active');\n      if(keyName.length===1){\n        popup.textContent=character.toUpperCase();\n        popup.style.left=(node.offsetLeft+node.parentElement.offsetLeft)+'px';\n        popup.style.top=(node.offsetTop+node.parentElement.offsetTop)+'px';\n        popup.style.display='flex';\n      }\n      if(character!==character.toLowerCase()&&/[A-Z]/.test(character)){\n        keyNodes.get('shift')?.classList.add('active');\n      }\n    }\n  }\n});\n"
    }
  ],
  "aspectVariants": [],
  "compositionKind": "video",
  "canvasBackground": "#000000",
  "editabilityTarget": "hybrid"
}
