// Hotel Walks — abstract illustrations for the marketing site.
// All Ink + Bone only. Drawn at 200×200 viewBox; pass color for the stroke.
(function() {
function Frame({ children, size = 180, stroke = "currentColor", style }) {
return (
);
}
/* ─── Feature 1 · Partner routing ─────────────────────────────
A central node, four partner nodes around it at different
distances. Labelled 1–4 to imply ranking.
─────────────────────────────────────────────────────────────── */
function IxRouting({ size = 180, color = "currentColor" }) {
const c = color;
const cx = 100, cy = 110;
const partners = [
{ x: 35, y: 50, n: "1" },
{ x: 170, y: 45, n: "2" },
{ x: 50, y: 175, n: "3" },
{ x: 175, y: 165, n: "4" },
];
return (
{/* center node */}
{/* connections */}
{partners.map((p, i) => (
))}
{/* partner dots */}
{partners.map((p, i) => (
{p.n}
))}
);
}
/* ─── Feature 2 · Escalation timer ────────────────────────────
A clock face with a hand mid-rotation, plus a forward arrow
suggesting "moves to the next one".
─────────────────────────────────────────────────────────────── */
function IxTimer({ size = 180, color = "currentColor" }) {
const c = color;
return (
{/* clock face */}
{/* tick marks at 12 / 3 / 6 / 9 */}
{[0,1,2,3].map(i => {
const a = (i * 90 - 90) * Math.PI / 180;
const r1 = 54, r2 = 60;
return ;
})}
{/* small ticks */}
{Array.from({length: 12}).map((_, i) => {
if (i % 3 === 0) return null;
const a = (i * 30 - 90) * Math.PI / 180;
const r1 = 56, r2 = 60;
return ;
})}
{/* hands — pointing at ~10 mins past */}
{/* forward arrow */}
);
}
/* ─── Feature 3 · Walk letter ─────────────────────────────────
Three stacked document silhouettes (guest / hotel / emailed).
A small "key" mark on the top one to evoke a certificate.
─────────────────────────────────────────────────────────────── */
// `bg` is the "paper" colour of the documents — it should match the surrounding card background so
// the doc rectangles read as outlined paper, and the key-hole and shaft sit cleanly inside them.
// Passing a CSS variable (e.g. "var(--hw-paper)") lets the icon flip with a parent's hover state.
function IxLetter({ size = 180, color = "currentColor", bg = "var(--ink)" }) {
const c = color;
return (
{/* back doc */}
{[40,55,70,85,100,115].map(y => (
))}
{/* middle doc */}
{[40,55,70,85,100,115].map(y => (
))}
{/* front doc */}
{/* mini key glyph */}
{/* text lines */}
{/* serial line */}
);
}
/* ─── Feature 4 · Invoices & credits ──────────────────────────
A ledger with rows summing to a total.
─────────────────────────────────────────────────────────────── */
function IxLedger({ size = 180, color = "currentColor" }) {
const c = color;
const rows = [
{ y: 45, w: 110, side: "L" },
{ y: 70, w: 130, side: "A" },
{ y: 95, w: 80, side: "L", strike: true }, // no-show
{ y: 120, w: 120, side: "A" },
];
return (
{/* header */}
DATE SIDE AMOUNT
{rows.map((r, i) => (
{/* small date pip */}
{/* side letter */}
{r.side}
{/* amount bar */}
{r.strike && }
))}
{/* total */}
TOTAL
);
}
/* ─── Small flow icons (32px-ish) ─────────────────────────── */
function FlowIcon({ kind, size = 36, color = "currentColor" }) {
const c = color;
const wrap = (children) => (
);
switch (kind) {
case "request":
// square with an arrow exiting
return wrap(<>
>);
case "broadcast":
// dot with three arcs
return wrap(<>
>);
case "accept":
return wrap(<>
>);
case "letter":
return wrap(<>
>);
case "settle":
return wrap(<>
>);
default: return null;
}
}
/* ─── Problem section · timeline graphic ──────────────────────
A timeline labelled 11:00pm → 11:45pm with failed call attempts
(X marks) and a single accept (•). On bone background, ink lines.
─────────────────────────────────────────────────────────────── */
function IxTimeline({ width = 460, color = "currentColor", fullWidth }) {
const c = color;
// 45-minute window from 11:00 PM. Times derived from t (0..1).
const events = [
{ t: 0.05, kind: "x", label: "call 1", time: "11:02" },
{ t: 0.20, kind: "x", label: "call 2", time: "11:09" },
{ t: 0.42, kind: "x", label: "call 3", time: "11:19" },
{ t: 0.62, kind: "x", label: "call 4", time: "11:28" },
{ t: 0.92, kind: "ok", label: "accept", time: "11:41" },
];
return (
);
}
window.HWIx = { IxRouting, IxTimer, IxLetter, IxLedger, FlowIcon, IxTimeline };
})();