"use client"; import { useMemo, useState } from "react"; import ToolShell from "@/components/toolkit/ToolShell"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; function num(v: string) { const n = parseFloat(v); return Number.isFinite(n) ? n : 0; } const UM_PER_INCH = 25400; export default function Page() { const [spotUm, setSpotUm] = useState("60"); const [gapUm, setGapUm] = useState("40"); const [lpi, setLpi] = useState("635"); // 635 LPI ≈ 40 µm gap // Keep gap and LPI linked both ways function onGapChange(v: string) { setGapUm(v); const g = num(v); setLpi(g > 0 ? (UM_PER_INCH / g).toFixed(2) : ""); } function onLpiChange(v: string) { setLpi(v); const L = num(v); setGapUm(L > 0 ? (UM_PER_INCH / L).toFixed(2) : ""); } const coverage = useMemo(() => { const d = num(spotUm); const g = num(gapUm); if (d <= 0 || g <= 0) return { overlap: 0, uncovered: 0 }; const signed = 100 * (1 - g / d); return { overlap: Math.max(0, signed), uncovered: Math.max(0, -signed) }; }, [spotUm, gapUm]); const gapMm = (num(gapUm) / 1000) || 0; const spotMm = (num(spotUm) / 1000) || 0; return ( Inputs Result
Overlap
{coverage.overlap.toFixed(1)}%
{coverage.uncovered > 0 && (
{coverage.uncovered.toFixed(1)}% uncovered gap
)}
Gap
{gapMm.toFixed(4)} mm
{num(gapUm).toFixed(1)} µm
Spot Ø
{spotMm.toFixed(4)} mm
{num(spotUm).toFixed(1)} µm
From LPI
{num(lpi) > 0 ? (UM_PER_INCH / num(lpi) / 1000).toFixed(4) : "0.0000"} mm
{num(lpi) > 0 ? (UM_PER_INCH / num(lpi)).toFixed(1) : "0.0"} µm
); }