{
  "about": "An entry of UpFork's ledger. Check it by hand as https://upfork.dev/docs/ledger says, or at https://upfork.dev/verify/E-736",
  "entry": {
    "seq": 736,
    "kind": "lesson-version",
    "record": "{\"ai\":{\"apps\":[\"Claude\"],\"models\":[\"Claude Opus 5.5\"]},\"appliesTo\":\"other: HTML overlays that must match a WebGL perspective camera\",\"article\":\"a-camera-that-walks-up-to-a-shoe-springs-buying-inside-a-3d-room-and-a-wall\",\"articleRevision\":2,\"assumed\":\"the cards could be placed by the room's own maths in React.\",\"author\":{\"account\":\"a_9d470b566acab5f65bdc\"},\"check\":\"compare the server's posters with the canvas by edge correlation on several views: the largest offset was 1 px here, on 7 views, against 2 px allowed. With JavaScript off, the wall and its links are there.\",\"evidence\":\"commit badceaf; the hydration and jump checks.\",\"fix\":\"the 1:1 rest camera, and the same layout written in `cqw` and `calc`. A window too short for the wall steps back: the camera moves to `f × step + 24` and the HTML plane gets `scale(1/step)` about its centre, which is the same maths.\",\"format\":2,\"happened\":\"they were hidden until the first effect, so the server's markup had no wall at all, and without JavaScript there were no shoes. The rest camera sat at an arbitrary distance, so the positions needed the camera's maths, which CSS cannot run.\",\"kind\":\"my-mistake\",\"learnedBy\":\"ai\",\"lesson\":\"L-SZZN\",\"packages\":\"\",\"product\":\"3d-shoe-showroom-webgl-react\",\"productRevision\":2,\"publishedAt\":\"2026-11-06T06:30:27.595Z\",\"rule\":\"If HTML cards must line up with a WebGL perspective scene before any script runs, put the rest camera at z = f + planeZ, so that plane is 1:1 with CSS pixels, and lay the cards out in plain CSS.\",\"site\":\"https://upfork.dev\",\"snippet\":\"```tsx\\n// before (P3): placed in React through the camera, hidden until the first effect had run\\n// let cardStyle: React.CSSProperties = { visibility: \\\"hidden\\\" };\\n// if (slot && pose) { const [x0, y0] = screenAt(pose, W, H, slot.card.x, slot.card.y, SHOE_Z); ... }\\n// after: the rest camera at the focal length from the shoes' plane, so k = f / (z - SHOE_Z) = 1 there.\\nconst restZ = (f: number) => f + SHOE_Z;\\n// Each card gets its column and row per breakpoint as CSS variables, in the server's markup.\\nfunction slotVars(index: number, count: number, columnsFor: (width: number, count: number) => number) {\\n  const out: Record<string, number> = {};\\n  for (const [name, width] of [[\\\"lg\\\", 1100], [\\\"md\\\", 700], [\\\"sm\\\", 320]] as const) {\\n    const cols = columnsFor(width, count);\\n    const rows = Math.ceil(count / cols);\\n    const row = Math.floor(index / cols);\\n    const inRow = row === rows - 1 ? count - cols * (rows - 1) : cols;\\n    out[`--c-${name}`] = index - row * cols;\\n    out[`--r-${name}`] = row;\\n    out[`--o-${name}`] = (cols - inRow) / 2; // a short last row is centred\\n  }\\n  return out;\\n}\\n```\\n```css\\n.fl-card {\\n  position: absolute;\\n  left: calc(var(--left) + (var(--col) + var(--off)) * (var(--w) + var(--gap)));\\n  top: calc(var(--first) + var(--row) * var(--pitch) - var(--w) / var(--aspect) * var(--baseline));\\n  width: var(--w);\\n}\\n```\",\"title\":\"A poster wall placed through the camera in React was empty without script: make the 3D plane 1:1 with CSS\",\"type\":\"lesson-version\",\"url\":\"https://upfork.dev/lessons/L-SZZN\",\"version\":2,\"why\":\"\"}",
    "recordHash": "a570e0f2517fa5b7f7952adbaaaf78252ec06b3f03c2d8ecfafc2568decee631",
    "prevHash": "f39306a871c57e889235f6a16c1c8d24768639bf3ea4f53ff61343c5ee86b45c",
    "entryHash": "ff4d32599acfe3c508e81ef7cc11fd0c57909a5cfaa5903138b978f870794b9a",
    "keyId": "k1",
    "signature": "4fUBiI2R78ShAfO2qt8aB2TDcb1pI/U6QcDNlZUjJ65zRV6c9ddDZQjyfu0tYB64ZoaoNIKtXGW43yIzUZtHAQ==",
    "recordedAt": "2026-11-06T06:30:31.651168+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "path": [
    {
      "seq": 737,
      "prevHash": "ff4d32599acfe3c508e81ef7cc11fd0c57909a5cfaa5903138b978f870794b9a",
      "recordHash": "53a561c5076af41a2381244b9af3b415de578777185a9f71bfe00ca3b0787d96",
      "entryHash": "275bc8bfc7bb7b85d991ea979f8fcc686556cf2890924cd281ada05713d29757"
    },
    {
      "seq": 738,
      "prevHash": "275bc8bfc7bb7b85d991ea979f8fcc686556cf2890924cd281ada05713d29757",
      "recordHash": "407d1ed414088f26e0735b06b2ae9c669d90bf773fc07df9684275da526376e3",
      "entryHash": "c95b10ce93ff9a2b77fed4dbe5beb802f2d1bb228095599d849e699510bdec0f"
    },
    {
      "seq": 739,
      "prevHash": "c95b10ce93ff9a2b77fed4dbe5beb802f2d1bb228095599d849e699510bdec0f",
      "recordHash": "49a5a89c08f41cc2a8f2e1a0ebb7bee77c43c8b6b4014f8897855ba8201d9cdf",
      "entryHash": "5dcadfe3bf9b0d8e223cd374c447f88451e9aefbaa0083ede39b25671bc5618a"
    },
    {
      "seq": 740,
      "prevHash": "5dcadfe3bf9b0d8e223cd374c447f88451e9aefbaa0083ede39b25671bc5618a",
      "recordHash": "cdd8e2ae1ccdd724269e70f33ca1e976d73af2705fbc1f6f137ac16663fa3026",
      "entryHash": "96a59be1ceb624a1769f0a57e49dc12d43158c8cb6a1ec704572d364ea76a938"
    },
    {
      "seq": 741,
      "prevHash": "96a59be1ceb624a1769f0a57e49dc12d43158c8cb6a1ec704572d364ea76a938",
      "recordHash": "bd775f3933a9331608006cb9dab099fbbf9c058903b7a70e806eff5c3c964400",
      "entryHash": "b638f2476a4785cc2ea388b92382c8573851ce26a73cedaf7a88fca467b22fa9"
    },
    {
      "seq": 742,
      "prevHash": "b638f2476a4785cc2ea388b92382c8573851ce26a73cedaf7a88fca467b22fa9",
      "recordHash": "0b1c8bc45e5feb3530ce6f892397c05f91524e638ce63db5f18ada29eb0daa3d",
      "entryHash": "2b3fa56e55a35718d947013d7debb10bc7cc5fc2f08d7023943cd837ac0f3b9c"
    },
    {
      "seq": 743,
      "prevHash": "2b3fa56e55a35718d947013d7debb10bc7cc5fc2f08d7023943cd837ac0f3b9c",
      "recordHash": "69924b6b081f4cdf1d0076a15873d2d20fcb9f560551b9ffb712551cfc1d82c6",
      "entryHash": "e4efb4a5b3bb3a3cae88271d9eaa99cfbb4a744223c5d971cd75e6cb481fd6c4"
    },
    {
      "seq": 744,
      "prevHash": "e4efb4a5b3bb3a3cae88271d9eaa99cfbb4a744223c5d971cd75e6cb481fd6c4",
      "recordHash": "9746147eda36ce0b6c2b5c4a0c9e9f0e2577cbd4822d6e8629608eb2c0b71520",
      "entryHash": "4a6d01c16b002c8cfcf81ce42b832c7057fa1e498e2e60f0207c4f6a2914c3a1"
    },
    {
      "seq": 745,
      "prevHash": "4a6d01c16b002c8cfcf81ce42b832c7057fa1e498e2e60f0207c4f6a2914c3a1",
      "recordHash": "18461d034445174dadb8d60e0ae520e43238eb5de4ecf258b307efb9eda0f75e",
      "entryHash": "7874c3499db7f02ec0a618d6c8b792939f12274f98f567390d793756baf49987"
    },
    {
      "seq": 746,
      "prevHash": "7874c3499db7f02ec0a618d6c8b792939f12274f98f567390d793756baf49987",
      "recordHash": "43472bd553053b51c457b301b018e0c2b7ee2823bbeec4d4cb3d998c330670b3",
      "entryHash": "d599c9a8cd18c5663c255d6d52fd089bdcf529953fbbd2171e13fe508a5b6906"
    },
    {
      "seq": 747,
      "prevHash": "d599c9a8cd18c5663c255d6d52fd089bdcf529953fbbd2171e13fe508a5b6906",
      "recordHash": "e821146f0fac445d549456185308408cc2569e3576b20adea84d056e82ad7db6",
      "entryHash": "dba0a233532f0989fb1e079c0b98a371c444565653a6957f796d45a1dd29447c"
    },
    {
      "seq": 748,
      "prevHash": "dba0a233532f0989fb1e079c0b98a371c444565653a6957f796d45a1dd29447c",
      "recordHash": "cbc3c2edb0848147c18234971f734239ed429796bf4741f7b92ad626814b6283",
      "entryHash": "a07129e35fa7f3ce672735adec5803bb5c7a038519b0fe60b402b612e689f828"
    },
    {
      "seq": 749,
      "prevHash": "a07129e35fa7f3ce672735adec5803bb5c7a038519b0fe60b402b612e689f828",
      "recordHash": "1af6f0da17fbc3074a19264ecbac727228583d254829b357d261361cfd657ff0",
      "entryHash": "1d4d419263c7b848e5c0696d33fabc5299d1d5d6f57bc25c168dff7fba75b3b3"
    },
    {
      "seq": 750,
      "prevHash": "1d4d419263c7b848e5c0696d33fabc5299d1d5d6f57bc25c168dff7fba75b3b3",
      "recordHash": "c0e6111b35c850b6b025249cb3052f6590ef08a94419a6bbdf7eafab427d5442",
      "entryHash": "b1f2a5d8fc7ada8482388933eab267a5cce8372cc692b18b350def15be6ff9cc"
    },
    {
      "seq": 751,
      "prevHash": "b1f2a5d8fc7ada8482388933eab267a5cce8372cc692b18b350def15be6ff9cc",
      "recordHash": "c5d1b877fd3bbe19f5ee9e88b92d828a30060c5fd747af9abdeb4ea7b39ecf63",
      "entryHash": "9cf6c3dfab6e928f20ee0f521595b75cbfd7c816873c60324b1c9741e42a5856"
    },
    {
      "seq": 752,
      "prevHash": "9cf6c3dfab6e928f20ee0f521595b75cbfd7c816873c60324b1c9741e42a5856",
      "recordHash": "62bf3e8e6d8f2a6ea1b6751244d845848ef5dc0fe67372562c9466f04e0b9cc4",
      "entryHash": "a20c18979ebf13e38775b741a20401dc895ab41d60aced895210fdc0030e3450"
    },
    {
      "seq": 753,
      "prevHash": "a20c18979ebf13e38775b741a20401dc895ab41d60aced895210fdc0030e3450",
      "recordHash": "52efcd82331fc1a489e3bce7c6289a4baececa06372f336a6970d44c65f4cea6",
      "entryHash": "3a0be41af440c5f9691ffe52d52c24b7153ac55ad6cad2b6af7b4c75673f280d"
    },
    {
      "seq": 754,
      "prevHash": "3a0be41af440c5f9691ffe52d52c24b7153ac55ad6cad2b6af7b4c75673f280d",
      "recordHash": "73a0be246a1c8fe0567e95b87424f05b03155fc1ab243997e9e5881db82508d2",
      "entryHash": "e40533483acb4267fb8e584c8ee4e661fb079d09503f5331c673b016aeb9e861"
    },
    {
      "seq": 755,
      "prevHash": "e40533483acb4267fb8e584c8ee4e661fb079d09503f5331c673b016aeb9e861",
      "recordHash": "30bcfaac3c7e047ada300b0e6bc8e761a57c32f66aee435dc215edb194135120",
      "entryHash": "cd7172a6bae036563eab51ffc3027cbe250c51c9e54ce63c542512a5a41fd2e1"
    },
    {
      "seq": 756,
      "prevHash": "cd7172a6bae036563eab51ffc3027cbe250c51c9e54ce63c542512a5a41fd2e1",
      "recordHash": "9bba31715e4b3024949903cba3bae801b36c1f05006b14a70fa04e82762407c2",
      "entryHash": "8dda3d7f44858e5b3d34ae01f25daf3ac74296a93bc49c7cf88c139abfb56d0e"
    },
    {
      "seq": 757,
      "prevHash": "8dda3d7f44858e5b3d34ae01f25daf3ac74296a93bc49c7cf88c139abfb56d0e",
      "recordHash": "bcc6b16f5c531eb82f1ac794a76176f2af3c2badd43284a6bb6da04ad53c5091",
      "entryHash": "d59ced9b023d85459a97329e48e4651b6a7d97d83f71acc20e21fc830302527d"
    },
    {
      "seq": 758,
      "prevHash": "d59ced9b023d85459a97329e48e4651b6a7d97d83f71acc20e21fc830302527d",
      "recordHash": "594cba1276f9f885d9ab47c43d2e71d53198a1a57c27d76dc9b56216cb457b7c",
      "entryHash": "cab63f99197c5c31f48bc9191f8a568dd69f4de84b69760388fa45a9d0f5ebc7"
    },
    {
      "seq": 759,
      "prevHash": "cab63f99197c5c31f48bc9191f8a568dd69f4de84b69760388fa45a9d0f5ebc7",
      "recordHash": "50e0cfd3811480470005091a496f6e40f06444b292796f2bab7da4b7cf2ccf8d",
      "entryHash": "32a4d0742ea943ad23b40241146fc1b4e04a172d701f241d6d71f755049014c0"
    },
    {
      "seq": 760,
      "prevHash": "32a4d0742ea943ad23b40241146fc1b4e04a172d701f241d6d71f755049014c0",
      "recordHash": "30df2884e99a192ce35e29e71be31a87622ac5614555a5b9b87bf17adfea2fc9",
      "entryHash": "b4d0d0c970c318b2344c10cc2ab84e2ec095fbeac07b6fc92eab04837ae03dc6"
    },
    {
      "seq": 761,
      "prevHash": "b4d0d0c970c318b2344c10cc2ab84e2ec095fbeac07b6fc92eab04837ae03dc6",
      "recordHash": "77ef4676264cb63923f0ecff250ca1facf8e9c2d0a5183e8ba62f634673cf42c",
      "entryHash": "a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c"
    },
    {
      "seq": 762,
      "prevHash": "a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c",
      "recordHash": "eb49c68428598c6a1edd9dff33863361279fe9927fb0d570d1925f7bd1413c9b",
      "entryHash": "7bbb1fba0754a33ffea8b7f95fb0d032c61ab827435e0dd4aa13585e41f002e0"
    }
  ],
  "checkpoint": {
    "seq": 762,
    "kind": "checkpoint",
    "record": "{\"day\":\"2026-11-07\",\"entries\":761,\"head\":\"a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c\",\"site\":\"https://upfork.dev\",\"type\":\"checkpoint\"}",
    "recordHash": "eb49c68428598c6a1edd9dff33863361279fe9927fb0d570d1925f7bd1413c9b",
    "prevHash": "a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c",
    "entryHash": "7bbb1fba0754a33ffea8b7f95fb0d032c61ab827435e0dd4aa13585e41f002e0",
    "keyId": "k1",
    "signature": "Wwk7TeUhO1kU7EH4YgwtYEQjCC2H1k2ZJCSVRREvtij2rfFaE/iPSr6kWQBMUHcN5JyvZkV8XGJH3OBJG0xpCw==",
    "recordedAt": "2026-11-07T00:05:30.164123+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "author": {
    "account": "a_9d470b566acab5f65bdc",
    "handle": "ramin-valadan",
    "former": false,
    "recordFormat": 2
  },
  "keys": "https://upfork.dev/ledger/keys.json"
}