anentrypoint-design 0.0.141 → 0.0.143

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/app-shell.css CHANGED
@@ -644,17 +644,18 @@ table tr.clickable:hover td { background: var(--bg-2); }
644
644
 
645
645
  /* File Grid */
646
646
  .ds-file-grid {
647
- display: grid;
648
- grid-template-columns: 1fr;
649
- gap: var(--space-2);
647
+ display: flex;
648
+ flex-direction: column;
649
+ gap: 3px;
650
650
  }
651
651
  .ds-file-row {
652
- grid-template-columns: 24px 1fr auto;
652
+ grid-template-columns: 22px minmax(0, 1fr) auto;
653
653
  gap: 10px; padding: 10px 12px;
654
654
  font-size: var(--fs-xs);
655
655
  }
656
- .ds-file-row .name { font-size: var(--fs-sm); }
657
- .ds-file-row .size { font-size: var(--fs-micro); }
656
+ /* On mobile, fold meta under the title and keep actions inline. */
657
+ .ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
658
+ .ds-file-row .ds-file-actions { opacity: 1; }
658
659
 
659
660
  /* Chat */
660
661
  .chat-stack { max-width: 100%; min-width: 0; }
@@ -760,14 +761,9 @@ table tr.clickable:hover td { background: var(--bg-2); }
760
761
  h2, .t-h2 { font-size: clamp(20px, 4cqi, 36px); }
761
762
  h3, .t-h3 { font-size: clamp(18px, 3.5cqi, 28px); }
762
763
 
763
- /* File Grid2-3 columns on tablet */
764
- .ds-file-grid {
765
- display: grid;
766
- grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
767
- gap: var(--space-3);
768
- }
764
+ /* File listsingle column rows on tablet (cards only via data-columns) */
769
765
  .ds-file-row {
770
- grid-template-columns: 24px 1fr auto;
766
+ grid-template-columns: 24px minmax(0, 1fr) auto auto;
771
767
  gap: 12px; padding: 12px 14px;
772
768
  }
773
769
 
@@ -809,13 +805,6 @@ table tr.clickable:hover td { background: var(--bg-2); }
809
805
  Desktop Breakpoint Enhancements (1025px and up)
810
806
  ────────────────────────────────────────────────────────────────────── */
811
807
  @media (min-width: 1025px) {
812
- /* File Grid — 3-4 columns on desktop */
813
- .ds-file-grid {
814
- display: grid;
815
- grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
816
- gap: var(--space-4);
817
- }
818
-
819
808
  /* Chat Bubbles */
820
809
  .chat-stack { max-width: min(70%, 480px); }
821
810
  .chat-bubble {
@@ -844,43 +833,377 @@ table tr.clickable:hover td { background: var(--bg-2); }
844
833
  File surface — responsive grid + row layouts
845
834
  ============================================================ */
846
835
 
847
- /* Default file grid — auto-responsive with CSS Grid */
836
+ /* Default file grid — a vertical list of rows. Each row lays out its own
837
+ columns internally; the container only stacks them. Card mode (multi-column)
838
+ is opt-in via [data-columns]. */
848
839
  .ds-file-grid {
849
- display: grid;
850
- grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
851
- gap: var(--space-4);
852
- /* Responsive via container queries in media breakpoints below */
840
+ display: flex;
841
+ flex-direction: column;
842
+ gap: 4px;
853
843
  }
854
844
 
855
- /* File row — linear layout (used in list view) */
845
+ /* File row — linear layout (icon · title · meta · actions) */
856
846
  .ds-file-row {
857
- display: grid; grid-template-columns: 28px minmax(0, 1fr) auto auto;
847
+ display: grid; grid-template-columns: 26px minmax(0, 1fr) auto auto;
858
848
  gap: 14px; align-items: center;
859
- padding: 12px 18px; background: var(--bg);
849
+ padding: 11px 16px; background: var(--bg);
850
+ border: var(--bw-hair) solid transparent;
860
851
  border-radius: var(--r-2); color: var(--fg);
861
- transition: background var(--dur-snap) var(--ease);
852
+ cursor: pointer;
853
+ transition: background var(--dur-snap) var(--ease),
854
+ border-color var(--dur-snap) var(--ease),
855
+ transform var(--dur-snap) var(--ease);
856
+ }
857
+ .ds-file-row:hover {
858
+ background: var(--bg-2);
859
+ border-color: var(--rule);
860
+ }
861
+ .ds-file-row:active { transform: translateY(1px); }
862
+ .ds-file-row.active { background: var(--accent-tint); border-color: var(--accent); }
863
+ .ds-file-row[data-file-type="dir"] { border-left-width: 3px; border-left-color: var(--accent); }
864
+ .ds-file-row[data-file-type="image"] { border-left-width: 3px; border-left-color: var(--mascot); }
865
+ .ds-file-row[data-file-type="video"] { border-left-width: 3px; border-left-color: var(--purple-2); }
866
+ .ds-file-row[data-file-type="audio"] { border-left-width: 3px; border-left-color: var(--sky); }
867
+ .ds-file-row[data-file-type="code"] { border-left-width: 3px; border-left-color: var(--green-2); }
868
+ .ds-file-row[data-file-type="text"] { border-left-width: 3px; border-left-color: var(--ink-3); }
869
+ .ds-file-row[data-file-type="archive"] { border-left-width: 3px; border-left-color: var(--flame); }
870
+ .ds-file-row[data-file-type="document"] { border-left-width: 3px; border-left-color: var(--sun); }
871
+ .ds-file-row[data-file-type="symlink"] { border-left-width: 3px; border-left-color: var(--purple); }
872
+ .ds-file-row[data-file-type="other"] { border-left-width: 3px; border-left-color: var(--fg-3); }
873
+
874
+ /* Row internals — these are the classes FileRow actually renders. */
875
+ .ds-file-row .title {
876
+ font-weight: 500; font-size: var(--fs-sm);
877
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
878
+ min-width: 0;
879
+ }
880
+ .ds-file-row .code {
881
+ font-family: var(--ff-mono); font-size: var(--fs-micro);
882
+ color: var(--fg-3);
883
+ }
884
+ .ds-file-row .ds-file-meta {
885
+ font-family: var(--ff-mono); font-size: var(--fs-xs);
886
+ color: var(--fg-3); white-space: nowrap;
887
+ }
888
+
889
+ /* File icon — glyph chip, tinted per type. */
890
+ .ds-file-icon {
891
+ display: inline-flex; align-items: center; justify-content: center;
892
+ width: 26px; height: 26px; font-size: 15px; line-height: 1;
893
+ color: var(--fg-2);
862
894
  }
863
- .ds-file-row + .ds-file-row { margin-top: 3px; }
864
- .ds-file-row:hover { background: var(--bg-2); }
865
- .ds-file-row[data-file-type="dir"] { border-left: 3px solid var(--accent); padding-left: 11px; }
866
- .ds-file-row[data-file-type="image"] { border-left: 3px solid var(--mascot); padding-left: 11px; }
867
- .ds-file-row[data-file-type="video"] { border-left: 3px solid var(--purple-2); padding-left: 11px; }
868
- .ds-file-row[data-file-type="audio"] { border-left: 3px solid var(--sky); padding-left: 11px; }
869
- .ds-file-row[data-file-type="code"] { border-left: 3px solid var(--green-2); padding-left: 11px; }
870
- .ds-file-row[data-file-type="text"] { border-left: 3px solid var(--ink-3); padding-left: 11px; }
871
- .ds-file-row[data-file-type="archive"] { border-left: 3px solid var(--flame); padding-left: 11px; }
872
- .ds-file-row[data-file-type="document"] { border-left: 3px solid var(--sun); padding-left: 11px; }
873
- .ds-file-row[data-file-type="other"] { border-left: 3px solid var(--fg-3); padding-left: 11px; }
874
- .ds-file-row .name { font-weight: 500; font-size: var(--fs-sm); }
875
- .ds-file-row .size { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); }
876
- .ds-file-row .time { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); }
877
-
878
- /* File grid — data-columns attribute (explicit column override) */
895
+ .ds-file-row[data-file-type="dir"] .ds-file-icon { color: var(--accent); }
896
+ .ds-file-row[data-file-type="image"] .ds-file-icon { color: var(--mascot); }
897
+ .ds-file-row[data-file-type="video"] .ds-file-icon { color: var(--purple-2); }
898
+ .ds-file-row[data-file-type="audio"] .ds-file-icon { color: var(--sky); }
899
+ .ds-file-row[data-file-type="code"] .ds-file-icon { color: var(--green-2); }
900
+ .ds-file-row[data-file-type="archive"] .ds-file-icon { color: var(--flame); }
901
+ .ds-file-row[data-file-type="document"] .ds-file-icon { color: var(--sun); }
902
+
903
+ /* Row actions hidden until hover/focus, revealed without layout shift. */
904
+ .ds-file-actions {
905
+ display: inline-flex; gap: 2px; align-items: center;
906
+ opacity: 0; transition: opacity var(--dur-base) var(--ease);
907
+ }
908
+ .ds-file-row:hover .ds-file-actions,
909
+ .ds-file-row:focus-within .ds-file-actions { opacity: 1; }
910
+ .ds-file-act {
911
+ display: inline-flex; align-items: center; justify-content: center;
912
+ width: 28px; height: 28px; padding: 0;
913
+ background: transparent; border: 0; border-radius: var(--r-1);
914
+ color: var(--fg-3); font-size: 14px; cursor: pointer;
915
+ transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
916
+ }
917
+ .ds-file-act:hover { background: var(--bg-3); color: var(--fg); }
918
+ .ds-file-act-warn:hover { background: color-mix(in oklab, var(--warn) 18%, var(--bg)); color: var(--warn); }
919
+
920
+ /* Card mode — opt-in via data-columns; switches the list to a grid. */
921
+ .ds-file-grid[data-columns] { display: grid; gap: var(--space-3); }
879
922
  .ds-file-grid[data-columns="1"] { grid-template-columns: 1fr; }
880
923
  .ds-file-grid[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
881
924
  .ds-file-grid[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }
882
925
  .ds-file-grid[data-columns="4"] { grid-template-columns: repeat(4, 1fr); }
883
926
 
927
+ /* ============================================================
928
+ File browser surface — stage, toolbar, breadcrumb, dropzone,
929
+ upload progress, empty state, modals, preview. Authored for
930
+ fsbrowse but lives in the shared kit under .ds-247420 scope.
931
+ ============================================================ */
932
+
933
+ /* Stage — the scrollable content column. */
934
+ .ds-file-stage {
935
+ display: flex; flex-direction: column; gap: var(--space-3);
936
+ width: 100%; max-width: 920px; margin: 0 auto;
937
+ padding: var(--space-2) var(--space-3) var(--space-4);
938
+ }
939
+ /* When the stage is the app-main child, the shell already supplies top
940
+ padding — collapse the stage's own so content isn't pushed down. */
941
+ .app-main > div > .ds-file-stage,
942
+ .app-main .ds-file-stage { padding-top: 0; }
943
+
944
+ /* Breadcrumb path */
945
+ .ds-crumb-path {
946
+ display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
947
+ font-size: var(--fs-sm);
948
+ }
949
+ .ds-crumb-seg {
950
+ background: transparent; border: 0; cursor: pointer;
951
+ padding: 4px 8px; border-radius: var(--r-1);
952
+ color: var(--fg-3); font-family: inherit; font-size: var(--fs-sm);
953
+ transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
954
+ }
955
+ .ds-crumb-seg:hover { background: var(--bg-2); color: var(--fg); }
956
+ .ds-crumb-seg.leaf { color: var(--fg); font-weight: 600; }
957
+ .ds-crumb-sep { color: var(--fg-3); opacity: 0.6; user-select: none; }
958
+
959
+ /* Toolbar */
960
+ .ds-file-toolbar {
961
+ display: flex; align-items: center; justify-content: space-between;
962
+ gap: var(--space-2); flex-wrap: wrap;
963
+ }
964
+ .ds-file-toolbar-left,
965
+ .ds-file-toolbar-right {
966
+ display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
967
+ }
968
+ .ds-meta-mono {
969
+ font-family: var(--ff-mono); font-size: var(--fs-xs);
970
+ color: var(--fg-3); letter-spacing: var(--tr-caps);
971
+ }
972
+
973
+ /* Error banner — dismissible toast row. */
974
+ .ds-error-banner {
975
+ padding: 10px 14px; border-radius: var(--r-2);
976
+ background: color-mix(in oklab, var(--warn) 14%, var(--bg));
977
+ border: var(--bw-hair) solid color-mix(in oklab, var(--warn) 40%, transparent);
978
+ color: var(--warn); font-size: var(--fs-sm); cursor: pointer;
979
+ }
980
+ .ds-error-banner:hover { background: color-mix(in oklab, var(--warn) 20%, var(--bg)); }
981
+
982
+ /* Dropzone */
983
+ .ds-dropzone {
984
+ border: var(--bw-rule) dashed var(--rule);
985
+ border-radius: var(--r-3); background: var(--bg);
986
+ transition: border-color var(--dur-base) var(--ease), background var(--dur-base) var(--ease);
987
+ }
988
+ .ds-dropzone-inner {
989
+ display: flex; align-items: center; justify-content: center;
990
+ gap: var(--space-2); flex-wrap: wrap;
991
+ padding: var(--space-4) var(--space-3); text-align: center;
992
+ }
993
+ .ds-dropzone-glyph { font-size: 22px; color: var(--fg-3); }
994
+ .ds-dropzone-label { font-size: var(--fs-sm); color: var(--fg-3); }
995
+ .ds-dropzone.dragover {
996
+ border-color: var(--accent);
997
+ background: var(--accent-tint);
998
+ }
999
+ @media (prefers-reduced-motion: no-preference) {
1000
+ .ds-dropzone.dragover { animation: ds-dropzone-pulse 1.1s var(--ease) infinite; }
1001
+ }
1002
+ .ds-dropzone.dragover .ds-dropzone-glyph,
1003
+ .ds-dropzone.dragover .ds-dropzone-label { color: var(--accent); }
1004
+ @keyframes ds-dropzone-pulse {
1005
+ 0%, 100% { border-color: var(--accent); }
1006
+ 50% { border-color: color-mix(in oklab, var(--accent) 45%, transparent); }
1007
+ }
1008
+
1009
+ /* Upload progress */
1010
+ .ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
1011
+ .ds-upload-item {
1012
+ display: grid; grid-template-columns: minmax(0, 1fr) 120px 44px;
1013
+ gap: var(--space-2); align-items: center;
1014
+ padding: 8px 12px; border-radius: var(--r-2);
1015
+ background: var(--bg-2); font-size: var(--fs-xs);
1016
+ }
1017
+ .ds-upload-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1018
+ .ds-upload-bar {
1019
+ height: 6px; border-radius: var(--r-pill);
1020
+ background: var(--bg-3); overflow: hidden;
1021
+ }
1022
+ .ds-upload-fill {
1023
+ display: block; height: 100%; width: 0;
1024
+ background: var(--accent); border-radius: var(--r-pill);
1025
+ transition: width var(--dur-base) var(--ease);
1026
+ }
1027
+ .ds-upload-pct {
1028
+ font-family: var(--ff-mono); font-size: var(--fs-micro);
1029
+ color: var(--fg-3); text-align: right;
1030
+ }
1031
+ .ds-upload-item.done .ds-upload-fill { background: var(--success); }
1032
+ .ds-upload-item.done .ds-upload-pct { color: var(--success); }
1033
+ .ds-upload-item.error .ds-upload-fill { background: var(--warn); }
1034
+ .ds-upload-item.error .ds-upload-pct { color: var(--warn); }
1035
+
1036
+ /* Empty state */
1037
+ .ds-file-empty {
1038
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
1039
+ gap: var(--space-2); padding: var(--space-6) var(--space-3);
1040
+ color: var(--fg-3); text-align: center;
1041
+ }
1042
+ .ds-file-empty-glyph { font-size: 34px; opacity: 0.55; }
1043
+ .ds-file-empty-text { font-size: var(--fs-sm); }
1044
+
1045
+ /* ── Modals ───────────────────────────────────────────────── */
1046
+ .ds-modal-backdrop {
1047
+ position: fixed; inset: 0; z-index: var(--z-modal, 800);
1048
+ display: flex; align-items: center; justify-content: center;
1049
+ padding: var(--space-3);
1050
+ background: color-mix(in oklab, var(--ink) 55%, transparent);
1051
+ backdrop-filter: blur(3px);
1052
+ }
1053
+ @media (prefers-reduced-motion: no-preference) {
1054
+ .ds-modal-backdrop { animation: ds-modal-fade var(--dur-base) var(--ease); }
1055
+ }
1056
+ @keyframes ds-modal-fade { from { opacity: 0; } to { opacity: 1; } }
1057
+ .ds-modal {
1058
+ display: flex; flex-direction: column;
1059
+ width: 100%; max-width: 460px; max-height: calc(100vh - 2 * var(--space-4));
1060
+ background: var(--bg); color: var(--fg);
1061
+ border: var(--bw-hair) solid var(--rule);
1062
+ border-radius: var(--r-3); box-shadow: var(--shadow-3);
1063
+ overflow: hidden;
1064
+ }
1065
+ @media (prefers-reduced-motion: no-preference) {
1066
+ .ds-modal { animation: ds-modal-rise var(--dur-base) var(--ease); }
1067
+ }
1068
+ @keyframes ds-modal-rise {
1069
+ from { opacity: 0; transform: translateY(8px) scale(0.98); }
1070
+ to { opacity: 1; transform: none; }
1071
+ }
1072
+ .ds-modal-small { max-width: 380px; }
1073
+ .ds-modal-preview { max-width: 880px; }
1074
+ .ds-modal-head {
1075
+ padding: var(--space-3) var(--space-4);
1076
+ font-weight: 600; font-size: var(--fs-body);
1077
+ border-bottom: var(--bw-hair) solid var(--rule);
1078
+ }
1079
+ .ds-modal-body { padding: var(--space-4); overflow: auto; font-size: var(--fs-sm); }
1080
+ .ds-modal-actions {
1081
+ display: flex; justify-content: flex-end; gap: var(--space-2);
1082
+ padding: var(--space-3) var(--space-4);
1083
+ border-top: var(--bw-hair) solid var(--rule);
1084
+ }
1085
+ .ds-modal-input {
1086
+ width: 100%; padding: 10px 12px;
1087
+ background: var(--bg-2); border: var(--bw-hair) solid var(--rule);
1088
+ border-radius: var(--r-2); color: var(--fg);
1089
+ font-family: inherit; font-size: var(--fs-sm);
1090
+ }
1091
+ .ds-modal-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
1092
+ .btn-primary.danger {
1093
+ background: var(--warn);
1094
+ border-color: var(--warn);
1095
+ color: #fff;
1096
+ }
1097
+
1098
+ /* ── Preview ──────────────────────────────────────────────── */
1099
+ .ds-preview-head {
1100
+ display: flex; align-items: center; gap: var(--space-3);
1101
+ padding: var(--space-3) var(--space-4);
1102
+ border-bottom: var(--bw-hair) solid var(--rule);
1103
+ }
1104
+ .ds-preview-name {
1105
+ font-weight: 600; font-size: var(--fs-body);
1106
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
1107
+ }
1108
+ .ds-preview-meta {
1109
+ font-family: var(--ff-mono); font-size: var(--fs-xs);
1110
+ color: var(--fg-3); white-space: nowrap;
1111
+ }
1112
+ .ds-preview-actions { display: inline-flex; gap: 2px; margin-left: auto; }
1113
+ .ds-preview-body {
1114
+ flex: 1; min-height: 0; overflow: auto;
1115
+ padding: var(--space-3) var(--space-4);
1116
+ display: flex; flex-direction: column;
1117
+ }
1118
+ .ds-preview-media {
1119
+ max-width: 100%; max-height: 70vh; margin: 0 auto;
1120
+ border-radius: var(--r-2); object-fit: contain;
1121
+ }
1122
+ .ds-preview-audio { width: 100%; }
1123
+ .ds-preview-code,
1124
+ .ds-preview-text {
1125
+ margin: 0; flex: 1; min-height: 0; overflow: auto;
1126
+ padding: var(--space-3);
1127
+ background: var(--ink); color: var(--paper);
1128
+ border-radius: var(--r-2);
1129
+ font-family: var(--ff-mono); font-size: var(--fs-xs); line-height: var(--lh-base);
1130
+ white-space: pre; tab-size: 2;
1131
+ }
1132
+ .ds-preview-text { white-space: pre-wrap; word-break: break-word; }
1133
+ .ds-preview-code code, .ds-preview-text code { font: inherit; color: inherit; background: none; }
1134
+ .ds-preview-truncated {
1135
+ margin-top: var(--space-2); padding-top: var(--space-2);
1136
+ border-top: var(--bw-hair) solid color-mix(in oklab, var(--paper) 20%, transparent);
1137
+ color: var(--paper-3); font-size: var(--fs-micro);
1138
+ }
1139
+ .ds-preview-fallback {
1140
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
1141
+ gap: var(--space-2); padding: var(--space-6); color: var(--fg-3);
1142
+ }
1143
+ .ds-preview-glyph { font-size: 34px; opacity: 0.6; }
1144
+
1145
+ /* Thin scrollbars inside preview bodies. */
1146
+ .ds-preview-code, .ds-preview-text, .ds-modal-body, .ds-preview-body {
1147
+ scrollbar-width: thin;
1148
+ }
1149
+ .ds-preview-code::-webkit-scrollbar,
1150
+ .ds-preview-text::-webkit-scrollbar,
1151
+ .ds-preview-body::-webkit-scrollbar,
1152
+ .ds-modal-body::-webkit-scrollbar { width: 10px; height: 10px; }
1153
+ .ds-preview-code::-webkit-scrollbar-thumb,
1154
+ .ds-preview-text::-webkit-scrollbar-thumb {
1155
+ background: color-mix(in oklab, var(--paper) 28%, transparent);
1156
+ border-radius: var(--r-pill); border: 2px solid transparent; background-clip: padding-box;
1157
+ }
1158
+ .ds-preview-body::-webkit-scrollbar-thumb,
1159
+ .ds-modal-body::-webkit-scrollbar-thumb {
1160
+ background: var(--bg-3); border-radius: var(--r-pill);
1161
+ }
1162
+
1163
+ /* Mobile — modals go near-fullscreen, preview media shrinks. */
1164
+ @media (max-width: 560px) {
1165
+ .ds-modal { max-width: 100%; max-height: calc(100vh - 2 * var(--space-3)); }
1166
+ .ds-modal-preview { width: 100%; height: calc(100vh - 2 * var(--space-3)); max-height: none; }
1167
+ .ds-preview-media { max-height: 50vh; }
1168
+ .ds-file-stage { padding: var(--space-3) var(--space-2); }
1169
+ }
1170
+
1171
+ /* ── File browser UX affordances ──────────────────────────── */
1172
+ /* Toolbar filter input — compact search box. */
1173
+ .ds-filter-input {
1174
+ width: clamp(120px, 22vw, 220px);
1175
+ padding: 7px 12px;
1176
+ background: var(--bg-2); border: var(--bw-hair) solid var(--rule);
1177
+ border-radius: var(--r-pill); color: var(--fg);
1178
+ font-family: inherit; font-size: var(--fs-xs);
1179
+ }
1180
+ .ds-filter-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
1181
+
1182
+ /* Loading skeleton — placeholder rows while a directory loads. */
1183
+ .ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
1184
+ .ds-file-skeleton {
1185
+ height: 48px; border-radius: var(--r-2);
1186
+ background: linear-gradient(90deg,
1187
+ var(--bg) 0%, var(--bg-2) 50%, var(--bg) 100%);
1188
+ background-size: 200% 100%;
1189
+ }
1190
+ @media (prefers-reduced-motion: no-preference) {
1191
+ .ds-file-skeleton { animation: ds-skeleton-shimmer 1.2s var(--ease) infinite; }
1192
+ }
1193
+ @keyframes ds-skeleton-shimmer {
1194
+ 0% { background-position: 200% 0; }
1195
+ 100% { background-position: -200% 0; }
1196
+ }
1197
+
1198
+ /* Drag-to-move drop target highlight on a directory row. */
1199
+ .ds-file-row.ds-drop-target {
1200
+ border-color: var(--accent);
1201
+ background: var(--accent-tint);
1202
+ box-shadow: inset 0 0 0 1px var(--accent);
1203
+ }
1204
+ .ds-file-row[draggable="true"] { cursor: grab; }
1205
+ .ds-file-row[draggable="true"]:active { cursor: grabbing; }
1206
+
884
1207
  /* ============================================================
885
1208
  Theme toggle (segmented + compact) — bound to src/theme.js
886
1209
  ============================================================ */
@@ -175,7 +175,8 @@ select:focus-visible {
175
175
  outline-offset: 2px;
176
176
  }
177
177
 
178
- [data-theme="ink"] {
178
+ [data-theme="ink"],
179
+ [data-theme="dark"] {
179
180
  --bg: var(--ink);
180
181
  --bg-2: var(--ink-2);
181
182
  --bg-3: #464650;