@akanjs/cli 3.0.0-beta.8 → 3.0.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/.build-stamp +1 -1
- package/CodeAgent-2vmp9qe0.js +9 -0
- package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/CodeTui-5ed6bg2a.js +1457 -0
- package/README.ko.md +83 -28
- package/README.md +70 -27
- package/TunnelShare-cwh9ezsm.js +9 -0
- package/{agent.command-0q17pnrs.js → agent.command-gn73rhe7.js} +8 -9
- package/akanCode.js +102 -0
- package/application.command-e968t0hw.js +246 -0
- package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-64taxseg.js} +121 -77
- package/buildBatch.proc.js +120 -32
- package/cloud.command-0jm301rr.js +95 -0
- package/cloud.script-nemnzjpv.js +20 -0
- package/code.command-18kcm7hq.js +154 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/context.command-trd9bn18.js +48 -0
- package/context.runner-y5hwh673.js +21 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-06z2dmrr.js} +2 -2
- package/{devTui-m1atgkc9.js → devTui-q7k7bakd.js} +122 -40
- package/fileSys-wzzrntkw.js +9 -0
- package/guideline.command-bdmdn2de.js +42 -0
- package/guidelines/agentRule/agentRule.instruction.md +154 -26
- package/guidelines/conventions/conventions.instruction.md +134 -48
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/guidelines/queryRule/queryRule.instruction.md +21 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +291 -6
- package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
- package/guidelines/transportRule/transportRule.instruction.md +10 -8
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +20 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
- package/incrementalBuilder.proc.js +564 -109
- package/index-0wpybxtr.js +2729 -0
- package/{index-kcxmv48c.js → index-2ahj896a.js} +45 -79
- package/index-2wc41k5w.js +49 -0
- package/index-3hx1z96c.js +87 -0
- package/{index-2tv3fdx4.js → index-3w94e7n3.js} +1228 -1458
- package/{index-hwkygn9s.js → index-48k96p55.js} +325 -36
- package/index-4npz05nm.js +187 -0
- package/{index-q0y2jq9j.js → index-52w0fvh8.js} +21 -4
- package/index-6he6gvfg.js +4300 -0
- package/index-7md2g9vw.js +6 -0
- package/{index-04bk599g.js → index-93j60em0.js} +10 -17
- package/index-94s080qm.js +266 -0
- package/index-9dp031by.js +12 -0
- package/{index-ktb5njgy.js → index-9z771ptz.js} +49 -99
- package/{index-y6n8nmny.js → index-abxpehf8.js} +75 -203
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/{index-9077wzd2.js → index-by9pxkr0.js} +43 -26
- package/index-c6eggbee.js +123 -0
- package/index-d2242ksy.js +99 -0
- package/index-drehwpdt.js +1119 -0
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-ffvk10zz.js → index-f3c78nd6.js} +107 -241
- package/index-gbggbqcp.js +1058 -0
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/index-hsmtysz4.js +53 -0
- package/{index-j9yhg404.js → index-jmrn54tt.js} +4 -7
- package/{index-a64esmtb.js → index-kcdj1z5v.js} +523 -1022
- package/{index-d43r08tf.js → index-kqabytj7.js} +77 -150
- package/{index-vyvre9en.js → index-mbxbhay5.js} +6 -2
- package/{index-vxtad5bd.js → index-mgxpx3f2.js} +5 -8
- package/index-p6pbz9n5.js +25 -0
- package/{index-sj5vxr8f.js → index-p993efkq.js} +981 -897
- package/{index-2xp0kfkt.js → index-pmhqttv3.js} +37 -25
- package/index-tqm7jjcn.js +700 -0
- package/{index-0g7r8xz3.js → index-vpj42xwt.js} +114 -232
- package/index-wa5jbxj1.js +760 -0
- package/{index-k2j1hc4r.js → index-wprnsjms.js} +12 -12
- package/{index-gyd220p2.js → index-y3mphr1m.js} +554 -577
- package/index-yg7jhz8x.js +69 -0
- package/{index-h7yw2z9n.js → index-zzvvc845.js} +8 -14
- package/index.js +23 -22
- package/{library.command-qzzbj6d8.js → library.command-9h749a1x.js} +4 -5
- package/{localRegistry.command-vyrgg4xw.js → localRegistry.command-2bqqhxyz.js} +23 -43
- package/{module.command-rq5hq3ax.js → module.command-nv8nzgft.js} +8 -12
- package/{package.command-d9hd6v9n.js → package.command-mq4bggp6.js} +6 -7
- package/package.json +15 -7
- package/{page.command-126d56te.js → page.command-j639n707.js} +4 -5
- package/{primitive.command-taxd1538.js → primitive.command-kz6849th.js} +9 -23
- package/prompter-76k56b37.js +8 -0
- package/{quality.command-6gsna0a3.js → quality.command-4hyabwkb.js} +205 -377
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-tq2dgy72.js → repair.command-a9awpbqr.js} +11 -35
- package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
- package/{scalar.command-3bcmrrkv.js → scalar.command-ma4fpm9m.js} +7 -11
- package/skills/akan-code/SKILL.md +130 -0
- package/skills/akan-debug/SKILL.md +42 -0
- package/skills/akan-deps/SKILL.md +50 -0
- package/skills/akan-err/SKILL.md +39 -0
- package/skills/akan-module/SKILL.md +45 -0
- package/skills/akan-scaffold/SKILL.md +76 -0
- package/skills/akan-scalar/SKILL.md +52 -0
- package/skills/akan-service/SKILL.md +34 -0
- package/skills/akan-store/SKILL.md +67 -0
- package/skills/akan-ui/SKILL.md +63 -0
- package/skills/akan-validate/SKILL.md +44 -0
- package/{subspace.command-eddzqpx3.js → subspace.command-3k2pmrs4.js} +53 -62
- package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
- package/templates/app/page/_index.tsx +257 -258
- package/templates/app/page/_layout.tsx +5 -1
- package/templates/app/page/_overrides.tsx +12 -0
- package/templates/app/page/styles.css.template +316 -14
- package/templates/app/public/apple-touch-icon.png +0 -0
- package/templates/app/public/favicon.ico +0 -0
- package/templates/app/public/jelly/cloud.webp +0 -0
- package/templates/app/public/jelly/comet.webp +0 -0
- package/templates/app/public/jelly/moon.webp +0 -0
- package/templates/app/public/jelly/planet.webp +0 -0
- package/templates/app/public/jelly/rocket.webp +0 -0
- package/templates/app/public/jelly/star.webp +0 -0
- package/templates/app/public/jelly/sugar.webp +0 -0
- package/templates/app/public/logo.png +0 -0
- package/templates/app/ui/Recipe/index.ts +9 -0
- package/templates/app/ui/Recipe/jellyButton.ts +63 -0
- package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
- package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
- package/templates/appSample/lib/task/Task.Unit.tsx +1 -1
- package/templates/appSample/lib/task/Task.Util.tsx +10 -13
- package/templates/appSample/lib/task/Task.View.tsx +2 -2
- package/templates/appSample/lib/task/Task.Zone.tsx +5 -2
- package/templates/appSample/lib/task/task.abstract.ts +12 -32
- package/templates/appSample/lib/task/task.signal.spec.ts +1 -15
- package/templates/appSample/lib/task/task.signal.test.ts +15 -1
- package/templates/appSample/lib/task/task.signal.ts +10 -8
- package/templates/appSample/page/task/[taskId]/_index.tsx +6 -6
- package/templates/appSample/page/task/[taskId]/edit.tsx +5 -4
- package/templates/appSample/page/task/_index.tsx +4 -3
- package/templates/appSample/page/task/_layout.tsx +1 -1
- package/templates/appSample/page/task/new.tsx +5 -4
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
- package/templates/appSample/ui/GlobalLoading.tsx +2 -1
- package/templates/appSample/ui/QuantityControl.tsx +3 -3
- package/templates/client.ts +7 -30
- package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
- package/templates/crudPages/[__model__Id]/page.tsx +2 -1
- package/templates/crudPages/new/page.tsx +2 -1
- package/templates/crudPages/page.tsx +2 -1
- package/templates/crudSinglePage/page.tsx +2 -1
- package/templates/lib/__lib/lib.dictionary.ts +0 -2
- package/templates/lib/__lib/lib.document.ts +0 -2
- package/templates/lib/sig.ts +8 -30
- package/templates/localDev/docker-compose.yaml.template +3 -14
- package/templates/module/__model__.signal.ts +12 -4
- package/templates/pkgRoot/tsconfig.json.template +2 -7
- package/templates/server.ts +1 -3
- package/templates/service/__model__.abstract.md.template +8 -0
- package/templates/workspaceRoot/.gitignore.template +0 -1
- package/templates/workspaceRoot/AGENTS.md.template +6 -0
- package/templates/workspaceRoot/package.json.template +1 -3
- package/tunnel.command-xwr46b66.js +129 -0
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-t7wqe4h7.js +79 -0
- package/{workspace.command-06wvstgr.js → workspace.command-4derhzrh.js} +79 -109
- package/abstractCompactor-gmkc0z8j.js +0 -102
- package/application.command-18y0s485.js +0 -204
- package/applicationReleasePackager-4yasxwv9.js +0 -244
- package/capacitorApp-36rbr858.js +0 -12
- package/cloud.command-av97ndh6.js +0 -94
- package/cloud.script-cm11xjdz.js +0 -20
- package/context.command-5v37ef3n.js +0 -81
- package/devTuiView-0hc2emhe.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/guideline.command-4pz9g1rt.js +0 -360
- package/guidelines/agentRule/agentRule.generate.json +0 -31
- package/guidelines/componentRule/componentRule.generate.json +0 -31
- package/guidelines/conventions/conventions.generate.json +0 -25
- package/guidelines/cssRule/cssRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
- package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
- package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
- package/guidelines/enumConstant/enumConstant.generate.json +0 -31
- package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
- package/guidelines/fieldRule/fieldRule.generate.json +0 -31
- package/guidelines/framework/framework.generate.json +0 -32
- package/guidelines/mcpRule/mcpRule.generate.json +0 -35
- package/guidelines/modelConstant/modelConstant.generate.json +0 -32
- package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
- package/guidelines/modelDocument/modelDocument.generate.json +0 -31
- package/guidelines/modelService/modelService.generate.json +0 -31
- package/guidelines/modelSignal/modelSignal.generate.json +0 -31
- package/guidelines/modelStore/modelStore.generate.json +0 -31
- package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
- package/guidelines/modelUnit/modelUnit.generate.json +0 -31
- package/guidelines/modelUtil/modelUtil.generate.json +0 -31
- package/guidelines/modelView/modelView.generate.json +0 -31
- package/guidelines/modelZone/modelZone.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
- package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
- package/guidelines/queryRule/queryRule.generate.json +0 -31
- package/guidelines/recipeRule/recipeRule.generate.json +0 -31
- package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
- package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
- package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
- package/guidelines/scalarModule/scalarModule.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
- package/guidelines/ssrRule/ssrRule.generate.json +0 -31
- package/guidelines/transportRule/transportRule.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
- package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
- package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
- package/index-47pj3aee.js +0 -76
- package/index-5ystnsd5.js +0 -841
- package/index-6wwzs1bc.js +0 -7
- package/index-a17x49vg.js +0 -229
- package/index-m0xccmmm.js +0 -228
- package/index-meh558jy.js +0 -65
- package/index-rtxxan88.js +0 -471
- package/index-te54x9zm.js +0 -338
- package/index-w8kmx1b6.js +0 -2176
- package/index-wt7qrtd4.js +0 -1516
- package/templates/__scalar/__model__/__model__.abstract.md +0 -28
- package/templates/module/__model__.abstract.md +0 -28
- package/templates/service/__model__.abstract.md +0 -28
- package/templates/workspaceRoot/patches/react-dom@19.2.7.patch.template +0 -62
- package/workflow.command-gtdnzvbz.js +0 -108
|
@@ -1,17 +1,319 @@
|
|
|
1
1
|
@import "tailwindcss";
|
|
2
2
|
@import "akanjs/ui/styles.css";
|
|
3
3
|
|
|
4
|
-
/* The
|
|
5
|
-
data-theme switching)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
/* The jelly star palette. akanjs/ui/styles.css owns the theme system (token mapping, dark variant, runtime
|
|
5
|
+
data-theme switching), so a rebrand only overrides the token values below. The star red (--jelly) is a fill
|
|
6
|
+
color; --primary carries white text, so it is one step darker to keep 4.5:1 contrast. */
|
|
7
|
+
:root,
|
|
8
|
+
[data-theme="light"] {
|
|
9
|
+
--background: #f1f1ee;
|
|
10
|
+
--foreground: #0d0d0e;
|
|
11
|
+
--primary: #e02d27;
|
|
12
|
+
--primary-foreground: #ffffff;
|
|
13
|
+
--secondary: #0d0d0e;
|
|
14
|
+
--secondary-foreground: #f6f6f3;
|
|
15
|
+
--accent: #7650d8;
|
|
16
|
+
--accent-foreground: #ffffff;
|
|
17
|
+
--neutral: #26262a;
|
|
18
|
+
--neutral-foreground: #f6f6f3;
|
|
19
|
+
--info: #1f6fe0;
|
|
20
|
+
--info-foreground: #ffffff;
|
|
21
|
+
--success: #3f8f1f;
|
|
22
|
+
--success-foreground: #ffffff;
|
|
23
|
+
--warning: #f2b51c;
|
|
24
|
+
--warning-foreground: #0d0d0e;
|
|
25
|
+
--destructive: #c4161c;
|
|
26
|
+
--destructive-foreground: #ffffff;
|
|
27
|
+
--open: #5aa82a;
|
|
28
|
+
--open-foreground: #0d0d0e;
|
|
29
|
+
--muted: #e6e6e1;
|
|
30
|
+
--muted-foreground: #66666b;
|
|
31
|
+
--card: #fbfbf9;
|
|
32
|
+
--card-foreground: #0d0d0e;
|
|
33
|
+
--popover: #ffffff;
|
|
34
|
+
--popover-foreground: #0d0d0e;
|
|
35
|
+
--border: #dcdcd6;
|
|
36
|
+
--input: #d4d4ce;
|
|
37
|
+
--ring: #e02d27;
|
|
38
|
+
--jelly: #ef3a2d;
|
|
39
|
+
--studio-shadow: color-mix(in oklab, #3a2a20 16%, transparent);
|
|
40
|
+
--sky-top: #dfe5f7;
|
|
41
|
+
--sky-bottom: #f6eadf;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[data-theme="dark"] {
|
|
45
|
+
--background: #0f1129;
|
|
46
|
+
--foreground: #f3f1fb;
|
|
47
|
+
--primary: #e02d27;
|
|
48
|
+
--primary-foreground: #ffffff;
|
|
49
|
+
--secondary: #f3f1fb;
|
|
50
|
+
--secondary-foreground: #0f1129;
|
|
51
|
+
--accent: #a585e0;
|
|
52
|
+
--accent-foreground: #0f1129;
|
|
53
|
+
--neutral: #262a4d;
|
|
54
|
+
--neutral-foreground: #f3f1fb;
|
|
55
|
+
--info: #4b8ef0;
|
|
56
|
+
--info-foreground: #0f1129;
|
|
57
|
+
--success: #7cc23a;
|
|
58
|
+
--success-foreground: #0f1129;
|
|
59
|
+
--warning: #f6c437;
|
|
60
|
+
--warning-foreground: #0f1129;
|
|
61
|
+
--destructive: #e5383b;
|
|
62
|
+
--destructive-foreground: #ffffff;
|
|
63
|
+
--open: #7cc23a;
|
|
64
|
+
--open-foreground: #0f1129;
|
|
65
|
+
--muted: #1a1d3b;
|
|
66
|
+
--muted-foreground: #a6a8c9;
|
|
67
|
+
--card: #161935;
|
|
68
|
+
--card-foreground: #f3f1fb;
|
|
69
|
+
--popover: #1b1e40;
|
|
70
|
+
--popover-foreground: #f3f1fb;
|
|
71
|
+
--border: #2b2f57;
|
|
72
|
+
--input: #33376a;
|
|
73
|
+
--ring: #f0392e;
|
|
74
|
+
--jelly: #f2402f;
|
|
75
|
+
--studio-shadow: color-mix(in oklab, #02030f 65%, transparent);
|
|
76
|
+
--sky-top: #25215f;
|
|
77
|
+
--sky-bottom: #2d1749;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:root {
|
|
81
|
+
--planet: #1f6fe0;
|
|
82
|
+
--rocket: #82c43c;
|
|
83
|
+
--moon: #f6e27a;
|
|
84
|
+
--cloud: #a585e0;
|
|
85
|
+
--comet: #e3228e;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@theme inline {
|
|
89
|
+
--color-jelly: var(--jelly);
|
|
90
|
+
--color-planet: var(--planet);
|
|
91
|
+
--color-rocket: var(--rocket);
|
|
92
|
+
--color-moon: var(--moon);
|
|
93
|
+
--color-cloud: var(--cloud);
|
|
94
|
+
--color-comet: var(--comet);
|
|
95
|
+
--radius-box: 1.5rem;
|
|
96
|
+
--radius-field: 0.875rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* A sampled damped spring: overshoots the target by 18%, wobbles twice and settles. */
|
|
100
|
+
@theme {
|
|
101
|
+
--ease-jelly: linear(0, 0.42 6%, 0.86 13%, 1.12 21%, 1.18 26%, 1.13 32%, 1 41%, 0.95 48%, 0.97 56%, 1.01 66%, 1.005 78%, 1);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* html and body both paint a background color, so body's background is not propagated to the canvas: the sky
|
|
105
|
+
sits on body, and isolation keeps the grain layer above body's own background. */
|
|
106
|
+
@layer base {
|
|
107
|
+
body {
|
|
108
|
+
isolation: isolate;
|
|
109
|
+
background-image:
|
|
110
|
+
radial-gradient(120% 60% at 50% -14%, var(--sky-top), transparent 64%),
|
|
111
|
+
radial-gradient(110% 55% at 50% 114%, var(--sky-bottom), transparent 68%);
|
|
112
|
+
background-attachment: fixed;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
body::before {
|
|
116
|
+
content: "";
|
|
117
|
+
position: fixed;
|
|
118
|
+
inset: 0;
|
|
119
|
+
z-index: -1;
|
|
120
|
+
pointer-events: none;
|
|
121
|
+
opacity: 0.06;
|
|
122
|
+
mix-blend-mode: multiply;
|
|
123
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
[data-theme="dark"] body::before {
|
|
127
|
+
opacity: 0.1;
|
|
128
|
+
mix-blend-mode: overlay;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
h1,
|
|
132
|
+
h2 {
|
|
133
|
+
letter-spacing: -0.035em;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
::selection {
|
|
137
|
+
background-color: color-mix(in oklab, var(--jelly) 24%, transparent);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@keyframes jelly-intro {
|
|
142
|
+
from {
|
|
143
|
+
opacity: 0;
|
|
144
|
+
translate: 0 1.25rem;
|
|
145
|
+
filter: blur(6px);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@keyframes jelly-breathe {
|
|
150
|
+
0%,
|
|
151
|
+
100% {
|
|
152
|
+
scale: 1 1;
|
|
153
|
+
}
|
|
154
|
+
50% {
|
|
155
|
+
scale: 1.035 0.965;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@keyframes jelly-wobble {
|
|
160
|
+
0% {
|
|
161
|
+
scale: 1 1;
|
|
162
|
+
}
|
|
163
|
+
16% {
|
|
164
|
+
scale: 1.16 0.86;
|
|
165
|
+
}
|
|
166
|
+
32% {
|
|
167
|
+
scale: 0.9 1.1;
|
|
168
|
+
}
|
|
169
|
+
48% {
|
|
170
|
+
scale: 1.06 0.95;
|
|
171
|
+
}
|
|
172
|
+
64% {
|
|
173
|
+
scale: 0.97 1.03;
|
|
174
|
+
}
|
|
175
|
+
82% {
|
|
176
|
+
scale: 1.01 0.99;
|
|
177
|
+
}
|
|
178
|
+
100% {
|
|
179
|
+
scale: 1 1;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@keyframes jelly-float {
|
|
184
|
+
0%,
|
|
185
|
+
100% {
|
|
186
|
+
translate: 0 0;
|
|
187
|
+
rotate: calc(var(--float-tilt, 4deg) * -1);
|
|
188
|
+
}
|
|
189
|
+
50% {
|
|
190
|
+
translate: 0 calc(var(--float-rise, 0.9rem) * -1);
|
|
191
|
+
rotate: var(--float-tilt, 4deg);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@utility intro-rise {
|
|
196
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
197
|
+
animation: jelly-intro 1.1s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
198
|
+
animation-delay: var(--intro-delay, 0ms);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@utility jelly-breathe {
|
|
203
|
+
transform-origin: 50% 100%;
|
|
204
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
205
|
+
animation: jelly-breathe 3.2s ease-in-out infinite;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@utility jelly-wobble {
|
|
210
|
+
transform-origin: 50% 100%;
|
|
211
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
212
|
+
animation: jelly-wobble 0.9s ease-out both;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@utility jelly-float {
|
|
217
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
218
|
+
animation: jelly-float var(--float-duration, 6s) ease-in-out var(--float-delay, 0s) infinite;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@utility squish {
|
|
223
|
+
transition:
|
|
224
|
+
scale 700ms var(--ease-jelly),
|
|
225
|
+
translate 700ms var(--ease-jelly);
|
|
226
|
+
&:hover {
|
|
227
|
+
scale: 1.04 0.97;
|
|
228
|
+
}
|
|
229
|
+
&:active {
|
|
230
|
+
scale: 1.08 0.9;
|
|
231
|
+
transition-duration: 90ms;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@utility tint-* {
|
|
236
|
+
--tint: --value(--color-*);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* A gummy surface. public/jelly/sugar.webp is a high-pass of the logo star's sugar coating (128 gray = no change),
|
|
240
|
+
laid on in hard-light so every tint gets the same sugar grain. */
|
|
241
|
+
@utility jelly {
|
|
242
|
+
--jelly-tint: var(--tint, var(--primary));
|
|
243
|
+
--jelly-deep: color-mix(in oklab, var(--jelly-tint) 70%, black);
|
|
244
|
+
--jelly-haze: color-mix(in oklab, var(--jelly-tint) 55%, white);
|
|
245
|
+
background-color: var(--jelly-tint);
|
|
246
|
+
background-image:
|
|
247
|
+
url("/jelly/sugar.webp"),
|
|
248
|
+
radial-gradient(120% 95% at 26% -8%, color-mix(in oklab, white 26%, transparent), transparent 58%),
|
|
249
|
+
radial-gradient(110% 90% at 60% 125%, color-mix(in oklab, var(--jelly-deep) 30%, transparent), transparent 60%);
|
|
250
|
+
background-size:
|
|
251
|
+
100px 100px,
|
|
252
|
+
100% 100%,
|
|
253
|
+
100% 100%;
|
|
254
|
+
background-repeat: repeat, no-repeat, no-repeat;
|
|
255
|
+
background-blend-mode: hard-light, normal, normal;
|
|
256
|
+
box-shadow:
|
|
257
|
+
inset 0 0 0 1px color-mix(in oklab, var(--jelly-haze) 40%, transparent),
|
|
258
|
+
inset 0 0 8px 1px color-mix(in oklab, white 20%, transparent),
|
|
259
|
+
inset 0 -3px 6px color-mix(in oklab, var(--jelly-deep) 28%, transparent),
|
|
260
|
+
0 6px 10px -6px color-mix(in oklab, var(--jelly-deep) 65%, transparent),
|
|
261
|
+
0 1px 2px color-mix(in oklab, black 12%, transparent);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@utility jelly-glass {
|
|
265
|
+
--jelly-tint: var(--tint, var(--card));
|
|
266
|
+
background-color: color-mix(in oklab, var(--card) 95%, var(--jelly-tint));
|
|
267
|
+
background-image:
|
|
268
|
+
radial-gradient(120% 70% at 20% -20%, color-mix(in oklab, white 55%, transparent), transparent 60%),
|
|
269
|
+
radial-gradient(90% 60% at 100% 120%, color-mix(in oklab, var(--jelly-tint) 9%, transparent), transparent 70%);
|
|
270
|
+
box-shadow:
|
|
271
|
+
inset 0 1px 0 color-mix(in oklab, white 70%, transparent),
|
|
272
|
+
inset 0 -1px 0 color-mix(in oklab, var(--jelly-tint) 14%, transparent),
|
|
273
|
+
0 22px 44px -28px var(--studio-shadow),
|
|
274
|
+
0 2px 6px -3px var(--studio-shadow);
|
|
275
|
+
@variant dark {
|
|
276
|
+
background-color: color-mix(in oklab, var(--card) 92%, var(--jelly-tint));
|
|
277
|
+
background-image:
|
|
278
|
+
radial-gradient(120% 70% at 20% -20%, color-mix(in oklab, white 7%, transparent), transparent 60%),
|
|
279
|
+
radial-gradient(90% 60% at 100% 120%, color-mix(in oklab, var(--jelly-tint) 14%, transparent), transparent 70%);
|
|
280
|
+
box-shadow:
|
|
281
|
+
inset 0 1px 0 color-mix(in oklab, white 11%, transparent),
|
|
282
|
+
inset 0 -1px 0 color-mix(in oklab, var(--jelly-tint) 18%, transparent),
|
|
283
|
+
0 22px 44px -28px var(--studio-shadow),
|
|
284
|
+
0 2px 6px -3px var(--studio-shadow);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* The same sugar, clipped to the glyphs of plain text-primary text. Clipping replaces the element's background, so
|
|
289
|
+
elements with a surface of their own (bg-*, jelly, glass) and currentColor drawings are skipped, and icons inside
|
|
290
|
+
get their color back. */
|
|
291
|
+
.text-primary:not(svg, [class*="bg-"], [class*="jelly"], [class*="glass"], [class*="-current"]) {
|
|
292
|
+
background-color: var(--primary);
|
|
293
|
+
background-image:
|
|
294
|
+
url("/jelly/sugar.webp"),
|
|
295
|
+
linear-gradient(
|
|
296
|
+
to bottom,
|
|
297
|
+
color-mix(in oklab, black 8%, var(--primary)),
|
|
298
|
+
color-mix(in oklab, white 14%, var(--primary)) 22%,
|
|
299
|
+
var(--primary) 60%,
|
|
300
|
+
color-mix(in oklab, black 8%, var(--primary))
|
|
301
|
+
);
|
|
302
|
+
background-size:
|
|
303
|
+
100px 100px,
|
|
304
|
+
100% 1lh;
|
|
305
|
+
background-origin: content-box;
|
|
306
|
+
background-blend-mode: hard-light, normal;
|
|
307
|
+
-webkit-background-clip: text;
|
|
308
|
+
background-clip: text;
|
|
309
|
+
color: transparent;
|
|
310
|
+
text-decoration-color: var(--primary);
|
|
311
|
+
& :is(svg, [class*="-current"]) {
|
|
312
|
+
color: var(--primary);
|
|
313
|
+
}
|
|
314
|
+
/* A heading's tight leading pushes descenders out of the box, where a text-clipped background is never painted. */
|
|
315
|
+
:is(h1, h2, h3, h4, h5, h6) & {
|
|
316
|
+
padding-block: 0.15em;
|
|
317
|
+
margin-block: -0.15em;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AppInfo, LibInfo } from "akanjs";
|
|
2
|
+
|
|
3
|
+
export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { appName: string }) {
|
|
4
|
+
return {
|
|
5
|
+
filename: "index.ts",
|
|
6
|
+
content: `export { type JellyButtonVariants, jellyButtonRecipe } from "./jellyButton";
|
|
7
|
+
`,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AppInfo, LibInfo } from "akanjs";
|
|
2
|
+
|
|
3
|
+
export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { appName: string }) {
|
|
4
|
+
return {
|
|
5
|
+
filename: "jellyButton.ts",
|
|
6
|
+
content: `import { recipe, tv } from "akanjs/ui";
|
|
7
|
+
|
|
8
|
+
/** Sugared gummy button with the same variants as akanjs's \`buttonRecipe\`; \`page/_overrides.tsx\` binds it to every akanjs/ui Button. ghost/outline/link stay surfaceless. */
|
|
9
|
+
export const jellyButtonRecipe = recipe(
|
|
10
|
+
tv({
|
|
11
|
+
base: "squish inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-full font-bold focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
12
|
+
variants: {
|
|
13
|
+
variant: {
|
|
14
|
+
default: "text-foreground",
|
|
15
|
+
primary: "tint-primary text-primary-foreground",
|
|
16
|
+
secondary: "tint-secondary text-secondary-foreground",
|
|
17
|
+
accent: "tint-accent text-accent-foreground",
|
|
18
|
+
neutral: "tint-neutral text-neutral-foreground",
|
|
19
|
+
outline: "border border-foreground/12 bg-background/70 text-foreground hover:bg-foreground/5",
|
|
20
|
+
ghost: "text-foreground/75 hover:bg-foreground/6 hover:text-foreground",
|
|
21
|
+
destructive: "tint-destructive text-destructive-foreground",
|
|
22
|
+
success: "tint-success text-success-foreground",
|
|
23
|
+
warning: "tint-warning text-warning-foreground",
|
|
24
|
+
info: "tint-info text-info-foreground",
|
|
25
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
26
|
+
},
|
|
27
|
+
size: {
|
|
28
|
+
xs: "h-6 px-2.5 text-xs",
|
|
29
|
+
sm: "h-8 px-3.5 text-sm",
|
|
30
|
+
md: "h-10 px-5 text-sm",
|
|
31
|
+
lg: "h-12 px-7 text-base",
|
|
32
|
+
icon: "h-10 w-10 px-0",
|
|
33
|
+
},
|
|
34
|
+
shape: {
|
|
35
|
+
default: "",
|
|
36
|
+
square: "aspect-square px-0",
|
|
37
|
+
circle: "aspect-square px-0",
|
|
38
|
+
},
|
|
39
|
+
outline: { true: "border bg-transparent", false: "" },
|
|
40
|
+
},
|
|
41
|
+
compoundVariants: [
|
|
42
|
+
{ variant: "default", outline: false, class: "jelly-glass" },
|
|
43
|
+
{
|
|
44
|
+
variant: ["primary", "secondary", "accent", "neutral", "destructive", "success", "warning", "info"],
|
|
45
|
+
outline: false,
|
|
46
|
+
class: "jelly",
|
|
47
|
+
},
|
|
48
|
+
{ variant: "primary", outline: true, class: "border-primary text-primary hover:bg-primary/8" },
|
|
49
|
+
{ variant: "secondary", outline: true, class: "border-secondary text-secondary hover:bg-secondary/8" },
|
|
50
|
+
{ variant: "accent", outline: true, class: "border-accent text-accent hover:bg-accent/8" },
|
|
51
|
+
{ variant: "neutral", outline: true, class: "border-neutral text-neutral hover:bg-neutral/8" },
|
|
52
|
+
{ variant: "destructive", outline: true, class: "border-destructive text-destructive hover:bg-destructive/8" },
|
|
53
|
+
{ variant: "success", outline: true, class: "border-success text-success hover:bg-success/8" },
|
|
54
|
+
{ variant: "warning", outline: true, class: "border-warning text-warning hover:bg-warning/8" },
|
|
55
|
+
{ variant: "info", outline: true, class: "border-info text-info hover:bg-info/8" },
|
|
56
|
+
],
|
|
57
|
+
defaultVariants: { variant: "primary", size: "md", shape: "default" },
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
export type JellyButtonVariants = NonNullable<Parameters<typeof jellyButtonRecipe>[0]>;
|
|
61
|
+
`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -3,45 +3,14 @@ import type { AppInfo, LibInfo } from "akanjs";
|
|
|
3
3
|
export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { appName: string }) {
|
|
4
4
|
return {
|
|
5
5
|
filename: "workHistory.abstract.md",
|
|
6
|
-
content: `#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Standard scalar layers:
|
|
15
|
-
- workHistory.constant.ts — enum (WorkHistoryAction) + entry class (WorkHistory) defined via via() + enumOf()
|
|
16
|
-
- workHistory.dictionary.ts — i18n via scalarDictionary() (fewer layers than modelDictionary)
|
|
17
|
-
- workHistory.abstract.md — embedding rules and intent
|
|
18
|
-
|
|
19
|
-
## Convention: lib/__scalar/<type>/ directory naming
|
|
20
|
-
|
|
21
|
-
- Scalar modules use double-underscore prefix: lib/__scalar/workHistory/
|
|
22
|
-
- Files drop the underscores: workHistory.constant.ts, not __workHistory.constant.ts
|
|
23
|
-
- Models embed scalars via field([WorkHistory]) — list-of-scalar embedding
|
|
24
|
-
|
|
25
|
-
## Embedding Example (in task.constant.ts)
|
|
26
|
-
|
|
27
|
-
TaskObject embeds a list of WorkHistory:
|
|
28
|
-
import { WorkHistory } from "../../__scalar/workHistory/workHistory.constant";
|
|
29
|
-
export class TaskObject extends via(TaskInput, (field) => ({
|
|
30
|
-
workHistory: field([WorkHistory]),
|
|
31
|
-
}))
|
|
32
|
-
|
|
33
|
-
Each status change (create, start, complete) pushes a new entry.
|
|
34
|
-
|
|
35
|
-
## Agent Notes
|
|
36
|
-
|
|
37
|
-
- Read this abstract before modifying the WorkHistory scalar.
|
|
38
|
-
- Update when new action types or fields are added.
|
|
39
|
-
- Do not duplicate workHistory fields in individual models; always reuse this scalar.
|
|
40
|
-
|
|
41
|
-
## Related Modules
|
|
42
|
-
|
|
43
|
-
- lib/task/ — database module embedding workHistory as a list field
|
|
44
|
-
- lib/_noti/ — pure service module (different module type, no scalar usage)
|
|
6
|
+
content: `# workHistory Abstract
|
|
7
|
+
One step in a task's history: which move happened, when, and an optional note.
|
|
8
|
+
|
|
9
|
+
## Rules
|
|
10
|
+
- Entries are only appended — by \`Task\`'s chain methods and by the task service on create — and never edited or
|
|
11
|
+
removed, so the list reads as the task's moves in order.
|
|
12
|
+
- \`at\` is the moment the entry was built when the writer gives none.
|
|
13
|
+
- \`note\` is empty on every entry the app writes itself.
|
|
45
14
|
`,
|
|
46
15
|
};
|
|
47
16
|
}
|
|
@@ -3,36 +3,13 @@ import type { AppInfo, LibInfo } from "akanjs";
|
|
|
3
3
|
export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { appName: string }) {
|
|
4
4
|
return {
|
|
5
5
|
filename: "noti.abstract.md",
|
|
6
|
-
content: `#
|
|
6
|
+
content: `# noti Service Abstract
|
|
7
|
+
Noti holds the in-app notification list on the client: the messages the app shows, an unread count, and dismissal.
|
|
7
8
|
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Both module types follow the same layer pattern, but service modules have fewer layers:
|
|
14
|
-
no constant.ts (no data shape), no document.ts (no DB queries), no UI components.
|
|
15
|
-
|
|
16
|
-
- noti.service.ts — business logic via serve("noti" as const, ...) (named service, no DB binding)
|
|
17
|
-
- noti.signal.ts — real-time pubsub endpoint bound via endpoint(srv.noti, ...)
|
|
18
|
-
- noti.store.ts — client state via store("noti" as const, ...) (named store, no signal binding)
|
|
19
|
-
- noti.dictionary.ts — i18n via serviceDictionary() (no model field labels)
|
|
20
|
-
|
|
21
|
-
## Convention: lib/_<service>/ directory naming
|
|
22
|
-
|
|
23
|
-
- Service modules live under lib/_<service>/ — the underscore prefix signals "this is a service, not a database model."
|
|
24
|
-
- Files drop the underscore: lib/_noti/noti.service.ts, not lib/_noti/_noti.service.ts.
|
|
25
|
-
- Scan registers into the same barrel files: srv.ts, sig.ts, st.ts, dict.ts.
|
|
26
|
-
|
|
27
|
-
## Convention: named serve/store (no DB binding)
|
|
28
|
-
|
|
29
|
-
- serve("noti" as const, ...) — service name passed as string, no db.<module> binding.
|
|
30
|
-
- store("noti" as const, ...) — store name passed as string, no sig.<module> binding.
|
|
31
|
-
|
|
32
|
-
## Related Modules
|
|
33
|
-
|
|
34
|
-
- lib/task/ — database module reference (compare structure differences)
|
|
35
|
-
- lib/__scalar/workHistory/ — reusable scalar field modules (double-underscore prefix, embedded in models)
|
|
9
|
+
## Rules
|
|
10
|
+
- Notifications live only in the client store; the server side declares nothing yet, so a reload starts empty.
|
|
11
|
+
- \`unreadCount\` counts additions since the last \`markAllRead()\`, not the list's length — removing a notification
|
|
12
|
+
does not lower it.
|
|
36
13
|
`,
|
|
37
14
|
};
|
|
38
15
|
}
|
|
@@ -30,7 +30,7 @@ export const Card = ({ task, className, href }: CardProps) => {
|
|
|
30
30
|
return (
|
|
31
31
|
<Layout.Unit
|
|
32
32
|
className={cn(
|
|
33
|
-
"
|
|
33
|
+
"jelly-glass block rounded-box p-5 transition-transform duration-300 ease-jelly hover:-translate-y-0.5",
|
|
34
34
|
className,
|
|
35
35
|
)}
|
|
36
36
|
href={href}
|
|
@@ -5,7 +5,8 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
|
|
|
5
5
|
filename: "Task.Util.tsx",
|
|
6
6
|
content: `"use client";
|
|
7
7
|
import { fetch, st, usePage } from "@apps/${dict.appName}/client";
|
|
8
|
-
import {
|
|
8
|
+
import { jellyButtonRecipe } from "@apps/${dict.appName}/ui";
|
|
9
|
+
import { Dropdown, Model } from "akanjs/ui";
|
|
9
10
|
|
|
10
11
|
// ===== Task.Util.tsx =====
|
|
11
12
|
// Convention: lib/<module>/ — PascalCase .tsx, Util suffix = action buttons/utility components.
|
|
@@ -19,10 +20,7 @@ interface StartProps {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export const Start = ({ taskId }: StartProps) => (
|
|
22
|
-
<button
|
|
23
|
-
className={buttonRecipe({ size: "xs" }, "border-primary/20 bg-primary/10 text-primary hover:bg-primary hover:text-primary-foreground")}
|
|
24
|
-
onClick={() => st.do.startTask(taskId)}
|
|
25
|
-
>
|
|
23
|
+
<button className={jellyButtonRecipe({ variant: "primary", size: "xs" })} onClick={() => st.do.startTask(taskId)}>
|
|
26
24
|
{usePage().l("task.taskStart")}
|
|
27
25
|
</button>
|
|
28
26
|
);
|
|
@@ -32,10 +30,7 @@ interface CompleteProps {
|
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
export const Complete = ({ taskId }: CompleteProps) => (
|
|
35
|
-
<button
|
|
36
|
-
className={buttonRecipe({ size: "xs" }, "border-success/20 bg-success/10 text-success hover:bg-success hover:text-success-foreground")}
|
|
37
|
-
onClick={() => st.do.completeTask(taskId)}
|
|
38
|
-
>
|
|
33
|
+
<button className={jellyButtonRecipe({ variant: "success", size: "xs" })} onClick={() => st.do.completeTask(taskId)}>
|
|
39
34
|
{usePage().l("task.taskComplete")}
|
|
40
35
|
</button>
|
|
41
36
|
);
|
|
@@ -46,7 +41,9 @@ interface RemoveProps {
|
|
|
46
41
|
|
|
47
42
|
export const Remove = ({ taskId }: RemoveProps) => (
|
|
48
43
|
<Model.Remove modelId={taskId} slice={fetch.slice.task}>
|
|
49
|
-
<button className={
|
|
44
|
+
<button className={jellyButtonRecipe({ variant: "ghost", size: "xs" }, "text-destructive")}>
|
|
45
|
+
{usePage().l("task.taskRemove")}
|
|
46
|
+
</button>
|
|
50
47
|
</Model.Remove>
|
|
51
48
|
);
|
|
52
49
|
|
|
@@ -59,9 +56,9 @@ export const Toolbox = ({ taskId, status }: ToolboxProps) => {
|
|
|
59
56
|
const { l } = usePage();
|
|
60
57
|
return (
|
|
61
58
|
<Dropdown
|
|
62
|
-
buttonClassName={
|
|
59
|
+
buttonClassName={jellyButtonRecipe({ variant: "ghost", size: "xs" })}
|
|
63
60
|
value={<span>···</span>}
|
|
64
|
-
dropdownClassName="w-40 rounded-box
|
|
61
|
+
dropdownClassName="jelly-glass w-40 rounded-box p-2"
|
|
65
62
|
content={
|
|
66
63
|
<>
|
|
67
64
|
{status === "todo" && (
|
|
@@ -96,7 +93,7 @@ export const Toolbox = ({ taskId, status }: ToolboxProps) => {
|
|
|
96
93
|
// New Task Button: Model.NewWrapper — triggers new Task creation form
|
|
97
94
|
// export const NewTask = () => (
|
|
98
95
|
// <Model.NewWrapper partial={{}}>
|
|
99
|
-
// <button className={
|
|
96
|
+
// <button className={jellyButtonRecipe({ variant: "primary", size: "sm" })}>+ New Task</button>
|
|
100
97
|
// </Model.NewWrapper>
|
|
101
98
|
// );
|
|
102
99
|
`,
|
|
@@ -29,12 +29,12 @@ export const General = ({ className, task }: GeneralProps) => {
|
|
|
29
29
|
return (
|
|
30
30
|
<div className={cn("flex w-full flex-col gap-4", className)}>
|
|
31
31
|
<div>
|
|
32
|
-
<h1 className="font-
|
|
32
|
+
<h1 className="font-black text-4xl text-foreground">{task.title}</h1>
|
|
33
33
|
<div className={cn("mt-1 font-medium text-sm", statusColor)}>{l(\`taskStatus.\${task.status}\`)}</div>
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
36
|
{task.content && (
|
|
37
|
-
<div className="
|
|
37
|
+
<div className="jelly-glass rounded-box p-5">
|
|
38
38
|
<p className="whitespace-pre-wrap text-foreground/80 text-sm">{task.content}</p>
|
|
39
39
|
</div>
|
|
40
40
|
)}
|
|
@@ -5,8 +5,9 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
|
|
|
5
5
|
filename: "Task.Zone.tsx",
|
|
6
6
|
content: `"use client";
|
|
7
7
|
import { type cnst, Task, usePage } from "@apps/${dict.appName}/client";
|
|
8
|
+
import { jellyButtonRecipe } from "@apps/${dict.appName}/ui";
|
|
8
9
|
import type { ClientInit, ClientView } from "akanjs/fetch";
|
|
9
|
-
import { Link, Load
|
|
10
|
+
import { Link, Load } from "akanjs/ui";
|
|
10
11
|
|
|
11
12
|
// ===== Task.Zone.tsx =====
|
|
12
13
|
// Convention: lib/<module>/ — PascalCase .tsx, Zone suffix = composition layer between pages and UI.
|
|
@@ -30,7 +31,9 @@ export const Card = ({ className, init }: CardProps) => {
|
|
|
30
31
|
<div className="flex flex-col items-center gap-4 py-16 text-center">
|
|
31
32
|
<div className="text-foreground/40 text-lg">{l("task.taskNoTasks")}</div>
|
|
32
33
|
<Link href="/task/new">
|
|
33
|
-
<button className={
|
|
34
|
+
<button className={jellyButtonRecipe({ variant: "primary", size: "sm" })}>
|
|
35
|
+
{l("task.taskCreateFirst")}
|
|
36
|
+
</button>
|
|
34
37
|
</Link>
|
|
35
38
|
</div>
|
|
36
39
|
)}
|