/* Maitha Tech — shared primitives for the home page.
Pulls the design-system components off the bundle namespace and
adds a few layout/scroll helpers used across sections. */
const DS = window.MaithaTechDesignSystem_b10928 || {};
const { Button, IconButton, Eyebrow, Badge, Input, Card, Avatar } = DS;
/* Reveal-on-scroll: adds .in when the element enters the viewport. */
function useReveal() {
const ref = React.useRef(null);
React.useEffect(() => {
const el = ref.current;
if (!el) return;
const show = () => el.classList.add("in");
if (typeof IntersectionObserver === "undefined") { show(); return; }
const io = new IntersectionObserver(
(entries) => entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); } }),
{ threshold: 0.16, rootMargin: "0px 0px -8% 0px" }
);
io.observe(el);
// Safety net: if the observer never fires in this embedding context,
// force-reveal so content is never stranded invisible.
const fallback = setTimeout(show, 700);
return () => { io.disconnect(); clearTimeout(fallback); };
}, []);
return ref;
}
/* A revealing block. delay in ms staggers children entrances. */
function Reveal({ children, delay = 0, as = "div", className = "", style = {}, ...rest }) {
const ref = useReveal();
const Tag = as;
return (
{children}
);
}
/* Playfair-italic accent word, with a hand-drawn brand scribble behind it.
Scribbles are recolored on the fly via CSS mask + brand accent (blue/orange).
s2 & s3 wrap around the word; the rest underline it. */
const SCRIBBLES = {
s1: { aspect: 22.28, kind: "under" },
s2: { aspect: 4.32, kind: "around" },
s3: { aspect: 3.39, kind: "around" },
s4: { aspect: 13.74, kind: "under" },
s5: { aspect: 13.35, kind: "under" },
s6: { aspect: 17.47, kind: "under" },
s7: { aspect: 17.45, kind: "under" },
};
function Accent({ children, scribble = "s5", tone = "blue", width, draw = true, behind = false }) {
const cfg = SCRIBBLES[scribble] || SCRIBBLES.s5;
const around = cfg.kind === "around";
const color = tone === "orange" ? "var(--mt-orange)" : "var(--mt-blue)";
const w = width != null ? width : (around ? 1.26 : 1.05);
const url = `url("assets/scribbles/${scribble}.svg")`;
const mark = {
position: "absolute", left: "50%", background: color, pointerEvents: "none", zIndex: behind ? -1 : 0,
width: `${w * 100}%`, aspectRatio: String(cfg.aspect),
WebkitMaskImage: url, maskImage: url,
WebkitMaskSize: "100% 100%", maskSize: "100% 100%",
WebkitMaskRepeat: "no-repeat", maskRepeat: "no-repeat",
...(around
? { top: "52%", transform: "translate(-50%, -50%)" }
: { top: "94%", transform: "translate(-50%, -50%)" }),
};
return (
{draw ? : null}
{children}
);
}
/* Section wrapper with the brand's generous vertical rhythm + a top hairline. */
function Section({ id, children, divider = true, style = {} }) {
return (
);
}
/* Eyebrow + heading + optional lead, the standard section opener. */
function SectionHead({ eyebrow, marker = "rule", title, lead, align = "left", max = 760 }) {
return (
{eyebrow ?
{eyebrow} : null}
{title}
{lead ?
{lead}
: null}
);
}
/* Decorative brand glyph (star / flower / circle) — a small monochrome accent.
star & flower ship black, so invert to white on the dark canvas; circle is
already a white stroke. Purely decorative — hidden from assistive tech. */
function Glyph({ name, size = 40, className = "", style = {} }) {
const invert = name !== "circle";
return (
);
}
/* Small circular arrow affordance used on cards & links. */
function ArrowDot({ size = 42 }) {
return (
);
}
Object.assign(window, { DS, Button, IconButton, Eyebrow, Badge, Input, Card, Avatar, useReveal, Reveal, Accent, Section, SectionHead, ArrowDot, Glyph });