hof.js

Free embeddable widgets. Get one for your site.

zoom.hof.js

Click and hold an image to zoom in. Right-click and hold to zoom back out. Release either button to stop. Works on touch too. No dependencies, no build step, one script tag.

Zoom demo image — click and hold to try it

Try it: left-click and hold to zoom in, right-click and hold to zoom out.

Add it to your site

<img src="your-image.png" data-zoom>
<script src="https://api.thatrealm.com/hof/zoom.hof.js"></script>

That's it. Any element matching [data-zoom] gets the interaction automatically. Multiple images on one page all work independently.

gallery.hof.js

Click any photo to open it fullscreen. X button, Escape, or click-outside to close. Injects its own styles and markup — no CSS changes needed on your page.

Try it: click the image above.

<figure class="hof-gallery-item"><img src="photo.jpg" alt="..."></figure>
<script src="https://api.thatrealm.com/hof/gallery.hof.js"></script>

menu.hof.js — the CSV-as-catalog widget family

A small business's menu, service list, or SKU sheet as a live, searchable catalog — driven by a plain CSV file, no build step, no backend. Search below (type-to-filter):

Try it: type "burg", "fry", or "pie" above.

<input type="text" data-menu-search list="menu-items">
<datalist id="menu-items" data-menu-list></datalist>
<script src="https://api.thatrealm.com/hof/menu.hof.js"
        data-menu-csv="/assets/your-menu.csv"></script>

Required CSV columns: id, name, price. Optional: category, subcategory, notes — any extra columns pass through untouched. A row with no id/name/numeric price is skipped, never defaulted to a placeholder price. Composes with three sibling widgets for a full order flow, each usable standalone:

Live production example: Bad Boy Diner's full order builder at badboydiner.com/order.html — one order across five printed menus, grouped search, an "All The Things" combined view, a review step, and live sales tax by pickup/delivery area.

<script src="https://api.thatrealm.com/hof/menu.hof.js"></script>
<script src="https://api.thatrealm.com/hof/order.hof.js"></script>
<script src="https://api.thatrealm.com/hof/cart.hof.js"></script>
<script src="https://api.thatrealm.com/hof/tax.hof.js"></script>
<script src="https://api.thatrealm.com/hof/checkout.hof.js"></script>

search.hof.js — zero-dependency similarity search

A lightweight, client-side similarity-search primitive for catalog-shaped data (menu.hof.js items, or any list of objects with a name/text field) — token-overlap + edit-distance scoring, no embedding model, no network call, no API key. Drop it in alongside menu.hof.js and a loose/misspelled/synonymous query ("kbbq", "fry") still narrows the search results. Try the demo search above: it's already running search.hof.js under the hood.

<script src="https://api.thatrealm.com/hof/menu.hof.js"></script>
<script src="https://api.thatrealm.com/hof/search.hof.js"></script>
<script>
  var index = new window.hofSearch.SimilarityIndex(items, { text: function (i) { return i.name; } });
  var ranked = index.search("fry", { limit: 20 });
</script>

pairings.hof.js — curated pairing/upsell suggestions

A business's own hand-authored "goes well with" pairing chart — deliberately NOT derived from search.hof.js's similarity scoring. You supply the pairing table (item id → paired item ids); pairings.hof.js resolves it back to real, currently priced menu items via menu.hof.js, and drops any pairing that's crossed a theme boundary you define (e.g. never suggest across unrelated menus).

<script src="https://api.thatrealm.com/hof/menu.hof.js"></script>
<script src="https://api.thatrealm.com/hof/pairings.hof.js"></script>
<script>
  var pairingTable = new window.hofPairings.PairingTable(rawPairings);
  var suggestions = pairingTable.suggestionsFor('burger-classic', menu, { limit: 4 });
</script>

Live production example: Bad Boy Diner's order builder computes Suggested Pairings live off the whole cart, across all 180 menu items — badboydiner.com/order.html.

menu-picker.hof.js — a scoped single-menu search-and-add picker

For a page dedicated to just ONE menu/category (a single event flyer, a breakfast-only page, a single service's price list) rather than the whole catalog. Composes menu.hof.js (loads the CSV), search.hof.js (optional, ranks within the scoped subset), and cart.hof.js (add/qty/persisted cart) — search box, per-row qty stepper, and an inline Add button, scoped to just the categories you pass in.

<div id="my-picker"></div>
<script src="https://api.thatrealm.com/hof/menu.hof.js"></script>
<script src="https://api.thatrealm.com/hof/search.hof.js"></script>
<script src="https://api.thatrealm.com/hof/cart.hof.js"></script>
<script src="https://api.thatrealm.com/hof/menu-picker.hof.js"></script>
<script>
  window.hofMenuPicker.mount(document.getElementById('my-picker'), {
    csvPath: '/assets/sku.csv',
    categories: ['korean-bbq'],
    label: 'Korean BBQ Menu',
    persistKey: 'my-store-cart'
  });
</script>

Live production example: Bad Boy Diner's standalone menu pages (Korean BBQ, Oktoberfest, breakfast, and more) each embed their own scoped picker — badboydiner.com/korean-bbq-menu.html.

jurisdictions.hof.js + logistics.hof.js + delivery.hof.js — deliver anywhere you serve, taxed correctly

Extends tax.hof.js's area→rate table into a full geography primitive: a business lists every jurisdiction it actually serves (by zip, city, or named area) — tax rate, whether delivery is offered there, and which delivery zone it falls in. Customers search or enter their own zip/address instead of picking from a fixed 3-option dropdown.

<script src="https://api.thatrealm.com/hof/jurisdictions.hof.js"></script>
<script src="https://api.thatrealm.com/hof/logistics.hof.js"></script>
<script src="https://api.thatrealm.com/hof/delivery.hof.js"></script>
<script>
  var jurisdictions = new window.hofJurisdictions.JurisdictionTable(myAreas);
  // colFactor (optional, per zone) scales the base+distance fee for cost-of-living —
  // omit it (or use 1.00) to reproduce plain zone-tier pricing with no adjustment.
  var logistics = new window.hofLogistics.DeliveryTable({
    'low-col-zone':  { base: 3.00, colFactor: 1.00 },
    'high-col-zone': { base: 3.00, colFactor: 1.25 }
  }, { freeOverSubtotal: 75 });
  var quoter = new window.hofDelivery.DeliveryQuoter({ jurisdictions: jurisdictions, logistics: logistics });
  var quote = quoter.resolveAndQuote('94061', cart.subtotal());
  // { ok:true, jurisdiction, delivery, subtotal, deliveryCharge, taxAmount, total }
</script>

Live production example: Bad Boy Diner's order builder's geography selector — badboydiner.com/order.html.

Want a whole site, not just a widget?

Get your site on thatrealm.com — old school + AI. Learn more.