@viberaven/cli 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2836 -241
- package/dist/cli.js.map +2 -2
- package/dist/manga/bg.webp +0 -0
- package/dist/manga/cards/authjs.webp +0 -0
- package/dist/manga/cards/clerk.webp +0 -0
- package/dist/manga/cards/github.webp +0 -0
- package/dist/manga/cards/posthog.webp +0 -0
- package/dist/manga/cards/resend.webp +0 -0
- package/dist/manga/cards/sentry.webp +0 -0
- package/dist/manga/cards/stripe.webp +0 -0
- package/dist/manga/cards/supabase.webp +0 -0
- package/dist/manga/cards/upstash.webp +0 -0
- package/dist/manga/cards/vercel.webp +0 -0
- package/dist/manga/emblem.png +0 -0
- package/dist/manga/favicon-128.png +0 -0
- package/dist/manga/favicon-180.png +0 -0
- package/dist/manga/favicon.png +0 -0
- package/dist/manga/poster.webp +0 -0
- package/dist/manga/raven-mark.png +0 -0
- package/dist/playbooks/stripe.json +17 -17
- package/dist/vendor/anime.umd.min.js +7 -0
- package/package.json +1 -1
- package/playbooks/stripe.json +17 -17
package/dist/cli.js
CHANGED
|
@@ -11558,7 +11558,7 @@ var VERSION;
|
|
|
11558
11558
|
var init_version = __esm({
|
|
11559
11559
|
"src/version.ts"() {
|
|
11560
11560
|
"use strict";
|
|
11561
|
-
VERSION = "1.4.
|
|
11561
|
+
VERSION = "1.4.2";
|
|
11562
11562
|
}
|
|
11563
11563
|
});
|
|
11564
11564
|
|
|
@@ -14872,6 +14872,8 @@ var init_providerLogos = __esm({
|
|
|
14872
14872
|
aws: '<svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" aria-hidden="true"><path fill="#FF9900" d="M6.763 10.582c4.95-2.283 10.563-2.283 15.475 0 .532.243.848.741.848 1.256 0 .532-.323 1.026-.85 1.256-4.912 2.283-10.525 2.283-15.474 0-.528-.23-.851-.724-.851-.279 0-.544.098-.754.243-4.95 2.283-10.563 2.283-15.475 0-.532-.243-.848-.741-.848-1.256 0-.532.323-1.026.85-1.256.228-.098.492-.196.754-.196.279 0 .544.098.754.243Z"/><path fill="#FF9900" d="M12 3.65c-2.772 0-5.027 1.147-5.027 2.553S9.228 8.756 12 8.756s5.027-1.147 5.027-2.553S14.772 3.65 12 3.65Z"/></svg>',
|
|
14873
14873
|
sentry: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3 22 20H2L12 3Zm0 5.1L6.8 17h2.1l3.1-5.3 3.1 5.3h2.1L12 8.1Z"/></svg>',
|
|
14874
14874
|
posthog: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#1D4AFF" d="M5.2 6.1h8.2c3 0 5.3 2 5.3 5.1 0 3.2-2.3 5.2-5.3 5.2H5.2V6.1Z"/><path fill="#F54E00" d="M4.1 4h4.2a2.35 2.35 0 0 1 0 4.7H4.1V4Z"/><circle cx="13.7" cy="11.75" r="1.1" fill="#F9BD2B"/><path fill="#F54E00" d="m16.5 9.35 2-1.15.85 1.3-2.15 1.3-.7-1.45Zm.38 4.78 2.42.86-.78 1.6-2.4-1.02.76-1.44Z"/></svg>',
|
|
14875
|
+
resend: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#FFFFFF" d="M14.679 0c4.648 0 7.413 2.765 7.413 6.434s-2.765 6.434-7.413 6.434H12.33L24 24h-8.245l-8.88-8.44c-.636-.588-.93-1.273-.93-1.86 0-.831.587-1.565 1.713-1.883l4.574-1.224c1.737-.465 2.936-1.81 2.936-3.572 0-2.153-1.761-3.4-3.939-3.4H0V0z"/></svg>',
|
|
14876
|
+
upstash: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#00E9A3" d="M13.8027 0C11.193 0 8.583.9952 6.5918 2.9863c-3.9823 3.9823-3.9823 10.4396 0 14.4219 1.9911 1.9911 5.2198 1.9911 7.211 0 1.991-1.9911 1.991-5.2198 0-7.211L12 12c.9956.9956.9956 2.6098 0 3.6055-.9956.9955-2.6099.9955-3.6055 0-2.9866-2.9868-2.9866-7.8297 0-10.8164 2.9868-2.9868 7.8297-2.9868 10.8164 0l1.8028-1.8028C19.0225.9952 16.4125 0 13.8027 0zM12 12c-.9956-.9956-.9956-2.6098 0-3.6055.9956-.9955 2.6098-.9955 3.6055 0 2.9867 2.9868 2.9867 7.8297 0 10.8164-2.9867 2.9868-7.8297 2.9868-10.8164 0l-1.8028 1.8028c3.9823 3.9822 10.4396 3.9822 14.4219 0 3.9823-3.9824 3.9823-10.4396 0-14.4219-.9956-.9956-2.3006-1.4922-3.6055-1.4922-1.3048 0-2.6099.4966-3.6054 1.4922-1.9912 1.9912-1.9912 5.2198 0 7.211z"/></svg>',
|
|
14875
14877
|
playwright: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#2EAD33" d="M8.4 8.2 5.4 17.2h2.3l.8-2.8h2.7l.8 2.8h2.3L11.6 8.2H8.4Zm1.1 4.8.8-2.4.8 2.4H9.5Z"/><path fill="#E2574C" d="M15.6 8.2 12.6 17.2h2.3l.8-2.8h2.7l.8 2.8h2.3L18.8 8.2h-3.2Zm1.1 4.8.8-2.4.8 2.4h-1.6Z"/><ellipse fill="#2EAD33" cx="9.5" cy="13.1" rx="1.1" ry="1.4"/><ellipse fill="#E2574C" cx="16.5" cy="13.1" rx="1.1" ry="1.4"/></svg>',
|
|
14876
14878
|
logrocket: '<svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" aria-hidden="true"><rect x="2" y="2" width="20" height="20" rx="5" fill="#764ABC"/><path fill="#FFFFFF" d="M12 7.4c2.7 0 4.9 2.2 4.9 4.9s-2.2 4.9-4.9 4.9-4.9-2.2-4.9-4.9 4.9-4.9 4.9-4.9Zm0 1.9a3 3 0 1 0 0 6 3 3 0 0 0 0-6Zm-3.2 7.4h6.4v1.5H8.8v-1.5Z"/></svg>',
|
|
14877
14879
|
figma: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8.5 3h3.5v6H8.5a3 3 0 1 1 0-6Zm3.5 6h3.5a3 3 0 1 0 0-6H12v6Zm0 0h3.5a3 3 0 1 1 0 6H12V9Zm-3.5 0H12v6H8.5a3 3 0 1 1 0-6ZM8.5 15H12v2.5A3.5 3.5 0 1 1 8.5 15Z"/></svg>',
|
|
@@ -16029,10 +16031,10 @@ const providerMarkAssets = {
|
|
|
16029
16031
|
};
|
|
16030
16032
|
|
|
16031
16033
|
const mascotAssets = {
|
|
16032
|
-
idle: '/
|
|
16033
|
-
fixing: '/
|
|
16034
|
-
verified: '/
|
|
16035
|
-
alert: '/
|
|
16034
|
+
idle: '/manga/raven-mark.png?v=manga1',
|
|
16035
|
+
fixing: '/manga/raven-mark.png?v=manga1',
|
|
16036
|
+
verified: '/manga/raven-mark.png?v=manga1',
|
|
16037
|
+
alert: '/manga/raven-mark.png?v=manga1',
|
|
16036
16038
|
};
|
|
16037
16039
|
|
|
16038
16040
|
const providerDashboardUrls = {
|
|
@@ -16268,10 +16270,22 @@ function providerAssetSrc(provider) {
|
|
|
16268
16270
|
return providerMarkAssets[provider.id] || providerAssets[provider.id] || providerAssets.supabase;
|
|
16269
16271
|
}
|
|
16270
16272
|
|
|
16273
|
+
function providerIconMarkup(provider) {
|
|
16274
|
+
const iconHtml = provider && provider.iconHtml ? String(provider.iconHtml) : '';
|
|
16275
|
+
if (iconHtml.trim()) return iconHtml;
|
|
16276
|
+
// Fallback must still be the PROVIDER icon, never the raven card-art. Build the real logo
|
|
16277
|
+
// from the provider id so a cold/offline boot shows Supabase/Vercel/etc, not a generic raven.
|
|
16278
|
+
const id = provider && provider.id ? String(provider.id).toLowerCase().replace(/[^a-z0-9]/g, '') : '';
|
|
16279
|
+
if (id) {
|
|
16280
|
+
const color = String(areaEnergy(provider.area) || '#e8c15a').replace('#', '');
|
|
16281
|
+
return '<img class="provider-logo__img" src="https://cdn.simpleicons.org/' + id + '/' + color + '" alt="" decoding="async" data-provider-logo-key="' + id + '" />';
|
|
16282
|
+
}
|
|
16283
|
+
return '<img src="' + providerAssetSrc(provider) + '" alt="" />';
|
|
16284
|
+
}
|
|
16285
|
+
|
|
16271
16286
|
function ProviderToken(provider, extraClass) {
|
|
16272
16287
|
const className = 'vr-provider-token' + (extraClass ? ' ' + extraClass : '');
|
|
16273
|
-
|
|
16274
|
-
return '<span class="' + className + '">' + (iconHtml.trim() ? iconHtml : '<img src="' + providerAssetSrc(provider) + '" alt="" />') + '</span>';
|
|
16288
|
+
return '<span class="' + className + '">' + providerIconMarkup(provider) + '</span>';
|
|
16275
16289
|
}
|
|
16276
16290
|
|
|
16277
16291
|
function areaEnergy(area) {
|
|
@@ -16294,26 +16308,53 @@ function gradeMark(tier) {
|
|
|
16294
16308
|
return '●';
|
|
16295
16309
|
}
|
|
16296
16310
|
|
|
16311
|
+
// Full manga card art (shipped in assets/manga/cards). Providers with baked
|
|
16312
|
+
// art render the image as the whole face + a holographic foil overlay; the
|
|
16313
|
+
// rest fall back to the CSS-built card anatomy below.
|
|
16314
|
+
const MANGA_CARD_ARTS = { supabase: 1, vercel: 1, github: 1, posthog: 1, stripe: 1, resend: 1, sentry: 1, upstash: 1, clerk: 1, authjs: 1 };
|
|
16315
|
+
function cardArtSrc(provider) {
|
|
16316
|
+
const id = provider && provider.id ? String(provider.id).toLowerCase().replace(/[^a-z0-9]/g, '') : '';
|
|
16317
|
+
// ?v bump busts stale browser cache when a card art is redrawn
|
|
16318
|
+
return MANGA_CARD_ARTS[id] ? '/manga/cards/' + id + '.webp?v=5' : '';
|
|
16319
|
+
}
|
|
16320
|
+
|
|
16297
16321
|
function TradingCard(provider, variant, options) {
|
|
16298
16322
|
const opts = options || {};
|
|
16299
16323
|
const size = variant === 'dealt' ? 'is-dealt' : variant === 'map' ? 'is-map' : 'is-hand';
|
|
16300
16324
|
const grade = provider.grade || { value: null, tier: 'facedown', label: 'FACE DOWN' };
|
|
16301
16325
|
const foil = escapeHtml(provider.id);
|
|
16302
16326
|
const placedClass = opts.placed ? ' is-placed' : '';
|
|
16327
|
+
const tagOpen = opts.asDiv ? 'div' : 'button type="button"';
|
|
16328
|
+
const tagClose = opts.asDiv ? 'div' : 'button';
|
|
16303
16329
|
if (grade.tier === 'facedown' && !opts.forceFace) {
|
|
16304
|
-
return '<' +
|
|
16330
|
+
return '<' + tagOpen + ' class="vr-tcard is-back ' + size + placedClass + '"' +
|
|
16305
16331
|
(opts.asDiv ? '' : ' data-action="deal-provider" data-provider="' + foil + '" aria-label="Flip ' + escapeHtml(provider.name) + ' \u2014 run its first checks" title="' + escapeHtml(provider.name) + ' \xB7 face down \u2014 click to flip"') +
|
|
16306
16332
|
(opts.style ? ' style="' + opts.style + '"' : '') + '>' +
|
|
16307
16333
|
'<span class="vr-tcard-backart"><img src="' + mascotAssets.idle + '" alt="" /></span>' +
|
|
16308
16334
|
'<span class="vr-tcard-backname">' + escapeHtml(provider.name) + '</span>' +
|
|
16309
|
-
'</' +
|
|
16335
|
+
'</' + tagClose + '>';
|
|
16310
16336
|
}
|
|
16311
16337
|
const flawless = grade.tier === 'flawless';
|
|
16312
|
-
|
|
16338
|
+
const artSrc = cardArtSrc(provider);
|
|
16339
|
+
if (artSrc) {
|
|
16340
|
+
// full-art face: the image IS the card; holo foil + glare ride on top,
|
|
16341
|
+
// grade chip and RAVEN GRADE strip overlay the corners.
|
|
16342
|
+
return '<' + tagOpen + ' class="vr-tcard has-art ' + size + placedClass + (flawless ? ' is-flawless' : '') + '" data-foil="' + foil + '"' +
|
|
16343
|
+
(opts.asDiv ? '' : ' data-action="deal-provider" data-provider="' + foil + '" aria-label="Deal ' + escapeHtml(provider.name) + ' \u2014 checks run instantly in chat" title="' + escapeHtml(provider.name) + ' \xB7 ' + escapeHtml(grade.label) + '"') +
|
|
16344
|
+
(opts.style ? ' style="' + opts.style + '"' : '') + '>' +
|
|
16345
|
+
'<img class="vr-tcard-artfull" src="' + artSrc + '" alt="' + escapeHtml(provider.name) + '" draggable="false" />' +
|
|
16346
|
+
'<span class="vr-tcard-holofoil" aria-hidden="true"></span>' +
|
|
16347
|
+
'<span class="vr-tcard-glare" aria-hidden="true"></span>' +
|
|
16348
|
+
(opts.placed ? '<span class="vr-tcard-unplace" data-action="unplace-card" data-unplace="' + foil + '" title="Remove from the table" role="button" aria-label="Remove from the table">✕</span>' : '') +
|
|
16349
|
+
'<span class="vr-tcard-hp is-onart"><span class="vr-tcard-energy" style="--vr-energy:' + areaEnergy(provider.area) + '"></span><i>' + (grade.value == null ? '?' : grade.value) + '</i></span>' +
|
|
16350
|
+
'<span class="vr-tcard-gradebar">' + (flawless ? '✶ ' : '') + 'RAVEN GRADE · ' + escapeHtml(grade.label) + '</span>' +
|
|
16351
|
+
'</' + tagClose + '>';
|
|
16352
|
+
}
|
|
16353
|
+
return '<' + tagOpen + ' class="vr-tcard ' + size + placedClass + (flawless ? ' is-flawless' : '') + '" data-foil="' + foil + '"' +
|
|
16313
16354
|
(opts.asDiv ? '' : ' data-action="deal-provider" data-provider="' + foil + '" aria-label="Deal ' + escapeHtml(provider.name) + ' \u2014 checks run instantly in chat" title="' + escapeHtml(provider.name) + ' \xB7 ' + escapeHtml(grade.label) + '"') +
|
|
16314
16355
|
(opts.style ? ' style="' + opts.style + '"' : '') + '>' +
|
|
16315
16356
|
'<span class="vr-tcard-sheen" aria-hidden="true"></span>' +
|
|
16316
|
-
(opts.placed ? '<span class="vr-tcard-unplace" data-action="unplace-card" data-unplace="' + foil + '" title="
|
|
16357
|
+
(opts.placed ? '<span class="vr-tcard-unplace" data-action="unplace-card" data-unplace="' + foil + '" title="Remove from the table" role="button" aria-label="Remove from the table">✕</span>' : '') +
|
|
16317
16358
|
'<span class="vr-tcard-inner">' +
|
|
16318
16359
|
'<span class="vr-tcard-head"><b>' + escapeHtml(provider.name) + '</b><span class="vr-tcard-hp"><span class="vr-tcard-energy" style="--vr-energy:' + areaEnergy(provider.area) + '" title="' + escapeHtml(String(provider.area || '')) + '"></span><i>' + (grade.value == null ? '?' : grade.value) + '</i></span></span>' +
|
|
16319
16360
|
'<span class="vr-tcard-artwin"><span class="vr-tcard-holo" aria-hidden="true"></span>' + ProviderToken(provider, 'is-tcard') + '</span>' +
|
|
@@ -16426,6 +16467,15 @@ function dealProviderCard(providerId) {
|
|
|
16426
16467
|
chat.messages.push(message);
|
|
16427
16468
|
demo.notice = provider.name + ' dealt into chat \u2014 checks running.';
|
|
16428
16469
|
render({ scrollToBottom: chatIndex });
|
|
16470
|
+
const dealtAt = Date.now();
|
|
16471
|
+
window.requestAnimationFrame(animateDealtCardIntoChat);
|
|
16472
|
+
// The local check returns almost instantly; hold the results render until the
|
|
16473
|
+
// deal animation has played, so it is actually visible (otherwise the full
|
|
16474
|
+
// re-render replaces the animating card before you see it).
|
|
16475
|
+
const renderAfterDeal = () => {
|
|
16476
|
+
const wait = Math.max(0, 720 - (Date.now() - dealtAt));
|
|
16477
|
+
window.setTimeout(() => render(), wait);
|
|
16478
|
+
};
|
|
16429
16479
|
fetch('/api/provider-check', {
|
|
16430
16480
|
method: 'POST',
|
|
16431
16481
|
headers: { 'content-type': 'application/json' },
|
|
@@ -16441,12 +16491,12 @@ function dealProviderCard(providerId) {
|
|
|
16441
16491
|
message.done = true;
|
|
16442
16492
|
const idx = providers.findIndex((item) => item.id === providerId);
|
|
16443
16493
|
if (idx >= 0 && payload.provider) providers[idx] = normalizeProvider(payload.provider);
|
|
16444
|
-
|
|
16494
|
+
renderAfterDeal();
|
|
16445
16495
|
})
|
|
16446
16496
|
.catch(() => {
|
|
16447
16497
|
message.error = 'Could not reach the local server \u2014 is the Studio still running?';
|
|
16448
16498
|
message.done = true;
|
|
16449
|
-
|
|
16499
|
+
renderAfterDeal();
|
|
16450
16500
|
});
|
|
16451
16501
|
}
|
|
16452
16502
|
|
|
@@ -17501,6 +17551,17 @@ function runChatTask(kind, promptOverride) {
|
|
|
17501
17551
|
clearChatTaskTimer();
|
|
17502
17552
|
const chatIndex = Math.max(0, Math.min(demo.pickerChatIndex || 0, demo.activeChatCount - 1));
|
|
17503
17553
|
const chat = chatContext(chatIndex);
|
|
17554
|
+
// Product contract: installed is NOT enough \u2014 force Test connection before
|
|
17555
|
+
// real agent control. If the selected CLI has not passed a connection probe,
|
|
17556
|
+
// route to the Terminal setup instead of spawning it.
|
|
17557
|
+
if (chat.cliId && chat.cliId !== 'terminal' && !cliAgentReady(chat.cliId)) {
|
|
17558
|
+
const agentLabel = (cliAgents.find((item) => item.id === chat.cliId)?.label) || chat.cliId;
|
|
17559
|
+
demo.pickerChatIndex = chatIndex;
|
|
17560
|
+
demo.notice = 'Connect ' + agentLabel + ' first \u2014 run Test connection in the Terminal tab, then send your mission.';
|
|
17561
|
+
selectTerminalCli(chat.cliId);
|
|
17562
|
+
render();
|
|
17563
|
+
return;
|
|
17564
|
+
}
|
|
17504
17565
|
const mission = resolveQuickActionMission(kind, chatIndex, promptOverride);
|
|
17505
17566
|
const meta = taskMeta(kind, chatIndex);
|
|
17506
17567
|
const attachedProviderId = chat.providerId || null;
|
|
@@ -17531,6 +17592,7 @@ function runChatTask(kind, promptOverride) {
|
|
|
17531
17592
|
error: '',
|
|
17532
17593
|
providerId: taskProviderId,
|
|
17533
17594
|
releaseId: taskReleaseId,
|
|
17595
|
+
startedAt: Date.now(),
|
|
17534
17596
|
};
|
|
17535
17597
|
if (chatIndex === 0) rememberRecentChat(label, provider, release, chat);
|
|
17536
17598
|
chat.providerId = null;
|
|
@@ -17541,6 +17603,7 @@ function runChatTask(kind, promptOverride) {
|
|
|
17541
17603
|
demo.activeStepId = kind === 'verify' ? 'verify' : kind === 'provider' ? 'provider' : 'agent';
|
|
17542
17604
|
demo.notice = meta.notice;
|
|
17543
17605
|
render({ scrollToBottom: chatIndex });
|
|
17606
|
+
startTaskElapsedTimer();
|
|
17544
17607
|
const finish = (message, isError, cardsPayload) => {
|
|
17545
17608
|
const taskContext = chat.activeTask || {};
|
|
17546
17609
|
const responseText = isError
|
|
@@ -18229,10 +18292,20 @@ function QuickstartModal() {
|
|
|
18229
18292
|
|
|
18230
18293
|
function DiscoveryModal() {
|
|
18231
18294
|
const found = providers.filter((provider) => provider.state !== 'not_detected');
|
|
18232
|
-
const
|
|
18233
|
-
const
|
|
18295
|
+
const hashRank = (id) => { let h = 0; for (let i = 0; i < id.length; i += 1) h = (h * 31 + id.charCodeAt(i)) >>> 0; return h; };
|
|
18296
|
+
const rankFor = (provider) => {
|
|
18234
18297
|
const tier = provider.grade ? provider.grade.tier : 'review';
|
|
18235
|
-
|
|
18298
|
+
if (tier === 'flawless') return ['legendary', 'LEGENDARY'];
|
|
18299
|
+
if (tier === 'clear') return ['epic', 'EPIC'];
|
|
18300
|
+
// ungraded providers still deal a real pack spread (common..legendary)
|
|
18301
|
+
const r = hashRank(provider.id) % 12;
|
|
18302
|
+
if (r === 0) return ['legendary', 'LEGENDARY'];
|
|
18303
|
+
if (r < 4) return ['epic', 'EPIC'];
|
|
18304
|
+
if (r < 10) return ['rare', 'RARE'];
|
|
18305
|
+
return ['common', 'COMMON'];
|
|
18306
|
+
};
|
|
18307
|
+
const cards = found.map((provider, index) => {
|
|
18308
|
+
const rank = rankFor(provider);
|
|
18236
18309
|
return '<div class="vr-discover-card' + (demo.flippedCards['disc:' + provider.id] ? ' is-flipped' : '') + '" data-flip-card data-flip-id="disc:' + escapeHtml(provider.id) + '" data-rank="' + rank[0] + '" style="--vr-i:' + String(index) + '">' +
|
|
18237
18310
|
'<span class="vr-flip-inner">' +
|
|
18238
18311
|
'<span class="vr-flip-back vr-tcard is-back is-dealt" data-action="flip-discover" role="button" tabindex="0" aria-label="Flip to reveal ' + escapeHtml(provider.name) + '">' +
|
|
@@ -18715,18 +18788,40 @@ function ChatMissionCards(cards, chatIndex, options, usedActions) {
|
|
|
18715
18788
|
return html;
|
|
18716
18789
|
}
|
|
18717
18790
|
|
|
18791
|
+
let taskElapsedTimer = null;
|
|
18792
|
+
function formatElapsed(ms) {
|
|
18793
|
+
const s = Math.max(0, Math.floor(ms / 1000));
|
|
18794
|
+
return Math.floor(s / 60) + ':' + String(s % 60).padStart(2, '0');
|
|
18795
|
+
}
|
|
18796
|
+
function anyLaneWorking() {
|
|
18797
|
+
return (demo.chatContexts || []).some((c) => c && c.activeTask && c.activeTask.phase === 'working' && c.activeTask.startedAt);
|
|
18798
|
+
}
|
|
18799
|
+
// Live heartbeat: while the agent runs, tick the elapsed clock every second so it never looks frozen.
|
|
18800
|
+
function startTaskElapsedTimer() {
|
|
18801
|
+
if (taskElapsedTimer) return;
|
|
18802
|
+
taskElapsedTimer = window.setInterval(() => {
|
|
18803
|
+
if (!anyLaneWorking()) { window.clearInterval(taskElapsedTimer); taskElapsedTimer = null; return; }
|
|
18804
|
+
document.querySelectorAll('[data-task-elapsed]').forEach((el) => {
|
|
18805
|
+
const start = Number(el.getAttribute('data-task-elapsed')) || 0;
|
|
18806
|
+
if (start) el.textContent = formatElapsed(Date.now() - start);
|
|
18807
|
+
});
|
|
18808
|
+
}, 1000);
|
|
18809
|
+
}
|
|
18810
|
+
|
|
18718
18811
|
function ChatTaskAnimation(chatIndex, compact) {
|
|
18719
18812
|
const chat = chatContext(chatIndex);
|
|
18720
18813
|
const task = chat.activeTask;
|
|
18721
18814
|
if (!task || task.phase !== 'working') return '';
|
|
18722
18815
|
const meta = taskMeta(task.kind);
|
|
18723
18816
|
const statusText = task.kind === 'verify' ? 'Verifying...' : task.kind === 'diff' ? 'Reviewing...' : task.kind === 'explain' ? 'Explaining...' : 'Working...';
|
|
18724
|
-
const thoughtText = 'reading
|
|
18817
|
+
const thoughtText = 'reading your repo';
|
|
18818
|
+
const started = task.startedAt || Date.now();
|
|
18819
|
+
const elapsedHtml = '<span class="vr-task-elapsed" data-task-elapsed="' + started + '">' + formatElapsed(Date.now() - started) + '</span>';
|
|
18725
18820
|
const compactClass = compact ? ' is-compact' : '';
|
|
18726
18821
|
const rail = compact ? '' : '<div class="vr-task-rail" aria-hidden="true"><span></span></div>';
|
|
18727
|
-
const detail = compact ? '' : '<p>' + escapeHtml(meta.line) + '
|
|
18822
|
+
const detail = compact ? '' : '<p>' + escapeHtml(meta.line) + ' On a large repo this can take a minute.</p>';
|
|
18728
18823
|
return '<section class="vr-chat-agent-task is-working' + compactClass + '" data-task="' + escapeHtml(task.kind) + '">' +
|
|
18729
|
-
'<header><span class="vr-task-glyph" aria-hidden="true"></span><div><strong>' + escapeHtml(statusText) + '</strong><em>(' + escapeHtml(thoughtText) + ')</em></div
|
|
18824
|
+
'<header><span class="vr-task-glyph" aria-hidden="true"></span><div><strong>' + escapeHtml(statusText) + '</strong><em>(' + escapeHtml(thoughtText) + ')</em></div>' + elapsedHtml + '<b>' + escapeHtml(meta.title) + '</b></header>' +
|
|
18730
18825
|
rail +
|
|
18731
18826
|
detail +
|
|
18732
18827
|
'</section>';
|
|
@@ -18740,16 +18835,19 @@ function formatAgentOutput(value) {
|
|
|
18740
18835
|
.filter((line) => !/^(OpenAI Codex v|workdir:|model:|provider:|approval:|sandbox:|reasoning effort:|reasoning summaries:|session id:|--------$|user$)/.test(line.trim()))
|
|
18741
18836
|
.join('\\n')
|
|
18742
18837
|
.trim();
|
|
18743
|
-
|
|
18838
|
+
// CLI-failure rewrites only apply to SHORT error output. A long real answer that merely
|
|
18839
|
+
// mentions "auth"/"sign in" (e.g. a production auth review) must never be mistaken for one.
|
|
18840
|
+
const compact = clean.length < 800;
|
|
18841
|
+
if (compact && /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist/i.test(clean)) {
|
|
18744
18842
|
return 'Gemini CLI is installed, but this account/client is not eligible for the current Gemini Code Assist CLI. Connect a supported Gemini CLI account, then retry this chat.';
|
|
18745
18843
|
}
|
|
18746
|
-
if (/not running in a trusted directory|--skip-trust|GEMINI_CLI_TRUST_WORKSPACE/i.test(clean)) {
|
|
18844
|
+
if (compact && /not running in a trusted directory|--skip-trust|GEMINI_CLI_TRUST_WORKSPACE/i.test(clean)) {
|
|
18747
18845
|
return 'Gemini CLI needs this project trusted for headless chat. VibeRaven now passes the trust flag for Gemini runs; retry after your Gemini account is eligible.';
|
|
18748
18846
|
}
|
|
18749
|
-
if (/command not found|not recognized as an internal or external command|ENOENT/i.test(clean)) {
|
|
18847
|
+
if (compact && /command not found|not recognized as an internal or external command|ENOENT/i.test(clean)) {
|
|
18750
18848
|
return 'The selected CLI is not available on PATH. Install it or sign in, then reconnect it from the chat header.';
|
|
18751
18849
|
}
|
|
18752
|
-
if (/
|
|
18850
|
+
if (compact && /not logged in|login required|not authenticated|authentication failed|unauthorized|please (run|sign|log)|run (codex|gemini|claude)[^\\n]{0,40}login/i.test(clean)) {
|
|
18753
18851
|
return 'The selected CLI needs sign-in before VibeRaven can use it. Sign in with the CLI, then retry this mission.';
|
|
18754
18852
|
}
|
|
18755
18853
|
const missionIndex = clean.indexOf('User mission:');
|
|
@@ -19008,6 +19106,21 @@ function agentErrorPresentation(text) {
|
|
|
19008
19106
|
return { headline: raw, raw: '' };
|
|
19009
19107
|
}
|
|
19010
19108
|
|
|
19109
|
+
function looksLikeRawTranscript(text) {
|
|
19110
|
+
const nonEmpty = String(text || '').split('\\n').filter((line) => line.trim());
|
|
19111
|
+
if (nonEmpty.length < 24) return false;
|
|
19112
|
+
let grepLike = 0;
|
|
19113
|
+
let structured = 0;
|
|
19114
|
+
nonEmpty.forEach((line) => {
|
|
19115
|
+
const t = line.trim();
|
|
19116
|
+
if (/:\\d+:\\s/.test(t) || /\\.(json|jsonl|ts|tsx|js|md|txt):\\d+/.test(t)) grepLike++;
|
|
19117
|
+
if (/^#{1,3}\\s+/.test(t) || /^\\*\\*[^*]+\\*\\*/.test(t)) structured++;
|
|
19118
|
+
});
|
|
19119
|
+
if (grepLike >= 8) return true;
|
|
19120
|
+
if (nonEmpty.length > 60 && structured <= 1) return true;
|
|
19121
|
+
return false;
|
|
19122
|
+
}
|
|
19123
|
+
|
|
19011
19124
|
function renderAgentAnswerHtml(rawText, chatIndex, cards, isError, usedActions) {
|
|
19012
19125
|
const tick = String.fromCharCode(96);
|
|
19013
19126
|
const fence = tick + tick + tick;
|
|
@@ -19022,6 +19135,16 @@ function renderAgentAnswerHtml(rawText, chatIndex, cards, isError, usedActions)
|
|
|
19022
19135
|
'</div>';
|
|
19023
19136
|
}
|
|
19024
19137
|
}
|
|
19138
|
+
if (looksLikeRawTranscript(text)) {
|
|
19139
|
+
const headline = isError
|
|
19140
|
+
? 'The agent explored your repo but did not finish with a clean summary.'
|
|
19141
|
+
: 'The agent returned raw work instead of a summary.';
|
|
19142
|
+
return '<div class="vr-agent-answer-body vr-agent-answer-raw">' +
|
|
19143
|
+
'<p class="vr-agent-raw-headline">' + escapeHtml(headline) + '</p>' +
|
|
19144
|
+
'<p class="vr-agent-raw-sub">Open the agent work below for the raw detail, or use Retry for a clean answer.</p>' +
|
|
19145
|
+
agentWorkLogHtml(text) +
|
|
19146
|
+
'</div>';
|
|
19147
|
+
}
|
|
19025
19148
|
const split = splitAgentTelemetry(text);
|
|
19026
19149
|
const workLog = split.work ? agentWorkLogHtml(split.work) : '';
|
|
19027
19150
|
let visibleText = dedupeAgentMarkdownBody(split.answer, cards);
|
|
@@ -19218,8 +19341,9 @@ function ChatAgentResponse(meta, responseText, isError, providerId, releaseId, k
|
|
|
19218
19341
|
: '';
|
|
19219
19342
|
return '<section class="vr-chat-message is-agent vr-chat-agent-response vr-hud-card is-' + statusTone + ' ' + (isError ? 'is-error' : 'is-ready') + '">' +
|
|
19220
19343
|
'<header class="vr-hud-strip">' +
|
|
19221
|
-
'<span class="vr-hud-avatar"><img src="
|
|
19344
|
+
'<span class="vr-hud-avatar is-raven"><img src="/manga/emblem.png" alt="" /></span>' +
|
|
19222
19345
|
'<strong>VibeRaven</strong>' +
|
|
19346
|
+
'<span class="vr-hud-aibadge">AI AGENT</span>' +
|
|
19223
19347
|
'<span class="vr-hud-status is-' + statusTone + '"><i></i>' + statusWord + '</span>' +
|
|
19224
19348
|
via +
|
|
19225
19349
|
'<b>Just now</b>' +
|
|
@@ -19273,7 +19397,7 @@ function ProviderCardMessage(message) {
|
|
|
19273
19397
|
const provider = providers.find((item) => item.id === message.providerId);
|
|
19274
19398
|
if (!provider) return '';
|
|
19275
19399
|
const grade = message.grade || provider.grade || { value: null, tier: 'facedown', label: 'FACE DOWN' };
|
|
19276
|
-
const rows = message.rows
|
|
19400
|
+
const rows = !Array.isArray(message.rows)
|
|
19277
19401
|
? '<div class="vr-card-row is-running"><span>◌</span> running checks…</div>'
|
|
19278
19402
|
: message.rows.map((row) => {
|
|
19279
19403
|
const ready = row.state === 'ready';
|
|
@@ -19362,8 +19486,8 @@ function renderChatMessages(chat, index) {
|
|
|
19362
19486
|
}
|
|
19363
19487
|
const meta = message.kind ? taskMeta(message.kind) : { title: 'VibeRaven Agent' };
|
|
19364
19488
|
const messageId = String(index) + '-' + String(messageIndex);
|
|
19365
|
-
return storyNode('is-agent' + (message.isError ? ' is-error' : ''),
|
|
19366
|
-
|
|
19489
|
+
return storyNode('is-agent has-raven' + (message.isError ? ' is-error' : ''),
|
|
19490
|
+
'<img class="vr-raven-coin" src="/manga/emblem.png" alt="" />',
|
|
19367
19491
|
ChatAgentResponse(meta, message.text, Boolean(message.isError), message.providerId, message.releaseId, message.kind, index, messageId, message.cards, { showPlan: demo.fixPlanExpandedChatIndex === index }));
|
|
19368
19492
|
}).join('');
|
|
19369
19493
|
return html;
|
|
@@ -19563,7 +19687,7 @@ function StudioChatLane(index) {
|
|
|
19563
19687
|
(gateNotClear && introBlocker ? '<button class="vr-start-here-cta" type="button" data-action="start-agent-fix" data-chat-index="' + String(index) + '">' + Icon('bolt') + '<span>Fix it with the connected agent</span></button>' : '') +
|
|
19564
19688
|
ChatEnvironmentConnectCard();
|
|
19565
19689
|
const staticIntro = fresh
|
|
19566
|
-
? storyNode('is-agent is-intro',
|
|
19690
|
+
? storyNode('is-agent is-intro has-raven', '<img class="vr-raven-coin" src="/manga/emblem.png" alt="" />', '<section class="vr-chat-message is-agent vr-chat-intro-message"><div><span class="vr-intro-raven"><img src="/manga/emblem.png" alt="" /></span><p><strong>VibeRaven Agent</strong><b>Agent</b><em class="is-ready">Ready</em></p></div>' + introBody + '</section>')
|
|
19567
19691
|
: '';
|
|
19568
19692
|
return '<article class="vr-chat-lane ' + (secondary ? 'is-secondary' : 'is-primary') + '" data-chat-index="' + String(index) + '">' +
|
|
19569
19693
|
(secondary ? '<button class="vr-chat-close" type="button" data-action="close-chat" data-chat-index="' + String(index) + '" aria-label="Close chat">' + Icon('x') + '</button>' : '') +
|
|
@@ -19735,23 +19859,32 @@ function worstProviderId() {
|
|
|
19735
19859
|
return worst ? worst.id : null;
|
|
19736
19860
|
}
|
|
19737
19861
|
|
|
19862
|
+
// Top-left plaque = the live table STATS (real repo/provider data), replacing
|
|
19863
|
+
// the old crimson ribbon. Compact stat cells so it fits the header row.
|
|
19738
19864
|
function TablePlaque() {
|
|
19739
19865
|
const gate = (currentState && currentState.gate) || {};
|
|
19740
|
-
const
|
|
19866
|
+
const gateClear = gate.status === 'clear';
|
|
19867
|
+
const stamp = gateClear
|
|
19741
19868
|
? '<span class="vr-stamp is-mini is-clear">RAVEN · CLEAR</span>'
|
|
19742
19869
|
: gate.status === 'not_clear'
|
|
19743
19870
|
? '<span class="vr-stamp is-mini is-notyet">NOT YET</span>'
|
|
19744
19871
|
: '<span class="vr-stamp is-mini is-idle">NOT SCANNED</span>';
|
|
19745
19872
|
const detected = providers.filter((item) => item.state !== 'not_detected');
|
|
19746
|
-
const flawless = detected.filter((item) => item.grade && item.grade.tier === 'flawless').length;
|
|
19747
19873
|
const review = detected.filter((item) => item.grade && item.grade.tier === 'review').length;
|
|
19748
19874
|
const graded = detected.filter((item) => item.grade && typeof item.grade.value === 'number');
|
|
19749
19875
|
const avg = graded.length ? graded.reduce((sum, item) => sum + item.grade.value, 0) / graded.length : 0;
|
|
19750
|
-
|
|
19751
|
-
|
|
19752
|
-
|
|
19753
|
-
'
|
|
19754
|
-
'
|
|
19876
|
+
const dirty = (demo.worktree && Number(demo.worktree.dirtyCount)) || 0;
|
|
19877
|
+
const cells = [
|
|
19878
|
+
{ label: 'Providers', value: String(detected.length), tone: 'gold' },
|
|
19879
|
+
{ label: 'Grade', value: graded.length ? avg.toFixed(1) : '—', tone: 'gold' },
|
|
19880
|
+
{ label: 'Review', value: String(review), tone: review > 0 ? 'orange' : 'muted' },
|
|
19881
|
+
{ label: 'Uncommitted', value: String(dirty), tone: dirty > 0 ? 'orange' : 'green' },
|
|
19882
|
+
];
|
|
19883
|
+
return '<div class="vr-table-ribbon">' +
|
|
19884
|
+
'<div class="vr-ribbon-brand"><strong>' + escapeHtml(projectName()).toUpperCase() + '</strong>' + stamp + '</div>' +
|
|
19885
|
+
'<div class="vr-ribbon-stats">' +
|
|
19886
|
+
cells.map((c) => '<span class="vr-ribbon-stat is-' + c.tone + '"><b>' + c.value + '</b><i>' + escapeHtml(c.label) + '</i></span>').join('') +
|
|
19887
|
+
'</div>' +
|
|
19755
19888
|
'</div>';
|
|
19756
19889
|
}
|
|
19757
19890
|
|
|
@@ -20567,7 +20700,7 @@ function TableRail() {
|
|
|
20567
20700
|
['worktree', 'repo', 'Worktree'],
|
|
20568
20701
|
];
|
|
20569
20702
|
return '<aside class="vr-left-context-rail is-table-rail" aria-label="Studio navigation">' +
|
|
20570
|
-
'<span class="vr-rail-raven" title="VibeRaven"><img src="
|
|
20703
|
+
'<span class="vr-rail-raven is-emblem" title="VibeRaven"><img src="/manga/emblem.png" alt="VibeRaven" /></span>' +
|
|
20571
20704
|
'<button class="vr-rail-icon is-new" type="button" data-action="new-chat" title="New chat">' + Icon('plus') + '</button>' +
|
|
20572
20705
|
'<button class="vr-rail-icon' + (demo.chatsFlyoutOpen ? ' is-active' : '') + '" type="button" data-action="toggle-chats-flyout" title="Recent chats">' + Icon('prompt') + '</button>' +
|
|
20573
20706
|
'<span class="vr-rail-sep" aria-hidden="true"></span>' +
|
|
@@ -20664,12 +20797,118 @@ function closeComposerPopovers() {
|
|
|
20664
20797
|
demo.dropActive = false;
|
|
20665
20798
|
}
|
|
20666
20799
|
|
|
20800
|
+
// anime.js entrance for the region map: stagger the nodes in when the view opens.
|
|
20801
|
+
// The nodes are positioned with inline transform:translate(x,y), so we animate
|
|
20802
|
+
// OPACITY ONLY (never transform) and clear the inline value on complete. Gated by
|
|
20803
|
+
// a flag that resets when the view leaves, so it plays once per open, not on every
|
|
20804
|
+
// full re-render.
|
|
20805
|
+
let regionMapAnimated = false;
|
|
20806
|
+
function animateRegionMapOnce() {
|
|
20807
|
+
const nodes = app.querySelectorAll('.vr-studio-architecture.is-region-map .vr-arch-node');
|
|
20808
|
+
if (!nodes.length) { regionMapAnimated = false; return; }
|
|
20809
|
+
if (regionMapAnimated || !window.anime || typeof window.anime.animate !== 'function') return;
|
|
20810
|
+
regionMapAnimated = true;
|
|
20811
|
+
const clear = () => nodes.forEach((n) => { n.style.opacity = ''; });
|
|
20812
|
+
try {
|
|
20813
|
+
window.anime.animate(nodes, {
|
|
20814
|
+
opacity: [0, 1],
|
|
20815
|
+
duration: 460,
|
|
20816
|
+
delay: window.anime.stagger(34),
|
|
20817
|
+
ease: 'out(2)',
|
|
20818
|
+
onComplete: clear,
|
|
20819
|
+
});
|
|
20820
|
+
} catch (err) { clear(); }
|
|
20821
|
+
}
|
|
20822
|
+
|
|
20823
|
+
// Release timeline (Versions view): stagger the version cards in when it opens.
|
|
20824
|
+
// The cards carry a --vr-rot rotation transform, so we animate OPACITY ONLY
|
|
20825
|
+
// (translate/scale would clobber the rotation) and clear it on complete. Gated
|
|
20826
|
+
// once per open like the region map.
|
|
20827
|
+
let releaseTimelineAnimated = false;
|
|
20828
|
+
function animateReleaseTimelineOnce() {
|
|
20829
|
+
const spread = app.querySelector('.vr-version-spread');
|
|
20830
|
+
if (!spread) { releaseTimelineAnimated = false; return; }
|
|
20831
|
+
if (releaseTimelineAnimated || !window.anime || typeof window.anime.animate !== 'function') return;
|
|
20832
|
+
const cards = app.querySelectorAll('.vr-version-spread .vr-vcard');
|
|
20833
|
+
if (!cards.length) return;
|
|
20834
|
+
releaseTimelineAnimated = true;
|
|
20835
|
+
const clear = () => cards.forEach((c) => { c.style.opacity = ''; });
|
|
20836
|
+
try {
|
|
20837
|
+
window.anime.animate(cards, {
|
|
20838
|
+
opacity: [0, 1],
|
|
20839
|
+
duration: 440,
|
|
20840
|
+
delay: window.anime.stagger(50),
|
|
20841
|
+
ease: 'out(2)',
|
|
20842
|
+
onComplete: clear,
|
|
20843
|
+
});
|
|
20844
|
+
} catch (err) { clear(); }
|
|
20845
|
+
}
|
|
20846
|
+
|
|
20847
|
+
// Chat view: stagger the existing message rows in when the chat first shows, so
|
|
20848
|
+
// there is visible motion on the default view (opening / refreshing / switching
|
|
20849
|
+
// to chat). Story nodes have no positioning transform, so translateY is safe;
|
|
20850
|
+
// cleared on complete. Gated once per chat-view open (a new deal animates its own
|
|
20851
|
+
// card separately). Reset when leaving chat or when the transcript is empty.
|
|
20852
|
+
let chatEntranceAnimated = false;
|
|
20853
|
+
function animateChatEntranceOnce() {
|
|
20854
|
+
if (demo.activeStudioTab !== 'chat') { chatEntranceAnimated = false; return; }
|
|
20855
|
+
const nodes = app.querySelectorAll('.vr-chat-transcript .vr-story-node');
|
|
20856
|
+
if (!nodes.length) { chatEntranceAnimated = false; return; }
|
|
20857
|
+
if (chatEntranceAnimated || !window.anime || typeof window.anime.animate !== 'function') return;
|
|
20858
|
+
chatEntranceAnimated = true;
|
|
20859
|
+
const clear = () => nodes.forEach((n) => { n.style.opacity = ''; n.style.transform = ''; });
|
|
20860
|
+
try {
|
|
20861
|
+
window.anime.animate(nodes, {
|
|
20862
|
+
opacity: [0, 1],
|
|
20863
|
+
translateY: [14, 0],
|
|
20864
|
+
duration: 440,
|
|
20865
|
+
delay: window.anime.stagger(60),
|
|
20866
|
+
ease: 'out(2)',
|
|
20867
|
+
onComplete: clear,
|
|
20868
|
+
});
|
|
20869
|
+
} catch (err) { clear(); }
|
|
20870
|
+
}
|
|
20871
|
+
|
|
20872
|
+
// Card dealt into chat: fade + scale + lift the newest provider-card message in.
|
|
20873
|
+
// Called only from dealProviderCard (not the generic render) so it plays once on
|
|
20874
|
+
// deal, not on the later check-complete re-render.
|
|
20875
|
+
function animateDealtCardIntoChat() {
|
|
20876
|
+
if (!window.anime || typeof window.anime.animate !== 'function') return;
|
|
20877
|
+
const cards = app.querySelectorAll('.vr-card-message');
|
|
20878
|
+
const el = cards[cards.length - 1];
|
|
20879
|
+
if (!el) return;
|
|
20880
|
+
const clear = () => {
|
|
20881
|
+
el.style.opacity = '';
|
|
20882
|
+
el.style.transform = '';
|
|
20883
|
+
el.style.scale = '';
|
|
20884
|
+
el.style.rotate = '';
|
|
20885
|
+
el.style.translate = '';
|
|
20886
|
+
el.style.transformOrigin = '';
|
|
20887
|
+
};
|
|
20888
|
+
try {
|
|
20889
|
+
el.style.transformOrigin = '18% 60%';
|
|
20890
|
+
window.anime.animate(el, {
|
|
20891
|
+
opacity: [0, 1],
|
|
20892
|
+
scale: [0.55, 1],
|
|
20893
|
+
translateY: [46, 0],
|
|
20894
|
+
translateX: [-30, 0],
|
|
20895
|
+
rotate: [-7, 0],
|
|
20896
|
+
duration: 720,
|
|
20897
|
+
ease: 'out(3)',
|
|
20898
|
+
onComplete: clear,
|
|
20899
|
+
});
|
|
20900
|
+
} catch (err) { clear(); }
|
|
20901
|
+
}
|
|
20902
|
+
|
|
20667
20903
|
function render(options) {
|
|
20668
20904
|
const opts = options || {};
|
|
20669
20905
|
const scrollState = opts.preserveScroll === false ? null : readChatScrollState();
|
|
20670
20906
|
stableModalRender = Boolean(demo.activeModal && demo.activeModal === lastRenderedModal);
|
|
20671
20907
|
app.innerHTML = VibeShell();
|
|
20672
20908
|
window.requestAnimationFrame(() => {
|
|
20909
|
+
animateRegionMapOnce();
|
|
20910
|
+
animateReleaseTimelineOnce();
|
|
20911
|
+
animateChatEntranceOnce();
|
|
20673
20912
|
if (opts.scrollToBottom != null) {
|
|
20674
20913
|
restoreChatScrollState({}, { scrollToBottom: opts.scrollToBottom });
|
|
20675
20914
|
} else if (scrollState) {
|
|
@@ -22085,6 +22324,7 @@ app.addEventListener('pointerdown', (event) => {
|
|
|
22085
22324
|
offsetX: event.clientX - rect.left,
|
|
22086
22325
|
offsetY: event.clientY - rect.top,
|
|
22087
22326
|
width: rect.width,
|
|
22327
|
+
height: rect.height,
|
|
22088
22328
|
moved: false,
|
|
22089
22329
|
};
|
|
22090
22330
|
});
|
|
@@ -22098,7 +22338,9 @@ app.addEventListener('pointermove', (event) => {
|
|
|
22098
22338
|
tableDragState.moved = true;
|
|
22099
22339
|
const ghost = tableDragState.el.cloneNode(true);
|
|
22100
22340
|
ghost.classList.add('vr-drag-ghost');
|
|
22341
|
+
ghost.classList.remove('is-placed', 'is-hand');
|
|
22101
22342
|
ghost.style.width = tableDragState.width + 'px';
|
|
22343
|
+
ghost.style.height = tableDragState.height + 'px';
|
|
22102
22344
|
document.body.appendChild(ghost);
|
|
22103
22345
|
tableDragState.ghost = ghost;
|
|
22104
22346
|
tableDragState.el.classList.add('is-drag-source');
|
|
@@ -22438,8 +22680,18 @@ app.addEventListener('scroll', (event) => {
|
|
|
22438
22680
|
}, true);
|
|
22439
22681
|
|
|
22440
22682
|
loadRecentChats();
|
|
22683
|
+
// Persistence: on refresh/reopen, restore the most recent chat so work is never lost.
|
|
22684
|
+
try {
|
|
22685
|
+
const lastChat = recentChats[0];
|
|
22686
|
+
if (lastChat && Array.isArray(lastChat.messages) && lastChat.messages.length) {
|
|
22687
|
+
demo.activeRecentChatId = lastChat.id;
|
|
22688
|
+
demo.activeChatCount = 1;
|
|
22689
|
+
demo.chatContexts = [restoreRecentChat(lastChat)];
|
|
22690
|
+
syncDemoFromChatContext(demo.chatContexts[0]);
|
|
22691
|
+
}
|
|
22692
|
+
} catch { /* restore is best-effort */ }
|
|
22441
22693
|
try {
|
|
22442
|
-
if (!window.localStorage.getItem('vrOnboarded') && !currentState.empty && !demo.activeModal && window.location.search.indexOf('shot') < 0) {
|
|
22694
|
+
if (!window.localStorage.getItem('vrOnboarded') && !demo.activeRecentChatId && !currentState.empty && !demo.activeModal && window.location.search.indexOf('shot') < 0) {
|
|
22443
22695
|
demo.activeModal = 'quickstart';
|
|
22444
22696
|
} else if (
|
|
22445
22697
|
!window.localStorage.getItem('vrPackOpened') && !currentState.empty && !demo.activeModal &&
|
|
@@ -22497,28 +22749,30 @@ var init_appCss = __esm({
|
|
|
22497
22749
|
"src/local-ui/static/appCss.ts"() {
|
|
22498
22750
|
"use strict";
|
|
22499
22751
|
localUiCss = `
|
|
22752
|
+
@import url('https://fonts.googleapis.com/css2?family=Anton&display=swap');
|
|
22500
22753
|
:root {
|
|
22501
|
-
--vr-bg: #
|
|
22502
|
-
--vr-bg-2: #
|
|
22503
|
-
--vr-panel: rgba(
|
|
22504
|
-
--vr-panel-2: rgba(
|
|
22754
|
+
--vr-bg: #0b0b0d;
|
|
22755
|
+
--vr-bg-2: #141418;
|
|
22756
|
+
--vr-panel: rgba(20, 20, 24, 0.8);
|
|
22757
|
+
--vr-panel-2: rgba(30, 30, 35, 0.72);
|
|
22505
22758
|
--vr-border: rgba(232, 193, 90, 0.26);
|
|
22506
22759
|
--vr-border-strong: rgba(232, 193, 90, 0.55);
|
|
22507
|
-
--vr-text: #
|
|
22508
|
-
--vr-muted: #
|
|
22760
|
+
--vr-text: #f4f1e8;
|
|
22761
|
+
--vr-muted: #a89a86;
|
|
22509
22762
|
--vr-purple: #e8c15a;
|
|
22510
22763
|
--vr-purple-2: #ffd76e;
|
|
22511
22764
|
--vr-blue: #8fa7ff;
|
|
22512
22765
|
--vr-green: #22c55e;
|
|
22513
22766
|
--vr-red: #ef4444;
|
|
22514
22767
|
--vr-orange: #ffb84d;
|
|
22515
|
-
--vr-glow-purple: 0 12px 32px rgba(0, 0, 0, 0.
|
|
22516
|
-
--vr-glow-green: 0 12px 32px rgba(0, 0, 0, 0.
|
|
22768
|
+
--vr-glow-purple: 0 12px 32px rgba(0, 0, 0, 0.5);
|
|
22769
|
+
--vr-glow-green: 0 12px 32px rgba(0, 0, 0, 0.5);
|
|
22517
22770
|
--vr-accent: #e8c15a;
|
|
22518
22771
|
--vr-gold: #e8c15a;
|
|
22519
22772
|
--vr-gold-bright: #ffe9ad;
|
|
22520
|
-
--vr-plate: rgba(
|
|
22773
|
+
--vr-plate: rgba(10, 10, 12, 0.85);
|
|
22521
22774
|
--vr-foil: linear-gradient(135deg, #fff3c4, #c98f2e 35%, #ffe9a8 55%, #8a5a1a 82%, #ffd76e);
|
|
22775
|
+
--mg-display: 'Anton', 'Arial Narrow', sans-serif;
|
|
22522
22776
|
}
|
|
22523
22777
|
|
|
22524
22778
|
* { box-sizing: border-box; }
|
|
@@ -22527,6 +22781,8 @@ body {
|
|
|
22527
22781
|
margin: 0;
|
|
22528
22782
|
overflow: hidden;
|
|
22529
22783
|
background: var(--vr-bg);
|
|
22784
|
+
background-image: radial-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1.4px);
|
|
22785
|
+
background-size: 6px 6px;
|
|
22530
22786
|
color: var(--vr-text);
|
|
22531
22787
|
font-family: Geist, Inter, "Segoe UI", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
22532
22788
|
font-size: 14px;
|
|
@@ -22581,7 +22837,7 @@ a i[data-icon] {
|
|
|
22581
22837
|
place-items: center;
|
|
22582
22838
|
border: 1px solid rgba(148, 163, 184, 0.16);
|
|
22583
22839
|
border-radius: 8px;
|
|
22584
|
-
background: rgba(
|
|
22840
|
+
background: rgba(24, 22, 28, 0.72);
|
|
22585
22841
|
color: #ffe9ad;
|
|
22586
22842
|
}
|
|
22587
22843
|
.vr-context-icon-chip.is-input {
|
|
@@ -22618,7 +22874,7 @@ a i[data-icon] {
|
|
|
22618
22874
|
.vr-bottom-tip-bar {
|
|
22619
22875
|
border: 1px solid var(--vr-border);
|
|
22620
22876
|
background:
|
|
22621
|
-
linear-gradient(180deg, rgba(
|
|
22877
|
+
linear-gradient(180deg, rgba(24, 22, 28, 0.68), rgba(13, 12, 16, 0.7)),
|
|
22622
22878
|
var(--vr-panel);
|
|
22623
22879
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.025);
|
|
22624
22880
|
}
|
|
@@ -22659,7 +22915,7 @@ a i[data-icon] {
|
|
|
22659
22915
|
background:
|
|
22660
22916
|
radial-gradient(circle at 42% 26%, rgba(34, 197, 94, 0.16), transparent 36%),
|
|
22661
22917
|
radial-gradient(circle at 68% 76%, rgba(232, 193, 90, 0.5), transparent 54%),
|
|
22662
|
-
linear-gradient(145deg, rgba(
|
|
22918
|
+
linear-gradient(145deg, rgba(24, 22, 28, 0.98), rgba(13, 12, 16, 0.8));
|
|
22663
22919
|
box-shadow:
|
|
22664
22920
|
inset 0 1px 0 rgba(255, 255, 255, 0.08),
|
|
22665
22921
|
0 0 28px rgba(0, 0, 0, 0);
|
|
@@ -22857,7 +23113,7 @@ a i[data-icon] {
|
|
|
22857
23113
|
border-radius: 7px;
|
|
22858
23114
|
background:
|
|
22859
23115
|
radial-gradient(circle at 34% 20%, rgba(255, 255, 255, 0.16), transparent 34%),
|
|
22860
|
-
rgba(
|
|
23116
|
+
rgba(24, 22, 28, 0.78);
|
|
22861
23117
|
}
|
|
22862
23118
|
|
|
22863
23119
|
.vr-inline-brand-mark img {
|
|
@@ -22870,7 +23126,7 @@ a i[data-icon] {
|
|
|
22870
23126
|
.vr-workspace-switcher > span {
|
|
22871
23127
|
width: 28px;
|
|
22872
23128
|
height: 28px;
|
|
22873
|
-
border: 2px solid rgba(
|
|
23129
|
+
border: 2px solid rgba(13, 12, 16, 0.9);
|
|
22874
23130
|
border-radius: 999px;
|
|
22875
23131
|
background:
|
|
22876
23132
|
radial-gradient(circle at 35% 28%, #f8fafc, transparent 10%),
|
|
@@ -22899,7 +23155,7 @@ a i[data-icon] {
|
|
|
22899
23155
|
border-radius: 9px;
|
|
22900
23156
|
background:
|
|
22901
23157
|
linear-gradient(180deg, rgba(148, 163, 184, 0.050), rgba(14, 165, 233, 0.04)),
|
|
22902
|
-
rgba(
|
|
23158
|
+
rgba(13, 12, 16, 0.34);
|
|
22903
23159
|
padding: 7px 8px;
|
|
22904
23160
|
}
|
|
22905
23161
|
|
|
@@ -23051,7 +23307,7 @@ a i[data-icon] {
|
|
|
23051
23307
|
border-width: 0 0 1px;
|
|
23052
23308
|
border-radius: 0;
|
|
23053
23309
|
padding: 0 14px;
|
|
23054
|
-
background: rgba(
|
|
23310
|
+
background: rgba(13, 12, 16, 0.52);
|
|
23055
23311
|
}
|
|
23056
23312
|
.vr-topbar-brand {
|
|
23057
23313
|
display: inline-grid;
|
|
@@ -23366,7 +23622,7 @@ a i[data-icon] {
|
|
|
23366
23622
|
border-width: 0 0 1px;
|
|
23367
23623
|
border-radius: 0;
|
|
23368
23624
|
padding: 0 28px;
|
|
23369
|
-
background: rgba(
|
|
23625
|
+
background: rgba(13, 12, 16, 0.5);
|
|
23370
23626
|
}
|
|
23371
23627
|
|
|
23372
23628
|
.vr-project-id {
|
|
@@ -23762,7 +24018,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
23762
24018
|
.vr-new-chat-button kbd {
|
|
23763
24019
|
border: 1px solid rgba(226, 232, 240, 0.12);
|
|
23764
24020
|
border-radius: 6px;
|
|
23765
|
-
background: rgba(
|
|
24021
|
+
background: rgba(13, 12, 16, 0.5);
|
|
23766
24022
|
color: #cbd5e1;
|
|
23767
24023
|
padding: 2px 6px;
|
|
23768
24024
|
font: 10px/1.2 "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
|
|
@@ -24115,7 +24371,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
24115
24371
|
margin: 8px 0 0;
|
|
24116
24372
|
padding: 8px 10px;
|
|
24117
24373
|
border-radius: 8px;
|
|
24118
|
-
background: rgba(
|
|
24374
|
+
background: rgba(13, 12, 16, 0.72);
|
|
24119
24375
|
overflow: auto;
|
|
24120
24376
|
}
|
|
24121
24377
|
.vr-cli-setup-step pre code {
|
|
@@ -24653,10 +24909,26 @@ body:has(.vr-app.is-dragging) {
|
|
|
24653
24909
|
min-height: 32px;
|
|
24654
24910
|
padding: 0 12px;
|
|
24655
24911
|
}
|
|
24656
|
-
|
|
24657
|
-
|
|
24912
|
+
/* Align the composer column with the chat messages. The transcript is a centered
|
|
24913
|
+
max-width column (min(1440px, 100% - 64px)) with 54px side padding, and messages
|
|
24914
|
+
are inset a further ~40px by the agent-avatar gutter. Match all of that here so
|
|
24915
|
+
the composer lines up with the message cards at every viewport width. Higher
|
|
24916
|
+
specificity (.vr-chat-lane) than the responsive command-bar padding passes. */
|
|
24917
|
+
.vr-studio-chat:not(.is-split) .vr-chat-lane .vr-chat-command-bar {
|
|
24918
|
+
width: min(1440px, calc(100% - 64px));
|
|
24919
|
+
max-width: min(1440px, calc(100% - 64px));
|
|
24920
|
+
margin-inline: auto;
|
|
24921
|
+
justify-self: center;
|
|
24922
|
+
padding: 6px 54px 10px 94px;
|
|
24658
24923
|
align-self: end;
|
|
24659
24924
|
}
|
|
24925
|
+
/* Size the composer to the same width as the chat messages and left-align it, so
|
|
24926
|
+
both edges line up with the cards (which are min(1120px, 100%)). */
|
|
24927
|
+
.vr-studio-chat:not(.is-split) .vr-chat-lane .vr-chat-command-bar > .vr-chat-composer {
|
|
24928
|
+
width: min(1120px, 100%);
|
|
24929
|
+
max-width: min(1120px, 100%);
|
|
24930
|
+
justify-self: start;
|
|
24931
|
+
}
|
|
24660
24932
|
.vr-studio-chat:not(.is-split) .vr-chat-command-bar > .vr-chat-composer {
|
|
24661
24933
|
min-height: 92px;
|
|
24662
24934
|
border-color: rgba(226, 232, 240, 0.16);
|
|
@@ -24711,7 +24983,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
24711
24983
|
height: 39px;
|
|
24712
24984
|
object-fit: contain;
|
|
24713
24985
|
transform: translateY(4px);
|
|
24714
|
-
filter: drop-shadow(0 0 10px rgba(
|
|
24986
|
+
filter: drop-shadow(0 0 10px rgba(24, 22, 28, 0.75));
|
|
24715
24987
|
}
|
|
24716
24988
|
.vr-chat-transcript > header strong,
|
|
24717
24989
|
.vr-chat-transcript > header em {
|
|
@@ -25093,7 +25365,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25093
25365
|
margin: 0;
|
|
25094
25366
|
padding: 8px 10px;
|
|
25095
25367
|
border-radius: 8px;
|
|
25096
|
-
background: rgba(
|
|
25368
|
+
background: rgba(13, 12, 16, 0.72);
|
|
25097
25369
|
overflow: auto;
|
|
25098
25370
|
}
|
|
25099
25371
|
.vr-cli-connect-expand pre code {
|
|
@@ -25161,7 +25433,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25161
25433
|
margin: 0;
|
|
25162
25434
|
padding: 14px 16px;
|
|
25163
25435
|
border-radius: 12px;
|
|
25164
|
-
background: rgba(
|
|
25436
|
+
background: rgba(13, 12, 16, 0.82);
|
|
25165
25437
|
border: 1px solid rgba(226, 232, 240, 0.1);
|
|
25166
25438
|
}
|
|
25167
25439
|
.vr-studio-terminal-log code {
|
|
@@ -25186,7 +25458,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25186
25458
|
padding: 6px 12px;
|
|
25187
25459
|
border-radius: 999px;
|
|
25188
25460
|
border: 1px solid rgba(226, 232, 240, 0.14);
|
|
25189
|
-
background: rgba(
|
|
25461
|
+
background: rgba(24, 22, 28, 0.72);
|
|
25190
25462
|
color: #e2e8f0;
|
|
25191
25463
|
font-size: 12px;
|
|
25192
25464
|
cursor: pointer;
|
|
@@ -25336,10 +25608,17 @@ body:has(.vr-app.is-dragging) {
|
|
|
25336
25608
|
position: relative;
|
|
25337
25609
|
z-index: 1;
|
|
25338
25610
|
display: grid;
|
|
25339
|
-
grid-template-columns: 18px auto minmax(0, 1fr);
|
|
25611
|
+
grid-template-columns: 18px auto auto minmax(0, 1fr);
|
|
25340
25612
|
align-items: center;
|
|
25341
25613
|
gap: 8px;
|
|
25342
25614
|
}
|
|
25615
|
+
.vr-task-elapsed {
|
|
25616
|
+
font-family: var(--vr-hud-mono);
|
|
25617
|
+
font-size: 12px;
|
|
25618
|
+
font-variant-numeric: tabular-nums;
|
|
25619
|
+
color: var(--vr-gold);
|
|
25620
|
+
letter-spacing: 0.04em;
|
|
25621
|
+
}
|
|
25343
25622
|
.vr-task-glyph {
|
|
25344
25623
|
position: relative;
|
|
25345
25624
|
width: 14px;
|
|
@@ -25453,6 +25732,11 @@ body:has(.vr-app.is-dragging) {
|
|
|
25453
25732
|
display: inline;
|
|
25454
25733
|
margin-left: 4px;
|
|
25455
25734
|
}
|
|
25735
|
+
/* compact header only has 3 columns; the redundant title (<b>) would wrap to a
|
|
25736
|
+
clipped second row ("...nges"), so drop it \u2014 the status word already says it. */
|
|
25737
|
+
.vr-chat-command-bar > .vr-chat-agent-task.is-compact header b {
|
|
25738
|
+
display: none;
|
|
25739
|
+
}
|
|
25456
25740
|
.vr-chat-agent-response {
|
|
25457
25741
|
max-width: min(920px, 82%);
|
|
25458
25742
|
display: grid;
|
|
@@ -25519,7 +25803,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25519
25803
|
border-radius: 12px;
|
|
25520
25804
|
background:
|
|
25521
25805
|
radial-gradient(circle at 0% 0%, rgba(148, 163, 184, 0.050), transparent 42%),
|
|
25522
|
-
rgba(
|
|
25806
|
+
rgba(24, 22, 28, 0.62);
|
|
25523
25807
|
padding: 10px 12px;
|
|
25524
25808
|
min-width: 0;
|
|
25525
25809
|
}
|
|
@@ -25551,7 +25835,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25551
25835
|
border-color: rgba(34, 197, 94, 0.28);
|
|
25552
25836
|
background:
|
|
25553
25837
|
radial-gradient(circle at 0% 0%, rgba(34, 197, 94, 0.12), transparent 42%),
|
|
25554
|
-
rgba(
|
|
25838
|
+
rgba(24, 22, 28, 0.62);
|
|
25555
25839
|
}
|
|
25556
25840
|
.vr-agent-gate-strip[data-tone="clear"] svg {
|
|
25557
25841
|
color: #86efac;
|
|
@@ -25560,7 +25844,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25560
25844
|
border-color: rgba(248, 113, 113, 0.28);
|
|
25561
25845
|
background:
|
|
25562
25846
|
radial-gradient(circle at 0% 0%, rgba(248, 113, 113, 0.1), transparent 42%),
|
|
25563
|
-
rgba(
|
|
25847
|
+
rgba(24, 22, 28, 0.62);
|
|
25564
25848
|
}
|
|
25565
25849
|
.vr-agent-gate-strip[data-tone="blocked"] svg {
|
|
25566
25850
|
color: #fca5a5;
|
|
@@ -25570,7 +25854,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25570
25854
|
border-radius: 12px;
|
|
25571
25855
|
background:
|
|
25572
25856
|
radial-gradient(circle at 0% 0%, rgba(148, 163, 184, 0.050), transparent 42%),
|
|
25573
|
-
rgba(
|
|
25857
|
+
rgba(24, 22, 28, 0.55);
|
|
25574
25858
|
padding: 12px 14px;
|
|
25575
25859
|
display: grid;
|
|
25576
25860
|
gap: 8px;
|
|
@@ -25656,7 +25940,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25656
25940
|
.vr-agent-answer-body code {
|
|
25657
25941
|
border: 1px solid rgba(148, 163, 184, 0.18);
|
|
25658
25942
|
border-radius: 6px;
|
|
25659
|
-
background: rgba(
|
|
25943
|
+
background: rgba(24, 22, 28, 0.72);
|
|
25660
25944
|
padding: 1px 6px;
|
|
25661
25945
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
25662
25946
|
font-size: 12px;
|
|
@@ -26030,7 +26314,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
26030
26314
|
width: fit-content;
|
|
26031
26315
|
border: 1px solid rgba(148, 163, 184, 0.22);
|
|
26032
26316
|
border-radius: 999px;
|
|
26033
|
-
background: rgba(
|
|
26317
|
+
background: rgba(24, 22, 28, 0.86);
|
|
26034
26318
|
color: #e2e8f0;
|
|
26035
26319
|
padding: 7px 12px;
|
|
26036
26320
|
}
|
|
@@ -26141,7 +26425,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
26141
26425
|
.vr-provider-drop-zone > .vr-provider-drop-label {
|
|
26142
26426
|
border: 1px dashed rgba(148, 163, 184, 0.22);
|
|
26143
26427
|
border-radius: 999px;
|
|
26144
|
-
background: rgba(
|
|
26428
|
+
background: rgba(13, 12, 16, 0.2);
|
|
26145
26429
|
padding: 5px 10px;
|
|
26146
26430
|
}
|
|
26147
26431
|
.vr-provider-drop-zone.is-active > .vr-provider-drop-label {
|
|
@@ -26879,7 +27163,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
26879
27163
|
place-items: center;
|
|
26880
27164
|
border: 1px solid rgba(120, 145, 190, 0.18);
|
|
26881
27165
|
border-radius: 10px;
|
|
26882
|
-
background: rgba(
|
|
27166
|
+
background: rgba(13, 12, 16, 0.44);
|
|
26883
27167
|
color: var(--vr-text);
|
|
26884
27168
|
transition:
|
|
26885
27169
|
transform 180ms cubic-bezier(0.23, 1, 0.32, 1),
|
|
@@ -27076,7 +27360,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
27076
27360
|
.vr-provider-card:hover .vr-provider-proof-chip,
|
|
27077
27361
|
.vr-provider-card.is-selected .vr-provider-proof-chip {
|
|
27078
27362
|
border-color: rgba(248, 250, 252, 0.22);
|
|
27079
|
-
background: rgba(
|
|
27363
|
+
background: rgba(13, 12, 16, 0.72);
|
|
27080
27364
|
}
|
|
27081
27365
|
.vr-provider-proof-chip svg {
|
|
27082
27366
|
width: 13px;
|
|
@@ -27405,7 +27689,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
27405
27689
|
border: 1px solid rgba(120, 145, 190, 0.15);
|
|
27406
27690
|
border-radius: 9px;
|
|
27407
27691
|
background:
|
|
27408
|
-
linear-gradient(180deg, rgba(
|
|
27692
|
+
linear-gradient(180deg, rgba(24, 22, 28, 0.64), rgba(8, 13, 24, 0.7));
|
|
27409
27693
|
color: var(--vr-text);
|
|
27410
27694
|
padding: 8px 10px;
|
|
27411
27695
|
text-align: left;
|
|
@@ -27652,7 +27936,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
27652
27936
|
border-radius: 999px;
|
|
27653
27937
|
background:
|
|
27654
27938
|
radial-gradient(circle at 50% 50%, rgba(34, 197, 94, 0.22), transparent 46%),
|
|
27655
|
-
rgba(
|
|
27939
|
+
rgba(24, 22, 28, 0.78);
|
|
27656
27940
|
box-shadow: 0 0 14px rgba(34, 197, 94, 0.2);
|
|
27657
27941
|
}
|
|
27658
27942
|
.vr-agent-will span i::before {
|
|
@@ -27801,7 +28085,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
27801
28085
|
gap: 7px;
|
|
27802
28086
|
border: 1px solid rgba(120, 145, 190, 0.2);
|
|
27803
28087
|
border-radius: 9px;
|
|
27804
|
-
background: rgba(
|
|
28088
|
+
background: rgba(13, 12, 16, 0.38);
|
|
27805
28089
|
color: #dbeafe;
|
|
27806
28090
|
padding: 0 10px;
|
|
27807
28091
|
text-decoration: none;
|
|
@@ -27912,9 +28196,13 @@ body:has(.vr-app.is-dragging) {
|
|
|
27912
28196
|
radial-gradient(circle at 72% 16%, rgba(34, 197, 94, 0.12), transparent 24%),
|
|
27913
28197
|
linear-gradient(rgba(148, 163, 184, 0.03) 1px, transparent 1px),
|
|
27914
28198
|
linear-gradient(90deg, rgba(148, 163, 184, 0.03) 1px, transparent 1px),
|
|
27915
|
-
rgba(1, 4, 13, 0.
|
|
28199
|
+
rgba(1, 4, 13, 0.86);
|
|
27916
28200
|
background-size: auto, auto, 42px 42px, 42px 42px, auto;
|
|
27917
|
-
backdrop-filter: blur(
|
|
28201
|
+
/* NOTE: no backdrop-filter here. A full-viewport backdrop-filter: blur()
|
|
28202
|
+
renders as SOLID BLACK on many real Windows GPU/driver combos (Intel/ANGLE),
|
|
28203
|
+
blacking out the whole Studio whenever a modal (e.g. the welcome modal) is
|
|
28204
|
+
open. Headless/software raster hides the bug. The dark base layer above
|
|
28205
|
+
gives the same focus without the GPU hazard. Do not re-add blur here. */
|
|
27918
28206
|
animation: vrModalFade 180ms ease-out both;
|
|
27919
28207
|
}
|
|
27920
28208
|
|
|
@@ -27933,7 +28221,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
27933
28221
|
radial-gradient(circle at 80% 15%, rgba(148, 163, 184, 0.050), transparent 27%),
|
|
27934
28222
|
radial-gradient(circle at 19% 8%, rgba(56, 189, 248, 0.12), transparent 24%),
|
|
27935
28223
|
radial-gradient(circle at 74% 70%, rgba(34, 197, 94, 0.08), transparent 28%),
|
|
27936
|
-
linear-gradient(180deg, rgba(13, 20, 43, 0.98), rgba(
|
|
28224
|
+
linear-gradient(180deg, rgba(13, 20, 43, 0.98), rgba(13, 12, 16, 0.995));
|
|
27937
28225
|
box-shadow:
|
|
27938
28226
|
0 0 0 1px rgba(255, 233, 173, 0.12),
|
|
27939
28227
|
0 0 70px rgba(0, 0, 0, 0),
|
|
@@ -27959,7 +28247,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
27959
28247
|
}
|
|
27960
28248
|
|
|
27961
28249
|
.vr-modal-card::-webkit-scrollbar-thumb {
|
|
27962
|
-
border: 3px solid rgba(
|
|
28250
|
+
border: 3px solid rgba(13, 12, 16, 0.92);
|
|
27963
28251
|
border-radius: 999px;
|
|
27964
28252
|
background: rgba(148, 163, 184, 0.4);
|
|
27965
28253
|
}
|
|
@@ -28043,7 +28331,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
28043
28331
|
border: 1px solid rgba(96, 122, 177, 0.24);
|
|
28044
28332
|
border-radius: 18px;
|
|
28045
28333
|
background:
|
|
28046
|
-
linear-gradient(90deg, rgba(148, 163, 184, 0.050), rgba(8, 17, 34, 0.48) 46%, rgba(
|
|
28334
|
+
linear-gradient(90deg, rgba(148, 163, 184, 0.050), rgba(8, 17, 34, 0.48) 46%, rgba(24, 22, 28, 0.08)),
|
|
28047
28335
|
radial-gradient(circle at 86% 42%, rgba(148, 163, 184, 0.050), transparent 32%);
|
|
28048
28336
|
padding: 22px 34px 22px 22px;
|
|
28049
28337
|
padding-right: 34px;
|
|
@@ -28318,7 +28606,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
28318
28606
|
.vr-modal-checks li.pending > span,
|
|
28319
28607
|
.vr-modal-tasklist li.pending > span {
|
|
28320
28608
|
border-color: rgba(96, 122, 177, 0.7);
|
|
28321
|
-
background: rgba(
|
|
28609
|
+
background: rgba(24, 22, 28, 0.5);
|
|
28322
28610
|
box-shadow: none;
|
|
28323
28611
|
}
|
|
28324
28612
|
|
|
@@ -28411,7 +28699,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
28411
28699
|
border: 1px solid rgba(96, 122, 177, 0.28);
|
|
28412
28700
|
border-radius: 16px;
|
|
28413
28701
|
background:
|
|
28414
|
-
linear-gradient(180deg, rgba(
|
|
28702
|
+
linear-gradient(180deg, rgba(24, 22, 28, 0.86), rgba(7, 16, 33, 0.94));
|
|
28415
28703
|
padding: 18px;
|
|
28416
28704
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
|
28417
28705
|
}
|
|
@@ -28621,7 +28909,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
28621
28909
|
margin: 0 0 10px;
|
|
28622
28910
|
border: 1px solid rgba(148, 163, 184, 0.14);
|
|
28623
28911
|
border-radius: 12px;
|
|
28624
|
-
background: rgba(
|
|
28912
|
+
background: rgba(24, 22, 28, 0.38);
|
|
28625
28913
|
padding: 10px 12px;
|
|
28626
28914
|
}
|
|
28627
28915
|
|
|
@@ -28653,7 +28941,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
28653
28941
|
align-items: start;
|
|
28654
28942
|
padding: 9px 11px;
|
|
28655
28943
|
border-radius: 10px;
|
|
28656
|
-
background: rgba(
|
|
28944
|
+
background: rgba(24, 22, 28, 0.38);
|
|
28657
28945
|
border: 1px solid rgba(148, 163, 184, 0.13);
|
|
28658
28946
|
color: #e2e8f0;
|
|
28659
28947
|
line-height: 1.35;
|
|
@@ -28859,7 +29147,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
28859
29147
|
border-radius: 12px;
|
|
28860
29148
|
background:
|
|
28861
29149
|
radial-gradient(circle at 0% 50%, rgba(148, 163, 184, 0.050), transparent 36%),
|
|
28862
|
-
rgba(
|
|
29150
|
+
rgba(13, 12, 16, 0.5);
|
|
28863
29151
|
color: var(--vr-text);
|
|
28864
29152
|
padding: 0 16px;
|
|
28865
29153
|
text-align: left;
|
|
@@ -28901,7 +29189,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
28901
29189
|
border-radius: 14px;
|
|
28902
29190
|
background:
|
|
28903
29191
|
radial-gradient(circle at 86% 0%, rgba(148, 163, 184, 0.050), transparent 34%),
|
|
28904
|
-
linear-gradient(180deg, rgba(
|
|
29192
|
+
linear-gradient(180deg, rgba(24, 22, 28, 0.96), rgba(13, 12, 16, 0.96));
|
|
28905
29193
|
padding: 18px;
|
|
28906
29194
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
|
28907
29195
|
}
|
|
@@ -30346,7 +30634,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
30346
30634
|
border-color: rgba(239, 68, 68, 0.38);
|
|
30347
30635
|
background:
|
|
30348
30636
|
radial-gradient(circle at 100% 0%, rgba(239, 68, 68, 0.12), transparent 210px),
|
|
30349
|
-
linear-gradient(135deg, rgba(
|
|
30637
|
+
linear-gradient(135deg, rgba(20, 19, 24, 0.9), rgba(13, 16, 24, 0.94));
|
|
30350
30638
|
}
|
|
30351
30639
|
|
|
30352
30640
|
.vr-chat-agent-response > div:first-child {
|
|
@@ -31812,13 +32100,19 @@ div.vr-branch-row {
|
|
|
31812
32100
|
painted once as body background layers (no extra composited layers).
|
|
31813
32101
|
PERF: tiles stay >= 22px and no backdrop-filter, ever. */
|
|
31814
32102
|
body {
|
|
31815
|
-
|
|
32103
|
+
/* manga skin: clean ink base. The full-bleed speed-line art was removed \u2014
|
|
32104
|
+
it read as disconnected wallpaper behind the chat. Just a fine screentone
|
|
32105
|
+
dot grid + a faint gold glow at the top edge. */
|
|
32106
|
+
background-color: #0a0a0d;
|
|
31816
32107
|
background-image:
|
|
31817
|
-
radial-gradient(circle, rgba(255,
|
|
31818
|
-
radial-gradient(ellipse
|
|
31819
|
-
|
|
31820
|
-
|
|
31821
|
-
background-
|
|
32108
|
+
radial-gradient(circle, rgba(255, 255, 255, 0.035) 1.2px, transparent 1.5px),
|
|
32109
|
+
radial-gradient(ellipse 72% 46% at 50% -6%, rgba(232, 193, 90, 0.05), transparent 62%);
|
|
32110
|
+
background-size: 24px 24px, 100% 100%;
|
|
32111
|
+
background-position: 0 0, center;
|
|
32112
|
+
background-repeat: repeat, no-repeat;
|
|
32113
|
+
/* scroll, not fixed: body never scrolls (overflow:hidden) so it looks
|
|
32114
|
+
identical, and fixed-attachment on the large art stalls headless capture. */
|
|
32115
|
+
background-attachment: scroll, scroll, scroll;
|
|
31822
32116
|
}
|
|
31823
32117
|
|
|
31824
32118
|
/* Glow buttons become solid, quiet primaries. */
|
|
@@ -33795,7 +34089,7 @@ body {
|
|
|
33795
34089
|
========================================================================== */
|
|
33796
34090
|
:root {
|
|
33797
34091
|
--vr-hud-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Consolas, monospace;
|
|
33798
|
-
--vr-hud-surface: rgba(
|
|
34092
|
+
--vr-hud-surface: rgba(13, 12, 16, 0.92);
|
|
33799
34093
|
--vr-hud-line: rgba(232, 193, 90, 0.16);
|
|
33800
34094
|
}
|
|
33801
34095
|
|
|
@@ -33911,6 +34205,20 @@ body {
|
|
|
33911
34205
|
word-break: break-word;
|
|
33912
34206
|
}
|
|
33913
34207
|
|
|
34208
|
+
/* Raw transcript guard: agent dumped grep/tool output instead of a clean answer.
|
|
34209
|
+
Show a themed headline + collapse the raw lines into the work log. */
|
|
34210
|
+
.vr-agent-answer-raw { display: flex; flex-direction: column; gap: 6px; }
|
|
34211
|
+
.vr-agent-raw-headline {
|
|
34212
|
+
margin: 0;
|
|
34213
|
+
font-weight: 700;
|
|
34214
|
+
color: var(--vr-gold-bright);
|
|
34215
|
+
}
|
|
34216
|
+
.vr-agent-raw-sub {
|
|
34217
|
+
margin: 0 0 4px;
|
|
34218
|
+
font-size: 12px;
|
|
34219
|
+
color: var(--vr-muted);
|
|
34220
|
+
}
|
|
34221
|
+
|
|
33914
34222
|
/* Retire legacy state styling: the frame never changes with state.
|
|
33915
34223
|
Only the three non-rail sides \u2014 border-left stays the signal color. */
|
|
33916
34224
|
.vr-chat-agent-response.is-ready,
|
|
@@ -34824,7 +35132,7 @@ button.vr-chat-gate-chip.vr-stamp i { display: none; }
|
|
|
34824
35132
|
Provider dots and version chips are untouched by design.
|
|
34825
35133
|
========================================================================== */
|
|
34826
35134
|
:root {
|
|
34827
|
-
--vr-display: "Bahnschrift SemiCondensed", "Bahnschrift", "Avenir Next Condensed", "Arial Narrow", "Segoe UI", sans-serif;
|
|
35135
|
+
--vr-display: "Anton", "Bahnschrift SemiCondensed", "Bahnschrift", "Avenir Next Condensed", "Arial Narrow", "Segoe UI", sans-serif;
|
|
34828
35136
|
--vr-ink: rgba(232, 193, 90, 0.6);
|
|
34829
35137
|
}
|
|
34830
35138
|
|
|
@@ -34903,13 +35211,15 @@ button.vr-chat-gate-chip.vr-stamp i { display: none; }
|
|
|
34903
35211
|
HUD layer: full conversion \u2014 the display voice and flat tags everywhere.
|
|
34904
35212
|
========================================================================== */
|
|
34905
35213
|
|
|
34906
|
-
/*
|
|
35214
|
+
/* Buttons default to the READABLE sans (was condensed display caps \u2014 the #1
|
|
35215
|
+
readability complaint). Marquee buttons (tabs, big CTAs) opt back into Anton
|
|
35216
|
+
via their own higher-specificity rules in the readability pass. */
|
|
34907
35217
|
.vr-composed-shell button:not(.vr-stamp),
|
|
34908
35218
|
.vr-modal-card button:not(.vr-stamp),
|
|
34909
35219
|
.vr-composed-shell .vr-agent-inline-action {
|
|
34910
|
-
font-family: var(--vr-
|
|
34911
|
-
text-transform:
|
|
34912
|
-
letter-spacing: 0.
|
|
35220
|
+
font-family: var(--vr-hud-sans, 'Geist', 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif);
|
|
35221
|
+
text-transform: none;
|
|
35222
|
+
letter-spacing: 0.01em;
|
|
34913
35223
|
}
|
|
34914
35224
|
|
|
34915
35225
|
/* Kill the pill: every badge/chip/tag becomes a flat mono tag.
|
|
@@ -35288,7 +35598,7 @@ button.vr-tcard { appearance: none; }
|
|
|
35288
35598
|
border: 2.5px solid #a8743a;
|
|
35289
35599
|
background:
|
|
35290
35600
|
radial-gradient(circle at 50% 42%, rgba(232, 193, 90, 0.12), transparent 60%),
|
|
35291
|
-
repeating-linear-gradient(45deg, #
|
|
35601
|
+
repeating-linear-gradient(45deg, #141418, #141418 7px, #1b1b22 7px, #1b1b22 14px);
|
|
35292
35602
|
align-items: center;
|
|
35293
35603
|
justify-content: center;
|
|
35294
35604
|
gap: 6px;
|
|
@@ -35343,10 +35653,10 @@ button.vr-tcard { appearance: none; }
|
|
|
35343
35653
|
}
|
|
35344
35654
|
|
|
35345
35655
|
.vr-tcard[data-foil='sentry'] {
|
|
35346
|
-
background: linear-gradient(160deg, #ffe3ea, #c2405e 30%, #ffd4de 52%, #
|
|
35656
|
+
background: linear-gradient(160deg, #ffe3ea, #c2405e 30%, #ffd4de 52%, #343040 78%, #ffd76e);
|
|
35347
35657
|
}
|
|
35348
35658
|
.vr-tcard[data-foil='sentry'] .vr-tcard-artwin {
|
|
35349
|
-
background: radial-gradient(circle at 50% 42%, #
|
|
35659
|
+
background: radial-gradient(circle at 50% 42%, #2b2732, #170a10 78%);
|
|
35350
35660
|
}
|
|
35351
35661
|
.vr-tcard[data-foil='sentry'] .vr-tcard-artwin .vr-provider-token.is-tcard {
|
|
35352
35662
|
filter: drop-shadow(0 0 9px #ff8fa8);
|
|
@@ -35494,7 +35804,7 @@ button.vr-tcard { appearance: none; }
|
|
|
35494
35804
|
place-items: center;
|
|
35495
35805
|
border: 1.5px solid var(--vr-border);
|
|
35496
35806
|
border-radius: 10px;
|
|
35497
|
-
background: rgba(
|
|
35807
|
+
background: rgba(13, 12, 16, 0.55);
|
|
35498
35808
|
color: var(--vr-muted);
|
|
35499
35809
|
cursor: pointer;
|
|
35500
35810
|
transition: border-color 100ms ease, color 100ms ease, transform 100ms ease;
|
|
@@ -35557,7 +35867,7 @@ button.vr-tcard { appearance: none; }
|
|
|
35557
35867
|
padding: 12px;
|
|
35558
35868
|
border: 2.5px solid var(--vr-gold);
|
|
35559
35869
|
border-radius: 50%;
|
|
35560
|
-
background: radial-gradient(circle at 40% 35%, #
|
|
35870
|
+
background: radial-gradient(circle at 40% 35%, #17171c, #0b0b0d);
|
|
35561
35871
|
box-shadow: 0 0 16px rgba(232, 193, 90, 0.3);
|
|
35562
35872
|
transition: transform 120ms ease, box-shadow 120ms ease;
|
|
35563
35873
|
}
|
|
@@ -35583,7 +35893,7 @@ button.vr-tcard { appearance: none; }
|
|
|
35583
35893
|
border: none;
|
|
35584
35894
|
border-radius: 0;
|
|
35585
35895
|
background:
|
|
35586
|
-
radial-gradient(ellipse 65% 50% at 25% 0%, rgba(
|
|
35896
|
+
radial-gradient(ellipse 65% 50% at 25% 0%, rgba(232, 193, 90, 0.2), transparent 65%),
|
|
35587
35897
|
radial-gradient(ellipse 50% 45% at 88% 75%, rgba(255, 170, 60, 0.14), transparent 65%),
|
|
35588
35898
|
var(--vr-bg);
|
|
35589
35899
|
}
|
|
@@ -35663,11 +35973,11 @@ button.vr-tcard { appearance: none; }
|
|
|
35663
35973
|
inset: 8px 12px 6px 4px;
|
|
35664
35974
|
border-radius: 30px;
|
|
35665
35975
|
background:
|
|
35666
|
-
radial-gradient(ellipse 85% 75% at 50% 42%, rgba(
|
|
35667
|
-
#
|
|
35976
|
+
radial-gradient(ellipse 85% 75% at 50% 42%, rgba(24, 24, 30, 0.92), rgba(12, 12, 16, 0.96) 78%),
|
|
35977
|
+
#0e0e12;
|
|
35668
35978
|
border: 2px solid rgba(232, 193, 90, 0.32);
|
|
35669
35979
|
box-shadow:
|
|
35670
|
-
inset 0 0 0 7px rgba(
|
|
35980
|
+
inset 0 0 0 7px rgba(26, 24, 30, 0.95),
|
|
35671
35981
|
inset 0 0 0 9px rgba(232, 193, 90, 0.14),
|
|
35672
35982
|
inset 0 0 90px rgba(0, 0, 0, 0.55),
|
|
35673
35983
|
0 24px 60px rgba(0, 0, 0, 0.55);
|
|
@@ -35871,7 +36181,7 @@ button.vr-tcard { appearance: none; }
|
|
|
35871
36181
|
padding: 10px 14px;
|
|
35872
36182
|
border: 1.5px solid rgba(255, 184, 77, 0.55);
|
|
35873
36183
|
border-radius: 10px;
|
|
35874
|
-
background: rgba(
|
|
36184
|
+
background: rgba(34, 30, 24, 0.5);
|
|
35875
36185
|
color: var(--vr-text);
|
|
35876
36186
|
font-size: 12.5px;
|
|
35877
36187
|
}
|
|
@@ -36059,7 +36369,7 @@ button.vr-tcard { appearance: none; }
|
|
|
36059
36369
|
/* chats flyout: opaque, above the table views, clicks land on it */
|
|
36060
36370
|
.vr-left-context-rail.is-table-rail { z-index: 60; }
|
|
36061
36371
|
.vr-chats-flyout {
|
|
36062
|
-
background: #
|
|
36372
|
+
background: #0e0e12;
|
|
36063
36373
|
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.75), 0 0 0 1px rgba(232, 193, 90, 0.12);
|
|
36064
36374
|
z-index: 90;
|
|
36065
36375
|
}
|
|
@@ -36107,7 +36417,7 @@ button.vr-tcard { appearance: none; }
|
|
|
36107
36417
|
background:
|
|
36108
36418
|
linear-gradient(160deg, rgba(232, 193, 90, 0.12), transparent 45%),
|
|
36109
36419
|
var(--vr-plate);
|
|
36110
|
-
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.5), inset 0 0 0 1.5px rgba(
|
|
36420
|
+
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.5), inset 0 0 0 1.5px rgba(15, 14, 18, 0.9), inset 0 0 0 2.5px rgba(232, 193, 90, 0.2);
|
|
36111
36421
|
padding: 10px 12px;
|
|
36112
36422
|
}
|
|
36113
36423
|
.vr-studio-architecture.is-region-map .vr-arch-node:not(.is-card) strong {
|
|
@@ -36117,7 +36427,7 @@ button.vr-tcard { appearance: none; }
|
|
|
36117
36427
|
}
|
|
36118
36428
|
.vr-studio-architecture.is-region-map .vr-arch-node:not(.is-card):hover {
|
|
36119
36429
|
border-color: var(--vr-gold);
|
|
36120
|
-
box-shadow: 0 12px 26px rgba(0, 0, 0, 0.55), 0 0 16px rgba(232, 193, 90, 0.25), inset 0 0 0 1.5px rgba(
|
|
36430
|
+
box-shadow: 0 12px 26px rgba(0, 0, 0, 0.55), 0 0 16px rgba(232, 193, 90, 0.25), inset 0 0 0 1.5px rgba(15, 14, 18, 0.9), inset 0 0 0 2.5px rgba(232, 193, 90, 0.3);
|
|
36121
36431
|
}
|
|
36122
36432
|
/* chat messages wear the card chrome */
|
|
36123
36433
|
.vr-chat-message.is-agent.vr-hud-card,
|
|
@@ -36253,7 +36563,7 @@ button.vr-tcard { appearance: none; }
|
|
|
36253
36563
|
background-size: 7px 7px;
|
|
36254
36564
|
}
|
|
36255
36565
|
.vr-qs-card[data-step='1'] .vr-qs-art { background: radial-gradient(circle at 50% 42%, #1f5a35, #08170e 78%); }
|
|
36256
|
-
.vr-qs-card[data-step='3'] .vr-qs-art { background: radial-gradient(circle at 50% 42%, #
|
|
36566
|
+
.vr-qs-card[data-step='3'] .vr-qs-art { background: radial-gradient(circle at 50% 42%, #2b2732, #170608 78%); }
|
|
36257
36567
|
.vr-qs-card[data-step='4'] .vr-qs-art { background: radial-gradient(circle at 50% 42%, #1c3a5a, #060e17 78%); }
|
|
36258
36568
|
.vr-qs-glyph { position: relative; }
|
|
36259
36569
|
.vr-qs-glyph i[data-icon] { width: 30px; height: 30px; color: #ffe9ad; filter: drop-shadow(0 0 9px rgba(255, 233, 173, 0.8)); }
|
|
@@ -36440,10 +36750,10 @@ button.vr-tcard { appearance: none; }
|
|
|
36440
36750
|
========================================================================== */
|
|
36441
36751
|
.vr-studio-architecture.is-region-map {
|
|
36442
36752
|
background:
|
|
36443
|
-
radial-gradient(ellipse 85% 75% at 50% 42%, rgba(
|
|
36444
|
-
#
|
|
36753
|
+
radial-gradient(ellipse 85% 75% at 50% 42%, rgba(24, 24, 30, 0.92), rgba(12, 12, 16, 0.96) 78%),
|
|
36754
|
+
#0e0e12;
|
|
36445
36755
|
box-shadow:
|
|
36446
|
-
inset 0 0 0 7px rgba(
|
|
36756
|
+
inset 0 0 0 7px rgba(26, 24, 30, 0.95),
|
|
36447
36757
|
inset 0 0 0 9px rgba(232, 193, 90, 0.14),
|
|
36448
36758
|
inset 0 0 90px rgba(0, 0, 0, 0.55);
|
|
36449
36759
|
border-radius: 22px;
|
|
@@ -36649,7 +36959,7 @@ button.vr-tcard { appearance: none; }
|
|
|
36649
36959
|
width: min(460px, 92%);
|
|
36650
36960
|
border: 2px solid var(--vr-border-strong);
|
|
36651
36961
|
border-radius: 14px;
|
|
36652
|
-
background: #
|
|
36962
|
+
background: #0e0e12;
|
|
36653
36963
|
box-shadow: 0 22px 48px rgba(0, 0, 0, 0.7), 0 0 24px rgba(232, 193, 90, 0.15);
|
|
36654
36964
|
overflow: hidden;
|
|
36655
36965
|
}
|
|
@@ -36790,32 +37100,54 @@ button.vr-tcard { appearance: none; }
|
|
|
36790
37100
|
z-index: 25;
|
|
36791
37101
|
display: flex;
|
|
36792
37102
|
align-items: center;
|
|
36793
|
-
gap:
|
|
37103
|
+
gap: 14px;
|
|
36794
37104
|
margin: 0;
|
|
36795
|
-
padding: 4px
|
|
36796
|
-
border:
|
|
36797
|
-
|
|
36798
|
-
background: rgba(20, 7, 8, 0.62);
|
|
36799
|
-
pointer-events: none;
|
|
37105
|
+
padding: 5px 8px 5px 4px;
|
|
37106
|
+
border: 0;
|
|
37107
|
+
background: none;
|
|
36800
37108
|
white-space: nowrap;
|
|
36801
37109
|
max-width: 100%;
|
|
36802
37110
|
overflow: hidden;
|
|
36803
37111
|
}
|
|
37112
|
+
.vr-ribbon-brand { display: flex; align-items: center; gap: 8px; }
|
|
36804
37113
|
.vr-table-ribbon strong {
|
|
36805
|
-
font-family: var(--
|
|
36806
|
-
font-size:
|
|
36807
|
-
font-weight:
|
|
36808
|
-
letter-spacing:
|
|
36809
|
-
color: var(--vr-
|
|
37114
|
+
font-family: var(--mg-display);
|
|
37115
|
+
font-size: 13px;
|
|
37116
|
+
font-weight: 400;
|
|
37117
|
+
letter-spacing: 1.5px;
|
|
37118
|
+
color: var(--vr-text);
|
|
37119
|
+
}
|
|
37120
|
+
/* the stats row that replaced the old crimson ribbon text */
|
|
37121
|
+
.vr-ribbon-stats { display: flex; align-items: stretch; gap: 0; }
|
|
37122
|
+
.vr-ribbon-stat {
|
|
37123
|
+
display: flex;
|
|
37124
|
+
flex-direction: column;
|
|
37125
|
+
justify-content: center;
|
|
37126
|
+
padding: 2px 13px;
|
|
37127
|
+
border-left: 1px solid var(--vr-border);
|
|
37128
|
+
}
|
|
37129
|
+
.vr-ribbon-stat:first-child { border-left: 0; }
|
|
37130
|
+
.vr-ribbon-stat b {
|
|
37131
|
+
font-family: var(--mg-display);
|
|
37132
|
+
font-weight: 400;
|
|
37133
|
+
font-size: 16px;
|
|
37134
|
+
line-height: 1;
|
|
37135
|
+
color: var(--vr-text);
|
|
36810
37136
|
}
|
|
36811
|
-
.vr-
|
|
37137
|
+
.vr-ribbon-stat i {
|
|
36812
37138
|
font-style: normal;
|
|
37139
|
+
margin-top: 3px;
|
|
36813
37140
|
font-family: var(--vr-hud-mono);
|
|
36814
|
-
font-size:
|
|
36815
|
-
|
|
36816
|
-
|
|
37141
|
+
font-size: 8.5px;
|
|
37142
|
+
font-weight: 600;
|
|
37143
|
+
letter-spacing: 0.08em;
|
|
36817
37144
|
text-transform: uppercase;
|
|
37145
|
+
color: var(--vr-muted);
|
|
36818
37146
|
}
|
|
37147
|
+
.vr-ribbon-stat.is-gold b { color: var(--vr-gold-bright); }
|
|
37148
|
+
.vr-ribbon-stat.is-green b { color: var(--vr-green); }
|
|
37149
|
+
.vr-ribbon-stat.is-orange b { color: var(--vr-orange); }
|
|
37150
|
+
.vr-ribbon-stat.is-muted b { color: rgba(244, 241, 232, 0.55); }
|
|
36819
37151
|
.vr-chat-lane.is-primary .vr-chat-transcript { padding-top: 16px; }
|
|
36820
37152
|
|
|
36821
37153
|
/* -- the card dock: a SLIM strip on the table rim, like a real card game.
|
|
@@ -37396,6 +37728,29 @@ button.vr-tcard { appearance: none; }
|
|
|
37396
37728
|
.vr-discover-card.is-flipped[data-rank='legendary'] .vr-flip-face .vr-tcard { animation: vr-reveal-legendary 1100ms ease-out 240ms both; }
|
|
37397
37729
|
.vr-discover-card.is-flipped[data-rank='epic'] .vr-flip-face .vr-tcard { animation: vr-reveal-epic 1100ms ease-out 240ms both; }
|
|
37398
37730
|
.vr-discover-card.is-flipped[data-rank='rare'] .vr-flip-face .vr-tcard { animation: vr-reveal-rare 1100ms ease-out 240ms both; }
|
|
37731
|
+
/* --- pack-opening polish --- */
|
|
37732
|
+
/* contain the collector raven so it never overlaps the first card + separate the header */
|
|
37733
|
+
.vr-modal-discover .vr-qs-head {
|
|
37734
|
+
align-items: center;
|
|
37735
|
+
gap: 16px;
|
|
37736
|
+
margin: 0 0 16px;
|
|
37737
|
+
padding-bottom: 14px;
|
|
37738
|
+
border-bottom: 1px solid rgba(255, 215, 110, 0.14);
|
|
37739
|
+
}
|
|
37740
|
+
.vr-modal-discover .vr-qs-raven { width: 72px; height: 72px; }
|
|
37741
|
+
/* COMMON tier (silver) so the pack reads like a real spread, not all-RARE */
|
|
37742
|
+
.vr-discover-card[data-rank='common'] .vr-discover-rank { color: #cbd5e1; text-shadow: 0 0 6px rgba(148, 163, 184, 0.55); }
|
|
37743
|
+
@keyframes vr-reveal-common {
|
|
37744
|
+
0% { box-shadow: 0 0 0 rgba(148, 163, 184, 0); }
|
|
37745
|
+
35% { box-shadow: 0 0 24px rgba(203, 213, 225, 0.55), 0 0 48px rgba(148, 163, 184, 0.28); }
|
|
37746
|
+
100% { box-shadow: 0 0 8px rgba(148, 163, 184, 0.22); }
|
|
37747
|
+
}
|
|
37748
|
+
.vr-discover-card.is-flipped[data-rank='common'] .vr-flip-face .vr-tcard { animation: vr-reveal-common 1000ms ease-out 240ms both; }
|
|
37749
|
+
/* Hearthstone-style: a rare pull jumps forward as it flips (not on stable re-renders) */
|
|
37750
|
+
.vr-modal-card:not(.is-stable-render) .vr-discover-card.is-flipped[data-rank='legendary'] { animation: vr-pop-hi 720ms cubic-bezier(0.2, 1.5, 0.3, 1) 180ms both; z-index: 5; }
|
|
37751
|
+
.vr-modal-card:not(.is-stable-render) .vr-discover-card.is-flipped[data-rank='epic'] { animation: vr-pop-mid 660ms cubic-bezier(0.2, 1.45, 0.3, 1) 180ms both; z-index: 4; }
|
|
37752
|
+
@keyframes vr-pop-hi { 0%, 100% { transform: scale(1); } 45% { transform: scale(1.16); } }
|
|
37753
|
+
@keyframes vr-pop-mid { 0%, 100% { transform: scale(1); } 45% { transform: scale(1.1); } }
|
|
37399
37754
|
.vr-discover-take {
|
|
37400
37755
|
border-color: var(--vr-gold-bright) !important;
|
|
37401
37756
|
background: var(--vr-gold-bright) !important;
|
|
@@ -37413,7 +37768,7 @@ button.vr-tcard { appearance: none; }
|
|
|
37413
37768
|
background:
|
|
37414
37769
|
radial-gradient(circle at 50% 42%, rgba(232, 193, 90, 0.35), rgba(232, 193, 90, 0.08) 32%, transparent 44%),
|
|
37415
37770
|
repeating-radial-gradient(circle at 50% 42%, rgba(232, 193, 90, 0.1) 0 2px, transparent 2px 10px),
|
|
37416
|
-
radial-gradient(ellipse at 50% 44%, #
|
|
37771
|
+
radial-gradient(ellipse at 50% 44%, #17171c, #0e0e12 82%);
|
|
37417
37772
|
}
|
|
37418
37773
|
.vr-qs-back img { width: 54px; height: 54px; opacity: 0.9; }
|
|
37419
37774
|
.vr-qs-back b {
|
|
@@ -37514,8 +37869,8 @@ button.vr-tcard { appearance: none; }
|
|
|
37514
37869
|
background:
|
|
37515
37870
|
radial-gradient(circle at 50% 44%, rgba(232, 193, 90, 0.42), rgba(232, 193, 90, 0.1) 36%, transparent 50%),
|
|
37516
37871
|
repeating-radial-gradient(circle at 50% 44%, rgba(232, 193, 90, 0.1) 0 2px, transparent 2px 11px),
|
|
37517
|
-
conic-gradient(from 210deg at 50% 46%, #
|
|
37518
|
-
#
|
|
37872
|
+
conic-gradient(from 210deg at 50% 46%, #17171d, #232329 22%, #18181f 48%, #20202a 74%, #17171d),
|
|
37873
|
+
#0e0e12;
|
|
37519
37874
|
}
|
|
37520
37875
|
.vr-tcard.is-back::after {
|
|
37521
37876
|
content: '';
|
|
@@ -37572,117 +37927,2295 @@ button.vr-tcard { appearance: none; }
|
|
|
37572
37927
|
margin: 0;
|
|
37573
37928
|
}
|
|
37574
37929
|
.vr-discover-grid { gap: 40px 14px; padding-bottom: 30px; }
|
|
37575
|
-
`;
|
|
37576
|
-
}
|
|
37577
|
-
});
|
|
37578
37930
|
|
|
37579
|
-
|
|
37580
|
-
|
|
37581
|
-
|
|
37931
|
+
/* ==========================================================================
|
|
37932
|
+
manga ink pass \u2014 the display voice becomes Anton. The HUD layer above set
|
|
37933
|
+
headings to Bahnschrift (a generic condensed); this final override swaps the
|
|
37934
|
+
marquee surfaces to the real loaded poster face so the Studio reads manga,
|
|
37935
|
+
not "condensed sans." Buttons and small labels stay Bahnschrift for
|
|
37936
|
+
legibility \u2014 Anton at 11px all-caps turns to mud.
|
|
37937
|
+
========================================================================== */
|
|
37938
|
+
.vr-composed-shell h1,
|
|
37939
|
+
.vr-composed-shell h2,
|
|
37940
|
+
.vr-composed-shell h3,
|
|
37941
|
+
.vr-modal-card h2,
|
|
37942
|
+
.vr-modal-card h3,
|
|
37943
|
+
.vr-quickstrike header,
|
|
37944
|
+
.vr-rail-launcher strong,
|
|
37945
|
+
.vr-arch-node > div strong,
|
|
37946
|
+
.vr-studio-architecture.is-region-map .vr-arch-node:not(.is-card) strong,
|
|
37947
|
+
.vr-card-portrait strong {
|
|
37948
|
+
font-family: var(--mg-display);
|
|
37949
|
+
text-transform: uppercase;
|
|
37950
|
+
letter-spacing: 0.03em;
|
|
37951
|
+
font-weight: 400;
|
|
37952
|
+
/* faint gold ink bleed so the poster type sits on the felt, not above it */
|
|
37953
|
+
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
|
|
37582
37954
|
}
|
|
37583
|
-
|
|
37584
|
-
|
|
37585
|
-
|
|
37586
|
-
|
|
37587
|
-
|
|
37588
|
-
|
|
37589
|
-
|
|
37590
|
-
|
|
37591
|
-
|
|
37592
|
-
|
|
37593
|
-
|
|
37594
|
-
|
|
37595
|
-
|
|
37596
|
-
|
|
37597
|
-
|
|
37598
|
-
|
|
37599
|
-
|
|
37600
|
-
|
|
37601
|
-
|
|
37602
|
-
|
|
37955
|
+
/* Anton has no bold \u2014 its native weight already reads heavy. Give the big
|
|
37956
|
+
section headers a touch more air so the caps don't crowd. */
|
|
37957
|
+
.vr-composed-shell h1 { letter-spacing: 0.02em; }
|
|
37958
|
+
|
|
37959
|
+
/* ==========================================================================
|
|
37960
|
+
manga chat: the VibeRaven voice wears the fierce raven emblem (refs 1 & 3
|
|
37961
|
+
put the raven bust beside the agent output). The coin frames the raven's
|
|
37962
|
+
face out of the transparent emblem; a gold ring seats it as an avatar.
|
|
37963
|
+
========================================================================== */
|
|
37964
|
+
.vr-story-node.has-raven .vr-story-dot {
|
|
37965
|
+
width: 34px;
|
|
37966
|
+
height: 34px;
|
|
37967
|
+
padding: 0;
|
|
37968
|
+
overflow: hidden;
|
|
37969
|
+
border: 1.5px solid var(--vr-border-strong);
|
|
37970
|
+
background: radial-gradient(circle at 50% 40%, #1a1a1f, #0a0a0d);
|
|
37971
|
+
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.35), 0 0 12px rgba(232, 193, 90, 0.18);
|
|
37972
|
+
}
|
|
37973
|
+
.vr-raven-coin {
|
|
37974
|
+
width: 100%;
|
|
37975
|
+
height: 100%;
|
|
37976
|
+
object-fit: cover;
|
|
37977
|
+
/* frame the raven's face (right side of the emblem art), not the sign */
|
|
37978
|
+
object-position: 74% 40%;
|
|
37979
|
+
transform: scale(1.55);
|
|
37980
|
+
}
|
|
37981
|
+
.vr-story-node.is-error.has-raven .vr-story-dot { border-color: rgba(239, 68, 68, 0.6); }
|
|
37982
|
+
/* the intro card's inline raven badge */
|
|
37983
|
+
.vr-chat-intro-message .vr-intro-raven {
|
|
37984
|
+
display: inline-grid;
|
|
37985
|
+
place-items: center;
|
|
37986
|
+
width: 30px;
|
|
37987
|
+
height: 30px;
|
|
37988
|
+
border-radius: 50%;
|
|
37989
|
+
overflow: hidden;
|
|
37990
|
+
border: 1.5px solid var(--vr-border-strong);
|
|
37991
|
+
background: radial-gradient(circle at 50% 40%, #1a1a1f, #0a0a0d);
|
|
37992
|
+
}
|
|
37993
|
+
.vr-chat-intro-message .vr-intro-raven img {
|
|
37994
|
+
width: 100%;
|
|
37995
|
+
height: 100%;
|
|
37996
|
+
object-fit: cover;
|
|
37997
|
+
object-position: 74% 40%;
|
|
37998
|
+
transform: scale(1.55);
|
|
37603
37999
|
}
|
|
37604
|
-
var init_appHtml = __esm({
|
|
37605
|
-
"src/local-ui/static/appHtml.ts"() {
|
|
37606
|
-
"use strict";
|
|
37607
|
-
init_appClient();
|
|
37608
|
-
init_appCss();
|
|
37609
|
-
}
|
|
37610
|
-
});
|
|
37611
38000
|
|
|
37612
|
-
|
|
37613
|
-
|
|
37614
|
-
|
|
38001
|
+
/* ==========================================================================
|
|
38002
|
+
manga card frame \u2014 match the gold-on-black provider-card asset (refs 3 & 4).
|
|
38003
|
+
Additive over the round-6/7 trading-card anatomy: ink-black inner (kills the
|
|
38004
|
+
last crimson tint at #140a0c), a gold halftone burst behind the glyph, a
|
|
38005
|
+
gold inset double-frame line, and Anton on the card name. Brand-colored
|
|
38006
|
+
glyphs stay (the binder mockup keeps provider colors on the gold frame).
|
|
38007
|
+
========================================================================== */
|
|
38008
|
+
.vr-tcard:not(.is-back) .vr-tcard-inner {
|
|
38009
|
+
background: #0c0c10;
|
|
38010
|
+
/* the second, inner gold line \u2014 reads as the ornate double frame */
|
|
38011
|
+
box-shadow: inset 0 0 0 1px rgba(232, 193, 90, 0.28);
|
|
38012
|
+
}
|
|
38013
|
+
.vr-tcard:not(.is-back) .vr-tcard-artwin {
|
|
38014
|
+
border-color: rgba(232, 193, 90, 0.32);
|
|
38015
|
+
/* gold burst radiating from behind the provider glyph */
|
|
38016
|
+
background:
|
|
38017
|
+
radial-gradient(circle at 50% 46%, rgba(232, 193, 90, 0.22), rgba(232, 193, 90, 0.05) 42%, transparent 68%),
|
|
38018
|
+
#08080b;
|
|
37615
38019
|
}
|
|
37616
|
-
|
|
37617
|
-
|
|
37618
|
-
|
|
37619
|
-
|
|
37620
|
-
|
|
37621
|
-
|
|
37622
|
-
|
|
37623
|
-
|
|
37624
|
-
|
|
37625
|
-
|
|
37626
|
-
|
|
37627
|
-
|
|
37628
|
-
}
|
|
37629
|
-
}
|
|
37630
|
-
return null;
|
|
38020
|
+
/* fine gold sunburst rays over the halftone \u2014 the asset's signature shimmer */
|
|
38021
|
+
.vr-tcard:not(.is-back) .vr-tcard-artwin::after {
|
|
38022
|
+
content: '';
|
|
38023
|
+
position: absolute;
|
|
38024
|
+
inset: 0;
|
|
38025
|
+
background:
|
|
38026
|
+
repeating-conic-gradient(from 0deg at 50% 46%,
|
|
38027
|
+
rgba(232, 193, 90, 0.10) 0deg 2deg, transparent 2deg 10deg);
|
|
38028
|
+
-webkit-mask-image: radial-gradient(circle at 50% 46%, #000 0, transparent 70%);
|
|
38029
|
+
mask-image: radial-gradient(circle at 50% 46%, #000 0, transparent 70%);
|
|
38030
|
+
pointer-events: none;
|
|
38031
|
+
z-index: 0;
|
|
37631
38032
|
}
|
|
37632
|
-
|
|
37633
|
-
|
|
37634
|
-
|
|
37635
|
-
|
|
37636
|
-
|
|
37637
|
-
|
|
37638
|
-
|
|
37639
|
-
try {
|
|
37640
|
-
const raw = await (0, import_promises23.readFile)(configPath, "utf8");
|
|
37641
|
-
const parsed = JSON.parse(raw.replace(/^\uFEFF/, ""));
|
|
37642
|
-
if (isRecord4(parsed)) config = parsed;
|
|
37643
|
-
} catch {
|
|
37644
|
-
}
|
|
37645
|
-
const servers = isRecord4(config.mcpServers) ? { ...config.mcpServers } : {};
|
|
37646
|
-
if (servers[providerId]) {
|
|
37647
|
-
return { ok: true, message: `${providerId} MCP server already configured in .mcp.json.`, path: ".mcp.json" };
|
|
37648
|
-
}
|
|
37649
|
-
servers[providerId] = recipe.entry;
|
|
37650
|
-
const next = { ...config, mcpServers: servers };
|
|
37651
|
-
await (0, import_promises23.writeFile)(configPath, `${JSON.stringify(next, null, 2)}
|
|
37652
|
-
`, "utf8");
|
|
37653
|
-
const suffix = recipe.note ? ` ${recipe.note}` : "";
|
|
37654
|
-
return { ok: true, message: `Added ${providerId} MCP server to .mcp.json.${suffix}`, path: ".mcp.json" };
|
|
38033
|
+
.vr-tcard:not(.is-back) .vr-tcard-artwin .vr-provider-token.is-tcard { z-index: 1; }
|
|
38034
|
+
/* card name speaks the poster face */
|
|
38035
|
+
.vr-tcard-head b {
|
|
38036
|
+
font-family: var(--mg-display);
|
|
38037
|
+
font-weight: 400;
|
|
38038
|
+
letter-spacing: 0.03em;
|
|
38039
|
+
color: var(--vr-gold-bright);
|
|
37655
38040
|
}
|
|
37656
|
-
|
|
37657
|
-
|
|
37658
|
-
|
|
38041
|
+
/* corner ticks: four gold L-brackets tucked into the frame corners */
|
|
38042
|
+
.vr-tcard:not(.is-back) .vr-tcard-inner::before {
|
|
38043
|
+
content: '';
|
|
38044
|
+
position: absolute;
|
|
38045
|
+
inset: 3px;
|
|
38046
|
+
pointer-events: none;
|
|
38047
|
+
z-index: 3;
|
|
38048
|
+
background:
|
|
38049
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) left top,
|
|
38050
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) left top,
|
|
38051
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) right top,
|
|
38052
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) right top,
|
|
38053
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) left bottom,
|
|
38054
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) left bottom,
|
|
38055
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) right bottom,
|
|
38056
|
+
linear-gradient(var(--vr-gold-bright), var(--vr-gold-bright)) right bottom;
|
|
38057
|
+
background-repeat: no-repeat;
|
|
38058
|
+
background-size: 10px 2px, 2px 10px;
|
|
38059
|
+
opacity: 0.9;
|
|
38060
|
+
}
|
|
38061
|
+
|
|
38062
|
+
/* THE collector redesign: the frame is always GOLD FOIL (like the binder
|
|
38063
|
+
mockup + the gold-on-black provider-card asset). Provider colour lives only
|
|
38064
|
+
in the art-window burst and the glyph glow \u2014 not the frame. This is what
|
|
38065
|
+
turns the cards from "casino colored rectangle" into "premium graded slab". */
|
|
38066
|
+
.vr-tcard[data-foil]:not(.is-back) {
|
|
38067
|
+
background: var(--vr-foil);
|
|
37659
38068
|
}
|
|
37660
|
-
|
|
37661
|
-
|
|
37662
|
-
|
|
37663
|
-
|
|
37664
|
-
|
|
37665
|
-
|
|
37666
|
-
return {};
|
|
37667
|
-
}
|
|
38069
|
+
.vr-tcard:not(.is-back) {
|
|
38070
|
+
border-radius: 12px;
|
|
38071
|
+
box-shadow:
|
|
38072
|
+
0 10px 24px rgba(0, 0, 0, 0.6),
|
|
38073
|
+
inset 0 0 0 1px rgba(0, 0, 0, 0.4),
|
|
38074
|
+
inset 0 0 0 2px rgba(255, 233, 173, 0.35);
|
|
37668
38075
|
}
|
|
37669
|
-
|
|
37670
|
-
|
|
37671
|
-
|
|
37672
|
-
|
|
37673
|
-
|
|
37674
|
-
|
|
37675
|
-
}
|
|
37676
|
-
return names;
|
|
38076
|
+
.vr-tcard:not(.is-back):hover {
|
|
38077
|
+
box-shadow:
|
|
38078
|
+
0 16px 32px rgba(0, 0, 0, 0.65),
|
|
38079
|
+
0 0 20px rgba(232, 193, 90, 0.4),
|
|
38080
|
+
inset 0 0 0 1px rgba(0, 0, 0, 0.4),
|
|
38081
|
+
inset 0 0 0 2px rgba(255, 233, 173, 0.5);
|
|
37677
38082
|
}
|
|
37678
|
-
|
|
37679
|
-
|
|
37680
|
-
|
|
37681
|
-
|
|
37682
|
-
|
|
37683
|
-
|
|
37684
|
-
|
|
37685
|
-
|
|
38083
|
+
/* the RAVEN GRADE line reads like a graded-slab label bar */
|
|
38084
|
+
.vr-tcard-grade {
|
|
38085
|
+
color: #241207;
|
|
38086
|
+
background: linear-gradient(180deg, #f6eed9, #e2d0a8);
|
|
38087
|
+
border-radius: 3px;
|
|
38088
|
+
padding: 2px 6px;
|
|
38089
|
+
font-weight: 700;
|
|
38090
|
+
}
|
|
38091
|
+
|
|
38092
|
+
/* ==========================================================================
|
|
38093
|
+
manga hero watermark \u2014 the empty chat void gets a faint raven emblem
|
|
38094
|
+
bleeding in from the right, like the faded raven behind the mockup chat.
|
|
38095
|
+
Fills dead space and carries the manga presence without hurting readability.
|
|
38096
|
+
========================================================================== */
|
|
38097
|
+
.vr-chat-lane.is-primary { position: relative; }
|
|
38098
|
+
/* keep the messages above any lane background */
|
|
38099
|
+
.vr-chat-lane.is-primary > * { position: relative; z-index: 1; }
|
|
38100
|
+
|
|
38101
|
+
/* ==========================================================================
|
|
38102
|
+
manga agent message \u2014 the screenshot-5 styling on REAL answers: a fierce
|
|
38103
|
+
raven avatar, an "AI AGENT" badge, and a faded raven bleeding behind the
|
|
38104
|
+
message (like the eye behind the mockup chat). No fake data.
|
|
38105
|
+
========================================================================== */
|
|
38106
|
+
.vr-chat-agent-response { position: relative; overflow: hidden; }
|
|
38107
|
+
.vr-chat-agent-response::before {
|
|
38108
|
+
content: '';
|
|
38109
|
+
position: absolute;
|
|
38110
|
+
right: -70px;
|
|
38111
|
+
top: 50%;
|
|
38112
|
+
transform: translateY(-50%);
|
|
38113
|
+
width: 340px;
|
|
38114
|
+
height: 340px;
|
|
38115
|
+
background: url('/manga/emblem.png') no-repeat center / contain;
|
|
38116
|
+
opacity: 0.06;
|
|
38117
|
+
pointer-events: none;
|
|
38118
|
+
z-index: 0;
|
|
38119
|
+
}
|
|
38120
|
+
.vr-chat-agent-response > * { position: relative; z-index: 1; }
|
|
38121
|
+
.vr-hud-avatar.is-raven {
|
|
38122
|
+
width: 34px;
|
|
38123
|
+
height: 34px;
|
|
38124
|
+
border-radius: 50%;
|
|
38125
|
+
overflow: hidden;
|
|
38126
|
+
border: 1.5px solid var(--vr-border-strong);
|
|
38127
|
+
background: radial-gradient(circle at 50% 40%, #1a1a1f, #0a0a0d);
|
|
38128
|
+
box-shadow: 0 0 12px rgba(232, 193, 90, 0.18);
|
|
38129
|
+
flex: none;
|
|
38130
|
+
}
|
|
38131
|
+
.vr-hud-avatar.is-raven img {
|
|
38132
|
+
width: 100%;
|
|
38133
|
+
height: 100%;
|
|
38134
|
+
object-fit: cover;
|
|
38135
|
+
object-position: 74% 40%;
|
|
38136
|
+
transform: scale(1.55);
|
|
38137
|
+
}
|
|
38138
|
+
.vr-hud-aibadge {
|
|
38139
|
+
font-family: var(--vr-hud-mono);
|
|
38140
|
+
font-size: 8.5px;
|
|
38141
|
+
font-weight: 700;
|
|
38142
|
+
letter-spacing: 0.12em;
|
|
38143
|
+
text-transform: uppercase;
|
|
38144
|
+
color: var(--vr-gold-bright);
|
|
38145
|
+
padding: 2px 7px;
|
|
38146
|
+
border-radius: 5px;
|
|
38147
|
+
background: rgba(232, 193, 90, 0.12);
|
|
38148
|
+
box-shadow: inset 0 0 0 1px rgba(232, 193, 90, 0.4);
|
|
38149
|
+
}
|
|
38150
|
+
|
|
38151
|
+
/* ==========================================================================
|
|
38152
|
+
full-art provider cards + holographic foil (the "shiny Pok\xE9mon" effect).
|
|
38153
|
+
The card art (assets/manga/cards/<id>.webp) is the whole face; an
|
|
38154
|
+
iridescent foil + a specular glare sweep ride on top and light up on hover.
|
|
38155
|
+
========================================================================== */
|
|
38156
|
+
.vr-tcard.has-art {
|
|
38157
|
+
padding: 0;
|
|
38158
|
+
border: none;
|
|
38159
|
+
overflow: hidden;
|
|
38160
|
+
border-radius: 11px;
|
|
38161
|
+
background: #000;
|
|
38162
|
+
box-shadow:
|
|
38163
|
+
0 10px 24px rgba(0, 0, 0, 0.6),
|
|
38164
|
+
inset 0 0 0 1px rgba(255, 233, 173, 0.3);
|
|
38165
|
+
}
|
|
38166
|
+
.vr-tcard.has-art .vr-tcard-artfull {
|
|
38167
|
+
display: block;
|
|
38168
|
+
width: 100%;
|
|
38169
|
+
height: 100%;
|
|
38170
|
+
object-fit: cover;
|
|
38171
|
+
border-radius: 11px;
|
|
38172
|
+
}
|
|
38173
|
+
/* iridescent holo foil \u2014 always faintly present, blooms on hover */
|
|
38174
|
+
.vr-tcard-holofoil {
|
|
38175
|
+
position: absolute;
|
|
38176
|
+
inset: 0;
|
|
38177
|
+
border-radius: 11px;
|
|
38178
|
+
pointer-events: none;
|
|
38179
|
+
z-index: 2;
|
|
38180
|
+
background: repeating-linear-gradient(115deg,
|
|
38181
|
+
rgba(255, 110, 150, 0.16) 0 7px,
|
|
38182
|
+
rgba(120, 200, 255, 0.16) 7px 14px,
|
|
38183
|
+
rgba(150, 255, 190, 0.16) 14px 21px,
|
|
38184
|
+
rgba(255, 240, 150, 0.16) 21px 28px);
|
|
38185
|
+
background-size: 220% 220%;
|
|
38186
|
+
mix-blend-mode: color-dodge;
|
|
38187
|
+
opacity: 0.16;
|
|
38188
|
+
transition: opacity 220ms ease;
|
|
38189
|
+
}
|
|
38190
|
+
/* gold sparkle glints over the foil */
|
|
38191
|
+
.vr-tcard-holofoil::after {
|
|
38192
|
+
content: '';
|
|
38193
|
+
position: absolute;
|
|
38194
|
+
inset: 0;
|
|
38195
|
+
border-radius: 11px;
|
|
38196
|
+
background:
|
|
38197
|
+
radial-gradient(circle at 28% 22%, rgba(255, 255, 255, 0.55), transparent 9%),
|
|
38198
|
+
radial-gradient(circle at 72% 58%, rgba(255, 233, 173, 0.5), transparent 8%),
|
|
38199
|
+
radial-gradient(circle at 52% 86%, rgba(255, 255, 255, 0.4), transparent 7%);
|
|
38200
|
+
mix-blend-mode: screen;
|
|
38201
|
+
opacity: 0.28;
|
|
38202
|
+
}
|
|
38203
|
+
/* specular glare bar that sweeps across on hover */
|
|
38204
|
+
.vr-tcard-glare {
|
|
38205
|
+
position: absolute;
|
|
38206
|
+
inset: 0;
|
|
38207
|
+
border-radius: 11px;
|
|
38208
|
+
pointer-events: none;
|
|
38209
|
+
z-index: 3;
|
|
38210
|
+
background: linear-gradient(115deg, transparent 36%, rgba(255, 255, 255, 0.3) 48%, rgba(255, 240, 200, 0.22) 54%, transparent 64%);
|
|
38211
|
+
background-size: 250% 250%;
|
|
38212
|
+
background-position: 120% 0%;
|
|
38213
|
+
opacity: 0;
|
|
38214
|
+
transition: opacity 200ms ease;
|
|
38215
|
+
}
|
|
38216
|
+
.vr-tcard.has-art:hover { transform: translateY(-6px) scale(1.04); }
|
|
38217
|
+
.vr-tcard.has-art:hover .vr-tcard-holofoil { opacity: 0.5; animation: vr-holo-shift 2.6s linear infinite; }
|
|
38218
|
+
.vr-tcard.has-art:hover .vr-tcard-glare { opacity: 1; animation: vr-glare-sweep 1.1s ease; }
|
|
38219
|
+
.vr-tcard.has-art.is-flawless { box-shadow: 0 12px 26px rgba(0, 0, 0, 0.6), 0 0 22px rgba(232, 193, 90, 0.5), inset 0 0 0 1px rgba(255, 233, 173, 0.55); }
|
|
38220
|
+
.vr-tcard.has-art.is-flawless .vr-tcard-holofoil { opacity: 0.34; }
|
|
38221
|
+
@keyframes vr-holo-shift { 0% { background-position: 0% 0%; } 100% { background-position: 220% 220%; } }
|
|
38222
|
+
@keyframes vr-glare-sweep { 0% { background-position: 120% 0%; } 100% { background-position: -40% 0%; } }
|
|
38223
|
+
/* grade medallion \u2014 a clean gold-ringed ink coin that suits the ornate art
|
|
38224
|
+
(was a pill with a colored energy dot that looked tacked-on). */
|
|
38225
|
+
.vr-tcard.has-art .vr-tcard-hp.is-onart {
|
|
38226
|
+
position: absolute;
|
|
38227
|
+
top: 7px;
|
|
38228
|
+
right: 7px;
|
|
38229
|
+
z-index: 4;
|
|
38230
|
+
display: grid;
|
|
38231
|
+
place-items: center;
|
|
38232
|
+
width: 21px;
|
|
38233
|
+
height: 21px;
|
|
38234
|
+
padding: 0;
|
|
38235
|
+
border-radius: 50%;
|
|
38236
|
+
background: radial-gradient(circle at 50% 34%, #2b2721, #0b0a0e);
|
|
38237
|
+
box-shadow: inset 0 0 0 1.5px rgba(255, 233, 173, 0.7), 0 1px 3px rgba(0, 0, 0, 0.6);
|
|
38238
|
+
}
|
|
38239
|
+
.vr-tcard.has-art .vr-tcard-hp.is-onart .vr-tcard-energy { display: none; }
|
|
38240
|
+
.vr-tcard.has-art .vr-tcard-hp.is-onart i {
|
|
38241
|
+
font-family: var(--mg-display);
|
|
38242
|
+
font-style: normal;
|
|
38243
|
+
font-size: 12px;
|
|
38244
|
+
line-height: 1;
|
|
38245
|
+
color: var(--vr-gold-bright);
|
|
38246
|
+
}
|
|
38247
|
+
.vr-tcard.is-hand.has-art .vr-tcard-hp.is-onart { width: 17px; height: 17px; top: 5px; right: 5px; }
|
|
38248
|
+
.vr-tcard.is-hand.has-art .vr-tcard-hp.is-onart i { font-size: 9.5px; }
|
|
38249
|
+
/* the baked art already carries the RAVEN GRADE band; hide the overlay strip */
|
|
38250
|
+
.vr-tcard.has-art .vr-tcard-gradebar { display: none; }
|
|
38251
|
+
|
|
38252
|
+
/* the agent message already carries the raven in its header (.vr-hud-avatar)
|
|
38253
|
+
and the intro carries .vr-intro-raven \u2014 so the timeline story-dot drops back
|
|
38254
|
+
to a small plain node instead of a second, redundant raven coin. */
|
|
38255
|
+
.vr-story-node.has-raven .vr-story-dot {
|
|
38256
|
+
width: 12px;
|
|
38257
|
+
height: 12px;
|
|
38258
|
+
margin-top: 16px;
|
|
38259
|
+
border-color: rgba(232, 193, 90, 0.5);
|
|
38260
|
+
background: radial-gradient(circle, var(--vr-gold) 0 2px, rgba(12, 13, 16, 0.96) 3px);
|
|
38261
|
+
box-shadow: 0 0 8px rgba(232, 193, 90, 0.25);
|
|
38262
|
+
}
|
|
38263
|
+
.vr-story-node.has-raven .vr-story-dot .vr-raven-coin { display: none; }
|
|
38264
|
+
|
|
38265
|
+
/* ==========================================================================
|
|
38266
|
+
manga comic panels \u2014 the real restructure. The chat panels were generic
|
|
38267
|
+
rounded-dark rectangles (why it "looked the same"). Now: hard notched
|
|
38268
|
+
corners (comic-panel cut), a bold gold spine on the left, faint gold
|
|
38269
|
+
halftone screentone inside, and a gold tab behind the header label.
|
|
38270
|
+
Applies to the MISSION cards and the VibeRaven agent answers.
|
|
38271
|
+
========================================================================== */
|
|
38272
|
+
.vr-chat-message.is-user.is-mission,
|
|
38273
|
+
.vr-chat-agent-response {
|
|
38274
|
+
position: relative;
|
|
38275
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
38276
|
+
border-left-width: 3px !important;
|
|
38277
|
+
border-radius: 4px !important;
|
|
38278
|
+
/* two opposite corners cut = comic panel */
|
|
38279
|
+
clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 20px, 100% 100%, 20px 100%, 0 calc(100% - 20px)) !important;
|
|
38280
|
+
background-color: rgba(13, 12, 16, 0.94) !important;
|
|
38281
|
+
background-image:
|
|
38282
|
+
radial-gradient(rgba(232, 193, 90, 0.055) 1px, transparent 1.4px),
|
|
38283
|
+
linear-gradient(160deg, rgba(232, 193, 90, 0.05), transparent 34%) !important;
|
|
38284
|
+
background-size: 9px 9px, auto !important;
|
|
38285
|
+
}
|
|
38286
|
+
/* MISSION panels lean cool-gold, agent panels get the warmer gold spine */
|
|
38287
|
+
.vr-chat-message.is-user.is-mission { border-left-color: var(--vr-gold) !important; }
|
|
38288
|
+
.vr-chat-agent-response.is-blocked { border-left-color: var(--vr-red) !important; }
|
|
38289
|
+
.vr-chat-agent-response.is-nominal { border-left-color: var(--vr-green) !important; }
|
|
38290
|
+
|
|
38291
|
+
/* header labels become inked tabs: MISSION / VIBERAVEN sit on a gold underline */
|
|
38292
|
+
.vr-chat-message.is-user.is-mission .vr-hud-strip strong,
|
|
38293
|
+
.vr-chat-message.is-user.is-mission > header strong,
|
|
38294
|
+
.vr-chat-agent-response .vr-hud-strip strong {
|
|
38295
|
+
position: relative;
|
|
38296
|
+
}
|
|
38297
|
+
.vr-chat-agent-response .vr-hud-strip {
|
|
38298
|
+
border-bottom: 1px solid rgba(232, 193, 90, 0.16);
|
|
38299
|
+
padding-bottom: 7px;
|
|
38300
|
+
margin-bottom: 2px;
|
|
38301
|
+
}
|
|
38302
|
+
/* a small gold corner bracket on the top-left of each panel */
|
|
38303
|
+
.vr-chat-message.is-user.is-mission::after,
|
|
38304
|
+
.vr-chat-agent-response::after {
|
|
38305
|
+
content: '';
|
|
38306
|
+
position: absolute;
|
|
38307
|
+
left: 7px;
|
|
38308
|
+
top: 7px;
|
|
38309
|
+
width: 12px;
|
|
38310
|
+
height: 12px;
|
|
38311
|
+
border-left: 2px solid rgba(232, 193, 90, 0.55);
|
|
38312
|
+
border-top: 2px solid rgba(232, 193, 90, 0.55);
|
|
38313
|
+
pointer-events: none;
|
|
38314
|
+
z-index: 2;
|
|
38315
|
+
}
|
|
38316
|
+
|
|
38317
|
+
/* ==========================================================================
|
|
38318
|
+
composer = a comic panel too (was a soft rounded "old-school" box). Same
|
|
38319
|
+
notched frame + halftone as the chat messages so the column is of-a-piece.
|
|
38320
|
+
========================================================================== */
|
|
38321
|
+
.vr-chat-lane .vr-chat-command-bar > .vr-chat-composer,
|
|
38322
|
+
.vr-studio-chat:not(.is-split) .vr-chat-lane.is-primary .vr-chat-command-bar > .vr-chat-composer {
|
|
38323
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
38324
|
+
border-radius: 5px !important;
|
|
38325
|
+
/* NO clip-path: the model/command/access menus are descendants and a notch
|
|
38326
|
+
here clipped them when they popped up (looked "corrupted"). */
|
|
38327
|
+
background-color: rgba(13, 12, 16, 0.96) !important;
|
|
38328
|
+
background-image: radial-gradient(rgba(232, 193, 90, 0.045) 1px, transparent 1.4px) !important;
|
|
38329
|
+
background-size: 9px 9px !important;
|
|
38330
|
+
box-shadow: 0 0 24px rgba(232, 193, 90, 0.07) !important;
|
|
38331
|
+
overflow: visible !important;
|
|
38332
|
+
}
|
|
38333
|
+
.vr-chat-lane .vr-chat-command-bar > .vr-chat-composer:focus-within {
|
|
38334
|
+
border-color: var(--vr-gold) !important;
|
|
38335
|
+
box-shadow: 0 0 26px rgba(232, 193, 90, 0.16) !important;
|
|
38336
|
+
}
|
|
38337
|
+
|
|
38338
|
+
/* ==========================================================================
|
|
38339
|
+
the OTHER views join the manga theme: worktree branch cards, the commit
|
|
38340
|
+
banner, and the region-map nodes all become comic panels (notched corners,
|
|
38341
|
+
gold frame, halftone). A faded raven bleeds in from the right of the table
|
|
38342
|
+
views like the warrior in the reference mockup.
|
|
38343
|
+
========================================================================== */
|
|
38344
|
+
.vr-bcard {
|
|
38345
|
+
position: relative;
|
|
38346
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
38347
|
+
border-radius: 4px !important;
|
|
38348
|
+
clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px));
|
|
38349
|
+
background-color: rgba(13, 12, 16, 0.95) !important;
|
|
38350
|
+
background-image: radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px) !important;
|
|
38351
|
+
background-size: 9px 9px !important;
|
|
38352
|
+
}
|
|
38353
|
+
.vr-bcard.is-current {
|
|
38354
|
+
border-color: var(--vr-gold) !important;
|
|
38355
|
+
box-shadow: 0 0 18px rgba(232, 193, 90, 0.18);
|
|
38356
|
+
}
|
|
38357
|
+
.vr-table-warning {
|
|
38358
|
+
position: relative;
|
|
38359
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
38360
|
+
border-left: 3px solid var(--vr-gold) !important;
|
|
38361
|
+
border-radius: 4px !important;
|
|
38362
|
+
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
|
|
38363
|
+
background-color: rgba(13, 12, 16, 0.95) !important;
|
|
38364
|
+
background-image:
|
|
38365
|
+
radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px),
|
|
38366
|
+
linear-gradient(160deg, rgba(232, 193, 90, 0.06), transparent 40%) !important;
|
|
38367
|
+
background-size: 9px 9px, auto !important;
|
|
38368
|
+
}
|
|
38369
|
+
/* region-map + architecture nodes get the comic-panel notch + halftone */
|
|
38370
|
+
.vr-arch-node:not(.is-card) {
|
|
38371
|
+
clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 12px 100%, 0 calc(100% - 12px));
|
|
38372
|
+
background-image: radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px) !important;
|
|
38373
|
+
background-size: 8px 8px !important;
|
|
38374
|
+
}
|
|
38375
|
+
/* the raven bleeds in from the right of the worktree/versions/region views */
|
|
38376
|
+
.vr-table-view,
|
|
38377
|
+
.vr-studio-architecture { position: relative; }
|
|
38378
|
+
.vr-table-view::after,
|
|
38379
|
+
.vr-studio-architecture.is-region-map::after {
|
|
38380
|
+
content: '';
|
|
38381
|
+
position: absolute;
|
|
38382
|
+
right: -40px;
|
|
38383
|
+
bottom: -20px;
|
|
38384
|
+
width: 460px;
|
|
38385
|
+
height: 460px;
|
|
38386
|
+
background: url('/manga/emblem.png') no-repeat right bottom / contain;
|
|
38387
|
+
opacity: 0.06;
|
|
38388
|
+
pointer-events: none;
|
|
38389
|
+
z-index: 0;
|
|
38390
|
+
}
|
|
38391
|
+
/* rail logo is the fierce raven, framed to its face */
|
|
38392
|
+
.vr-rail-raven.is-emblem {
|
|
38393
|
+
border-radius: 9px;
|
|
38394
|
+
overflow: hidden;
|
|
38395
|
+
border: 1px solid var(--vr-border-strong);
|
|
38396
|
+
background: radial-gradient(circle at 50% 40%, #1a1a1f, #0a0a0d);
|
|
38397
|
+
}
|
|
38398
|
+
.vr-rail-raven.is-emblem img {
|
|
38399
|
+
width: 100%;
|
|
38400
|
+
height: 100%;
|
|
38401
|
+
object-fit: cover;
|
|
38402
|
+
object-position: 74% 40%;
|
|
38403
|
+
transform: scale(1.5);
|
|
38404
|
+
}
|
|
38405
|
+
|
|
38406
|
+
/* ==========================================================================
|
|
38407
|
+
MANGA THEME PASS \u2014 dropdowns/menus, readability, world background, top bar,
|
|
38408
|
+
modal, chrome. One append block; wins by source order. No !important.
|
|
38409
|
+
========================================================================== */
|
|
38410
|
+
|
|
38411
|
+
/* ----- Area 1: dropdowns & popup menus (kill the white selected row) ----- */
|
|
38412
|
+
.vr-model-picker > button {
|
|
38413
|
+
border: 1px solid var(--vr-border);
|
|
38414
|
+
border-radius: 5px;
|
|
38415
|
+
background-color: rgba(13, 12, 16, 0.95);
|
|
38416
|
+
color: var(--vr-text);
|
|
38417
|
+
}
|
|
38418
|
+
.vr-model-picker > button span { color: var(--vr-muted); }
|
|
38419
|
+
.vr-model-picker > button strong { color: var(--vr-gold-bright); }
|
|
38420
|
+
.vr-model-picker > button i { border-color: var(--vr-gold); }
|
|
38421
|
+
.vr-model-picker > button:hover { border-color: var(--vr-border-strong); background-color: rgba(20, 18, 12, 0.96); }
|
|
38422
|
+
|
|
38423
|
+
.vr-model-menu,
|
|
38424
|
+
.vr-scope-menu,
|
|
38425
|
+
.vr-chat-command-popover {
|
|
38426
|
+
border: 1px solid var(--vr-border-strong);
|
|
38427
|
+
border-left: 3px solid var(--vr-gold);
|
|
38428
|
+
border-radius: 5px;
|
|
38429
|
+
background-color: rgba(10, 10, 13, 0.99);
|
|
38430
|
+
background-image: radial-gradient(rgba(232, 193, 90, 0.045) 1px, transparent 1.4px);
|
|
38431
|
+
background-size: 9px 9px;
|
|
38432
|
+
box-shadow: 4px 6px 0 rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.5);
|
|
38433
|
+
color: var(--vr-text);
|
|
38434
|
+
overflow: hidden;
|
|
38435
|
+
}
|
|
38436
|
+
.vr-model-menu p,
|
|
38437
|
+
.vr-scope-menu p {
|
|
38438
|
+
font-family: var(--mg-display);
|
|
38439
|
+
text-transform: uppercase;
|
|
38440
|
+
letter-spacing: 0.08em;
|
|
38441
|
+
color: var(--vr-gold);
|
|
38442
|
+
}
|
|
38443
|
+
.vr-model-menu button,
|
|
38444
|
+
.vr-scope-menu button,
|
|
38445
|
+
.vr-chat-command-popover button { border-radius: 3px; color: rgba(244, 241, 232, 0.9); }
|
|
38446
|
+
.vr-model-menu button strong { color: rgba(244, 241, 232, 0.95); }
|
|
38447
|
+
.vr-model-menu button em { color: var(--vr-muted); font-size: 11.5px; }
|
|
38448
|
+
.vr-chat-command-popover button.is-primary { color: var(--vr-gold-bright); }
|
|
38449
|
+
.vr-chat-command-popover button.is-muted { color: var(--vr-muted); }
|
|
38450
|
+
.vr-model-menu button:hover,
|
|
38451
|
+
.vr-scope-menu button:hover,
|
|
38452
|
+
.vr-chat-command-popover button:hover {
|
|
38453
|
+
background: rgba(232, 193, 90, 0.12);
|
|
38454
|
+
box-shadow: inset 3px 0 0 var(--vr-gold);
|
|
38455
|
+
color: var(--vr-gold-bright);
|
|
38456
|
+
}
|
|
38457
|
+
/* selected row: gold-tinted ink + spine (JS marks the active row with a <b>) */
|
|
38458
|
+
.vr-model-menu button[aria-selected="true"],
|
|
38459
|
+
.vr-model-menu button.is-active,
|
|
38460
|
+
.vr-model-menu button:has(> b),
|
|
38461
|
+
.vr-scope-menu button:has(> b) {
|
|
38462
|
+
background: rgba(232, 193, 90, 0.16);
|
|
38463
|
+
box-shadow: inset 3px 0 0 var(--vr-gold);
|
|
38464
|
+
}
|
|
38465
|
+
.vr-model-menu button[aria-selected="true"] strong,
|
|
38466
|
+
.vr-model-menu button:has(> b) strong { color: var(--vr-gold-bright); }
|
|
38467
|
+
.vr-model-menu button b,
|
|
38468
|
+
.vr-scope-menu button b { border-color: var(--vr-gold-bright); }
|
|
38469
|
+
/* themed menu scrollbars */
|
|
38470
|
+
.vr-model-menu::-webkit-scrollbar,
|
|
38471
|
+
.vr-scope-menu::-webkit-scrollbar,
|
|
38472
|
+
.vr-chat-command-popover::-webkit-scrollbar { width: 8px; }
|
|
38473
|
+
.vr-model-menu::-webkit-scrollbar-thumb,
|
|
38474
|
+
.vr-scope-menu::-webkit-scrollbar-thumb,
|
|
38475
|
+
.vr-chat-command-popover::-webkit-scrollbar-thumb { background: var(--vr-border-strong); border: 2px solid rgba(13, 12, 16, 0.97); }
|
|
38476
|
+
|
|
38477
|
+
.vr-chat-inline-actions > button,
|
|
38478
|
+
.vr-chat-command-trigger > button {
|
|
38479
|
+
border: 1px solid var(--vr-border);
|
|
38480
|
+
border-radius: 5px;
|
|
38481
|
+
background: rgba(13, 12, 16, 0.7);
|
|
38482
|
+
color: rgba(244, 241, 232, 0.82);
|
|
38483
|
+
}
|
|
38484
|
+
.vr-chat-inline-actions > button:hover,
|
|
38485
|
+
.vr-chat-command-trigger > button:hover {
|
|
38486
|
+
border-color: var(--vr-border-strong);
|
|
38487
|
+
background: rgba(20, 18, 12, 0.85);
|
|
38488
|
+
color: var(--vr-gold-bright);
|
|
38489
|
+
}
|
|
38490
|
+
|
|
38491
|
+
/* ----- Area 2: readability ----- */
|
|
38492
|
+
.vr-chat-command-bar .vr-chat-input { color: var(--vr-text); }
|
|
38493
|
+
.vr-chat-command-bar .vr-chat-input::placeholder { color: var(--vr-muted); }
|
|
38494
|
+
.vr-chat-inline-actions button.is-primary {
|
|
38495
|
+
background: var(--vr-gold);
|
|
38496
|
+
color: #241207;
|
|
38497
|
+
border-color: var(--vr-gold-bright);
|
|
38498
|
+
font-weight: 720;
|
|
38499
|
+
}
|
|
38500
|
+
.vr-chat-inline-actions button.is-muted { opacity: 1; color: var(--vr-muted); font-weight: 650; }
|
|
38501
|
+
.vr-cli-os-fallback { color: var(--vr-muted); text-decoration-color: var(--vr-border-strong); }
|
|
38502
|
+
.vr-cli-os-fallback:hover { color: var(--vr-gold-bright); }
|
|
38503
|
+
|
|
38504
|
+
/* ----- Area 4b: primary CTAs -> gold (after Area 1 so filled-gold wins) ----- */
|
|
38505
|
+
.vr-agent-followups button.is-primary,
|
|
38506
|
+
.vr-agent-inline-action.is-primary,
|
|
38507
|
+
.vr-chat-command-popover button.is-primary,
|
|
38508
|
+
.vr-cli-action-button.is-primary,
|
|
38509
|
+
.vr-studio-architecture > footer button.is-primary,
|
|
38510
|
+
.vr-arch-drawer footer button.is-primary,
|
|
38511
|
+
.vr-wt-actions button.is-primary,
|
|
38512
|
+
.vr-approve-all,
|
|
38513
|
+
.vr-new-chat-button,
|
|
38514
|
+
.vr-provider-ask-agent {
|
|
38515
|
+
background: var(--vr-gold);
|
|
38516
|
+
border-color: var(--vr-gold-bright);
|
|
38517
|
+
color: #0a0b0e;
|
|
38518
|
+
font-family: var(--mg-display);
|
|
38519
|
+
text-transform: uppercase;
|
|
38520
|
+
letter-spacing: 0.04em;
|
|
38521
|
+
}
|
|
38522
|
+
.vr-agent-followups button.is-primary:hover,
|
|
38523
|
+
.vr-agent-inline-action.is-primary:hover,
|
|
38524
|
+
.vr-chat-command-popover button.is-primary:hover,
|
|
38525
|
+
.vr-approve-all:hover,
|
|
38526
|
+
.vr-new-chat-button:hover,
|
|
38527
|
+
.vr-provider-ask-agent:hover { background: var(--vr-gold-bright); border-color: var(--vr-gold-bright); color: #0a0b0e; }
|
|
38528
|
+
.vr-composer-controls .vr-chat-send:not(.is-stop),
|
|
38529
|
+
.vr-chat-command-bar > .vr-chat-composer > .vr-chat-send:not(.is-stop) {
|
|
38530
|
+
background: var(--vr-gold);
|
|
38531
|
+
border-color: var(--vr-gold-bright);
|
|
38532
|
+
color: #0a0b0e;
|
|
38533
|
+
}
|
|
38534
|
+
.vr-composer-controls .vr-chat-send:not(.is-stop):hover,
|
|
38535
|
+
.vr-chat-command-bar > .vr-chat-composer > .vr-chat-send:not(.is-stop):hover { background: var(--vr-gold-bright); border-color: var(--vr-gold-bright); }
|
|
38536
|
+
|
|
38537
|
+
/* ----- Area 3: world background (inked drafting table, lit from above) ----- */
|
|
38538
|
+
body {
|
|
38539
|
+
background-color: #08080a;
|
|
38540
|
+
background-image:
|
|
38541
|
+
radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.6px),
|
|
38542
|
+
repeating-linear-gradient(52deg, rgba(232, 193, 90, 0.045) 0 1px, transparent 1px 8px),
|
|
38543
|
+
repeating-linear-gradient(-52deg, rgba(232, 193, 90, 0.04) 0 1px, transparent 1px 9px),
|
|
38544
|
+
radial-gradient(ellipse 70% 42% at 50% -8%, rgba(232, 193, 90, 0.07), transparent 60%),
|
|
38545
|
+
radial-gradient(120% 120% at 50% 40%, transparent 58%, rgba(0, 0, 0, 0.55) 100%),
|
|
38546
|
+
linear-gradient(180deg, #101015 0%, #0b0b0e 46%, #08080a 100%);
|
|
38547
|
+
background-size: 9px 9px, 900px 900px, 900px 900px, 100% 100%, 100% 100%, 100% 100%;
|
|
38548
|
+
background-position: 0 0, top right, bottom left, center top, center, center;
|
|
38549
|
+
background-repeat: repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat;
|
|
38550
|
+
background-attachment: scroll;
|
|
38551
|
+
}
|
|
38552
|
+
.vr-composed-shell {
|
|
38553
|
+
background:
|
|
38554
|
+
radial-gradient(ellipse 60% 30% at 50% -4%, rgba(232, 193, 90, 0.06), transparent 60%),
|
|
38555
|
+
radial-gradient(circle at 45% 9%, rgba(232, 193, 90, 0.035), transparent 30%),
|
|
38556
|
+
rgba(11, 12, 15, 0.965);
|
|
38557
|
+
box-shadow:
|
|
38558
|
+
inset 0 1px 0 rgba(255, 233, 173, 0.06),
|
|
38559
|
+
inset 0 0 0 1px rgba(232, 193, 90, 0.05),
|
|
38560
|
+
0 24px 60px rgba(0, 0, 0, 0.55);
|
|
38561
|
+
}
|
|
38562
|
+
.vr-studio-topbar {
|
|
38563
|
+
background:
|
|
38564
|
+
linear-gradient(180deg, rgba(232, 193, 90, 0.05), transparent 70%),
|
|
38565
|
+
rgba(13, 12, 16, 0.62);
|
|
38566
|
+
}
|
|
38567
|
+
|
|
38568
|
+
/* ----- Area 4a: top tab bar (CHAT/ARCHITECTURE/TERMINAL/DIFF) ----- */
|
|
38569
|
+
.vr-studio-tabs {
|
|
38570
|
+
border: 1px solid var(--vr-border);
|
|
38571
|
+
border-radius: 4px;
|
|
38572
|
+
clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 9px 100%, 0 calc(100% - 9px));
|
|
38573
|
+
background: rgba(13, 12, 16, 0.85);
|
|
38574
|
+
overflow: hidden;
|
|
38575
|
+
}
|
|
38576
|
+
.vr-studio-tabs button {
|
|
38577
|
+
font-family: var(--mg-display);
|
|
38578
|
+
text-transform: uppercase;
|
|
38579
|
+
letter-spacing: 0.05em;
|
|
38580
|
+
color: rgba(244, 241, 232, 0.7);
|
|
38581
|
+
}
|
|
38582
|
+
.vr-studio-tabs button:hover { color: var(--vr-gold-bright); background: rgba(232, 193, 90, 0.08); }
|
|
38583
|
+
.vr-studio-tabs button.is-active {
|
|
38584
|
+
background: var(--vr-gold);
|
|
38585
|
+
color: #0a0b0e;
|
|
38586
|
+
border-radius: 3px;
|
|
38587
|
+
box-shadow: inset 0 0 0 1px rgba(255, 233, 173, 0.5);
|
|
38588
|
+
}
|
|
38589
|
+
|
|
38590
|
+
/* ----- Area 4c: modal (ink+gold, not navy/cyan) ----- */
|
|
38591
|
+
.vr-modal-card {
|
|
38592
|
+
border-radius: 4px;
|
|
38593
|
+
clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 20px, 100% 100%, 20px 100%, 0 calc(100% - 20px));
|
|
38594
|
+
background:
|
|
38595
|
+
radial-gradient(ellipse 70% 40% at 50% -4%, rgba(232, 193, 90, 0.06), transparent 60%),
|
|
38596
|
+
radial-gradient(rgba(232, 193, 90, 0.04) 1px, transparent 1.4px),
|
|
38597
|
+
linear-gradient(180deg, rgba(16, 15, 12, 0.99), rgba(13, 12, 16, 0.995));
|
|
38598
|
+
background-size: 100% 100%, 11px 11px, 100%;
|
|
38599
|
+
}
|
|
38600
|
+
.vr-modal-card::before { background: linear-gradient(135deg, rgba(232, 193, 90, 0.08), transparent 28%); }
|
|
38601
|
+
.vr-modal-card::after { background: linear-gradient(90deg, transparent, rgba(232, 193, 90, 0.05), rgba(232, 193, 90, 0.2), transparent); opacity: 0.3; }
|
|
38602
|
+
.vr-modal-backdrop { background: radial-gradient(ellipse 60% 40% at 50% 8%, rgba(232, 193, 90, 0.07), transparent 45%), rgba(4, 5, 8, 0.8); }
|
|
38603
|
+
.vr-modal-card::-webkit-scrollbar-thumb { border: 3px solid rgba(13, 12, 16, 0.92); background: rgba(232, 193, 90, 0.4); }
|
|
38604
|
+
|
|
38605
|
+
/* ----- Area 4d: chrome buttons, terminal input, connect rows ----- */
|
|
38606
|
+
.vr-studio-add-chat,
|
|
38607
|
+
.vr-studio-actions > button:not(.vr-glow-button) {
|
|
38608
|
+
border: 1px solid var(--vr-border);
|
|
38609
|
+
border-radius: 5px;
|
|
38610
|
+
background: rgba(13, 12, 16, 0.7);
|
|
38611
|
+
color: rgba(244, 241, 232, 0.88);
|
|
38612
|
+
}
|
|
38613
|
+
.vr-studio-add-chat:hover,
|
|
38614
|
+
.vr-studio-actions > button:not(.vr-glow-button):hover { border-color: var(--vr-border-strong); background: rgba(232, 193, 90, 0.08); color: var(--vr-gold-bright); }
|
|
38615
|
+
.vr-terminal-compose textarea {
|
|
38616
|
+
border: 1px solid var(--vr-border);
|
|
38617
|
+
border-radius: 4px;
|
|
38618
|
+
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 8px 100%, 0 calc(100% - 8px));
|
|
38619
|
+
background: rgba(13, 12, 16, 0.72);
|
|
38620
|
+
color: rgba(244, 241, 232, 0.92);
|
|
38621
|
+
font-family: var(--vr-hud-mono);
|
|
38622
|
+
}
|
|
38623
|
+
.vr-terminal-compose textarea::placeholder { color: var(--vr-muted); }
|
|
38624
|
+
.vr-terminal-compose textarea:focus { border-color: var(--vr-gold); box-shadow: 0 0 18px rgba(232, 193, 90, 0.14); }
|
|
38625
|
+
.vr-env-connect-option {
|
|
38626
|
+
border: 1px solid var(--vr-border);
|
|
38627
|
+
border-radius: 4px;
|
|
38628
|
+
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 10px 100%, 0 calc(100% - 10px));
|
|
38629
|
+
background: rgba(13, 12, 16, 0.6);
|
|
38630
|
+
color: rgba(244, 241, 232, 0.9);
|
|
38631
|
+
}
|
|
38632
|
+
.vr-env-connect-option:hover { border-color: var(--vr-border-strong); background: rgba(232, 193, 90, 0.07); }
|
|
38633
|
+
.vr-env-connect-option b {
|
|
38634
|
+
border-radius: 3px;
|
|
38635
|
+
background: rgba(232, 193, 90, 0.1);
|
|
38636
|
+
color: var(--vr-gold-bright);
|
|
38637
|
+
font-family: var(--vr-hud-mono);
|
|
38638
|
+
text-transform: uppercase;
|
|
38639
|
+
letter-spacing: 0.04em;
|
|
38640
|
+
}
|
|
38641
|
+
|
|
38642
|
+
/* ----- Area 4e: focus ring ----- */
|
|
38643
|
+
button:focus-visible,
|
|
38644
|
+
a:focus-visible {
|
|
38645
|
+
outline: 2px solid var(--vr-gold);
|
|
38646
|
+
outline-offset: 2px;
|
|
38647
|
+
box-shadow: 0 0 0 4px rgba(232, 193, 90, 0.16);
|
|
38648
|
+
}
|
|
38649
|
+
|
|
38650
|
+
/* ----- Area 5: raven watermarks fade away from text (readability) ----- */
|
|
38651
|
+
.vr-chat-agent-response::before {
|
|
38652
|
+
opacity: 0.05;
|
|
38653
|
+
-webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 62%);
|
|
38654
|
+
mask-image: linear-gradient(90deg, transparent 0%, #000 62%);
|
|
38655
|
+
}
|
|
38656
|
+
.vr-table-view > *,
|
|
38657
|
+
.vr-studio-architecture.is-region-map > * { position: relative; z-index: 1; }
|
|
38658
|
+
.vr-table-view::after,
|
|
38659
|
+
.vr-studio-architecture.is-region-map::after {
|
|
38660
|
+
opacity: 0.05;
|
|
38661
|
+
-webkit-mask-image: radial-gradient(circle at right bottom, #000 28%, transparent 72%);
|
|
38662
|
+
mask-image: radial-gradient(circle at right bottom, #000 28%, transparent 72%);
|
|
38663
|
+
}
|
|
38664
|
+
|
|
38665
|
+
/* ----- placed cards get an always-visible X to clear them off the table.
|
|
38666
|
+
NB: has-art cards have overflow:hidden, so the X must sit INSIDE the card
|
|
38667
|
+
corner (top-left, away from the grade coin) or it gets clipped. ----- */
|
|
38668
|
+
.vr-tcard.is-placed .vr-tcard-unplace,
|
|
38669
|
+
.vr-vcard.is-mini.is-placed .vr-tcard-unplace {
|
|
38670
|
+
opacity: 1;
|
|
38671
|
+
width: 21px;
|
|
38672
|
+
height: 21px;
|
|
38673
|
+
top: 5px;
|
|
38674
|
+
left: 5px;
|
|
38675
|
+
right: auto;
|
|
38676
|
+
z-index: 6;
|
|
38677
|
+
background: rgba(6, 6, 8, 0.92);
|
|
38678
|
+
border: 1.5px solid var(--vr-gold);
|
|
38679
|
+
color: var(--vr-gold-bright);
|
|
38680
|
+
font-size: 11px;
|
|
38681
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.7);
|
|
38682
|
+
transition: transform 0.1s ease, background 0.1s ease, color 0.1s ease;
|
|
38683
|
+
}
|
|
38684
|
+
.vr-tcard.is-placed:hover .vr-tcard-unplace,
|
|
38685
|
+
.vr-vcard.is-mini.is-placed:hover .vr-tcard-unplace { opacity: 1; }
|
|
38686
|
+
.vr-tcard.is-placed .vr-tcard-unplace:hover,
|
|
38687
|
+
.vr-vcard.is-mini.is-placed .vr-tcard-unplace:hover {
|
|
38688
|
+
background: var(--vr-red);
|
|
38689
|
+
border-color: var(--vr-red);
|
|
38690
|
+
color: #fff;
|
|
38691
|
+
transform: scale(1.12);
|
|
38692
|
+
}
|
|
38693
|
+
|
|
38694
|
+
|
|
38695
|
+
/* ==========================================================================
|
|
38696
|
+
MANGA B&W CONTRAST PASS \u2014 appended AFTER "MANGA THEME PASS" so it wins by
|
|
38697
|
+
source order. Direction: blacker blacks, whiter/cream ink, crisp near-white
|
|
38698
|
+
hairlines, screentone dots for grey; gold pulled back to an ACCENT only
|
|
38699
|
+
(spines, selected rails, small marks). Semantic red kept for errors.
|
|
38700
|
+
De-duplicated + conflict-resolved (higher contrast wins). No !important
|
|
38701
|
+
except where an existing same-file !important rule must be overridden.
|
|
38702
|
+
========================================================================== */
|
|
38703
|
+
|
|
38704
|
+
/* ---------- (1) B&W CONTRAST BASE ---------- */
|
|
38705
|
+
|
|
38706
|
+
/* Retone root tokens: fixes the majority of muted labels + gold-alpha edges
|
|
38707
|
+
in one place. --vr-muted lifted off the dim tan; borders become near-white
|
|
38708
|
+
ink hairlines; gold moves to an explicit accent hook. */
|
|
38709
|
+
:root {
|
|
38710
|
+
--vr-bg: #050506;
|
|
38711
|
+
--vr-bg-2: #0e0e11;
|
|
38712
|
+
--vr-text: #f7f4ec;
|
|
38713
|
+
--vr-muted: #c4bcaf;
|
|
38714
|
+
--vr-border: rgba(238, 232, 220, 0.16);
|
|
38715
|
+
--vr-border-strong: rgba(238, 232, 220, 0.34);
|
|
38716
|
+
--vr-panel: rgba(9, 9, 11, 0.92);
|
|
38717
|
+
--vr-panel-2: rgba(14, 14, 17, 0.9);
|
|
38718
|
+
--vr-hud-surface: rgba(6, 6, 8, 0.94);
|
|
38719
|
+
--vr-hud-line: rgba(238, 232, 220, 0.14);
|
|
38720
|
+
--vr-accent-line: rgba(232, 193, 90, 0.55);
|
|
38721
|
+
}
|
|
38722
|
+
|
|
38723
|
+
/* World background: drop the gold cross-hatch haze for black paper + faint
|
|
38724
|
+
neutral screentone + vignette. */
|
|
38725
|
+
body {
|
|
38726
|
+
background-color: #050506;
|
|
38727
|
+
background-image:
|
|
38728
|
+
radial-gradient(rgba(244, 241, 232, 0.028) 1px, transparent 1.5px),
|
|
38729
|
+
radial-gradient(ellipse 68% 40% at 50% -8%, rgba(255, 255, 255, 0.035), transparent 62%),
|
|
38730
|
+
radial-gradient(130% 120% at 50% 42%, transparent 56%, rgba(0, 0, 0, 0.72) 100%),
|
|
38731
|
+
linear-gradient(180deg, #0c0c0f 0%, #08080a 48%, #050506 100%);
|
|
38732
|
+
background-size: 8px 8px, 100% 100%, 100% 100%, 100% 100%;
|
|
38733
|
+
background-position: 0 0, center top, center, center;
|
|
38734
|
+
background-repeat: repeat, no-repeat, no-repeat, no-repeat;
|
|
38735
|
+
}
|
|
38736
|
+
|
|
38737
|
+
/* Composed shell: near-flat true-black with one white top hairline. */
|
|
38738
|
+
.vr-composed-shell {
|
|
38739
|
+
background:
|
|
38740
|
+
radial-gradient(ellipse 62% 26% at 50% -3%, rgba(255, 255, 255, 0.04), transparent 60%),
|
|
38741
|
+
rgba(7, 7, 9, 0.975);
|
|
38742
|
+
box-shadow:
|
|
38743
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.07),
|
|
38744
|
+
inset 0 0 0 1px rgba(238, 232, 220, 0.05),
|
|
38745
|
+
0 24px 60px rgba(0, 0, 0, 0.62);
|
|
38746
|
+
}
|
|
38747
|
+
|
|
38748
|
+
/* Studio topbar: neutral top-light + single thin gold underline accent. */
|
|
38749
|
+
.vr-studio-topbar {
|
|
38750
|
+
background:
|
|
38751
|
+
linear-gradient(180deg, rgba(255, 255, 255, 0.045), transparent 70%),
|
|
38752
|
+
rgba(6, 6, 9, 0.72);
|
|
38753
|
+
border-bottom: 1px solid var(--vr-border);
|
|
38754
|
+
box-shadow: inset 0 -1px 0 var(--vr-accent-line);
|
|
38755
|
+
}
|
|
38756
|
+
|
|
38757
|
+
/* Persistent top-bar readout (was #64748b cold slate, ~3.4:1). */
|
|
38758
|
+
.vr-topbar-spacer { color: var(--vr-muted); font-weight: 780; }
|
|
38759
|
+
|
|
38760
|
+
/* Studio tabs: active tab reads as inked-white paper with a gold underline
|
|
38761
|
+
mark, not a gold slab; idle-tab contrast raised. */
|
|
38762
|
+
.vr-studio-tabs button { color: rgba(244, 241, 232, 0.82); }
|
|
38763
|
+
.vr-studio-tabs button.is-active {
|
|
38764
|
+
background: rgba(244, 241, 232, 0.1);
|
|
38765
|
+
color: #f7f4ec;
|
|
38766
|
+
box-shadow: inset 0 -2px 0 var(--vr-gold), inset 0 0 0 1px rgba(238, 232, 220, 0.14);
|
|
38767
|
+
}
|
|
38768
|
+
.vr-studio-tabs button:hover { color: #ffe9ad; background: rgba(255, 255, 255, 0.05); }
|
|
38769
|
+
|
|
38770
|
+
/* Dropdown / popup menus: clean black sheet (kills the gold halftone),
|
|
38771
|
+
gold only on the left spine + hover/selected rail; item + label contrast up. */
|
|
38772
|
+
.vr-model-menu,
|
|
38773
|
+
.vr-scope-menu,
|
|
38774
|
+
.vr-chat-command-popover {
|
|
38775
|
+
background-color: rgba(5, 5, 7, 0.99);
|
|
38776
|
+
background-image: none;
|
|
38777
|
+
border-color: var(--vr-border-strong);
|
|
38778
|
+
border-left: 3px solid var(--vr-gold);
|
|
38779
|
+
}
|
|
38780
|
+
.vr-model-menu button,
|
|
38781
|
+
.vr-scope-menu button,
|
|
38782
|
+
.vr-chat-command-popover button { color: #f0ece2; }
|
|
38783
|
+
.vr-model-menu button em { color: #c4bcae; }
|
|
38784
|
+
.vr-model-menu button:hover,
|
|
38785
|
+
.vr-scope-menu button:hover,
|
|
38786
|
+
.vr-chat-command-popover button:hover {
|
|
38787
|
+
background: rgba(255, 255, 255, 0.06);
|
|
38788
|
+
box-shadow: inset 3px 0 0 var(--vr-gold);
|
|
38789
|
+
color: #ffe9ad;
|
|
38790
|
+
}
|
|
38791
|
+
|
|
38792
|
+
/* HUD strip (telemetry line): raise the faded cool-grey meta to readable ink. */
|
|
38793
|
+
.vr-hud-strip { color: #c9c1b4; border-bottom-color: rgba(238, 232, 220, 0.12); }
|
|
38794
|
+
.vr-hud-strip strong { color: #f7f4ec; }
|
|
38795
|
+
.vr-hud-strip em { color: #c9c1b4; }
|
|
38796
|
+
.vr-hud-strip b { color: var(--vr-muted); font-weight: 600; } /* merged: was #b0a89b / rgba(156,163,175,.72) */
|
|
38797
|
+
|
|
38798
|
+
/* HUD card chassis: white-ruled black panel; the ONE spot of color is the
|
|
38799
|
+
left rail (semantic status). */
|
|
38800
|
+
.vr-hud-card {
|
|
38801
|
+
background: rgba(6, 6, 8, 0.94);
|
|
38802
|
+
border-color: rgba(238, 232, 220, 0.16);
|
|
38803
|
+
border-left-color: rgba(238, 232, 220, 0.45);
|
|
38804
|
+
}
|
|
38805
|
+
.vr-hud-card.is-nominal { border-left-color: var(--vr-green); }
|
|
38806
|
+
.vr-hud-card.is-blocked { border-left-color: var(--vr-red); }
|
|
38807
|
+
.vr-hud-card.is-working { border-left-color: var(--vr-orange); }
|
|
38808
|
+
.vr-hud-card.is-mission { border-left-color: var(--vr-gold); }
|
|
38809
|
+
|
|
38810
|
+
/* HUD gate row + severity: lift the primary line to full-opacity ink,
|
|
38811
|
+
metadata to solid grey. */
|
|
38812
|
+
.vr-hud-gate { background: rgba(255, 255, 255, 0.02); border-color: rgba(238, 232, 220, 0.14); }
|
|
38813
|
+
.vr-hud-gate header { border-bottom-color: rgba(238, 232, 220, 0.12); }
|
|
38814
|
+
.vr-hud-gate-row { border-bottom-color: rgba(238, 232, 220, 0.09); }
|
|
38815
|
+
.vr-hud-gate-row em { color: #f3efe6; }
|
|
38816
|
+
.vr-hud-gate-row em small { color: #c4bcae; }
|
|
38817
|
+
.vr-hud-gate-row b { color: #b6ae9f; }
|
|
38818
|
+
.vr-hud-sev.is-info { color: #b6ae9f; }
|
|
38819
|
+
.vr-hud-gate-foot {
|
|
38820
|
+
border-top-color: rgba(238, 232, 220, 0.12);
|
|
38821
|
+
background: rgba(255, 255, 255, 0.025);
|
|
38822
|
+
color: #f4f1e8;
|
|
38823
|
+
}
|
|
38824
|
+
.vr-hud-gate-foot b { color: #bcb4a6; }
|
|
38825
|
+
.vr-hud-gate-foot:hover { background: rgba(255, 255, 255, 0.05); }
|
|
38826
|
+
.vr-hud-raw { color: #bcb4a6; }
|
|
38827
|
+
.vr-agent-raw-sub { color: #c4bcae; }
|
|
38828
|
+
|
|
38829
|
+
/* ---------- (2) VERSIONS / WORKTREE / SHUFFLE ---------- */
|
|
38830
|
+
|
|
38831
|
+
/* Table view container + header: solid ink base so cream text pops; header
|
|
38832
|
+
is cream Anton with a hairline rule, gold reserved for the spine accents. */
|
|
38833
|
+
.vr-table-view { background: #0b0b0d !important; }
|
|
38834
|
+
.vr-table-view-head { border-bottom: 1.5px solid var(--vr-border-strong) !important; }
|
|
38835
|
+
.vr-table-view-head strong { color: var(--vr-text) !important; -webkit-text-stroke: 0.4px rgba(0, 0, 0, 0.35); }
|
|
38836
|
+
.vr-table-view-head span { color: var(--vr-muted) !important; }
|
|
38837
|
+
|
|
38838
|
+
/* Big version card: ink plate + white hairline + comic notch (large panel \u2014
|
|
38839
|
+
notch is safe here); gold only as border tint on current. NOTE: base rules
|
|
38840
|
+
at ~13450-13492 use !important, so these must too. */
|
|
38841
|
+
.vr-vcard {
|
|
38842
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
38843
|
+
border-radius: 4px !important;
|
|
38844
|
+
background: rgba(10, 10, 12, 0.96) !important;
|
|
38845
|
+
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.55) !important;
|
|
38846
|
+
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 16px 100%, 0 calc(100% - 16px));
|
|
38847
|
+
}
|
|
38848
|
+
.vr-vcard::before {
|
|
38849
|
+
inset: 4px !important;
|
|
38850
|
+
border-radius: 3px !important;
|
|
38851
|
+
background-color: rgba(11, 11, 13, 0.9) !important;
|
|
38852
|
+
background-image: radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px) !important;
|
|
38853
|
+
background-size: 9px 9px !important;
|
|
38854
|
+
}
|
|
38855
|
+
.vr-vcard:not(.is-current) { filter: none !important; opacity: 0.9; }
|
|
38856
|
+
.vr-vcard.is-current {
|
|
38857
|
+
border-color: var(--vr-gold) !important;
|
|
38858
|
+
border-left: 3px solid var(--vr-gold) !important; /* thin gold spine = "chosen" */
|
|
38859
|
+
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.55), 0 0 16px rgba(232, 193, 90, 0.16) !important;
|
|
38860
|
+
}
|
|
38861
|
+
.vr-vcard-top b,
|
|
38862
|
+
.vr-vpile-card b { color: var(--vr-text) !important; font-family: var(--vr-display) !important; letter-spacing: 0.5px; }
|
|
38863
|
+
/* merged .vr-vcard-meta: prefer --vr-muted (brightest) + the larger 8.5px */
|
|
38864
|
+
.vr-vcard-meta { color: var(--vr-muted) !important; font-size: 8.5px !important; letter-spacing: 0.8px; opacity: 0.95; }
|
|
38865
|
+
.vr-vcard-branch { color: #cfc6b6 !important; font-size: 8.5px !important; }
|
|
38866
|
+
|
|
38867
|
+
/* Version pile (bottom-left floating pile): thin hairline + gold spine, not a
|
|
38868
|
+
thick foil frame. */
|
|
38869
|
+
.vr-vpile-card {
|
|
38870
|
+
border: 1px solid var(--vr-border-strong) !important;
|
|
38871
|
+
border-left: 3px solid var(--vr-gold) !important;
|
|
38872
|
+
background: rgba(11, 11, 13, 0.96) !important;
|
|
38873
|
+
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.5) !important;
|
|
38874
|
+
}
|
|
38875
|
+
.vr-vpile-card.is-top {
|
|
38876
|
+
border-color: var(--vr-gold) !important;
|
|
38877
|
+
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.5), 0 0 12px rgba(232, 193, 90, 0.15) !important;
|
|
38878
|
+
}
|
|
38879
|
+
.vr-vpile-card:not(.is-top) { opacity: 0.8; }
|
|
38880
|
+
.vr-vpile-card em { color: #cfc6b6 !important; }
|
|
38881
|
+
.vr-version-pile-label { color: var(--vr-muted) !important; letter-spacing: 1.8px; }
|
|
38882
|
+
|
|
38883
|
+
/* SHUFFLE button: crisp ink pill + gold hairline; hover = thin gold-tint, not
|
|
38884
|
+
a solid gold slab. */
|
|
38885
|
+
.vr-pile-shuffle {
|
|
38886
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
38887
|
+
border-radius: 4px !important;
|
|
38888
|
+
background: rgba(11, 11, 13, 0.95) !important;
|
|
38889
|
+
color: var(--vr-text) !important;
|
|
38890
|
+
font-family: var(--vr-hud-mono) !important;
|
|
38891
|
+
font-size: 8.5px !important;
|
|
38892
|
+
font-weight: 700;
|
|
38893
|
+
letter-spacing: 1.4px;
|
|
38894
|
+
padding: 4px 10px !important;
|
|
38895
|
+
}
|
|
38896
|
+
.vr-pile-shuffle:hover {
|
|
38897
|
+
background: rgba(232, 193, 90, 0.12) !important;
|
|
38898
|
+
border-color: var(--vr-gold) !important;
|
|
38899
|
+
color: var(--vr-gold-bright) !important;
|
|
38900
|
+
}
|
|
38901
|
+
|
|
38902
|
+
/* Worktree branch card (bcard): gold spine + readable title/sub. */
|
|
38903
|
+
.vr-bcard { border-left: 3px solid var(--vr-gold) !important; }
|
|
38904
|
+
.vr-bcard b { color: var(--vr-text) !important; font-size: 13.5px !important; }
|
|
38905
|
+
.vr-bcard em { color: #cfc6b6 !important; font-size: 9px !important; }
|
|
38906
|
+
.vr-bcard-actions button {
|
|
38907
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
38908
|
+
color: var(--vr-text) !important;
|
|
38909
|
+
background: rgba(11, 11, 13, 0.6) !important;
|
|
38910
|
+
letter-spacing: 1px;
|
|
38911
|
+
}
|
|
38912
|
+
.vr-bcard-actions button:hover {
|
|
38913
|
+
background: rgba(232, 193, 90, 0.12) !important;
|
|
38914
|
+
border-color: var(--vr-gold) !important;
|
|
38915
|
+
color: var(--vr-gold-bright) !important;
|
|
38916
|
+
}
|
|
38917
|
+
|
|
38918
|
+
/* Worktree uncommitted-changes warning: readable body, orange COMMIT button. */
|
|
38919
|
+
.vr-table-warning { color: var(--vr-text) !important; font-size: 13px !important; }
|
|
38920
|
+
.vr-table-warning button { color: var(--vr-orange) !important; font-size: 9.5px !important; letter-spacing: 1.2px; }
|
|
38921
|
+
.vr-table-warning button:hover { background: var(--vr-orange) !important; color: #0b0b0d !important; }
|
|
38922
|
+
|
|
38923
|
+
/* Empty-state + add-version footer button. */
|
|
38924
|
+
.vr-table-empty { color: #cfc6b6 !important; font-size: 11.5px !important; }
|
|
38925
|
+
.vr-table-foot button { color: var(--vr-text) !important; border-color: var(--vr-border-strong) !important; }
|
|
38926
|
+
.vr-table-foot button:hover { background: rgba(232, 193, 90, 0.1) !important; color: var(--vr-gold-bright) !important; }
|
|
38927
|
+
|
|
38928
|
+
/* ---------- (3) CLEAR STAMP FIX (region-map node badge clipped) ---------- */
|
|
38929
|
+
/* The comic-notch clip-path on .vr-arch-node:not(.is-card) clips its
|
|
38930
|
+
corner-mounted .vr-arch-node-badge, cutting "CLEAR" -> "CLEA.". Per the
|
|
38931
|
+
manga rule (never notch anything whose badge reaches a corner), drop the
|
|
38932
|
+
notch on these nodes and keep the ink/halftone look via a hairline. */
|
|
38933
|
+
.vr-arch-node:not(.is-card) {
|
|
38934
|
+
clip-path: none;
|
|
38935
|
+
overflow: visible;
|
|
38936
|
+
border: 1.5px solid var(--vr-border-strong);
|
|
38937
|
+
background-image: radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px);
|
|
38938
|
+
background-size: 8px 8px;
|
|
38939
|
+
}
|
|
38940
|
+
.vr-studio-architecture.is-region-map .vr-arch-node:not(.is-card) .vr-arch-node-badge.vr-stamp.is-mini {
|
|
38941
|
+
overflow: visible;
|
|
38942
|
+
z-index: 3;
|
|
38943
|
+
background: var(--vr-bg);
|
|
38944
|
+
}
|
|
38945
|
+
|
|
38946
|
+
/* ---------- (4) WELCOME MODAL QUICKSTART CARDS (flip bleed-through) ---------- */
|
|
38947
|
+
/* On a DONE card (is-flipped, e.g. SCAN "SETUP \xB7 WON") the back-face mascot +
|
|
38948
|
+
FLIP label bled through because both faces trusted only backface-visibility.
|
|
38949
|
+
Hide the inactive face explicitly (opacity+visibility) and give the flip a
|
|
38950
|
+
fixed height so the four cards stay aligned. Make the back opaque. */
|
|
38951
|
+
.vr-qs-card.is-hero { position: relative; }
|
|
38952
|
+
.vr-qs-card.is-hero [data-flip-card],
|
|
38953
|
+
.vr-qs-card.is-hero .vr-flip-inner { height: 100%; }
|
|
38954
|
+
.vr-qs-card.is-hero .vr-flip-inner { min-height: 318px; }
|
|
38955
|
+
.vr-qs-card .vr-flip-face,
|
|
38956
|
+
.vr-qs-card .vr-flip-back {
|
|
38957
|
+
position: absolute;
|
|
38958
|
+
inset: 0;
|
|
38959
|
+
height: 100%;
|
|
38960
|
+
transition: opacity 200ms ease, visibility 200ms ease;
|
|
38961
|
+
}
|
|
38962
|
+
.vr-qs-card:not(.is-flipped) .vr-flip-face { opacity: 0; visibility: hidden; }
|
|
38963
|
+
.vr-qs-card.is-flipped .vr-flip-face { opacity: 1; visibility: visible; }
|
|
38964
|
+
.vr-qs-card.is-flipped .vr-flip-back { opacity: 0; visibility: hidden; }
|
|
38965
|
+
.vr-qs-card:not(.is-flipped) .vr-flip-back { opacity: 1; visibility: visible; }
|
|
38966
|
+
.vr-qs-card .vr-qs-back { background-color: #0e0e12; }
|
|
38967
|
+
.vr-qs-card.is-hero .vr-qs-card-inner { position: relative; z-index: 1; }
|
|
38968
|
+
|
|
38969
|
+
/* ---------- (5) READABILITY (retone off-palette / low-contrast text) ---------- */
|
|
38970
|
+
|
|
38971
|
+
/* Agent answer body / structured sections: warm near-white cream on the
|
|
38972
|
+
highest-traffic reading surface (was cool blue-greys). */
|
|
38973
|
+
.vr-agent-answer-body,
|
|
38974
|
+
.vr-agent-answer-text { color: #f2efe6; }
|
|
38975
|
+
.vr-agent-answer-body p { color: #eae6db; }
|
|
38976
|
+
.vr-agent-list li,
|
|
38977
|
+
.vr-chat-message p { color: var(--vr-text); } /* merged: cream token wins over #eae6db/#e7e7e9 */
|
|
38978
|
+
.vr-agent-answer-body .vr-agent-empty { color: #bcb4a6; }
|
|
38979
|
+
|
|
38980
|
+
/* Inline code / pill chips: near-white on true-black chip + white hairline,
|
|
38981
|
+
gold only as the faint left tick (was gold body text). */
|
|
38982
|
+
.vr-agent-answer-body code {
|
|
38983
|
+
background: rgba(4, 4, 6, 0.85);
|
|
38984
|
+
border-color: rgba(238, 232, 220, 0.16);
|
|
38985
|
+
border-left: 2px solid var(--vr-gold);
|
|
38986
|
+
color: #f4f1e8;
|
|
38987
|
+
}
|
|
38988
|
+
.vr-chat-message b {
|
|
38989
|
+
border-color: rgba(238, 232, 220, 0.24);
|
|
38990
|
+
background: rgba(255, 255, 255, 0.05);
|
|
38991
|
+
color: #f4f1e8;
|
|
38992
|
+
}
|
|
38993
|
+
|
|
38994
|
+
/* Chat sub-caption / notes / inline em: readable neutral cream-grey. */
|
|
38995
|
+
.vr-chat-message em,
|
|
38996
|
+
.vr-chat-copy { color: #c6bfb2; }
|
|
38997
|
+
.vr-chat-note { color: #cfc8ba; }
|
|
38998
|
+
|
|
38999
|
+
/* Chat bubbles (agent/system telemetry): true-black glass + white hairline +
|
|
39000
|
+
warm-white text (was #1d1e22 grey slab w/ blue-grey borders). */
|
|
39001
|
+
.vr-chat-bubble {
|
|
39002
|
+
background: rgba(7, 7, 9, 0.92);
|
|
39003
|
+
border-color: rgba(238, 232, 220, 0.16);
|
|
39004
|
+
}
|
|
39005
|
+
.vr-chat-bubble.is-system { background: rgba(4, 4, 6, 0.9); border-color: rgba(238, 232, 220, 0.14); }
|
|
39006
|
+
.vr-chat-bubble span { color: #e9e2d5; }
|
|
39007
|
+
.vr-chat-bubble p,
|
|
39008
|
+
.vr-chat-bubble ul { color: #f5f1e8; }
|
|
39009
|
+
|
|
39010
|
+
/* Terminal output: warm near-white body color (was cold #cbd5e1). */
|
|
39011
|
+
.vr-terminal-line { color: #ece7db; }
|
|
39012
|
+
|
|
39013
|
+
/* Region-map / architecture captions + hints (cold slate -> warm muted). */
|
|
39014
|
+
.vr-arch-zone { color: rgba(232, 214, 176, 0.82); font-weight: 800; }
|
|
39015
|
+
.vr-arch-hint { color: var(--vr-muted); }
|
|
39016
|
+
.vr-inspector-body .vr-studio-architecture.is-inspector-map .vr-arch-zone { color: rgba(244, 241, 232, 0.86); }
|
|
39017
|
+
|
|
39018
|
+
/* Card / hero TYPE eyebrows (were 6-7.5px at 0.5-0.55 alpha, illegible). */
|
|
39019
|
+
.vr-tcard-type { color: rgba(244, 241, 232, 0.9); font-size: 8px; letter-spacing: 1px; }
|
|
39020
|
+
.vr-qs-type {
|
|
39021
|
+
color: rgba(244, 241, 232, 0.9);
|
|
39022
|
+
font-size: 9px;
|
|
39023
|
+
position: relative; /* merged w/ Bug-2 stacking so SETUP\xB7WON sits above art */
|
|
39024
|
+
z-index: 2;
|
|
39025
|
+
margin-top: 2px;
|
|
39026
|
+
white-space: nowrap;
|
|
39027
|
+
}
|
|
39028
|
+
|
|
39029
|
+
/* Misc muted secondary lines / captions (cold slate -> warm muted). */
|
|
39030
|
+
.vr-context-chip-label .muted { color: var(--vr-muted); font-weight: 550; }
|
|
39031
|
+
.vr-recent-chat em,
|
|
39032
|
+
.vr-recent-chat small { color: var(--vr-muted); }
|
|
39033
|
+
.vr-provider-drop-zone { color: var(--vr-muted); }
|
|
39034
|
+
.vr-chat-agent-task header em { color: var(--vr-muted); }
|
|
39035
|
+
.vr-provider-mcp-panel em { color: var(--vr-muted); }
|
|
39036
|
+
|
|
39037
|
+
/* Icon-only close/secondary button: readable at rest, gold on hover. */
|
|
39038
|
+
.vr-context-chip-remove { color: var(--vr-muted); }
|
|
39039
|
+
.vr-context-chip-remove:hover { color: var(--vr-gold-bright); }
|
|
39040
|
+
|
|
39041
|
+
/* ==========================================================================
|
|
39042
|
+
LIVE TABLE STATS strip \u2014 real repo/provider metrics on the table (the
|
|
39043
|
+
"Active Users" KPI idea, sourced from real data). Manga stat cards: ink
|
|
39044
|
+
plate, white hairline, gold top-tick accent, big Anton number, mono label.
|
|
39045
|
+
========================================================================== */
|
|
39046
|
+
.vr-stat-strip {
|
|
39047
|
+
display: grid;
|
|
39048
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
39049
|
+
gap: 10px;
|
|
39050
|
+
margin: 0 0 16px;
|
|
39051
|
+
}
|
|
39052
|
+
@media (max-width: 1080px) { .vr-stat-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
|
|
39053
|
+
.vr-stat-card {
|
|
39054
|
+
position: relative;
|
|
39055
|
+
padding: 11px 13px 10px;
|
|
39056
|
+
border: 1px solid var(--vr-border-strong);
|
|
39057
|
+
border-top: 2px solid rgba(238, 232, 220, 0.28);
|
|
39058
|
+
border-radius: 4px;
|
|
39059
|
+
background:
|
|
39060
|
+
radial-gradient(rgba(232, 193, 90, 0.045) 1px, transparent 1.4px),
|
|
39061
|
+
rgba(9, 9, 11, 0.94);
|
|
39062
|
+
background-size: 9px 9px, auto;
|
|
39063
|
+
overflow: hidden;
|
|
39064
|
+
}
|
|
39065
|
+
.vr-stat-card::after {
|
|
39066
|
+
content: '';
|
|
39067
|
+
position: absolute;
|
|
39068
|
+
left: 0; top: 0;
|
|
39069
|
+
width: 26px; height: 2px;
|
|
39070
|
+
background: var(--vr-gold);
|
|
39071
|
+
}
|
|
39072
|
+
.vr-stat-card b {
|
|
39073
|
+
display: block;
|
|
39074
|
+
font-family: var(--mg-display);
|
|
39075
|
+
font-weight: 400;
|
|
39076
|
+
font-size: 27px;
|
|
39077
|
+
line-height: 1;
|
|
39078
|
+
letter-spacing: 0.01em;
|
|
39079
|
+
color: var(--vr-text);
|
|
39080
|
+
}
|
|
39081
|
+
.vr-stat-card.is-word b { font-size: 18px; padding: 4px 0 3px; }
|
|
39082
|
+
.vr-stat-card span {
|
|
39083
|
+
display: block;
|
|
39084
|
+
margin-top: 5px;
|
|
39085
|
+
font-family: var(--vr-hud-mono);
|
|
39086
|
+
font-size: 8.5px;
|
|
39087
|
+
font-weight: 650;
|
|
39088
|
+
letter-spacing: 0.14em;
|
|
39089
|
+
text-transform: uppercase;
|
|
39090
|
+
color: var(--vr-muted);
|
|
39091
|
+
}
|
|
39092
|
+
.vr-stat-card.is-gold b { color: var(--vr-gold-bright); }
|
|
39093
|
+
.vr-stat-card.is-green b { color: var(--vr-green); }
|
|
39094
|
+
.vr-stat-card.is-orange b { color: var(--vr-orange); }
|
|
39095
|
+
.vr-stat-card.is-muted b { color: rgba(244, 241, 232, 0.6); }
|
|
39096
|
+
.vr-stat-card.is-green::after { background: var(--vr-green); }
|
|
39097
|
+
.vr-stat-card.is-orange::after { background: var(--vr-orange); }
|
|
39098
|
+
|
|
39099
|
+
/* ==========================================================================
|
|
39100
|
+
FINAL FIXES \u2014 hand spread + hover, worktree tag clip, placed-card readability
|
|
39101
|
+
========================================================================== */
|
|
39102
|
+
/* Hand: cards stick together more (was -34 = too spread) so the fan reads as a
|
|
39103
|
+
held hand, with a clean hover lift on a high z so it never hides behind a
|
|
39104
|
+
neighbour. */
|
|
39105
|
+
.vr-hand-fan .vr-tcard { margin-left: -46px; }
|
|
39106
|
+
.vr-hand-fan .vr-tcard:first-child { margin-left: 0; }
|
|
39107
|
+
/* Stable hover: lift STRAIGHT up with almost no scale. A big scale grows the
|
|
39108
|
+
card footprint and flickers against the overlapping neighbours (the "buggy"
|
|
39109
|
+
hover). Keep the same width, just rise + straighten; smooth + GPU-hinted. */
|
|
39110
|
+
.vr-hand-fan .vr-tcard {
|
|
39111
|
+
transition: transform 130ms ease, box-shadow 130ms ease;
|
|
39112
|
+
will-change: transform;
|
|
39113
|
+
}
|
|
39114
|
+
.vr-hand-fan .vr-tcard:hover {
|
|
39115
|
+
transform: rotate(0deg) translateY(-26px) scale(1.02);
|
|
39116
|
+
z-index: 30;
|
|
39117
|
+
}
|
|
39118
|
+
|
|
39119
|
+
/* Worktree branch cards: drop the comic-notch that was slicing the
|
|
39120
|
+
"YOU ARE HERE" tag on the current branch (same clip bug as the region-map
|
|
39121
|
+
stamp). Keep the ink+gold-spine look via border only. */
|
|
39122
|
+
.vr-bcard { clip-path: none; overflow: visible; }
|
|
39123
|
+
.vr-bcard .vr-stamp.is-mini { z-index: 4; }
|
|
39124
|
+
|
|
39125
|
+
/* Placed-card X sits above the holo foil so it is always clickable. */
|
|
39126
|
+
.vr-tcard.is-placed .vr-tcard-holofoil,
|
|
39127
|
+
.vr-tcard.is-placed .vr-tcard-glare { pointer-events: none; }
|
|
39128
|
+
|
|
39129
|
+
/* Placed PROVIDER card X: top-left (grade coin is top-right), small + clean. */
|
|
39130
|
+
.vr-tcard.is-placed .vr-tcard-unplace {
|
|
39131
|
+
width: 17px;
|
|
39132
|
+
height: 17px;
|
|
39133
|
+
top: 5px;
|
|
39134
|
+
left: 5px;
|
|
39135
|
+
right: auto;
|
|
39136
|
+
font-size: 9px;
|
|
39137
|
+
}
|
|
39138
|
+
/* Placed VERSION card X: top-RIGHT (the V1.x label sits top-left), small. */
|
|
39139
|
+
.vr-vcard.is-mini.is-placed .vr-tcard-unplace {
|
|
39140
|
+
opacity: 1;
|
|
39141
|
+
width: 17px;
|
|
39142
|
+
height: 17px;
|
|
39143
|
+
top: 5px;
|
|
39144
|
+
right: 5px;
|
|
39145
|
+
left: auto;
|
|
39146
|
+
font-size: 9px;
|
|
39147
|
+
background: rgba(6, 6, 8, 0.92);
|
|
39148
|
+
border: 1.5px solid var(--vr-gold);
|
|
39149
|
+
color: var(--vr-gold-bright);
|
|
39150
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.7);
|
|
39151
|
+
}
|
|
39152
|
+
.vr-vcard.is-mini.is-placed .vr-tcard-unplace:hover { background: var(--vr-red); border-color: var(--vr-red); color: #fff; }
|
|
39153
|
+
|
|
39154
|
+
/* Placed-card HOVER must KEEP the translate(-50%,-50%) centering \u2014 the has-art
|
|
39155
|
+
hover rule was replacing it, so the card JUMPED off-position (the "buggy
|
|
39156
|
+
hover"). Gentle lift, keep centered, no snap. */
|
|
39157
|
+
.vr-tcard.is-placed:hover,
|
|
39158
|
+
.vr-tcard.is-placed.has-art:hover {
|
|
39159
|
+
transform: translate(-50%, -50%) rotate(0deg) scale(1.05) !important;
|
|
39160
|
+
z-index: 40;
|
|
39161
|
+
}
|
|
39162
|
+
|
|
39163
|
+
/* ==========================================================================
|
|
39164
|
+
MANGA READABILITY + CARD-VIBE PASS
|
|
39165
|
+
Appended after the FINAL FIXES block (>16354) so it wins by source order.
|
|
39166
|
+
(1) Typography: 3-tier hierarchy \u2014 Anton=headline only, mono=legible floor,
|
|
39167
|
+
sans=running/secondary UI. (2) Manga card-vibe: faint margin-only ink,
|
|
39168
|
+
gold halftone + card/raven/poster watermarks that NEVER sit behind text.
|
|
39169
|
+
!important is used ONLY where an existing same-file !important forces it.
|
|
39170
|
+
========================================================================== */
|
|
39171
|
+
|
|
39172
|
+
/* -------------------------------------------------------------------------
|
|
39173
|
+
(1) TYPOGRAPHY
|
|
39174
|
+
------------------------------------------------------------------------- */
|
|
39175
|
+
|
|
39176
|
+
/* 1a. Small mono-telemetry label FLOOR \u2014 lift every sub-9.5px cap to legible.
|
|
39177
|
+
(.vr-tcard-type/-grade base 7-8px; .vr-bcard em / .vr-vpile-card em carry
|
|
39178
|
+
an existing 9px !important, so those need !important to reach the floor.) */
|
|
39179
|
+
.vr-tcard-type,
|
|
39180
|
+
.vr-tcard-grade,
|
|
39181
|
+
.vr-tcard.is-back .vr-tcard-backname,
|
|
39182
|
+
.vr-qs-local,
|
|
39183
|
+
.vr-bcard em,
|
|
39184
|
+
.vr-vpile-card em,
|
|
39185
|
+
.vr-addpick-list button em {
|
|
39186
|
+
font-size: 9.5px !important; /* was 6\u20139px; beats 16104/16079 !important */
|
|
39187
|
+
line-height: 1.25;
|
|
39188
|
+
font-weight: 620; /* thin mono needs weight on black paper */
|
|
39189
|
+
}
|
|
39190
|
+
.vr-tcard.is-dealt .vr-tcard-type,
|
|
39191
|
+
.vr-tcard.is-dealt .vr-tcard-grade { font-size: 10px !important; }
|
|
39192
|
+
|
|
39193
|
+
/* 1b. Letter-spacing CAP on tiny caps \u2014 extreme 1.4\u20132px tracking smears words.
|
|
39194
|
+
(Cap to ~0.07em. .vr-hud-strip / chip .muted already retoned at 15992+,
|
|
39195
|
+
so only their tracking is nudged, not restated.) */
|
|
39196
|
+
.vr-tcard-type,
|
|
39197
|
+
.vr-tcard-grade,
|
|
39198
|
+
.vr-tcard.is-back .vr-tcard-backname,
|
|
39199
|
+
.vr-qs-local,
|
|
39200
|
+
.vr-pile-shuffle,
|
|
39201
|
+
.vr-bcard-actions button,
|
|
39202
|
+
.vr-table-warning button {
|
|
39203
|
+
letter-spacing: 0.07em;
|
|
39204
|
+
}
|
|
39205
|
+
.vr-hud-strip { letter-spacing: 0.04em; }
|
|
39206
|
+
|
|
39207
|
+
/* 1c. Anton DEMOTION \u2014 pull the condensed poster face off running UI text.
|
|
39208
|
+
Menu labels + action-button captions move to the readable sans stack. */
|
|
39209
|
+
.vr-scope-menu p,
|
|
39210
|
+
.vr-studio-add-chat,
|
|
39211
|
+
.vr-provider-ask-agent,
|
|
39212
|
+
.vr-new-chat-button,
|
|
39213
|
+
.vr-agent-followups button.is-primary,
|
|
39214
|
+
.vr-chat-command-popover button.is-primary,
|
|
39215
|
+
.vr-cli-action-button.is-primary {
|
|
39216
|
+
font-family: var(--vr-hud-sans, 'Geist', 'Inter', system-ui, sans-serif);
|
|
39217
|
+
font-weight: 700;
|
|
39218
|
+
letter-spacing: 0.03em;
|
|
39219
|
+
text-transform: uppercase;
|
|
39220
|
+
}
|
|
39221
|
+
.vr-scope-menu p { font-size: 10px; }
|
|
39222
|
+
|
|
39223
|
+
/* 1d. Studio tab bar \u2014 Anton stays (display scale) but sized up + opened for
|
|
39224
|
+
scannable CHAT / ARCHITECTURE / TERMINAL / DIFF. */
|
|
39225
|
+
.vr-studio-tabs button {
|
|
39226
|
+
font-size: 13px;
|
|
39227
|
+
letter-spacing: 0.06em;
|
|
39228
|
+
font-weight: 400; /* Anton is already heavy */
|
|
39229
|
+
}
|
|
39230
|
+
|
|
39231
|
+
/* 1e. HUD telemetry strip \u2014 bigger, weightier instrument line. */
|
|
39232
|
+
.vr-hud-strip { font-size: 10px; color: #d2cabc; }
|
|
39233
|
+
.vr-hud-strip strong { font-weight: 720; color: #f7f4ec; }
|
|
39234
|
+
.vr-hud-strip em,
|
|
39235
|
+
.vr-hud-strip b { font-weight: 600; }
|
|
39236
|
+
|
|
39237
|
+
/* 1f. Context chips \u2014 cream sans label, drop the cold-grey muted qualifier. */
|
|
39238
|
+
.vr-context-chip-label {
|
|
39239
|
+
font-size: 12px;
|
|
39240
|
+
font-weight: 620;
|
|
39241
|
+
letter-spacing: 0.01em;
|
|
39242
|
+
}
|
|
39243
|
+
.vr-context-chip-label .muted {
|
|
39244
|
+
color: var(--vr-muted);
|
|
39245
|
+
font-weight: 560;
|
|
39246
|
+
}
|
|
39247
|
+
|
|
39248
|
+
/* 1g. Region-map / architecture node badges + zone/hint \u2014 weight up, cap track. */
|
|
39249
|
+
.vr-arch-node-badge {
|
|
39250
|
+
font-size: 10.5px;
|
|
39251
|
+
font-weight: 780;
|
|
39252
|
+
letter-spacing: 0.02em;
|
|
39253
|
+
}
|
|
39254
|
+
.vr-arch-zone { font-size: 10px; letter-spacing: 0.06em; }
|
|
39255
|
+
.vr-arch-hint { font-size: 11px; letter-spacing: 0.01em; line-height: 1.4; }
|
|
39256
|
+
|
|
39257
|
+
/* 1h. Model/scope picker button \u2014 selected model reads clean, non-condensed. */
|
|
39258
|
+
.vr-model-picker > button strong {
|
|
39259
|
+
font-family: var(--vr-hud-sans, 'Geist', 'Inter', system-ui, sans-serif);
|
|
39260
|
+
font-size: 12px;
|
|
39261
|
+
font-weight: 680;
|
|
39262
|
+
letter-spacing: 0.01em;
|
|
39263
|
+
}
|
|
39264
|
+
.vr-model-picker > button span {
|
|
39265
|
+
font-size: 10px;
|
|
39266
|
+
letter-spacing: 0.02em;
|
|
39267
|
+
color: var(--vr-muted);
|
|
39268
|
+
}
|
|
39269
|
+
|
|
39270
|
+
/* 1i. Dropdown menu rows \u2014 readable item body + sub-caption, sans not condensed. */
|
|
39271
|
+
.vr-model-menu button,
|
|
39272
|
+
.vr-scope-menu button,
|
|
39273
|
+
.vr-chat-command-popover button {
|
|
39274
|
+
font-size: 12.5px;
|
|
39275
|
+
letter-spacing: 0.005em;
|
|
39276
|
+
}
|
|
39277
|
+
.vr-model-menu button strong { font-weight: 660; }
|
|
39278
|
+
.vr-model-menu button em { font-size: 11px; font-style: normal; color: var(--vr-muted); }
|
|
39279
|
+
|
|
39280
|
+
/* 1j. Stat-card label under the big Anton KPI number \u2014 size up the smear. */
|
|
39281
|
+
.vr-stat-card span {
|
|
39282
|
+
font-size: 9.5px;
|
|
39283
|
+
letter-spacing: 0.08em;
|
|
39284
|
+
font-weight: 620;
|
|
39285
|
+
color: #ccc4b6;
|
|
39286
|
+
}
|
|
39287
|
+
|
|
39288
|
+
/* 1k. Version card meta / branch / pile label \u2014 floor size + cap tracking.
|
|
39289
|
+
(Overrides the contrast-pass 8.5px !important at 16063-64 and the pile
|
|
39290
|
+
letter-spacing at 16080, so font-size/letter-spacing need !important.) */
|
|
39291
|
+
.vr-vcard-meta,
|
|
39292
|
+
.vr-vcard-branch {
|
|
39293
|
+
font-size: 9.5px !important; /* was 8.5px !important */
|
|
39294
|
+
letter-spacing: 0.05em !important;
|
|
39295
|
+
}
|
|
39296
|
+
.vr-version-pile-label {
|
|
39297
|
+
font-size: 9.5px !important;
|
|
39298
|
+
letter-spacing: 0.08em !important; /* was 1.8px */
|
|
39299
|
+
font-weight: 640;
|
|
39300
|
+
}
|
|
39301
|
+
|
|
39302
|
+
/* 1l. SHUFFLE / worktree / table-foot action captions \u2014 legible click labels. */
|
|
39303
|
+
.vr-pile-shuffle,
|
|
39304
|
+
.vr-bcard-actions button,
|
|
39305
|
+
.vr-table-warning button,
|
|
39306
|
+
.vr-table-foot button {
|
|
39307
|
+
font-size: 10px;
|
|
39308
|
+
letter-spacing: 0.07em;
|
|
39309
|
+
font-weight: 680;
|
|
39310
|
+
}
|
|
39311
|
+
|
|
39312
|
+
/* 1m. Highest-traffic reading surfaces \u2014 comfortable body size + leading. */
|
|
39313
|
+
.vr-agent-answer-body,
|
|
39314
|
+
.vr-agent-answer-body p,
|
|
39315
|
+
.vr-chat-message p,
|
|
39316
|
+
.vr-chat-bubble p {
|
|
39317
|
+
font-size: 13.5px;
|
|
39318
|
+
line-height: 1.55;
|
|
39319
|
+
letter-spacing: 0.003em;
|
|
39320
|
+
}
|
|
39321
|
+
.vr-terminal-line { font-size: 12.5px; line-height: 1.5; }
|
|
39322
|
+
|
|
39323
|
+
/* 1n. Empty-state / drop-zone / note / recent-chat meta \u2014 lift learn-the-UI text. */
|
|
39324
|
+
.vr-table-empty { font-size: 12.5px; line-height: 1.45; }
|
|
39325
|
+
.vr-provider-drop-zone { font-size: 12px; letter-spacing: 0.01em; }
|
|
39326
|
+
.vr-chat-note { font-size: 12px; line-height: 1.45; }
|
|
39327
|
+
.vr-recent-chat em,
|
|
39328
|
+
.vr-recent-chat small { font-size: 11px; font-style: normal; }
|
|
39329
|
+
|
|
39330
|
+
/* 1o. Env-connect code chip + terminal compose \u2014 legible mono command hints. */
|
|
39331
|
+
.vr-env-connect-option b {
|
|
39332
|
+
font-size: 10px;
|
|
39333
|
+
letter-spacing: 0.04em;
|
|
39334
|
+
font-weight: 640;
|
|
39335
|
+
}
|
|
39336
|
+
.vr-terminal-compose textarea {
|
|
39337
|
+
font-size: 13px;
|
|
39338
|
+
line-height: 1.5;
|
|
39339
|
+
letter-spacing: 0;
|
|
39340
|
+
}
|
|
39341
|
+
|
|
39342
|
+
/* -------------------------------------------------------------------------
|
|
39343
|
+
(2) MANGA CARD-VIBE BACKGROUND \u2014 all margin/corner-masked, never behind text
|
|
39344
|
+
------------------------------------------------------------------------- */
|
|
39345
|
+
|
|
39346
|
+
/* Keep app chrome above the fixed texture layers so opaque panels occlude them. */
|
|
39347
|
+
.vr-app { position: relative; z-index: 1; }
|
|
39348
|
+
.vr-composed-shell { position: relative; z-index: 1; }
|
|
39349
|
+
|
|
39350
|
+
/* 2a. Fixed full-viewport ink-splatter, painted ONLY in the outer page gutter.
|
|
39351
|
+
The .vr-composed-shell (opaque near-black, margin:10px 12px) sits on top and
|
|
39352
|
+
blocks it wherever real content lives; screen-blend keeps it light ink. */
|
|
39353
|
+
body::before {
|
|
39354
|
+
content: '';
|
|
39355
|
+
position: fixed;
|
|
39356
|
+
inset: 0;
|
|
39357
|
+
z-index: 0;
|
|
39358
|
+
pointer-events: none;
|
|
39359
|
+
background: url('/manga/bg.webp') no-repeat center center / cover;
|
|
39360
|
+
/* opacity + mask only \u2014 no mix-blend/filter (those are GPU-heavy on a
|
|
39361
|
+
fixed full-viewport layer and stall headless capture). The art is already
|
|
39362
|
+
ink-on-black so it reads as faint ink in the gutter at this opacity. */
|
|
39363
|
+
opacity: 0.09;
|
|
39364
|
+
-webkit-mask-image: radial-gradient(ellipse 74% 70% at 50% 46%, transparent 60%, #000 92%);
|
|
39365
|
+
mask-image: radial-gradient(ellipse 74% 70% at 50% 46%, transparent 60%, #000 92%);
|
|
39366
|
+
}
|
|
39367
|
+
|
|
39368
|
+
/* 2b. Corner-weighted fine GOLD halftone screentone (manga-card dot vibe),
|
|
39369
|
+
masked to two opposite corners only so the chat/panel mid-screen stays clean. */
|
|
39370
|
+
body::after {
|
|
39371
|
+
content: '';
|
|
39372
|
+
position: fixed;
|
|
39373
|
+
inset: 0;
|
|
39374
|
+
z-index: 0;
|
|
39375
|
+
pointer-events: none;
|
|
39376
|
+
background-image: radial-gradient(rgba(232, 193, 90, 0.10) 0.9px, transparent 1.3px);
|
|
39377
|
+
background-size: 5px 5px;
|
|
39378
|
+
opacity: 0.5;
|
|
39379
|
+
-webkit-mask-image:
|
|
39380
|
+
radial-gradient(circle at 100% 0%, #000 0%, transparent 34%),
|
|
39381
|
+
radial-gradient(circle at 0% 100%, #000 0%, transparent 34%);
|
|
39382
|
+
mask-image:
|
|
39383
|
+
radial-gradient(circle at 100% 0%, #000 0%, transparent 34%),
|
|
39384
|
+
radial-gradient(circle at 0% 100%, #000 0%, transparent 34%);
|
|
39385
|
+
-webkit-mask-composite: source-over;
|
|
39386
|
+
mask-composite: add;
|
|
39387
|
+
}
|
|
39388
|
+
|
|
39389
|
+
/* 2c. Ghost provider card tucked into the shell's top-left gutter, behind the
|
|
39390
|
+
translucent topbar/rail only. Lives inside overflow:hidden (clipped to shell),
|
|
39391
|
+
blurred + rotated like a card left on the table, faded before the chat column.
|
|
39392
|
+
RISK NOTE: .vr-composed-shell::after is reused as the drop overlay while
|
|
39393
|
+
dragging (.vr-app.is-dragging-*), which harmlessly hides this watermark
|
|
39394
|
+
during an active drag; it returns on drop. Idle state is unaffected. */
|
|
39395
|
+
.vr-composed-shell .vr-studio-body::after {
|
|
39396
|
+
content: '';
|
|
39397
|
+
position: absolute;
|
|
39398
|
+
left: -70px;
|
|
39399
|
+
top: -40px;
|
|
39400
|
+
width: 300px;
|
|
39401
|
+
height: 420px;
|
|
39402
|
+
z-index: 0;
|
|
39403
|
+
pointer-events: none;
|
|
39404
|
+
background: url('/manga/cards/supabase.webp') no-repeat center / contain;
|
|
39405
|
+
opacity: 0.05;
|
|
39406
|
+
transform: rotate(-13deg);
|
|
39407
|
+
filter: grayscale(0.6) contrast(0.95) blur(0.4px);
|
|
39408
|
+
-webkit-mask-image: linear-gradient(135deg, #000 12%, transparent 62%);
|
|
39409
|
+
mask-image: linear-gradient(135deg, #000 12%, transparent 62%);
|
|
39410
|
+
}
|
|
39411
|
+
|
|
39412
|
+
/* 2d. Existing raven emblem watermark (base at 15577, opacity 0.06, no mask):
|
|
39413
|
+
add a corner-fade mask + push below content so it never creeps under rows.
|
|
39414
|
+
!important here re-targets the already-textured pseudo across states. */
|
|
39415
|
+
.vr-table-view::after,
|
|
39416
|
+
.vr-studio-architecture.is-region-map::after {
|
|
39417
|
+
z-index: 0 !important;
|
|
39418
|
+
opacity: 0.07 !important;
|
|
39419
|
+
-webkit-mask-image: radial-gradient(circle at 100% 100%, #000 0%, transparent 58%) !important;
|
|
39420
|
+
mask-image: radial-gradient(circle at 100% 100%, #000 0%, transparent 58%) !important;
|
|
39421
|
+
}
|
|
39422
|
+
.vr-table-view > *,
|
|
39423
|
+
.vr-studio-architecture.is-region-map > * { position: relative; z-index: 1; }
|
|
39424
|
+
|
|
39425
|
+
/* 2e. Poster ghost low in the left gutter of the studio body \u2014 far-corner masked
|
|
39426
|
+
+ blurred so it never reaches the readable center/right columns. */
|
|
39427
|
+
.vr-composed-shell .vr-studio-body { position: relative; }
|
|
39428
|
+
.vr-composed-shell .vr-studio-body::before {
|
|
39429
|
+
content: '';
|
|
39430
|
+
position: absolute;
|
|
39431
|
+
left: -30px;
|
|
39432
|
+
bottom: -30px;
|
|
39433
|
+
width: 280px;
|
|
39434
|
+
height: 360px;
|
|
39435
|
+
z-index: 0;
|
|
39436
|
+
pointer-events: none;
|
|
39437
|
+
background: url('/manga/poster.webp') no-repeat left bottom / contain;
|
|
39438
|
+
opacity: 0.045;
|
|
39439
|
+
filter: grayscale(0.7) contrast(1.05) blur(0.6px);
|
|
39440
|
+
-webkit-mask-image: radial-gradient(circle at 0% 100%, #000 0%, transparent 55%);
|
|
39441
|
+
mask-image: radial-gradient(circle at 0% 100%, #000 0%, transparent 55%);
|
|
39442
|
+
}
|
|
39443
|
+
|
|
39444
|
+
/* 2f. CONTRAST GUARD \u2014 the three translucent panels are rgba(18,20,24,.78),
|
|
39445
|
+
22% transparent, so texture could faintly show under text. Bump the ink base
|
|
39446
|
+
more opaque; margins keep the vibe, text stays crisp. (background-color only,
|
|
39447
|
+
later source order beats the shorthand at 1737 without !important.) */
|
|
39448
|
+
.vr-studio-chat,
|
|
39449
|
+
.vr-studio-terminal,
|
|
39450
|
+
.vr-studio-diff { background-color: rgba(14, 15, 19, 0.9); }
|
|
39451
|
+
|
|
39452
|
+
/* ============================================================================
|
|
39453
|
+
MANGA READABILITY \u2014 FINAL ENFORCEMENT PASS (appended after all prior
|
|
39454
|
+
override chains: MANGA THEME PASS / B&W CONTRAST / FINAL FIXES / READABILITY).
|
|
39455
|
+
Wins by source order. Two groups:
|
|
39456
|
+
(1) READABLE FONTS \u2014 strict 3-tier type system, no coloured/gradient
|
|
39457
|
+
button text, condensed Anton pulled off all running/clickable UI.
|
|
39458
|
+
(2) MENTION + WELCOME/HANDOFF MANGA THEME \u2014 re-skin the old blue-slate
|
|
39459
|
+
PromptModal + quickstart to ink/gold manga.
|
|
39460
|
+
!important is used ONLY where an existing same-file !important forces it
|
|
39461
|
+
(documented inline). Readability always wins over theme where they overlap.
|
|
39462
|
+
RISK NOTES: clip-path notches added to modal/menu panels can clip focus
|
|
39463
|
+
rings / drop-shadows on the notched corner \u2014 acceptable (decorative corner
|
|
39464
|
+
only, ~12-18px, no interactive target sits there). No overflow:hidden added,
|
|
39465
|
+
so popovers/tooltips are unaffected.
|
|
39466
|
+
========================================================================= */
|
|
39467
|
+
|
|
39468
|
+
/* ---------------------------------------------------------------------------
|
|
39469
|
+
GROUP 1 \u2014 READABLE FONTS
|
|
39470
|
+
--------------------------------------------------------------------------- */
|
|
39471
|
+
|
|
39472
|
+
/* 1.0 \u2014 Foundation: guarantee one clean non-condensed sans stack for TIER 2.
|
|
39473
|
+
Every rule below that says var(--vr-hud-sans) resolves to this. */
|
|
39474
|
+
:root {
|
|
39475
|
+
--vr-hud-sans: 'Geist', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
39476
|
+
}
|
|
39477
|
+
|
|
39478
|
+
/* 1.1 \u2014 Composer action bar (ADD CONTEXT / MENTION / COMMANDS / WORST CARD /
|
|
39479
|
+
ADD CARD): the exact pills the user screenshotted. Clean sans, normal-case,
|
|
39480
|
+
comfortable size, single cream colour. Neutralise any inherited condensed
|
|
39481
|
+
face and any -webkit-text-fill on the label span. */
|
|
39482
|
+
.vr-chat-inline-actions > button,
|
|
39483
|
+
.vr-chat-command-trigger > button,
|
|
39484
|
+
.vr-chat-inline-actions button {
|
|
39485
|
+
font-family: var(--vr-hud-sans);
|
|
39486
|
+
font-size: 12.5px;
|
|
39487
|
+
font-weight: 650;
|
|
39488
|
+
letter-spacing: 0.02em;
|
|
39489
|
+
text-transform: none;
|
|
39490
|
+
color: var(--vr-text);
|
|
39491
|
+
}
|
|
39492
|
+
.vr-chat-inline-actions > button span,
|
|
39493
|
+
.vr-chat-command-trigger > button span {
|
|
39494
|
+
font-family: var(--vr-hud-sans);
|
|
39495
|
+
font-weight: 650;
|
|
39496
|
+
letter-spacing: 0.02em;
|
|
39497
|
+
color: var(--vr-text);
|
|
39498
|
+
-webkit-text-fill-color: currentColor;
|
|
39499
|
+
background: none;
|
|
39500
|
+
}
|
|
39501
|
+
|
|
39502
|
+
/* 1.2 \u2014 Composer action icons: kill MENTION multicolour / ADD CARD purple.
|
|
39503
|
+
Pin all glyphs to the same muted cream as the label so each pill is one
|
|
39504
|
+
legible colour. (Worst-card icon keeps a gold accent \u2014 see 1.3.) */
|
|
39505
|
+
.vr-chat-inline-actions > button i[data-icon],
|
|
39506
|
+
.vr-chat-inline-actions > button svg,
|
|
39507
|
+
.vr-chat-command-trigger > button i[data-icon],
|
|
39508
|
+
.vr-chat-command-trigger > button svg {
|
|
39509
|
+
color: var(--vr-muted);
|
|
39510
|
+
stroke: var(--vr-muted);
|
|
39511
|
+
}
|
|
39512
|
+
|
|
39513
|
+
/* 1.3 \u2014 WORST CARD pill: remove the gold TEXT (overrides 14663-14664). Label
|
|
39514
|
+
goes cream like its siblings; gold survives only as border + icon accent. */
|
|
39515
|
+
.vr-chat-inline-actions > button.is-worst-card,
|
|
39516
|
+
.vr-chat-inline-actions > button.is-worst-card span {
|
|
39517
|
+
color: var(--vr-text);
|
|
39518
|
+
}
|
|
39519
|
+
.vr-chat-inline-actions > button.is-worst-card {
|
|
39520
|
+
border-color: rgba(232, 193, 90, 0.42);
|
|
39521
|
+
}
|
|
39522
|
+
.vr-chat-inline-actions > button.is-worst-card i[data-icon],
|
|
39523
|
+
.vr-chat-inline-actions > button.is-worst-card svg {
|
|
39524
|
+
color: var(--vr-gold);
|
|
39525
|
+
stroke: var(--vr-gold);
|
|
39526
|
+
}
|
|
39527
|
+
|
|
39528
|
+
/* 1.4 \u2014 is-primary composer pills (gold fill): dark ink text, not gold text. */
|
|
39529
|
+
.vr-chat-inline-actions button.is-primary,
|
|
39530
|
+
.vr-chat-inline-actions button.is-primary span {
|
|
39531
|
+
color: #1a1206;
|
|
39532
|
+
}
|
|
39533
|
+
|
|
39534
|
+
/* 1.5 \u2014 Hover on composer buttons: emphasis via border + bright ink, not by
|
|
39535
|
+
flipping the whole label. Gold-bright label on hover is legible on the
|
|
39536
|
+
darkened background and matches the menu hover language elsewhere. */
|
|
39537
|
+
.vr-chat-inline-actions button:hover,
|
|
39538
|
+
.vr-chat-inline-actions > button:hover,
|
|
39539
|
+
.vr-chat-command-trigger > button:hover {
|
|
39540
|
+
color: var(--vr-gold-bright);
|
|
39541
|
+
border-color: var(--vr-gold);
|
|
39542
|
+
background: rgba(20, 18, 12, 0.85);
|
|
39543
|
+
}
|
|
39544
|
+
.vr-chat-inline-actions > button:hover span { color: var(--vr-gold-bright); }
|
|
39545
|
+
.vr-chat-inline-actions > button:hover i[data-icon],
|
|
39546
|
+
.vr-chat-inline-actions > button:hover svg {
|
|
39547
|
+
color: var(--vr-gold-bright);
|
|
39548
|
+
stroke: var(--vr-gold-bright);
|
|
39549
|
+
}
|
|
39550
|
+
|
|
39551
|
+
/* 1.6 \u2014 ADD CARD shelf chip + is-gold variant. Base 8.5px/1.4px mono (14503)
|
|
39552
|
+
is NOT !important, so plain declarations win by source order \u2014 no
|
|
39553
|
+
!important needed. Readable sans, >=11px, tight tracking; gold stays as the
|
|
39554
|
+
FILL with dark ink text. */
|
|
39555
|
+
.vr-shelf-chip {
|
|
39556
|
+
font-family: var(--vr-hud-sans);
|
|
39557
|
+
font-size: 11px;
|
|
39558
|
+
font-weight: 650;
|
|
39559
|
+
letter-spacing: 0.03em;
|
|
39560
|
+
text-transform: none;
|
|
39561
|
+
color: var(--vr-text);
|
|
39562
|
+
}
|
|
39563
|
+
.vr-shelf-chip.is-gold { color: #1a1206; }
|
|
39564
|
+
|
|
39565
|
+
/* 1.7 \u2014 Quick-action tiles (left rail). Sans, readable weight/size, single
|
|
39566
|
+
cream colour; icon a quiet accent. */
|
|
39567
|
+
.vr-quick-action,
|
|
39568
|
+
.vr-quick-action strong,
|
|
39569
|
+
.vr-quick-action em {
|
|
39570
|
+
font-family: var(--vr-hud-sans);
|
|
39571
|
+
letter-spacing: 0.01em;
|
|
39572
|
+
text-transform: none;
|
|
39573
|
+
color: var(--vr-text);
|
|
39574
|
+
}
|
|
39575
|
+
.vr-quick-action strong { font-size: 12.5px; font-weight: 660; }
|
|
39576
|
+
.vr-quick-action em { font-size: 11px; font-weight: 500; color: var(--vr-muted); }
|
|
39577
|
+
.vr-quick-action i, .vr-quick-action svg { color: var(--vr-muted); stroke: var(--vr-muted); }
|
|
39578
|
+
|
|
39579
|
+
/* 1.8 \u2014 Dropdown menu rows (model / scope / command popover). Sans, comfortable
|
|
39580
|
+
size, cream text. Section HEADERS (.vr-model-menu p / .vr-scope-menu p) stay
|
|
39581
|
+
Anton gold \u2014 that is a valid TIER-1 eyebrow, restyled in 1.9 / GROUP 2. */
|
|
39582
|
+
.vr-model-menu button,
|
|
39583
|
+
.vr-scope-menu button,
|
|
39584
|
+
.vr-chat-command-popover button {
|
|
39585
|
+
font-family: var(--vr-hud-sans);
|
|
39586
|
+
font-size: 12.5px;
|
|
39587
|
+
font-weight: 600;
|
|
39588
|
+
letter-spacing: 0.005em;
|
|
39589
|
+
text-transform: none;
|
|
39590
|
+
color: var(--vr-text);
|
|
39591
|
+
}
|
|
39592
|
+
.vr-model-menu button strong,
|
|
39593
|
+
.vr-scope-menu button strong { font-family: var(--vr-hud-sans); font-weight: 660; }
|
|
39594
|
+
.vr-model-menu button em,
|
|
39595
|
+
.vr-scope-menu button em {
|
|
39596
|
+
font-family: var(--vr-hud-sans);
|
|
39597
|
+
font-style: normal;
|
|
39598
|
+
font-weight: 500;
|
|
39599
|
+
color: var(--vr-muted);
|
|
39600
|
+
}
|
|
39601
|
+
|
|
39602
|
+
/* 1.9 \u2014 Quickstrike command menu: clickable rows go sans/cream; header stays a
|
|
39603
|
+
small tracked eyebrow. */
|
|
39604
|
+
.vr-quickstrike button {
|
|
39605
|
+
font-family: var(--vr-hud-sans);
|
|
39606
|
+
font-size: 12.5px;
|
|
39607
|
+
font-weight: 600;
|
|
39608
|
+
letter-spacing: 0.01em;
|
|
39609
|
+
text-transform: none;
|
|
39610
|
+
color: var(--vr-text);
|
|
39611
|
+
}
|
|
39612
|
+
.vr-quickstrike header {
|
|
39613
|
+
font-size: 11px;
|
|
39614
|
+
letter-spacing: 0.06em;
|
|
39615
|
+
}
|
|
39616
|
+
|
|
39617
|
+
/* 1.10 \u2014 Model/scope picker trigger (selected-model label). */
|
|
39618
|
+
.vr-model-picker > button strong {
|
|
39619
|
+
font-family: var(--vr-hud-sans);
|
|
39620
|
+
font-size: 12px;
|
|
39621
|
+
font-weight: 660;
|
|
39622
|
+
letter-spacing: 0.01em;
|
|
39623
|
+
color: var(--vr-text);
|
|
39624
|
+
}
|
|
39625
|
+
.vr-model-picker > button span {
|
|
39626
|
+
font-family: var(--vr-hud-sans);
|
|
39627
|
+
font-size: 10.5px;
|
|
39628
|
+
letter-spacing: 0.02em;
|
|
39629
|
+
color: var(--vr-muted);
|
|
39630
|
+
}
|
|
39631
|
+
|
|
39632
|
+
/* 1.11 \u2014 Primary gold CTAs that were switched to Anton (15704+): pull them to
|
|
39633
|
+
bold sans, dark ink on gold. Gold is fill/accent, never text colour. */
|
|
39634
|
+
.vr-new-chat-button,
|
|
39635
|
+
.vr-provider-ask-agent,
|
|
39636
|
+
.vr-approve-all,
|
|
39637
|
+
.vr-chat-command-popover button.is-primary,
|
|
39638
|
+
.vr-agent-followups button.is-primary,
|
|
39639
|
+
.vr-agent-inline-action.is-primary,
|
|
39640
|
+
.vr-cli-action-button.is-primary,
|
|
39641
|
+
.vr-studio-add-chat,
|
|
39642
|
+
.vr-studio-architecture > footer button.is-primary,
|
|
39643
|
+
.vr-arch-drawer footer button.is-primary,
|
|
39644
|
+
.vr-wt-actions button.is-primary {
|
|
39645
|
+
font-family: var(--vr-hud-sans);
|
|
39646
|
+
font-weight: 700;
|
|
39647
|
+
letter-spacing: 0.02em;
|
|
39648
|
+
text-transform: none;
|
|
39649
|
+
color: #1a1206;
|
|
39650
|
+
}
|
|
39651
|
+
|
|
39652
|
+
/* 1.12 \u2014 Studio tab bar (CHAT / ARCHITECTURE / TERMINAL / DIFF): legitimate
|
|
39653
|
+
TIER-1 marquee. Keep Anton, but lock size/tracking legible; active tab keeps
|
|
39654
|
+
dark ink on gold. */
|
|
39655
|
+
.vr-studio-tabs button {
|
|
39656
|
+
font-family: var(--mg-display);
|
|
39657
|
+
font-size: 13.5px;
|
|
39658
|
+
letter-spacing: 0.06em;
|
|
39659
|
+
font-weight: 400;
|
|
39660
|
+
}
|
|
39661
|
+
.vr-studio-tabs button.is-active { color: #0a0b0e; }
|
|
39662
|
+
|
|
39663
|
+
/* 1.13 \u2014 Context chips + provider drop-label in the composer. */
|
|
39664
|
+
.vr-context-chip-label,
|
|
39665
|
+
.vr-provider-drop-label {
|
|
39666
|
+
font-family: var(--vr-hud-sans);
|
|
39667
|
+
font-size: 12px;
|
|
39668
|
+
font-weight: 620;
|
|
39669
|
+
letter-spacing: 0.01em;
|
|
39670
|
+
text-transform: none;
|
|
39671
|
+
color: var(--vr-text);
|
|
39672
|
+
}
|
|
39673
|
+
.vr-context-chip-label .muted { font-weight: 520; color: var(--vr-muted); }
|
|
39674
|
+
|
|
39675
|
+
/* 1.14 \u2014 Stat-card LABEL beneath the Anton KPI number. The number
|
|
39676
|
+
(.vr-stat-card b) keeps Anton untouched; only the micro-label is lifted. */
|
|
39677
|
+
.vr-stat-card span {
|
|
39678
|
+
font-family: var(--vr-hud-sans);
|
|
39679
|
+
font-size: 10.5px;
|
|
39680
|
+
font-weight: 600;
|
|
39681
|
+
letter-spacing: 0.04em;
|
|
39682
|
+
text-transform: uppercase;
|
|
39683
|
+
color: #ccc4b6;
|
|
39684
|
+
}
|
|
39685
|
+
|
|
39686
|
+
/* 1.15 \u2014 Ribbon stat qualifier + table-ribbon brand value. */
|
|
39687
|
+
.vr-ribbon-stat i {
|
|
39688
|
+
font-family: var(--vr-hud-sans);
|
|
39689
|
+
font-size: 10px;
|
|
39690
|
+
font-weight: 600;
|
|
39691
|
+
letter-spacing: 0.03em;
|
|
39692
|
+
color: var(--vr-muted);
|
|
39693
|
+
}
|
|
39694
|
+
.vr-table-ribbon > b {
|
|
39695
|
+
font-family: var(--vr-hud-sans);
|
|
39696
|
+
font-size: 12.5px;
|
|
39697
|
+
font-weight: 700;
|
|
39698
|
+
color: var(--vr-gold-bright);
|
|
39699
|
+
}
|
|
39700
|
+
|
|
39701
|
+
/* 1.16 \u2014 Version card meta / branch / pile labels. These carry same-file
|
|
39702
|
+
!important (16062/16064/16065/16081) on color/size/family, so !important is
|
|
39703
|
+
required here to win on family + tracking. Size floors from 16386 are left
|
|
39704
|
+
intact (readability floor already >=9.5px). */
|
|
39705
|
+
.vr-vcard-meta,
|
|
39706
|
+
.vr-vcard-branch,
|
|
39707
|
+
.vr-version-pile-label {
|
|
39708
|
+
font-family: var(--vr-hud-sans) !important;
|
|
39709
|
+
letter-spacing: 0.03em !important;
|
|
39710
|
+
text-transform: none;
|
|
39711
|
+
}
|
|
39712
|
+
.vr-vpile-card b {
|
|
39713
|
+
font-family: var(--vr-hud-sans) !important; /* beats 16062 !important */
|
|
39714
|
+
letter-spacing: 0.01em;
|
|
39715
|
+
}
|
|
39716
|
+
|
|
39717
|
+
/* 1.17 \u2014 Shuffle / worktree / table-foot / back-card / addpick action captions:
|
|
39718
|
+
every click label a plain readable word, not a condensed cap. */
|
|
39719
|
+
.vr-pile-shuffle,
|
|
39720
|
+
.vr-bcard-actions button,
|
|
39721
|
+
.vr-table-warning button,
|
|
39722
|
+
.vr-table-foot button,
|
|
39723
|
+
.vr-addpick-list button strong {
|
|
39724
|
+
font-family: var(--vr-hud-sans);
|
|
39725
|
+
font-size: 11px;
|
|
39726
|
+
font-weight: 640;
|
|
39727
|
+
letter-spacing: 0.03em;
|
|
39728
|
+
text-transform: none;
|
|
39729
|
+
color: var(--vr-text);
|
|
39730
|
+
}
|
|
39731
|
+
|
|
39732
|
+
/* 1.18 \u2014 Global guard: no gradient/clipped text may re-enter any button/label.
|
|
39733
|
+
(No same-file !important on -webkit-text-fill-color, so none needed here.) */
|
|
39734
|
+
.vr-chat-inline-actions button,
|
|
39735
|
+
.vr-chat-command-trigger button,
|
|
39736
|
+
.vr-quick-action,
|
|
39737
|
+
.vr-quick-action strong,
|
|
39738
|
+
.vr-quick-action em,
|
|
39739
|
+
.vr-shelf-chip,
|
|
39740
|
+
.vr-studio-tabs button,
|
|
39741
|
+
.vr-model-menu button,
|
|
39742
|
+
.vr-scope-menu button,
|
|
39743
|
+
.vr-chat-command-popover button {
|
|
39744
|
+
-webkit-text-fill-color: currentColor;
|
|
39745
|
+
-webkit-background-clip: border-box;
|
|
39746
|
+
background-clip: border-box;
|
|
39747
|
+
}
|
|
39748
|
+
|
|
39749
|
+
/* ---------------------------------------------------------------------------
|
|
39750
|
+
GROUP 2 \u2014 MENTION + WELCOME/HANDOFF MANGA THEME
|
|
39751
|
+
The composer "Mention" button (data-action="prompt") opens the PromptModal,
|
|
39752
|
+
so re-theming the PromptModal fixes both the "mention screen" and the Scoped
|
|
39753
|
+
Handoff / Agent Mission modal. Also sweeps the leftover blue-slate theme off
|
|
39754
|
+
Guide/Plan/Notifications and finishes the quickstart cards.
|
|
39755
|
+
RISK NOTE: clip-path notch on modal panels clips the far corner only; no
|
|
39756
|
+
text or control sits there.
|
|
39757
|
+
--------------------------------------------------------------------------- */
|
|
39758
|
+
|
|
39759
|
+
/* 2.1 \u2014 Modal header shell (Agent Mission / Guide): navy gradient + slate
|
|
39760
|
+
border -> ink panel, gold left spine, gold halftone. */
|
|
39761
|
+
.vr-modal-prompt-head,
|
|
39762
|
+
.vr-modal-guide-head {
|
|
39763
|
+
border: 1px solid var(--vr-border-strong);
|
|
39764
|
+
border-left: 3px solid var(--vr-gold);
|
|
39765
|
+
border-radius: 0;
|
|
39766
|
+
clip-path: polygon(0 0, calc(100% - 18px) 0, 100% 18px, 100% 100%, 18px 100%, 0 calc(100% - 18px));
|
|
39767
|
+
background-color: rgba(9, 9, 11, 0.94);
|
|
39768
|
+
background-image:
|
|
39769
|
+
radial-gradient(circle at 12% 30%, rgba(232, 193, 90, 0.07), transparent 40%),
|
|
39770
|
+
radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px);
|
|
39771
|
+
background-size: auto, 9px 9px;
|
|
39772
|
+
box-shadow: 5px 6px 0 rgba(0, 0, 0, 0.55);
|
|
39773
|
+
}
|
|
39774
|
+
|
|
39775
|
+
/* 2.2 \u2014 Header eyebrow: gold token, small Anton poster eyebrow. */
|
|
39776
|
+
.vr-modal-prompt-head p,
|
|
39777
|
+
.vr-modal-guide-head p {
|
|
39778
|
+
color: var(--vr-gold);
|
|
39779
|
+
font-family: var(--mg-display);
|
|
39780
|
+
font-weight: 400;
|
|
39781
|
+
font-size: 12px;
|
|
39782
|
+
letter-spacing: 0.14em;
|
|
39783
|
+
}
|
|
39784
|
+
|
|
39785
|
+
/* 2.3 \u2014 Header title: Anton poster caps, cream ink. */
|
|
39786
|
+
.vr-modal-prompt-head h2,
|
|
39787
|
+
.vr-modal-guide-head h2 {
|
|
39788
|
+
font-family: var(--mg-display);
|
|
39789
|
+
font-weight: 400;
|
|
39790
|
+
font-size: 40px;
|
|
39791
|
+
letter-spacing: 0.01em;
|
|
39792
|
+
text-transform: uppercase;
|
|
39793
|
+
color: var(--vr-text);
|
|
39794
|
+
}
|
|
39795
|
+
|
|
39796
|
+
/* 2.4 \u2014 Header sub-copy: ice-blue -> readable cream sans. */
|
|
39797
|
+
.vr-modal-prompt-head em,
|
|
39798
|
+
.vr-modal-guide-head em {
|
|
39799
|
+
font-family: var(--vr-hud-sans);
|
|
39800
|
+
color: var(--vr-muted);
|
|
39801
|
+
font-size: 14px;
|
|
39802
|
+
font-style: normal;
|
|
39803
|
+
line-height: 1.5;
|
|
39804
|
+
}
|
|
39805
|
+
|
|
39806
|
+
/* 2.5 \u2014 Header side aside (Scope / One gap): slate glass -> ink + gold hairline. */
|
|
39807
|
+
.vr-modal-prompt-head aside,
|
|
39808
|
+
.vr-modal-guide-head aside {
|
|
39809
|
+
border: 1px solid var(--vr-border-strong);
|
|
39810
|
+
border-radius: 0;
|
|
39811
|
+
background: rgba(0, 0, 0, 0.28);
|
|
39812
|
+
}
|
|
39813
|
+
.vr-modal-prompt-head aside > i,
|
|
39814
|
+
.vr-modal-guide-head aside > i {
|
|
39815
|
+
background: rgba(232, 193, 90, 0.10);
|
|
39816
|
+
color: var(--vr-gold-bright);
|
|
39817
|
+
border-radius: 0;
|
|
39818
|
+
}
|
|
39819
|
+
.vr-modal-prompt-head aside > span,
|
|
39820
|
+
.vr-modal-guide-head aside > span {
|
|
39821
|
+
color: var(--vr-gold);
|
|
39822
|
+
font-family: var(--vr-hud-sans);
|
|
39823
|
+
letter-spacing: 0.06em;
|
|
39824
|
+
}
|
|
39825
|
+
.vr-modal-prompt-head aside > strong,
|
|
39826
|
+
.vr-modal-guide-head aside > strong { color: var(--vr-text); }
|
|
39827
|
+
|
|
39828
|
+
/* 2.6 \u2014 Scoped-handoff mission <pre> card: navy border + ice-blue mono ->
|
|
39829
|
+
ink card, gold spine, cream mono. */
|
|
39830
|
+
.vr-modal-prompt-card {
|
|
39831
|
+
border: 1px solid var(--vr-border);
|
|
39832
|
+
border-left: 3px solid var(--vr-gold);
|
|
39833
|
+
border-radius: 0;
|
|
39834
|
+
clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px));
|
|
39835
|
+
background:
|
|
39836
|
+
radial-gradient(circle at 88% 0%, rgba(232, 193, 90, 0.05), transparent 34%),
|
|
39837
|
+
rgba(9, 9, 11, 0.94);
|
|
39838
|
+
}
|
|
39839
|
+
.vr-modal-prompt-card pre {
|
|
39840
|
+
color: var(--vr-text);
|
|
39841
|
+
font-family: var(--vr-hud-mono);
|
|
39842
|
+
font-size: 12.5px;
|
|
39843
|
+
line-height: 1.7;
|
|
39844
|
+
}
|
|
39845
|
+
|
|
39846
|
+
/* 2.7 \u2014 Flow/signal list panels: navy -> ink + gold halftone. */
|
|
39847
|
+
.vr-modal-flow-list,
|
|
39848
|
+
.vr-modal-signal-list {
|
|
39849
|
+
border: 1px solid var(--vr-border-strong);
|
|
39850
|
+
border-radius: 0;
|
|
39851
|
+
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 16px 100%, 0 calc(100% - 16px));
|
|
39852
|
+
background:
|
|
39853
|
+
radial-gradient(rgba(232, 193, 90, 0.04) 1px, transparent 1.4px) 0 0 / 9px 9px,
|
|
39854
|
+
rgba(9, 9, 11, 0.94);
|
|
39855
|
+
}
|
|
39856
|
+
|
|
39857
|
+
/* 2.8 \u2014 Flow-list step rows: slate borders + purple glow + cold-blue caption
|
|
39858
|
+
-> ink rows, gold-tinted hover spine, readable sans. */
|
|
39859
|
+
.vr-modal-flow-list button {
|
|
39860
|
+
border: 1px solid var(--vr-border);
|
|
39861
|
+
border-radius: 0;
|
|
39862
|
+
background: rgba(0, 0, 0, 0.25);
|
|
39863
|
+
}
|
|
39864
|
+
.vr-modal-flow-list button:hover {
|
|
39865
|
+
border-color: var(--vr-gold);
|
|
39866
|
+
box-shadow: inset 3px 0 0 var(--vr-gold);
|
|
39867
|
+
background: rgba(232, 193, 90, 0.10);
|
|
39868
|
+
}
|
|
39869
|
+
.vr-modal-flow-list button > span {
|
|
39870
|
+
border: 2px solid var(--vr-gold);
|
|
39871
|
+
color: var(--vr-gold-bright);
|
|
39872
|
+
}
|
|
39873
|
+
.vr-modal-flow-list strong { font-family: var(--vr-hud-sans); color: var(--vr-text); }
|
|
39874
|
+
.vr-modal-flow-list em {
|
|
39875
|
+
font-family: var(--vr-hud-sans);
|
|
39876
|
+
color: var(--vr-muted);
|
|
39877
|
+
font-size: 12px;
|
|
39878
|
+
line-height: 1.45;
|
|
39879
|
+
}
|
|
39880
|
+
|
|
39881
|
+
/* 2.9 \u2014 Composer scope/mention popup panel: reinforce ink + gold spine +
|
|
39882
|
+
comic-notch so it reads as part of the manga card system. */
|
|
39883
|
+
.vr-scope-menu {
|
|
39884
|
+
border-radius: 0;
|
|
39885
|
+
border-left: 3px solid var(--vr-gold);
|
|
39886
|
+
clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 12px 100%, 0 calc(100% - 12px));
|
|
39887
|
+
background-color: rgba(9, 9, 11, 0.96);
|
|
39888
|
+
box-shadow: 4px 6px 0 rgba(0, 0, 0, 0.55);
|
|
39889
|
+
}
|
|
39890
|
+
|
|
39891
|
+
/* 2.10 \u2014 Scope/mention popup section label: Anton gold eyebrow, legible size.
|
|
39892
|
+
(Group 1 already forced the ROWS to sans; this only styles the <p> header.) */
|
|
39893
|
+
.vr-scope-menu p {
|
|
39894
|
+
font-family: var(--mg-display);
|
|
39895
|
+
font-size: 11px;
|
|
39896
|
+
letter-spacing: 0.14em;
|
|
39897
|
+
color: var(--vr-gold);
|
|
39898
|
+
}
|
|
39899
|
+
|
|
39900
|
+
/* 2.11 \u2014 Scope/mention popup rows: gold-tinted hover + selected state.
|
|
39901
|
+
(Font-family/size/colour already set sans in Group 1 \xA71.8 \u2014 here we only add
|
|
39902
|
+
the hover/selected theming so the two passes don't fight.) */
|
|
39903
|
+
.vr-scope-menu button:hover {
|
|
39904
|
+
background: rgba(232, 193, 90, 0.14);
|
|
39905
|
+
box-shadow: inset 3px 0 0 var(--vr-gold);
|
|
39906
|
+
color: var(--vr-gold-bright);
|
|
39907
|
+
}
|
|
39908
|
+
.vr-scope-menu button:has(> b) {
|
|
39909
|
+
background: rgba(232, 193, 90, 0.18);
|
|
39910
|
+
box-shadow: inset 3px 0 0 var(--vr-gold-bright);
|
|
39911
|
+
color: var(--vr-gold-bright);
|
|
39912
|
+
}
|
|
39913
|
+
|
|
39914
|
+
/* 2.12 \u2014 Welcome/quickstart title: condensed --vr-display -> Anton poster. */
|
|
39915
|
+
.vr-qs-head h2 {
|
|
39916
|
+
font-family: var(--mg-display);
|
|
39917
|
+
font-weight: 400;
|
|
39918
|
+
font-size: 32px;
|
|
39919
|
+
letter-spacing: 0.02em;
|
|
39920
|
+
color: var(--vr-text);
|
|
39921
|
+
}
|
|
39922
|
+
|
|
39923
|
+
/* 2.13 \u2014 Welcome sub-copy + LOCAL badge. The 9.5px floor at 16386 keeps
|
|
39924
|
+
.vr-qs-local legible; here we only recolor to gold (no size restated, so we
|
|
39925
|
+
don't fight that !important). */
|
|
39926
|
+
.vr-qs-head p {
|
|
39927
|
+
font-family: var(--vr-hud-sans);
|
|
39928
|
+
font-size: 13px;
|
|
39929
|
+
color: var(--vr-muted);
|
|
39930
|
+
}
|
|
39931
|
+
.vr-qs-local {
|
|
39932
|
+
color: var(--vr-gold);
|
|
39933
|
+
font-weight: 660;
|
|
39934
|
+
}
|
|
39935
|
+
|
|
39936
|
+
/* 2.14 \u2014 Welcome hero cards: rounded flat -> gold clipped-frame collector card. */
|
|
39937
|
+
.vr-qs-card.is-hero {
|
|
39938
|
+
border-radius: 0;
|
|
39939
|
+
clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px));
|
|
39940
|
+
background: linear-gradient(160deg, var(--vr-gold), rgba(232, 193, 90, 0.35));
|
|
39941
|
+
padding: 2px;
|
|
39942
|
+
box-shadow: 0 14px 30px rgba(0, 0, 0, 0.6);
|
|
39943
|
+
}
|
|
39944
|
+
.vr-qs-card.is-hero .vr-qs-card-inner {
|
|
39945
|
+
border-radius: 0;
|
|
39946
|
+
clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 12px 100%, 0 calc(100% - 12px));
|
|
39947
|
+
background:
|
|
39948
|
+
radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px) 0 0 / 8px 8px,
|
|
39949
|
+
rgba(9, 9, 11, 0.96);
|
|
39950
|
+
}
|
|
39951
|
+
|
|
39952
|
+
/* 2.15 \u2014 Welcome hero card title: Anton only on the title; body/labels go sans. */
|
|
39953
|
+
.vr-qs-card.is-hero .vr-qs-card-top strong {
|
|
39954
|
+
font-family: var(--mg-display);
|
|
39955
|
+
font-weight: 400;
|
|
39956
|
+
font-size: 15px;
|
|
39957
|
+
letter-spacing: 0.02em;
|
|
39958
|
+
text-transform: uppercase;
|
|
39959
|
+
color: var(--vr-text);
|
|
39960
|
+
}
|
|
39961
|
+
.vr-qs-card.is-hero .vr-qs-card em,
|
|
39962
|
+
.vr-qs-card.is-hero .vr-qs-type {
|
|
39963
|
+
font-family: var(--vr-hud-sans);
|
|
39964
|
+
color: var(--vr-muted);
|
|
39965
|
+
}
|
|
39966
|
+
.vr-qs-card.is-hero button {
|
|
39967
|
+
font-family: var(--vr-hud-sans);
|
|
39968
|
+
font-weight: 700;
|
|
39969
|
+
letter-spacing: 0.02em;
|
|
39970
|
+
text-transform: none;
|
|
39971
|
+
color: var(--vr-gold-bright);
|
|
39972
|
+
border-color: var(--vr-gold);
|
|
39973
|
+
}
|
|
39974
|
+
|
|
39975
|
+
/* ==========================================================================
|
|
39976
|
+
FINAL POLISH \u2014 drag ghost, active tab, low-quality chat cards
|
|
39977
|
+
========================================================================== */
|
|
39978
|
+
/* Drag ghost: a clean floating card preview. It was a clone that KEPT the
|
|
39979
|
+
placed/hand card's position:absolute + translate(-50%,-50%) / rotation /
|
|
39980
|
+
negative margin, so it rendered as a corrupted half-card. Reset to a plain
|
|
39981
|
+
fixed, upright (slightly tilted) card sized to the source. */
|
|
39982
|
+
.vr-drag-ghost {
|
|
39983
|
+
position: fixed !important;
|
|
39984
|
+
margin: 0 !important;
|
|
39985
|
+
transform: rotate(-4deg) !important;
|
|
39986
|
+
transform-origin: top left;
|
|
39987
|
+
z-index: 100000 !important;
|
|
39988
|
+
pointer-events: none !important;
|
|
39989
|
+
opacity: 0.96;
|
|
39990
|
+
box-shadow: 0 24px 46px rgba(0, 0, 0, 0.78);
|
|
39991
|
+
transition: none !important;
|
|
39992
|
+
}
|
|
39993
|
+
.vr-drag-ghost .vr-tcard-unplace { display: none !important; }
|
|
39994
|
+
.vr-drag-ghost .vr-tcard-holofoil,
|
|
39995
|
+
.vr-drag-ghost .vr-tcard-glare { animation: none !important; opacity: 0.2 !important; }
|
|
39996
|
+
|
|
39997
|
+
/* Active tab: was dark #0a0b0e text on a near-transparent wash = an unreadable
|
|
39998
|
+
"black mark". Gold-bright text on a subtle wash + gold underline reads clean. */
|
|
39999
|
+
.vr-studio-tabs button.is-active {
|
|
40000
|
+
color: var(--vr-gold-bright) !important;
|
|
40001
|
+
background: rgba(244, 241, 232, 0.05);
|
|
40002
|
+
box-shadow: inset 0 -2px 0 var(--vr-gold), inset 0 0 0 1px rgba(232, 193, 90, 0.26);
|
|
40003
|
+
border-radius: 4px;
|
|
40004
|
+
}
|
|
40005
|
+
|
|
40006
|
+
/* ==========================================================================
|
|
40007
|
+
VERSION CARDS \u2014 richer "release card" (was small/plain crimson-inner).
|
|
40008
|
+
Gold ornate frame + comic notch + halftone + BIG Anton version number,
|
|
40009
|
+
matching the premium provider-card language. No full-art (releases have no
|
|
40010
|
+
art), so the version number IS the hero.
|
|
40011
|
+
========================================================================== */
|
|
40012
|
+
.vr-vcard {
|
|
40013
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
40014
|
+
border-radius: 5px !important;
|
|
40015
|
+
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 16px 100%, 0 calc(100% - 16px));
|
|
40016
|
+
background: rgba(9, 9, 11, 0.97) !important;
|
|
40017
|
+
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.6), inset 0 0 0 1px rgba(232, 193, 90, 0.16) !important;
|
|
40018
|
+
overflow: hidden !important;
|
|
40019
|
+
}
|
|
40020
|
+
.vr-vcard::before {
|
|
40021
|
+
inset: 0 !important;
|
|
40022
|
+
border-radius: 0 !important;
|
|
40023
|
+
background-color: transparent !important;
|
|
40024
|
+
background-image:
|
|
40025
|
+
radial-gradient(rgba(232, 193, 90, 0.05) 1px, transparent 1.4px),
|
|
40026
|
+
radial-gradient(ellipse 78% 46% at 50% 0%, rgba(232, 193, 90, 0.07), transparent 60%) !important;
|
|
40027
|
+
background-size: 9px 9px, 100% 100% !important;
|
|
40028
|
+
background-repeat: repeat, no-repeat !important;
|
|
40029
|
+
opacity: 1 !important;
|
|
40030
|
+
}
|
|
40031
|
+
.vr-vcard:not(.is-current) { filter: none !important; opacity: 0.92; }
|
|
40032
|
+
.vr-vcard.is-current {
|
|
40033
|
+
border-color: var(--vr-gold) !important;
|
|
40034
|
+
border-left: 3px solid var(--vr-gold) !important;
|
|
40035
|
+
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.6), 0 0 22px rgba(232, 193, 90, 0.24), inset 0 0 0 1px rgba(232, 193, 90, 0.2) !important;
|
|
40036
|
+
}
|
|
40037
|
+
.vr-vcard-top b {
|
|
40038
|
+
font-family: var(--mg-display) !important;
|
|
40039
|
+
font-size: 26px !important;
|
|
40040
|
+
font-weight: 400 !important;
|
|
40041
|
+
color: var(--vr-gold-bright) !important;
|
|
40042
|
+
letter-spacing: 0.02em !important;
|
|
40043
|
+
}
|
|
40044
|
+
.vr-vcard.is-mini .vr-vcard-top b { font-size: 22px !important; }
|
|
40045
|
+
.vr-vcard-branch { color: var(--vr-muted) !important; }
|
|
40046
|
+
/* four gold corner ticks like the provider cards */
|
|
40047
|
+
.vr-vcard .vr-vcard-foot::after {
|
|
40048
|
+
content: '';
|
|
40049
|
+
position: absolute;
|
|
40050
|
+
left: 8px; bottom: 8px; right: 8px;
|
|
40051
|
+
height: 1px;
|
|
40052
|
+
background: linear-gradient(90deg, var(--vr-gold), transparent 70%);
|
|
40053
|
+
opacity: 0.5;
|
|
40054
|
+
}
|
|
40055
|
+
|
|
40056
|
+
/* ==========================================================================
|
|
40057
|
+
WELCOME FLIP-CARD BACK \u2014 flat manga halftone (was a gold spiral). Ink plate,
|
|
40058
|
+
gold halftone screentone, a soft gold top-glow, the fierce raven mark, gold
|
|
40059
|
+
FLIP label. Reads as a face-down manga card, not a casino spiral.
|
|
40060
|
+
========================================================================== */
|
|
40061
|
+
.vr-qs-back,
|
|
40062
|
+
.vr-tcard.is-back:not(.has-art) {
|
|
40063
|
+
border: 1.5px solid var(--vr-border-strong) !important;
|
|
40064
|
+
border-radius: 5px !important;
|
|
40065
|
+
background:
|
|
40066
|
+
radial-gradient(rgba(232, 193, 90, 0.06) 1px, transparent 1.4px) 0 0 / 9px 9px,
|
|
40067
|
+
radial-gradient(ellipse 72% 52% at 50% 40%, rgba(232, 193, 90, 0.08), transparent 62%),
|
|
40068
|
+
#0a0a0d !important;
|
|
40069
|
+
}
|
|
40070
|
+
.vr-qs-back::after,
|
|
40071
|
+
.vr-tcard.is-back:not(.has-art)::after {
|
|
40072
|
+
content: '';
|
|
40073
|
+
position: absolute;
|
|
40074
|
+
inset: 5px;
|
|
40075
|
+
border: 1px solid rgba(232, 193, 90, 0.22);
|
|
40076
|
+
border-radius: 3px;
|
|
40077
|
+
pointer-events: none;
|
|
40078
|
+
}
|
|
40079
|
+
.vr-qs-back img,
|
|
40080
|
+
.vr-tcard.is-back:not(.has-art) .vr-tcard-backart img {
|
|
40081
|
+
width: 62px !important;
|
|
40082
|
+
height: 62px !important;
|
|
40083
|
+
opacity: 0.96 !important;
|
|
40084
|
+
filter: drop-shadow(0 0 10px rgba(232, 193, 90, 0.22));
|
|
40085
|
+
}
|
|
40086
|
+
.vr-qs-back b,
|
|
40087
|
+
.vr-tcard.is-back:not(.has-art) .vr-tcard-backname {
|
|
40088
|
+
color: var(--vr-gold-bright) !important;
|
|
40089
|
+
font-family: var(--vr-hud-mono) !important;
|
|
40090
|
+
letter-spacing: 0.16em !important;
|
|
40091
|
+
}
|
|
40092
|
+
|
|
40093
|
+
/* Region map: keep the grade medallion in the top-right corner like the binder,
|
|
40094
|
+
just scaled down to fit the small map cards so it stays tucked in the corner
|
|
40095
|
+
instead of covering the provider name. */
|
|
40096
|
+
.vr-studio-architecture.is-region-map .vr-arch-node.is-card .vr-tcard-hp.is-onart {
|
|
40097
|
+
top: 5px;
|
|
40098
|
+
right: 5px;
|
|
40099
|
+
bottom: auto;
|
|
40100
|
+
transform: none;
|
|
40101
|
+
width: 16px;
|
|
40102
|
+
height: 16px;
|
|
40103
|
+
}
|
|
40104
|
+
.vr-studio-architecture.is-region-map .vr-arch-node.is-card .vr-tcard-hp.is-onart i {
|
|
40105
|
+
font-size: 9px;
|
|
40106
|
+
}
|
|
40107
|
+
`;
|
|
40108
|
+
}
|
|
40109
|
+
});
|
|
40110
|
+
|
|
40111
|
+
// src/local-ui/static/appHtml.ts
|
|
40112
|
+
function escapeJsonForHtml(value) {
|
|
40113
|
+
return JSON.stringify(value).replace(/</g, "\\u003c");
|
|
40114
|
+
}
|
|
40115
|
+
function renderLocalUiHtml(state) {
|
|
40116
|
+
return `<!doctype html>
|
|
40117
|
+
<html lang="en">
|
|
40118
|
+
<head>
|
|
40119
|
+
<meta charset="utf-8" />
|
|
40120
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
40121
|
+
<meta name="theme-color" content="#0b0b0d" />
|
|
40122
|
+
<title>VibeRaven</title>
|
|
40123
|
+
<link rel="icon" type="image/png" href="/manga/favicon.png?v=manga1" />
|
|
40124
|
+
<link rel="shortcut icon" type="image/png" href="/manga/favicon.png?v=manga1" />
|
|
40125
|
+
<link rel="apple-touch-icon" href="/manga/favicon-180.png?v=manga1" />
|
|
40126
|
+
<link rel="preload" as="image" href="/report/assets/viberaven-mascot.png?v=raven-cards-2" />
|
|
40127
|
+
<style>${localUiCss}</style>
|
|
40128
|
+
</head>
|
|
40129
|
+
<body>
|
|
40130
|
+
<div id="vr-app" class="vr-app" aria-label="VibeRaven"></div>
|
|
40131
|
+
<script id="vr-state" type="application/json">${escapeJsonForHtml(state)}</script>
|
|
40132
|
+
<script src="/vendor/anime.umd.min.js"></script>
|
|
40133
|
+
<script>${localUiClientJs}</script>
|
|
40134
|
+
</body>
|
|
40135
|
+
</html>`;
|
|
40136
|
+
}
|
|
40137
|
+
var init_appHtml = __esm({
|
|
40138
|
+
"src/local-ui/static/appHtml.ts"() {
|
|
40139
|
+
"use strict";
|
|
40140
|
+
init_appClient();
|
|
40141
|
+
init_appCss();
|
|
40142
|
+
}
|
|
40143
|
+
});
|
|
40144
|
+
|
|
40145
|
+
// src/local-ui/server.ts
|
|
40146
|
+
function normalizeShellCommand(value) {
|
|
40147
|
+
return value.trim().replace(/\s+/g, " ");
|
|
40148
|
+
}
|
|
40149
|
+
function resolveApprovedShellCommand(command, requestedCliId) {
|
|
40150
|
+
const normalized = normalizeShellCommand(command);
|
|
40151
|
+
const candidateIds = requestedCliId ? [requestedCliId] : ["codex", "claude", "gemini"];
|
|
40152
|
+
for (const cliId of candidateIds) {
|
|
40153
|
+
const setup = CLI_AGENT_SETUP[cliId];
|
|
40154
|
+
const install = normalizeShellCommand(setup.installCommand);
|
|
40155
|
+
if (normalized === install) {
|
|
40156
|
+
return { cliId, step: "install", command: setup.installCommand };
|
|
40157
|
+
}
|
|
40158
|
+
const signIn = normalizeShellCommand(setup.signInCommand);
|
|
40159
|
+
if (normalized === signIn) {
|
|
40160
|
+
return { cliId, step: "sign-in", command: setup.signInCommand };
|
|
40161
|
+
}
|
|
40162
|
+
}
|
|
40163
|
+
return null;
|
|
40164
|
+
}
|
|
40165
|
+
async function connectProviderMcp(cwd, providerId) {
|
|
40166
|
+
const recipe = MCP_SERVER_RECIPES[providerId];
|
|
40167
|
+
if (!recipe) {
|
|
40168
|
+
return { ok: false, message: `No known MCP server for ${providerId} yet. Add one manually to .mcp.json.` };
|
|
40169
|
+
}
|
|
40170
|
+
const configPath = (0, import_node_path30.join)(cwd, ".mcp.json");
|
|
40171
|
+
let config = {};
|
|
40172
|
+
try {
|
|
40173
|
+
const raw = await (0, import_promises23.readFile)(configPath, "utf8");
|
|
40174
|
+
const parsed = JSON.parse(raw.replace(/^\uFEFF/, ""));
|
|
40175
|
+
if (isRecord4(parsed)) config = parsed;
|
|
40176
|
+
} catch {
|
|
40177
|
+
}
|
|
40178
|
+
const servers = isRecord4(config.mcpServers) ? { ...config.mcpServers } : {};
|
|
40179
|
+
if (servers[providerId]) {
|
|
40180
|
+
return { ok: true, message: `${providerId} MCP server already configured in .mcp.json.`, path: ".mcp.json" };
|
|
40181
|
+
}
|
|
40182
|
+
servers[providerId] = recipe.entry;
|
|
40183
|
+
const next = { ...config, mcpServers: servers };
|
|
40184
|
+
await (0, import_promises23.writeFile)(configPath, `${JSON.stringify(next, null, 2)}
|
|
40185
|
+
`, "utf8");
|
|
40186
|
+
const suffix = recipe.note ? ` ${recipe.note}` : "";
|
|
40187
|
+
return { ok: true, message: `Added ${providerId} MCP server to .mcp.json.${suffix}`, path: ".mcp.json" };
|
|
40188
|
+
}
|
|
40189
|
+
async function defaultScanRunner(flags, positional) {
|
|
40190
|
+
const cli = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
40191
|
+
return cli.runScanCommand(flags, positional);
|
|
40192
|
+
}
|
|
40193
|
+
async function readPackageJson(cwd) {
|
|
40194
|
+
try {
|
|
40195
|
+
const raw = await (0, import_promises23.readFile)((0, import_node_path30.join)(cwd, "package.json"), "utf8");
|
|
40196
|
+
const parsed = JSON.parse(raw.replace(/^\uFEFF/, ""));
|
|
40197
|
+
return isRecord4(parsed) ? parsed : {};
|
|
40198
|
+
} catch {
|
|
40199
|
+
return {};
|
|
40200
|
+
}
|
|
40201
|
+
}
|
|
40202
|
+
function dependencyNames(packageJson) {
|
|
40203
|
+
const names = /* @__PURE__ */ new Set();
|
|
40204
|
+
for (const key of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
|
|
40205
|
+
const value = packageJson[key];
|
|
40206
|
+
if (!isRecord4(value)) continue;
|
|
40207
|
+
Object.keys(value).forEach((name) => names.add(name.toLowerCase()));
|
|
40208
|
+
}
|
|
40209
|
+
return names;
|
|
40210
|
+
}
|
|
40211
|
+
async function listProjectFiles(cwd, maxFiles = 1800) {
|
|
40212
|
+
const skipped = /* @__PURE__ */ new Set([".git", "node_modules", ".next", "dist", "build", "coverage", ".turbo", ".viberaven"]);
|
|
40213
|
+
const files = [];
|
|
40214
|
+
async function walk(dir, prefix = "") {
|
|
40215
|
+
if (files.length >= maxFiles) return;
|
|
40216
|
+
let entries;
|
|
40217
|
+
try {
|
|
40218
|
+
entries = await (0, import_promises23.readdir)(dir, { withFileTypes: true });
|
|
37686
40219
|
} catch {
|
|
37687
40220
|
return;
|
|
37688
40221
|
}
|
|
@@ -38316,13 +40849,13 @@ function parseAgentChatRequest(value) {
|
|
|
38316
40849
|
function taskKindExecutionBlock(taskKind) {
|
|
38317
40850
|
switch (taskKind) {
|
|
38318
40851
|
case "analyze":
|
|
38319
|
-
return "Execution mode: analyze launch readiness.
|
|
40852
|
+
return "Execution mode: analyze launch readiness. Inspect the real application code \u2014 auth, protected routes, middleware, database/RLS, migrations, webhooks, and env usage. Return a short prose summary plus up to 3 concrete blockers, each with the real code file path. Do not read, grep, or cite the .viberaven/ folder; those are stale internal artifacts.";
|
|
38320
40853
|
case "plan":
|
|
38321
40854
|
return "Execution mode: build an ordered fix plan from repo evidence. If the top blocker is repo-code, apply that fix in the project before answering. Do not reply with only manual instructions when code edits are possible.";
|
|
38322
40855
|
case "fix":
|
|
38323
40856
|
return "Execution mode: apply one minimal scoped repo fix IN CODE NOW. Read existing files, edit the project, save changes, then summarize. Forbidden: telling the user what to do manually when you can patch the repo yourself.";
|
|
38324
40857
|
case "verify":
|
|
38325
|
-
return "Execution mode: verify launch readiness
|
|
40858
|
+
return "Execution mode: verify launch readiness against the real code. Re-check the specific files you changed and run the project tests or build when available. Do not rely on .viberaven/ scan artifacts.";
|
|
38326
40859
|
case "provider":
|
|
38327
40860
|
return "Execution mode: provider proof or connect mission. Edit repo wiring when missing; separate dashboard-only steps from code changes; never claim live connection without proof.";
|
|
38328
40861
|
case "diff":
|
|
@@ -38347,9 +40880,18 @@ function missionCardsContextBlock(state) {
|
|
|
38347
40880
|
});
|
|
38348
40881
|
return lines.length > 1 ? lines.join("\n") : void 0;
|
|
38349
40882
|
}
|
|
40883
|
+
async function hasPriorReleases(cwd) {
|
|
40884
|
+
try {
|
|
40885
|
+
const tags = await runGit(cwd, ["tag", "--list"]);
|
|
40886
|
+
return Boolean(tags.trim());
|
|
40887
|
+
} catch {
|
|
40888
|
+
return false;
|
|
40889
|
+
}
|
|
40890
|
+
}
|
|
38350
40891
|
async function buildAgentChatPrompt(request, cwd) {
|
|
38351
40892
|
const state = await readState(cwd);
|
|
38352
40893
|
const executionBlock = taskKindExecutionBlock(request.taskKind);
|
|
40894
|
+
const priorReleases = await hasPriorReleases(cwd);
|
|
38353
40895
|
const cardsBlock = missionCardsContextBlock(state);
|
|
38354
40896
|
const providerState2 = request.provider?.id ? state.providers.find((provider2) => provider2.id === request.provider?.id) : state.providers.find((provider2) => provider2.name === request.provider?.name);
|
|
38355
40897
|
const mcp = providerState2?.mcp;
|
|
@@ -38367,6 +40909,7 @@ async function buildAgentChatPrompt(request, cwd) {
|
|
|
38367
40909
|
releaseDiffBlock,
|
|
38368
40910
|
state.gate?.label ? `Project status: ${state.gate.label} (${state.gate.status ?? "unknown"})` : void 0,
|
|
38369
40911
|
state.missionControl?.mainBlocker ? `Main blocker: ${state.missionControl.mainBlocker}` : void 0,
|
|
40912
|
+
priorReleases ? "Deployment state: this project already has release tags, so it may already be in production. When asked about production readiness, prioritize what changed since the last release and the risk in the NEXT change over first-launch blockers." : void 0,
|
|
38370
40913
|
executionBlock,
|
|
38371
40914
|
cardsBlock,
|
|
38372
40915
|
"",
|
|
@@ -38378,9 +40921,11 @@ async function buildAgentChatPrompt(request, cwd) {
|
|
|
38378
40921
|
"- Return only the final user-facing answer. Do not echo this prompt, session metadata, logs, or command transcripts.",
|
|
38379
40922
|
"- For fix/plan/provider repo gaps: edit files in this project before answering. Manual dashboard steps are only for gaps that cannot be solved in repo code.",
|
|
38380
40923
|
"- Never paste long VibeRaven operator manuals, heal loops, or PowerShell command blocks unless the user explicitly asked how to run verify.",
|
|
40924
|
+
"- Do not read, grep, cite, or paste the contents of the .viberaven/ folder. Those are stale internal scan artifacts, not source of truth. Reason from the real application code (auth, routes, middleware, migrations, webhooks, env usage).",
|
|
40925
|
+
"- Keep the whole answer under ~15 lines. Never paste file contents, grep output, JSON, or command transcripts; summarize in prose and short bullets.",
|
|
38381
40926
|
"",
|
|
38382
40927
|
"Response format (markdown):",
|
|
38383
|
-
"1. **Findings** \u2014 bullets
|
|
40928
|
+
"1. **Findings** \u2014 up to 3 bullets, each naming the real code file and the risk",
|
|
38384
40929
|
"2. **Changes made** \u2014 what you edited, or say none only if the blocker is dashboard-only",
|
|
38385
40930
|
'3. **Files touched** \u2014 list paths (or "none")',
|
|
38386
40931
|
"4. **Next step** \u2014 one verify action or one dashboard action (do not paste raw npx commands; the UI renders Verify buttons)",
|
|
@@ -38786,7 +41331,7 @@ async function sendReportArtifact(cwd, response) {
|
|
|
38786
41331
|
<body>
|
|
38787
41332
|
<main>
|
|
38788
41333
|
<div class="brand">
|
|
38789
|
-
<img src="/report/assets/viberaven-
|
|
41334
|
+
<img src="/report/assets/viberaven-mascot.png" alt="" />
|
|
38790
41335
|
<div>
|
|
38791
41336
|
<h1>Report preview is ready</h1>
|
|
38792
41337
|
<p>${projectName} does not have a generated report artifact yet. The launch screen still gives you the provider map, agent handoff, and verification preview.</p>
|
|
@@ -38815,6 +41360,30 @@ async function sendExtensionIcon(cwd, response) {
|
|
|
38815
41360
|
sendText(response, 404, "Icon not found");
|
|
38816
41361
|
}
|
|
38817
41362
|
}
|
|
41363
|
+
async function sendMangaAsset(pathname, response) {
|
|
41364
|
+
const name = decodeURIComponent(pathname.replace(/^\/manga\//, ""));
|
|
41365
|
+
if (name.includes("..") || !/^(cards\/)?[a-z0-9._-]+\.(png|webp|svg|jpg|jpeg)$/i.test(name)) {
|
|
41366
|
+
sendText(response, 404, "Asset not found");
|
|
41367
|
+
return;
|
|
41368
|
+
}
|
|
41369
|
+
const candidates = [
|
|
41370
|
+
(0, import_node_path30.join)(__dirname, "manga", name),
|
|
41371
|
+
// installed + dev: <pkg>/dist/manga
|
|
41372
|
+
(0, import_node_path30.join)(__dirname, "..", "assets", "manga", name),
|
|
41373
|
+
// fallback: <pkg>/assets/manga (source)
|
|
41374
|
+
(0, import_node_path30.join)(__dirname, "..", "..", "assets", "manga", name)
|
|
41375
|
+
];
|
|
41376
|
+
for (const candidate of candidates) {
|
|
41377
|
+
try {
|
|
41378
|
+
const body = await (0, import_promises23.readFile)(candidate);
|
|
41379
|
+
response.setHeader("cache-control", "no-cache");
|
|
41380
|
+
sendBinary(response, 200, contentTypeForAsset(candidate), body);
|
|
41381
|
+
return;
|
|
41382
|
+
} catch {
|
|
41383
|
+
}
|
|
41384
|
+
}
|
|
41385
|
+
sendText(response, 404, "Asset not found");
|
|
41386
|
+
}
|
|
38818
41387
|
function contentTypeForAsset(pathname) {
|
|
38819
41388
|
switch ((0, import_node_path30.extname)(pathname).toLowerCase()) {
|
|
38820
41389
|
case ".svg":
|
|
@@ -38866,7 +41435,12 @@ async function handleRequest(request, response, options) {
|
|
|
38866
41435
|
}
|
|
38867
41436
|
if (request.method === "GET" && url.pathname === "/") {
|
|
38868
41437
|
const state = await readState(options.cwd);
|
|
38869
|
-
response.writeHead(200, {
|
|
41438
|
+
response.writeHead(200, {
|
|
41439
|
+
"content-type": "text/html; charset=utf-8",
|
|
41440
|
+
"cache-control": "no-store, no-cache, must-revalidate",
|
|
41441
|
+
pragma: "no-cache",
|
|
41442
|
+
expires: "0"
|
|
41443
|
+
});
|
|
38870
41444
|
response.end(renderLocalUiHtml(state));
|
|
38871
41445
|
return;
|
|
38872
41446
|
}
|
|
@@ -39199,6 +41773,27 @@ async function handleRequest(request, response, options) {
|
|
|
39199
41773
|
await sendBundledReportAsset(url.pathname, response);
|
|
39200
41774
|
return;
|
|
39201
41775
|
}
|
|
41776
|
+
if (request.method === "GET" && url.pathname.startsWith("/manga/")) {
|
|
41777
|
+
await sendMangaAsset(url.pathname, response);
|
|
41778
|
+
return;
|
|
41779
|
+
}
|
|
41780
|
+
if (request.method === "GET" && url.pathname === "/vendor/anime.umd.min.js") {
|
|
41781
|
+
for (const candidate of [
|
|
41782
|
+
(0, import_node_path30.join)(__dirname, "vendor", "anime.umd.min.js"),
|
|
41783
|
+
(0, import_node_path30.join)(__dirname, "..", "assets", "vendor", "anime.umd.min.js"),
|
|
41784
|
+
(0, import_node_path30.join)(__dirname, "..", "..", "assets", "vendor", "anime.umd.min.js")
|
|
41785
|
+
]) {
|
|
41786
|
+
try {
|
|
41787
|
+
const body = await (0, import_promises23.readFile)(candidate);
|
|
41788
|
+
response.setHeader("cache-control", "public, max-age=604800, immutable");
|
|
41789
|
+
sendBinary(response, 200, "text/javascript; charset=utf-8", body);
|
|
41790
|
+
return;
|
|
41791
|
+
} catch {
|
|
41792
|
+
}
|
|
41793
|
+
}
|
|
41794
|
+
sendText(response, 404, "Asset not found");
|
|
41795
|
+
return;
|
|
41796
|
+
}
|
|
39202
41797
|
if (request.method === "POST" && url.pathname === "/api/scan") {
|
|
39203
41798
|
await options.scanRunner({ "agent-mode": true }, [options.cwd]);
|
|
39204
41799
|
sendJson(response, await readState(options.cwd));
|