@korso/shepherd-ui 0.3.1 → 0.5.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.
Files changed (38) hide show
  1. package/LICENSE +661 -0
  2. package/dist/ShepherdRoot.js +13 -12
  3. package/dist/client.d.ts +6 -0
  4. package/dist/client.js +14 -0
  5. package/dist/components/Dashboard.d.ts +7 -1
  6. package/dist/components/Dashboard.js +2 -2
  7. package/dist/config/ConfigPanel.d.ts +14 -0
  8. package/dist/config/ConfigPanel.js +16 -0
  9. package/dist/config/ConnectAgent.d.ts +1 -2
  10. package/dist/config/ConnectAgent.js +6 -12
  11. package/dist/config/GeneralSettings.d.ts +8 -0
  12. package/dist/config/GeneralSettings.js +27 -0
  13. package/dist/config/Invites.d.ts +7 -0
  14. package/dist/config/Invites.js +84 -0
  15. package/dist/config/Members.d.ts +1 -3
  16. package/dist/config/Members.js +4 -23
  17. package/dist/config/WorkspaceSwitcher.d.ts +14 -0
  18. package/dist/config/WorkspaceSwitcher.js +108 -0
  19. package/dist/config/index.d.ts +8 -2
  20. package/dist/config/index.js +6 -3
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +1 -1
  23. package/dist/lib/Dashboard-C48qY8R2.js +1412 -0
  24. package/dist/lib/index.d.ts +63 -22
  25. package/dist/lib/index.js +552 -302
  26. package/dist/lib/selfhost.js +1 -1
  27. package/dist/lib/styles.css +128 -18
  28. package/dist/preview.js +40 -4
  29. package/dist/selfhost/assets/index-CK7qrsNo.css +1 -0
  30. package/dist/selfhost/assets/index-adPvx18g.js +40 -0
  31. package/dist/selfhost/index.html +2 -2
  32. package/dist/test/mockClient.js +3 -0
  33. package/package.json +2 -2
  34. package/dist/config/Workspaces.d.ts +0 -15
  35. package/dist/config/Workspaces.js +0 -116
  36. package/dist/lib/Dashboard-Bgi50wCo.js +0 -1396
  37. package/dist/selfhost/assets/index-D0C3m6st.js +0 -40
  38. package/dist/selfhost/assets/index-rNR1Acph.css +0 -1
@@ -1,6 +1,6 @@
1
1
  import { jsx as e, jsxs as l } from "react/jsx-runtime";
2
2
  import { useState as s, useMemo as h } from "react";
3
- import { c as d, a as m, D as u } from "./Dashboard-Bgi50wCo.js";
3
+ import { c as d, a as m, D as u } from "./Dashboard-C48qY8R2.js";
4
4
  const i = "shepherd.token";
5
5
  function p() {
6
6
  try {
@@ -46,6 +46,56 @@
46
46
  background:transparent; cursor:pointer; font:inherit; }
47
47
  .tab--active { background:var(--ink); color:var(--bg); }
48
48
 
49
+ /* Workspace switcher (app-bar): the active-workspace indicator + the one
50
+ home for switch/create/join. Shown on every tab. */
51
+ .ws-switcher { position:relative; }
52
+ .ws-trig { display:inline-flex; align-items:center; gap:8px; font:inherit; font-size:13px;
53
+ font-weight:600; color:var(--ink); cursor:pointer;
54
+ border:1px solid var(--line); border-radius:9px; padding:5px 10px; background:var(--card); }
55
+ .ws-trig:hover { border-color:var(--ink3); }
56
+ .ws-trig--empty { background:transparent; border-style:dashed; border-color:var(--ink2); }
57
+ .ws-avatar { width:18px; height:18px; border-radius:6px; background:var(--ink); color:var(--bg);
58
+ display:grid; place-items:center; font-size:10px; font-weight:700; flex:none; }
59
+ .ws-avatar--sm { width:16px; height:16px; font-size:9px; }
60
+ .ws-plus { color:var(--ink2); font-weight:700; }
61
+ .ws-name { max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
62
+ .ws-caret { color:var(--ink3); font-size:10px; }
63
+
64
+ .ws-menu { position:absolute; top:40px; left:0; width:240px; z-index:20;
65
+ background:var(--card); border:1px solid var(--line); border-radius:11px; padding:6px;
66
+ box-shadow:0 8px 24px rgba(50,40,20,.16); }
67
+ .ws-menu__head { margin:0; padding:6px 8px; font-size:10px; letter-spacing:.08em;
68
+ text-transform:uppercase; color:var(--ink3); }
69
+ .ws-menu__none { margin:0; padding:2px 8px 6px; color:var(--ink3); font-style:italic; font-size:13px; }
70
+ .ws-menu__list { list-style:none; margin:0; padding:0; }
71
+ .ws-mi { display:flex; align-items:center; gap:8px; width:100%; text-align:left; font:inherit;
72
+ font-size:13px; color:var(--ink); background:transparent; border:0; border-radius:7px;
73
+ padding:7px 8px; cursor:pointer; }
74
+ .ws-mi:hover { background:var(--chip); }
75
+ .ws-mi--on { font-weight:600; }
76
+ .ws-mi__name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
77
+ .ws-mi__check { color:var(--live); }
78
+ .ws-menu__actions { display:flex; flex-direction:column; margin-top:5px; padding-top:5px;
79
+ border-top:1px solid var(--line2); }
80
+ .ws-action { display:flex; align-items:center; gap:8px; width:100%; text-align:left; font:inherit;
81
+ font-size:13px; color:var(--ink2); background:transparent; border:0; border-radius:7px;
82
+ padding:8px; cursor:pointer; }
83
+ .ws-action:hover { background:var(--chip); color:var(--ink); }
84
+
85
+ .ws-form { display:flex; flex-direction:column; gap:8px; padding:4px; }
86
+ .ws-form label { font-size:10px; font-weight:600; letter-spacing:.05em; text-transform:uppercase;
87
+ color:var(--ink3); }
88
+ .ws-form input { padding:8px 10px; border-radius:8px; border:1px solid var(--line);
89
+ background:var(--bg); color:var(--ink); font:inherit; }
90
+ .ws-form input:focus { outline:none; border-color:var(--terr); box-shadow:0 0 0 3px rgba(122,106,72,.14); }
91
+ .ws-form__row { display:flex; gap:8px; justify-content:flex-end; }
92
+ .ws-form__row button { font:inherit; font-size:13px; font-weight:600; border-radius:8px;
93
+ padding:7px 14px; cursor:pointer; border:1px solid var(--ink); background:var(--ink); color:var(--bg); }
94
+ .ws-form__row button:disabled { opacity:.55; cursor:default; }
95
+ .ws-form__back { background:transparent !important; color:var(--ink2) !important;
96
+ border-color:var(--line) !important; }
97
+ .ws-menu__error { margin:6px 4px 2px; font-size:12.5px; color:var(--drop); }
98
+
49
99
  /* Crew strip */
50
100
  .crew { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:26px 0 32px; }
51
101
  .person { display:inline-flex; align-items:center; gap:9px; padding:5px 13px 5px 5px;
@@ -187,11 +237,40 @@
187
237
  .shepherd-config { display:flex; flex-direction:column; }
188
238
  .shepherd-config h2 { font-size:16px; margin:0 0 22px; }
189
239
 
190
- /* Flat sections: no card chrome. Each section sits directly on the page;
191
- consecutive sections are set off by a hairline rather than a box. */
192
- .shepherd-config > section { padding:26px 0; }
193
- .shepherd-config > section:first-of-type { padding-top:0; }
194
- .shepherd-config > section + section { border-top:1px solid var(--line2); }
240
+ /* Config sidebar: a left nav of sections beside the active section's
241
+ panel, replacing the old single long scroll. */
242
+ .config-layout { display:flex; gap:32px; align-items:flex-start; }
243
+ .config-nav { flex:none; width:170px; display:flex; flex-direction:column; gap:2px;
244
+ position:sticky; top:0; }
245
+ /* Scoped under .shepherd-config to out-specify the generic dark-fill
246
+ `.shepherd-config button` rule — these are plain nav links, not buttons. */
247
+ .shepherd-config .config-nav__item { text-align:left; font:inherit; font-size:13.5px;
248
+ color:var(--ink2); background:transparent; border:0; border-radius:8px; padding:8px 12px;
249
+ cursor:pointer; box-shadow:inset 2px 0 0 transparent; transition:color .12s ease, background .12s ease; }
250
+ /* Extra .config-nav in the chain so this out-specifies the generic dark
251
+ `.shepherd-config button:hover` fill — a translucent tint, not a block. */
252
+ .shepherd-config .config-nav .config-nav__item:hover { color:var(--ink);
253
+ background:rgba(50,44,32,.06); }
254
+ .shepherd-config .config-nav__item--on { color:var(--ink); font-weight:600;
255
+ box-shadow:inset 2px 0 0 var(--ink); }
256
+ .shepherd-config .config-nav .config-nav__item--on:hover { background:transparent; }
257
+ .config-panel { flex:1; min-width:0; }
258
+
259
+ /* Two sections can share a panel (Members + Invites); set them off by a
260
+ hairline, mirroring the old flat-section separation. */
261
+ .config-panel > section + section { margin-top:26px; padding-top:26px;
262
+ border-top:1px solid var(--line2); }
263
+
264
+ /* No-workspace Config prompt (create/join now live in the switcher). */
265
+ .config-none { color:var(--ink2); font-size:13.5px; max-width:520px; }
266
+
267
+ /* Read-only workspace facts (name / role) in General. */
268
+ .shepherd-config .readonly-value { margin:0; font-size:14px; color:var(--ink);
269
+ padding:9px 12px; border-radius:8px; border:1px solid var(--line2); background:var(--bg); }
270
+ .shepherd-general .leave { padding-top:4px; }
271
+ .shepherd-config button.danger { border-color:var(--drop); background:transparent; color:var(--drop);
272
+ align-self:flex-start; }
273
+ .shepherd-config button.danger:hover:not(:disabled) { background:var(--drop); color:var(--bg); }
195
274
  .shepherd-config .card-head h3 {
196
275
  font-size:13px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
197
276
  color:var(--ink2); margin:0; }
@@ -215,10 +294,10 @@
215
294
  .shepherd-config .field__row { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
216
295
  .shepherd-config .field__row > input { flex:1; min-width:200px; }
217
296
 
218
- /* Admin zone (invites) is set off from create/join by a hairline. */
219
- .shepherd-workspaces .admin { display:flex; flex-direction:column; gap:14px;
220
- padding-top:16px; border-top:1px solid var(--line2); }
221
- .shepherd-workspaces .invites { display:flex; flex-direction:column; gap:10px; align-items:flex-start; }
297
+ /* Invite-by-code: a compact button with the freshly-created code shown
298
+ above it (the button below mints another). */
299
+ .shepherd-invites .invites { gap:12px; }
300
+ .shepherd-invites .invites > button { align-self:flex-start; }
222
301
 
223
302
  .shepherd-config input, .shepherd-config select {
224
303
  padding:9px 12px; border-radius:8px; border:1px solid var(--line);
@@ -252,21 +331,52 @@
252
331
  border:1px solid var(--line); background:var(--bg); color:var(--ink);
253
332
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:12px; line-height:1.5;
254
333
  overflow-x:auto; white-space:pre-wrap; word-break:break-word; }
255
- .shepherd-connect-agent .install-command__copy {
256
- position:absolute; top:8px; right:8px; padding:4px 10px; font-size:11px;
257
- border-radius:6px; border:1px solid var(--line); background:var(--card);
258
- color:var(--ink2); cursor:pointer; transition:background .12s ease, color .12s ease; }
259
- .shepherd-connect-agent .install-command__copy:hover { background:var(--ink); color:var(--bg); }
334
+ /* Bare icon button (clipboard → check on copy), not a filled pill. Extra
335
+ selector depth beats the generic dark `.shepherd-config button` fill. */
336
+ .shepherd-config .shepherd-connect-agent .install-command__copy {
337
+ position:absolute; top:7px; right:7px; display:grid; place-items:center;
338
+ width:28px; height:28px; padding:0; border-radius:7px; border:0;
339
+ background:transparent; color:var(--ink3); cursor:pointer;
340
+ transition:background .12s ease, color .12s ease; }
341
+ .shepherd-config .shepherd-connect-agent .install-command__copy:hover {
342
+ background:rgba(50,44,32,.08); color:var(--ink); }
260
343
  .shepherd-connect-agent h4 { margin:6px 0 0; font-size:11px; font-weight:600;
261
344
  letter-spacing:.05em; text-transform:uppercase; color:var(--ink3); }
262
345
 
263
- .shepherd-config .invite-result, .shepherd-connect-agent .token-once {
346
+ .shepherd-connect-agent .token-once {
264
347
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:12px;
265
348
  padding:10px 12px; border-radius:8px;
266
349
  background:var(--chip); border:1px solid var(--line2); }
267
- .shepherd-config .invite-result { display:flex; flex-direction:column; gap:8px; word-break:break-all; }
268
- .shepherd-config .invite-result__row { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
269
- .shepherd-config .invite-result a { color:var(--ink2); }
350
+
351
+ /* Created-invite card: an eyebrow + use count + a quiet Revoke, then the
352
+ code and join link each with their own Copy affordance. */
353
+ .shepherd-config .invite-result { align-self:stretch; display:flex; flex-direction:column;
354
+ gap:12px; padding:14px 16px; border-radius:10px; background:var(--card);
355
+ border:1px solid var(--line); }
356
+ .shepherd-config .invite-result__head { display:flex; align-items:center; gap:12px; }
357
+ .shepherd-config .invite-result__eyebrow { flex:1; font-size:11px; font-weight:600;
358
+ letter-spacing:.05em; text-transform:uppercase; color:var(--ink3); }
359
+ .shepherd-config .invite-uses { font-size:12px; color:var(--ink3); }
360
+ .shepherd-config .invite-result__copyrow { display:flex; align-items:center; gap:10px; }
361
+ .shepherd-config .invite-result__copyrow > code { flex:1; min-width:0; font-size:15px;
362
+ font-weight:600; font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
363
+ color:var(--ink); letter-spacing:.02em; word-break:break-all; }
364
+ .shepherd-config .invite-result__copyrow--link { padding-top:10px;
365
+ border-top:1px solid var(--line2); }
366
+ .shepherd-config .invite-result__copyrow--link a { flex:1; min-width:0; font-size:12px;
367
+ color:var(--ink2); word-break:break-all; }
368
+
369
+ /* Quiet buttons inside the card: a bordered Copy pill and a text-only
370
+ Revoke. Extra selector depth beats the generic dark `button` fill+hover. */
371
+ .shepherd-config .invite-result .copy-btn { flex:none; padding:5px 12px; font-size:12px;
372
+ font-weight:600; border-radius:7px; border:1px solid var(--line); background:var(--bg);
373
+ color:var(--ink2); cursor:pointer; }
374
+ .shepherd-config .invite-result .copy-btn:hover { background:var(--ink); color:var(--bg);
375
+ border-color:var(--ink); }
376
+ .shepherd-config .invite-result .link-btn { flex:none; padding:0; font-size:12px;
377
+ font-weight:600; border:0; background:transparent; color:var(--drop); cursor:pointer; }
378
+ .shepherd-config .invite-result .link-btn:hover { background:transparent;
379
+ text-decoration:underline; }
270
380
  .shepherd-config .revoked { color:var(--ink3); text-decoration:line-through; }
271
381
  .shepherd-empty-state { text-align:center; color:var(--ink2); padding:48px 24px; }
272
382
  .shepherd-empty-state button { margin-top:14px; }
package/dist/preview.js CHANGED
@@ -41,11 +41,26 @@ let tokens = [
41
41
  ];
42
42
  let nextTokenId = 3;
43
43
  let lastInvite = null;
44
- const workspace = { id: "ws_preview", slug: "acme", name: "Acme Engineering", role: "admin" };
44
+ // A small mutable list so the app-bar workspace switcher (switch / create /
45
+ // join) can be clicked through — create/join append here, listWorkspaces reads it.
46
+ let workspaces = [
47
+ { id: "ws_preview", slug: "poop", name: "Poop on a stick", role: "admin" },
48
+ { id: "ws_acme", slug: "acme", name: "Acme Engineering", role: "member" },
49
+ ];
50
+ let nextWsId = 1;
45
51
  const previewClient = {
46
52
  baseUrl: "https://shepherd-hub-preview.a.run.app",
47
- listWorkspaces: async () => ({ workspaces: [workspace] }),
48
- createWorkspace: async (_body) => workspace,
53
+ listWorkspaces: async () => ({ workspaces }),
54
+ createWorkspace: async (body) => {
55
+ const ws = {
56
+ id: `ws_new_${nextWsId++}`,
57
+ slug: "new",
58
+ name: body.name,
59
+ role: "admin",
60
+ };
61
+ workspaces = [...workspaces, ws];
62
+ return ws;
63
+ },
49
64
  mintToken: async (_workspaceId, body) => {
50
65
  const id = `tok_${nextTokenId++}`;
51
66
  tokens = [
@@ -58,6 +73,18 @@ const previewClient = {
58
73
  revokeToken: async (_workspaceId, tokenId) => {
59
74
  tokens = tokens.map((t) => (t.id === tokenId ? { ...t, revokedAt: new Date().toISOString() } : t));
60
75
  },
76
+ mintAccountToken: async (body) => {
77
+ const id = `tok_${nextTokenId++}`;
78
+ tokens = [
79
+ ...tokens,
80
+ { id, name: body.name ?? null, createdAt: new Date().toISOString(), lastUsedAt: null, revokedAt: null },
81
+ ];
82
+ return { token: `shp_previewtoken${id}`, id };
83
+ },
84
+ listAccountTokens: async () => ({ tokens }),
85
+ revokeAccountToken: async (tokenId) => {
86
+ tokens = tokens.map((t) => (t.id === tokenId ? { ...t, revokedAt: new Date().toISOString() } : t));
87
+ },
61
88
  createInvite: async (_workspaceId, body) => {
62
89
  lastInvite = {
63
90
  code: "PREVIEW-CODE",
@@ -74,7 +101,16 @@ const previewClient = {
74
101
  revokeInvite: async () => {
75
102
  lastInvite = null;
76
103
  },
77
- redeemInvite: async () => ({ workspace }),
104
+ redeemInvite: async () => {
105
+ const joined = {
106
+ id: `ws_joined_${nextWsId++}`,
107
+ slug: "joined",
108
+ name: "Joined workspace",
109
+ role: "member",
110
+ };
111
+ workspaces = [...workspaces, joined];
112
+ return { workspace: joined };
113
+ },
78
114
  listMembers: async () => ({ members }),
79
115
  removeMember: async (_workspaceId, accountId) => {
80
116
  members = members.filter((m) => m.accountId !== accountId);
@@ -0,0 +1 @@
1
+ :root{--bg:#ece0c6;--ink:#322c20;--ink2:#6f6450;--ink3:#9c917a;--line:#d7c9ac;--line2:#e0d4b9;--live:#3d8b58;--drop:#bd4f3a;--chip:#e3d6ba;--terr:#7a6a48;--card:#f5ecd9}*{box-sizing:border-box}html,body{height:100%}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.45 Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif;-webkit-font-smoothing:antialiased}.wrap{max-width:1100px;margin:0 auto;padding:40px 44px}header{display:flex;align-items:center;gap:12px;padding-bottom:18px}.brand{font-size:17px;font-weight:600}.vitals{color:var(--ink3);font-size:12.5px}.grow{flex:1}.status{font-size:12px;color:var(--ink3)}.status--ok{color:var(--live)}.status--warn{color:var(--terr)}.status--error{color:var(--drop)}.freshness{font-size:12px;color:var(--ink3)}.repo{position:relative}.repo-trig{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-family:inherit;color:var(--ink);-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid var(--line);border-radius:8px;padding:4px 10px;background:#fffaee66;cursor:pointer}.repo-trig .slash{color:var(--ink3)}.repo-menu{position:absolute;top:36px;left:0;min-width:200px;background:var(--card);border:1px solid var(--line);border-radius:10px;padding:5px;box-shadow:0 8px 24px #32281424;z-index:5}.repo-mi{display:flex;justify-content:space-between;gap:14px;padding:7px 9px;width:100%;text-align:left;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-family:inherit;color:inherit;background:transparent;border-radius:7px;font-size:13px;cursor:pointer}.repo-mi:hover{background:var(--chip)}.repo-mi.on{background:var(--chip);font-weight:600}.repo-mi .ct{font-size:11px;color:var(--ink3)}.repo-mi.all{border-top:1px solid var(--line2);margin-top:4px;padding-top:9px;color:var(--ink2)}.tabs{display:flex;gap:4px;margin-left:auto}.tab{font-size:13px;color:var(--ink2);padding:5px 11px;border:0;border-radius:7px;background:transparent;cursor:pointer;font:inherit}.tab--active{background:var(--ink);color:var(--bg)}.ws-switcher{position:relative}.ws-trig{display:inline-flex;align-items:center;gap:8px;font:inherit;font-size:13px;font-weight:600;color:var(--ink);cursor:pointer;border:1px solid var(--line);border-radius:9px;padding:5px 10px;background:var(--card)}.ws-trig:hover{border-color:var(--ink3)}.ws-trig--empty{background:transparent;border-style:dashed;border-color:var(--ink2)}.ws-avatar{width:18px;height:18px;border-radius:6px;background:var(--ink);color:var(--bg);display:grid;place-items:center;font-size:10px;font-weight:700;flex:none}.ws-avatar--sm{width:16px;height:16px;font-size:9px}.ws-plus{color:var(--ink2);font-weight:700}.ws-name{max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ws-caret{color:var(--ink3);font-size:10px}.ws-menu{position:absolute;top:40px;left:0;width:240px;z-index:20;background:var(--card);border:1px solid var(--line);border-radius:11px;padding:6px;box-shadow:0 8px 24px #32281429}.ws-menu__head{margin:0;padding:6px 8px;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink3)}.ws-menu__none{margin:0;padding:2px 8px 6px;color:var(--ink3);font-style:italic;font-size:13px}.ws-menu__list{list-style:none;margin:0;padding:0}.ws-mi{display:flex;align-items:center;gap:8px;width:100%;text-align:left;font:inherit;font-size:13px;color:var(--ink);background:transparent;border:0;border-radius:7px;padding:7px 8px;cursor:pointer}.ws-mi:hover{background:var(--chip)}.ws-mi--on{font-weight:600}.ws-mi__name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ws-mi__check{color:var(--live)}.ws-menu__actions{display:flex;flex-direction:column;margin-top:5px;padding-top:5px;border-top:1px solid var(--line2)}.ws-action{display:flex;align-items:center;gap:8px;width:100%;text-align:left;font:inherit;font-size:13px;color:var(--ink2);background:transparent;border:0;border-radius:7px;padding:8px;cursor:pointer}.ws-action:hover{background:var(--chip);color:var(--ink)}.ws-form{display:flex;flex-direction:column;gap:8px;padding:4px}.ws-form label{font-size:10px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}.ws-form input{padding:8px 10px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--ink);font:inherit}.ws-form input:focus{outline:none;border-color:var(--terr);box-shadow:0 0 0 3px #7a6a4824}.ws-form__row{display:flex;gap:8px;justify-content:flex-end}.ws-form__row button{font:inherit;font-size:13px;font-weight:600;border-radius:8px;padding:7px 14px;cursor:pointer;border:1px solid var(--ink);background:var(--ink);color:var(--bg)}.ws-form__row button:disabled{opacity:.55;cursor:default}.ws-form__back{background:transparent!important;color:var(--ink2)!important;border-color:var(--line)!important}.ws-menu__error{margin:6px 4px 2px;font-size:12.5px;color:var(--drop)}.crew{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:26px 0 32px}.person{display:inline-flex;align-items:center;gap:9px;padding:5px 13px 5px 5px;border:1px solid var(--line);border-radius:999px;background:var(--card);font-size:13px}.person--idle{opacity:.55}.avatar{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;font-size:10px;font-weight:700;color:#fff;flex:none}.person__name{font-weight:600}.person__doing{color:var(--ink3);font-size:12px}.board{display:grid;grid-template-columns:1fr 1px 1fr;gap:0}.board__rule{background:var(--line)}.col{padding:0 36px}.col:first-child{padding-left:0}.col:last-child{padding-right:0}.colhead{display:flex;align-items:center;gap:8px;margin-bottom:6px}.colhead h2{font-size:12px;font-weight:600;letter-spacing:.03em;margin:0;text-transform:uppercase;color:var(--ink2)}.colhead .n{font-size:11px;color:var(--ink3);background:var(--chip);border-radius:999px;padding:1px 8px}.task{padding:16px 0;border-bottom:1px solid var(--line2)}.task__r1{display:flex;align-items:center;gap:8px}.task__who{font-size:13.5px;font-weight:600}.task__tag{font-size:11px;color:var(--ink3)}.task__repo{font-size:11px;color:var(--terr);background:#7a6a481a;border-radius:4px;padding:0 6px}.task__stat{margin-left:auto;font-size:11px;font-weight:500;color:var(--ink3)}.task__stat--drop{color:var(--drop)}.livedot{width:7px;height:7px;border-radius:50%;background:var(--live);margin-left:auto}.task__intent{font-size:13.5px;margin:5px 0 0;line-height:1.45}.terr{margin-top:8px;display:flex;flex-wrap:wrap;gap:6px;align-items:center}.terr__lbl{font-size:9.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink3)}.glob{font-family:ui-monospace,Menlo,monospace;font-size:11px;color:var(--terr);background:#7a6a481f;border:1px solid rgba(122,106,72,.22);border-radius:5px;padding:1px 7px}.task__meta{font-size:11.5px;color:var(--ink3);margin-top:6px}.terrx{margin-top:8px}.terrx summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:6px;flex-wrap:wrap;-webkit-user-select:none;user-select:none}.terrx summary::-webkit-details-marker{display:none}.terrx .terr--full{margin-top:8px}.glob--more{cursor:pointer;color:var(--ink2);background:var(--chip);border:1px solid var(--line)}.glob--more .tw{color:var(--ink3);display:inline-block;transition:transform .15s}.terrx[open] summary .glob--more .tw{transform:rotate(90deg)}.grp{padding:16px 0;border-bottom:1px solid var(--line2)}.grp__head{display:flex;align-items:center;gap:8px}.grp__who{font-size:13.5px;font-weight:600}.grp__tag,.grp__count{font-size:11px;color:var(--ink3)}.grp__dot{width:7px;height:7px;border-radius:50%;background:var(--live);margin-left:auto}.claims{margin:10px 0 0 6px;padding-left:14px;border-left:1px solid var(--line)}.claim{padding:6px 0}.claim+.claim{border-top:1px solid var(--line2);margin-top:6px}.fold{margin-top:10px}.fold summary{list-style:none;cursor:pointer;font-size:12px;color:var(--ink2);display:inline-flex;align-items:center;gap:6px;-webkit-user-select:none;user-select:none}.fold summary::-webkit-details-marker{display:none}.fold summary .tw{display:inline-block;color:var(--ink3);transition:transform .15s}.fold[open] summary .tw{transform:rotate(90deg)}.fold__body{margin:8px 0 0 6px;padding-left:14px;border-left:1px dashed var(--line)}.covered{font-size:10.5px;color:var(--ink3);font-style:italic;margin-top:4px}.day{font-size:11px;color:var(--ink3);padding:18px 0 2px;font-weight:600}.more{margin-top:20px;font-size:12.5px;color:var(--ink2);padding:7px 13px;border:1px solid var(--line);border-radius:8px;background:#fffaee59;cursor:pointer}.empty{color:var(--ink3);font-style:italic;padding:14px 0}.chat-wrap{background:var(--card);border:1px solid var(--line);border-radius:12px;display:flex;flex-direction:column;overflow:hidden;height:calc(100vh - 150px);min-height:320px}.chat{flex:1;overflow-y:auto;padding:16px}.chat{scrollbar-width:thin;scrollbar-color:var(--line) transparent}.chat::-webkit-scrollbar{width:10px}.chat::-webkit-scrollbar-track{background:transparent}.chat::-webkit-scrollbar-thumb{background:var(--line);border-radius:999px;border:3px solid var(--card);background-clip:padding-box}.chat::-webkit-scrollbar-thumb:hover{background:var(--ink3);background-clip:padding-box}.chat__note{padding:9px 16px;font-size:11.5px;color:var(--ink3)}.msg{display:flex;gap:11px;padding:9px 0}.msg__avatar{flex:none;width:32px;height:32px;border-radius:50%;display:grid;place-items:center;font-size:12px;font-weight:700;color:#fff}.msg__body{min-width:0;flex:1}.msg__head{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.msg__who{font-weight:600}.msg__human{font-size:12px;color:var(--ink3)}.msg__to{font-size:11.5px;color:var(--terr)}.msg__time{font-size:11.5px;color:var(--ink3);margin-left:auto}.msg__text{margin-top:3px;padding:8px 12px;border-radius:4px 12px 12px;background:var(--chip);white-space:pre-wrap;word-break:break-word}.msg--targeted .msg__text{box-shadow:inset 3px 0 0 var(--terr)}.msg--me,.msg--me .msg__head{flex-direction:row-reverse}.msg--me .msg__time{margin-left:0;margin-right:auto}.msg--me .msg__body{display:flex;flex-direction:column;align-items:flex-end}.msg--me .msg__text{border-radius:12px 4px 12px 12px;background:#d4e7d2}.msg--me.msg--targeted .msg__text{box-shadow:inset -3px 0 0 var(--terr)}.composer{position:relative;border-top:1px solid var(--line);padding:10px 12px}.chat-form{display:flex;gap:8px}.chat-input{flex:1;padding:9px 12px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--ink);font:inherit}.chat-input:focus{outline:none;border-color:var(--terr)}.chat-send{padding:9px 16px;border-radius:8px;border:1px solid var(--ink);background:var(--ink);color:var(--bg);font-weight:600;cursor:pointer;font:inherit}.chat-send:disabled{opacity:.5;cursor:default}.mention-pop{position:absolute;left:12px;right:12px;bottom:56px;z-index:6;background:var(--card);border:1px solid var(--line);border-radius:10px;padding:5px;box-shadow:0 8px 24px #32281429;max-height:200px;overflow-y:auto}.mention-mi{display:flex;align-items:center;gap:9px;width:100%;text-align:left;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-family:inherit;color:inherit;background:transparent;border-radius:7px;padding:6px 8px;font-size:13px;cursor:pointer}.mention-mi:hover,.mention-mi.on{background:var(--chip)}.mention-mi .ma{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;font-size:9px;font-weight:700;color:#fff;flex:none}.gate{max-width:420px;margin:12vh auto 0;text-align:center}.gate h1{font-size:19px;margin:0 0 6px}.gate p{color:var(--ink2);margin:0 0 20px}.gate form{display:flex;gap:8px}.gate input{flex:1;padding:10px 12px;border-radius:8px;border:1px solid var(--line);background:var(--card);color:var(--ink)}.gate button{padding:10px 16px;border-radius:8px;border:1px solid var(--ink);background:var(--ink);color:var(--bg);font-weight:600;cursor:pointer}.shepherd-root{max-width:1100px;margin:0 auto;padding:40px 44px}.shepherd-root>main{padding-top:18px}.shepherd-config{display:flex;flex-direction:column}.shepherd-config h2{font-size:16px;margin:0 0 22px}.config-layout{display:flex;gap:32px;align-items:flex-start}.config-nav{flex:none;width:170px;display:flex;flex-direction:column;gap:2px;position:sticky;top:0}.shepherd-config .config-nav__item{text-align:left;font:inherit;font-size:13.5px;color:var(--ink2);background:transparent;border:0;border-radius:8px;padding:8px 12px;cursor:pointer;box-shadow:inset 2px 0 0 transparent;transition:color .12s ease,background .12s ease}.shepherd-config .config-nav .config-nav__item:hover{color:var(--ink);background:#322c200f}.shepherd-config .config-nav__item--on{color:var(--ink);font-weight:600;box-shadow:inset 2px 0 0 var(--ink)}.shepherd-config .config-nav .config-nav__item--on:hover{background:transparent}.config-panel{flex:1;min-width:0}.config-panel>section+section{margin-top:26px;padding-top:26px;border-top:1px solid var(--line2)}.config-none{color:var(--ink2);font-size:13.5px;max-width:520px}.shepherd-config .readonly-value{margin:0;font-size:14px;color:var(--ink);padding:9px 12px;border-radius:8px;border:1px solid var(--line2);background:var(--bg)}.shepherd-general .leave{padding-top:4px}.shepherd-config button.danger{border-color:var(--drop);background:transparent;color:var(--drop);align-self:flex-start}.shepherd-config button.danger:hover:not(:disabled){background:var(--drop);color:var(--bg)}.shepherd-config .card-head h3{font-size:13px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--ink2);margin:0}.shepherd-config .card-sub{margin:4px 0 0;font-size:12.5px;color:var(--ink3)}.shepherd-config .card-head{margin-bottom:16px}.shepherd-config .card-body{display:flex;flex-direction:column;gap:16px}.shepherd-config .card-body>[role=alert]{margin:0;color:var(--drop);font-size:13px}.shepherd-config .card-body>[role=status]{margin:0;color:var(--ink2);font-size:13px}.shepherd-config .field{display:flex;flex-direction:column;gap:8px}.shepherd-config .card-body label{font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}.shepherd-config .helper{margin:0;font-size:12.5px;color:var(--ink2)}.shepherd-config .field>select{width:100%}.shepherd-config select{appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239c917a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 28px center;padding-right:44px}.shepherd-config .field__row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.shepherd-config .field__row>input{flex:1;min-width:200px}.shepherd-invites .invites{gap:12px}.shepherd-invites .invites>button{align-self:flex-start}.shepherd-config input,.shepherd-config select{padding:9px 12px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--ink);font:inherit;transition:border-color .12s ease,box-shadow .12s ease}.shepherd-config input::placeholder{color:var(--ink3)}.shepherd-config input:focus,.shepherd-config select:focus{outline:none;border-color:var(--terr);box-shadow:0 0 0 3px #7a6a4824}.shepherd-config button{padding:9px 16px;border-radius:8px;border:1px solid var(--ink);background:var(--ink);color:var(--bg);font-weight:600;cursor:pointer;font:inherit;white-space:nowrap;transition:background .12s ease}.shepherd-config button:hover:not(:disabled){background:#413a2a}.shepherd-config button:disabled{opacity:.55;cursor:default}.shepherd-config ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.shepherd-config li{display:flex;align-items:center;gap:10px;padding:10px 0;font-size:13px}.shepherd-config li+li{border-top:1px solid var(--line2)}.shepherd-config li>span:first-child{flex:1;min-width:0;font-weight:500}.shepherd-config li button{padding:5px 12px}.shepherd-config .role,.shepherd-config .token-meta{color:var(--ink3);font-size:12px}.shepherd-config .email-invite__status{margin:0;font-size:12.5px;color:var(--ink2)}.shepherd-connect-agent .install-command{position:relative}.shepherd-connect-agent pre{margin:0;padding:12px 14px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--ink);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.5;overflow-x:auto;white-space:pre-wrap;word-break:break-word}.shepherd-config .shepherd-connect-agent .install-command__copy{position:absolute;top:7px;right:7px;display:grid;place-items:center;width:28px;height:28px;padding:0;border-radius:7px;border:0;background:transparent;color:var(--ink3);cursor:pointer;transition:background .12s ease,color .12s ease}.shepherd-config .shepherd-connect-agent .install-command__copy:hover{background:#322c2014;color:var(--ink)}.shepherd-connect-agent h4{margin:6px 0 0;font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}.shepherd-connect-agent .token-once{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;padding:10px 12px;border-radius:8px;background:var(--chip);border:1px solid var(--line2)}.shepherd-config .invite-result{align-self:stretch;display:flex;flex-direction:column;gap:12px;padding:14px 16px;border-radius:10px;background:var(--card);border:1px solid var(--line)}.shepherd-config .invite-result__head{display:flex;align-items:center;gap:12px}.shepherd-config .invite-result__eyebrow{flex:1;font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}.shepherd-config .invite-uses{font-size:12px;color:var(--ink3)}.shepherd-config .invite-result__copyrow{display:flex;align-items:center;gap:10px}.shepherd-config .invite-result__copyrow>code{flex:1;min-width:0;font-size:15px;font-weight:600;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--ink);letter-spacing:.02em;word-break:break-all}.shepherd-config .invite-result__copyrow--link{padding-top:10px;border-top:1px solid var(--line2)}.shepherd-config .invite-result__copyrow--link a{flex:1;min-width:0;font-size:12px;color:var(--ink2);word-break:break-all}.shepherd-config .invite-result .copy-btn{flex:none;padding:5px 12px;font-size:12px;font-weight:600;border-radius:7px;border:1px solid var(--line);background:var(--bg);color:var(--ink2);cursor:pointer}.shepherd-config .invite-result .copy-btn:hover{background:var(--ink);color:var(--bg);border-color:var(--ink)}.shepherd-config .invite-result .link-btn{flex:none;padding:0;font-size:12px;font-weight:600;border:0;background:transparent;color:var(--drop);cursor:pointer}.shepherd-config .invite-result .link-btn:hover{background:transparent;text-decoration:underline}.shepherd-config .revoked{color:var(--ink3);text-decoration:line-through}.shepherd-empty-state{text-align:center;color:var(--ink2);padding:48px 24px}.shepherd-empty-state button{margin-top:14px}.shepherd-feedback{position:fixed;right:20px;bottom:20px;z-index:10}.shepherd-feedback__trigger{padding:9px 16px;border-radius:999px;border:1px solid var(--ink);background:var(--ink);color:var(--bg);font-weight:600;font-size:13px;font:inherit;cursor:pointer;box-shadow:0 8px 24px #3228142e}.shepherd-feedback__trigger:hover{background:#413a2a}.shepherd-feedback__panel{position:absolute;right:0;bottom:calc(100% + 10px);width:280px;display:flex;flex-direction:column;gap:10px;padding:16px;background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:0 8px 24px #3228142e}.shepherd-feedback__panel h3{margin:0;font-size:13px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--ink2)}.shepherd-feedback__panel [role=status]{margin:0;font-size:13px;color:var(--ink2)}.shepherd-feedback__panel [role=alert]{margin:0;font-size:13px;color:var(--drop)}.shepherd-feedback__types{display:flex;gap:6px}.shepherd-feedback__types button{flex:1;padding:6px 0;border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--ink2);font-size:12.5px;font:inherit;cursor:pointer;transition:background .12s ease,color .12s ease}.shepherd-feedback__types button[aria-pressed=true]{background:var(--ink);color:var(--bg);border-color:var(--ink);font-weight:600}.shepherd-feedback__panel textarea{min-height:80px;padding:9px 12px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--ink);font:inherit;resize:vertical}.shepherd-feedback__panel textarea::placeholder{color:var(--ink3)}.shepherd-feedback__panel textarea:focus{outline:none;border-color:var(--terr);box-shadow:0 0 0 3px #7a6a4824}.shepherd-feedback__panel>button{padding:9px 16px;border-radius:8px;border:1px solid var(--ink);background:var(--ink);color:var(--bg);font-weight:600;cursor:pointer;font:inherit}.shepherd-feedback__panel>button:hover:not(:disabled){background:#413a2a}.shepherd-feedback__panel>button:disabled{opacity:.55;cursor:default}