diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 8fc7492..abab89a 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -4,6 +4,9 @@ on: push: branches: - main + # Daily rebuild so posts dated in the future are picked up on their publish day. + schedule: + - cron: "5 5 * * *" jobs: deploy: diff --git a/IDEAS.md b/IDEAS.md new file mode 100644 index 0000000..d705d5c --- /dev/null +++ b/IDEAS.md @@ -0,0 +1,53 @@ +# Future interactive post ideas + +Working scratch list. Same format as the NLOS post: vanilla JS, 2D canvas, scenes scoped to a single post via `` and ` diff --git a/static/css/scene.css b/static/css/scene.css new file mode 100644 index 0000000..6d08441 --- /dev/null +++ b/static/css/scene.css @@ -0,0 +1,94 @@ +/* Generic interactive-scene styles. Scoped to posts that opt in by + wrapping content in `.scene-host` and by linking this stylesheet + from the post's markdown. */ + +.scene-host { + --s-bg: #1f232b; + --s-panel: #242932; + --s-fg: #d4d8df; + --s-dim: #7d8594; + --s-grid: #323844; + --s-blue: #61afef; + --s-cyan: #56b6c2; + --s-green: #98c379; + --s-orange: #d19a66; + --s-red: #e06c75; + --s-yellow: #e5c07b; + --s-magenta: #c678dd; +} + +.scene-box { + margin: 2.5rem 0; + background: var(--s-bg); + border: 1px solid var(--s-grid); + border-radius: 6px; + padding: 0.75rem 0.75rem 1rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35); +} + +.scene-box canvas { + display: block; + width: 100%; + height: auto; + touch-action: none; + cursor: grab; + background: transparent; +} + +.scene-box canvas:active { cursor: grabbing; } + +.scene-controls { + display: grid; + grid-template-columns: 1fr; + gap: 0.5rem; + margin-top: 0.75rem; + font-size: 0.9rem; +} + +@media (min-width: 640px) { + .scene-controls { grid-template-columns: repeat(2, 1fr); } + .scene-controls.scene-controls--three { grid-template-columns: repeat(3, 1fr); } +} + +.scene-control { display: flex; flex-direction: column; gap: 0.2rem; } + +.scene-control label { + color: var(--s-dim); + font-size: 0.8rem; + display: flex; + justify-content: space-between; + gap: 0.5rem; +} + +.scene-control label .scene-value { + color: var(--s-fg); + font-variant-numeric: tabular-nums; +} + +.scene-control input[type="range"] { + width: 100%; + accent-color: var(--s-cyan); +} + +.scene-box .scene-caption { + margin-top: 0.5rem; + font-size: 0.85rem; + color: var(--s-dim); + line-height: 1.45; +} + +.scene-box .scene-readout { + display: flex; + flex-wrap: wrap; + gap: 0.75rem 1.5rem; + padding: 0.5rem 0; + margin-top: 0.25rem; + color: var(--s-fg); + font-size: 0.85rem; + font-variant-numeric: tabular-nums; +} + +.scene-box .scene-readout .scene-readout-item span:first-child { + color: var(--s-dim); + margin-right: 0.35rem; +} diff --git a/static/js/transistor.js b/static/js/transistor.js new file mode 100644 index 0000000..6e1fea9 --- /dev/null +++ b/static/js/transistor.js @@ -0,0 +1,827 @@ +// BJT amplifier explainer. Vanilla JS + 2D canvas. +// Scoped to the single post via /