sketchmark 2.1.0 → 2.1.2
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/package.json +1 -7
- package/ANIMATABLE_MATRIX.md +0 -177
- package/KERNEL_SPEC.md +0 -412
- package/PACKS.md +0 -81
- package/PRESETS.md +0 -182
- package/dist/src/builders/index.d.ts +0 -64
- package/dist/src/builders/index.js +0 -212
- package/dist/src/compounds.d.ts +0 -13
- package/dist/src/compounds.js +0 -118
- package/dist/src/deck.d.ts +0 -4
- package/dist/src/deck.js +0 -91
- package/dist/src/export/index.d.ts +0 -8
- package/dist/src/export/index.js +0 -15
- package/dist/src/kernel.d.ts +0 -8
- package/dist/src/kernel.js +0 -68
- package/dist/src/motion.d.ts +0 -4
- package/dist/src/motion.js +0 -262
- package/dist/src/patch.d.ts +0 -5
- package/dist/src/patch.js +0 -72
- package/dist/src/player/index.d.ts +0 -68
- package/dist/src/player/index.js +0 -600
- package/dist/src/project.d.ts +0 -11
- package/dist/src/project.js +0 -107
- package/dist/src/render/raw-three.d.ts +0 -7
- package/dist/src/render/raw-three.js +0 -17
- package/dist/src/render/three-html.d.ts +0 -2
- package/dist/src/render/three-html.js +0 -257
- package/dist/src/render/three-preview-svg.d.ts +0 -3
- package/dist/src/render/three-preview-svg.js +0 -102
- package/dist/src/scenes.d.ts +0 -4
- package/dist/src/scenes.js +0 -26
- package/dist/src/sequences.d.ts +0 -43
- package/dist/src/sequences.js +0 -109
- package/dist/src/shapes/builtins.d.ts +0 -2
- package/dist/src/shapes/builtins.js +0 -393
- package/dist/src/shapes/common.d.ts +0 -9
- package/dist/src/shapes/common.js +0 -76
- package/dist/src/shapes/geometry.d.ts +0 -22
- package/dist/src/shapes/geometry.js +0 -166
- package/dist/src/shapes/index.d.ts +0 -2
- package/dist/src/shapes/index.js +0 -18
- package/dist/src/shapes/registry.d.ts +0 -8
- package/dist/src/shapes/registry.js +0 -31
- package/dist/src/shapes/types.d.ts +0 -32
- package/dist/src/shapes/types.js +0 -2
- package/examples/1730642890464.jpg +0 -0
- package/examples/app-screen.svg +0 -1
- package/examples/app-screen.visual.json +0 -503
- package/examples/dashboard-table.svg +0 -1
- package/examples/dashboard-table.visual.json +0 -708
- package/examples/dev-docs.svg +0 -1
- package/examples/dev-docs.visual.json +0 -248
- package/examples/explainer.mp4 +0 -0
- package/examples/explainer.visual.json +0 -1713
- package/examples/group-origin-effects-lab-check.svg +0 -1
- package/examples/group-origin-effects-lab.visual.json +0 -1880
- package/examples/image-clip-radius.visual.json +0 -271
- package/examples/make-app-screen.cjs +0 -368
- package/examples/make-dashboard-table.cjs +0 -277
- package/examples/make-dev-docs.cjs +0 -233
- package/examples/make-explainer.cjs +0 -438
- package/examples/make-group-origin-effects-lab.cjs +0 -370
- package/examples/make-image-clip-radius.cjs +0 -169
- package/examples/make-modal-dialog.cjs +0 -355
- package/examples/make-origin-effects-lab.cjs +0 -311
- package/examples/make-preset-character-motion.cjs +0 -32
- package/examples/make-presets-demo.cjs +0 -30
- package/examples/make-pricing.cjs +0 -286
- package/examples/make-product-demo.cjs +0 -468
- package/examples/make-product-hero.cjs +0 -223
- package/examples/make-release-notes.cjs +0 -333
- package/examples/make-settings-panel.cjs +0 -435
- package/examples/make-split-preview.cjs +0 -248
- package/examples/make-storyboard.cjs +0 -215
- package/examples/make-transcript.cjs +0 -234
- package/examples/make-typography-test.cjs +0 -397
- package/examples/make-ui-demo-explainer.cjs +0 -1094
- package/examples/make-ui-flow.cjs +0 -762
- package/examples/make-walkthrough.cjs +0 -815
- package/examples/modal-dialog.svg +0 -1
- package/examples/modal-dialog.visual.json +0 -239
- package/examples/origin-effects-lab-check.svg +0 -1
- package/examples/origin-effects-lab.visual.json +0 -1412
- package/examples/preset-character-motion.visual.json +0 -949
- package/examples/presets-demo.visual.json +0 -787
- package/examples/pricing.svg +0 -1
- package/examples/pricing.visual.json +0 -652
- package/examples/product-demo.mp4 +0 -0
- package/examples/product-demo.visual.json +0 -866
- package/examples/product-hero.svg +0 -1
- package/examples/product-hero.visual.json +0 -242
- package/examples/release-notes.svg +0 -1
- package/examples/release-notes.visual.json +0 -467
- package/examples/settings-panel.svg +0 -1
- package/examples/settings-panel.visual.json +0 -501
- package/examples/split-preview.svg +0 -1
- package/examples/split-preview.visual.json +0 -124
- package/examples/storyboard.svg +0 -1
- package/examples/storyboard.visual.json +0 -312
- package/examples/transcript.svg +0 -1
- package/examples/transcript.visual.json +0 -407
- package/examples/typography-indent-check.svg +0 -1
- package/examples/typography-lineheight-0.svg +0 -1
- package/examples/typography-lineheight-2.svg +0 -1
- package/examples/typography-test-check.svg +0 -1
- package/examples/typography-test.svg +0 -1
- package/examples/typography-test.visual.json +0 -757
- package/examples/ui-demo-explainer-billing.svg +0 -1
- package/examples/ui-demo-explainer-check.svg +0 -1
- package/examples/ui-demo-explainer-save.svg +0 -1
- package/examples/ui-demo-explainer-toggle.svg +0 -1
- package/examples/ui-demo-explainer.mp4 +0 -0
- package/examples/ui-demo-explainer.visual.json +0 -2597
- package/examples/ui-flow.mp4 +0 -0
- package/examples/ui-flow.visual.json +0 -1211
- package/examples/walkthrough.mp4 +0 -0
- package/examples/walkthrough.visual.json +0 -1372
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.roundedRectPath = roundedRectPath;
|
|
4
|
-
exports.circlePath = circlePath;
|
|
5
|
-
exports.ellipsePath = ellipsePath;
|
|
6
|
-
exports.linePath = linePath;
|
|
7
|
-
exports.curvePath = curvePath;
|
|
8
|
-
exports.pointsPath = pointsPath;
|
|
9
|
-
exports.arcPath = arcPath;
|
|
10
|
-
exports.point2 = point2;
|
|
11
|
-
exports.cuboidGeometry = cuboidGeometry;
|
|
12
|
-
exports.planeGeometry = planeGeometry;
|
|
13
|
-
exports.sphereGeometry = sphereGeometry;
|
|
14
|
-
exports.triangulateFaces = triangulateFaces;
|
|
15
|
-
const utils_1 = require("../utils");
|
|
16
|
-
function roundedRectPath(x, y, width, height, radius) {
|
|
17
|
-
const r = Math.max(0, Math.min(radius, width / 2, height / 2));
|
|
18
|
-
if (r <= 0)
|
|
19
|
-
return `M ${x} ${y} H ${x + width} V ${y + height} H ${x} Z`;
|
|
20
|
-
return [
|
|
21
|
-
`M ${x + r} ${y}`,
|
|
22
|
-
`H ${x + width - r}`,
|
|
23
|
-
`A ${r} ${r} 0 0 1 ${x + width} ${y + r}`,
|
|
24
|
-
`V ${y + height - r}`,
|
|
25
|
-
`A ${r} ${r} 0 0 1 ${x + width - r} ${y + height}`,
|
|
26
|
-
`H ${x + r}`,
|
|
27
|
-
`A ${r} ${r} 0 0 1 ${x} ${y + height - r}`,
|
|
28
|
-
`V ${y + r}`,
|
|
29
|
-
`A ${r} ${r} 0 0 1 ${x + r} ${y}`,
|
|
30
|
-
"Z"
|
|
31
|
-
].join(" ");
|
|
32
|
-
}
|
|
33
|
-
function circlePath(cx, cy, radius) {
|
|
34
|
-
return `M ${cx - radius} ${cy} A ${radius} ${radius} 0 1 0 ${cx + radius} ${cy} A ${radius} ${radius} 0 1 0 ${cx - radius} ${cy} Z`;
|
|
35
|
-
}
|
|
36
|
-
function ellipsePath(cx, cy, rx, ry) {
|
|
37
|
-
return `M ${cx - rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx + rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx - rx} ${cy} Z`;
|
|
38
|
-
}
|
|
39
|
-
function linePath(from, to) {
|
|
40
|
-
return `M ${from[0]} ${from[1]} L ${to[0]} ${to[1]}`;
|
|
41
|
-
}
|
|
42
|
-
function curvePath(from, control1, control2, to) {
|
|
43
|
-
return control2
|
|
44
|
-
? `M ${from[0]} ${from[1]} C ${control1[0]} ${control1[1]} ${control2[0]} ${control2[1]} ${to[0]} ${to[1]}`
|
|
45
|
-
: `M ${from[0]} ${from[1]} Q ${control1[0]} ${control1[1]} ${to[0]} ${to[1]}`;
|
|
46
|
-
}
|
|
47
|
-
function pointsPath(points, closed) {
|
|
48
|
-
if (!points.length)
|
|
49
|
-
return "";
|
|
50
|
-
const [first, ...rest] = points;
|
|
51
|
-
return `M ${first[0]} ${first[1]}${rest.map((point) => ` L ${point[0]} ${point[1]}`).join("")}${closed ? " Z" : ""}`;
|
|
52
|
-
}
|
|
53
|
-
function arcPath(cx, cy, radius, startAngle, endAngle, counterclockwise, closed) {
|
|
54
|
-
const start = normalizeArcStart(startAngle, endAngle, counterclockwise);
|
|
55
|
-
const end = normalizeArcEnd(start, endAngle, counterclockwise);
|
|
56
|
-
const startPoint = polarPoint(cx, cy, radius, start);
|
|
57
|
-
const endPoint = polarPoint(cx, cy, radius, end);
|
|
58
|
-
const delta = Math.abs(end - start);
|
|
59
|
-
const largeArc = delta % 360 > 180 ? 1 : 0;
|
|
60
|
-
const sweep = counterclockwise ? 0 : 1;
|
|
61
|
-
const arc = `M ${startPoint[0]} ${startPoint[1]} A ${radius} ${radius} 0 ${largeArc} ${sweep} ${endPoint[0]} ${endPoint[1]}`;
|
|
62
|
-
return closed ? `${arc} L ${cx} ${cy} Z` : arc;
|
|
63
|
-
}
|
|
64
|
-
function point2(value) {
|
|
65
|
-
return (0, utils_1.isPoint2)(value) ? [value[0], value[1]] : [0, 0];
|
|
66
|
-
}
|
|
67
|
-
function cuboidGeometry(size) {
|
|
68
|
-
const [w, h, d] = size;
|
|
69
|
-
const x = w / 2;
|
|
70
|
-
const y = h / 2;
|
|
71
|
-
const z = d / 2;
|
|
72
|
-
return {
|
|
73
|
-
vertices: [
|
|
74
|
-
[-x, -y, z],
|
|
75
|
-
[x, -y, z],
|
|
76
|
-
[x, y, z],
|
|
77
|
-
[-x, y, z],
|
|
78
|
-
[-x, -y, -z],
|
|
79
|
-
[x, -y, -z],
|
|
80
|
-
[x, y, -z],
|
|
81
|
-
[-x, y, -z]
|
|
82
|
-
],
|
|
83
|
-
faces: [
|
|
84
|
-
[0, 1, 2, 3],
|
|
85
|
-
[1, 5, 6, 2],
|
|
86
|
-
[5, 4, 7, 6],
|
|
87
|
-
[4, 0, 3, 7],
|
|
88
|
-
[3, 2, 6, 7],
|
|
89
|
-
[4, 5, 1, 0]
|
|
90
|
-
]
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function planeGeometry(size) {
|
|
94
|
-
const [w, d] = size;
|
|
95
|
-
const x = w / 2;
|
|
96
|
-
const z = d / 2;
|
|
97
|
-
return {
|
|
98
|
-
vertices: [
|
|
99
|
-
[-x, 0, -z],
|
|
100
|
-
[x, 0, -z],
|
|
101
|
-
[x, 0, z],
|
|
102
|
-
[-x, 0, z]
|
|
103
|
-
],
|
|
104
|
-
faces: [[0, 1, 2, 3]]
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
function sphereGeometry(radius, segments = 24, rings = 12) {
|
|
108
|
-
const vertices = [];
|
|
109
|
-
const faces = [];
|
|
110
|
-
for (let ring = 0; ring <= rings; ring += 1) {
|
|
111
|
-
const phi = (ring / rings) * Math.PI;
|
|
112
|
-
const y = Math.cos(phi) * radius;
|
|
113
|
-
const rr = Math.sin(phi) * radius;
|
|
114
|
-
for (let segment = 0; segment < segments; segment += 1) {
|
|
115
|
-
const theta = (segment / segments) * Math.PI * 2;
|
|
116
|
-
vertices.push([Math.cos(theta) * rr, y, Math.sin(theta) * rr]);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
for (let ring = 0; ring < rings; ring += 1) {
|
|
120
|
-
for (let segment = 0; segment < segments; segment += 1) {
|
|
121
|
-
const next = (segment + 1) % segments;
|
|
122
|
-
faces.push([
|
|
123
|
-
ring * segments + segment,
|
|
124
|
-
ring * segments + next,
|
|
125
|
-
(ring + 1) * segments + next,
|
|
126
|
-
(ring + 1) * segments + segment
|
|
127
|
-
]);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return { vertices, faces };
|
|
131
|
-
}
|
|
132
|
-
function triangulateFaces(faces) {
|
|
133
|
-
return faces.flatMap((face) => triangulateFace(face));
|
|
134
|
-
}
|
|
135
|
-
function triangulateFace(face) {
|
|
136
|
-
if (face.length < 3)
|
|
137
|
-
return [];
|
|
138
|
-
const out = [];
|
|
139
|
-
for (let index = 1; index < face.length - 1; index += 1)
|
|
140
|
-
out.push(face[0], face[index], face[index + 1]);
|
|
141
|
-
return out;
|
|
142
|
-
}
|
|
143
|
-
function normalizeArcStart(startAngle, endAngle, counterclockwise) {
|
|
144
|
-
if (!counterclockwise)
|
|
145
|
-
return startAngle;
|
|
146
|
-
let start = startAngle;
|
|
147
|
-
while (start <= endAngle)
|
|
148
|
-
start += 360;
|
|
149
|
-
return start;
|
|
150
|
-
}
|
|
151
|
-
function normalizeArcEnd(startAngle, endAngle, counterclockwise) {
|
|
152
|
-
let end = endAngle;
|
|
153
|
-
if (counterclockwise) {
|
|
154
|
-
while (end >= startAngle)
|
|
155
|
-
end -= 360;
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
while (end <= startAngle)
|
|
159
|
-
end += 360;
|
|
160
|
-
}
|
|
161
|
-
return end;
|
|
162
|
-
}
|
|
163
|
-
function polarPoint(cx, cy, radius, degrees) {
|
|
164
|
-
const radians = (degrees * Math.PI) / 180;
|
|
165
|
-
return [cx + radius * Math.cos(radians), cy + radius * Math.sin(radians)];
|
|
166
|
-
}
|
package/dist/src/shapes/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./types"), exports);
|
|
18
|
-
__exportStar(require("./registry"), exports);
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { KernelElement, VisualElement } from "../types";
|
|
2
|
-
import type { ShapeDefinition, ShapeLoweringContext } from "./types";
|
|
3
|
-
export declare function registerInternalShapeLowerer(lowerer: ShapeDefinition): void;
|
|
4
|
-
export declare function getInternalShapeLowerer(type: string): ShapeDefinition | undefined;
|
|
5
|
-
export declare function getInternalShapeDefinition(type: string): ShapeDefinition | undefined;
|
|
6
|
-
export declare function lowerAuthoringElement(element: VisualElement, context: ShapeLoweringContext): KernelElement | KernelElement[];
|
|
7
|
-
export declare function registeredAuthoringShapeTypes(): string[];
|
|
8
|
-
export declare function registeredAuthoringShapeDefinitions(): ShapeDefinition[];
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.registerInternalShapeLowerer = registerInternalShapeLowerer;
|
|
4
|
-
exports.getInternalShapeLowerer = getInternalShapeLowerer;
|
|
5
|
-
exports.getInternalShapeDefinition = getInternalShapeDefinition;
|
|
6
|
-
exports.lowerAuthoringElement = lowerAuthoringElement;
|
|
7
|
-
exports.registeredAuthoringShapeTypes = registeredAuthoringShapeTypes;
|
|
8
|
-
exports.registeredAuthoringShapeDefinitions = registeredAuthoringShapeDefinitions;
|
|
9
|
-
const builtins_1 = require("./builtins");
|
|
10
|
-
const shapeLowerers = new Map();
|
|
11
|
-
for (const lowerer of builtins_1.builtInShapeLowerers)
|
|
12
|
-
registerInternalShapeLowerer(lowerer);
|
|
13
|
-
function registerInternalShapeLowerer(lowerer) {
|
|
14
|
-
shapeLowerers.set(lowerer.type, lowerer);
|
|
15
|
-
}
|
|
16
|
-
function getInternalShapeLowerer(type) {
|
|
17
|
-
return shapeLowerers.get(type);
|
|
18
|
-
}
|
|
19
|
-
function getInternalShapeDefinition(type) {
|
|
20
|
-
return getInternalShapeLowerer(type);
|
|
21
|
-
}
|
|
22
|
-
function lowerAuthoringElement(element, context) {
|
|
23
|
-
const lowerer = getInternalShapeLowerer(element.type);
|
|
24
|
-
return lowerer ? lowerer.lower(element, context) : [];
|
|
25
|
-
}
|
|
26
|
-
function registeredAuthoringShapeTypes() {
|
|
27
|
-
return [...shapeLowerers.keys()].sort();
|
|
28
|
-
}
|
|
29
|
-
function registeredAuthoringShapeDefinitions() {
|
|
30
|
-
return [...shapeLowerers.values()];
|
|
31
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { ImageElement, KernelElement, ValidationIssue, ValidationWarning, VisualDocument, VisualElement } from "../types";
|
|
2
|
-
export interface ShapeLoweringContext {
|
|
3
|
-
lowerElements(elements: VisualElement[]): KernelElement[];
|
|
4
|
-
}
|
|
5
|
-
export interface ShapeValidationContext {
|
|
6
|
-
document: VisualDocument;
|
|
7
|
-
path: string;
|
|
8
|
-
ids: Map<string, VisualElement>;
|
|
9
|
-
issues: ValidationIssue[];
|
|
10
|
-
warnings: ValidationWarning[];
|
|
11
|
-
addIssue(path: string, code: string, message: string, suggestion?: string): void;
|
|
12
|
-
addWarning(path: string, code: string, message: string, suggestion?: string): void;
|
|
13
|
-
requireNumber(value: unknown, path: string): void;
|
|
14
|
-
requirePoint2(value: unknown, path: string, code: string, message: string): void;
|
|
15
|
-
requirePoint2Array(value: unknown, minLength: number, path: string, code: string, message: string): void;
|
|
16
|
-
requirePoint3(value: unknown, path: string, code: string, message: string): void;
|
|
17
|
-
validateEndpoint(value: unknown, path: string): void;
|
|
18
|
-
validateImageOptions(element: ImageElement): void;
|
|
19
|
-
}
|
|
20
|
-
export interface ShapeSchemaFragment {
|
|
21
|
-
properties?: Record<string, unknown>;
|
|
22
|
-
}
|
|
23
|
-
export interface ShapeDefinition {
|
|
24
|
-
type: string;
|
|
25
|
-
kind: "2d" | "3d";
|
|
26
|
-
pathQueryable?: boolean;
|
|
27
|
-
schema?: ShapeSchemaFragment;
|
|
28
|
-
lower(element: VisualElement, context: ShapeLoweringContext): KernelElement | KernelElement[];
|
|
29
|
-
validateGeometry(element: VisualElement, context: ShapeValidationContext): void;
|
|
30
|
-
validateReferences?(element: VisualElement, context: ShapeValidationContext): void;
|
|
31
|
-
validateWarnings?(element: VisualElement, context: ShapeValidationContext): void;
|
|
32
|
-
}
|
package/dist/src/shapes/types.js
DELETED
|
Binary file
|
package/examples/app-screen.svg
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1440" height="900" viewBox="0 0 1440 900" role="img"><rect x="0" y="0" width="1440" height="900" fill="#f1f5f9"/><path id="sidebar-bg" d="M 0 0 L 240 0 L 240 900 L 0 900 Z" fill="#1e293b" stroke="none" stroke-width="0"/><text id="sidebar-logo" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="16" font-weight="700" fill="#e2e8f0"><tspan x="24" y="32">Acme Studio</tspan></text><text id="ws-heading" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="10" font-weight="600" letter-spacing="1" fill="#94a3b8"><tspan x="24" y="77">WORKSPACE</tspan></text><text id="nav-dashboard" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="102.5">Dashboard</tspan></text><path id="nav-projects-active-bg" d="M 18 126 L 222 126 Q 228 126 228 132 L 228 150 Q 228 156 222 156 L 18 156 Q 12 156 12 150 L 12 132 Q 12 126 18 126 Z" fill="#334155" stroke="none" stroke-width="0"/><text id="nav-projects" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="500" fill="#e2e8f0"><tspan x="24" y="136.5">Projects</tspan></text><path id="nav-projects-indicator" d="M 4 130 L 4 148" fill="none" stroke="#2563eb" stroke-width="3" stroke-linecap="round"/><text id="nav-tasks" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="170.5">Tasks</tspan></text><text id="nav-calendar" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="204.5">Calendar</tspan></text><text id="an-heading" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="10" font-weight="600" letter-spacing="1" fill="#94a3b8"><tspan x="24" y="261">ANALYTICS</tspan></text><text id="nav-overview" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="286.5">Overview</tspan></text><text id="nav-reports" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="320.5">Reports</tspan></text><text id="nav-exports" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="354.5">Exports</tspan></text><text id="st-heading" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="10" font-weight="600" letter-spacing="1" fill="#94a3b8"><tspan x="24" y="411">SETTINGS</tspan></text><text id="nav-general" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="436.5">General</tspan></text><text id="nav-team" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="470.5">Team Members</tspan></text><text id="nav-billing" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="504.5">Billing</tspan></text><text id="nav-integrations" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#94a3b8"><tspan x="24" y="538.5">Integrations</tspan></text><text id="main-title" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="28" font-weight="700" fill="#0f172a"><tspan x="280" y="46">Projects</tspan></text><text id="main-summary" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="14" font-weight="400" fill="#475569"><tspan x="280" y="79">Track active projects across your workspace. Filter by status or team to narrow</tspan><tspan x="280" y="101.4">results. Each card shows the latest activity snapshot and assigned owner.</tspan></text><path id="chip-bg-0" d="M 295 124 L 319.5 124 Q 334.5 124 334.5 139 L 334.5 139 Q 334.5 154 319.5 154 L 295 154 Q 280 154 280 139 L 280 139 Q 280 124 295 124 Z" fill="#2563eb" stroke="none" stroke-width="0"/><text id="chip-text-0" text-anchor="middle" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="500" fill="#ffffff"><tspan x="307.25" y="139">All</tspan></text><path id="chip-bg-1" d="M 359.5 124 L 406.5 124 Q 421.5 124 421.5 139 L 421.5 139 Q 421.5 154 406.5 154 L 359.5 154 Q 344.5 154 344.5 139 L 344.5 139 Q 344.5 124 359.5 124 Z" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/><text id="chip-text-1" text-anchor="middle" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="500" fill="#334155"><tspan x="383" y="139">Active</tspan></text><path id="chip-bg-2" d="M 446.5 124 L 508.5 124 Q 523.5 124 523.5 139 L 523.5 139 Q 523.5 154 508.5 154 L 446.5 154 Q 431.5 154 431.5 139 L 431.5 139 Q 431.5 124 446.5 124 Z" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/><text id="chip-text-2" text-anchor="middle" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="500" fill="#334155"><tspan x="477.5" y="139">Archived</tspan></text><path id="chip-bg-3" d="M 548.5 124 L 603 124 Q 618 124 618 139 L 618 139 Q 618 154 603 154 L 548.5 154 Q 533.5 154 533.5 139 L 533.5 139 Q 533.5 124 548.5 124 Z" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/><text id="chip-text-3" text-anchor="middle" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="500" fill="#334155"><tspan x="575.75" y="139">My Team</tspan></text><text id="table-caption" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="12" font-weight="400" fill="#64748b"><tspan x="280" y="188">Showing 3 of 12 projects · Sorted by last activity</tspan></text><path id="card-a-bg" d="M 288 210 L 1392 210 Q 1400 210 1400 218 L 1400 322 Q 1400 330 1392 330 L 288 330 Q 280 330 280 322 L 280 218 Q 280 210 288 210 Z" fill="#ffffff" stroke="#e2e8f0" stroke-width="1"/><text id="card-a-title" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="16" font-weight="600" fill="#1e293b"><tspan x="300" y="234">Design System v3</tspan></text><text id="card-a-body" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#64748b"><tspan x="300" y="258.5">Component library refactor with updated tokens, accessibility</tspan><tspan x="300" y="278.65">improvements, and new layout primitives for dashboard views.</tspan></text><text id="card-a-meta" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="11" font-weight="400" fill="#94a3b8"><tspan x="300" y="313.5">Updated 2 hours ago · Sarah K.</tspan></text><path id="card-b-bg" d="M 288 346 L 1392 346 Q 1400 346 1400 354 L 1400 458 Q 1400 466 1392 466 L 288 466 Q 280 466 280 458 L 280 354 Q 280 346 288 346 Z" fill="#ffffff" stroke="#e2e8f0" stroke-width="1"/><text id="card-b-title" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="16" font-weight="600" fill="#1e293b"><tspan x="300" y="370">API Gateway Migration</tspan></text><text id="card-b-body" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#64748b"><tspan x="300" y="394.5">Moving from the legacy REST proxy to a new GraphQL federation</tspan><tspan x="300" y="414.65">layer with per-service schema ownership and rate limiting.</tspan></text><text id="card-b-meta" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="11" font-weight="400" fill="#94a3b8"><tspan x="300" y="449.5">Updated 1 day ago · Marcus T.</tspan></text><path id="card-c-bg" d="M 288 482 L 1392 482 Q 1400 482 1400 490 L 1400 594 Q 1400 602 1392 602 L 288 602 Q 280 602 280 594 L 280 490 Q 280 482 288 482 Z" fill="#ffffff" stroke="#e2e8f0" stroke-width="1"/><text id="card-c-title" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="16" font-weight="600" fill="#1e293b"><tspan x="300" y="506">Onboarding Flow Redesign</tspan></text><text id="card-c-body" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="13" font-weight="400" fill="#64748b"><tspan x="300" y="530.5">Streamlining the first-run experience with progressive disclosure,</tspan><tspan x="300" y="550.65">reduced form fields, and contextual help tooltips.</tspan></text><text id="card-c-meta" text-anchor="start" dominant-baseline="middle" font-family="Roboto, Arial, sans-serif" font-size="11" font-weight="400" fill="#94a3b8"><tspan x="300" y="585.5">Updated 3 days ago · Priya N.</tspan></text></svg>
|