Marginalia & annotations in general

Ideally possible on any page; browser extension / bookmarklet (part of the K-Web Tools extension).

Ultimately you should be able to do all of it freely, but at the same time choose to stay within helpful borders etc, example: default to put comments in the margin next to the selection (move it only if you really want to).

💬 Comment

Comment on a selection of text, like in Google Docs.
Comment on the document.

🖍️ Draw

Minimal drawing on top of page that is useful?
Boring, but asking why might help. It could be for:

This is surely too simple but you may: try the crudest version possible, a craying should appear bottom right, just click it and draw!

[ Note for Kalle https://chatgpt.com/c/681d12ba-b7dc-8008-8d77-552481f0aafb ]

Appendix A: The code for the /draw demo above

Written by ChatGPT 4o (not their strongest coder).
PS. This code is just inlined in this Google Docs document, pretty cool huh?

// crayon.js
const draw = () => {
  const id = '🖍️'
  const toggle = document.createElement('div')
  Object.assign(toggle.style, {
    position: 'fixed', bottom: '10px', right: '10px',
    fontSize: '24px', cursor: 'pointer', opacity: '0.25',
    zIndex: 99999, userSelect: 'none'
  })
  toggle.textContent = id
  document.body.appendChild(toggle)

  const canvas = document.createElement('canvas')
  Object.assign(canvas.style, {
    position: 'fixed', top: 0, left: 0, width: '100vw', height: '100vh',
    zIndex: 99998, pointerEvents: 'none'
  })
  canvas.width = window.innerWidth
  canvas.height = window.innerHeight
  document.body.appendChild(canvas)

  const ctx = canvas.getContext('2d')
  ctx.lineJoin = ctx.lineCap = 'round'
  ctx.strokeStyle = 'rgba(255,0,0,0.7)'
  ctx.lineWidth = 4

  let drawing = false, enabled = false
  let points = JSON.parse(localStorage.crayonDraw || '[]')

  const redraw = () => {
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    for (const line of points) {
      ctx.beginPath()
      for (let i = 0; i < line.length; i++) {
        const p = line[i]
        i ? ctx.lineTo(p.x, p.y) : ctx.moveTo(p.x, p.y)
      }
      ctx.stroke()
    }
  }

  redraw()

  const newLine = () => { points.push([]) }

  const addPoint = e => {
    const x = e.clientX, y = e.clientY
    points.at(-1).push({x, y})
    ctx.lineTo(x, y)
    ctx.stroke()
  }

  canvas.addEventListener('mousedown', e => {
    if (!enabled) return
    drawing = true
    ctx.beginPath()
    ctx.moveTo(e.clientX, e.clientY)
    newLine()
    addPoint(e)
  })

  canvas.addEventListener('mousemove', e => {
    if (!enabled || !drawing) return
    addPoint(e)
  })

  window.addEventListener('mouseup', () => {
    if (drawing) {
      drawing = false
      localStorage.crayonDraw = JSON.stringify(points)
    }
  })

  toggle.onclick = () => {
    enabled = !enabled
    canvas.style.pointerEvents = enabled ? 'auto' : 'none'
    toggle.style.opacity = enabled ? '1.0' : '0.25'
    if (!enabled) redraw()
  }
}