@khorsheed/dsh-mobile 0.1.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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.i18n.yaml +6 -0
  3. package/README.md +132 -0
  4. package/README.zh.md +132 -0
  5. package/cordis.patch.yml +3 -0
  6. package/examples/https-ingress.mjs +84 -0
  7. package/examples/safari-stream-compat.mjs +98 -0
  8. package/lib/client.js +6138 -0
  9. package/lib/index.js +172 -0
  10. package/lib/invariant.js +20 -0
  11. package/lib/types/client/ConnectPhone.d.ts +9 -0
  12. package/lib/types/client/ConnectPhone.js +83 -0
  13. package/lib/types/client/DirectoryFlow.d.ts +14 -0
  14. package/lib/types/client/DirectoryFlow.js +75 -0
  15. package/lib/types/client/MobileChrome.d.ts +15 -0
  16. package/lib/types/client/MobileChrome.js +124 -0
  17. package/lib/types/client/MobileIcon.d.ts +6 -0
  18. package/lib/types/client/MobileIcon.js +16 -0
  19. package/lib/types/client/MobileLibrary.d.ts +13 -0
  20. package/lib/types/client/MobileLibrary.js +73 -0
  21. package/lib/types/client/MobileQueue.d.ts +9 -0
  22. package/lib/types/client/MobileQueue.js +90 -0
  23. package/lib/types/client/MobileRooms.d.ts +13 -0
  24. package/lib/types/client/MobileRooms.js +80 -0
  25. package/lib/types/client/MobileSeats.d.ts +4 -0
  26. package/lib/types/client/MobileSeats.js +5 -0
  27. package/lib/types/client/MobileTools.d.ts +7 -0
  28. package/lib/types/client/MobileTools.js +34 -0
  29. package/lib/types/client/SessionRename.d.ts +10 -0
  30. package/lib/types/client/SessionRename.js +43 -0
  31. package/lib/types/client/SubmissionFocus.d.ts +26 -0
  32. package/lib/types/client/SubmissionFocus.js +74 -0
  33. package/lib/types/client/composerActions.d.ts +24 -0
  34. package/lib/types/client/composerActions.js +66 -0
  35. package/lib/types/client/composerFocus.d.ts +15 -0
  36. package/lib/types/client/composerFocus.js +41 -0
  37. package/lib/types/client/directory.d.ts +17 -0
  38. package/lib/types/client/directory.js +54 -0
  39. package/lib/types/client/foreground.d.ts +4 -0
  40. package/lib/types/client/foreground.js +47 -0
  41. package/lib/types/client/gestures.d.ts +4 -0
  42. package/lib/types/client/gestures.js +118 -0
  43. package/lib/types/client/index.d.ts +20 -0
  44. package/lib/types/client/index.js +144 -0
  45. package/lib/types/client/locales.d.ts +145 -0
  46. package/lib/types/client/locales.js +80 -0
  47. package/lib/types/client/messageMenu.d.ts +19 -0
  48. package/lib/types/client/messageMenu.js +99 -0
  49. package/lib/types/client/native.d.ts +6 -0
  50. package/lib/types/client/native.js +15 -0
  51. package/lib/types/client/navigation.d.ts +41 -0
  52. package/lib/types/client/navigation.js +61 -0
  53. package/lib/types/client/pickers.d.ts +17 -0
  54. package/lib/types/client/pickers.js +109 -0
  55. package/lib/types/client/presentation.d.ts +38 -0
  56. package/lib/types/client/presentation.js +146 -0
  57. package/lib/types/client/queue.d.ts +47 -0
  58. package/lib/types/client/queue.js +26 -0
  59. package/lib/types/client/roomActions.d.ts +6 -0
  60. package/lib/types/client/roomActions.js +41 -0
  61. package/lib/types/client/rooms.d.ts +44 -0
  62. package/lib/types/client/rooms.js +75 -0
  63. package/lib/types/client/styles.d.ts +4 -0
  64. package/lib/types/client/styles.js +434 -0
  65. package/lib/types/client/surface.d.ts +17 -0
  66. package/lib/types/client/surface.js +112 -0
  67. package/lib/types/client/viewport.d.ts +13 -0
  68. package/lib/types/client/viewport.js +42 -0
  69. package/lib/types/connect.d.ts +7 -0
  70. package/lib/types/connect.js +61 -0
  71. package/lib/types/directories.d.ts +5 -0
  72. package/lib/types/directories.js +39 -0
  73. package/lib/types/index.d.ts +9 -0
  74. package/lib/types/index.js +21 -0
  75. package/lib/types/invariant.d.ts +16 -0
  76. package/lib/types/invariant.js +17 -0
  77. package/lib/types/protocol.d.ts +30 -0
  78. package/lib/types/protocol.js +17 -0
  79. package/locale/en.json +1 -0
  80. package/locale/zh.json +1 -0
  81. package/package.json +102 -0
@@ -0,0 +1,434 @@
1
+ export const ORDINARY_TITLE = '[data-slot="main.conversation"] header:has([data-conversation-header-corner]) nav:has(> span:only-child > button:disabled + [data-slot="conversation.session.header.lineage"]:empty)';
2
+ /** Local overrides target official slot anchors; frame attributes are verified before activation. */
3
+ export const MOBILE_CSS = `
4
+ html[data-dsh-mobile] { --mobile-bar: 56px; --mobile-accent: #4d6bfe; }
5
+ html[data-dsh-mobile] body { overscroll-behavior: none; }
6
+ html[data-dsh-mobile] [data-mobile-frame] {
7
+ background: var(--dsw-alias-bg-base, #fff);
8
+ box-sizing: border-box; height: var(--mobile-height, 100dvh) !important;
9
+ padding-top: var(--mobile-bar); padding-bottom: env(safe-area-inset-bottom, 0px);
10
+ grid-template-columns: 0px minmax(0, 1fr) 0px !important;
11
+ grid-template-rows: minmax(0, 1fr); transition: none !important;
12
+ }
13
+ html[data-dsh-mobile] [data-mobile-frame] > div:has(> [data-slot="sidebar"]) {
14
+ position: absolute; inset: var(--mobile-bar) auto 0 0; z-index: 22;
15
+ width: min(88vw, 360px); border-radius: 0 24px 24px 0;
16
+ box-shadow: 16px 0 60px #15244320;
17
+ }
18
+ html[data-dsh-mobile] [data-mobile-frame][data-sidebar-collapsed] > div:has(> [data-slot="sidebar"]) { display: none; }
19
+ html[data-dsh-mobile] [data-mobile-frame] > div:has(> [data-slot="main"]) { grid-column: 2; grid-row: 1; min-width: 0; }
20
+ html[data-dsh-mobile] [data-mobile-frame] > [data-rightbar-col] { grid-column: 3; grid-row: 1; }
21
+ html[data-dsh-mobile] [data-mobile-frame]:not([data-rightbar-collapsed]) > [data-rightbar-col] {
22
+ position: absolute; inset: var(--mobile-bar) 0 0; z-index: 24; width: 100%;
23
+ background: var(--dsw-alias-bg-base, white); min-width: 0;
24
+ }
25
+ html[data-dsh-mobile] [data-mobile-frame] > [data-side] { display: none; }
26
+ html[data-dsh-mobile] [data-mobile-frame] > [data-shell-overlay] { z-index: 23; pointer-events: none; }
27
+ html[data-dsh-mobile] [data-slot="main.conversation"] > div {
28
+ --dsh-chat-content-width: calc(100vw - 48px);
29
+ --dsh-composer-side-clearance: 12px;
30
+ }
31
+ html[data-dsh-mobile] [data-composer-card] { border-radius: 24px; }
32
+ html[data-dsh-mobile] [data-composer-card] [contenteditable="true"] { font-size: 16px; }
33
+ html[data-dsh-mobile] [data-width-handle] { display: none; }
34
+ html[data-dsh-mobile] [data-composer-seat] { padding-bottom: 8px; }
35
+ html[data-dsh-mobile] [data-conversation-scroll] { overscroll-behavior-y: contain; }
36
+ html[data-dsh-mobile] [data-slot="conversation.header.tabs"] { overflow-x: auto; }
37
+ html[data-dsh-mobile] [data-slot="conversation.input.left"],
38
+ html[data-dsh-mobile] [data-slot="conversation.input.right"] { max-width: 100%; }
39
+ [data-mobile-toolbar] {
40
+ position: absolute; inset: 0 0 auto; height: var(--mobile-bar, 56px); display: flex;
41
+ align-items: center; justify-content: space-between; gap: 8px; padding: 0 12px;
42
+ box-sizing: border-box; background: var(--dsw-alias-bg-base, #fff);
43
+ border-bottom: 1px solid var(--dsw-alias-border-l3, #edf0f5); pointer-events: auto;
44
+ }
45
+ [data-mobile-toolbar] button, [data-mobile-dialog] button {
46
+ border: 0; border-radius: 16px; min-height: 44px; min-width: 44px;
47
+ padding: 10px 14px; font: inherit; cursor: pointer;
48
+ color: var(--dsw-alias-label-primary, #152443); background: transparent;
49
+ -webkit-tap-highlight-color: transparent;
50
+ }
51
+ [data-mobile-toolbar] button:hover, [data-mobile-dialog] button:hover { background: #4d6bfe12; }
52
+ [data-mobile-toolbar] strong { font-size: 18px; font-weight: 600; letter-spacing: -0.6px; color: var(--mobile-accent, #4d6bfe); }
53
+ [data-mobile-toolbar] small { color: var(--dsw-alias-label-tertiary, #778195); font-size: 11px; display: block; text-align: center; }
54
+ [data-mobile-toolbar] svg { display: block; }
55
+ [data-mobile-shade] { position: absolute; inset: var(--mobile-bar) 0 0 min(88vw, 360px); border: 0; background: #15244330; pointer-events: auto; }
56
+ [data-mobile-dialog] {
57
+ color: var(--dsw-alias-label-primary, #152443); background: var(--dsw-alias-bg-base, white);
58
+ border: 1px solid var(--dsw-alias-border-l3, #e6eaf2); border-radius: 28px;
59
+ width: min(440px, calc(100vw - 32px)); box-sizing: border-box; padding: 24px;
60
+ max-height: calc(100dvh - 48px); overflow-y: auto; box-shadow: 0 24px 90px #15244325;
61
+ }
62
+ [data-mobile-dialog] input { box-sizing: border-box; width: 100%; margin-top: 12px; padding: 14px; border: 1px solid #ccd3df; border-radius: 14px; font: inherit; font-size: 16px; }
63
+ [data-mobile-dialog] button:disabled { opacity: .4; cursor: default; }
64
+ [data-mobile-dialog]::backdrop { background: #15244355; backdrop-filter: blur(8px); }
65
+ [data-mobile-dialog] h2 { margin: 0 0 24px; font-size: 24px; font-weight: 500; }
66
+ [data-mobile-dialog] h3 { font-size: 13px; font-weight: 500; color: var(--dsw-alias-label-tertiary, #778195); margin: 24px 0 10px; }
67
+ [data-mobile-dialog] p { font-size: 13px; line-height: 1.7; color: var(--dsw-alias-label-tertiary, #778195); overflow-wrap: anywhere; }
68
+ [data-mobile-dialog] [role="group"] { display: flex; flex-wrap: wrap; gap: 6px; }
69
+ [data-mobile-dialog] button[aria-pressed="true"] { color: #4d6bfe; background: #4d6bfe12; }
70
+ [data-mobile-dialog] [data-mobile-done] { display: block; width: 100%; margin-top: 24px; background: #4d6bfe; color: white; border-radius: 100px; }
71
+
72
+ /* Hide an empty ordinary breadcrumb; populated catalogs keep their Host trigger. */
73
+ html[data-dsh-mobile]:has([data-mobile-session-title]) ${ORDINARY_TITLE} { display:none; }
74
+ html[data-dsh-mobile] [data-mobile-lineage-count] { flex-shrink:0; white-space:nowrap; }
75
+ [data-mobile-restore] { position:fixed; right:16px; bottom:max(16px,env(safe-area-inset-bottom)); z-index:1200; pointer-events:auto; min-height:44px; padding:10px 18px; border:1px solid #4d6bfe40; border-radius:24px; background:var(--dsw-alias-bg-base,white); color:#4d6bfe; font:inherit; box-shadow:0 3px 18px #15244318; }
76
+
77
+ /* Mobile-owned library: scrolling content and a separate keyboard-aware search dock. */
78
+ [data-mobile-library] { position:absolute; inset:var(--mobile-bar,56px) 0 0; display:flex; flex-direction:column; overflow:hidden; pointer-events:auto; background:var(--dsw-alias-bg-base,white); color:var(--dsw-alias-label-primary,#181a20); }
79
+ [data-mobile-library] button { font:inherit; cursor:pointer; color:inherit; -webkit-tap-highlight-color:transparent; }
80
+ [data-mobile-library-header] { display:flex; align-items:center; justify-content:space-between; flex-shrink:0; gap:12px; padding:12px 22px 14px; }
81
+ [data-mobile-library] h1 { margin:0; font-size:30px; font-weight:600; letter-spacing:-1px; }
82
+ [data-mobile-grouping] { display:flex; padding:3px; border-radius:13px; background:var(--dsw-alias-bg-module-platform,#f2f3f6); }
83
+ [data-mobile-grouping] button { border:0; border-radius:10px; min-height:44px; padding:0 12px; font-size:12px; background:none; }
84
+ [data-mobile-grouping] button[aria-pressed=true] { background:var(--dsw-alias-button-floating-fill,white); box-shadow:0 1px 4px #17203815; }
85
+ [data-mobile-recents] { flex:1; min-height:0; overflow-y:auto; padding:0 22px 12px; overscroll-behavior:contain; }
86
+ [data-mobile-session-group] h2 { color:var(--dsw-alias-label-tertiary,#727680); font-size:12px; font-weight:500; margin:16px 0 4px; }
87
+ [data-mobile-session-group] ul { list-style:none; padding:0; margin:0; }
88
+ [data-mobile-workspace-group] { display:grid; grid-template-columns:18px minmax(0,1fr) auto 18px; align-items:center; width:100%; gap:9px; padding:14px 0; min-height:48px; text-align:left; background:none; border:0; }
89
+ [data-mobile-workspace-group] svg { display:block; }
90
+ [data-mobile-workspace-group] strong, [data-mobile-workspace-group] small { line-height:20px; margin:0; }
91
+ [data-mobile-workspace-group] strong { min-width:0; overflow-wrap:anywhere; font-size:14px; font-weight:500; }
92
+ [data-mobile-workspace-group] small { color:var(--dsw-alias-label-tertiary,#727680); font-size:12px; }
93
+ [data-mobile-session] { display:flex; align-items:center; gap:12px; width:100%; min-height:78px; padding:16px 0; text-align:left; border:0; border-bottom:1px solid var(--dsw-alias-border-l3,#e8e9ee); background:none; }
94
+ [data-mobile-session-copy] { min-width:0; flex:1; }
95
+ [data-mobile-session-copy] strong { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:16px; line-height:1.5; font-weight:500; }
96
+ [data-mobile-session-copy] small { display:block; color:var(--dsw-alias-label-tertiary,#727680); font-size:12px; margin-top:6px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
97
+ [data-mobile-session] time { font-size:11px; color:var(--dsw-alias-label-tertiary,#727680); flex-shrink:0; }
98
+ [data-mobile-session]:active { background:#4d6bfe0a; }
99
+ [data-mobile-activity] { font-size:11px; color:var(--mobile-accent,#4d6bfe); white-space:nowrap; }
100
+ [data-mobile-activity]::before { content:''; display:inline-block; width:5px; height:5px; margin-right:5px; vertical-align:middle; border-radius:50%; background:currentColor; }
101
+ [data-mobile-empty] { color:var(--dsw-alias-label-tertiary,#727680); padding:32px 0; text-align:center; font-size:14px; }
102
+ [data-mobile-search-dock] { display:flex; flex-shrink:0; align-items:center; gap:10px; padding:12px 16px max(10px,env(safe-area-inset-bottom)); background:var(--dsw-alias-bg-base,white); }
103
+ [data-mobile-search] { display:flex; flex:1; min-width:0; align-items:center; gap:8px; min-height:50px; border:1px solid var(--dsw-alias-border-l3,#e8e9ee); border-radius:28px; padding:0 16px; background:var(--dsw-alias-bg-module-platform,#f2f3f6); color:var(--dsw-alias-label-tertiary,#727680); }
104
+ [data-mobile-search] svg { flex-shrink:0; }
105
+ [data-mobile-search] input { width:100%; min-width:0; border:0; background:none; color:var(--dsw-alias-label-primary,#181a20); font:inherit; font-size:16px; padding:12px 0; }
106
+ [data-mobile-search]:focus-within { outline:2px solid #4d6bfe65; outline-offset:2px; }
107
+ [data-mobile-scan] { display:grid; place-items:center; width:50px; height:50px; flex-shrink:0; border:1px solid var(--dsw-alias-border-l3,#e8e9ee); background:var(--dsw-alias-bg-module-platform,#f2f3f6); border-radius:50%; }
108
+ [data-mobile-search-cancel] { min-height:50px; min-width:44px; color:var(--mobile-accent,#4d6bfe) !important; background:none; border:0; font-size:14px; }
109
+ [data-mobile-nav-title] { flex:1; min-width:0; text-align:center; }
110
+ [data-mobile-nav-title] strong { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--dsw-alias-label-primary,#181a20); font-size:16px; }
111
+ html[data-dsh-mobile] [data-mobile-toolbar] { border-bottom:0; padding:0 12px; }
112
+ [data-mobile-toolbar] button { color:var(--mobile-accent,#4d6bfe); }
113
+ [data-mobile-connection-status] { position:absolute; top:var(--mobile-bar); left:12px; right:12px; display:flex; align-items:center; justify-content:space-between; gap:12px; border-radius:12px; padding:0 12px; font-size:12px; background:var(--dsw-alias-bg-module-platform,#f2f3f6); pointer-events:auto; z-index:1; }
114
+ [data-mobile-connection-status] button { border:0; background:none; color:var(--mobile-accent,#4d6bfe); min-height:40px; }
115
+ html[data-dsh-mobile]:has([data-mobile-connection-status]) { --mobile-bar:96px; }
116
+ html[data-dsh-mobile]:has([data-mobile-connection-status]) [data-mobile-toolbar] { height:56px; }
117
+ html[data-dsh-mobile]:has([data-mobile-connection-status]) [data-mobile-connection-status] { top:56px; }
118
+ [data-mobile-dialog] { margin:auto 0 0; width:100%; max-width:none; max-height:75dvh; border-radius:26px 26px 0 0; padding-bottom:max(24px,env(safe-area-inset-bottom)); }
119
+ [data-mobile-dialog] [data-mobile-option] { width:100%; display:block; text-align:left; border-radius:0; border-bottom:1px solid var(--dsw-alias-border-l3,#e8e9ee); padding:14px 0; }
120
+ /* Preserve the official composer, controls, confirmations and message actions. */
121
+ html[data-dsh-mobile] [data-composer-card] { border-radius:20px; box-shadow:none; background:var(--dsw-alias-bg-module-platform,#f2f3f6); }
122
+ html[data-dsh-mobile] [data-composer-card] [data-input-scroll] { max-height:min(28dvh,220px); }
123
+ html[data-dsh-mobile] [data-composer-card] > div:last-child { flex-wrap:wrap; gap:8px; }
124
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div { flex-wrap:wrap; min-width:0; gap:6px; }
125
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div:last-child { margin-left:auto; }
126
+ html[data-dsh-mobile] [data-composer-card] > div:last-child button { min-height:44px; }
127
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] { min-width:0; max-width:min(62vw,270px); }
128
+ /* Dock the same blank-session composer; the checked hero mark anchors its optional headline. */
129
+ html[data-dsh-mobile] [data-slot="main.conversation"] [data-phase="hero"] [data-conversation-scroll] { justify-content:flex-end; }
130
+ html[data-dsh-mobile] [data-slot="main.conversation"] [data-phase="hero"] [data-composer-seat] { flex:1; min-height:0; }
131
+ html[data-dsh-mobile] [data-phase="hero"] [data-composer-seat] > div:has([data-slot="conversation.hero.brand.mark"]) { flex:1; align-self:stretch; padding-bottom:8px; }
132
+ html[data-dsh-mobile] [data-phase="hero"] [data-composer-seat] > div > div:first-child:has([data-slot="conversation.hero.brand.mark"]) { flex:1; min-height:100px; justify-content:center; }
133
+ /* rc1 semantic menu anchors, only inside the official composer/hero seats. */
134
+ html[data-dsh-mobile] :is([data-composer-card],[data-slot="conversation.hero.agentPreset"],[data-slot="conversation.hero.workspace"]) [role="menu"]:not([role="menu"] [role="menu"]) {
135
+ position:fixed !important; inset:auto 12px max(12px,env(safe-area-inset-bottom)) !important; width:auto !important; min-width:0; max-width:none; max-height:min(65dvh,520px); overflow-y:auto; border-radius:24px; padding:12px; z-index:1100;
136
+ }
137
+ html[data-dsh-mobile] :is([data-composer-card],[data-slot="conversation.hero.agentPreset"],[data-slot="conversation.hero.workspace"]) [role="menuitem"] { min-height:48px; }
138
+ /* Approved mobile visual system. Native SwiftUI owns its safe area; Safari owns its own. */
139
+ /* Resolve aliases on body: the official theme presenter publishes its palette there.
140
+ Root aliases resolve before body tokens exist and freeze their light fallbacks. */
141
+ html[data-dsh-mobile] body { --mobile-face:var(--dsw-alias-button-floating-fill,#fff); --mobile-soft:var(--dsw-alias-bg-module-platform,#f3f4f6); --mobile-line:var(--dsw-alias-border-l3,#eceef1); --mobile-accent:var(--dsw-alias-state-business-primary,#4d6bfe); --mobile-shadow:0 6px 24px #1823380b; }
142
+ html[data-mobile-native-insets] [data-mobile-frame] { padding-bottom:0; }
143
+ html[data-mobile-native-insets] :is([data-mobile-search-dock],[data-mobile-dialog]) { padding-bottom:8px; }
144
+ html[data-dsh-mobile] [data-mobile-toolbar] { height:64px; padding:8px 16px; }
145
+ html[data-dsh-mobile] { --mobile-bar:64px; }
146
+ html[data-dsh-mobile]:has([data-mobile-connection-status]) { --mobile-bar:104px; }
147
+ html[data-dsh-mobile]:has([data-mobile-connection-status]) [data-mobile-toolbar] { height:64px; }
148
+ html[data-dsh-mobile]:has([data-mobile-connection-status]) [data-mobile-connection-status] { top:64px; }
149
+ [data-mobile-toolbar] button { display:grid; place-items:center; width:44px; height:44px; padding:0; border-radius:50%; corner-shape:round; background:var(--mobile-face); box-shadow:var(--mobile-shadow); color:var(--dsw-alias-label-primary,#202226); }
150
+ [data-mobile-nav-title] strong { font-weight:500; letter-spacing:0; }
151
+ [data-mobile-library] h1 { font-size:26px; font-weight:500; letter-spacing:-.7px; }
152
+ [data-mobile-grouping] { border-radius:19px; }
153
+ [data-mobile-grouping] button { border-radius:16px; min-height:38px; }
154
+ [data-mobile-library-header] { padding:16px 20px; }
155
+ [data-mobile-recents] { padding:0 12px 12px; }
156
+ [data-mobile-workspace-group] { padding:12px 10px; color:var(--dsw-alias-label-tertiary,#74767c)!important; }
157
+ [data-mobile-workspace-group] strong { font-size:13px; font-weight:400; }
158
+ [data-mobile-session-group] h2 { padding:0 10px; }
159
+ [data-mobile-session] { border:0; border-radius:16px; padding:14px 12px; min-height:68px; }
160
+ [data-mobile-session][aria-current=page] { background:var(--mobile-soft); }
161
+ [data-mobile-session-copy] strong { font-size:15px; font-weight:400; }
162
+ [data-mobile-session-copy] small:empty { display:none; }
163
+ [data-mobile-search-dock] { padding:12px 14px max(8px,env(safe-area-inset-bottom)); gap:8px; }
164
+ [data-mobile-search] { min-height:50px; background:var(--mobile-face); border:1px solid var(--mobile-line); box-shadow:var(--mobile-shadow); }
165
+ [data-mobile-search]:focus-within { outline:none; }
166
+ [data-mobile-search] input:focus, html[data-dsh-mobile] [data-composer-card] [contenteditable]:focus { outline:none!important; box-shadow:none!important; }
167
+ [data-mobile-search] input::placeholder { color:var(--dsw-alias-label-secondary,#61666b); opacity:1; }
168
+ html[data-dsh-mobile] [data-composer-placeholder] { color:var(--dsw-alias-label-secondary,#61666b); }
169
+ [data-mobile-search] input, html[data-dsh-mobile] [data-composer-card] [contenteditable] { caret-color:var(--mobile-accent); }
170
+ html[data-mobile-input=keyboard] [data-mobile-search]:focus-within, html[data-mobile-input=keyboard] [data-composer-card]:has([contenteditable]:focus) { outline:2px solid var(--mobile-accent); outline-offset:3px; }
171
+ [data-mobile-scan], [data-mobile-search-cancel] { display:grid; place-items:center; min-width:50px; width:50px; height:50px; border:1px solid var(--mobile-line); background:var(--mobile-face); box-shadow:var(--mobile-shadow); border-radius:50%; corner-shape:round; color:var(--dsw-alias-label-primary,#202226)!important; }
172
+ html[data-dsh-mobile] [data-composer-card] { border-radius:25px; border:1px solid var(--mobile-line); background:var(--mobile-face); box-shadow:var(--mobile-shadow); }
173
+ html[data-dsh-mobile] [data-composer-card] > div:last-child { gap:4px; }
174
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div { gap:3px; }
175
+ html[data-dsh-mobile] [data-composer-card] > div:last-child button { min-height:40px; }
176
+ /* rc1's two direct toolbar buttons precede the hidden attachment input.
177
+ Scope narrowly so plugin buttons, permission menus and send retain their own states. */
178
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div:first-child > button:has(~ input[type=file][hidden]) { width:40px; height:40px; min-width:40px; padding:0; background:transparent; border-radius:50%; }
179
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div:first-child > button:has(~ input[type=file][hidden]):active:not(:disabled) { background:var(--dsw-alias-interactive-bg-active); }
180
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] { max-width:min(43vw,210px); }
181
+ html[data-dsh-mobile] [data-composer-seat] { padding-bottom:2px; }
182
+ /* The compact stats row on both host lines: 0.1.5 mounts it as
183
+ [data-composer-stats]; alpha.2 deleted that attribute and wraps the dock
184
+ (stats pills + context meter) in a real flex row directly after the card.
185
+ On 0.1.5 the sibling selector lands on the display:contents slot wrapper —
186
+ inert for padding/gap, same font-size by inheritance — so both rules stay. */
187
+ html[data-dsh-mobile] [data-composer-stats], html[data-dsh-mobile] [data-composer-card] + div { padding:4px 12px 0; gap:10px; font-size:11px; }
188
+ html[data-dsh-mobile] [data-composer-stats] button, html[data-dsh-mobile] [data-composer-card] + div button { min-height:32px; }
189
+ /* Follow the real chain fallback -> stack -> HeroShell path, not display:contents wrappers. */
190
+ html[data-dsh-mobile] [data-phase=hero] [data-composer-seat] { flex:1 0 auto; }
191
+ html[data-dsh-mobile] [data-phase=hero] [data-chain-overlay-fallback="conversation.composer"] > div:has([data-mobile-welcome]) { flex:1; align-self:stretch; padding-bottom:0; width:100%; }
192
+ html[data-dsh-mobile] [data-phase=hero] [data-chain-overlay-fallback="conversation.composer"] > div > div:has([data-mobile-welcome]) { flex:1; height:auto; min-height:160px; padding:24px 16px 40px; }
193
+ html[data-dsh-mobile] [data-phase=hero] span:has(> [data-slot="conversation.hero.brand.mark"]):has([data-mobile-welcome]) + span { display:none; }
194
+ [data-mobile-welcome] { text-align:center; }
195
+ [data-mobile-welcome] small { color:var(--mobile-accent); letter-spacing:3px; font-size:13px; }
196
+ [data-mobile-welcome] h2 { font-size:25px; font-weight:500; line-height:1.4; margin:16px 0 9px; letter-spacing:-.6px; }
197
+ [data-mobile-welcome] p { font-size:13px; line-height:1.6; margin:0; color:var(--dsw-alias-label-tertiary,#74767c); }
198
+ html[data-dsh-mobile]:has([data-phase=hero]) [data-mobile-toolbar][data-library=false] [data-mobile-new=true] { visibility:hidden; }
199
+ html[data-dsh-mobile] [data-phase=hero] div:has(> [data-slot="conversation.hero.workspace"]) { gap:6px; padding:6px 18px; flex-wrap:wrap; }
200
+ html[data-dsh-mobile] [data-phase=hero] div:has(> [data-slot="conversation.hero.workspace"]) > button, html[data-dsh-mobile] [data-slot="conversation.hero.agentPreset"] button[aria-haspopup] { border-radius:18px; min-height:40px; font-size:13px; background:var(--mobile-soft); }
201
+ /* Quiet, read-only metadata below the mobile title. */
202
+ [data-mobile-subtitle] { display:flex; justify-content:center; align-items:center; gap:5px; margin-top:3px; font-size:11px; line-height:16px; color:var(--dsw-alias-label-secondary,#61666b); }
203
+ [data-mobile-subtitle] > span:first-child { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
204
+ [data-mobile-subtitle] > span:last-child:not(:first-child) { flex-shrink:0; max-width:60%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
205
+ html[data-dsh-mobile]:has([data-mobile-session-title]) [data-mobile-header-hidden], [data-mobile-hidden-tab] { display:none!important; }
206
+ /* Fold only the identified official trigger buttons, not their menus or owners. */
207
+ [data-mobile-folded-action] { display:none!important; }
208
+ [data-mobile-tools-seat] { display:contents; }
209
+ html[data-dsh-mobile] [data-mobile-tools-open] { display:grid; place-items:center; width:44px; height:44px; min-width:44px; padding:0; border:0; border-radius:50%; corner-shape:round; color:var(--dsw-alias-label-primary); background:var(--mobile-soft); }
210
+ [data-mobile-tools-dialog] { box-sizing:border-box; margin:auto auto 0; width:min(100%,520px); max-width:100%; max-height:75dvh; overflow-y:auto; padding:16px 20px max(20px,env(safe-area-inset-bottom)); border:1px solid var(--mobile-line); border-bottom:0; border-radius:26px 26px 0 0; background:var(--mobile-face); color:var(--dsw-alias-label-primary); box-shadow:0 -8px 40px #0002; }
211
+ [data-mobile-tools-dialog]::backdrop { background:#0005; }
212
+ [data-mobile-tools-dialog] [data-mobile-tools-handle] { width:34px; height:4px; margin:0 auto 12px; border-radius:4px; background:var(--dsw-alias-label-tertiary); opacity:.5; }
213
+ [data-mobile-tools-dialog] header { display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
214
+ [data-mobile-tools-dialog] strong { font-size:16px; font-weight:500; }
215
+ [data-mobile-tools-dialog] button { font:inherit; color:inherit; cursor:pointer; border:0; background:transparent; -webkit-tap-highlight-color:transparent; }
216
+ [data-mobile-tools-dialog] button:disabled { opacity:.45; cursor:default; }
217
+ [data-mobile-tools-dialog] header button { width:44px; height:44px; display:grid; place-items:center; border-radius:50%; padding:0; }
218
+ [data-mobile-tools-grid] { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
219
+ [data-mobile-tools-grid] button { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; min-height:92px; padding:12px; border-radius:20px; background:var(--mobile-soft); font-size:14px; }
220
+ [data-mobile-tools-permission] { display:flex; align-items:center; width:100%; gap:10px; margin-top:12px; min-height:64px; padding:12px 0; text-align:left; font-size:14px!important; }
221
+ [data-mobile-tools-permission] > span { flex-shrink:0; }
222
+ [data-mobile-tools-permission] > small { margin-left:auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px; color:var(--dsw-alias-label-secondary); }
223
+ [data-mobile-tools-dialog] svg { flex:none; }
224
+ html[data-mobile-input=pointer] [data-mobile-tools-dialog] button:focus { outline:none; }
225
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div:last-child > button:has(>svg):not([aria-haspopup]) { width:44px; height:44px; min-width:44px; padding:0; border-radius:50%; corner-shape:round; transform:none; }
226
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div:last-child > button:has(>svg):not([aria-haspopup]) > svg { width:20px; height:20px; flex:none; }
227
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] { max-width:min(56vw,260px); }
228
+ /* Keep the send row on one line; 0.1.5 also seats the host context meter in it
229
+ (alpha.2 moved the meter into the dock row below the card). */
230
+ html[data-dsh-mobile] [data-composer-card] > div:last-child, html[data-dsh-mobile] [data-composer-card] > div:last-child > div:last-child { flex-wrap:nowrap; }
231
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] { min-width:0; max-width:min(43vw,210px); flex:1 1 auto; }
232
+ /* rc1's model slot uses display:contents. Size its root and restore the label
233
+ after folding the other input controls; unknown renderers keep their markup. */
234
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] > div { min-width:0; max-width:min(43vw,210px); }
235
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] > div > button[aria-haspopup="menu"]:has(> svg:first-child + span) { max-width:100%; height:44px; }
236
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] > div > button[aria-haspopup="menu"] > svg:first-child:has(+ span) { display:none; }
237
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] > div > button[aria-haspopup="menu"] > svg:first-child + span { display:block; }
238
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div:last-child > span:has(> button[aria-haspopup="dialog"] > svg > circle) { position:static; flex:0 0 auto; }
239
+ /* Translucency belongs to surfaces. Foreground colors remain fully opaque. */
240
+ html[data-dsh-mobile] body { --mobile-shadow:0 6px 22px color-mix(in srgb,var(--dsw-alias-label-primary) 9%,transparent); --mobile-glass:color-mix(in srgb,var(--mobile-face) 86%,transparent); --mobile-edge:color-mix(in srgb,var(--dsw-alias-label-primary) 14%,transparent); }
241
+ html[data-dsh-mobile] :is([data-mobile-toolbar] button,[data-mobile-scan],[data-mobile-search-cancel],[data-mobile-search],[data-mobile-tools-open],[data-composer-card]) {
242
+ background:var(--mobile-glass); border:1px solid var(--mobile-edge); box-shadow:inset 0 1px 0 color-mix(in srgb,var(--dsw-alias-label-primary) 5%,transparent),var(--mobile-shadow);
243
+ -webkit-backdrop-filter:blur(18px) saturate(1.25); backdrop-filter:blur(18px) saturate(1.25);
244
+ }
245
+ html[data-dsh-mobile] :is([data-mobile-toolbar] button,[data-mobile-scan],[data-mobile-tools-open]):active { background:var(--mobile-soft); transform:scale(.97); }
246
+ html[data-dsh-mobile] [data-mobile-icon] { flex-shrink:0; aspect-ratio:1; }
247
+ @media (prefers-reduced-transparency: reduce) { html[data-dsh-mobile] body { --mobile-glass:var(--mobile-face); } }
248
+ @supports not (backdrop-filter:blur(1px)) { html[data-dsh-mobile] body { --mobile-glass:var(--mobile-face); } }
249
+ html[data-dsh-mobile] [data-composer-card] > div:last-child > div:last-child { flex:1 1 0; justify-content:flex-end; }
250
+ html[data-dsh-mobile] [data-composer-seat] div:has(> textarea):has(> div > button[aria-label]) { border-radius:25px; background:var(--mobile-glass); border:1px solid var(--mobile-edge); box-shadow:var(--mobile-shadow); -webkit-backdrop-filter:blur(18px); backdrop-filter:blur(18px); }
251
+ html[data-dsh-mobile] [data-composer-seat] textarea { font-size:16px; max-height:26dvh; }
252
+ html[data-dsh-mobile] [data-composer-seat] div:has(> textarea) > div > button[aria-label] { width:44px; height:44px; min-width:44px; padding:0; border-radius:50%; }
253
+ html[data-dsh-mobile] [data-composer-seat]:has([data-mobile-room-queue]) [data-testid="room-queue-strip"] { display:none; }
254
+ [data-mobile-room-queue] { padding:4px 16px; }
255
+ [data-mobile-queue-pill] { border:1px solid var(--mobile-edge); background:var(--mobile-glass); border-radius:20px; padding:8px 14px; min-height:36px; color:var(--dsw-alias-label-primary); }
256
+ [data-mobile-queue-row] { padding:8px 0; border-bottom:1px solid var(--mobile-line); }
257
+ [data-mobile-queue-row] p { overflow-wrap:anywhere; white-space:pre-wrap; font-size:14px; }
258
+ [data-mobile-queue-row] button { min-height:44px; padding:8px 12px; }
259
+ [data-mobile-queue-row] textarea { width:100%; background:var(--mobile-soft); color:var(--dsw-alias-label-primary); border:1px solid var(--mobile-line); border-radius:12px; padding:8px; }
260
+ /* Mobile action surfaces retain each plugin's controls and callback semantics. */
261
+ [data-mobile-message-menu] { position:fixed; margin:0; width:240px; max-width:calc(100vw - 24px); padding:8px; border-radius:22px; border:1px solid var(--mobile-edge); background:var(--mobile-glass); color:var(--dsw-alias-label-primary); box-shadow:var(--mobile-shadow); -webkit-backdrop-filter:blur(22px); backdrop-filter:blur(22px); }
262
+ [data-mobile-message-menu]::backdrop { background:#0002; }
263
+ [data-mobile-message-menu] button { display:flex; gap:14px; align-items:center; width:100%; min-height:48px; padding:8px 14px; border:0; border-radius:14px; background:none; color:inherit; font:inherit; text-align:left; }
264
+ [data-mobile-message-menu] button:active { background:var(--mobile-soft); }
265
+ [data-mobile-message-menu] svg { width:20px; height:20px; flex:none; }
266
+ [data-mobile-message-menu] button:disabled { opacity:.45; }
267
+ [data-mobile-toolbar]:has([data-mobile-members-open]) > [data-mobile-new] { display:none; }
268
+ [data-mobile-members-open] { position:relative; }
269
+ [data-mobile-members-open] small { position:absolute; bottom:-3px; right:-2px; min-width:16px; border-radius:10px; font-size:10px; background:var(--mobile-soft); color:var(--dsw-alias-label-primary); }
270
+ [data-mobile-room-dialog] { text-align:left; line-height:1.5; }
271
+ [data-mobile-room-dialog] header button { background:var(--mobile-soft); }
272
+ [data-mobile-room-dialog] label { display:block; font-size:13px; margin:16px 0; }
273
+ [data-mobile-room-dialog] :is(input,textarea,select) { display:block; width:100%; box-sizing:border-box; border:1px solid var(--mobile-line); border-radius:14px; padding:12px; margin-top:6px; font:inherit; font-size:16px; background:var(--mobile-soft); color:var(--dsw-alias-label-primary); }
274
+ [data-mobile-room-dialog] [role=alert] { color:var(--dsw-alias-state-danger-primary,#b73535); font-size:13px; }
275
+ [data-mobile-room-hint], [data-mobile-room-dialog] details { font-size:12px; color:var(--dsw-alias-label-secondary); }
276
+ [data-mobile-room-dialog] details { overflow-wrap:anywhere; }
277
+ [data-mobile-member-row] { display:flex; align-items:center; gap:8px; padding:6px 0; }
278
+ [data-mobile-member-chat] { display:flex!important; align-items:center; flex:1; min-width:0; gap:12px; text-align:left; padding:8px 0; }
279
+ [data-mobile-member-chat]:disabled { opacity:1!important; }
280
+ [data-mobile-member-chat] > span:last-child { min-width:0; }
281
+ [data-mobile-member-chat] strong, [data-mobile-member-chat] small { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
282
+ [data-mobile-member-chat] small { font-size:12px; color:var(--dsw-alias-label-secondary); }
283
+ [data-mobile-avatar] { display:grid; place-items:center; width:42px; height:42px; flex:none; border-radius:15px; background:var(--mobile-soft); }
284
+ [data-mobile-room-dialog] [data-mobile-room-primary] { display:flex; align-items:center; justify-content:center; gap:8px; width:100%; min-height:46px; margin:18px 0 8px; border-radius:16px; background:var(--mobile-accent); color:var(--dsw-alias-bg-base); }
285
+ [data-mobile-room-dialog] :is([data-mobile-room-back],[data-mobile-room-secondary] button,[data-mobile-confirm] button) { min-height:44px; padding:8px 16px; }
286
+ [data-mobile-room-secondary] { display:flex; justify-content:space-between; }
287
+ html[data-dsh-mobile] [data-queue-dock] { max-width:100%; }
288
+ html[data-dsh-mobile] [data-queue-dock] button { min-height:40px; }
289
+ html[data-dsh-mobile] [data-slot="conversation.input.dock"] section:has(> button[aria-expanded]) > button { min-height:36px; border-radius:20px; }
290
+ html[data-dsh-mobile] [data-slot="conversation.input.dock"] section > ul[aria-label] { position:fixed; inset:auto 12px max(12px,env(safe-area-inset-bottom)); min-width:0; max-width:none; max-height:62dvh; border-radius:24px; padding:12px; z-index:1200; box-shadow:var(--mobile-shadow); }
291
+ html[data-dsh-mobile] [data-slot="conversation.input.dock"] section > ul[aria-label] button { min-height:44px; }
292
+ @media (prefers-reduced-motion: reduce) { [data-mobile-frame] * { scroll-behavior:auto !important; } }
293
+
294
+ /* One mobile reading scale; derived from host text size without writing its preference. */
295
+ html[data-dsh-mobile] body { --mobile-text:max(17px,var(--dsh-content-font-size,14px)); --mobile-caption:max(14px,var(--dsh-content-font-size-secondary,13px)); }
296
+ html[data-dsh-mobile] :is([data-mobile-library],[data-mobile-dialog],[data-mobile-tools-dialog],[data-mobile-message-menu]) { font-size:var(--mobile-text); line-height:1.55; }
297
+ html[data-dsh-mobile] :is([data-mobile-nav-title] strong,[data-mobile-session-copy] strong,[data-mobile-search] input,[data-composer-card] [contenteditable],[data-composer-seat] textarea,[data-mobile-member-chat] strong) { font-size:var(--mobile-text); line-height:1.55; }
298
+ html[data-dsh-mobile] :is([data-mobile-workspace-group] strong,[data-mobile-tools-grid] button,[data-mobile-tools-permission],[data-mobile-dialog] h3,[data-mobile-grouping] button) { font-size:16px!important; }
299
+ html[data-dsh-mobile] :is([data-mobile-subtitle],[data-mobile-nav-title] small,[data-mobile-session-copy] small,[data-mobile-session] time,[data-mobile-workspace-group] small,[data-mobile-session-group] h2,[data-mobile-activity],[data-mobile-room-hint],[data-mobile-member-chat] small,[data-mobile-tools-permission] small,[data-mobile-dialog] p) { font-size:var(--mobile-caption); line-height:1.5; color:var(--dsw-alias-label-secondary); }
300
+ html[data-dsh-mobile] [data-slot="conversation.input.model"] button { font-size:15px; }
301
+ html[data-dsh-mobile] [data-conversation-scroll] {
302
+ --dsh-content-font-size:var(--mobile-text); --dsh-content-font-size-secondary:var(--mobile-caption);
303
+ --dsw-font-markdown-base:var(--mobile-text)/1.65 var(--dsw-font-family);
304
+ --dsw-font-markdown-base-font-size:var(--mobile-text); --dsw-font-markdown-base-line-height:1.65;
305
+ --dsw-font-markdown-base-strong:600 var(--mobile-text)/1.65 var(--dsw-font-family);
306
+ --dsw-font-markdown-base-strong-font-size:var(--mobile-text);
307
+ --dsw-font-markdown-base-italic:italic var(--mobile-text)/1.65 var(--dsw-font-family);
308
+ --dsw-font-markdown-base-italic-font-size:var(--mobile-text);
309
+ }
310
+ /* All Room invite/edit entry points retain the same React form and callbacks. */
311
+ html[data-dsh-mobile] [data-mobile-header-hidden]:has([data-mobile-room-form]) { display:contents!important; }
312
+ html[data-dsh-mobile] [data-mobile-room-overlay] { position:fixed; inset:0; height:var(--mobile-height,100dvh); z-index:1400; align-items:flex-end; justify-content:center; padding:8px; box-sizing:border-box; background:#0005; -webkit-backdrop-filter:blur(5px); backdrop-filter:blur(5px); }
313
+ html[data-dsh-mobile] [data-mobile-room-form] { box-sizing:border-box; width:100%; max-width:560px; max-height:calc(var(--mobile-height,100dvh) - 24px); margin:0; gap:16px; padding:20px 20px max(16px,env(safe-area-inset-bottom)); border-radius:28px; border:1px solid var(--mobile-edge); background:var(--mobile-face); color:var(--dsw-alias-label-primary); box-shadow:var(--mobile-shadow); text-align:left; overflow-y:auto; font-size:var(--mobile-text); }
314
+ html[data-dsh-mobile] [data-mobile-room-form]::before { content:''; display:block; flex:none; width:36px; height:4px; border-radius:4px; background:var(--dsw-alias-label-secondary); opacity:.35; align-self:center; margin:-10px 0 0; }
315
+ html[data-dsh-mobile] [data-mobile-room-form] > div:first-child { font-size:21px; line-height:1.4; font-weight:600; }
316
+ html[data-dsh-mobile] [data-mobile-room-form] > div:has(> div > label) { flex-direction:column; gap:16px; }
317
+ html[data-dsh-mobile] [data-mobile-room-form] > div > div:has(>label) { gap:18px; }
318
+ html[data-dsh-mobile] [data-mobile-room-form] > div > div:has(>[data-member]) { order:-1; width:auto; }
319
+ html[data-dsh-mobile] [data-mobile-room-form] > div > div:has(>[data-member]) > span { display:none; }
320
+ html[data-dsh-mobile] [data-mobile-room-form] [data-member] { border:0; background:var(--mobile-soft); border-radius:18px; padding:14px; }
321
+ html[data-dsh-mobile] [data-mobile-room-form] [data-member] p { font-size:14px; margin:6px 0 0; }
322
+ html[data-dsh-mobile] [data-mobile-room-form] label { gap:7px; }
323
+ html[data-dsh-mobile] [data-mobile-room-form] label > span:first-child { font-size:15px; line-height:1.5; font-weight:500; color:var(--dsw-alias-label-primary); }
324
+ html[data-dsh-mobile] [data-mobile-room-form] label > span:last-child:not(:first-child), html[data-dsh-mobile] [data-mobile-room-form] [role=status] { font-size:14px; line-height:1.5; color:var(--dsw-alias-label-secondary); }
325
+ html[data-dsh-mobile] [data-mobile-room-form] :is(input,textarea,select) { box-sizing:border-box; min-width:0; min-height:48px; border-radius:14px; padding:11px 12px; font-size:17px; line-height:1.5; background:var(--mobile-soft); border:1px solid var(--mobile-edge); color:var(--dsw-alias-label-primary); }
326
+ html[data-dsh-mobile] [data-mobile-room-form] textarea { min-height:94px; resize:vertical; }
327
+ html[data-dsh-mobile] [data-mobile-room-form] button { min-height:44px; min-width:44px; font-size:16px; border-radius:14px; }
328
+ html[data-dsh-mobile] [data-mobile-room-form] summary { min-height:44px; padding:10px 0; font-size:16px; color:var(--dsw-alias-label-primary); }
329
+ html[data-dsh-mobile] [data-mobile-room-form] > div:last-child { position:sticky; bottom:-16px; background:var(--mobile-face); padding:12px 0 0; margin-top:0; display:grid; grid-template-columns:1fr 1fr; gap:12px; }
330
+ html[data-dsh-mobile] [data-mobile-room-form] [role=alert] { font-size:15px; line-height:1.5; }
331
+ html[data-dsh-mobile] [data-member] { font-size:16px; }
332
+ html[data-dsh-mobile] [data-member] button { min-height:44px; font-size:15px; }
333
+ html[data-dsh-mobile] [data-mobile-room-form] [data-member] > div:first-child > span:nth-child(2) > span:first-child { font-size:16px; }
334
+ html[data-dsh-mobile] [data-mobile-room-form] [data-member] p { color:var(--dsw-alias-label-secondary); }
335
+ html[data-dsh-mobile] [data-mobile-room-form] > div:last-child button:disabled { opacity:1; color:var(--dsw-alias-label-secondary); background:var(--mobile-soft); border:1px solid var(--mobile-edge); cursor:default; }
336
+ html[data-dsh-mobile] [data-mobile-queue-row] p { font-size:var(--mobile-text); }
337
+ html[data-dsh-mobile] [data-mobile-members-open] small { font-size:12px; min-width:18px; }
338
+
339
+ /* One viewport: the transcript alone scrolls; the official seat keeps its identity. */
340
+ html[data-dsh-mobile], html[data-dsh-mobile] body, html[data-dsh-mobile] #root { width:100%; height:100%; overflow:hidden; overscroll-behavior:none; }
341
+ html[data-dsh-mobile] [data-mobile-frame] { position:fixed; inset:var(--mobile-top,0px) 0 auto; overflow:hidden; }
342
+ html[data-dsh-mobile] [data-mobile-frame] > div:has(> [data-slot="main"]) { position:relative; min-height:0; height:100%; overflow:hidden; }
343
+ html[data-dsh-mobile] [data-slot="main.conversation"] > [data-phase] { min-height:0; overflow:hidden; --dsh-chat-content-width:calc(var(--dsh-conversation-column-width,100vw) - 48px); }
344
+ html[data-dsh-mobile] [data-phase=active] [data-conversation-scroll] { box-sizing:border-box; padding-bottom:var(--mobile-composer-height,180px); scroll-padding-bottom:12px; }
345
+ html[data-dsh-mobile] [data-phase=active] [data-composer-seat] { position:absolute; bottom:0; left:0; right:0; width:auto; padding-top:8px; padding-bottom:4px; background:var(--dsw-alias-bg-base); }
346
+ html[data-dsh-mobile] [data-phase=active] [data-conversation-scroll] > div:has(> [data-slot="conversation.session"]) { flex:1 0 auto; }
347
+ html[data-dsh-mobile] [data-phase=hero] [data-conversation-scroll] { overscroll-behavior:contain; }
348
+ html[data-dsh-mobile] [data-mobile-frame] { --mobile-pane-width:min(84vw,380px); }
349
+ [data-mobile-library-pane] { position:absolute; inset:0 auto 0 0; width:var(--mobile-pane-width,min(84vw,380px)); background:var(--dsw-alias-bg-base); pointer-events:auto; }
350
+ [data-mobile-library-pane][hidden] { display:none; }
351
+ html[data-dsh-mobile] [data-mobile-frame][data-sidebar-collapsed]:has([data-mobile-library-pane]) > div:has(> [data-slot="sidebar"]) { display:none; }
352
+ [data-mobile-library-pane] [data-mobile-library] { inset:var(--mobile-bar,64px) 0 0; }
353
+ html[data-mobile-library-open] [data-mobile-connection-status] { right:calc(100% - var(--mobile-pane-width) + 12px); }
354
+ [data-mobile-library-toolbar] { height:64px; padding:8px 16px; display:flex; align-items:center; justify-content:space-between; box-sizing:border-box; }
355
+ [data-mobile-library-toolbar] button { display:grid; place-items:center; width:44px; height:44px; padding:0; border-radius:50%; border:1px solid var(--mobile-edge); background:var(--mobile-glass); color:var(--dsw-alias-label-primary); box-shadow:var(--mobile-shadow); }
356
+ [data-mobile-library-pane] [data-mobile-library-header] { padding:12px 16px; gap:8px; }
357
+ [data-mobile-library-pane] [data-mobile-library-header] h1 { font-size:26px; }
358
+ [data-mobile-library-pane] [data-mobile-recents] { padding:0 12px 12px; }
359
+ [data-mobile-library-pane] [data-mobile-session] { padding:12px; }
360
+ [data-mobile-library-pane] [data-mobile-session] time { display:none; }
361
+ html[data-mobile-library-open] [data-mobile-frame] > div:has(> [data-slot="main"]) { transform:translate3d(var(--mobile-pane-width),0,0); border-left:1px solid var(--mobile-edge); border-radius:0 0 0 28px; }
362
+ html[data-mobile-library-open] [data-mobile-toolbar] { transform:translate3d(var(--mobile-pane-width),0,0); width:100%; border-left:1px solid var(--mobile-edge); border-radius:28px 0 0 0; }
363
+ [data-mobile-peek-close] { position:absolute; inset:0 0 0 var(--mobile-pane-width); pointer-events:auto; background:transparent; border:0; padding:0; cursor:pointer; -webkit-tap-highlight-color:transparent; z-index:30; }
364
+ @media(max-width:959px) and (prefers-reduced-motion:no-preference) {
365
+ html[data-dsh-mobile]:not([data-mobile-gesture]) [data-mobile-frame] > div:has(> [data-slot="main"]),
366
+ html[data-dsh-mobile]:not([data-mobile-gesture]) [data-mobile-toolbar] { transition:transform 220ms cubic-bezier(.2,.8,.2,1),border-radius 220ms ease; }
367
+ }
368
+ [data-mobile-title-line] { display:flex; align-items:center; justify-content:center; min-width:0; }
369
+ [data-mobile-title-line] strong { flex:0 1 auto; }
370
+ html[data-dsh-mobile] [data-mobile-rename] { display:grid; place-items:center; flex:none; width:28px; min-width:28px; height:32px; min-height:32px; padding:4px; background:none; box-shadow:none; border:0; backdrop-filter:none; }
371
+ [data-mobile-original-rename] { display:none!important; }
372
+ @media(min-width:960px) {
373
+ html[data-dsh-mobile] [data-mobile-frame] { --mobile-pane-width:320px; padding-left:320px; }
374
+ html[data-dsh-mobile] [data-mobile-library-pane][hidden] { display:block; }
375
+ html[data-dsh-mobile] [data-mobile-toolbar] { left:320px; transform:none; width:auto; right:0; border-radius:0; }
376
+ html[data-dsh-mobile] [data-mobile-frame] > div:has(> [data-slot="main"]) { left:0; transform:none; border-left:1px solid var(--mobile-edge); border-radius:0; }
377
+ html[data-dsh-mobile] [data-mobile-peek-close] { display:none; }
378
+ }
379
+
380
+ [data-mobile-picker-shade] { position:fixed; inset:0; z-index:1099; background:#0005; backdrop-filter:blur(3px); }
381
+ html[data-dsh-mobile] [data-mobile-picker] { position:fixed!important; inset:auto 0 0!important; width:min(100%,560px)!important; margin:0 auto; max-width:100%; max-height:75dvh!important; min-width:0!important; box-sizing:border-box; z-index:1100; border-radius:26px 26px 0 0; padding:16px 16px max(20px,env(safe-area-inset-bottom)); background:var(--mobile-face); color:var(--dsw-alias-label-primary); border:1px solid var(--mobile-edge); box-shadow:0 -8px 40px #0002; overflow:auto; }
382
+ [data-mobile-picker-chrome] { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:12px; padding:4px 8px 16px; }
383
+ [data-mobile-picker-chrome] strong { font-size:20px; font-weight:600; }
384
+ [data-mobile-picker-chrome] button { border:0; background:none; color:var(--mobile-accent); min-height:44px; font:inherit; font-size:16px; }
385
+ [data-mobile-picker-chrome] input { width:100%; min-height:46px; box-sizing:border-box; border:1px solid var(--mobile-edge); border-radius:16px; padding:10px 14px; font:inherit; font-size:17px; background:var(--mobile-soft); color:inherit; }
386
+ html[data-dsh-mobile] [data-mobile-picker] > [role=presentation] { max-height:none; overflow:visible; }
387
+ html[data-dsh-mobile] [data-mobile-picker] [role=menuitem] { min-height:52px; padding:12px; border-radius:14px; font-size:17px; }
388
+ html[data-dsh-mobile] [data-mobile-picker] [role=menuitem][hidden] { display:none; }
389
+ html[data-dsh-mobile] [data-mobile-picker=preset] [role=menuitem] span > span:last-child { font-size:14px; line-height:1.55; color:var(--dsw-alias-label-secondary); }
390
+
391
+ html[data-mobile-gesture] [data-mobile-library-pane][hidden] { display:block; }
392
+ html[data-mobile-gesture] [data-mobile-frame] > div:has(> [data-slot="main"]), html[data-mobile-gesture] [data-mobile-toolbar] { transform:translate3d(var(--mobile-drag-offset),0,0)!important; width:100%; }
393
+ html[data-dsh-mobile] [data-slot="main.conversation"] > [data-phase] header:has([data-conversation-header-corner]) { min-height:0; padding:6px 16px 0; }
394
+ html[data-dsh-mobile] [data-mobile-toolbar] [data-mobile-rename] { background:transparent; border:0; border-radius:0; box-shadow:none; -webkit-backdrop-filter:none; backdrop-filter:none; color:var(--dsw-alias-label-secondary); }
395
+ html[data-dsh-mobile] [data-mobile-picker=preset] [role=menuitem] > span span:first-child { font-size:17px; font-weight:500; line-height:1.5; }
396
+
397
+ /* Rename lives above the page, with a keyboard-aware viewport of its own. */
398
+ html[data-dsh-mobile] [data-mobile-rename-dialog] { position:fixed; inset:calc(var(--mobile-top,0px) + var(--mobile-height,100dvh) / 2) 0 auto; transform:translateY(-50%); margin:0 auto; max-height:calc(var(--mobile-height,100dvh) - 32px); width:min(360px,calc(100vw - 40px)); padding:24px; border-radius:26px; background:var(--mobile-face); border-color:var(--mobile-edge); }
399
+ [data-mobile-rename-dialog] h2 { font-size:20px; margin:0 0 20px; }
400
+ [data-mobile-rename-dialog] label { font-size:14px; color:var(--dsw-alias-label-secondary); }
401
+ [data-mobile-rename-dialog] input { background:var(--mobile-soft); color:var(--dsw-alias-label-primary); border-color:var(--mobile-edge); font-size:17px; margin-top:8px; }
402
+ html[data-dsh-mobile] [data-mobile-rename-dialog] input:focus { outline:none; box-shadow:0 0 0 2px color-mix(in srgb,var(--mobile-accent) 24%,transparent); border-color:var(--mobile-accent); }
403
+ [data-mobile-rename-dialog] footer { display:flex; justify-content:flex-end; gap:10px; margin-top:24px; }
404
+ [data-mobile-rename-dialog] [data-mobile-primary] { background:var(--mobile-accent); color:white; border-radius:22px; padding-inline:22px; }
405
+ html[data-dsh-mobile] [data-mobile-picker=preset] [role=menuitem] { border-radius:0; }
406
+ html[data-dsh-mobile] [data-mobile-picker=preset] [data-mobile-picker-divider] { border-top:1px solid var(--mobile-edge); margin-top:8px; padding-top:20px; }
407
+
408
+ [data-mobile-directory] { width:min(100%,520px); height:min(78dvh,720px); max-height:calc(var(--mobile-height,100dvh) - 24px); margin:auto auto 0; padding:20px 22px max(16px,env(safe-area-inset-bottom)); border-radius:28px 28px 0 0; color:var(--dsw-alias-label-primary); background:var(--mobile-face,var(--dsw-alias-bg-base)); }
409
+ [data-mobile-directory][open] { display:flex; flex-direction:column; }
410
+ [data-mobile-directory] header { display:flex; justify-content:space-between; align-items:center; flex:none; }
411
+ [data-mobile-directory] header h2 { margin:0; font-size:21px; }
412
+ [data-mobile-directory] button { font:inherit; color:inherit; cursor:pointer; background:transparent; border:0; }
413
+ [data-mobile-directory] header button { display:grid; place-items:center; width:44px; height:44px; }
414
+ [data-directory-tabs] { display:flex; gap:4px; padding:4px; margin:12px 0; border-radius:16px; background:var(--mobile-soft); flex:none; }
415
+ [data-directory-tabs] button { flex:1; min-height:42px; border-radius:12px; }
416
+ [data-directory-tabs] button[aria-pressed=true] { background:var(--mobile-face); color:var(--mobile-accent); box-shadow:0 1px 5px #0001; }
417
+ [data-directory-scroll] { min-height:0; flex:1; overflow:auto; overscroll-behavior:contain; }
418
+ [data-mobile-directory] [data-directory-row] { display:flex; gap:12px; align-items:center; width:100%; min-height:56px; padding:12px 2px; text-align:left; border-radius:0; border-bottom:1px solid var(--mobile-line); }
419
+ [data-directory-row] > span { flex:1; min-width:0; overflow-wrap:anywhere; }
420
+ [data-directory-row] strong { display:block; font-weight:500; }
421
+ [data-directory-row] small { display:block; color:var(--dsw-alias-label-secondary); font-size:13px; margin-top:4px; }
422
+ [data-directory-row] svg { flex:none; }
423
+ [data-directory-current] { display:flex; align-items:center; gap:10px; font-size:14px; padding:8px 0; overflow-wrap:anywhere; }
424
+ [data-directory-current] svg { flex:none; }
425
+ [data-directory-manual] summary { cursor:pointer; padding:8px 0; font-size:14px; color:var(--mobile-accent); }
426
+ [data-directory-path] { display:flex; align-items:center; gap:8px; }
427
+ [data-directory-path] input { min-width:0; flex:1; }
428
+ [data-mobile-directory] input { color:inherit; background:var(--mobile-soft); border-color:var(--mobile-line); margin:8px 0; }
429
+ [data-directory-location] { display:flex; align-items:center; justify-content:space-between; gap:8px; margin:8px 0; font-size:14px; }
430
+ [data-directory-location] button,[data-directory-location] label { display:flex; align-items:center; gap:6px; min-height:40px; }
431
+ [data-directory-location] input { width:18px; }
432
+ [data-mobile-directory] footer { flex:none; padding-top:10px; }
433
+ [data-mobile-directory] [data-mobile-done] { margin-top:0; background:var(--mobile-accent); color:white; min-height:48px; }
434
+ `;
@@ -0,0 +1,17 @@
1
+ /** Checked rc1 presentation anchors. No nodes move and no action callbacks change.
2
+ * Unknown header contributions retain their official presentation. */
3
+ export declare class MobileSurface {
4
+ private readonly doc;
5
+ private marks;
6
+ private preset;
7
+ private listeners;
8
+ constructor(doc: Document);
9
+ readonly getSnapshot: () => string;
10
+ readonly subscribe: (listener: () => void) => () => void;
11
+ private publish;
12
+ private mark;
13
+ sync(frame?: HTMLElement): void;
14
+ private clearMarks;
15
+ dispose(): void;
16
+ }
17
+ //# sourceMappingURL=surface.d.ts.map
@@ -0,0 +1,112 @@
1
+ /** Checked rc1 presentation anchors. No nodes move and no action callbacks change.
2
+ * Unknown header contributions retain their official presentation. */
3
+ export class MobileSurface {
4
+ doc;
5
+ marks = new Map();
6
+ preset = '';
7
+ listeners = new Set();
8
+ constructor(doc) {
9
+ this.doc = doc;
10
+ }
11
+ getSnapshot = () => this.preset;
12
+ subscribe = (listener) => { this.listeners.add(listener); return () => { this.listeners.delete(listener); }; };
13
+ publish(preset) { if (preset !== this.preset) {
14
+ this.preset = preset;
15
+ for (const listener of this.listeners)
16
+ listener();
17
+ } }
18
+ mark(el, name) {
19
+ el.setAttribute(name, '');
20
+ const names = this.marks.get(el) ?? new Set();
21
+ names.add(name);
22
+ this.marks.set(el, names);
23
+ }
24
+ sync(frame) {
25
+ this.clearMarks();
26
+ const root = frame?.querySelector('[data-slot="main.conversation"] > [data-phase]');
27
+ const row = root?.querySelector('header [data-conversation-header-corner]')?.parentElement;
28
+ const ordinary = row?.querySelector('nav > span:only-child > button:disabled + [data-slot="conversation.session.header.lineage"]:empty');
29
+ let preset = '';
30
+ if (row) {
31
+ for (const button of row.querySelectorAll('[data-slot="conversation.session.header.actions"] button[aria-label]')) {
32
+ if (/^(重命名会话|Rename session)$/.test(button.getAttribute('aria-label') ?? ''))
33
+ this.mark(button, 'data-mobile-original-rename');
34
+ }
35
+ }
36
+ if (root?.dataset.phase === 'active' && row) {
37
+ // The ordinary current title duplicates the mobile title. Compact only the
38
+ // checked count dropdown; preserve ancestor links and subagent switchers.
39
+ for (const title of row.querySelectorAll('nav > span > button:disabled')) {
40
+ const slot = title.nextElementSibling;
41
+ if (slot?.getAttribute('data-slot') !== 'conversation.session.header.lineage')
42
+ continue;
43
+ const count = slot.querySelector(':scope > div:only-child > button[aria-haspopup="tree"]');
44
+ const separator = count?.previousElementSibling;
45
+ if (!count || separator?.tagName !== 'SPAN' || separator.textContent !== '/')
46
+ continue;
47
+ this.mark(title, 'data-mobile-header-hidden');
48
+ this.mark(separator, 'data-mobile-header-hidden');
49
+ this.mark(count, 'data-mobile-lineage-count');
50
+ }
51
+ const label = row.querySelector('[data-slot="conversation.session.header.actions"] > span[title]:has(svg mask[id^="mask0_agent_preset"])');
52
+ if (label) {
53
+ preset = label.textContent?.trim() ?? '';
54
+ this.mark(label, 'data-mobile-header-hidden');
55
+ }
56
+ for (const img of row.querySelectorAll('img[src^="/open-in-app/icon/"]')) {
57
+ const split = img.closest('button')?.parentElement;
58
+ if (split && split.querySelectorAll('button').length === 2)
59
+ this.mark(split, 'data-mobile-header-hidden');
60
+ }
61
+ for (const button of row.querySelectorAll('[data-sidebar-right-expand], [data-slot="conversation.session.header.utilities"] > span > button[aria-haspopup="menu"][aria-busy]')) {
62
+ if (button.hasAttribute('data-sidebar-right-expand') || /^(更多操作|More actions)$/i.test(button.getAttribute('aria-label') ?? ''))
63
+ this.mark(button, 'data-mobile-header-hidden');
64
+ }
65
+ if (this.doc.querySelector('[data-mobile-members-open], [data-mobile-tools-open]')) {
66
+ for (const button of row.querySelectorAll('[data-slot="conversation.session.header.actions"] button')) {
67
+ if (/^(+|\+)?\s*(邀请 agent|Invite agent)$/i.test(button.textContent?.trim() ?? ''))
68
+ this.mark(button, 'data-mobile-header-hidden');
69
+ }
70
+ }
71
+ // Collapse only a fully accounted-for row. Keep any plugin action or unknown text.
72
+ const content = row.cloneNode(true);
73
+ content.querySelectorAll('[data-mobile-header-hidden], [data-mobile-original-rename], svg').forEach(el => el.remove());
74
+ if (ordinary)
75
+ content.querySelector('nav')?.remove();
76
+ if (!content.textContent?.trim() && !content.querySelector('button, input, a, img, canvas, video, iframe, [role="button"]'))
77
+ this.mark(row, 'data-mobile-header-hidden');
78
+ }
79
+ this.publish(preset);
80
+ if (root) {
81
+ const tabs = root.querySelector('header [role="tablist"]');
82
+ if (tabs) {
83
+ const trajectory = Array.from(tabs.querySelectorAll('[role="tab"]')).find(el => /^(轨迹|Trajectory)$/i.test(el.textContent?.trim() ?? ''));
84
+ if (trajectory && trajectory.getAttribute('aria-selected') !== 'true') {
85
+ this.mark(trajectory, 'data-mobile-hidden-tab');
86
+ if (tabs.querySelectorAll('[role="tab"]').length === 2)
87
+ this.mark(tabs, 'data-mobile-hidden-tab');
88
+ }
89
+ }
90
+ // Members remains the authoritative settings/removal view, also reachable
91
+ // if the mobile shortcut cannot recognize a future Room action layout.
92
+ const header = row?.parentElement;
93
+ if (header && Array.from(header.children).every(child => child.hasAttribute('data-mobile-header-hidden') || child.hasAttribute('data-mobile-hidden-tab')))
94
+ this.mark(header, 'data-mobile-header-hidden');
95
+ }
96
+ if (frame)
97
+ for (const dialog of frame.querySelectorAll('[role="dialog"][aria-modal="true"]')) {
98
+ // Room invite/edit signature: preview member, name dice, advanced cwd.
99
+ // Never style arbitrary host/plugin dialogs based on title text alone.
100
+ if (!dialog.querySelector('[data-member]') || !dialog.querySelector('details input[readonly]') || !dialog.querySelector('button[aria-label]:not([disabled])'))
101
+ continue;
102
+ this.mark(dialog, 'data-mobile-room-form');
103
+ const overlay = dialog.parentElement;
104
+ if (overlay?.getAttribute('role') === 'presentation')
105
+ this.mark(overlay, 'data-mobile-room-overlay');
106
+ }
107
+ }
108
+ clearMarks() { for (const [el, names] of this.marks)
109
+ for (const name of names)
110
+ el.removeAttribute(name); this.marks.clear(); }
111
+ dispose() { this.clearMarks(); this.publish(''); this.listeners.clear(); }
112
+ }
@@ -0,0 +1,13 @@
1
+ /** Geometry only: keep the official composer mounted and reserve its measured height. */
2
+ export declare class MobileViewport {
3
+ private readonly win;
4
+ private seat;
5
+ private root;
6
+ private readonly observer?;
7
+ private theme;
8
+ constructor(win: Window);
9
+ sync(frame?: HTMLElement): void;
10
+ private measure;
11
+ dispose(): void;
12
+ }
13
+ //# sourceMappingURL=viewport.d.ts.map