@oddessentials/agent-guild 0.7.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +6 -2
  2. package/package.json +1 -1
  3. package/web/app.js +69 -17
  4. package/web/index.html +13 -3
  5. package/web/skins/guild/skin.css +502 -0
  6. package/web/skins/orbital/characters/anthropic/idle.avif +0 -0
  7. package/web/skins/orbital/characters/anthropic/idle.webp +0 -0
  8. package/web/skins/orbital/characters/anthropic/locked.avif +0 -0
  9. package/web/skins/orbital/characters/anthropic/locked.webp +0 -0
  10. package/web/skins/orbital/characters/anthropic/working.avif +0 -0
  11. package/web/skins/orbital/characters/anthropic/working.webp +0 -0
  12. package/web/skins/orbital/characters/google/idle.avif +0 -0
  13. package/web/skins/orbital/characters/google/idle.webp +0 -0
  14. package/web/skins/orbital/characters/google/locked.avif +0 -0
  15. package/web/skins/orbital/characters/google/locked.webp +0 -0
  16. package/web/skins/orbital/characters/google/working.avif +0 -0
  17. package/web/skins/orbital/characters/google/working.webp +0 -0
  18. package/web/skins/orbital/characters/openai/idle.avif +0 -0
  19. package/web/skins/orbital/characters/openai/idle.webp +0 -0
  20. package/web/skins/orbital/characters/openai/locked.avif +0 -0
  21. package/web/skins/orbital/characters/openai/locked.webp +0 -0
  22. package/web/skins/orbital/characters/openai/working.avif +0 -0
  23. package/web/skins/orbital/characters/openai/working.webp +0 -0
  24. package/web/skins/orbital/characters/shell/idle.avif +0 -0
  25. package/web/skins/orbital/characters/shell/idle.webp +0 -0
  26. package/web/skins/orbital/characters/shell/locked.avif +0 -0
  27. package/web/skins/orbital/characters/shell/locked.webp +0 -0
  28. package/web/skins/orbital/characters/shell/working.avif +0 -0
  29. package/web/skins/orbital/characters/shell/working.webp +0 -0
  30. package/web/skins/orbital/characters/xai/idle.avif +0 -0
  31. package/web/skins/orbital/characters/xai/idle.webp +0 -0
  32. package/web/skins/orbital/characters/xai/locked.avif +0 -0
  33. package/web/skins/orbital/characters/xai/locked.webp +0 -0
  34. package/web/skins/orbital/characters/xai/working.avif +0 -0
  35. package/web/skins/orbital/characters/xai/working.webp +0 -0
  36. package/web/skins/orbital/familiars/aether.png +0 -0
  37. package/web/skins/orbital/familiars/flame.png +0 -0
  38. package/web/skins/orbital/familiars/leaf.png +0 -0
  39. package/web/skins/orbital/familiars/night.png +0 -0
  40. package/web/skins/orbital/fonts/OFL.txt +93 -0
  41. package/web/skins/orbital/fonts/exo2.woff2 +0 -0
  42. package/web/skins/orbital/icons/anthropic.avif +0 -0
  43. package/web/skins/orbital/icons/anthropic.webp +0 -0
  44. package/web/skins/orbital/icons/google.avif +0 -0
  45. package/web/skins/orbital/icons/google.webp +0 -0
  46. package/web/skins/orbital/icons/openai.avif +0 -0
  47. package/web/skins/orbital/icons/openai.webp +0 -0
  48. package/web/skins/orbital/icons/shell.avif +0 -0
  49. package/web/skins/orbital/icons/shell.webp +0 -0
  50. package/web/skins/orbital/icons/xai.avif +0 -0
  51. package/web/skins/orbital/icons/xai.webp +0 -0
  52. package/web/skins/orbital/page-light.avif +0 -0
  53. package/web/skins/orbital/page-light.webp +0 -0
  54. package/web/skins/orbital/page.avif +0 -0
  55. package/web/skins/orbital/page.webp +0 -0
  56. package/web/skins/orbital/skin.css +393 -0
  57. package/web/skins/orbital/ui/empty-state.avif +0 -0
  58. package/web/skins/orbital/ui/empty-state.webp +0 -0
  59. package/web/skins/orbital/ui/level.svg +1 -0
  60. package/web/skins/orbital/ui/lock.svg +1 -0
  61. package/web/skins/orbital/ui/plasma.svg +1 -0
  62. package/web/skins/orbital/ui/power.svg +1 -0
  63. package/web/skins/professional/banners/anthropic/idle.svg +1 -0
  64. package/web/skins/professional/banners/anthropic/locked.svg +1 -0
  65. package/web/skins/professional/banners/anthropic/working.svg +1 -0
  66. package/web/skins/professional/banners/google/idle.svg +1 -0
  67. package/web/skins/professional/banners/google/locked.svg +1 -0
  68. package/web/skins/professional/banners/google/working.svg +1 -0
  69. package/web/skins/professional/banners/openai/idle.svg +1 -0
  70. package/web/skins/professional/banners/openai/locked.svg +1 -0
  71. package/web/skins/professional/banners/openai/working.svg +1 -0
  72. package/web/skins/professional/banners/shell/idle.svg +1 -0
  73. package/web/skins/professional/banners/shell/locked.svg +1 -0
  74. package/web/skins/professional/banners/shell/working.svg +1 -0
  75. package/web/skins/professional/banners/xai/idle.svg +1 -0
  76. package/web/skins/professional/banners/xai/locked.svg +1 -0
  77. package/web/skins/professional/banners/xai/working.svg +1 -0
  78. package/web/skins/professional/icons/anthropic.svg +1 -0
  79. package/web/skins/professional/icons/google.svg +1 -0
  80. package/web/skins/professional/icons/openai.svg +1 -0
  81. package/web/skins/professional/icons/shell.svg +1 -0
  82. package/web/skins/professional/icons/xai.svg +1 -0
  83. package/web/skins/professional/page-light.svg +1 -0
  84. package/web/skins/professional/page.svg +1 -0
  85. package/web/skins/professional/skin.css +253 -0
  86. package/web/skins/professional/ui/empty-state-light.svg +1 -0
  87. package/web/skins/professional/ui/empty-state.svg +1 -0
  88. package/web/skins/professional/ui/lock.svg +1 -0
  89. package/web/styles.css +43 -44
  90. package/web/theme.js +19 -3
  91. package/web/art/art.css +0 -467
  92. /package/web/{art/ui/guild-crest.png → brand/crest.png} +0 -0
  93. /package/web/{art/ui → brand}/favicon.png +0 -0
  94. /package/web/{art → skins/guild}/characters/anthropic/idle.avif +0 -0
  95. /package/web/{art → skins/guild}/characters/anthropic/idle.webp +0 -0
  96. /package/web/{art → skins/guild}/characters/anthropic/locked.avif +0 -0
  97. /package/web/{art → skins/guild}/characters/anthropic/locked.webp +0 -0
  98. /package/web/{art → skins/guild}/characters/anthropic/working.avif +0 -0
  99. /package/web/{art → skins/guild}/characters/anthropic/working.webp +0 -0
  100. /package/web/{art → skins/guild}/characters/google/idle.avif +0 -0
  101. /package/web/{art → skins/guild}/characters/google/idle.webp +0 -0
  102. /package/web/{art → skins/guild}/characters/google/locked.avif +0 -0
  103. /package/web/{art → skins/guild}/characters/google/locked.webp +0 -0
  104. /package/web/{art → skins/guild}/characters/google/working.avif +0 -0
  105. /package/web/{art → skins/guild}/characters/google/working.webp +0 -0
  106. /package/web/{art → skins/guild}/characters/openai/idle.avif +0 -0
  107. /package/web/{art → skins/guild}/characters/openai/idle.webp +0 -0
  108. /package/web/{art → skins/guild}/characters/openai/locked.avif +0 -0
  109. /package/web/{art → skins/guild}/characters/openai/locked.webp +0 -0
  110. /package/web/{art → skins/guild}/characters/openai/working.avif +0 -0
  111. /package/web/{art → skins/guild}/characters/openai/working.webp +0 -0
  112. /package/web/{art → skins/guild}/characters/shell/idle.avif +0 -0
  113. /package/web/{art → skins/guild}/characters/shell/idle.webp +0 -0
  114. /package/web/{art → skins/guild}/characters/shell/locked.avif +0 -0
  115. /package/web/{art → skins/guild}/characters/shell/locked.webp +0 -0
  116. /package/web/{art → skins/guild}/characters/shell/working.avif +0 -0
  117. /package/web/{art → skins/guild}/characters/shell/working.webp +0 -0
  118. /package/web/{art → skins/guild}/characters/xai/idle.avif +0 -0
  119. /package/web/{art → skins/guild}/characters/xai/idle.webp +0 -0
  120. /package/web/{art → skins/guild}/characters/xai/locked.avif +0 -0
  121. /package/web/{art → skins/guild}/characters/xai/locked.webp +0 -0
  122. /package/web/{art → skins/guild}/characters/xai/working.avif +0 -0
  123. /package/web/{art → skins/guild}/characters/xai/working.webp +0 -0
  124. /package/web/{art → skins/guild}/familiars/aether.png +0 -0
  125. /package/web/{art → skins/guild}/familiars/flame.png +0 -0
  126. /package/web/{art → skins/guild}/familiars/leaf.png +0 -0
  127. /package/web/{art → skins/guild}/familiars/night.png +0 -0
  128. /package/web/{art → skins/guild}/icons/anthropic.avif +0 -0
  129. /package/web/{art → skins/guild}/icons/anthropic.webp +0 -0
  130. /package/web/{art → skins/guild}/icons/google.avif +0 -0
  131. /package/web/{art → skins/guild}/icons/google.webp +0 -0
  132. /package/web/{art → skins/guild}/icons/openai.avif +0 -0
  133. /package/web/{art → skins/guild}/icons/openai.webp +0 -0
  134. /package/web/{art → skins/guild}/icons/shell.avif +0 -0
  135. /package/web/{art → skins/guild}/icons/shell.webp +0 -0
  136. /package/web/{art → skins/guild}/icons/xai.avif +0 -0
  137. /package/web/{art → skins/guild}/icons/xai.webp +0 -0
  138. /package/web/{art → skins/guild}/page-light.avif +0 -0
  139. /package/web/{art → skins/guild}/page-light.webp +0 -0
  140. /package/web/{art → skins/guild}/page.avif +0 -0
  141. /package/web/{art → skins/guild}/page.webp +0 -0
  142. /package/web/{art → skins/guild}/ui/empty-state.avif +0 -0
  143. /package/web/{art → skins/guild}/ui/empty-state.webp +0 -0
  144. /package/web/{art → skins/guild}/ui/frame-ornate.png +0 -0
  145. /package/web/{art → skins/guild}/ui/frame.png +0 -0
  146. /package/web/{art → skins/guild}/ui/gem-mana.png +0 -0
  147. /package/web/{art → skins/guild}/ui/gem-vitality.png +0 -0
  148. /package/web/{art → skins/guild}/ui/level-medallion.png +0 -0
  149. /package/web/{art → skins/guild}/ui/padlock.png +0 -0
package/web/styles.css CHANGED
@@ -12,29 +12,13 @@
12
12
  line-gap-override: 0%;
13
13
  }
14
14
 
15
+ /* Skin-independent tokens. Colours, surfaces, radius and the display font come from
16
+ the active skin (web/skins/<id>/skin.css), so they are not declared here; the logo treatment, terminal and icons below never change with a skin. */
15
17
  :root {
16
- --bg: #f3eee3;
17
- --surface: #fffcf6;
18
- --surface-2: #f5eedf;
19
- --border: #e3d7bd;
20
- --text: #221b12;
21
- --muted: #6b5c45;
22
- --heading: #2c2216;
23
- --accent: #5a3fc0;
24
- --accent-fill: #5a3fc0;
25
- --accent-text: #ffffff;
26
- --danger: #a8302b;
27
- --ok: #1d6e40;
28
- --warn: #8a5300;
29
- --gold: #b8892f;
30
- --gold-ink: #7a5715;
31
- --focus: #5a3fc0;
32
18
  --wordmark: linear-gradient(180deg, #a77a26 0%, #7a5715 55%, #563c0b 100%);
33
- --shadow: 0 1px 2px rgba(70, 48, 12, 0.08), 0 4px 14px rgba(70, 48, 12, 0.08);
34
19
  --term-bg: #0f1115;
35
- --radius: 6px;
36
20
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
37
- --font-display: "Cinzel", "Cinzel Fallback", "Palatino Linotype", Palatino, Georgia, serif;
21
+ --font-brand: "Cinzel", "Cinzel Fallback", "Palatino Linotype", Palatino, Georgia, serif;
38
22
  --font-mono: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;
39
23
  --icon-sun: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='4.2'/%3E%3Cpath d='M12 2.5v2.2M12 19.3v2.2M2.5 12h2.2M19.3 12h2.2M5.3 5.3l1.6 1.6M17.1 17.1l1.6 1.6M5.3 18.7l1.6-1.6M17.1 6.9l1.6-1.6'/%3E%3C/svg%3E");
40
24
  --icon-moon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'%3E%3Cpath d='M19.5 14.6A8 8 0 0 1 9.4 4.5a8 8 0 1 0 10.1 10.1z'/%3E%3C/svg%3E");
@@ -48,25 +32,9 @@
48
32
  scrollbar-color: color-mix(in srgb, var(--muted) 45%, transparent) transparent;
49
33
  }
50
34
 
51
- /* theme.js sets data-theme from the saved choice or the system setting before the first paint. */
35
+ /* theme.js sets data-theme and data-skin from the saved choice or the system setting before the first paint. */
52
36
  :root[data-theme="dark"] {
53
- --bg: #0f1115;
54
- --surface: #171a21;
55
- --surface-2: #1e222b;
56
- --border: #2a303b;
57
- --text: #e6e9ef;
58
- --muted: #9aa4b2;
59
- --heading: #f1e2c2;
60
- --accent: #ac9ff7;
61
- --accent-fill: #5b40d0;
62
- --danger: #ef6b66;
63
- --ok: #4cc38a;
64
- --warn: #e0a84a;
65
- --gold: #e8c47c;
66
- --gold-ink: #e8c47c;
67
- --focus: #e8c47c;
68
37
  --wordmark: linear-gradient(180deg, #fbe9bd 0%, #e2b867 55%, #a97b35 100%);
69
- --shadow: none;
70
38
  color-scheme: dark;
71
39
  }
72
40
 
@@ -75,7 +43,7 @@ body { margin: 0; background: var(--bg); color: var(--text); min-height: 100vh;
75
43
  ::selection { background: color-mix(in srgb, var(--accent) 32%, transparent); }
76
44
  h1, h2 { margin: 0; font-family: var(--font-display); color: var(--heading); }
77
45
  h1 {
78
- font-size: 1.32rem; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap;
46
+ font-family: var(--font-brand); font-size: 1.32rem; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap;
79
47
  background: var(--wordmark); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
80
48
  }
81
49
  h2 { font-size: 1.02rem; font-weight: 600; letter-spacing: 0.03em; }
@@ -89,6 +57,10 @@ code, pre { font-family: var(--font-mono); }
89
57
  position: sticky; top: 0; z-index: 5;
90
58
  }
91
59
  .brand { display: flex; align-items: center; gap: 10px; }
60
+ .brand::before {
61
+ content: ""; width: 34px; height: 34px; flex: none;
62
+ background: url("/brand/crest.png") center / contain no-repeat;
63
+ }
92
64
  .version {
93
65
  position: relative; font-family: inherit; font-size: 0.72rem; font-weight: 600; padding: 1px 7px; border-radius: 999px; white-space: nowrap;
94
66
  background: var(--surface-2); color: var(--muted); border: 1px solid var(--border); font-variant-numeric: tabular-nums; cursor: pointer;
@@ -166,7 +138,7 @@ main { max-width: 1200px; margin: 0 auto; padding: 26px 16px 56px; display: grid
166
138
  font: inherit; font-size: 0.78rem; text-align: left; cursor: pointer;
167
139
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
168
140
  }
169
- .model-stats-head::after, .console-link::after, .theme-toggle::before, .model-name::before, .provider .copies summary::before {
141
+ .model-stats-head::after, .console-link::after, .appearance::after, .model-name::before, .provider .copies summary::before {
170
142
  content: ""; display: inline-block; flex: none; width: 0.75em; height: 0.75em; margin-left: 0.3em; vertical-align: -0.05em;
171
143
  background: currentColor; mask: var(--icon-chevron) center / contain no-repeat;
172
144
  }
@@ -312,14 +284,40 @@ main { max-width: 1200px; margin: 0 auto; padding: 26px 16px 56px; display: grid
312
284
  .btn.danger { color: var(--danger); }
313
285
  .btn.danger:hover { border-color: var(--danger); }
314
286
  .btn:disabled { opacity: 0.6; cursor: progress; }
315
- .stop-manager, .restart-manager, .theme-toggle, .upgrade { white-space: nowrap; }
316
- .theme-toggle::before { width: 1em; height: 1em; margin: 0 0.4em 0 0; vertical-align: -0.15em; mask-image: var(--icon-sun); }
317
- .theme-toggle[data-next="dark"]::before { mask-image: var(--icon-moon); }
287
+ .stop-manager, .restart-manager, .appearance, .upgrade { white-space: nowrap; }
288
+ .appearance::before, .appearance-menu .choice > span::before {
289
+ content: ""; display: inline-block; width: 1em; height: 1em; margin-right: 0.4em; vertical-align: -0.15em;
290
+ background: currentColor; mask: var(--icon-sun) center / contain no-repeat;
291
+ }
292
+ :root[data-theme="dark"] .appearance::before, .appearance-menu .choice > .mode-dark::before { mask-image: var(--icon-moon); }
293
+ .appearance::after { margin-left: 0.45em; transform: rotate(90deg); transition: transform 0.15s var(--ease); }
294
+ .appearance:has(+ :popover-open)::after { transform: rotate(-90deg); }
295
+ .appearance-menu {
296
+ position: fixed; inset: auto; margin: 0; min-width: 190px; padding: 6px; display: none;
297
+ border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text);
298
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22); font-size: 0.85rem;
299
+ }
300
+ .appearance-menu:popover-open { display: grid; gap: 4px; animation: fade-in 0.12s var(--ease); }
301
+ .appearance-menu fieldset { margin: 0; padding: 0; border: 0; display: grid; }
302
+ .appearance-menu fieldset + fieldset { padding-top: 4px; border-top: 1px solid var(--border); }
303
+ .appearance-menu legend { padding: 6px 8px 4px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
304
+ .appearance-menu .choice { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: calc(var(--radius) - 2px); cursor: pointer; }
305
+ .appearance-menu .choice:hover, .appearance-menu .choice:has(:focus-visible) { background: var(--surface-2); }
306
+ .appearance-menu .choice:has(:focus-visible) { outline: 2px solid var(--focus); outline-offset: -2px; }
307
+ .appearance-menu .choice input { margin: 0; accent-color: var(--accent-fill); }
308
+ .appearance-menu .choice:has(:checked) { font-weight: 600; }
309
+ #skin-choices .choice > span::before { content: none; }
318
310
  .btn.upgrade, .btn.restart-manager.pending { color: var(--warn); border-color: var(--warn); }
319
311
  .upgrade-note { font-size: 0.85rem; color: var(--warn); }
320
312
 
321
313
  .empty { color: var(--muted); margin: 8px 0 0; }
322
314
 
315
+ body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after {
316
+ content: ""; position: fixed; left: 50%; top: 50%; width: 72px; height: 72px; margin: -36px 0 0 -36px;
317
+ background: url("/brand/crest.png") center / contain no-repeat;
318
+ animation: splash 1.4s ease-in-out infinite alternate;
319
+ }
320
+
323
321
  .auth { max-width: 560px; margin: 60px auto; padding: 24px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); display: grid; gap: 12px; }
324
322
  .auth p { margin: 0; color: var(--muted); line-height: 1.5; }
325
323
  .auth pre { margin: 0; padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius); }
@@ -604,15 +602,16 @@ a.news-link:visited { color: var(--muted); }
604
602
  @keyframes stat-fill { from { transform: scaleX(0); } }
605
603
  @keyframes toast-in { from { opacity: 0; transform: translate(-50%, 10px); } }
606
604
  @keyframes fade-in { from { opacity: 0; } }
605
+ @keyframes splash { from { opacity: 0.3; transform: scale(0.95); } to { opacity: 0.85; transform: scale(1.03); } }
607
606
  @keyframes theme-reveal {
608
607
  from { clip-path: circle(0 at var(--reveal-x) var(--reveal-y)); }
609
608
  to { clip-path: circle(var(--reveal-r) at var(--reveal-x) var(--reveal-y)); }
610
609
  }
611
610
 
612
611
  @media (prefers-reduced-motion: reduce) {
613
- .status-pill.active::before, .agent.working::after, .model-detail .stat-fill, .toast:not([hidden]), .tip:not([hidden]) { animation: none; }
614
- .model-name::before, .provider .copies summary::before, .btn, .models, .news-panel, .models::backdrop, .news-panel::backdrop { transition: none; }
615
- .github-waiting::before { animation: none; }
612
+ .status-pill.active::before, .agent.working::after, .model-detail .stat-fill, .toast:not([hidden]), .tip:not([hidden]), .appearance-menu:popover-open { animation: none; }
613
+ .model-name::before, .provider .copies summary::before, .appearance::after, .btn, .models, .news-panel, .models::backdrop, .news-panel::backdrop { transition: none; }
614
+ .github-waiting::before, body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after { animation: none; }
616
615
  .btn:active:not(:disabled) { transform: none; }
617
616
  }
618
617
 
package/web/theme.js CHANGED
@@ -1,10 +1,26 @@
1
- // Applies the chosen theme before the first paint, so the page never flashes
2
- // the other one. Loaded in <head> as a plain script; app.js owns the toggle.
1
+ // Applies the chosen skin and light or dark theme before the first paint, so
2
+ // the page never flashes another one. Loaded in <head> as a plain script;
3
+ // app.js owns the controls.
3
4
  (function () {
5
+ // The skins the page offers, in menu order; the first is the default. Each
6
+ // has a stylesheet at /skins/<id>/skin.css, linked from index.html.
7
+ var skins = [
8
+ { id: 'guild', name: 'Guild' },
9
+ { id: 'professional', name: 'Professional' },
10
+ { id: 'orbital', name: 'Orbital' },
11
+ ];
12
+ window.agentGuildSkins = skins;
13
+
4
14
  var theme = null;
5
- try { theme = localStorage.getItem('agentGuild.theme'); } catch (e) { /* storage unavailable */ }
15
+ var skin = null;
16
+ try {
17
+ theme = localStorage.getItem('agentGuild.theme');
18
+ skin = localStorage.getItem('agentGuild.skin');
19
+ } catch (e) { /* storage unavailable */ }
6
20
  if (theme !== 'light' && theme !== 'dark') {
7
21
  theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
8
22
  }
23
+ if (!skins.some(function (s) { return s.id === skin; })) skin = skins[0].id;
9
24
  document.documentElement.dataset.theme = theme;
25
+ document.documentElement.dataset.skin = skin;
10
26
  })();
package/web/art/art.css DELETED
@@ -1,467 +0,0 @@
1
- .brand::before {
2
- content: ""; width: 34px; height: 34px; flex: none;
3
- background: url("/art/ui/guild-crest.png") center / contain no-repeat;
4
- }
5
- .topbar { border-bottom: 1px solid; border-image: linear-gradient(90deg, transparent, color-mix(in srgb, var(--gold) 55%, transparent) 25%, color-mix(in srgb, var(--gold) 55%, transparent) 75%, transparent) 1; }
6
- .version { background: transparent; color: var(--gold-ink); border-color: color-mix(in srgb, var(--gold) 45%, transparent); }
7
- .version:hover { color: var(--gold-ink); border-color: var(--gold); }
8
- .version.unread::after {
9
- background: radial-gradient(circle at 35% 30%, #fff 0 14%, var(--accent) 48%, color-mix(in srgb, var(--accent) 55%, #000) 100%);
10
- box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 70%, transparent);
11
- }
12
- .connection .dot {
13
- width: 9px; height: 9px;
14
- background: radial-gradient(circle at 35% 30%, #fff 0 14%, var(--dot) 48%, color-mix(in srgb, var(--dot) 55%, #000) 100%);
15
- box-shadow: 0 0 6px color-mix(in srgb, var(--dot) 70%, transparent);
16
- }
17
- .section-head {
18
- padding-bottom: 9px; border-bottom: 1px solid;
19
- border-image: linear-gradient(90deg, var(--gold), color-mix(in srgb, var(--gold) 35%, transparent) 45%, transparent 90%) 1;
20
- }
21
-
22
- .provider, .session-card {
23
- --pc: #a67cf6;
24
- --idle: image-set(url("/art/characters/shell/idle.avif") type("image/avif"), url("/art/characters/shell/idle.webp") type("image/webp"));
25
- --working: image-set(url("/art/characters/shell/working.avif") type("image/avif"), url("/art/characters/shell/working.webp") type("image/webp"));
26
- --locked: image-set(url("/art/characters/shell/locked.avif") type("image/avif"), url("/art/characters/shell/locked.webp") type("image/webp"));
27
- }
28
- .provider[data-id="anthropic"], .session-card[data-provider="anthropic"] {
29
- --pc: #d97757;
30
- --idle: image-set(url("/art/characters/anthropic/idle.avif") type("image/avif"), url("/art/characters/anthropic/idle.webp") type("image/webp"));
31
- --working: image-set(url("/art/characters/anthropic/working.avif") type("image/avif"), url("/art/characters/anthropic/working.webp") type("image/webp"));
32
- --locked: image-set(url("/art/characters/anthropic/locked.avif") type("image/avif"), url("/art/characters/anthropic/locked.webp") type("image/webp"));
33
- }
34
- .provider[data-id="openai"], .session-card[data-provider="openai"] {
35
- --pc: #1fd08f;
36
- --idle: image-set(url("/art/characters/openai/idle.avif") type("image/avif"), url("/art/characters/openai/idle.webp") type("image/webp"));
37
- --working: image-set(url("/art/characters/openai/working.avif") type("image/avif"), url("/art/characters/openai/working.webp") type("image/webp"));
38
- --locked: image-set(url("/art/characters/openai/locked.avif") type("image/avif"), url("/art/characters/openai/locked.webp") type("image/webp"));
39
- }
40
- .provider[data-id="google"], .session-card[data-provider="google"] {
41
- --pc: #5b9cff;
42
- --idle: image-set(url("/art/characters/google/idle.avif") type("image/avif"), url("/art/characters/google/idle.webp") type("image/webp"));
43
- --working: image-set(url("/art/characters/google/working.avif") type("image/avif"), url("/art/characters/google/working.webp") type("image/webp"));
44
- --locked: image-set(url("/art/characters/google/locked.avif") type("image/avif"), url("/art/characters/google/locked.webp") type("image/webp"));
45
- }
46
- .provider[data-id="xai"], .session-card[data-provider="xai"] {
47
- --pc: #38d6e8;
48
- --idle: image-set(url("/art/characters/xai/idle.avif") type("image/avif"), url("/art/characters/xai/idle.webp") type("image/webp"));
49
- --working: image-set(url("/art/characters/xai/working.avif") type("image/avif"), url("/art/characters/xai/working.webp") type("image/webp"));
50
- --locked: image-set(url("/art/characters/xai/locked.avif") type("image/avif"), url("/art/characters/xai/locked.webp") type("image/webp"));
51
- }
52
-
53
- .provider-icon[data-provider="anthropic"] { --icon: image-set(url("/art/icons/anthropic.avif") type("image/avif"), url("/art/icons/anthropic.webp") type("image/webp")); }
54
- .provider-icon[data-provider="openai"] { --icon: image-set(url("/art/icons/openai.avif") type("image/avif"), url("/art/icons/openai.webp") type("image/webp")); }
55
- .provider-icon[data-provider="google"] { --icon: image-set(url("/art/icons/google.avif") type("image/avif"), url("/art/icons/google.webp") type("image/webp")); }
56
- .provider-icon[data-provider="xai"] { --icon: image-set(url("/art/icons/xai.avif") type("image/avif"), url("/art/icons/xai.webp") type("image/webp")); }
57
- .provider-icon[data-provider="shell"] { --icon: image-set(url("/art/icons/shell.avif") type("image/avif"), url("/art/icons/shell.webp") type("image/webp")); }
58
- .provider-icon:not(.has-image)[data-provider="anthropic"],
59
- .provider-icon:not(.has-image)[data-provider="openai"],
60
- .provider-icon:not(.has-image)[data-provider="google"],
61
- .provider-icon:not(.has-image)[data-provider="xai"],
62
- .provider-icon:not(.has-image)[data-provider="shell"] {
63
- background: var(--icon) center / cover no-repeat; color: transparent;
64
- }
65
-
66
- body::before {
67
- content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
68
- background: var(--page-art) center bottom / cover no-repeat;
69
- }
70
-
71
- .provider, .session-card {
72
- position: relative; isolation: isolate; overflow: hidden;
73
- border-radius: 6px; padding: 18px;
74
- transition: border-color 0.2s, box-shadow 0.2s, transform 0.3s var(--ease);
75
- }
76
- .provider:hover { transform: translateY(-3px); }
77
- .session-card:hover { transform: translateY(-2px); }
78
- .provider::before {
79
- content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
80
- background: linear-gradient(105deg, transparent 38%, var(--glint) 50%, transparent 62%);
81
- transform: translateX(-110%);
82
- }
83
- .provider:hover::before { transform: translateX(110%); transition: transform 1s var(--ease); }
84
- .provider .card-art::before { transition: transform 0.5s var(--ease); }
85
- .provider:hover .card-art::before { transform: translate(calc(var(--px, 0) * -7px), calc(var(--py, 0) * -5px)) scale(1.045); }
86
- .providers.deal > .provider { animation: deal 0.55s var(--ease) both; }
87
- .providers.deal > .provider:nth-child(2) { animation-delay: 0.06s; }
88
- .providers.deal > .provider:nth-child(3) { animation-delay: 0.12s; }
89
- .providers.deal > .provider:nth-child(4) { animation-delay: 0.18s; }
90
- .providers.deal > .provider:nth-child(5) { animation-delay: 0.24s; }
91
- .providers.deal > .provider:nth-child(6) { animation-delay: 0.3s; }
92
- .providers.deal > .provider:nth-child(n + 7) { animation-delay: 0.36s; }
93
- .session-card.enter { animation: card-enter 0.5s var(--ease) both; }
94
- .provider::after, .session-card::after {
95
- content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
96
- border: 44px solid transparent; border-image: url("/art/ui/frame.png") 168;
97
- }
98
- .card-art { position: absolute; z-index: -1; overflow: hidden; pointer-events: none; }
99
- .card-art::before { content: ""; position: absolute; inset: 0; background: var(--idle) no-repeat; }
100
- .provider.unavailable .card-art::before { background-image: var(--locked); }
101
- .provider.unavailable::after {
102
- background: url("/art/ui/padlock.png") right 16px top 14px / 30px 40px no-repeat border-box;
103
- }
104
- .session-card { min-height: 196px; }
105
- .session-card .card-art::after {
106
- content: ""; position: absolute; inset: 0; background: var(--working) no-repeat;
107
- opacity: 0; transition: opacity 0.6s var(--ease);
108
- }
109
- .session-card:has(.status-pill.active) .card-art::after { opacity: 1; }
110
- .card-aura {
111
- position: absolute; z-index: -1; overflow: hidden; pointer-events: none;
112
- opacity: 0; transition: opacity 0.6s var(--ease);
113
- }
114
- .card-aura::before {
115
- content: ""; position: absolute; inset: -12%;
116
- background: radial-gradient(closest-side, transparent 52%, color-mix(in srgb, var(--pc) 55%, transparent) 84%, transparent);
117
- }
118
- .card-aura::after {
119
- content: ""; position: absolute; inset: 0 0 auto; height: calc(100% + 96px);
120
- background-image:
121
- radial-gradient(circle, color-mix(in srgb, var(--pc) 80%, #fff) 0 1.4px, transparent 2.2px),
122
- radial-gradient(circle, color-mix(in srgb, var(--pc) 65%, #fff) 0 1px, transparent 1.8px),
123
- radial-gradient(circle, #fff3d0 0 0.9px, transparent 1.6px);
124
- background-size: 44px 96px, 61px 48px, 37px 96px;
125
- background-position: 6px 10px, 30px 30px, 18px 62px;
126
- }
127
- .session-card:has(.status-pill.active) .card-aura { opacity: 1; }
128
- .session-card:has(.status-pill.active) .card-aura::before { animation: aura 3.6s ease-in-out infinite alternate; }
129
- .session-card:has(.status-pill.active) .card-aura::after { animation: sparks 3.2s linear infinite; }
130
- body:has(#terminal-panel:not([hidden])) main :is(.card-aura, .status-pill, .agent)::before,
131
- body:has(#terminal-panel:not([hidden])) main :is(.card-aura, .agent)::after { animation-play-state: paused; }
132
- .session-card .card-top > .provider-icon { display: none; }
133
- .session-card .card-top { flex-wrap: wrap; gap: 6px 8px; }
134
- .session-card .card-title { flex-basis: 100%; }
135
-
136
- .level-badge {
137
- display: grid; place-items: center; position: absolute; left: 12px; bottom: 12px; z-index: 1;
138
- width: 46px; height: 46px; padding-top: 1px;
139
- background: url("/art/ui/level-medallion.png") center / contain no-repeat;
140
- font: 700 1.05rem var(--font-display); color: #f6dea6;
141
- text-shadow: 0 1px 2px #000, 0 0 6px rgba(0, 0, 0, 0.8);
142
- }
143
- .level-badge.level-up { animation: level-up 1.2s var(--ease); }
144
- .agent.summon { animation: summon 0.6s var(--ease) both; }
145
-
146
- #empty { padding: 4px 16px 8px; text-align: center; }
147
- #empty::before {
148
- content: ""; display: block; width: 190px; height: 206px; margin: 0 auto 12px;
149
- background: image-set(url("/art/ui/empty-state.avif") type("image/avif"), url("/art/ui/empty-state.webp") type("image/webp")) center / contain no-repeat;
150
- filter: drop-shadow(0 12px 14px var(--empty-shadow));
151
- }
152
-
153
- body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after {
154
- content: ""; position: fixed; left: 50%; top: 50%; width: 72px; height: 72px; margin: -36px 0 0 -36px;
155
- background: url("/art/ui/guild-crest.png") center / contain no-repeat;
156
- animation: splash 1.4s ease-in-out infinite alternate;
157
- }
158
-
159
- .agent {
160
- border-width: 1px; border-color: var(--fc); place-items: end end; padding: 0 3px 1px 0;
161
- background: #0e1016 center / 118% auto no-repeat;
162
- color: #fff; font-size: 0.62rem; text-shadow: 0 0 3px #000, 0 1px 2px #000;
163
- box-shadow: 0 0 10px color-mix(in srgb, var(--fc) 45%, transparent);
164
- }
165
- .session-card .agent { width: 34px; height: 34px; }
166
- .agent.working::after { border-color: var(--fc); }
167
- .agent[data-familiar="flame"] { --fc: #f08a3c; background-image: url("/art/familiars/flame.png"); }
168
- .agent[data-familiar="leaf"] { --fc: #5fd068; background-image: url("/art/familiars/leaf.png"); }
169
- .agent[data-familiar="night"] { --fc: #a66cf0; background-image: url("/art/familiars/night.png"); }
170
- .agent[data-familiar="aether"] { --fc: #7cc8ff; background-image: url("/art/familiars/aether.png"); }
171
-
172
- .meter-label { padding-left: 18px; background: url("/art/ui/gem-vitality.png") left center / 14px auto no-repeat; }
173
- .meter + .meter .meter-label { background-image: url("/art/ui/gem-mana.png"); }
174
- .meter-bar, .stat-bar { height: 7px; }
175
- .model-stats-head { color: var(--gold-ink); }
176
- .stat-tier { border-radius: 3px; font-family: var(--font-display); }
177
- .tier-s .stat-tier { color: #2b1b06; background: linear-gradient(180deg, #fbe9bd 0%, #e2b867 55%, #a97b35 100%); }
178
-
179
- .tip {
180
- background: #14120f; color: #ece4d1; border: 1px solid #4a3d25;
181
- box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.06), 0 10px 28px rgba(0, 0, 0, 0.45);
182
- }
183
- .tip strong { color: #f0cf8a; font-family: var(--font-display); }
184
-
185
- .models::after, .auth::after {
186
- content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
187
- border: 54px solid transparent; border-image: url("/art/ui/frame-ornate.png") 232;
188
- }
189
- .models-bar { padding: 30px 36px 12px; }
190
- .models-body { margin: 0 24px; padding: 0 12px 14px; }
191
- .models-source { padding: 10px 36px 30px; }
192
- .history-tools { padding: 10px 36px 0; }
193
- .history-form { padding: 10px 36px 30px; }
194
- .github-accounts { padding: 10px 36px; }
195
- .model-group h4, .news-day, .changelog-type { font-family: var(--font-display); letter-spacing: 0.08em; color: var(--gold-ink); }
196
- .news-bar { padding: 16px 18px 12px; }
197
- .news-filters, .news-status { padding-left: 18px; padding-right: 18px; }
198
- .news-body { padding: 0 18px 14px; }
199
- .news-row { transition: background-color 0.15s; }
200
- .news-row:hover { background: color-mix(in srgb, var(--gold) 7%, transparent); }
201
- .news-row:first-child { border-radius: 6px 6px 0 0; }
202
- .news-row:last-child { border-radius: 0 0 6px 6px; }
203
-
204
- .terminal-panel { border-radius: 6px; }
205
- .panel-bar { padding: 10px 14px; border-bottom: 1px solid; border-image: linear-gradient(90deg, transparent, var(--gold) 20%, var(--gold) 80%, transparent) 1; }
206
-
207
- .auth { position: relative; border-radius: 6px; padding: 40px 44px; }
208
- .auth pre { color: var(--gold-ink); }
209
-
210
- :where(:root[data-theme="dark"]) {
211
- --gold-dim: #8a6d3b;
212
- --card-bg: rgba(18, 20, 26, 0.9);
213
- --glint: rgba(255, 238, 200, 0.1);
214
- --empty-shadow: rgba(0, 0, 0, 0.55);
215
- --page-art: image-set(url("/art/page.avif") type("image/avif"), url("/art/page.webp") type("image/webp"));
216
-
217
- body { background: #0b0c10; }
218
- .topbar { background: rgba(12, 13, 17, 0.88); backdrop-filter: blur(6px); }
219
-
220
- .provider, .session-card {
221
- background: var(--card-bg);
222
- border: 1px solid color-mix(in srgb, var(--pc) 35%, #2a303b);
223
- box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.06), 0 8px 24px rgba(0, 0, 0, 0.35);
224
- }
225
- .provider:hover, .session-card:hover {
226
- border-color: color-mix(in srgb, var(--pc) 70%, #2a303b);
227
- box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.1), 0 0 22px color-mix(in srgb, var(--pc) 22%, transparent);
228
- }
229
-
230
- .provider { padding-top: 188px; }
231
- .provider .card-art {
232
- inset: 0 0 auto 0; height: 250px;
233
- mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
234
- }
235
- .provider .card-art::before { background-size: cover; background-position: center top; }
236
- .provider.unavailable { border-color: #2a2d33; }
237
- .provider .vendor { color: #f3ead8; }
238
-
239
- .session-card { padding-left: 152px; }
240
- .session-card .card-art, .session-card .card-aura {
241
- inset: 0 auto 0 0; width: 168px;
242
- mask-image: linear-gradient(to right, #000 62%, transparent 100%);
243
- }
244
- .session-card .card-aura {
245
- mask-image: linear-gradient(to right, #000 62%, transparent 100%), linear-gradient(transparent, #000 22%, #000 78%, transparent);
246
- mask-composite: intersect;
247
- }
248
- .session-card .card-art::before, .session-card .card-art::after { background-size: 168px auto; background-position: center top; }
249
- .session-card:has(.status-pill.active) {
250
- border-color: color-mix(in srgb, var(--pc) 75%, #2a303b);
251
- box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.1), 0 0 26px color-mix(in srgb, var(--pc) 28%, transparent);
252
- }
253
- .session-card.exited .card-art { filter: grayscale(1) brightness(0.7); }
254
-
255
- .meter-bar, .stat-bar { background: #0c0e12; box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.18); }
256
- .meter-fill { background: linear-gradient(90deg, #1f9d5c, #52e08f); box-shadow: 0 0 8px rgba(82, 224, 143, 0.55); }
257
- .meter + .meter .meter-fill { background: linear-gradient(90deg, #2a62c9, #5ba6ff); box-shadow: 0 0 8px rgba(91, 166, 255, 0.55); }
258
- .meter.low .meter-fill { background: var(--warn); box-shadow: 0 0 8px rgba(224, 168, 74, 0.5); }
259
- .meter.empty .meter-fill { background: var(--danger); box-shadow: 0 0 8px rgba(239, 107, 102, 0.5); }
260
-
261
- .info { color: #b89a5e; }
262
- .info:hover, .info:focus-visible { color: var(--gold); }
263
- .stat-fill {
264
- background: linear-gradient(90deg, color-mix(in srgb, var(--tier) 55%, #000), var(--tier));
265
- box-shadow: 0 0 8px color-mix(in srgb, var(--tier) 50%, transparent);
266
- }
267
- .stat-tier {
268
- background: linear-gradient(color-mix(in srgb, var(--tier) 34%, #1a1d26), #0d0f15);
269
- border-color: color-mix(in srgb, var(--tier) 70%, #000);
270
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 0 6px color-mix(in srgb, var(--tier) 30%, transparent);
271
- }
272
- .tier-s .stat-tier { border-color: #f6dea6; box-shadow: 0 0 10px rgba(232, 196, 124, 0.6); }
273
-
274
- .models {
275
- border-radius: 6px; border-color: #4a3d25; background: #12141a;
276
- box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.06), 0 24px 60px rgba(0, 0, 0, 0.6);
277
- }
278
- .models::backdrop { background: rgba(5, 6, 9, 0.72); }
279
- .models-bar, .models-source, .model-columns, .model { border-color: #2a2418; }
280
- .model-columns { background: #12141a; }
281
- .model-toggle:hover { background: rgba(232, 196, 124, 0.06); }
282
- .model-group h4 { color: #c9ab72; }
283
- .badge { background: rgba(0, 0, 0, 0.45); border-color: #4a3d25; }
284
- .model-pill:hover { border-color: var(--gold-dim); }
285
-
286
- .news-latest {
287
- border-radius: 6px; border-color: #4a3d25; background: var(--card-bg);
288
- box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.06), 0 8px 24px rgba(0, 0, 0, 0.35);
289
- }
290
- .news-row + .news-row, .news-bar, .news-filters, .news-item, .news-status, .changelog-release + .changelog-release { border-color: #2a2418; }
291
- .news-link { color: #f3ead8; }
292
- a.news-link:visited { color: var(--muted); }
293
- .news-panel {
294
- background: #12141a; border-left-color: #4a3d25;
295
- box-shadow: inset 1px 0 0 rgba(232, 196, 124, 0.08), -24px 0 60px rgba(0, 0, 0, 0.6);
296
- }
297
- .news-panel::backdrop { background: rgba(5, 6, 9, 0.72); }
298
- .news-day { background: #12141a; color: #c9ab72; }
299
- .changelog-type { color: #c9ab72; }
300
- .news-filter { border-color: #4a3d25; background: rgba(0, 0, 0, 0.35); }
301
- .news-filter:hover { border-color: var(--gold-dim); }
302
- .news-filter[aria-pressed="true"] { border-color: #b8955a; color: #fff; background: #5b40d0 linear-gradient(#7a5fe6, #4f34bf); }
303
-
304
- .status-pill { background: rgba(0, 0, 0, 0.45); border: 1px solid #4a3d25; }
305
- .status-pill.active { border-color: color-mix(in srgb, var(--ok) 55%, transparent); box-shadow: 0 0 10px rgba(76, 195, 138, 0.25); }
306
- .model-pill { border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); }
307
- .provider .tier { background: rgba(0, 0, 0, 0.45); border-color: #4a3d25; color: var(--gold); }
308
-
309
- .btn {
310
- border-color: #4a3d25;
311
- background: linear-gradient(#242834, #171a22);
312
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 1px 2px rgba(0, 0, 0, 0.5);
313
- }
314
- .btn:hover { border-color: var(--gold-dim); }
315
- .btn.primary {
316
- border-color: #b8955a; color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
317
- background: #5b40d0 linear-gradient(#7a5fe6, #4f34bf);
318
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 2px 10px rgba(91, 64, 208, 0.35);
319
- }
320
- .btn.primary:hover { border-color: var(--gold); filter: brightness(1.08); }
321
- .btn.danger { color: #ff9a94; }
322
- .btn.danger:hover { border-color: #b8524d; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 12px rgba(239, 107, 102, 0.3); }
323
- .cwd input, .auth input { border-color: #4a3d25; background: rgba(12, 13, 17, 0.8); }
324
- .auth {
325
- background: var(--card-bg);
326
- border: 1px solid #4a3d25; box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.06), 0 8px 24px rgba(0, 0, 0, 0.35);
327
- }
328
- .auth pre { background: rgba(12, 13, 17, 0.8); border: 1px solid #2a2418; }
329
- .notice h2 { color: #ff9a94; }
330
- .notice.stopping h2 { color: var(--gold); }
331
- .terminal-panel { border-color: #4a3d25; box-shadow: inset 0 0 0 1px rgba(232, 196, 124, 0.06), 0 24px 60px rgba(0, 0, 0, 0.6); }
332
- .panel-bar { background: linear-gradient(#1a1d25, #121419); }
333
-
334
- @media (max-width: 640px) {
335
- .session-card { padding-left: 118px; }
336
- .session-card .card-art, .session-card .card-aura { width: 132px; }
337
- .session-card .card-art::before, .session-card .card-art::after { background-size: 132px auto; }
338
- }
339
- }
340
-
341
- :where(:root[data-theme="light"]) {
342
- --page-art: image-set(url("/art/page-light.avif") type("image/avif"), url("/art/page-light.webp") type("image/webp"));
343
- --glint: rgba(255, 244, 214, 0.26);
344
- --empty-shadow: rgba(70, 48, 12, 0.28);
345
- --card-shadow: inset 0 1px 0 #fff, 0 1px 2px rgba(70, 48, 12, 0.08), 0 10px 26px rgba(70, 48, 12, 0.1);
346
-
347
- body { background: #eee5d4; }
348
- .topbar { background: rgba(255, 252, 246, 0.9); backdrop-filter: blur(6px); }
349
-
350
- .provider, .session-card {
351
- background: var(--surface);
352
- border: 1px solid #e4d6b6;
353
- box-shadow: var(--card-shadow);
354
- }
355
- .provider:hover, .session-card:hover {
356
- border-color: color-mix(in srgb, var(--pc) 40%, #d7c49b);
357
- box-shadow: inset 0 1px 0 #fff, 0 2px 4px rgba(70, 48, 12, 0.08), 0 14px 34px rgba(70, 48, 12, 0.15);
358
- }
359
- .card-art {
360
- border-radius: 3px;
361
- background: radial-gradient(85% 70% at 50% 34%, color-mix(in srgb, var(--pc) 46%, #1d1726) 0%, #120f17 74%);
362
- box-shadow: inset 0 0 0 1px rgba(255, 233, 186, 0.3), 0 0 0 1px #c9a45e, 0 1px 3px rgba(70, 48, 12, 0.3);
363
- }
364
- .provider .card-art::after {
365
- content: ""; position: absolute; inset: 0;
366
- background: linear-gradient(transparent 58%, rgba(10, 8, 14, 0.45));
367
- box-shadow: inset 0 0 18px rgba(0, 0, 0, 0.55);
368
- }
369
-
370
- .provider { padding-top: 242px; }
371
- .provider .card-art { inset: 14px 14px auto; height: 214px; }
372
- .provider .card-art::before { background-size: 112% auto; background-position: 50% 4%; }
373
- .provider.unavailable .card-art { background: radial-gradient(85% 70% at 50% 34%, #45434a 0%, #17161a 74%); }
374
- .provider-icon:not(.has-image)[data-provider] { box-shadow: 0 0 0 1px #c9a45e, 0 1px 3px rgba(70, 48, 12, 0.3); }
375
-
376
- .session-card { padding-left: 160px; }
377
- .session-card .card-art, .session-card .card-aura { inset: 14px auto 14px 14px; width: 132px; border-radius: 3px; }
378
- .session-card .card-aura { mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent); }
379
- .session-card .card-art::before, .session-card .card-art::after { background-size: 160% auto; background-position: 50% 8%; }
380
- .session-card:has(.status-pill.active) {
381
- border-color: color-mix(in srgb, var(--pc) 55%, #d7c49b);
382
- box-shadow: inset 0 1px 0 #fff, 0 2px 4px rgba(70, 48, 12, 0.08), 0 12px 30px color-mix(in srgb, var(--pc) 22%, rgba(70, 48, 12, 0.12));
383
- }
384
- .session-card.exited .card-art { filter: grayscale(1) brightness(0.9); }
385
-
386
- .meter-bar, .stat-bar { background: #ebe2cd; box-shadow: inset 0 1px 2px rgba(70, 48, 12, 0.2); }
387
- .meter-fill { background: linear-gradient(90deg, #1b7a45, #31a868); }
388
- .meter + .meter .meter-fill { background: linear-gradient(90deg, #2a57b0, #4382e2); }
389
- .meter.low .meter-fill { background: linear-gradient(90deg, #9a5f00, #d08a14); }
390
- .meter.empty .meter-fill { background: linear-gradient(90deg, #a8302b, #d24a43); }
391
- .stat-fill { background: linear-gradient(90deg, color-mix(in srgb, var(--tier) 72%, #3a2a10), var(--tier)); }
392
- .stat-tier {
393
- background: linear-gradient(color-mix(in srgb, var(--tier) 10%, #fffdf8), color-mix(in srgb, var(--tier) 24%, #fffdf8));
394
- border-color: color-mix(in srgb, var(--tier) 55%, #fff);
395
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
396
- }
397
- .tier-s .stat-tier { color: #3a2604; border-color: #b8892f; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 1px 3px rgba(150, 100, 20, 0.35); }
398
-
399
- .models { border-color: #d8c597; box-shadow: 0 24px 60px rgba(40, 28, 8, 0.28); }
400
- .models::backdrop { background: rgba(40, 30, 14, 0.38); }
401
- .model-toggle:hover { background: #f6eedd; }
402
-
403
- .news-latest { border-color: #e4d6b6; box-shadow: 0 1px 2px rgba(70, 48, 12, 0.08), 0 10px 26px rgba(70, 48, 12, 0.08); }
404
- .news-panel { border-left-color: #e2d3b2; box-shadow: -24px 0 60px rgba(40, 28, 8, 0.22); }
405
- .news-panel::backdrop { background: rgba(40, 30, 14, 0.3); }
406
-
407
- .status-pill { background: #f6efe0; border: 1px solid #e2d3b2; }
408
- .status-pill.active { border-color: color-mix(in srgb, var(--ok) 40%, transparent); background: color-mix(in srgb, var(--ok) 8%, #fffcf6); }
409
- .status-pill.exited { border-color: color-mix(in srgb, var(--danger) 35%, transparent); background: color-mix(in srgb, var(--danger) 6%, #fffcf6); }
410
- .model-pill { border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); background: color-mix(in srgb, var(--accent) 9%, #fffcf6); }
411
- .provider .tier { color: #5c3f08; border-color: #d4b06a; background: linear-gradient(#fbf0d2, #f1dfb2); }
412
-
413
- .btn {
414
- border-color: #d8c597;
415
- background: linear-gradient(#fffefa, #f2e9d6);
416
- box-shadow: inset 0 1px 0 #fff, 0 1px 2px rgba(70, 48, 12, 0.12);
417
- }
418
- .btn:hover { border-color: #b8892f; }
419
- .btn.primary {
420
- border-color: #8f6d2a; color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);
421
- background: #5a3fc0 linear-gradient(#6c51d6, #4a30ad);
422
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 2px 6px rgba(74, 48, 173, 0.28);
423
- }
424
- .btn.primary:hover { border-color: #b8892f; filter: brightness(1.08); }
425
- .btn.danger:hover { border-color: #c4625d; }
426
- .cwd input, .auth input, .history-tools input[type="search"], .history-form input {
427
- border-color: #dccba5; background: #fffdf8; box-shadow: inset 0 1px 2px rgba(70, 48, 12, 0.06);
428
- }
429
- .auth { border-color: #e4d6b6; box-shadow: var(--card-shadow); }
430
- .auth pre { background: #f6efe0; border: 1px solid #e4d6b6; }
431
- .terminal-panel { border-color: #c9b07a; box-shadow: 0 24px 60px rgba(40, 28, 8, 0.35); }
432
- .panel-bar { background: linear-gradient(#fffdf8, #f3ead7); }
433
-
434
- @media (max-width: 640px) {
435
- .session-card { padding-left: 140px; }
436
- .session-card .card-art, .session-card .card-aura { width: 112px; }
437
- .session-card .card-art::before, .session-card .card-art::after { background-size: 165% auto; }
438
- }
439
- }
440
-
441
- @media (max-width: 640px) {
442
- .models::after, .auth::after { border-width: 40px; }
443
- .models-bar { padding: 24px 26px 10px; }
444
- .models-body { margin: 0 16px; padding: 0 10px 12px; }
445
- .models-source { padding: 10px 26px 24px; }
446
- .history-tools { padding: 10px 26px 0; }
447
- .history-form { padding: 10px 26px 24px; }
448
- .github-accounts { padding: 10px 26px; }
449
- .auth { padding: 32px 30px; }
450
- }
451
-
452
- @keyframes deal { from { opacity: 0; transform: translateY(16px) rotate(-1.2deg) scale(0.97); } }
453
- @keyframes card-enter { from { opacity: 0; transform: translateY(10px) scale(0.98); } }
454
- @keyframes aura { from { opacity: 0.5; transform: scale(0.97); } to { opacity: 1; transform: scale(1.03); } }
455
- @keyframes sparks { to { transform: translateY(-96px); } }
456
- @keyframes level-up { 30% { transform: scale(1.28); filter: brightness(1.5) drop-shadow(0 0 8px #f6dea6); } }
457
- @keyframes summon { from { opacity: 0; transform: scale(0.3); } 60% { opacity: 1; transform: scale(1.15); } }
458
- @keyframes splash { from { opacity: 0.3; transform: scale(0.95); } to { opacity: 0.85; transform: scale(1.03); } }
459
-
460
- @media (prefers-reduced-motion: reduce) {
461
- .provider, .session-card, .card-aura, .session-card .card-art::after, .provider .card-art::before { transition: none; }
462
- .provider:hover, .session-card:hover, .provider:hover .card-art::before { transform: none; }
463
- .provider::before { display: none; }
464
- .providers.deal > .provider, .session-card.enter, .level-badge.level-up, .agent.summon,
465
- .session-card:has(.status-pill.active) .card-aura::before, .session-card:has(.status-pill.active) .card-aura::after,
466
- body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after { animation: none; }
467
- }
File without changes
File without changes