@co0ontty/wand 1.24.0 → 1.25.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.
@@ -121,12 +121,33 @@
121
121
  }
122
122
  }
123
123
 
124
- /* ===== PWA 独立窗口模式 ===== */
125
- /* 顶部安全区:用 max() 保底,避免 iPad 横屏/Stage Manager 等 inset 为 0 的场景下贴顶,
126
- 同时为 iPadOS Stage Manager 浮动控件预留视觉缓冲 */
124
+ /* ===== 设备安全区 (notch / 状态栏 / 圆角) =====
125
+ 全局 --wand-safe-top/bottom/left/right 在所有上下文(PWA、Android APK 内嵌
126
+ WebView、普通移动浏览器、桌面) 中都可用。在没有 inset 的设备上回退到
127
+ 0px,所以不会影响桌面浏览体验。固定定位 (position: fixed) 的顶部元素
128
+ (如文件面板抽屉、各类预览/对话框) 必须自己消费这些 inset,因为它们脱离
129
+ 了 .app-container 的 padding 流。*/
130
+ :root {
131
+ --wand-safe-top: env(safe-area-inset-top, 0px);
132
+ --wand-safe-bottom: env(safe-area-inset-bottom, 0px);
133
+ --wand-safe-left: env(safe-area-inset-left, 0px);
134
+ --wand-safe-right: env(safe-area-inset-right, 0px);
135
+ --safe-bottom: env(safe-area-inset-bottom, 0px);
136
+ /* 默认与 wand-safe-top 等价; PWA / .is-pwa 下被覆盖为 max(inset, 14px) */
137
+ --pwa-safe-top: env(safe-area-inset-top, 0px);
138
+ }
139
+
140
+ /* 在普通移动浏览器 / Android WebView 边到边渲染 / 旋转后地址栏隐藏等场景下,
141
+ .app-container 同样需要消费 safe-area-inset-top, 否则 .main-header-row
142
+ 会被状态栏挡住。inset 为 0 的设备上为 0px, 不影响桌面。*/
143
+ .app-container {
144
+ padding-top: var(--wand-safe-top);
145
+ }
146
+
147
+ /* PWA 独立窗口模式: 加一个最小 14px 的视觉缓冲, 避开 iPadOS Stage Manager
148
+ 浮动控件 / iOS 状态栏底色和 UI 太贴的视觉粘连。 */
127
149
  @media (display-mode: standalone) {
128
150
  :root {
129
- --safe-bottom: env(safe-area-inset-bottom, 0px);
130
151
  --pwa-safe-top: max(env(safe-area-inset-top, 0px), 14px);
131
152
  }
132
153
  .app-container {
@@ -143,7 +164,6 @@
143
164
 
144
165
  /* iOS Safari PWA fallback (navigator.standalone adds .is-pwa via JS) */
145
166
  .is-pwa {
146
- --safe-bottom: env(safe-area-inset-bottom, 0px);
147
167
  --pwa-safe-top: max(env(safe-area-inset-top, 0px), 14px);
148
168
  }
149
169
  .is-pwa .app-container {
@@ -175,6 +195,9 @@
175
195
  text-rendering: optimizeLegibility;
176
196
  min-height: 100%;
177
197
  height: 100%;
198
+ /* 兜底背景:iOS Safari 在键盘弹起 / 地址栏收起 / 安全区时
199
+ body 可能短于 html,露出的部分必须也是奶油色,否则会看到默认白底。 */
200
+ background-color: #f6f1e8;
178
201
  }
179
202
 
180
203
  body {
@@ -666,10 +689,10 @@
666
689
  .tree-children.open { display: block; }
667
690
 
668
691
  .file-explorer-header {
669
- padding: 10px 14px 8px;
692
+ padding: 10px 14px 6px;
670
693
  display: flex;
671
694
  align-items: center;
672
- gap: 8px;
695
+ gap: 6px;
673
696
  flex-shrink: 0;
674
697
  }
675
698
 
@@ -688,11 +711,11 @@
688
711
  /* When rendered as <input> (editable path) keep the same look but reveal
689
712
  an editable affordance on hover/focus. */
690
713
  input.file-explorer-path {
691
- background: transparent;
692
- border: 1px solid transparent;
693
- border-radius: var(--radius-sm);
694
- padding: 4px 8px;
695
- height: 28px;
714
+ background: var(--bg-secondary);
715
+ border: 1px solid var(--border-subtle);
716
+ border-radius: 8px;
717
+ padding: 6px 10px;
718
+ height: 30px;
696
719
  line-height: 1.2;
697
720
  cursor: text;
698
721
  transition: background-color var(--transition-fast),
@@ -708,7 +731,7 @@
708
731
  opacity: 0.6;
709
732
  }
710
733
  input.file-explorer-path:hover {
711
- background: rgba(255, 255, 255, 0.5);
734
+ background: var(--bg-primary);
712
735
  border-color: var(--border);
713
736
  color: var(--text-secondary);
714
737
  }
@@ -717,6 +740,7 @@
717
740
  border-color: var(--accent);
718
741
  color: var(--text-primary);
719
742
  text-overflow: clip;
743
+ box-shadow: 0 0 0 3px rgba(212, 152, 99, 0.12);
720
744
  }
721
745
 
722
746
  .file-explorer-actions { display: flex; gap: 4px; margin-left: auto; flex-shrink: 0; }
@@ -751,6 +775,10 @@
751
775
  display: flex;
752
776
  flex-direction: column;
753
777
  box-shadow: -4px 0 24px rgba(0, 0, 0, 0.1);
778
+ /* 抽屉是 position:fixed, 脱离了 app-container 的 padding, 必须自己消费
779
+ 状态栏 / notch 安全区, 否则 .file-side-panel-header 会被刘海/状态栏挡住。*/
780
+ padding-top: var(--wand-safe-top);
781
+ padding-bottom: var(--wand-safe-bottom);
754
782
  }
755
783
 
756
784
  .file-side-panel.open {
@@ -788,15 +816,95 @@
788
816
  display: flex;
789
817
  align-items: center;
790
818
  justify-content: space-between;
791
- padding: 12px 16px;
792
- border-bottom: 1px solid var(--border);
819
+ padding: 12px 14px 10px;
820
+ border-bottom: 1px solid var(--border-subtle);
793
821
  flex-shrink: 0;
822
+ gap: 8px;
823
+ background: linear-gradient(
824
+ to bottom,
825
+ rgba(255, 255, 255, 0.4),
826
+ rgba(255, 255, 255, 0)
827
+ );
828
+ }
829
+
830
+ .file-side-panel-title-group {
831
+ display: flex;
832
+ align-items: center;
833
+ gap: 8px;
834
+ min-width: 0;
835
+ flex: 1;
836
+ }
837
+
838
+ .file-side-panel-icon {
839
+ display: inline-flex;
840
+ align-items: center;
841
+ justify-content: center;
842
+ color: var(--accent);
843
+ opacity: 0.85;
794
844
  }
795
845
 
796
846
  .file-side-panel-title {
797
847
  font-size: 0.875rem;
798
848
  font-weight: 600;
799
849
  color: var(--text-primary);
850
+ letter-spacing: 0.01em;
851
+ }
852
+
853
+ .file-side-panel-header-actions {
854
+ display: flex;
855
+ align-items: center;
856
+ gap: 2px;
857
+ flex-shrink: 0;
858
+ }
859
+
860
+ .file-side-panel-iconbtn {
861
+ width: 30px;
862
+ height: 30px;
863
+ display: inline-flex;
864
+ align-items: center;
865
+ justify-content: center;
866
+ padding: 0;
867
+ background: transparent;
868
+ border: 1px solid transparent;
869
+ border-radius: 8px;
870
+ color: var(--text-muted);
871
+ cursor: pointer;
872
+ transition: background var(--transition-fast),
873
+ color var(--transition-fast),
874
+ border-color var(--transition-fast),
875
+ transform var(--transition-fast);
876
+ }
877
+
878
+ .file-side-panel-iconbtn:hover {
879
+ background: var(--bg-tertiary);
880
+ color: var(--text-primary);
881
+ border-color: var(--border-subtle);
882
+ }
883
+
884
+ .file-side-panel-iconbtn:active {
885
+ transform: scale(0.94);
886
+ }
887
+
888
+ .file-side-panel-iconbtn.active {
889
+ color: var(--accent);
890
+ background: var(--accent-muted);
891
+ border-color: rgba(212, 152, 99, 0.35);
892
+ }
893
+
894
+ .file-side-panel-iconbtn.close:hover {
895
+ color: var(--text-primary);
896
+ background: rgba(220, 70, 70, 0.08);
897
+ border-color: rgba(220, 70, 70, 0.25);
898
+ }
899
+
900
+ .file-side-panel-iconbtn .wand-icon {
901
+ display: block;
902
+ }
903
+
904
+ /* The refresh icon nudges with a subtle spin on hover to reinforce its purpose. */
905
+ .file-side-panel-iconbtn:hover .wand-icon-refresh {
906
+ transform: rotate(60deg);
907
+ transition: transform 0.25s var(--ease-out-expo);
800
908
  }
801
909
 
802
910
  .file-side-panel-body {
@@ -861,30 +969,44 @@
861
969
  }
862
970
 
863
971
  .file-search-box {
864
- padding: 8px 12px;
972
+ padding: 8px 12px 10px;
865
973
  display: flex;
866
974
  align-items: center;
867
- gap: 8px;
975
+ gap: 0;
868
976
  border-bottom: 1px solid var(--border-subtle);
869
977
  flex-shrink: 0;
978
+ position: relative;
979
+ }
980
+
981
+ .file-search-icon {
982
+ position: absolute;
983
+ left: 22px;
984
+ top: 50%;
985
+ transform: translateY(-50%);
986
+ color: var(--text-muted);
987
+ pointer-events: none;
988
+ display: inline-flex;
989
+ align-items: center;
990
+ opacity: 0.7;
870
991
  }
871
992
 
872
993
  .file-search-input {
873
994
  flex: 1;
874
- padding: 6px 10px;
995
+ padding: 7px 32px 7px 30px;
875
996
  border: 1px solid var(--border);
876
- border-radius: 6px;
997
+ border-radius: 8px;
877
998
  font-size: 0.8125rem;
878
999
  font-family: var(--font-sans);
879
1000
  background: var(--bg-secondary);
880
1001
  color: var(--text-primary);
881
1002
  outline: none;
882
- transition: border-color 0.15s ease;
1003
+ transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
883
1004
  }
884
1005
 
885
1006
  .file-search-input:focus {
886
1007
  border-color: var(--accent);
887
1008
  background: var(--bg-primary);
1009
+ box-shadow: 0 0 0 3px rgba(212, 152, 99, 0.12);
888
1010
  }
889
1011
 
890
1012
  .file-search-input::placeholder {
@@ -892,20 +1014,31 @@
892
1014
  }
893
1015
 
894
1016
  .file-search-clear {
1017
+ position: absolute;
1018
+ right: 18px;
1019
+ top: 50%;
1020
+ transform: translateY(-50%);
895
1021
  background: none;
896
1022
  border: none;
897
1023
  cursor: pointer;
898
- font-size: 1rem;
899
1024
  padding: 4px;
900
- border-radius: 4px;
1025
+ width: 22px;
1026
+ height: 22px;
1027
+ border-radius: 50%;
901
1028
  color: var(--text-muted);
902
1029
  display: none;
903
1030
  align-items: center;
904
1031
  justify-content: center;
1032
+ transition: background 0.15s ease, color 0.15s ease;
1033
+ }
1034
+
1035
+ .file-search-clear:hover {
1036
+ background: var(--bg-tertiary);
1037
+ color: var(--text-primary);
905
1038
  }
906
1039
 
907
1040
  .file-search-clear.visible {
908
- display: flex;
1041
+ display: inline-flex;
909
1042
  }
910
1043
 
911
1044
  .file-search-clear:hover {
@@ -6712,7 +6845,11 @@
6712
6845
  display: flex;
6713
6846
  align-items: center;
6714
6847
  justify-content: center;
6715
- padding: 32px;
6848
+ /* 给安全区让位, 避免 iPhone notch / Dynamic Island / 横屏圆角切到模态内容 */
6849
+ padding-top: max(32px, var(--wand-safe-top));
6850
+ padding-bottom: max(32px, var(--wand-safe-bottom));
6851
+ padding-left: max(32px, var(--wand-safe-left));
6852
+ padding-right: max(32px, var(--wand-safe-right));
6716
6853
  animation: liquidBackdropIn 0.28s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
6717
6854
  }
6718
6855
 
@@ -8237,6 +8374,10 @@
8237
8374
  .app-container {
8238
8375
  min-height: 100dvh;
8239
8376
  height: 100dvh;
8377
+ /* 与 body 同步:键盘弹起时 JS 注入 --app-viewport-height,
8378
+ app-container 跟随 visualViewport 收缩,input-panel 自动贴键盘上沿;
8379
+ 键盘收起后变量被移除,回到 100dvh,input-panel 自然回到屏幕底部。 */
8380
+ height: var(--app-viewport-height, 100dvh);
8240
8381
  overflow: hidden;
8241
8382
  }
8242
8383
 
@@ -8378,7 +8519,11 @@
8378
8519
  padding-bottom: calc(6px + var(--safe-bottom, 0px) + var(--keyboard-offset, 0px));
8379
8520
  flex: 0 0 auto;
8380
8521
  margin-top: auto;
8381
- background: linear-gradient(180deg, rgba(246, 241, 232, 0.5) 0%, rgba(246, 241, 232, 0.88) 30%, rgba(246, 241, 232, 0.96) 100%);
8522
+ /* 渐变只覆盖上半段做平滑过渡,下半段用纯色铺满 safe-area 区域,
8523
+ 避免 iOS Safari 在 home indicator / 安全区域露出 html 背景。 */
8524
+ background:
8525
+ linear-gradient(180deg, rgba(246, 241, 232, 0.5) 0%, rgba(246, 241, 232, 0.88) 30%, #f6f1e8 100%),
8526
+ #f6f1e8;
8382
8527
  backdrop-filter: blur(12px);
8383
8528
  }
8384
8529
 
@@ -8706,6 +8851,9 @@
8706
8851
  /* 模态框移动端优化 */
8707
8852
  .modal-backdrop {
8708
8853
  padding: 8px;
8854
+ padding-top: max(8px, var(--wand-safe-top));
8855
+ padding-left: max(8px, var(--wand-safe-left));
8856
+ padding-right: max(8px, var(--wand-safe-right));
8709
8857
  align-items: flex-end;
8710
8858
  }
8711
8859
 
@@ -8729,10 +8877,14 @@
8729
8877
  /* 文件面板 */
8730
8878
  .main-content.file-panel-open { margin-right: 0; }
8731
8879
  .file-side-panel { width: 100%; }
8732
- .file-side-panel-header { padding: 6px 8px; min-height: 36px; }
8733
- .file-explorer-header { padding: 4px 6px; }
8734
- .file-search-box { padding: 4px; }
8735
- .file-search-input { min-height: 32px; font-size: 14px; }
8880
+ .file-side-panel-header { padding: 10px 12px; min-height: 48px; }
8881
+ .file-side-panel-iconbtn { width: 34px; height: 34px; }
8882
+ .file-explorer-header { padding: 6px 10px 4px; gap: 6px; }
8883
+ .file-explorer-up { width: 32px; height: 32px; }
8884
+ .file-search-box { padding: 6px 10px 8px; }
8885
+ .file-search-icon { left: 20px; }
8886
+ .file-search-clear { right: 16px; }
8887
+ .file-search-input { min-height: 34px; font-size: 14px; padding: 7px 32px 7px 30px; }
8736
8888
  .file-item { padding: 6px 8px; min-height: 32px; }
8737
8889
 
8738
8890
  /* 欢迎页移动端 */
@@ -10685,12 +10837,16 @@
10685
10837
  flex-shrink: 0;
10686
10838
  }
10687
10839
  .file-preview-toolbar-btn {
10688
- padding: 4px 6px;
10840
+ padding: 0 6px;
10689
10841
  font-size: 0.75rem;
10690
10842
  }
10691
10843
  .file-preview-close {
10692
- font-size: 1.375rem;
10693
- padding: 6px 10px;
10844
+ width: 34px;
10845
+ height: 34px;
10846
+ padding: 0;
10847
+ }
10848
+ .file-preview-icon {
10849
+ font-size: 1.125rem;
10694
10850
  }
10695
10851
  /* 底部安全区(小白条 / 圆角) */
10696
10852
  .file-preview-body {
@@ -10702,8 +10858,8 @@
10702
10858
  display: flex;
10703
10859
  align-items: center;
10704
10860
  gap: 12px;
10705
- padding: 10px 16px;
10706
- border-bottom: 1px solid var(--border);
10861
+ padding: 12px 18px;
10862
+ border-bottom: 1px solid var(--border-subtle);
10707
10863
  background: var(--bg-secondary);
10708
10864
  flex-shrink: 0;
10709
10865
  }
@@ -10711,57 +10867,114 @@
10711
10867
  .file-preview-title {
10712
10868
  display: flex;
10713
10869
  align-items: center;
10714
- gap: 8px;
10870
+ gap: 10px;
10715
10871
  font-size: 0.9375rem;
10716
10872
  font-weight: 600;
10717
10873
  color: var(--text-primary);
10874
+ flex: 1;
10875
+ min-width: 0;
10876
+ }
10877
+
10878
+ .file-preview-icon {
10879
+ font-size: 1.25rem;
10880
+ line-height: 1;
10718
10881
  flex-shrink: 0;
10719
10882
  }
10720
10883
 
10884
+ .file-preview-name-block {
10885
+ display: flex;
10886
+ flex-direction: column;
10887
+ gap: 2px;
10888
+ min-width: 0;
10889
+ flex: 1;
10890
+ }
10891
+
10892
+ .file-preview-name-row {
10893
+ display: flex;
10894
+ align-items: baseline;
10895
+ gap: 8px;
10896
+ min-width: 0;
10897
+ }
10898
+
10721
10899
  .file-preview-filename {
10722
10900
  overflow: hidden;
10723
10901
  text-overflow: ellipsis;
10724
10902
  white-space: nowrap;
10903
+ font-size: 0.9375rem;
10904
+ font-weight: 600;
10905
+ color: var(--text-primary);
10906
+ letter-spacing: 0.01em;
10907
+ min-width: 0;
10725
10908
  }
10726
10909
 
10727
10910
  .file-preview-path {
10728
- font-size: 0.75rem;
10911
+ font-size: 0.7rem;
10729
10912
  color: var(--text-muted);
10730
10913
  font-family: var(--font-mono);
10731
10914
  overflow: hidden;
10732
10915
  text-overflow: ellipsis;
10733
10916
  white-space: nowrap;
10734
- flex: 1;
10735
10917
  min-width: 0;
10736
- margin: 0 12px;
10918
+ opacity: 0.8;
10919
+ }
10920
+
10921
+ .file-preview-dirty {
10922
+ font-size: 0.6875rem;
10923
+ color: #c66a1a;
10924
+ font-weight: 600;
10925
+ letter-spacing: 0.02em;
10926
+ flex-shrink: 0;
10927
+ padding: 1px 8px;
10928
+ background: rgba(198, 106, 26, 0.1);
10929
+ border: 1px solid rgba(198, 106, 26, 0.25);
10930
+ border-radius: 999px;
10931
+ animation: dirty-pulse 1.6s ease-in-out infinite;
10932
+ }
10933
+
10934
+ @keyframes dirty-pulse {
10935
+ 0%, 100% { opacity: 0.65; }
10936
+ 50% { opacity: 1; }
10737
10937
  }
10738
10938
 
10739
10939
  .file-preview-lang {
10740
- font-size: 0.75rem;
10741
- font-weight: 500;
10940
+ font-size: 0.6875rem;
10941
+ font-weight: 600;
10742
10942
  padding: 2px 8px;
10743
- border-radius: 4px;
10744
- background: var(--bg-tertiary);
10745
- color: var(--text-secondary);
10746
- border: 1px solid var(--border);
10943
+ border-radius: 999px;
10944
+ background: var(--accent-muted);
10945
+ color: var(--accent);
10946
+ border: 1px solid rgba(212, 152, 99, 0.3);
10947
+ letter-spacing: 0.04em;
10948
+ text-transform: uppercase;
10949
+ flex-shrink: 0;
10950
+ align-self: center;
10747
10951
  }
10748
10952
 
10749
10953
  .file-preview-close {
10750
10954
  background: none;
10751
- border: none;
10752
- font-size: 1.25rem;
10955
+ border: 1px solid transparent;
10753
10956
  cursor: pointer;
10754
10957
  color: var(--text-muted);
10755
- padding: 4px 8px;
10756
- border-radius: var(--radius-sm);
10757
- transition: background 0.15s, color 0.15s;
10958
+ width: 32px;
10959
+ height: 32px;
10960
+ padding: 0;
10961
+ border-radius: 8px;
10962
+ display: inline-flex;
10963
+ align-items: center;
10964
+ justify-content: center;
10965
+ transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
10758
10966
  line-height: 1;
10759
10967
  flex-shrink: 0;
10760
10968
  }
10761
10969
 
10762
10970
  .file-preview-close:hover {
10763
- background: var(--bg-tertiary);
10971
+ background: rgba(220, 70, 70, 0.08);
10764
10972
  color: var(--text-primary);
10973
+ border-color: rgba(220, 70, 70, 0.25);
10974
+ }
10975
+
10976
+ .file-preview-close:active {
10977
+ transform: scale(0.94);
10765
10978
  }
10766
10979
 
10767
10980
  .file-preview-body {
@@ -11078,31 +11291,31 @@
11078
11291
  }
11079
11292
 
11080
11293
  /* ── File explorer header extras ── */
11081
- .file-explorer-up,
11082
- .file-explorer-toggle-hidden {
11083
- background: none;
11084
- border: none;
11294
+ .file-explorer-up {
11295
+ background: transparent;
11296
+ border: 1px solid transparent;
11085
11297
  cursor: pointer;
11086
- font-size: 1rem;
11087
- padding: 4px;
11088
- width: 28px;
11089
- height: 28px;
11090
- border-radius: 6px;
11298
+ padding: 0;
11299
+ width: 30px;
11300
+ height: 30px;
11301
+ border-radius: 8px;
11091
11302
  color: var(--text-muted);
11092
- display: flex;
11303
+ display: inline-flex;
11093
11304
  align-items: center;
11094
11305
  justify-content: center;
11095
- transition: background var(--transition-fast), color var(--transition-fast);
11306
+ transition: background var(--transition-fast),
11307
+ color var(--transition-fast),
11308
+ border-color var(--transition-fast),
11309
+ transform var(--transition-fast);
11096
11310
  flex-shrink: 0;
11097
11311
  }
11098
- .file-explorer-up:hover,
11099
- .file-explorer-toggle-hidden:hover {
11312
+ .file-explorer-up:hover {
11100
11313
  background: var(--bg-tertiary);
11101
- color: var(--text-secondary);
11314
+ color: var(--text-primary);
11315
+ border-color: var(--border-subtle);
11102
11316
  }
11103
- .file-explorer-toggle-hidden.active {
11104
- color: var(--accent);
11105
- background: var(--accent-muted);
11317
+ .file-explorer-up:active {
11318
+ transform: translateY(-1px);
11106
11319
  }
11107
11320
 
11108
11321
  /* ── File tree size/meta column ── */
@@ -11194,29 +11407,127 @@
11194
11407
  margin-left: 8px;
11195
11408
  }
11196
11409
  .file-preview-toolbar-btn {
11197
- background: none;
11198
- border: 1px solid transparent;
11410
+ background: var(--bg-primary);
11411
+ border: 1px solid var(--border-subtle);
11199
11412
  cursor: pointer;
11200
- padding: 4px 8px;
11201
- min-width: 32px;
11202
- height: 28px;
11203
- border-radius: 6px;
11204
- color: var(--text-muted);
11413
+ padding: 0 8px;
11414
+ min-width: 30px;
11415
+ height: 30px;
11416
+ gap: 6px;
11417
+ border-radius: 8px;
11418
+ color: var(--text-secondary);
11205
11419
  font-size: 0.75rem;
11206
11420
  display: inline-flex;
11207
11421
  align-items: center;
11208
11422
  justify-content: center;
11209
- transition: background 0.15s, color 0.15s, border-color 0.15s;
11423
+ transition: background 0.15s, color 0.15s, border-color 0.15s,
11424
+ box-shadow 0.15s, transform 0.1s;
11210
11425
  }
11211
11426
  .file-preview-toolbar-btn:hover {
11212
11427
  background: var(--bg-tertiary);
11213
11428
  color: var(--text-primary);
11214
11429
  border-color: var(--border);
11430
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
11431
+ }
11432
+ .file-preview-toolbar-btn:active {
11433
+ transform: scale(0.95);
11434
+ }
11435
+ .file-preview-toolbar-btn:disabled {
11436
+ opacity: 0.5;
11437
+ cursor: not-allowed;
11438
+ transform: none;
11439
+ }
11440
+ .file-preview-toolbar-btn .toolbar-icon {
11441
+ display: inline-flex;
11442
+ align-items: center;
11443
+ justify-content: center;
11444
+ }
11445
+ .file-preview-toolbar-btn .toolbar-text {
11446
+ font-weight: 600;
11447
+ letter-spacing: 0.01em;
11215
11448
  }
11216
11449
  .file-preview-toolbar-btn.toolbar-active {
11217
11450
  background: var(--accent-muted);
11218
11451
  color: var(--accent);
11452
+ border-color: rgba(212, 152, 99, 0.4);
11453
+ }
11454
+ .file-preview-toolbar-btn.primary {
11455
+ background: var(--accent);
11456
+ color: #fff;
11219
11457
  border-color: var(--accent);
11458
+ box-shadow: 0 1px 2px rgba(89, 58, 32, 0.15);
11459
+ }
11460
+ .file-preview-toolbar-btn.primary:hover {
11461
+ background: #b87a47;
11462
+ border-color: #b87a47;
11463
+ color: #fff;
11464
+ box-shadow: 0 2px 6px rgba(89, 58, 32, 0.2);
11465
+ }
11466
+ .file-preview-toolbar-btn.danger {
11467
+ color: #c0392b;
11468
+ }
11469
+ .file-preview-toolbar-btn.danger:hover {
11470
+ background: rgba(220, 70, 70, 0.08);
11471
+ border-color: rgba(220, 70, 70, 0.3);
11472
+ color: #a02818;
11473
+ }
11474
+
11475
+ /* Grouped chip (e.g. font-size −/+ combo) */
11476
+ .file-preview-toolbar-group {
11477
+ display: inline-flex;
11478
+ align-items: stretch;
11479
+ border: 1px solid var(--border-subtle);
11480
+ border-radius: 8px;
11481
+ overflow: hidden;
11482
+ background: var(--bg-primary);
11483
+ }
11484
+ .file-preview-toolbar-group .file-preview-toolbar-btn {
11485
+ border: none;
11486
+ border-radius: 0;
11487
+ background: transparent;
11488
+ min-width: 28px;
11489
+ height: 28px;
11490
+ box-shadow: none;
11491
+ }
11492
+ .file-preview-toolbar-group .file-preview-toolbar-btn:hover {
11493
+ background: var(--bg-tertiary);
11494
+ }
11495
+ .file-preview-toolbar-grouplabel {
11496
+ display: inline-flex;
11497
+ align-items: center;
11498
+ justify-content: center;
11499
+ padding: 0 6px;
11500
+ color: var(--text-muted);
11501
+ border-left: 1px solid var(--border-subtle);
11502
+ border-right: 1px solid var(--border-subtle);
11503
+ background: var(--bg-secondary);
11504
+ }
11505
+
11506
+ /* In edit mode the toolbar shows only save / revert / cancel; emphasize the
11507
+ primary save action visually. */
11508
+ .file-preview-toolbar.editing {
11509
+ gap: 6px;
11510
+ }
11511
+
11512
+ /* Mobile: shrink toolbar buttons a hair so they fit. */
11513
+ @media (max-width: 768px) {
11514
+ .file-preview-toolbar-btn {
11515
+ height: 28px;
11516
+ min-width: 28px;
11517
+ padding: 0 6px;
11518
+ }
11519
+ .file-preview-toolbar-btn .toolbar-text {
11520
+ display: none;
11521
+ }
11522
+ .file-preview-toolbar-btn.primary .toolbar-text {
11523
+ display: inline-flex;
11524
+ }
11525
+ }
11526
+
11527
+ /* ── Inline file-icon glyph (header) ── */
11528
+ .wand-icon {
11529
+ flex-shrink: 0;
11530
+ vertical-align: middle;
11220
11531
  }
11221
11532
 
11222
11533
  /* ── Code preview wrap mode ── */
@@ -11225,6 +11536,50 @@
11225
11536
  word-break: break-word;
11226
11537
  }
11227
11538
 
11539
+ /* ── Code editor (inline file edit mode) ── */
11540
+ .file-preview-body.editing {
11541
+ padding: 0;
11542
+ background: var(--bg-primary);
11543
+ }
11544
+ .code-editor-wrapper {
11545
+ display: flex;
11546
+ width: 100%;
11547
+ height: 100%;
11548
+ min-height: 0;
11549
+ background: var(--bg-primary);
11550
+ }
11551
+ .code-editor-textarea {
11552
+ flex: 1;
11553
+ width: 100%;
11554
+ height: 100%;
11555
+ min-height: 0;
11556
+ box-sizing: border-box;
11557
+ padding: 16px 20px;
11558
+ margin: 0;
11559
+ border: none;
11560
+ outline: none;
11561
+ resize: none;
11562
+ font-family: var(--font-mono);
11563
+ font-size: var(--font-size-sm);
11564
+ line-height: var(--line-height);
11565
+ color: var(--text-primary);
11566
+ background: var(--bg-primary);
11567
+ tab-size: 2;
11568
+ -moz-tab-size: 2;
11569
+ white-space: pre;
11570
+ overflow: auto;
11571
+ caret-color: var(--accent);
11572
+ scrollbar-width: thin;
11573
+ scrollbar-color: var(--border-default) transparent;
11574
+ }
11575
+ .code-editor-textarea::-webkit-scrollbar { width: 8px; height: 8px; }
11576
+ .code-editor-textarea::-webkit-scrollbar-track { background: transparent; }
11577
+ .code-editor-textarea::-webkit-scrollbar-thumb { background: var(--border-default); border-radius: 4px; }
11578
+ .code-editor-textarea::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
11579
+ .code-editor-textarea:focus {
11580
+ box-shadow: inset 0 0 0 2px rgba(212, 152, 99, 0.15);
11581
+ }
11582
+
11228
11583
  /* ── Image preview ── */
11229
11584
  .file-preview-body.kind-image {
11230
11585
  display: flex;
@@ -13168,7 +13523,11 @@
13168
13523
  display: flex;
13169
13524
  align-items: center;
13170
13525
  justify-content: center;
13171
- padding: 24px;
13526
+ /* 给安全区让位, 避免对话框在 iPhone 横屏 / 小屏被刘海或 Home Indicator 切到 */
13527
+ padding-top: max(24px, var(--wand-safe-top));
13528
+ padding-bottom: max(24px, var(--wand-safe-bottom));
13529
+ padding-left: max(24px, var(--wand-safe-left));
13530
+ padding-right: max(24px, var(--wand-safe-right));
13172
13531
  background: rgba(20, 14, 8, 0.34);
13173
13532
  backdrop-filter: blur(18px) saturate(140%);
13174
13533
  -webkit-backdrop-filter: blur(18px) saturate(140%);