diff --git a/README.md b/README.md
index 5191432..fdd4b7c 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,59 @@
# this-must-be-the-place--mural--colorblock-fx
+
+
A canvas-based sign-painted block letter effect — white face, red mid-layer, black depth — inspired by the ["This Must Be The Place"](https://www.thebanner.com/community/local-news/this-must-be-the-place-mural-painted-espo-DMKP5D3IJNCWZEDL6NW6JOGKCE/) mural.
+
+
+
+
+## Quick start
+
+No build step. Open either file directly in a browser.
+
+
+## How the effect works
+
+Three canvas draw passes, back to front:
+
+```
+1. Deep layer — drawn at offset (i, i) for i = depth…1 → black
+2. Mid layer — drawn at offset (i, i) for i = depth×0.55…1 → red
+3. Face layer — drawn at (0, 0) → white
+```
+
+This simulates physically mounted block letters casting a red then black shadow, the same technique used in hand-painted signs and murals.
+
+## Embedding in your own page
+
+Copy `embed.html` or paste the snippet below. The only dependency is the [Bebas Neue](https://fonts.google.com/specimen/Bebas+Neue) Google Font (falls back to Impact).
+
+```html
+
+
+
+
+
+
+
+
+
+```
+
+## Options
+
+```js
+blockLetterFX(canvas, text, {
+ faceColor: '#f0f0f0', // letter face
+ midColor: '#cc2200', // red mid-layer
+ deepColor: '#111111', // black depth
+ depthPct: 0.09, // extrusion as fraction of font size (0–0.25)
+ spacing: 2, // letter-spacing in px
+ padding: 28, // horizontal padding in px
+})
+```
+
+## License
+
+MIT
diff --git a/block-letter-fx.js b/block-letter-fx.js
new file mode 100644
index 0000000..fef9c06
--- /dev/null
+++ b/block-letter-fx.js
@@ -0,0 +1,78 @@
+(function (root, factory) {
+ if (typeof module !== 'undefined' && module.exports) module.exports = factory();
+ else root.blockLetterFX = factory();
+})(typeof self !== 'undefined' ? self : this, function () {
+
+ var DEFAULT_OPTS = {
+ faceColor: '#f0f0f0',
+ midColor: '#cc2200',
+ deepColor: '#111111',
+ depthPct: 0.09,
+ spacing: 2,
+ padding: 28,
+ };
+
+ function draw(canvas, text, opts) {
+ opts = Object.assign({}, DEFAULT_OPTS, opts || {});
+ text = (text || '').trim() || 'BLOCK LETTER FX';
+
+ var ctx = canvas.getContext('2d');
+ var DPR = window.devicePixelRatio || 1;
+ var LETTER_SPACING = opts.spacing;
+ var maxW = canvas.parentElement
+ ? canvas.parentElement.clientWidth - opts.padding * 2
+ : 600;
+
+ var fontSize = Math.round(maxW * 0.11);
+ ctx.font = 'normal ' + fontSize + 'px "Bebas Neue", Impact, sans-serif';
+ var textW = ctx.measureText(text).width + LETTER_SPACING * text.length;
+ while (textW > maxW && fontSize > 8) {
+ fontSize--;
+ ctx.font = 'normal ' + fontSize + 'px "Bebas Neue", Impact, sans-serif';
+ textW = ctx.measureText(text).width + LETTER_SPACING * text.length;
+ }
+
+ var depth = Math.round(fontSize * opts.depthPct);
+ var padY = Math.round(fontSize * 0.2);
+ var cssW = textW + opts.padding * 2;
+ var cssH = fontSize + padY * 2 + depth;
+
+ canvas.width = Math.round(cssW * DPR);
+ canvas.height = Math.round(cssH * DPR);
+ canvas.style.width = cssW + 'px';
+ canvas.style.height = cssH + 'px';
+
+ ctx.scale(DPR, DPR);
+ ctx.clearRect(0, 0, cssW, cssH);
+ ctx.font = 'normal ' + fontSize + 'px "Bebas Neue", Impact, sans-serif';
+ ctx.textBaseline = 'top';
+ ctx.letterSpacing = LETTER_SPACING + 'px';
+
+ var x = opts.padding;
+ var y = padY;
+
+ for (var i = depth; i >= 1; i--) {
+ ctx.fillStyle = opts.deepColor;
+ ctx.fillText(text, x + i, y + i);
+ }
+ for (var i = Math.round(depth * 0.55); i >= 1; i--) {
+ ctx.fillStyle = opts.midColor;
+ ctx.fillText(text, x + i, y + i);
+ }
+ ctx.fillStyle = opts.faceColor;
+ ctx.fillText(text, x, y);
+ }
+
+ function blockLetterFX(canvas, text, opts) {
+ function render() { draw(canvas, text, opts); }
+ if (document.fonts && document.fonts.load) {
+ document.fonts.load('1em "Bebas Neue"').then(render);
+ } else {
+ setTimeout(render, 400);
+ }
+ window.addEventListener('resize', render);
+ return { redraw: render };
+ }
+
+ return blockLetterFX;
+});
diff --git a/preview.png b/preview.png
new file mode 100644
index 0000000..e580219
Binary files /dev/null and b/preview.png differ