@bongos/core 1.19.420 → 1.19.421

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 (34) hide show
  1. package/.bongos-core.json +68 -33
  2. package/docs/copy-inventory.md +282 -281
  3. package/docs/copy-registry.json +375 -366
  4. package/docs/design/mocks/hub/mine.html +377 -0
  5. package/docs/design/projects-hub-direction-v2.md +25 -1
  6. package/docs/file-map.md +1 -0
  7. package/docs/module-api-changelog.md +2 -0
  8. package/modules/hall-ui/public/settings.html +3 -2
  9. package/modules/hall-ui/public/settings.js +10 -6
  10. package/modules/platform-identity/account-visibility.js +94 -3
  11. package/modules/platform-identity/platform-identity.js +45 -50
  12. package/modules/platform-identity/routes/connections.js +3 -3
  13. package/modules/ui-design/kit/fixtures/featured-hub.json +1 -0
  14. package/modules/ui-design/kit/fixtures/provisioning-instances-empty.json +4 -0
  15. package/modules/ui-design/kit/fixtures/provisioning-instances.json +99 -0
  16. package/modules/ui-design/kit/lib.js +6 -2
  17. package/modules/ui-design/kit/probe.js +1 -1
  18. package/modules/ui-design/kit/render.js +1 -1
  19. package/modules/ui-design/kit/serve.js +63 -2
  20. package/package-lock.json +2 -2
  21. package/package.json +1 -1
  22. package/public-landing/assets/cosmos.css +224 -18
  23. package/public-landing/projects-empty.states.json +49 -0
  24. package/public-landing/projects-floor.states.json +63 -0
  25. package/public-landing/projects.html +112 -51
  26. package/public-landing/projects.probes.json +32 -7
  27. package/public-landing/projects.states.json +10 -6
  28. package/src/module-api.js +1 -1
  29. package/tests/account_privacy_flags.mjs +17 -10
  30. package/tests/effective_visibility_predicate.mjs +891 -0
  31. package/tests/profile_route.mjs +22 -11
  32. package/tests/projects_hub.mjs +33 -5
  33. package/tests/projects_hub_pre_uat.mjs +18 -6
  34. package/tests/ui_design_kit.mjs +32 -2
@@ -377,22 +377,6 @@ h1{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3.4vw,32
377
377
  .chip.calm .cdot{background:var(--ink-faint);}
378
378
  @keyframes chipPulse{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 35%,transparent)}50%{box-shadow:0 0 0 5px transparent}}
379
379
 
380
- /* ── the orb: the gate's project sphere, docked onto a card. Glow follows
381
- verification — warm when verified live, amber-dim when stale, ashen when
382
- it failed its check, ghosted when torn down. Born for the dark sky; on
383
- light cards the inset ring keeps it grounded. ── */
384
- .orb{flex:0 0 54px;width:54px;height:54px;border-radius:50%;position:relative;overflow:visible;border:none;padding:0;
385
- background:radial-gradient(120% 120% at 50% 50%, var(--acc,#fb923c), color-mix(in srgb, var(--acc,#fb923c) 55%, #1b2b52) 100%);
386
- box-shadow:0 0 0 1.5px rgba(255,255,255,.35) inset, 0 6px 18px rgba(20,16,40,.28), 0 0 26px var(--glow, rgba(251,146,60,.5));}
387
- .orb::after{content:'';position:absolute;inset:0;border-radius:50%;pointer-events:none;
388
- background:radial-gradient(38% 34% at 34% 28%, rgba(255,255,255,.9), rgba(255,255,255,0) 60%);}
389
- .orb.dim{filter:saturate(.55) brightness(.92);--glow:rgba(217,119,6,.35);}
390
- .orb.ashen{filter:saturate(.3) brightness(.78);--glow:rgba(220,38,38,.22);}
391
- .orb.ghost{opacity:.4;box-shadow:0 0 0 1.5px rgba(255,255,255,.25) inset;filter:saturate(.2);}
392
- /* only the LINKED orb is clickable: orbFor() emits a <span class="orb"> for
393
- every non-navigable state, and index.html's .conItem .orb takes cursor:inherit
394
- from the <a> it sits inside — so .orb.ghost's cursor reset is redundant. */
395
- a.orb{cursor:pointer;}
396
380
 
397
381
  /* ── project cards ── */
398
382
  .projects{list-style:none;display:flex;flex-direction:column;gap:18px;}
@@ -1152,8 +1136,6 @@ p.sec-p{font-size:var(--fs-lede);font-weight:500;color:var(--ink-soft);line-heig
1152
1136
  @media (max-width:640px){
1153
1137
  .projHead{gap:8px;}
1154
1138
  .actions{flex-direction:column;align-items:stretch;}
1155
- .proj{flex-direction:column;}
1156
- .orb{width:44px;height:44px;flex-basis:44px;}
1157
1139
  .mineBar .search .count{display:none;} /* the "All 16" pill already carries the number */
1158
1140
  }
1159
1141
  /* the carried surfaces: only the hit-area floors the world asks for (direction
@@ -1162,7 +1144,231 @@ p.sec-p{font-size:var(--fs-lede);font-weight:500;color:var(--ink-soft);line-heig
1162
1144
  on a phone instead of pushing the page sideways */
1163
1145
  #sub-table-body{overflow-x:auto;}
1164
1146
  .tbl th button{min-height:24px;display:inline-flex;align-items:center;}
1147
+ .tbl a.ptitle{display:inline-flex;align-items:center;min-height:24px;}
1165
1148
  .foot a,.finePrint a{display:inline-block;padding:3px 0;min-height:24px;}
1149
+ /* ═══════════════════════════════════════════════════════════════════════
1150
+ YOUR PROJECTS + THE MANAGE PAGE, IN THE WORLD (task 1003345; direction
1151
+ record §14, the owner's pick: v1 the ledger row). Both views keep the
1152
+ markup the truth rules pin (renderCard / orbFor / stripMarkup, the manage
1153
+ ids) and take the world's grammar by SCOPE: no card ground, hairlines for
1154
+ structure, the project's own planet as the row's object, the strip drawn
1155
+ as the lifecycle rail, the doors as hairline pills with the accent only on
1156
+ the one that acts. One set of FIXED tracks across every row, so the list
1157
+ reads as one ledger (task 1003348). Dark only (ADR 0204); every colour a
1158
+ token; halos are outlines, never box-shadow (DESIGN.md).
1159
+ ═══════════════════════════════════════════════════════════════════════ */
1160
+ #view-mine .wrap,#view-manage .wrap{max-width:1180px;}
1161
+ #view-mine .card,#view-manage .card{background:none;border-radius:0;box-shadow:none;padding:0;margin:0;}
1162
+ /* the view title in the display voice, lowercase; the lede stays one clause */
1163
+ #view-mine .hero,#view-manage .hero{padding-top:34px;padding-bottom:22px;}
1164
+ #view-mine .hero h1,#view-manage .hero h1{font-weight:300;font-size:clamp(28px,3.4vw,44px);letter-spacing:-.035em;line-height:1.04;text-transform:lowercase;color:var(--ink);text-shadow:none;}
1165
+ #view-mine .hero .lede,#view-manage .hero .lede{color:var(--ink-soft);font-weight:400;text-shadow:none;margin:8px 0 0;}
1166
+ #view-mine .hero .lede b,#view-manage .hero .lede b{color:var(--ink);font-weight:500;}
1167
+ #view-mine .finePrint,#view-manage .finePrint{font-weight:400;font-size:13.5px;line-height:1.5;}
1168
+ #view-mine .loading,#view-manage .loading{font-weight:400;}
1169
+
1170
+ /* ── the planet, docked: the sky's object, relative instead of absolute; its
1171
+ state reads on the object (ghost = torn down, ashen = failed its check,
1172
+ dim = a stale probe), and only the live one is a link ── */
1173
+ #view-mine .worldOrb,#view-manage .worldOrb{position:relative;left:auto;top:auto;transform:none;display:block;cursor:default;opacity:1;pointer-events:auto;}
1174
+ #view-mine a.worldOrb,#view-manage a.worldOrb{cursor:pointer;}
1175
+ #view-mine .worldOrb .disc,#view-manage .worldOrb .disc{display:block;margin:0;}
1176
+ #view-mine span.worldOrb:hover .disc,#view-manage span.worldOrb:hover .disc{translate:none;}
1177
+ #view-mine .worldOrb.ghost,#view-manage .worldOrb.ghost{opacity:.4;filter:saturate(.2);}
1178
+ #view-mine .worldOrb.ashen,#view-manage .worldOrb.ashen{filter:saturate(.3) brightness(.78);}
1179
+ #view-mine .worldOrb.dim,#view-manage .worldOrb.dim{opacity:1;filter:saturate(.55) brightness(.92);}
1180
+
1181
+ /* ── the search: one hairline field, the count in the label face; the
1182
+ filters: hairline pills, the pressed one inverted to ink ── */
1183
+ #view-mine .mineBar{gap:18px;margin:0 0 8px;justify-content:space-between;}
1184
+ #view-mine .mineBar .search{max-width:520px;gap:12px;background:none;border:0;border-bottom:1px solid var(--rule);border-radius:0;padding:10px 0;backdrop-filter:none;}
1185
+ #view-mine .mineBar .search:focus-within{box-shadow:none;border-bottom-color:var(--ink);}
1186
+ #view-mine .mineBar .search svg{width:18px;height:18px;stroke-width:1.6;}
1187
+ #view-mine .mineBar .search input{font-family:var(--font-body);font-size:15.5px;min-height:28px;padding:0;}
1188
+ #view-mine .mineBar .search .count{font-family:var(--label-face);font-size:var(--label-size);letter-spacing:var(--label-space);text-transform:uppercase;}
1189
+ #view-mine .filters{gap:8px;}
1190
+ #view-mine .filters button{min-height:36px;padding:0 15px;gap:8px;font-family:var(--font-body);font-weight:400;font-size:14.5px;text-transform:lowercase;color:var(--ink-soft);background:none;border:1px solid var(--rule);}
1191
+ #view-mine .filters button:hover{border-color:var(--ink-faint);color:var(--ink);}
1192
+ #view-mine .filters button[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--bg);}
1193
+ #view-mine .filters .n{font-family:var(--label-face);font-size:var(--label-size);letter-spacing:var(--label-space);font-weight:400;}
1194
+ #view-mine .mineEmpty{font-weight:400;color:var(--ink-soft);}
1195
+ #view-mine .linklike,#view-manage .linklike{font-weight:400;color:var(--ink-soft);}
1196
+
1197
+ /* ── the ledger row: planet · name and chip · the facts · the rail · the
1198
+ doors. The planet and the doors are fixed widths; the three middle tracks
1199
+ share the rest by ratio with NO content minimum, so every row lays its
1200
+ columns on the same lines (task 1003348). The body is its own grid on the
1201
+ same four tracks, so renderCard's markup stands as pinned. ── */
1202
+ #view-mine .projects{gap:0;margin-top:8px;}
1203
+ #view-mine .proj{display:grid;grid-template-columns:72px minmax(0,1fr);gap:0 22px;align-items:center;padding:22px 0;border:0;border-top:1px solid var(--rule-soft);border-radius:0;background:none;}
1204
+ #view-mine .projects .proj:last-child{border-bottom:1px solid var(--rule-soft);}
1205
+ #view-mine .projBody{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1.3fr) minmax(0,1fr) 232px;grid-template-areas:"who facts rail doors" "who addr rail doors";gap:0 22px;align-items:center;min-width:0;}
1206
+ #view-mine .projHead{grid-area:who;display:grid;gap:8px;justify-items:start;align-content:center;}
1207
+ #view-mine .projMeta{grid-area:facts;align-self:end;}
1208
+ #view-mine .addr{grid-area:addr;align-self:start;}
1209
+ #view-mine .strip{grid-area:rail;}
1210
+ #view-mine .actions{grid-area:doors;}
1211
+ /* everything else on a card (a snag, a status line, the torn-down note, the
1212
+ address fold) is a full row under the ledger line */
1213
+ #view-mine .projBody>.projMsg,#view-mine .projBody>.attachFold{grid-column:1/-1;}
1214
+ #view-mine .projMsg{min-height:0;margin:0;font-weight:400;}
1215
+ #view-mine .projMsg:not(:empty){margin-top:10px;}
1216
+ #view-mine .projMsg.err{margin-top:12px;}
1217
+ #view-mine .attachFold{margin-top:10px;}
1218
+ #view-mine .actions:has(.confirmRow){grid-area:auto;grid-column:1/-1;justify-content:flex-start;margin-top:12px;}
1219
+ /* the name in the body face; the chip beneath it, allowed to wrap */
1220
+ #view-mine .projName{font-family:var(--font-body);font-weight:500;font-size:17px;letter-spacing:-.015em;color:var(--ink);}
1221
+ #view-mine .proj.gone .projName{color:var(--ink-soft);}
1222
+ #view-mine .projHead .chip{white-space:normal;line-height:1.3;}
1223
+ /* the facts: label-face lines; the repo in mono with no plate */
1224
+ #view-mine .projMeta{display:grid;gap:5px;margin:0;font-family:var(--label-face);font-size:var(--label-size);font-weight:400;letter-spacing:var(--label-space);text-transform:uppercase;color:var(--ink-faint);}
1225
+ #view-mine .projMeta>span+span::before{content:none;margin:0;}
1226
+ #view-mine .projMeta code,#view-mine .addr code{font-family:var(--font-mono);font-size:12.5px;letter-spacing:0;text-transform:none;color:var(--ink-soft);background:none;border-radius:0;padding:0;}
1227
+ /* the address: the honest clause in the body face */
1228
+ #view-mine .addr{margin:5px 0 0;font-size:13.5px;font-weight:400;line-height:1.45;color:var(--ink-soft);}
1229
+ #view-mine .addr .none{font-style:normal;color:var(--ink-faint);}
1230
+ /* every inline link on these views clears the 24px hit floor: a short link as a
1231
+ box; the address clause's mono link may run long and must wrap inside the
1232
+ prose, so it stays inline and takes the floor as vertical padding (an inline's
1233
+ rect is its content box plus padding, never the line box) */
1234
+ #view-mine .projMsg a,#view-mine .attachNote a,#view-manage .ledger a,#view-manage .backRow a,#view-manage .mSec a{display:inline-block;padding:3px 0;min-height:24px;line-height:18px;font-weight:400;text-decoration:none;}
1235
+ #view-mine .addr{line-height:1.6;}
1236
+ #view-mine .addr a{display:inline;padding:4px 0;font-weight:400;text-decoration:none;}
1237
+ #view-mine .addr a,#view-manage .ledger a{font-family:var(--font-mono);font-size:12.5px;color:var(--ink-soft);}
1238
+ #view-mine .addr a:hover,#view-manage .ledger a:hover{color:var(--ink);text-decoration:underline;}
1239
+ #view-mine .projMsg a,#view-manage .mSec a{color:var(--ink);text-decoration:underline;}
1240
+ #view-mine .attachFold summary{display:inline-flex;align-items:center;min-height:24px;font-weight:400;font-size:13.5px;color:var(--ink-soft);}
1241
+ #view-mine .attachFold summary:hover,#view-mine .attachFold[open] summary{color:var(--ink);}
1242
+
1243
+ /* ── the lifecycle rail (DESIGN.md): stripMarkup's markup, drawn as three
1244
+ hairlines with a 7px dot and one lit step — no plate, no connector, no
1245
+ pulse. Live keeps the world's green; a wind-down stays neutral. ── */
1246
+ #view-mine .strip,#view-manage .strip{border:0;border-radius:0;padding:0;background:none;margin:0;}
1247
+ #view-mine .strip .stages,#view-manage .strip .stages{display:grid;grid-template-columns:repeat(3,1fr);gap:0 10px;margin:0;}
1248
+ #view-mine .strip .stages li,#view-manage .strip .stages li{display:block;position:relative;border-top:1px solid var(--rule);padding:12px 0 0;}
1249
+ #view-mine .strip .stages li::before,#view-manage .strip .stages li::before{content:none;}
1250
+ #view-mine .strip .sdot,#view-manage .strip .sdot{position:absolute;top:-4px;left:0;width:7px;height:7px;border:1px solid var(--rule);border-radius:50%;background:var(--bg);display:block;}
1251
+ #view-mine .strip .sdot::after,#view-manage .strip .sdot::after{content:none;}
1252
+ #view-mine .strip .slbl,#view-manage .strip .slbl{display:block;font-family:var(--label-face);font-size:var(--label-size);font-weight:400;letter-spacing:var(--label-space);text-transform:uppercase;line-height:1.3;color:var(--ink-faint);}
1253
+ #view-mine .strip .stages li.done,#view-manage .strip .stages li.done{border-top-color:var(--ink-soft);}
1254
+ #view-mine .strip .stages li.done .sdot,#view-manage .strip .stages li.done .sdot{background:var(--ink-soft);border-color:var(--ink-soft);}
1255
+ #view-mine .strip .stages li.done .slbl,#view-manage .strip .stages li.done .slbl{color:var(--ink-soft);}
1256
+ #view-mine .strip .stages li.now,#view-manage .strip .stages li.now{border-top-color:var(--accent);}
1257
+ #view-mine .strip .stages li.now .sdot,#view-manage .strip .stages li.now .sdot{background:var(--accent);border-color:var(--accent);outline:4px solid color-mix(in srgb,var(--accent) 22%,transparent);}
1258
+ #view-mine .strip .stages li.now .slbl,#view-manage .strip .stages li.now .slbl{color:var(--ink);}
1259
+ #view-mine .strip.isLive .stages li.done,#view-manage .strip.isLive .stages li.done{border-top-color:var(--ok);}
1260
+ #view-mine .strip.isLive .stages li.done .sdot,#view-manage .strip.isLive .stages li.done .sdot{background:var(--ok);border-color:var(--ok);}
1261
+ #view-mine .strip.isLive .stages li.done .slbl,#view-manage .strip.isLive .stages li.done .slbl{color:var(--ok);}
1262
+ #view-mine .strip.flowDown .stages li.now,#view-manage .strip.flowDown .stages li.now{border-top-color:var(--ink-soft);}
1263
+ #view-mine .strip.flowDown .stages li.now .sdot,#view-manage .strip.flowDown .stages li.now .sdot{background:var(--ink-soft);border-color:var(--ink-soft);outline:none;}
1264
+ #view-mine .strip.flowDown .stages li.now .slbl,#view-manage .strip.flowDown .stages li.now .slbl{color:var(--ink-soft);}
1265
+ #view-mine .strip .pnote,#view-manage .strip .pnote{text-align:left;font-size:13px;font-weight:400;line-height:1.45;color:var(--ink-soft);margin:8px 0 0;min-height:0;}
1266
+ #view-mine .strip.isLive .pnote,#view-manage .strip.isLive .pnote{color:var(--ok);}
1267
+
1268
+ /* ── the doors: hairline pills, lowercase; the accent only on the one that
1269
+ acts (the plain .btn.small: try again, bring it back, restart, save); the
1270
+ ender on the error ink; no lift, no shadow ── */
1271
+ #view-mine .actions,#view-manage .actions{gap:8px;margin:0;}
1272
+ #view-mine .actions{justify-content:flex-end;}
1273
+ #view-mine .btn,#view-manage .btn{min-height:44px;padding:0 22px;font-family:var(--font-body);font-weight:500;font-size:15px;text-transform:lowercase;white-space:nowrap;box-shadow:none;transition:border-color .15s ease,background .15s ease;}
1274
+ #view-mine .btn:hover,#view-manage .btn:hover{transform:none;box-shadow:none;}
1275
+ #view-mine .btn:active,#view-manage .btn:active{transform:none;}
1276
+ #view-mine .btn.small,#view-manage .btn.small{min-height:40px;padding:0 18px;font-weight:400;font-size:14.5px;color:var(--ink);background:none;border:1px solid var(--rule);}
1277
+ #view-mine .btn.small:hover,#view-manage .btn.small:hover{border-color:var(--ink-faint);color:var(--ink);}
1278
+ #view-mine .btn.small:not(.ghost):not(.danger),#view-manage .btn.small:not(.ghost):not(.danger){background:var(--accent);border-color:var(--accent);color:var(--accent-on);font-weight:500;}
1279
+ #view-mine .btn.small:not(.ghost):not(.danger):hover,#view-manage .btn.small:not(.ghost):not(.danger):hover{background:color-mix(in srgb,var(--accent) 88%,var(--ink));border-color:color-mix(in srgb,var(--accent) 88%,var(--ink));color:var(--accent-on);}
1280
+ #view-mine .btn.small.danger,#view-manage .btn.small.danger{border-color:color-mix(in srgb,var(--err) 45%,transparent);color:var(--err);}
1281
+ #view-mine .btn.small.danger:hover,#view-manage .btn.small.danger:hover{background:none;border-color:var(--err);color:var(--err);}
1282
+ #view-mine .btn.small:disabled,#view-manage .btn.small:disabled{background:none;border-color:var(--rule-soft);color:var(--ink-faint);}
1283
+ /* the fold's field and the ender's typed-back name: a hairline field */
1284
+ #view-mine .attach,#view-manage .attach{gap:10px 14px;margin-top:12px;align-items:center;}
1285
+ #view-mine .attach input[type=text],#view-manage .attach input[type=text]{min-width:220px;min-height:40px;font-family:var(--font-body);font-size:15.5px;font-weight:400;color:var(--ink);background:none;border:0;border-bottom:1px solid var(--rule);border-radius:0;padding:8px 0;}
1286
+ #view-mine .attach input[type=text]::placeholder,#view-manage .attach input[type=text]::placeholder{font-weight:400;}
1287
+ #view-mine .attach input[type=text]:focus,#view-manage .attach input[type=text]:focus{border-bottom-color:var(--ink);box-shadow:none;}
1288
+ #view-mine .confirmRow,#view-manage .confirmRow{font-weight:400;}
1289
+ #view-mine .confirmRow .plain,#view-manage .confirmRow .plain{font-weight:400;font-size:14.5px;line-height:1.5;}
1290
+
1291
+ /* ── the empty state: a band of the Projects band's grammar, one door ── */
1292
+ #view-mine .empty{display:grid;gap:14px;justify-items:start;text-align:left;background:var(--bg-card);border:0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);border-radius:0;padding:58px var(--gutter) 62px;}
1293
+ #view-mine .empty h2{font-family:var(--font-display);font-weight:300;font-size:clamp(30px,4vw,48px);letter-spacing:-.035em;line-height:1.02;text-transform:lowercase;color:var(--ink);margin:0;max-width:16ch;}
1294
+ #view-mine .empty p{margin:0 0 8px;font-size:16px;font-weight:400;line-height:1.5;color:var(--ink-soft);max-width:52ch;}
1295
+
1296
+ /* ── the manage page: the back link in the label face; the head with the
1297
+ planet, the name in the display voice and its chip; the ledger of facts on
1298
+ hairlines; the settings as hairline sections, the title and its clause
1299
+ left, the choice as hairline cells right ── */
1300
+ #view-manage .backRow{margin:26px 0 0;font-family:var(--label-face);font-size:var(--label-size);letter-spacing:var(--label-space);text-transform:uppercase;font-weight:400;}
1301
+ #view-manage .backRow a{color:var(--ink-faint);}
1302
+ #view-manage .backRow a:hover{color:var(--ink);}
1303
+ #view-manage .mHead{display:flex;align-items:center;gap:26px;padding-top:22px;padding-bottom:8px;}
1304
+ #view-manage .mHead .titleRow{display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;}
1305
+ #view-manage #mOrb:empty{display:none;}
1306
+ #view-manage #mOrb .worldOrb{--orb-scale:1.5;}
1307
+ /* the page's clause belongs to a project that rendered — the signed-out and
1308
+ not-found states keep the heading and drop the clause */
1309
+ #view-manage .mHead:has(~ #mMain[hidden]) .lede{display:none;}
1310
+ #view-manage .ledger{display:grid;grid-template-columns:172px 1fr;gap:0 22px;margin:14px 0 0;}
1311
+ #view-manage .ledger>*:not([hidden]){display:contents;}
1312
+ #view-manage .ledger .k,#view-manage .ledger .v{border-top:1px solid var(--rule-soft);padding:13px 0;min-width:0;}
1313
+ #view-manage .ledger .k{font-family:var(--label-face);font-size:var(--label-size);letter-spacing:var(--label-space);text-transform:uppercase;color:var(--ink-faint);padding-top:16px;}
1314
+ #view-manage .ledger .v{font-size:15px;line-height:1.5;color:var(--ink);overflow-wrap:anywhere;}
1315
+ #view-manage .ledger .v code{font-family:var(--font-mono);font-size:13.5px;color:var(--ink-soft);background:none;border-radius:0;padding:0;}
1316
+ #view-manage .ledger .v small{display:block;font-size:13px;color:var(--ink-soft);}
1317
+ #view-manage .ledger .v .none{color:var(--ink-faint);font-style:normal;}
1318
+ #view-manage .swDot{display:inline-block;width:11px;height:11px;border-radius:50%;background:var(--sw);border:1px solid var(--rule);vertical-align:-1px;margin-right:8px;}
1319
+ #view-manage #mStrip{max-width:520px;margin:22px 0 0;}
1320
+ #view-manage #mFacts .projMsg{font-weight:400;}
1321
+ #view-manage #mActs{justify-content:flex-start;margin-top:22px;}
1322
+ #view-manage #mFacts{padding-bottom:34px;}
1323
+ #view-manage .mSec{display:grid;grid-template-columns:minmax(200px,300px) 1fr;grid-template-rows:auto 1fr;gap:6px 40px;border-top:1px solid var(--rule);padding:30px 0 34px;}
1324
+ #view-manage .mSec h2{grid-column:1;grid-row:1;font-family:var(--font-display);font-weight:300;font-size:clamp(22px,2.4vw,28px);letter-spacing:-.03em;line-height:1.08;text-transform:lowercase;color:var(--ink);margin:0;}
1325
+ #view-manage .mSec>details{grid-column:1;grid-row:2;align-self:start;margin:0;max-width:34ch;color:var(--ink-faint);}
1326
+ #view-manage .mSec>details summary{cursor:pointer;display:inline-flex;align-items:center;min-height:24px;color:var(--ink-soft);}
1327
+ #view-manage .mSec>details summary:hover{color:var(--ink);}
1328
+ #view-manage .mSec>details p{margin-top:8px;}
1329
+ #view-manage .mSec>div{grid-column:2;grid-row:1/span 2;display:grid;gap:16px;align-content:start;min-width:0;}
1330
+ #view-manage .mSec .addr,#view-manage .mSec .plain{margin:0;font-size:15px;font-weight:400;line-height:1.5;color:var(--ink-soft);}
1331
+ #view-manage .mSec .addr b{color:var(--ink);font-weight:500;}
1332
+ #view-manage .mSec .finePrint{margin:0;}
1333
+ #view-manage .mSec .projMsg{margin:0;min-height:0;font-weight:400;}
1334
+ #view-manage .mSec .projMsg:not(:empty){margin-top:2px;}
1335
+ /* a choice: hairline-separated cells; the chosen one carries the dot and the ink */
1336
+ #view-manage [role="radiogroup"]{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);}
1337
+ #view-manage .visOpt{position:relative;display:block;margin:0;padding:16px 18px 18px;border:0;border-left:1px solid var(--rule-soft);border-radius:0;cursor:pointer;}
1338
+ #view-manage .visOpt:first-child{border-left:0;padding-left:0;}
1339
+ #view-manage .visOpt input{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip-path:inset(50%);}
1340
+ #view-manage .visOpt>span{display:block;font-size:13px;line-height:1.45;color:var(--ink-faint);}
1341
+ #view-manage .visOpt b{display:flex;align-items:center;gap:10px;margin-bottom:6px;font-family:var(--font-body);font-weight:500;font-size:15px;color:var(--ink);}
1342
+ #view-manage .visOpt b::before{content:"";width:7px;height:7px;border-radius:50%;border:1px solid var(--rule);background:var(--bg);flex:none;}
1343
+ #view-manage .visOpt:has(input:checked) b::before{background:var(--accent);border-color:var(--accent);outline:4px solid color-mix(in srgb,var(--accent) 22%,transparent);}
1344
+ #view-manage .visOpt:focus-within{outline:2px solid var(--accent);outline-offset:3px;}
1345
+ #view-manage #mVisRuns b,#view-manage #mJoinRuns b{color:var(--ok);font-weight:500;}
1346
+
1347
+ /* this block stays HERE, after the rules it narrows: a same-specificity mobile
1348
+ override only wins by source order, so folding it into the hub's earlier
1349
+ 900px block would put every stack rule before the grid it undoes */
1350
+ @media (max-width:900px){
1351
+ /* the row stacks: planet and name, then the facts, the rail and the doors —
1352
+ the body dissolves into the row's grid (display:contents) so the planet
1353
+ sits beside the name alone */
1354
+ #view-mine .proj{grid-template-columns:56px minmax(0,1fr);gap:0 16px;padding:20px 0;}
1355
+ #view-mine .proj .worldOrb{--orb-scale:.875;grid-column:1;grid-row:1;}
1356
+ #view-mine .projBody{display:contents;}
1357
+ #view-mine .projHead{grid-area:auto;grid-column:2;grid-row:1;}
1358
+ #view-mine .projMeta,#view-mine .addr,#view-mine .strip,#view-mine .actions,#view-mine .projBody>.projMsg,#view-mine .projBody>.attachFold{grid-area:auto;grid-column:1/-1;}
1359
+ #view-mine .projMeta{margin-top:14px;}
1360
+ #view-mine .strip{margin-top:16px;}
1361
+ #view-mine .actions{margin-top:16px;justify-content:flex-start;flex-direction:row;align-items:center;}
1362
+ #view-manage .mHead{flex-wrap:wrap;gap:14px;}
1363
+ #view-manage .ledger{grid-template-columns:1fr;}
1364
+ #view-manage .ledger .k{padding-bottom:0;}
1365
+ #view-manage .ledger .v{border-top:0;padding-top:6px;}
1366
+ #view-manage .mSec{grid-template-columns:1fr;grid-template-rows:auto;gap:14px;}
1367
+ #view-manage .mSec h2,#view-manage .mSec>details,#view-manage .mSec>div{grid-column:1;grid-row:auto;}
1368
+ #view-manage [role="radiogroup"]{grid-template-columns:1fr;}
1369
+ #view-manage .visOpt{border-left:0;padding-left:0;border-top:1px solid var(--rule-soft);}
1370
+ #view-manage .visOpt:first-child{border-top:0;}
1371
+ }
1166
1372
  @media (prefers-reduced-motion:reduce){
1167
1373
  *,*::before,*::after{animation:none !important;transition:none !important;}
1168
1374
  }
@@ -0,0 +1,49 @@
1
+ {
2
+ "_": "The mine view with no projects (task 1003345): the same page, the same stub, one fixture aliased to the empty list. Rendered by name: node modules/ui-design/kit/render.js --states public-landing/projects-empty.states.json",
3
+ "page": "/projects",
4
+ "surface": "public-landing",
5
+ "modes": [
6
+ "dark"
7
+ ],
8
+ "modeQuery": false,
9
+ "stub": {
10
+ "fixtures": {
11
+ "provisioning-instances": "provisioning-instances-empty"
12
+ }
13
+ },
14
+ "ignoreRequests": [
15
+ "/api/(gds|bongos)/me$",
16
+ "/my-projects"
17
+ ],
18
+ "ignoreConsole": [
19
+ "/api/(gds|bongos)/me",
20
+ "\\b401\\b",
21
+ "Unauthorized"
22
+ ],
23
+ "ignoreControls": [
24
+ ".skip",
25
+ ".vh"
26
+ ],
27
+ "states": {
28
+ "in-mine-empty": {
29
+ "auth": true,
30
+ "url": "/projects?view=mine",
31
+ "expect": {
32
+ "visible": [
33
+ "#empty",
34
+ "#empty a[data-nav-to=\"new\"]"
35
+ ],
36
+ "hidden": [
37
+ "#mineBar",
38
+ "#qWrap"
39
+ ],
40
+ "count": [
41
+ [
42
+ "#projectsList .proj",
43
+ 0
44
+ ]
45
+ ]
46
+ }
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,63 @@
1
+ {
2
+ "_": "The all-null floor card (task 1003301) on the hub's own catalog (task 1003345): the same page, the same stub, the catalog aliased to featured-hub.json — the landing's three plus Tidewater, a null row nobody owns. Demo, the landing catalog's floor row, is owned by the signed-in stub, and an owned orb's plain click opens its manage view, never its card. Rendered by name: node modules/ui-design/kit/render.js --states public-landing/projects-floor.states.json",
3
+ "page": "/projects",
4
+ "surface": "public-landing",
5
+ "modes": [
6
+ "dark"
7
+ ],
8
+ "modeQuery": false,
9
+ "stub": {
10
+ "fixtures": {
11
+ "featured": "featured-hub"
12
+ }
13
+ },
14
+ "ignoreRequests": [
15
+ "/api/(gds|bongos)/me$",
16
+ "/my-projects",
17
+ "/provisioning/instances/999",
18
+ "/provisioning/instances/101$",
19
+ "/api/gds/instance$"
20
+ ],
21
+ "ignoreConsole": [
22
+ "/api/(gds|bongos)/me",
23
+ "\\b401\\b",
24
+ "\\b404\\b",
25
+ "Unauthorized"
26
+ ],
27
+ "ignoreControls": [
28
+ ".skip",
29
+ ".vh"
30
+ ],
31
+ "states": {
32
+ "card-floor": {
33
+ "auth": true,
34
+ "actions": [
35
+ [
36
+ "dispatchClick",
37
+ "#orbField a.worldOrb[data-origin=\"https://tidewater.cloudbongos.com\"]"
38
+ ],
39
+ [
40
+ "wait",
41
+ 600
42
+ ]
43
+ ],
44
+ "expect": {
45
+ "dialog": true,
46
+ "hidden": [
47
+ "#cardArt",
48
+ "#cardFaces",
49
+ "#cardFigs",
50
+ "#cardHall",
51
+ "#cardRel",
52
+ "#cardTypeL",
53
+ "#cardOwnerL"
54
+ ],
55
+ "visible": [
56
+ "#cardOpen",
57
+ "#cardRuns",
58
+ "#cardListed"
59
+ ]
60
+ }
61
+ }
62
+ }
63
+ }