@orangecheck/app-design 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -846,39 +846,313 @@ function Lockup({ name = "orangecheck", size = 28, className }) {
846
846
  }
847
847
  );
848
848
  }
849
+
850
+ // src/brand/portrait-tone.ts
851
+ var PORTRAIT_TONE_SIZE = 128;
852
+ var PORTRAIT_TONE_B64 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAADCKz/v//9lYBgAAAAAAAAAAAAAAFUJqiaTD5/PdnFJZqub/////////6beKXzoFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkEGl+dzPP/6XksDAAAAAAAAAAAAAABGjJTgavFzcyyhIrS////////////5serj0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABggiVXWMv/vsj0YlDAAAAAAAAAAAAAAMHTVejKWwwr+1x/n/////////////7t/Vp00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDCdFSlWU6fGrXy4eFgAAAAAAAAAAAAsZLlB5oLrQ3Of///////////////////7hnTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwABGTAzP3bK78yGOiErIQUAAAAAAAAACRYsWIa63fH/////////////////////+d2/fCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAVMD1NdbXu6q9NGRoeGQ0AAAAAAAAJHTJbneH////////////////////////v0L+rcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwGCR4zP09ync3uwlwYBgkQHCQgEAULGig8VYfP///////////////////////////v5NewYRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAYMGSEkMFJ1pebdgSUAAAAIHTI9P0lieIyq3f//////////////////////////////9s2lVgEAAAAAAAAAAAAGBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgsRGBAROni19v+1RgAAAAAGIT9efqfM5///////////////////////////////////2a9yIQAAAAAAAAAAABUcDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwULGB0lEgQoecf0/995FAAAAAAJKV+az/3////////////////////////////////////coGowAAAAAAAAAAAAHD0pAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBA0hLzwhARxlq9n77JIkAAAAAAAVUJrV////////////////////+fT///nm+f//////+dKfaCkAAAAAAAAAAA0iRjwHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgEAAR5HZ0IUM3Wnz+/djS4AAAAAAAcwa6Xd///////////////////z4f7/39Lu///////76b9rDgAAAAAAAAAdPSkwMA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAkAAAAJ3uiZSlFg7DP4s+ENgcAAAAABhQvXJ3q//////////////////Pn//jQyM/X6v//+OfqqzcAAAAAAAAAABI6MDAzHgkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB4IAA1Gq7trNUZ5r8O/p2EoEAQFBwkRESFPlez/////////////////9Pb//9/Mt6qvx+bMpZRMAAAAAAAAAAAAABY1UmRJHgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALDBglNV+tt3VMXJK7r5R7SSEQCw4RFiAkQoTP//////////////////////////HQqIyg2ch/MwAAAAAAAAAAAAAABihfnZRKFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhAFHTY/aJ+YZUZntcCRe21HKBoSEBQaJUaM3P//////////////////////+Pn76dS9p6/V2n4JAAAAAAAAAAAAAAQLKG3H1Yc5DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcJxElOkOPx5JKMGjCuIeGeUonHhwVEhUrddL////////////////////////4+em6r8/fzcqzWAAAAAAAAAAAAAAAFCRMkdDSom82DQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSkhES5MZb30t1k5eMfHsreXWTUhGRUSHU2o+P//////////////////////////77OkzdzFolgLAAAAAAAAAAAAAAASRXKdx8+7q3gyCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGgAAHEJ+zfTDbUl4x+Lf2qhlQigYFBo5gd3////////////////////////////2xaqdnJJSAgAAAAAHDgAABAAAAAVHdpjN6eLcu2spDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwEAAAMMo3d36BrXIrV6ubqvWo3JCAgL1+y/////////////////////////+/7//TVs3tlTQsAAAAAAA0SAAcoBQAAAC5llcjm7vnvqFwkBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZHAAAAAkvkdzDf1xnr/bz6f7ffz0kHSdFidn/////////////////////////+fjmwKqSakYNAAAAAAAHDQQAABQEAAAAGEl2pc3s///IeTAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACs1AAAAEU2q1bt8TFy1///5/+mkYjIeL16o7v//////////////////////////9qtrXFVPLwAAAAAAAAQGAAAAAAAAAAAMNV6RwOz//9mUQBUJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJLykBAAw2ku75z4dTZaj0///51bOHRSc9drv2///////++//////////////////5nEozQ0kVAAAAAAAAAAAAAAAAAAAAAA5Ccpe44v303a9YGgcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATk8DAAAGF7H///afkZcoPb///bMspRWLkaHwPH//////fH2//////////////////6/bzc3MgAAAAAAAAAAAAAAAAAAAAAAHluVs7q7yNfPt3MuDAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANjIAAAAQcN///8dbKUqt//////bcuoFJXqDP+f/////c7P///////////////////+azazIAAAAAAAAAAAAAAAAAAAAAAAY3eL3ZvZSfx8jCoFkhCwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOCwAAAByM+f//tVIuSrX////////4unh5sOr//////+T0/////////////////////+yyWAAAAAAAAAAAAAAAAAAAAAAAJG239P3DkaTDwNDQgSwOCwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOFAgAAAAAPbX///+1WSs/q//////////FhmqN5P///////////////////////////////9+EDAAAAAAAAAAAAAAAAAAABilkre7//+mvpLC62e6qRhYLBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEvGgYAAA5cx////8BYHD2z////////86VqSWjZ////////////////////////////////33wLAAAAAAAAAAAAAAAAAA09g7/n/////+GomLPQ58hqJQwCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQNTkiEQAAK5fs////6n4sUMX////////sklI6Z9r////////////////////////////////UWwAAAAAAAAAAAAAAAAUpWJXh////////9r+Xp7e1q20rDQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCckHUJrUiEVAgBNz///////rVJhwv////////ONPzBq3P///////////////////////////////81AAAAAAAAAAAAAAAAWRoHD+P////////npzaWPkZGRazISBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ4oPzc1Ypp2LxkFCXb5///////CeXan3P//////6oc2ImHZ////////////////////////////////0jYAAAAAAAAAAAAAFk2U1////////////vHisnlyhJR1OhkHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABonKT1JQEZojHtPLxUwq////////+e/p6Cy0vP////qj0MhVdD////////////////////////////////VNgAAAAAAAAAAABVJhtf////////////77tyvg3WGon88FggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQJCkyTFhHTG9+dnNWP2/d///////////it6Sgw/////+qTSdTvf///////////////////////////////7gpAAAAAAAAAAAHPYTF////////////89XIyrqqkpi1j0IVBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESkvKS4/Rz1GfpqGfHh1pfv////////////QlHaa5P///8hcN2rD///////////////////////////////UfBIAAAAAAAAAABllu+7////////////pxcrh2bqdp7OVVhwGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYgMjozKScvPGGlyKKBeITC//////////////61hInC////5oxomuf/////////////////////////////2nk8BAAAAAAAAAAAKXCrwtz//////////uzn8/TcsJylmoRTHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFiszOjopIS9NkdnduKKJkeT///////////////vFp8r////+u4+1+f////////////////////////////+RPy8VAAAAAAAAAAAwW2pigdL///jm///v6f3/9uTNvauKb0AUBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkhLzMzOTowP3K44ce3w7rN///////////////////q/f/////KlLf/////////////////////////////vVZAXkUAAAAAAAAAACA2MydMr///9Ob///Hk8/356tzHnW9VMg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEhwhLi4yQDZNmNDMr7ja5v7//////////////////////////9SfwP///////////////////////////9ptNVmVcwkAAAAAAAAADBESGkOk+///////+O7x+PHawK+SYUMpCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYcHiApLjM8L0Wc2tC7x+r/////////////////////////////5sDa////////////////////////////qzMhZbOdIgAAAAAAAAcOEBkoPZHz//////nc2urx8eHHuKdvPyACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFScrKCEoPUVGZ7js5Nzh+//////////////////////////////cw+T///////////////////b///////+gIhRbtbI6AAAAAAAQICgrOkVDe9z/////3MC6x9ns9unStYFHGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZKC4uIS5JT2Kl6vju5ub//////////////////////////////8iz4f/////////////////+7P///////5EcAi91diwAAAAADBooPU1ZX1Nwx////+fQ1biaq8/v++a/lFUWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABRkkKSwvQFBTarDk2tnHv+/////////////////////////////cu8jv////////7+z////////////////ngRkAByQiDAYNERQdKC85RVVcU2S4////7+LfrYOcv9Xv58CSTREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJHCgvLzM8P0xtorunp6Cf1///////////////////////////5Kqy5P//+/b7+/nfx+///////////////+qYKAAABwcCDhUWGSEwPDo/TU9JWar/////9M+il623wuHcvYxFDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsZLj01LiwsTYmvsJKGhIa/////////////////5+bz//////TIrcr5/+fF1///6cWy3P//////////////+btGAgACBQcSFhgcITJFRUlVT0ZZqv7////0yqiyt6i94te1fjYFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAkNTMuJyVQoMzQuqSJeK3////////////25LqNg5i/3NC4sr/X8//z0Lvi///cu8rq/v/////////////9z2QNAAUIDBIWGBocJzk9P1BSSVuk9v///+e9pKuklLXm3bBtJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIGDR0nJyQhJ0qNyunq2reSqvP//////////8+ddVxYebXNqIOY1fbx2sfM3////+/V3O/////////////////neRQABgcICw0OERQWJzA3SkxHVYPH////5rudkoNtj9XapFsWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYVJygcGBooQ3W78f722rKw5P//////////uGhMXHCYzMeakr/k1K2Uj7Da/f///+/Q2v////////////////+KHQUGBQcHBwYMGB0pNT1NTE1VapTH8f/uyqKJdVZ1w8eDNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEECEvLCEgIig3a8L////kysDX8f////////uaR0BniaKrl4y44cWKb2t1oMjS5Pv/78DF////////////////8YQhCAcGDRAMBw4cHCU2P0ZPW15faHyo1Nq9mpSKZXawqmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkWJCUoLzU2LCxivf////bm0Mrm////////xWUuM1iRqJqJjauvf15hc4mour/a+f/nv8X////////////////hiSgFAgcYHRQQFRkSFik2MjpVXFlTUnOan4p7h41vcI+ESQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxAZHSUvNj0sKWHC////9vPqz+H//////+6JNR4rT5/IvbCceWJWW3CNmpKSuOr9///q9P///////////////+qoOgUCCxYVDA4WFhASISwrNUlQUFZea3NrYmuDh3JeZVglAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDRQdJyUiJyEpZM3////5///XyOr/////wGIsJzdfr+HawI1PP1l1jY97c4G77/v//////////////////////bdFDAwNDAgGCA4UEhQiLDA6QkdHWHNrUExWcoyBZUpALwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYSGSElIRgWITZyyP///////9e63P///9d/Qi4vQG2w19SiXzlDc5+leVt7qs/U2fT///////////////7////5lCsIDQwJBwYGDBkYFBkgLDpARlBkc1Y2OlZ8jGpHMyEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhAVGBwdGRgnR4zU/v//////1cLs////rVUnHCdAb6rIx6d2ZXiqv5RcZaDMv4+UyPj///js/////+rIwvP//9pbDQQICQkEAAANIiQcGRglNTpFXHBhPCkwUHh5UzIaBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDA4SGBYUGSQ9eLPU/f///93F0Pn//8d1NxoWKDxeotXSuq2wsr2wg3CNq6qMZG+w5v//2bfS38zCr4N+ref/wkAFBAYLDAQAAAshJyEeHCIuMjlPW0wvICA8ZGVHJQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICxIeHR0lJCg9Xn+q2unHq7jQ5+m7bTUZFB0pMlOn5NnAzenXqIqXuruchHl2irjp//+6e3yDcG1wU0dVeauVMAAAAQkNBQAABRUeHBIWKDIzLCw1NSkeHDBVVjoUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIIFCIoLzcrISIwRVt/lIaHpbKwlGE3IRESHSIvW6jc4uz//+6rncXhu42Ej6vCyOH+0G81LjInJzUsJykvRkANAAAABwsCAAACDh0hGRknKyskGSElIBwYITk3HgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYZJzA8TEY3OTw3MDxDR1t1f2dDLB0VERggIjBZn9f4/////tDN18ir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";
853
+ var portrait = null;
854
+ function portraitTone() {
855
+ if (!portrait) {
856
+ const bin = atob(PORTRAIT_TONE_B64);
857
+ const data = new Uint8Array(bin.length);
858
+ for (let i = 0; i < bin.length; i++) data[i] = bin.charCodeAt(i);
859
+ portrait = { size: PORTRAIT_TONE_SIZE, data };
860
+ }
861
+ return portrait;
862
+ }
863
+ function sample(tone, u, v) {
864
+ const n = tone.size;
865
+ const x = Math.min(n - 1.001, Math.max(0, u * n - 0.5));
866
+ const y = Math.min(n - 1.001, Math.max(0, v * n - 0.5));
867
+ const x0 = Math.floor(x);
868
+ const y0 = Math.floor(y);
869
+ const fx = x - x0;
870
+ const fy = y - y0;
871
+ const d = tone.data;
872
+ const a = d[y0 * n + x0] * (1 - fx) + d[y0 * n + x0 + 1] * fx;
873
+ const b = d[(y0 + 1) * n + x0] * (1 - fx) + d[(y0 + 1) * n + x0 + 1] * fx;
874
+ return (a * (1 - fy) + b * fy) / 255;
875
+ }
876
+ var easeOut = (k) => 1 - Math.pow(1 - k, 3);
877
+ function HalftoneCanvas({
878
+ tone,
879
+ density = 86,
880
+ lens = true,
881
+ intro = true,
882
+ breathe = true,
883
+ ink = "#0d0a08",
884
+ fallbackSrc,
885
+ alt,
886
+ className,
887
+ style
888
+ }) {
889
+ const wrap = react.useRef(null);
890
+ const canvas = react.useRef(null);
891
+ const [live, setLive] = react.useState(false);
892
+ react.useEffect(() => {
893
+ const el = wrap.current;
894
+ const cv = canvas.current;
895
+ if (!el || !cv) return;
896
+ const ctx = cv.getContext("2d");
897
+ if (!ctx) return;
898
+ const t = tone ?? portraitTone();
899
+ const still = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
900
+ let size = 0;
901
+ let dots = new Float32Array(0);
902
+ let count = 0;
903
+ const pointer = { x: 0, y: 0, tx: 0, ty: 0, k: 0, on: false };
904
+ let start = 0;
905
+ let raf = 0;
906
+ let visible = true;
907
+ function layout() {
908
+ const s = el.clientWidth;
909
+ if (!s || s === size) return;
910
+ size = s;
911
+ const dpr = Math.min(2, window.devicePixelRatio || 1);
912
+ cv.width = Math.round(s * dpr);
913
+ cv.height = Math.round(s * dpr);
914
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
915
+ const pitch = s / density;
916
+ const c = s / 2;
917
+ const ca = Math.SQRT1_2;
918
+ const span = Math.ceil(s * 0.75 / pitch) + 1;
919
+ const out = [];
920
+ for (let i = -span; i <= span; i++) {
921
+ for (let j = -span; j <= span; j++) {
922
+ const u = i * pitch;
923
+ const v = j * pitch;
924
+ const x = c + (u - v) * ca;
925
+ const y = c + (u + v) * ca;
926
+ const dc = Math.hypot(x - c, y - c);
927
+ if (dc > c - pitch * 0.6) continue;
928
+ const inkv = sample(t, x / s, y / s);
929
+ if (inkv < 0.1) continue;
930
+ const r = pitch * Math.sqrt(inkv / Math.PI) * 1.1;
931
+ out.push(x, y, r, dc / c * 1100);
932
+ }
933
+ }
934
+ dots = Float32Array.from(out);
935
+ count = out.length / 4;
936
+ }
937
+ function frame(now) {
938
+ if (!start) start = now;
939
+ const el2 = now - start;
940
+ pointer.x += (pointer.tx - pointer.x) * 0.18;
941
+ pointer.y += (pointer.ty - pointer.y) * 0.18;
942
+ pointer.k += ((pointer.on ? 1 : 0) - pointer.k) * 0.12;
943
+ const L = size * 0.22;
944
+ ctx.clearRect(0, 0, size, size);
945
+ ctx.fillStyle = ink;
946
+ ctx.beginPath();
947
+ const wave = breathe && !still;
948
+ const sec = now / 1e3;
949
+ for (let n = 0; n < count; n++) {
950
+ let x = dots[n * 4];
951
+ let y = dots[n * 4 + 1];
952
+ let r = dots[n * 4 + 2];
953
+ if (intro && !still) {
954
+ const k = Math.min(1, Math.max(0, (el2 - dots[n * 4 + 3]) / 650));
955
+ if (k <= 0) continue;
956
+ r *= easeOut(k);
957
+ }
958
+ if (wave) r *= 1 + 0.05 * Math.sin(sec * 1.1 + (x + y) / size * 6);
959
+ if (pointer.k > 0.01) {
960
+ const dx = x - pointer.x;
961
+ const dy = y - pointer.y;
962
+ const d = Math.hypot(dx, dy);
963
+ if (d < L) {
964
+ const f = (1 - d / L) * pointer.k;
965
+ r *= 1 - 0.75 * f * f;
966
+ if (d > 1e-3) {
967
+ const push = f * (size / density) * 2.6;
968
+ x += dx / d * push;
969
+ y += dy / d * push;
970
+ }
971
+ }
972
+ }
973
+ ctx.moveTo(x + r, y);
974
+ ctx.arc(x, y, r, 0, Math.PI * 2);
975
+ }
976
+ ctx.fill();
977
+ const introDone = !intro || still || el2 > 1900;
978
+ const busy = wave || pointer.k > 0.01 || !introDone;
979
+ raf = busy && visible && !document.hidden ? requestAnimationFrame(frame) : 0;
980
+ }
981
+ const kick = () => {
982
+ if (!raf && visible && !document.hidden) raf = requestAnimationFrame(frame);
983
+ };
984
+ layout();
985
+ setLive(true);
986
+ kick();
987
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => (layout(), kick())) : null;
988
+ ro?.observe(el);
989
+ const io = typeof IntersectionObserver !== "undefined" ? new IntersectionObserver(([e]) => {
990
+ visible = Boolean(e?.isIntersecting);
991
+ kick();
992
+ }) : null;
993
+ io?.observe(el);
994
+ const onVis = () => kick();
995
+ document.addEventListener("visibilitychange", onVis);
996
+ const move = (e) => {
997
+ const b = el.getBoundingClientRect();
998
+ pointer.tx = e.clientX - b.left;
999
+ pointer.ty = e.clientY - b.top;
1000
+ if (!pointer.on) {
1001
+ pointer.x = pointer.tx;
1002
+ pointer.y = pointer.ty;
1003
+ }
1004
+ pointer.on = true;
1005
+ kick();
1006
+ };
1007
+ const leave = () => {
1008
+ pointer.on = false;
1009
+ kick();
1010
+ };
1011
+ if (lens && !still) {
1012
+ el.addEventListener("pointermove", move);
1013
+ el.addEventListener("pointerleave", leave);
1014
+ }
1015
+ return () => {
1016
+ cancelAnimationFrame(raf);
1017
+ ro?.disconnect();
1018
+ io?.disconnect();
1019
+ document.removeEventListener("visibilitychange", onVis);
1020
+ el.removeEventListener("pointermove", move);
1021
+ el.removeEventListener("pointerleave", leave);
1022
+ };
1023
+ }, [tone, density, lens, intro, breathe, ink]);
1024
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: wrap, className: cn("relative aspect-square w-full", className), style, "data-live": live || void 0, children: [
1025
+ fallbackSrc ? (
1026
+ // eslint-disable-next-line @next/next/no-img-element -- the still screen, until the live one draws
1027
+ /* @__PURE__ */ jsxRuntime.jsx(
1028
+ "img",
1029
+ {
1030
+ src: fallbackSrc,
1031
+ alt: "",
1032
+ "aria-hidden": true,
1033
+ className: cn("absolute inset-0 size-full select-none transition-opacity duration-300", live && "opacity-0"),
1034
+ draggable: false
1035
+ }
1036
+ )
1037
+ ) : null,
1038
+ /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvas, role: "img", "aria-label": alt, className: "absolute inset-0 size-full" })
1039
+ ] });
1040
+ }
849
1041
  var SPHERE_GRADIENT = "radial-gradient(86% 86% at 36% 32%, #fff7f0 0%, #ffdec8 14%, #ffa069 34%, #ff7030 56%, #f65210 78%, #de4006 100%)";
850
1042
  var SPHERE_DEPTH = "inset -14px -22px 44px rgb(150 40 0 / 0.16), 0 36px 70px -34px rgb(234 88 11 / 0.45)";
851
- function Ball({ src, alt, float }) {
852
- return /* @__PURE__ */ jsxRuntime.jsx(
853
- "div",
854
- {
855
- className: cn("relative size-full overflow-hidden rounded-full", float && "oca-animate-float"),
856
- style: { background: SPHERE_GRADIENT, boxShadow: SPHERE_DEPTH },
857
- children: /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt, className: "absolute inset-0 size-full select-none", draggable: false })
858
- }
859
- );
1043
+ var SPHERE_GLOSS = "radial-gradient(38% 30% at 33% 22%, rgb(255 255 255 / 0.55), transparent 72%)";
1044
+ function Ball({ src, alt, float, live }) {
1045
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative size-full", float && "oca-animate-float"), children: [
1046
+ /* @__PURE__ */ jsxRuntime.jsx(
1047
+ "div",
1048
+ {
1049
+ "aria-hidden": true,
1050
+ className: "absolute inset-x-[14%] -bottom-[7%] h-[10%] rounded-[50%] bg-[rgb(234_88_11/0.28)] blur-2xl"
1051
+ }
1052
+ ),
1053
+ /* @__PURE__ */ jsxRuntime.jsxs(
1054
+ "div",
1055
+ {
1056
+ className: "relative size-full overflow-hidden rounded-full",
1057
+ style: { background: SPHERE_GRADIENT, boxShadow: SPHERE_DEPTH },
1058
+ children: [
1059
+ live ? /* @__PURE__ */ jsxRuntime.jsx(HalftoneCanvas, { fallbackSrc: src, alt }) : (
1060
+ // eslint-disable-next-line @next/next/no-img-element -- a static dot layer, sized by CSS
1061
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt, className: "absolute inset-0 size-full select-none", draggable: false })
1062
+ ),
1063
+ /* @__PURE__ */ jsxRuntime.jsx(
1064
+ "div",
1065
+ {
1066
+ "aria-hidden": true,
1067
+ className: "pointer-events-none absolute inset-0 rounded-full mix-blend-soft-light",
1068
+ style: { background: SPHERE_GLOSS }
1069
+ }
1070
+ )
1071
+ ]
1072
+ }
1073
+ )
1074
+ ] });
860
1075
  }
861
- function HalftoneSphere({ src, alt, stadium = false, float = false, className, style }) {
1076
+ function HalftoneSphere({
1077
+ src,
1078
+ alt,
1079
+ stadium = false,
1080
+ float = false,
1081
+ live = false,
1082
+ className,
1083
+ style
1084
+ }) {
862
1085
  if (!stadium) {
863
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative aspect-square w-full", className), style, children: /* @__PURE__ */ jsxRuntime.jsx(Ball, { src, alt, float }) });
1086
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative aspect-square w-full", className), style, children: /* @__PURE__ */ jsxRuntime.jsx(Ball, { src, alt, float, live }) });
864
1087
  }
865
1088
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative aspect-[1.255/1.127] w-full", className), style, children: [
866
1089
  /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "oca-stadium pointer-events-none absolute left-0 top-0 h-full w-[88.4%] rounded-[32%]" }),
867
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 right-0 aspect-square w-[79.7%]", children: /* @__PURE__ */ jsxRuntime.jsx(Ball, { src, alt, float }) })
1090
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 right-0 aspect-square w-[79.7%]", children: /* @__PURE__ */ jsxRuntime.jsx(Ball, { src, alt, float, live }) })
868
1091
  ] });
869
1092
  }
870
- function IsoCheck({ size = 360, settle = false, shadow = true, title, className }) {
871
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative inline-block", settle && "oca-animate-settle", className), style: { width: size }, children: [
872
- /* @__PURE__ */ jsxRuntime.jsx(Mark, { size, title, className: "relative z-10 block" }),
873
- shadow ? /* @__PURE__ */ jsxRuntime.jsx(
874
- "div",
875
- {
876
- "aria-hidden": true,
877
- className: "absolute left-[8%] right-[8%] rounded-[50%] opacity-60 blur-xl",
878
- style: { height: size * 0.08, bottom: -size * 0.04, background: "rgb(234 88 11 / 0.18)" }
879
- }
880
- ) : null
881
- ] });
1093
+ function IsoCheck({ size = 360, settle = false, shadow = true, tilt = false, title, className }) {
1094
+ const ref = react.useRef(null);
1095
+ react.useEffect(() => {
1096
+ const el = ref.current;
1097
+ if (!el || !tilt || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
1098
+ let raf = 0;
1099
+ let tx = 0;
1100
+ let ty = 0;
1101
+ let x = 0;
1102
+ let y = 0;
1103
+ const step = () => {
1104
+ x += (tx - x) * 0.08;
1105
+ y += (ty - y) * 0.08;
1106
+ el.style.setProperty("--rx", `${(-y * 10).toFixed(2)}deg`);
1107
+ el.style.setProperty("--ry", `${(x * 14).toFixed(2)}deg`);
1108
+ raf = Math.abs(tx - x) + Math.abs(ty - y) > 1e-3 ? requestAnimationFrame(step) : 0;
1109
+ };
1110
+ const move = (e) => {
1111
+ const b = el.getBoundingClientRect();
1112
+ tx = Math.max(-1, Math.min(1, (e.clientX - (b.left + b.width / 2)) / (window.innerWidth / 2)));
1113
+ ty = Math.max(-1, Math.min(1, (e.clientY - (b.top + b.height / 2)) / (window.innerHeight / 2)));
1114
+ if (!raf) raf = requestAnimationFrame(step);
1115
+ };
1116
+ window.addEventListener("pointermove", move, { passive: true });
1117
+ return () => {
1118
+ cancelAnimationFrame(raf);
1119
+ window.removeEventListener("pointermove", move);
1120
+ };
1121
+ }, [tilt]);
1122
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1123
+ "div",
1124
+ {
1125
+ ref,
1126
+ className: cn("relative inline-block", settle && "oca-animate-settle", className),
1127
+ style: { width: size, perspective: tilt ? 900 : void 0 },
1128
+ children: [
1129
+ tilt ? /* @__PURE__ */ jsxRuntime.jsx(
1130
+ "div",
1131
+ {
1132
+ "aria-hidden": true,
1133
+ className: "absolute left-1/2 top-1/2 -z-0 aspect-square w-[120%] -translate-x-1/2 -translate-y-1/2 rounded-full opacity-70 blur-3xl",
1134
+ style: { background: "radial-gradient(closest-side, rgb(255 140 70 / 0.35), transparent)" }
1135
+ }
1136
+ ) : null,
1137
+ /* @__PURE__ */ jsxRuntime.jsx(
1138
+ "div",
1139
+ {
1140
+ className: "relative z-10 transition-transform duration-300 ease-out",
1141
+ style: tilt ? { transform: "rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg))", transformStyle: "preserve-3d" } : void 0,
1142
+ children: /* @__PURE__ */ jsxRuntime.jsx(Mark, { size, title, className: "block" })
1143
+ }
1144
+ ),
1145
+ shadow ? /* @__PURE__ */ jsxRuntime.jsx(
1146
+ "div",
1147
+ {
1148
+ "aria-hidden": true,
1149
+ className: "absolute left-[8%] right-[8%] rounded-[50%] opacity-60 blur-xl",
1150
+ style: { height: size * 0.08, bottom: -size * 0.04, background: "rgb(234 88 11 / 0.18)" }
1151
+ }
1152
+ ) : null
1153
+ ]
1154
+ }
1155
+ );
882
1156
  }
883
1157
  var CELL_W = 22;
884
1158
  var CELL_H = 27;
@@ -898,6 +1172,7 @@ function Crowd({
898
1172
  seed = 21,
899
1173
  tone = "ink",
900
1174
  label = "A crowd of identical accounts. Only a few are real.",
1175
+ story = false,
901
1176
  className
902
1177
  }) {
903
1178
  const width = cols * CELL_W;
@@ -906,37 +1181,52 @@ function Crowd({
906
1181
  const nearFrom = Math.floor(rows / 2) * cols;
907
1182
  const realSet = new Set([...picks(real, rows * cols - nearFrom, seed)].map((i) => i + nearFrom));
908
1183
  const bot = tone === "ink" ? "#ffffff" : "#0a0a0a";
1184
+ let lcg = seed * 7919 >>> 0;
1185
+ const leaveAt = () => {
1186
+ lcg = Math.imul(lcg, 1664525) + 1013904223 >>> 0;
1187
+ return 0.12 + lcg / 2 ** 32 * 0.6;
1188
+ };
909
1189
  let y = 0;
910
- return /* @__PURE__ */ jsxRuntime.jsx(
1190
+ return /* @__PURE__ */ jsxRuntime.jsxs(
911
1191
  "svg",
912
1192
  {
913
1193
  role: "img",
914
1194
  "aria-label": label,
915
1195
  viewBox: `0 0 ${width} ${Math.ceil(height)}`,
916
- className: cn("block h-auto w-full", className),
917
- children: scales.map((s, r) => {
918
- const rowY = y;
919
- y += CELL_H * s;
920
- const rowW = cols * CELL_W * s;
921
- const x0 = (width - rowW) / 2;
922
- return Array.from({ length: cols }, (_, c) => {
923
- const i = r * cols + c;
924
- const isReal = realSet.has(i);
925
- return /* @__PURE__ */ jsxRuntime.jsxs(
926
- "g",
927
- {
928
- transform: `translate(${x0 + c * CELL_W * s} ${rowY}) scale(${s})`,
929
- fill: isReal ? "var(--oca-orange)" : bot,
930
- fillOpacity: isReal ? 1 : 0.1 + 0.16 * s,
931
- children: [
932
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: 11, cy: 8, r: 4.4 }),
933
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 25a8 8.5 0 0 1 16 0Z" })
934
- ]
935
- },
936
- i
937
- );
938
- });
939
- })
1196
+ className: cn("block h-auto w-full overflow-visible", className),
1197
+ children: [
1198
+ story ? /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: "oca-crowd-glow", children: [
1199
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0", stopColor: "#ff7a3d", stopOpacity: "0.55" }),
1200
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "1", stopColor: "#ff7a3d", stopOpacity: "0" })
1201
+ ] }) }) : null,
1202
+ scales.map((s, r) => {
1203
+ const rowY = y;
1204
+ y += CELL_H * s;
1205
+ const rowW = cols * CELL_W * s;
1206
+ const x0 = (width - rowW) / 2;
1207
+ return Array.from({ length: cols }, (_, c) => {
1208
+ const i = r * cols + c;
1209
+ const isReal = realSet.has(i);
1210
+ const t = leaveAt();
1211
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0 + c * CELL_W * s} ${rowY}) scale(${s})`, children: [
1212
+ isReal && story ? /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "oca-crowd-halo", cx: 11, cy: 14, r: 13, fill: "url(#oca-crowd-glow)" }) : null,
1213
+ /* @__PURE__ */ jsxRuntime.jsxs(
1214
+ "g",
1215
+ {
1216
+ className: story ? isReal ? "oca-crowd-real" : "oca-crowd-bot" : void 0,
1217
+ style: story && !isReal ? { "--t": t.toFixed(3) } : void 0,
1218
+ fill: isReal ? "var(--oca-orange)" : bot,
1219
+ fillOpacity: isReal ? 1 : 0.1 + 0.16 * s,
1220
+ children: [
1221
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: 11, cy: 8, r: 4.4 }),
1222
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 25a8 8.5 0 0 1 16 0Z" })
1223
+ ]
1224
+ }
1225
+ )
1226
+ ] }, i);
1227
+ });
1228
+ })
1229
+ ]
940
1230
  }
941
1231
  );
942
1232
  }
@@ -1801,6 +2091,205 @@ function SatsFigure({
1801
2091
  hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] text-muted-foreground", children: hint }) : null
1802
2092
  ] });
1803
2093
  }
2094
+ function prefersStill() {
2095
+ return typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
2096
+ }
2097
+ function useInView(rootMargin = "0px 0px -12% 0px") {
2098
+ const ref = react.useRef(null);
2099
+ const [seen, setSeen] = react.useState(false);
2100
+ react.useEffect(() => {
2101
+ const el = ref.current;
2102
+ if (!el || seen) return;
2103
+ if (typeof IntersectionObserver === "undefined") {
2104
+ setSeen(true);
2105
+ return;
2106
+ }
2107
+ const io = new IntersectionObserver(
2108
+ ([e]) => {
2109
+ if (e?.isIntersecting) {
2110
+ setSeen(true);
2111
+ io.disconnect();
2112
+ }
2113
+ },
2114
+ { rootMargin }
2115
+ );
2116
+ io.observe(el);
2117
+ return () => io.disconnect();
2118
+ }, [rootMargin, seen]);
2119
+ return [ref, seen];
2120
+ }
2121
+ function Reveal({
2122
+ as = "div",
2123
+ delay = 0,
2124
+ className,
2125
+ style,
2126
+ children
2127
+ }) {
2128
+ const ref = react.useRef(null);
2129
+ react.useEffect(() => {
2130
+ const el = ref.current;
2131
+ if (!el || prefersStill() || typeof IntersectionObserver === "undefined") return;
2132
+ if (el.getBoundingClientRect().top < window.innerHeight * 0.92) return;
2133
+ el.dataset.reveal = "pending";
2134
+ const io = new IntersectionObserver(
2135
+ ([e]) => {
2136
+ if (e?.isIntersecting) {
2137
+ el.dataset.reveal = "shown";
2138
+ io.disconnect();
2139
+ }
2140
+ },
2141
+ { rootMargin: "0px 0px -10% 0px" }
2142
+ );
2143
+ io.observe(el);
2144
+ return () => io.disconnect();
2145
+ }, []);
2146
+ return react.createElement(
2147
+ as,
2148
+ { ref, className, style: { ...style, "--reveal-delay": `${delay}ms` } },
2149
+ children
2150
+ );
2151
+ }
2152
+ function ScrollStory({
2153
+ length = 2,
2154
+ className,
2155
+ innerClassName,
2156
+ children
2157
+ }) {
2158
+ const ref = react.useRef(null);
2159
+ const [pinned, setPinned] = react.useState(false);
2160
+ react.useEffect(() => {
2161
+ const el = ref.current;
2162
+ if (!el || prefersStill()) return;
2163
+ setPinned(true);
2164
+ let raf = 0;
2165
+ const update = () => {
2166
+ raf = 0;
2167
+ const r = el.getBoundingClientRect();
2168
+ const travel = r.height - window.innerHeight;
2169
+ const p = travel > 0 ? Math.min(1, Math.max(0, -r.top / travel)) : 0;
2170
+ el.style.setProperty("--p", p.toFixed(4));
2171
+ };
2172
+ const on = () => {
2173
+ if (!raf) raf = requestAnimationFrame(update);
2174
+ };
2175
+ update();
2176
+ window.addEventListener("scroll", on, { passive: true });
2177
+ window.addEventListener("resize", on);
2178
+ return () => {
2179
+ cancelAnimationFrame(raf);
2180
+ window.removeEventListener("scroll", on);
2181
+ window.removeEventListener("resize", on);
2182
+ };
2183
+ }, []);
2184
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("relative", className), style: pinned ? { height: `${length * 100}svh` } : void 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(pinned && "sticky top-0 flex min-h-svh items-center", innerClassName), children }) });
2185
+ }
2186
+ function Ticker({
2187
+ value,
2188
+ duration = 1200,
2189
+ format = (n) => Math.round(n).toLocaleString("en-US"),
2190
+ className
2191
+ }) {
2192
+ const [ref, seen] = useInView();
2193
+ const [shown, setShown] = react.useState(value);
2194
+ const animate = react.useRef(null);
2195
+ react.useEffect(() => {
2196
+ const el = ref.current;
2197
+ if (!el || animate.current !== null) return;
2198
+ animate.current = !prefersStill() && el.getBoundingClientRect().top > window.innerHeight * 0.9;
2199
+ if (animate.current) setShown(0);
2200
+ }, [ref]);
2201
+ react.useEffect(() => {
2202
+ if (!seen) return;
2203
+ if (!animate.current) {
2204
+ setShown(value);
2205
+ return;
2206
+ }
2207
+ let raf = 0;
2208
+ const t0 = performance.now();
2209
+ const step = (now) => {
2210
+ const k = Math.min(1, (now - t0) / duration);
2211
+ setShown(value * (1 - Math.pow(1 - k, 3)));
2212
+ if (k < 1) raf = requestAnimationFrame(step);
2213
+ };
2214
+ raf = requestAnimationFrame(step);
2215
+ return () => cancelAnimationFrame(raf);
2216
+ }, [seen, value, duration]);
2217
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn("oca-tabular", className), children: format(shown) });
2218
+ }
2219
+ function PhoneFrame({ className, style, children }) {
2220
+ return /* @__PURE__ */ jsxRuntime.jsx(
2221
+ "div",
2222
+ {
2223
+ className: cn(
2224
+ "relative w-[17.5rem] shrink-0 rounded-[2.9rem] bg-[#0b0b0c] p-[0.6rem]",
2225
+ "shadow-[0_50px_100px_-40px_rgb(10_10_10/0.55),0_0_0_1px_rgb(255_255_255/0.06)_inset]",
2226
+ className
2227
+ ),
2228
+ style,
2229
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative aspect-[9/19.2] overflow-hidden rounded-[2.35rem] bg-background", children: [
2230
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "absolute left-1/2 top-2.5 z-10 h-[1.35rem] w-[5.6rem] -translate-x-1/2 rounded-full bg-[#0b0b0c]" }),
2231
+ children
2232
+ ] })
2233
+ }
2234
+ );
2235
+ }
2236
+ function BrowserFrame({
2237
+ url = "ochk.app",
2238
+ className,
2239
+ style,
2240
+ children
2241
+ }) {
2242
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2243
+ "div",
2244
+ {
2245
+ className: cn(
2246
+ "overflow-hidden rounded-[1.1rem] border border-border bg-card",
2247
+ "shadow-[0_40px_90px_-40px_rgb(10_10_10/0.45)]",
2248
+ className
2249
+ ),
2250
+ style,
2251
+ children: [
2252
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-10 items-center gap-3 border-b border-border px-4", children: [
2253
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-hidden": true, className: "flex gap-1.5", children: [
2254
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2.5 rounded-full bg-[#ff5f57]" }),
2255
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2.5 rounded-full bg-[#febc2e]" }),
2256
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2.5 rounded-full bg-[#28c840]" })
2257
+ ] }),
2258
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto flex h-6 min-w-0 max-w-[60%] flex-1 items-center justify-center rounded-md bg-muted px-3 text-[0.75rem] text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: url }) }),
2259
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "w-[2.6rem]" })
2260
+ ] }),
2261
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children })
2262
+ ]
2263
+ }
2264
+ );
2265
+ }
2266
+ function FloatChip({
2267
+ icon,
2268
+ title,
2269
+ detail,
2270
+ delay = 0,
2271
+ className,
2272
+ style
2273
+ }) {
2274
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2275
+ "div",
2276
+ {
2277
+ className: cn(
2278
+ "oca-animate-drift flex items-center gap-3 rounded-2xl border border-border bg-card/90 py-2.5 pl-2.5 pr-4 backdrop-blur-md",
2279
+ "shadow-[0_24px_50px_-24px_rgb(10_10_10/0.35)]",
2280
+ className
2281
+ ),
2282
+ style: { animationDelay: `${-delay}s`, ...style },
2283
+ children: [
2284
+ icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-4", children: icon }) : null,
2285
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
2286
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] font-medium leading-tight", children: title }),
2287
+ detail ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.8125rem] leading-tight text-muted-foreground", children: detail }) : null
2288
+ ] })
2289
+ ]
2290
+ }
2291
+ );
2292
+ }
1804
2293
  function NavLink({ item, className, onNavigate }) {
1805
2294
  const cls = cn(
1806
2295
  "rounded-full px-3 py-2 text-[0.9375rem] transition-colors",
@@ -2093,6 +2582,7 @@ exports.ActivityList = ActivityList;
2093
2582
  exports.AppIcon = AppIcon;
2094
2583
  exports.AppShell = AppShell;
2095
2584
  exports.Badge = Badge;
2585
+ exports.BrowserFrame = BrowserFrame;
2096
2586
  exports.Button = Button;
2097
2587
  exports.Card = Card;
2098
2588
  exports.CardContent = CardContent;
@@ -2129,7 +2619,9 @@ exports.EmptyLine = EmptyLine;
2129
2619
  exports.EmptyState = EmptyState;
2130
2620
  exports.Eyebrow = Eyebrow;
2131
2621
  exports.Field = Field;
2622
+ exports.FloatChip = FloatChip;
2132
2623
  exports.Footnote = Footnote;
2624
+ exports.HalftoneCanvas = HalftoneCanvas;
2133
2625
  exports.HalftoneSphere = HalftoneSphere;
2134
2626
  exports.HashChip = HashChip;
2135
2627
  exports.Input = Input;
@@ -2146,6 +2638,7 @@ exports.Notice = Notice;
2146
2638
  exports.PackageCard = PackageCard;
2147
2639
  exports.PageHeader = PageHeader;
2148
2640
  exports.PageHero = PageHero;
2641
+ exports.PhoneFrame = PhoneFrame;
2149
2642
  exports.Popover = Popover;
2150
2643
  exports.PopoverAnchor = PopoverAnchor;
2151
2644
  exports.PopoverContent = PopoverContent;
@@ -2154,10 +2647,12 @@ exports.ProgressSteps = ProgressSteps;
2154
2647
  exports.Prose = Prose;
2155
2648
  exports.RadioGroup = RadioGroup;
2156
2649
  exports.RadioGroupItem = RadioGroupItem;
2650
+ exports.Reveal = Reveal;
2157
2651
  exports.SPHERE_GRADIENT = SPHERE_GRADIENT;
2158
2652
  exports.Sats = Sats;
2159
2653
  exports.SatsFigure = SatsFigure;
2160
2654
  exports.ScrollFade = ScrollFade;
2655
+ exports.ScrollStory = ScrollStory;
2161
2656
  exports.Section = Section;
2162
2657
  exports.SectionIntro = SectionIntro;
2163
2658
  exports.Select = Select;
@@ -2191,6 +2686,7 @@ exports.TabsList = TabsList;
2191
2686
  exports.TabsTrigger = TabsTrigger;
2192
2687
  exports.Textarea = Textarea;
2193
2688
  exports.ThemeToggle = ThemeToggle;
2689
+ exports.Ticker = Ticker;
2194
2690
  exports.Toaster = Toaster;
2195
2691
  exports.Tooltip = Tooltip;
2196
2692
  exports.TooltipContent = TooltipContent;
@@ -2204,9 +2700,11 @@ exports.badgeVariants = badgeVariants;
2204
2700
  exports.buttonVariants = buttonVariants;
2205
2701
  exports.cardVariants = cardVariants;
2206
2702
  exports.cn = cn;
2703
+ exports.portraitTone = portraitTone;
2207
2704
  exports.satsText = satsText;
2208
2705
  exports.sectionVariants = sectionVariants;
2209
2706
  exports.useCopy = useCopy;
2707
+ exports.useInView = useInView;
2210
2708
  exports.useShellPlace = useShellPlace;
2211
2709
  exports.useTimedOut = useTimedOut;
2212
2710
  //# sourceMappingURL=index.js.map