@illuma-ai/icons 2.2.0 → 2.3.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.
@@ -0,0 +1,25 @@
1
+ import { SVGProps } from 'react';
2
+ export interface TerminalIconProps extends Omit<SVGProps<SVGSVGElement>, 'children'> {
3
+ /** Pixel size for width and height. Defaults to 24. */
4
+ size?: number;
5
+ }
6
+ /**
7
+ * Static terminal glyph — a rounded window with a prompt chevron and a cursor
8
+ * line. `currentColor` for strokes so it inherits the surrounding text color
9
+ * (works on light and dark); the cursor is brand yellow.
10
+ */
11
+ export declare const TerminalIcon: import('react').ForwardRefExoticComponent<Omit<TerminalIconProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
12
+ export interface AnimatedTerminalIconProps extends TerminalIconProps {
13
+ /** When false, renders the static icon (no animation). Defaults to true. */
14
+ running?: boolean;
15
+ /** Cursor/typing color. Defaults to brand yellow (#facc15). */
16
+ accent?: string;
17
+ }
18
+ /**
19
+ * Animated terminal logo for an in-progress terminal/code step: a prompt chevron
20
+ * with a blinking yellow cursor and a subtle "typing" line that grows and resets,
21
+ * evoking a command being typed. Subtle enough to suit light and dark themes;
22
+ * honors `prefers-reduced-motion` (framer-motion disables transform/opacity
23
+ * tweens automatically). When `running` is false it settles to the static icon.
24
+ */
25
+ export declare const AnimatedTerminalIcon: import('react').ForwardRefExoticComponent<Omit<AnimatedTerminalIconProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,16 @@
1
+ export interface ThinkingOrbProps {
2
+ /** Pixel diameter. Defaults to 20 (inline with text). */
3
+ size?: number;
4
+ /** Animation speed multiplier. Defaults to 1. */
5
+ speed?: number;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * A premium, AI-"thinking" fluid orb rendered with raw WebGL (no three.js). A
10
+ * simplex-noise–deformed sphere with a shifting cyan→violet→magenta→amber
11
+ * gradient and fresnel rim — the kind of organic, alive blob shown in modern
12
+ * assistant UIs. Self-contained (~3KB), 60fps on a tiny canvas, transparent
13
+ * background so it sits inline beside "Thinking" text on any theme. Falls back
14
+ * gracefully (renders nothing) where WebGL is unavailable.
15
+ */
16
+ export declare function ThinkingOrb({ size, speed, className }: ThinkingOrbProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ export { TerminalIcon, AnimatedTerminalIcon } from './Terminal';
2
+ export type { TerminalIconProps, AnimatedTerminalIconProps } from './Terminal';
3
+ export { ThinkingOrb } from './ThinkingOrb';
4
+ export type { ThinkingOrbProps } from './ThinkingOrb';
package/dist/brand.cjs ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),l=require("react"),u=require("framer-motion"),p=l.forwardRef(function({size:o=24,className:a,...r},n){return i.jsxs("svg",{ref:n,width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:a,role:"img","aria-label":"Terminal",...r,children:[i.jsx("rect",{x:"2.5",y:"4",width:"19",height:"16",rx:"2.5"}),i.jsx("path",{d:"m6.5 9 3 3-3 3"}),i.jsx("path",{d:"M12.5 15h4",stroke:"#facc15"})]})}),b=l.forwardRef(function({size:o=24,running:a=!0,accent:r="#facc15",className:n,...s},e){return a?i.jsxs("svg",{ref:e,width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:n,role:"img","aria-label":"Terminal running",...s,children:[i.jsx("rect",{x:"2.5",y:"4",width:"19",height:"16",rx:"2.5"}),i.jsx("path",{d:"m6.5 9 3 3-3 3"}),i.jsx(u.motion.path,{d:"M12.5 15h5",stroke:r,initial:{pathLength:0,opacity:.9},animate:{pathLength:[0,1,1,0]},transition:{duration:1.6,times:[0,.5,.8,1],repeat:1/0,ease:"easeInOut"}}),i.jsx(u.motion.rect,{x:"18.5",y:"13.4",width:"1.6",height:"3.2",rx:"0.3",fill:r,stroke:"none",animate:{opacity:[1,1,0,0,1]},transition:{duration:1.1,times:[0,.4,.5,.9,1],repeat:1/0}})]}):i.jsx(p,{ref:e,size:o,className:n,...s})}),R=`
2
+ attribute vec2 p;
3
+ varying vec2 uv;
4
+ void main() { uv = p; gl_Position = vec4(p, 0.0, 1.0); }
5
+ `,T=`
6
+ precision highp float;
7
+ varying vec2 uv;
8
+ uniform float t;
9
+
10
+ // Classic 2D simplex noise (Ashima Arts, MIT) — compact.
11
+ vec3 permute(vec3 x){return mod(((x*34.0)+1.0)*x,289.0);}
12
+ float snoise(vec2 v){
13
+ const vec4 C=vec4(0.211324865,0.366025404,-0.577350269,0.024390244);
14
+ vec2 i=floor(v+dot(v,C.yy));vec2 x0=v-i+dot(i,C.xx);
15
+ vec2 i1=(x0.x>x0.y)?vec2(1.0,0.0):vec2(0.0,1.0);
16
+ vec4 x12=x0.xyxy+C.xxzz;x12.xy-=i1;
17
+ i=mod(i,289.0);
18
+ vec3 p=permute(permute(i.y+vec3(0.0,i1.y,1.0))+i.x+vec3(0.0,i1.x,1.0));
19
+ vec3 m=max(0.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),dot(x12.zw,x12.zw)),0.0);
20
+ m=m*m;m=m*m;
21
+ vec3 x=2.0*fract(p*C.www)-1.0;vec3 h=abs(x)-0.5;vec3 ox=floor(x+0.5);vec3 a0=x-ox;
22
+ m*=1.79284291-0.85373472*(a0*a0+h*h);
23
+ vec3 g;g.x=a0.x*x0.x+h.x*x0.y;g.yz=a0.yz*x12.xz+h.yz*x12.yw;
24
+ return 130.0*dot(m,g);
25
+ }
26
+
27
+ void main(){
28
+ vec2 p=uv;
29
+ float r=length(p);
30
+ // Noise-deform the radius so the silhouette wobbles organically.
31
+ float n=snoise(p*2.2+vec2(t*0.25,t*0.18))*0.5+snoise(p*4.0-vec2(t*0.2))*0.25;
32
+ float edge=0.78+n*0.16;
33
+ float orb=smoothstep(edge,edge-0.18,r);
34
+ if(orb<0.01){ gl_FragColor=vec4(0.0); return; }
35
+ // Shifting gradient palette.
36
+ float a=atan(p.y,p.x);
37
+ float f=0.5+0.5*sin(a*1.0+t*0.6+n*2.0);
38
+ vec3 cyan=vec3(0.20,0.85,0.95);
39
+ vec3 violet=vec3(0.55,0.35,0.95);
40
+ vec3 magenta=vec3(0.95,0.30,0.70);
41
+ vec3 amber=vec3(1.0,0.75,0.30);
42
+ vec3 col=mix(cyan,violet,smoothstep(0.0,0.4,f));
43
+ col=mix(col,magenta,smoothstep(0.35,0.7,f));
44
+ col=mix(col,amber,smoothstep(0.7,1.0,f));
45
+ // Inner glow + fresnel rim.
46
+ float glow=smoothstep(0.0,0.6,1.0-r);
47
+ col+=glow*0.25;
48
+ float rim=smoothstep(edge-0.02,edge-0.16,r);
49
+ col=mix(col,vec3(1.0),(1.0-rim)*0.35*orb);
50
+ gl_FragColor=vec4(col,orb);
51
+ }
52
+ `;function g(t,o,a){const r=t.createShader(o);return t.shaderSource(r,a),t.compileShader(r),r}function k({size:t=20,speed:o=1,className:a}){const r=l.useRef(null);return l.useEffect(()=>{const n=r.current;if(!n)return;const s=Math.min(window.devicePixelRatio||1,2);n.width=t*s,n.height=t*s;const e=n.getContext("webgl",{premultipliedAlpha:!1,alpha:!0});if(!e)return;const c=e.createProgram();e.attachShader(c,g(e,e.VERTEX_SHADER,R)),e.attachShader(c,g(e,e.FRAGMENT_SHADER,T)),e.linkProgram(c),e.useProgram(c);const y=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,y),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,3,-1,-1,3]),e.STATIC_DRAW);const d=e.getAttribLocation(c,"p");e.enableVertexAttribArray(d),e.vertexAttribPointer(d,2,e.FLOAT,!1,0,0);const w=e.getUniformLocation(c,"t");e.viewport(0,0,n.width,n.height),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA);const f=typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;let m=0,x=0;const v=h=>{x||(x=h);const A=(h-x)/1e3*o;e.uniform1f(w,f?.4:A),e.drawArrays(e.TRIANGLES,0,3),f||(m=requestAnimationFrame(v))};return m=requestAnimationFrame(v),()=>{cancelAnimationFrame(m),e.getExtension("WEBGL_lose_context")?.loseContext()}},[t,o]),i.jsx("canvas",{ref:r,className:a,style:{width:t,height:t,display:"inline-block"},role:"img","aria-label":"Thinking"})}exports.AnimatedTerminalIcon=b;exports.TerminalIcon=p;exports.ThinkingOrb=k;
53
+ //# sourceMappingURL=brand.cjs.map
@@ -0,0 +1,178 @@
1
+ import { jsxs as p, jsx as n } from "react/jsx-runtime";
2
+ import { forwardRef as g, useRef as b, useEffect as R } from "react";
3
+ import { motion as v } from "framer-motion";
4
+ const T = g(function({ size: o = 24, className: a, ...r }, i) {
5
+ return /* @__PURE__ */ p(
6
+ "svg",
7
+ {
8
+ ref: i,
9
+ width: o,
10
+ height: o,
11
+ viewBox: "0 0 24 24",
12
+ fill: "none",
13
+ stroke: "currentColor",
14
+ strokeWidth: 2,
15
+ strokeLinecap: "round",
16
+ strokeLinejoin: "round",
17
+ className: a,
18
+ role: "img",
19
+ "aria-label": "Terminal",
20
+ ...r,
21
+ children: [
22
+ /* @__PURE__ */ n("rect", { x: "2.5", y: "4", width: "19", height: "16", rx: "2.5" }),
23
+ /* @__PURE__ */ n("path", { d: "m6.5 9 3 3-3 3" }),
24
+ /* @__PURE__ */ n("path", { d: "M12.5 15h4", stroke: "#facc15" })
25
+ ]
26
+ }
27
+ );
28
+ }), _ = g(
29
+ function({ size: o = 24, running: a = !0, accent: r = "#facc15", className: i, ...l }, e) {
30
+ return a ? /* @__PURE__ */ p(
31
+ "svg",
32
+ {
33
+ ref: e,
34
+ width: o,
35
+ height: o,
36
+ viewBox: "0 0 24 24",
37
+ fill: "none",
38
+ stroke: "currentColor",
39
+ strokeWidth: 2,
40
+ strokeLinecap: "round",
41
+ strokeLinejoin: "round",
42
+ className: i,
43
+ role: "img",
44
+ "aria-label": "Terminal running",
45
+ ...l,
46
+ children: [
47
+ /* @__PURE__ */ n("rect", { x: "2.5", y: "4", width: "19", height: "16", rx: "2.5" }),
48
+ /* @__PURE__ */ n("path", { d: "m6.5 9 3 3-3 3" }),
49
+ /* @__PURE__ */ n(
50
+ v.path,
51
+ {
52
+ d: "M12.5 15h5",
53
+ stroke: r,
54
+ initial: { pathLength: 0, opacity: 0.9 },
55
+ animate: { pathLength: [0, 1, 1, 0] },
56
+ transition: { duration: 1.6, times: [0, 0.5, 0.8, 1], repeat: 1 / 0, ease: "easeInOut" }
57
+ }
58
+ ),
59
+ /* @__PURE__ */ n(
60
+ v.rect,
61
+ {
62
+ x: "18.5",
63
+ y: "13.4",
64
+ width: "1.6",
65
+ height: "3.2",
66
+ rx: "0.3",
67
+ fill: r,
68
+ stroke: "none",
69
+ animate: { opacity: [1, 1, 0, 0, 1] },
70
+ transition: { duration: 1.1, times: [0, 0.4, 0.5, 0.9, 1], repeat: 1 / 0 }
71
+ }
72
+ )
73
+ ]
74
+ }
75
+ ) : /* @__PURE__ */ n(T, { ref: e, size: o, className: i, ...l });
76
+ }
77
+ ), k = `
78
+ attribute vec2 p;
79
+ varying vec2 uv;
80
+ void main() { uv = p; gl_Position = vec4(p, 0.0, 1.0); }
81
+ `, C = `
82
+ precision highp float;
83
+ varying vec2 uv;
84
+ uniform float t;
85
+
86
+ // Classic 2D simplex noise (Ashima Arts, MIT) — compact.
87
+ vec3 permute(vec3 x){return mod(((x*34.0)+1.0)*x,289.0);}
88
+ float snoise(vec2 v){
89
+ const vec4 C=vec4(0.211324865,0.366025404,-0.577350269,0.024390244);
90
+ vec2 i=floor(v+dot(v,C.yy));vec2 x0=v-i+dot(i,C.xx);
91
+ vec2 i1=(x0.x>x0.y)?vec2(1.0,0.0):vec2(0.0,1.0);
92
+ vec4 x12=x0.xyxy+C.xxzz;x12.xy-=i1;
93
+ i=mod(i,289.0);
94
+ vec3 p=permute(permute(i.y+vec3(0.0,i1.y,1.0))+i.x+vec3(0.0,i1.x,1.0));
95
+ vec3 m=max(0.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),dot(x12.zw,x12.zw)),0.0);
96
+ m=m*m;m=m*m;
97
+ vec3 x=2.0*fract(p*C.www)-1.0;vec3 h=abs(x)-0.5;vec3 ox=floor(x+0.5);vec3 a0=x-ox;
98
+ m*=1.79284291-0.85373472*(a0*a0+h*h);
99
+ vec3 g;g.x=a0.x*x0.x+h.x*x0.y;g.yz=a0.yz*x12.xz+h.yz*x12.yw;
100
+ return 130.0*dot(m,g);
101
+ }
102
+
103
+ void main(){
104
+ vec2 p=uv;
105
+ float r=length(p);
106
+ // Noise-deform the radius so the silhouette wobbles organically.
107
+ float n=snoise(p*2.2+vec2(t*0.25,t*0.18))*0.5+snoise(p*4.0-vec2(t*0.2))*0.25;
108
+ float edge=0.78+n*0.16;
109
+ float orb=smoothstep(edge,edge-0.18,r);
110
+ if(orb<0.01){ gl_FragColor=vec4(0.0); return; }
111
+ // Shifting gradient palette.
112
+ float a=atan(p.y,p.x);
113
+ float f=0.5+0.5*sin(a*1.0+t*0.6+n*2.0);
114
+ vec3 cyan=vec3(0.20,0.85,0.95);
115
+ vec3 violet=vec3(0.55,0.35,0.95);
116
+ vec3 magenta=vec3(0.95,0.30,0.70);
117
+ vec3 amber=vec3(1.0,0.75,0.30);
118
+ vec3 col=mix(cyan,violet,smoothstep(0.0,0.4,f));
119
+ col=mix(col,magenta,smoothstep(0.35,0.7,f));
120
+ col=mix(col,amber,smoothstep(0.7,1.0,f));
121
+ // Inner glow + fresnel rim.
122
+ float glow=smoothstep(0.0,0.6,1.0-r);
123
+ col+=glow*0.25;
124
+ float rim=smoothstep(edge-0.02,edge-0.16,r);
125
+ col=mix(col,vec3(1.0),(1.0-rim)*0.35*orb);
126
+ gl_FragColor=vec4(col,orb);
127
+ }
128
+ `;
129
+ function u(t, o, a) {
130
+ const r = t.createShader(o);
131
+ return t.shaderSource(r, a), t.compileShader(r), r;
132
+ }
133
+ function S({ size: t = 20, speed: o = 1, className: a }) {
134
+ const r = b(null);
135
+ return R(() => {
136
+ const i = r.current;
137
+ if (!i)
138
+ return;
139
+ const l = Math.min(window.devicePixelRatio || 1, 2);
140
+ i.width = t * l, i.height = t * l;
141
+ const e = i.getContext("webgl", { premultipliedAlpha: !1, alpha: !0 });
142
+ if (!e)
143
+ return;
144
+ const c = e.createProgram();
145
+ e.attachShader(c, u(e, e.VERTEX_SHADER, k)), e.attachShader(c, u(e, e.FRAGMENT_SHADER, C)), e.linkProgram(c), e.useProgram(c);
146
+ const y = e.createBuffer();
147
+ e.bindBuffer(e.ARRAY_BUFFER, y), e.bufferData(e.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), e.STATIC_DRAW);
148
+ const x = e.getAttribLocation(c, "p");
149
+ e.enableVertexAttribArray(x), e.vertexAttribPointer(x, 2, e.FLOAT, !1, 0, 0);
150
+ const w = e.getUniformLocation(c, "t");
151
+ e.viewport(0, 0, i.width, i.height), e.enable(e.BLEND), e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA);
152
+ const d = typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
153
+ let s = 0, m = 0;
154
+ const f = (h) => {
155
+ m || (m = h);
156
+ const A = (h - m) / 1e3 * o;
157
+ e.uniform1f(w, d ? 0.4 : A), e.drawArrays(e.TRIANGLES, 0, 3), d || (s = requestAnimationFrame(f));
158
+ };
159
+ return s = requestAnimationFrame(f), () => {
160
+ cancelAnimationFrame(s), e.getExtension("WEBGL_lose_context")?.loseContext();
161
+ };
162
+ }, [t, o]), /* @__PURE__ */ n(
163
+ "canvas",
164
+ {
165
+ ref: r,
166
+ className: a,
167
+ style: { width: t, height: t, display: "inline-block" },
168
+ role: "img",
169
+ "aria-label": "Thinking"
170
+ }
171
+ );
172
+ }
173
+ export {
174
+ _ as AnimatedTerminalIcon,
175
+ T as TerminalIcon,
176
+ S as ThinkingOrb
177
+ };
178
+ //# sourceMappingURL=brand.es.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@illuma-ai/icons",
3
- "version": "2.2.0",
4
- "description": "Illuma icon system: icons8 2025-color Office/Fluent file-type icons (static + animated coding-state GIFs) + hover-animated nav icons.",
3
+ "version": "2.3.0",
4
+ "description": "Illuma icon system: file-type icons (static + animated GIF), hover-animated nav icons, terminal logo, and a WebGL thinking orb.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Illuma AI",
@@ -24,6 +24,11 @@
24
24
  "types": "./dist/animated/index.d.ts",
25
25
  "import": "./dist/animated.es.js",
26
26
  "require": "./dist/animated.cjs"
27
+ },
28
+ "./brand": {
29
+ "types": "./dist/brand/index.d.ts",
30
+ "import": "./dist/brand.es.js",
31
+ "require": "./dist/brand.cjs"
27
32
  }
28
33
  },
29
34
  "files": [