@geminixiang/mikan 0.2.0 → 0.2.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/CHANGELOG.md +33 -0
- package/README.md +54 -181
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +5 -4
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/shared.d.ts +3 -2
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +11 -11
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +1 -0
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +43 -1
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +2 -3
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/admin/portal.d.ts +27 -0
- package/dist/admin/portal.d.ts.map +1 -0
- package/dist/admin/portal.js +2029 -0
- package/dist/admin/portal.js.map +1 -0
- package/dist/admin/store.d.ts +22 -0
- package/dist/admin/store.d.ts.map +1 -0
- package/dist/admin/store.js +39 -0
- package/dist/admin/store.js.map +1 -0
- package/dist/agent.d.ts +5 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +10 -9
- package/dist/agent.js.map +1 -1
- package/dist/commands/admin.d.ts +8 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +59 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +8 -7
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +38 -14
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +2 -2
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +13 -3
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +2 -2
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.d.ts.map +1 -1
- package/dist/commands/session-view.js +3 -6
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +11 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/commands/utils.d.ts +1 -0
- package/dist/commands/utils.d.ts.map +1 -1
- package/dist/commands/utils.js +5 -0
- package/dist/commands/utils.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -13
- package/dist/config.js.map +1 -1
- package/dist/events.d.ts +0 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +2 -5
- package/dist/events.js.map +1 -1
- package/dist/file-guards.d.ts.map +1 -1
- package/dist/file-guards.js +10 -7
- package/dist/file-guards.js.map +1 -1
- package/dist/login/portal.d.ts +11 -1
- package/dist/login/portal.d.ts.map +1 -1
- package/dist/login/portal.js +57 -175
- package/dist/login/portal.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +5 -1
- package/dist/main.js.map +1 -1
- package/dist/portal-shell.d.ts +30 -0
- package/dist/portal-shell.d.ts.map +1 -0
- package/dist/portal-shell.js +371 -0
- package/dist/portal-shell.js.map +1 -0
- package/dist/session-view/portal.d.ts.map +1 -1
- package/dist/session-view/portal.js +88 -242
- package/dist/session-view/portal.js.map +1 -1
- package/dist/store.d.ts +1 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +30 -12
- package/dist/store.js.map +1 -1
- package/dist/vault.d.ts.map +1 -1
- package/dist/vault.js +2 -8
- package/dist/vault.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { basename } from "path";
|
|
2
2
|
import MarkdownIt from "markdown-it";
|
|
3
3
|
import * as log from "../log.js";
|
|
4
|
+
import { renderPortalShell } from "../portal-shell.js";
|
|
4
5
|
import { reportUserFacingError } from "../sentry.js";
|
|
5
6
|
import { inferConversationKind } from "../sessions/policy.js";
|
|
6
7
|
import { loadSessionViewModel, resolveRequestedSessionFile, } from "./service.js";
|
|
@@ -153,55 +154,51 @@ function renderSessionPage(model, token, expiresAt, isRunning, displayedSessionK
|
|
|
153
154
|
${renderRelationCard(model.parent, token)}
|
|
154
155
|
</section>`
|
|
155
156
|
: "";
|
|
156
|
-
|
|
157
|
-
<div
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
<
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
<div class="hero-side">
|
|
168
|
-
<span class="hero-badge hero-badge-status${isRunning ? " is-running" : ""}"><span class="hero-badge-dot"></span><strong data-session-status>${esc(isRunning ? "Running" : "Idle")}</strong></span>
|
|
169
|
-
<span class="hero-badge">${esc(displayedSessionKey === conversationId ? "Channel" : "Thread")}</span>
|
|
170
|
-
</div>
|
|
157
|
+
const body = `<header class="page-head">
|
|
158
|
+
<div>
|
|
159
|
+
<p class="eyebrow">Session</p>
|
|
160
|
+
<h2 class="page-title">${esc(model.title)}</h2>
|
|
161
|
+
<p class="page-desc">
|
|
162
|
+
<span>Created ${esc(formatDate(model.createdAt))}</span> ·
|
|
163
|
+
<span>Updated <strong data-session-updated>${esc(formatDate(model.updatedAt))}</strong></span> ·
|
|
164
|
+
<span><strong data-session-entries>${esc(String(model.entryCount))}</strong> entries</span>
|
|
165
|
+
</p>
|
|
171
166
|
</div>
|
|
172
|
-
<div class="
|
|
173
|
-
<span class="
|
|
174
|
-
<span class="
|
|
175
|
-
<span class="hero-detail"><span class="hero-detail-label">Expires</span><span>${esc(formatDate(new Date(expiresAt).toISOString()))}</span></span>
|
|
167
|
+
<div class="session-side">
|
|
168
|
+
<span class="session-badge session-badge-status${isRunning ? " is-running" : ""}"><span class="session-badge-dot"></span><strong data-session-status>${esc(isRunning ? "Running" : "Idle")}</strong></span>
|
|
169
|
+
<span class="session-badge">${esc(displayedSessionKey === conversationId ? "Channel" : "Thread")}</span>
|
|
176
170
|
</div>
|
|
177
171
|
</header>
|
|
178
172
|
|
|
173
|
+
<div class="session-detail-row">
|
|
174
|
+
<span class="session-detail"><span class="session-detail-label">Session</span><code>${esc(model.sessionId.slice(0, 8))}</code></span>
|
|
175
|
+
<span class="session-detail"><span class="session-detail-label">File</span><code>${esc(model.fileName)}</code></span>
|
|
176
|
+
<span class="session-detail"><span class="session-detail-label">Expires</span><span>${esc(formatDate(new Date(expiresAt).toISOString()))}</span></span>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
179
|
${relatedSections}
|
|
180
180
|
|
|
181
|
-
<
|
|
181
|
+
<div class="timeline-shell">
|
|
182
182
|
<div class="timeline-list" data-timeline-list>
|
|
183
183
|
${items}
|
|
184
184
|
</div>
|
|
185
|
-
</
|
|
185
|
+
</div>
|
|
186
186
|
|
|
187
187
|
<button class="jump-latest-btn" type="button" hidden data-jump-latest aria-label="Jump to latest" title="Jump to latest">↓</button>
|
|
188
188
|
|
|
189
189
|
<section class="composer-card">
|
|
190
|
-
<div class="composer-copy">
|
|
191
|
-
<p class="eyebrow">Interactive preview</p>
|
|
192
|
-
<p>Ask mikan in this same session. Replies stay in Session View and do not post back to Slack.</p>
|
|
193
|
-
</div>
|
|
194
190
|
<form class="composer-form" data-session-composer>
|
|
195
191
|
<input type="hidden" name="token" value="${esc(token)}">
|
|
196
192
|
<input type="hidden" name="session" value="${esc(model.fileName)}">
|
|
197
193
|
<input type="hidden" name="sessionKey" value="${esc(displayedSessionKey)}">
|
|
198
|
-
<textarea name="text" rows="1" placeholder="
|
|
194
|
+
<textarea name="text" rows="1" placeholder="Ask mikan in this session… (replies stay in Session View)" required></textarea>
|
|
199
195
|
<div class="composer-actions">
|
|
200
196
|
<span class="composer-status" data-composer-status></span>
|
|
201
197
|
<button class="composer-send-btn" type="submit" aria-label="Send" title="Send">↑</button>
|
|
202
198
|
</div>
|
|
203
199
|
</form>
|
|
204
|
-
</section
|
|
200
|
+
</section>`;
|
|
201
|
+
return renderHtmlDocument(`${model.title} · Session Viewer`, body, isRunning);
|
|
205
202
|
}
|
|
206
203
|
function renderRelationCard(relation, token) {
|
|
207
204
|
const href = `/session?token=${encodeURIComponent(token)}&session=${encodeURIComponent(relation.fileName)}`;
|
|
@@ -623,24 +620,21 @@ function json(res, status, body) {
|
|
|
623
620
|
function renderStatusPage(title, message) {
|
|
624
621
|
return renderHtmlDocument(title, `<section class="card stack">
|
|
625
622
|
<p class="eyebrow">mikan</p>
|
|
626
|
-
<h1>${esc(title)}</h1>
|
|
623
|
+
<h1 class="page-title">${esc(title)}</h1>
|
|
627
624
|
<div class="status err">${esc(message)}</div>
|
|
628
625
|
</section>`, false);
|
|
629
626
|
}
|
|
630
627
|
function renderHtmlDocument(title, shellContent, isRunning) {
|
|
631
|
-
return
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
${shellContent}
|
|
642
|
-
</main>
|
|
643
|
-
<script>
|
|
628
|
+
return renderPortalShell({
|
|
629
|
+
activeView: "session",
|
|
630
|
+
pageTitle: "Session",
|
|
631
|
+
body: shellContent,
|
|
632
|
+
extraStyles: sessionViewStyles,
|
|
633
|
+
bodyAttributes: { "data-session-running": isRunning ? "true" : "false" },
|
|
634
|
+
inlineScript: sessionViewScript,
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
const sessionViewScript = `
|
|
644
638
|
const form = document.querySelector('[data-session-composer]');
|
|
645
639
|
const timelineList = document.querySelector('[data-timeline-list]');
|
|
646
640
|
const jumpLatestBtn = document.querySelector('[data-jump-latest]');
|
|
@@ -808,10 +802,7 @@ function renderHtmlDocument(title, shellContent, isRunning) {
|
|
|
808
802
|
});
|
|
809
803
|
|
|
810
804
|
toggleJumpButton();
|
|
811
|
-
|
|
812
|
-
</body>
|
|
813
|
-
</html>`;
|
|
814
|
-
}
|
|
805
|
+
`;
|
|
815
806
|
function formatDate(value) {
|
|
816
807
|
const date = new Date(value);
|
|
817
808
|
if (Number.isNaN(date.getTime()))
|
|
@@ -826,17 +817,8 @@ function esc(value) {
|
|
|
826
817
|
.replaceAll('"', """)
|
|
827
818
|
.replaceAll("'", "'");
|
|
828
819
|
}
|
|
829
|
-
const
|
|
830
|
-
@import url('https://fonts.googleapis.com/css2?family=Lora:wght@400;600&family=DM+Sans:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');
|
|
831
|
-
|
|
820
|
+
const sessionViewStyles = `
|
|
832
821
|
:root {
|
|
833
|
-
--bg: #f0ece3;
|
|
834
|
-
--surface: #ffffff;
|
|
835
|
-
--border: rgba(0, 0, 0, 0.08);
|
|
836
|
-
--text: #18181b;
|
|
837
|
-
--muted: #71717a;
|
|
838
|
-
--subtle: #a1a1aa;
|
|
839
|
-
|
|
840
822
|
--user-bg: #18181b;
|
|
841
823
|
--user-text: #fafafa;
|
|
842
824
|
--user-time: rgba(250, 250, 250, 0.5);
|
|
@@ -852,174 +834,56 @@ const styles = `
|
|
|
852
834
|
--tool-ok: #3fb950;
|
|
853
835
|
--tool-err: #f85149;
|
|
854
836
|
--tool-time: #484f58;
|
|
855
|
-
|
|
856
|
-
--ok-bg: #f0fdf4;
|
|
857
|
-
--ok-text: #15803d;
|
|
858
|
-
--err-bg: #fef2f2;
|
|
859
|
-
--err-text: #b91c1c;
|
|
860
837
|
}
|
|
861
838
|
|
|
862
|
-
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
863
|
-
|
|
864
839
|
body {
|
|
865
|
-
|
|
866
|
-
padding:
|
|
867
|
-
display: flex;
|
|
868
|
-
flex-direction: column;
|
|
869
|
-
align-items: center;
|
|
840
|
+
/* Extra bottom padding for the fixed composer */
|
|
841
|
+
padding-bottom: calc(140px + env(safe-area-inset-bottom, 0px));
|
|
870
842
|
overflow-x: hidden;
|
|
871
|
-
background-color: var(--bg);
|
|
872
|
-
background-image:
|
|
873
|
-
radial-gradient(ellipse 80% 40% at 50% -10%, rgba(255,255,255,0.6) 0%, transparent 70%);
|
|
874
|
-
color: var(--text);
|
|
875
|
-
font-family: 'DM Sans', 'Segoe UI', system-ui, sans-serif;
|
|
876
|
-
font-size: 15px;
|
|
877
|
-
line-height: 1.5;
|
|
878
|
-
-webkit-font-smoothing: antialiased;
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
.shell {
|
|
882
|
-
width: 100%;
|
|
883
|
-
max-width: 780px;
|
|
884
|
-
min-width: 0;
|
|
885
|
-
display: flex;
|
|
886
|
-
flex-direction: column;
|
|
887
|
-
gap: 12px;
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
/* ── Hero ─────────────────────────────────────────────────────────────── */
|
|
891
|
-
|
|
892
|
-
.hero-card {
|
|
893
|
-
padding: 28px 32px 24px;
|
|
894
|
-
border: 1px solid var(--border);
|
|
895
|
-
border-radius: 20px;
|
|
896
|
-
background: var(--surface);
|
|
897
|
-
box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 4px 16px rgba(0,0,0,0.06);
|
|
898
843
|
}
|
|
899
844
|
|
|
900
|
-
|
|
901
|
-
display: flex;
|
|
902
|
-
align-items: flex-start;
|
|
903
|
-
justify-content: space-between;
|
|
904
|
-
gap: 20px;
|
|
905
|
-
margin-bottom: 18px;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
.hero-wordmark {
|
|
909
|
-
display: block;
|
|
910
|
-
margin-bottom: 6px;
|
|
911
|
-
color: var(--subtle);
|
|
912
|
-
font-size: 0.72rem;
|
|
913
|
-
font-weight: 600;
|
|
914
|
-
letter-spacing: 0.12em;
|
|
915
|
-
text-transform: uppercase;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
.hero-title {
|
|
919
|
-
font-family: 'Lora', Georgia, serif;
|
|
920
|
-
font-size: clamp(1.4rem, 2.5vw, 1.75rem);
|
|
921
|
-
font-weight: 600;
|
|
922
|
-
line-height: 1.2;
|
|
923
|
-
letter-spacing: -0.01em;
|
|
924
|
-
color: var(--text);
|
|
925
|
-
text-wrap: balance;
|
|
926
|
-
margin-bottom: 8px;
|
|
927
|
-
}
|
|
845
|
+
/* ── Session-specific page-head extras ─────────────────────────────── */
|
|
928
846
|
|
|
929
|
-
.
|
|
930
|
-
display: flex;
|
|
931
|
-
flex-wrap: wrap;
|
|
932
|
-
gap: 8px 14px;
|
|
933
|
-
color: var(--muted);
|
|
934
|
-
font-size: 0.82rem;
|
|
935
|
-
line-height: 1.4;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
.hero-meta-line strong {
|
|
939
|
-
color: var(--text);
|
|
940
|
-
font-weight: 600;
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
.hero-side {
|
|
944
|
-
display: flex;
|
|
945
|
-
flex-direction: column;
|
|
946
|
-
align-items: flex-end;
|
|
947
|
-
gap: 8px;
|
|
847
|
+
.session-side {
|
|
848
|
+
display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
|
|
948
849
|
flex-shrink: 0;
|
|
949
850
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
gap: 8px;
|
|
955
|
-
padding: 6px 11px;
|
|
956
|
-
border: 1px solid var(--border);
|
|
957
|
-
border-radius: 999px;
|
|
958
|
-
background: rgba(255,255,255,0.7);
|
|
959
|
-
font-size: 0.78rem;
|
|
960
|
-
color: var(--muted);
|
|
851
|
+
.session-badge {
|
|
852
|
+
display: inline-flex; align-items: center; gap: 8px;
|
|
853
|
+
padding: 6px 11px; border: 1px solid var(--border); border-radius: 999px;
|
|
854
|
+
background: rgba(255,255,255,0.7); font-size: 0.78rem; color: var(--muted);
|
|
961
855
|
line-height: 1;
|
|
962
856
|
}
|
|
963
|
-
|
|
964
|
-
.
|
|
965
|
-
color:
|
|
966
|
-
font-weight: 600;
|
|
857
|
+
.session-badge strong { color: var(--text); font-weight: 600; }
|
|
858
|
+
.session-badge-status.is-running {
|
|
859
|
+
background: #fff7ed; border-color: rgba(217, 119, 6, 0.18); color: #9a3412;
|
|
967
860
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
background: #
|
|
971
|
-
border-color: rgba(217, 119, 6, 0.18);
|
|
972
|
-
color: #9a3412;
|
|
861
|
+
.session-badge-dot {
|
|
862
|
+
width: 7px; height: 7px; border-radius: 50%;
|
|
863
|
+
background: #a1a1aa; flex-shrink: 0;
|
|
973
864
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
width: 7px;
|
|
977
|
-
height: 7px;
|
|
978
|
-
border-radius: 50%;
|
|
979
|
-
background: #a1a1aa;
|
|
980
|
-
flex-shrink: 0;
|
|
865
|
+
.session-badge-status.is-running .session-badge-dot {
|
|
866
|
+
background: #d97706; box-shadow: 0 0 0 4px rgba(217, 119, 6, 0.14);
|
|
981
867
|
}
|
|
982
868
|
|
|
983
|
-
.
|
|
984
|
-
|
|
985
|
-
|
|
869
|
+
.session-detail-row {
|
|
870
|
+
display: flex; flex-wrap: wrap; gap: 8px;
|
|
871
|
+
padding: 12px 14px; border: 1px solid var(--border); border-radius: 14px;
|
|
872
|
+
background: rgba(255,255,255,0.6);
|
|
986
873
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
gap: 10px;
|
|
992
|
-
padding-top: 14px;
|
|
993
|
-
border-top: 1px solid rgba(0, 0, 0, 0.06);
|
|
874
|
+
.session-detail {
|
|
875
|
+
display: inline-flex; align-items: center; gap: 8px; min-width: 0;
|
|
876
|
+
padding: 4px 10px; border-radius: 10px; background: rgba(0, 0, 0, 0.025);
|
|
877
|
+
color: var(--muted); font-size: 0.78rem;
|
|
994
878
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
align-items: center;
|
|
999
|
-
gap: 8px;
|
|
1000
|
-
min-width: 0;
|
|
1001
|
-
padding: 6px 10px;
|
|
1002
|
-
border-radius: 12px;
|
|
1003
|
-
background: rgba(0, 0, 0, 0.025);
|
|
1004
|
-
color: var(--muted);
|
|
1005
|
-
font-size: 0.78rem;
|
|
879
|
+
.session-detail-label {
|
|
880
|
+
text-transform: uppercase; letter-spacing: 0.08em;
|
|
881
|
+
font-size: 0.68rem; color: var(--subtle);
|
|
1006
882
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
font-size: 0.68rem;
|
|
1012
|
-
color: var(--subtle);
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
.hero-detail code {
|
|
1016
|
-
min-width: 0;
|
|
1017
|
-
overflow: hidden;
|
|
1018
|
-
text-overflow: ellipsis;
|
|
1019
|
-
white-space: nowrap;
|
|
1020
|
-
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
|
1021
|
-
font-size: 0.74rem;
|
|
1022
|
-
color: var(--text);
|
|
883
|
+
.session-detail code {
|
|
884
|
+
min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
885
|
+
font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.74rem;
|
|
886
|
+
color: var(--text); padding: 0;
|
|
1023
887
|
}
|
|
1024
888
|
|
|
1025
889
|
/* ── Timeline shell ───────────────────────────────────────────────────── */
|
|
@@ -1622,32 +1486,8 @@ const styles = `
|
|
|
1622
1486
|
|
|
1623
1487
|
/* ── Status page ──────────────────────────────────────────────────────── */
|
|
1624
1488
|
|
|
1625
|
-
.card {
|
|
1626
|
-
padding: 28px 32px;
|
|
1627
|
-
border: 1px solid var(--border);
|
|
1628
|
-
border-radius: 20px;
|
|
1629
|
-
background: var(--surface);
|
|
1630
|
-
box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 4px 16px rgba(0,0,0,0.06);
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
1489
|
.stack > * + * { margin-top: 14px; }
|
|
1634
1490
|
|
|
1635
|
-
.eyebrow {
|
|
1636
|
-
color: var(--subtle);
|
|
1637
|
-
font-size: 0.72rem;
|
|
1638
|
-
font-weight: 600;
|
|
1639
|
-
letter-spacing: 0.12em;
|
|
1640
|
-
text-transform: uppercase;
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
h1 {
|
|
1644
|
-
font-family: 'Lora', Georgia, serif;
|
|
1645
|
-
font-size: clamp(1.4rem, 2.5vw, 1.75rem);
|
|
1646
|
-
font-weight: 600;
|
|
1647
|
-
letter-spacing: -0.01em;
|
|
1648
|
-
line-height: 1.2;
|
|
1649
|
-
}
|
|
1650
|
-
|
|
1651
1491
|
p { color: var(--muted); font-size: 0.9rem; line-height: 1.5; }
|
|
1652
1492
|
|
|
1653
1493
|
.status {
|
|
@@ -1666,11 +1506,10 @@ const styles = `
|
|
|
1666
1506
|
|
|
1667
1507
|
.composer-card {
|
|
1668
1508
|
position: fixed;
|
|
1669
|
-
left:
|
|
1509
|
+
left: calc(72px + (100vw - 72px) / 2);
|
|
1670
1510
|
bottom: calc(16px + env(safe-area-inset-bottom, 0px));
|
|
1671
1511
|
transform: translateX(-50%);
|
|
1672
|
-
width: calc(
|
|
1673
|
-
max-width: 780px;
|
|
1512
|
+
width: min(960px, calc(100vw - 96px));
|
|
1674
1513
|
padding: 10px 12px 10px 14px;
|
|
1675
1514
|
border: 1px solid var(--border);
|
|
1676
1515
|
border-radius: 22px;
|
|
@@ -1681,8 +1520,6 @@ const styles = `
|
|
|
1681
1520
|
z-index: 20;
|
|
1682
1521
|
}
|
|
1683
1522
|
|
|
1684
|
-
.composer-card .composer-copy { display: none; }
|
|
1685
|
-
|
|
1686
1523
|
.composer-form {
|
|
1687
1524
|
display: flex;
|
|
1688
1525
|
flex-direction: column;
|
|
@@ -1691,7 +1528,7 @@ const styles = `
|
|
|
1691
1528
|
|
|
1692
1529
|
.jump-latest-btn {
|
|
1693
1530
|
position: fixed;
|
|
1694
|
-
left:
|
|
1531
|
+
left: calc(72px + (100vw - 72px) / 2);
|
|
1695
1532
|
bottom: calc(env(safe-area-inset-bottom, 0px) + 120px);
|
|
1696
1533
|
z-index: 25;
|
|
1697
1534
|
width: 42px;
|
|
@@ -1799,16 +1636,25 @@ const styles = `
|
|
|
1799
1636
|
|
|
1800
1637
|
/* ── Responsive ───────────────────────────────────────────────────────── */
|
|
1801
1638
|
|
|
1802
|
-
@media (max-width:
|
|
1803
|
-
|
|
1639
|
+
@media (max-width: 900px) {
|
|
1640
|
+
.composer-card {
|
|
1641
|
+
left: 50%;
|
|
1642
|
+
width: min(960px, calc(100vw - 24px));
|
|
1643
|
+
}
|
|
1644
|
+
.jump-latest-btn { left: 50%; }
|
|
1645
|
+
}
|
|
1804
1646
|
|
|
1805
|
-
|
|
1647
|
+
@media (max-width: 600px) {
|
|
1648
|
+
body { padding-bottom: calc(130px + env(safe-area-inset-bottom, 0px)); }
|
|
1806
1649
|
|
|
1807
|
-
.
|
|
1650
|
+
.composer-card {
|
|
1651
|
+
width: calc(100vw - 16px);
|
|
1652
|
+
bottom: calc(8px + env(safe-area-inset-bottom, 0px));
|
|
1653
|
+
padding: 8px 10px;
|
|
1654
|
+
border-radius: 18px;
|
|
1655
|
+
}
|
|
1808
1656
|
|
|
1809
|
-
.
|
|
1810
|
-
.hero-side { align-items: flex-start; }
|
|
1811
|
-
.hero-detail-row { gap: 8px; }
|
|
1657
|
+
.session-side { align-items: flex-start; flex-direction: row; }
|
|
1812
1658
|
|
|
1813
1659
|
.user-bubble,
|
|
1814
1660
|
.msg-assistant,
|