@symerian/symi 3.5.30 → 3.5.31

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.
@@ -865,36 +865,177 @@ body {
865
865
  which lets the substrate / cards container's overflow-y: auto
866
866
  reliably engage instead of pushing the parent.
867
867
  Combined: every mode reliably bounds to the column. */
868
+ /* ── Symframe Design Tokens (Option 1 — 3.5.31) ─────────────────────────
869
+ Exhaustive token set extracted from existing symframe CSS — every literal
870
+ value used in the symframe surface has been replaced with a var(--sf-*)
871
+ reference. Visual identity preserved exactly. Token names are numeric
872
+ (--sf-cyan-12) rather than semantic (--sf-cyan-border); semantic naming +
873
+ tier consolidation happens in Option 3 (visual harmonization).
874
+
875
+ Defined at :root so the tokens are inherited by every selector in the
876
+ symframe surface without scoping concerns. Future selectors elsewhere
877
+ in the codebase will see the tokens but won't accidentally use them.
878
+ */
879
+ :root {
880
+ /* ── Cyan accent opacities (15 distinct tiers from existing usage) ── */
881
+ --sf-cyan-04: rgba(0, 212, 255, 0.04);
882
+ --sf-cyan-05: rgba(0, 212, 255, 0.05);
883
+ --sf-cyan-06: rgba(0, 212, 255, 0.06);
884
+ --sf-cyan-08: rgba(0, 212, 255, 0.08);
885
+ --sf-cyan-10: rgba(0, 212, 255, 0.1);
886
+ --sf-cyan-12: rgba(0, 212, 255, 0.12);
887
+ --sf-cyan-14: rgba(0, 212, 255, 0.14);
888
+ --sf-cyan-15: rgba(0, 212, 255, 0.15);
889
+ --sf-cyan-18: rgba(0, 212, 255, 0.18);
890
+ --sf-cyan-20: rgba(0, 212, 255, 0.2);
891
+ --sf-cyan-25: rgba(0, 212, 255, 0.25);
892
+ --sf-cyan-32: rgba(0, 212, 255, 0.32);
893
+ --sf-cyan-35: rgba(0, 212, 255, 0.35);
894
+ --sf-cyan-45: rgba(0, 212, 255, 0.45);
895
+ --sf-cyan-50: rgba(0, 212, 255, 0.5);
896
+ --sf-cyan-55: rgba(0, 212, 255, 0.55);
897
+ --sf-cyan-60: rgba(0, 212, 255, 0.6);
898
+ --sf-cyan-65: rgba(0, 212, 255, 0.65);
899
+
900
+ /* ── White opacity tiers ── */
901
+ --sf-white-02: rgba(255, 255, 255, 0.02);
902
+ --sf-white-03: rgba(255, 255, 255, 0.03);
903
+ --sf-white-04: rgba(255, 255, 255, 0.04);
904
+ --sf-white-05: rgba(255, 255, 255, 0.05);
905
+ --sf-white-06: rgba(255, 255, 255, 0.06);
906
+ --sf-white-08: rgba(255, 255, 255, 0.08);
907
+ --sf-white-09: rgba(255, 255, 255, 0.09);
908
+ --sf-white-10: rgba(255, 255, 255, 0.1);
909
+ --sf-white-12: rgba(255, 255, 255, 0.12);
910
+
911
+ /* ── Black opacity tiers (shadows + dark fills) ── */
912
+ --sf-black-15: rgba(0, 0, 0, 0.15);
913
+ --sf-black-20: rgba(0, 0, 0, 0.2);
914
+ --sf-black-25: rgba(0, 0, 0, 0.25);
915
+ --sf-black-30: rgba(0, 0, 0, 0.3);
916
+ --sf-black-35: rgba(0, 0, 0, 0.35);
917
+ --sf-black-40: rgba(0, 0, 0, 0.4);
918
+ --sf-black-55: rgba(0, 0, 0, 0.55);
919
+
920
+ /* ── Surface fills (dark blue-tinted glass) ── */
921
+ --sf-surface-card: rgba(10, 16, 26, 0.62);
922
+ --sf-surface-menu: rgba(10, 16, 26, 0.95);
923
+
924
+ /* ── Intent palette (Stage D.1 — used by intent stripes, considering
925
+ button, AWAITING flag, producing pulse, and the substrate badges
926
+ that mirror these colors) ── */
927
+ /* amber — weighing intent + considering button */
928
+ --sf-amber-12: rgba(245, 183, 58, 0.12);
929
+ --sf-amber-32: rgba(245, 183, 58, 0.32);
930
+ /* pink — awaiting flag + considering-empty + panel-ref-miss pulse */
931
+ --sf-pink-10: rgba(244, 114, 182, 0.1);
932
+ --sf-pink-22: rgba(244, 114, 182, 0.22);
933
+ --sf-pink-55: rgba(244, 114, 182, 0.55);
934
+ --sf-pink-60: rgba(244, 114, 182, 0.6);
935
+ --sf-pink-85: rgba(244, 114, 182, 0.85);
936
+ /* green — producing intent + result reasoning badge */
937
+ --sf-green-10: rgba(52, 211, 153, 0.1);
938
+ --sf-green-18: rgba(52, 211, 153, 0.18);
939
+ --sf-green-20: rgba(52, 211, 153, 0.2);
940
+ --sf-green-55: rgba(52, 211, 153, 0.55);
941
+ --sf-green-75: rgba(52, 211, 153, 0.75);
942
+ --sf-green-100: rgba(52, 211, 153, 1);
943
+ /* violet — drafted intent + tool reasoning badge */
944
+ --sf-violet-12: rgba(139, 92, 246, 0.12);
945
+ --sf-violet-20: rgba(139, 92, 246, 0.2);
946
+ --sf-violet-22: rgba(139, 92, 246, 0.22);
947
+ --sf-violet-25: rgba(139, 92, 246, 0.25);
948
+ --sf-violet-32: rgba(139, 92, 246, 0.32);
949
+ --sf-violet-55: rgba(139, 92, 246, 0.55);
950
+
951
+ /* ── Padding / gap / margin values (px) ── */
952
+ --sf-pad-2: 2px;
953
+ --sf-pad-4: 4px;
954
+ --sf-pad-5: 5px;
955
+ --sf-pad-6: 6px;
956
+ --sf-pad-8: 8px;
957
+ --sf-pad-10: 10px;
958
+ --sf-pad-12: 12px;
959
+
960
+ /* ── Font sizes (px) ── */
961
+ --sf-text-8: 8px;
962
+ --sf-text-9: 9px;
963
+ --sf-text-10: 10px;
964
+ --sf-text-11: 11px;
965
+ --sf-text-12: 12px;
966
+ --sf-text-13: 13px;
967
+ --sf-text-16: 16px;
968
+
969
+ /* ── Border-radius (px / %) ── */
970
+ --sf-radius-2: 2px;
971
+ --sf-radius-3: 3px;
972
+ --sf-radius-4: 4px;
973
+ --sf-radius-5: 5px;
974
+ --sf-radius-6: 6px;
975
+ --sf-radius-8: 8px;
976
+ --sf-radius-10: 10px;
977
+ --sf-radius-pill: 50%;
978
+
979
+ /* ── Content bounds (height limits) ── */
980
+ --sf-bound-row: 38px;
981
+ --sf-bound-tool: 100px;
982
+ --sf-bound-detail: 120px;
983
+ --sf-bound-list: 200px;
984
+ --sf-bound-media: 280px;
985
+ --sf-bound-body: 320px;
986
+
987
+ /* ── Motion durations ── */
988
+ --sf-time-fast: 0.15s;
989
+ --sf-time-quick: 0.2s;
990
+ --sf-time-200ms: 200ms;
991
+ --sf-time-slow: 0.3s;
992
+ --sf-time-normal: 0.4s;
993
+ --sf-time-medium: 0.5s;
994
+ --sf-time-soft: 0.6s;
995
+ --sf-time-600ms: 600ms;
996
+ --sf-time-easy: 0.8s;
997
+ --sf-time-800ms: 800ms;
998
+ --sf-time-1s: 1s;
999
+ --sf-time-pulse: 1.2s;
1000
+ --sf-time-pulse-prod: 2.6s;
1001
+ --sf-time-pulse-quiet: 3.2s;
1002
+ }
1003
+
868
1004
  .symframe {
869
1005
  display: grid;
870
1006
  grid-template-rows: auto minmax(0, 1fr) auto;
871
- gap: 8px;
1007
+ gap: var(--sf-pad-8);
1008
+
872
1009
  flex: 1 1 0;
873
1010
  min-height: 0;
874
1011
  overflow: hidden;
875
1012
  }
876
1013
  .symframe-header {
877
- padding: 8px 10px 10px;
878
- border-bottom: 1px solid rgba(0, 212, 255, 0.12);
879
- margin-bottom: 4px;
1014
+ padding: var(--sf-pad-8) var(--sf-pad-10) var(--sf-pad-10);
1015
+
1016
+ border-bottom: 1px solid var(--sf-cyan-12);
1017
+ margin-bottom: var(--sf-pad-4);
1018
+
880
1019
  min-height: 0;
881
1020
  }
882
1021
  .symframe-header-row {
883
1022
  display: flex;
884
1023
  align-items: baseline;
885
1024
  justify-content: space-between;
886
- gap: 10px;
1025
+ gap: var(--sf-pad-10);
887
1026
  }
888
1027
  .symframe-title {
889
1028
  font-family: var(--font-mono);
890
- font-size: 12px;
1029
+ font-size: var(--sf-text-12);
1030
+
891
1031
  font-weight: 600;
892
1032
  letter-spacing: 0.14em;
893
1033
  color: var(--accent-cyan);
894
1034
  }
895
1035
  .symframe-count {
896
1036
  font-family: var(--font-mono);
897
- font-size: 9px;
1037
+ font-size: var(--sf-text-9);
1038
+
898
1039
  letter-spacing: 0.06em;
899
1040
  color: var(--text-dim);
900
1041
  opacity: 0.7;
@@ -902,11 +1043,13 @@ body {
902
1043
  }
903
1044
  .symframe-sub {
904
1045
  font-family: var(--font-mono);
905
- font-size: 9px;
1046
+ font-size: var(--sf-text-9);
1047
+
906
1048
  letter-spacing: 0.04em;
907
1049
  color: var(--text-dim);
908
1050
  opacity: 0.55;
909
- margin-top: 4px;
1051
+ margin-top: var(--sf-pad-4);
1052
+
910
1053
  line-height: 1.4;
911
1054
  }
912
1055
 
@@ -914,14 +1057,16 @@ body {
914
1057
  .symframe-modes {
915
1058
  display: flex;
916
1059
  align-items: center;
917
- gap: 6px;
918
- margin-top: 6px;
1060
+ gap: var(--sf-pad-6);
1061
+
1062
+ margin-top: var(--sf-pad-6);
919
1063
  }
920
1064
  .mode-chip {
921
1065
  width: 10px;
922
1066
  height: 10px;
923
- border-radius: 50%;
924
- border: 1px solid rgba(0, 212, 255, 0.32);
1067
+ border-radius: var(--sf-radius-pill);
1068
+
1069
+ border: 1px solid var(--sf-cyan-32);
925
1070
  background: transparent;
926
1071
  padding: 0;
927
1072
  cursor: pointer;
@@ -933,32 +1078,35 @@ body {
933
1078
  }
934
1079
  .mode-chip:hover {
935
1080
  border-color: var(--accent-cyan);
936
- background: rgba(0, 212, 255, 0.15);
1081
+ background: var(--sf-cyan-15);
937
1082
  transform: scale(1.15);
938
1083
  }
939
1084
  .mode-chip.active {
940
1085
  background: var(--accent-cyan);
941
1086
  border-color: var(--accent-cyan);
942
- box-shadow: 0 0 6px rgba(0, 212, 255, 0.5);
1087
+ box-shadow: 0 0 6px var(--sf-cyan-50);
943
1088
  }
944
1089
  .mode-auto {
945
1090
  margin-left: auto;
946
- padding: 2px 8px;
1091
+ padding: var(--sf-pad-2) var(--sf-pad-8);
1092
+
947
1093
  font-family: var(--font-mono);
948
- font-size: 8px;
1094
+ font-size: var(--sf-text-8);
1095
+
949
1096
  font-weight: 700;
950
1097
  letter-spacing: 0.12em;
951
1098
  color: var(--accent-cyan);
952
- background: rgba(0, 212, 255, 0.08);
953
- border: 1px solid rgba(0, 212, 255, 0.32);
954
- border-radius: 8px;
1099
+ background: var(--sf-cyan-08);
1100
+ border: 1px solid var(--sf-cyan-32);
1101
+ border-radius: var(--sf-radius-8);
1102
+
955
1103
  cursor: pointer;
956
1104
  transition:
957
1105
  background 0.15s ease,
958
1106
  color 0.15s ease;
959
1107
  }
960
1108
  .mode-auto:hover {
961
- background: rgba(0, 212, 255, 0.2);
1109
+ background: var(--sf-cyan-20);
962
1110
  color: var(--text);
963
1111
  }
964
1112
 
@@ -967,15 +1115,19 @@ body {
967
1115
  AND adds .considering-weighing to #symframe (CSS below) which dims
968
1116
  non-weighing cards for the duration. */
969
1117
  .considering-btn {
970
- margin-left: 4px;
971
- padding: 2px 7px;
972
- font-size: 11px;
1118
+ margin-left: var(--sf-pad-4);
1119
+
1120
+ padding: var(--sf-pad-2) 7px;
1121
+
1122
+ font-size: var(--sf-text-11);
1123
+
973
1124
  line-height: 1;
974
1125
  font-family: var(--font-mono);
975
1126
  color: #f5b73a; /* amber — same hue as weighing intent */
976
1127
  background: transparent;
977
- border: 1px solid rgba(245, 183, 58, 0.32);
978
- border-radius: 8px;
1128
+ border: 1px solid var(--sf-amber-32);
1129
+ border-radius: var(--sf-radius-8);
1130
+
979
1131
  cursor: pointer;
980
1132
  transition:
981
1133
  background 0.15s ease,
@@ -983,7 +1135,7 @@ body {
983
1135
  transform 0.15s ease;
984
1136
  }
985
1137
  .considering-btn:hover {
986
- background: rgba(245, 183, 58, 0.12);
1138
+ background: var(--sf-amber-12);
987
1139
  border-color: #f5b73a;
988
1140
  }
989
1141
  .considering-btn:active {
@@ -992,16 +1144,16 @@ body {
992
1144
  /* Brief red flash when clicked while no weighing cards exist —
993
1145
  tells the user "I have nothing to surface here." */
994
1146
  .considering-btn.considering-empty {
995
- animation: considering-empty-pulse 0.8s ease-out;
1147
+ animation: considering-empty-pulse var(--sf-time-easy) ease-out;
996
1148
  }
997
1149
  @keyframes considering-empty-pulse {
998
1150
  0%,
999
1151
  100% {
1000
- border-color: rgba(245, 183, 58, 0.32);
1152
+ border-color: var(--sf-amber-32);
1001
1153
  }
1002
1154
  50% {
1003
- border-color: rgba(244, 114, 182, 0.6);
1004
- background: rgba(244, 114, 182, 0.1);
1155
+ border-color: var(--sf-pink-60);
1156
+ background: var(--sf-pink-10);
1005
1157
  }
1006
1158
  }
1007
1159
  /* While considering-weighing is active, dim non-weighing cards so the
@@ -1015,14 +1167,15 @@ body {
1015
1167
  }
1016
1168
  .symframe.considering-weighing .symframe-substrate {
1017
1169
  opacity: 0.45;
1018
- transition: opacity 0.4s ease;
1170
+ transition: opacity var(--sf-time-normal) ease;
1019
1171
  }
1020
1172
  @media (prefers-reduced-motion: reduce) {
1021
1173
  .considering-btn.considering-empty {
1022
1174
  animation: none;
1023
1175
  }
1024
1176
  .symframe.considering-weighing .symframe-card-dynamic:not([data-intent="weighing"]) {
1025
- transition: opacity 0.2s ease;
1177
+ transition: opacity var(--sf-time-quick) ease;
1178
+
1026
1179
  filter: none;
1027
1180
  }
1028
1181
  }
@@ -1038,8 +1191,10 @@ body {
1038
1191
  border-bottom: 1px dashed currentColor;
1039
1192
  cursor: pointer;
1040
1193
  font-weight: 500;
1041
- padding: 0 2px;
1042
- border-radius: 3px;
1194
+ padding: 0 var(--sf-pad-2);
1195
+
1196
+ border-radius: var(--sf-radius-3);
1197
+
1043
1198
  transition:
1044
1199
  background 0.15s ease,
1045
1200
  border-bottom-style 0.15s ease;
@@ -1050,7 +1205,7 @@ body {
1050
1205
  opacity: 0.7;
1051
1206
  }
1052
1207
  .panel-ref:hover {
1053
- background: rgba(0, 212, 255, 0.12);
1208
+ background: var(--sf-cyan-12);
1054
1209
  border-bottom-style: solid;
1055
1210
  }
1056
1211
  /* Orphan reference — the card is no longer in the panel. Subdued so
@@ -1065,15 +1220,15 @@ body {
1065
1220
  /* Click-miss flash: a brief pink tint signals "I tried to dwell but
1066
1221
  that card isn't currently registered." */
1067
1222
  .panel-ref.panel-ref-miss {
1068
- animation: panel-ref-miss-pulse 1s ease-out;
1223
+ animation: panel-ref-miss-pulse var(--sf-time-1s) ease-out;
1069
1224
  }
1070
1225
  @keyframes panel-ref-miss-pulse {
1071
1226
  0%,
1072
1227
  100% {
1073
- background: rgba(0, 212, 255, 0.12);
1228
+ background: var(--sf-cyan-12);
1074
1229
  }
1075
1230
  50% {
1076
- background: rgba(244, 114, 182, 0.22);
1231
+ background: var(--sf-pink-22);
1077
1232
  }
1078
1233
  }
1079
1234
 
@@ -1104,7 +1259,7 @@ body {
1104
1259
  /* When focusedId is set, dim non-matching cards. */
1105
1260
  .symframe[data-mode="focus"][data-focus-id] .symframe-card-dynamic {
1106
1261
  opacity: 0.25;
1107
- transition: opacity 0.4s ease;
1262
+ transition: opacity var(--sf-time-normal) ease;
1108
1263
  }
1109
1264
  .symframe[data-mode="focus"][data-focus-id] .symframe-card-dynamic:hover {
1110
1265
  opacity: 0.6;
@@ -1121,9 +1276,9 @@ body {
1121
1276
  plenty of focus signal on their own. */
1122
1277
  opacity: 1 !important;
1123
1278
  box-shadow:
1124
- 0 0 24px rgba(0, 212, 255, 0.35),
1125
- inset 0 1px 0 rgba(255, 255, 255, 0.06),
1126
- 0 4px 12px rgba(0, 0, 0, 0.25);
1279
+ 0 0 24px var(--sf-cyan-35),
1280
+ inset 0 1px 0 var(--sf-white-06),
1281
+ 0 4px 12px var(--sf-black-25);
1127
1282
  border-color: var(--accent-cyan) !important;
1128
1283
  transition:
1129
1284
  box-shadow 0.4s ease,
@@ -1159,7 +1314,8 @@ body {
1159
1314
  opacity: 0.35;
1160
1315
  }
1161
1316
  .symframe[data-mode="awaiting"] .symframe-card-dynamic {
1162
- max-height: 38px;
1317
+ max-height: var(--sf-bound-row);
1318
+
1163
1319
  overflow: hidden;
1164
1320
  transition:
1165
1321
  max-height 0.4s ease,
@@ -1174,9 +1330,10 @@ body {
1174
1330
  "dominant" without exceeding the column. The `overflow: hidden`
1175
1331
  from C.4 still clips any overflow from misbehaving children. */
1176
1332
  max-height: 80%;
1177
- background: rgba(0, 212, 255, 0.04);
1178
- border-radius: 10px;
1179
- margin-top: 8px;
1333
+ background: var(--sf-cyan-04);
1334
+ border-radius: var(--sf-radius-10);
1335
+
1336
+ margin-top: var(--sf-pad-8);
1180
1337
  }
1181
1338
  .symframe[data-mode="awaiting"] .awaiting-list {
1182
1339
  /* The footer is now sized larger than baseline. Let the list flex
@@ -1242,10 +1399,11 @@ body {
1242
1399
  min-height: 0;
1243
1400
  display: flex;
1244
1401
  flex-direction: column;
1245
- gap: 10px;
1402
+ gap: var(--sf-pad-10);
1403
+
1246
1404
  overflow-y: auto;
1247
1405
  scrollbar-width: thin;
1248
- scrollbar-color: rgba(0, 212, 255, 0.12) transparent;
1406
+ scrollbar-color: var(--sf-cyan-12) transparent;
1249
1407
  /* Let scroll/click events fall through the empty space between cards
1250
1408
  down to the substrate, so the user can scroll reasoning even when
1251
1409
  foreground cards are foregrounded. Cards themselves re-enable
@@ -1259,8 +1417,8 @@ body {
1259
1417
  width: 3px;
1260
1418
  }
1261
1419
  .symframe-cards::-webkit-scrollbar-thumb {
1262
- background: rgba(0, 212, 255, 0.12);
1263
- border-radius: 2px;
1420
+ background: var(--sf-cyan-12);
1421
+ border-radius: var(--sf-radius-2);
1264
1422
  }
1265
1423
 
1266
1424
  /* ── Substrate (ambient reasoning layer, Stage B) ──────────────────── */
@@ -1275,17 +1433,19 @@ body {
1275
1433
  overflow-y: auto;
1276
1434
  display: flex;
1277
1435
  flex-direction: column;
1278
- gap: 6px;
1279
- padding: 2px 4px 4px;
1436
+ gap: var(--sf-pad-6);
1437
+
1438
+ padding: var(--sf-pad-2) var(--sf-pad-4) var(--sf-pad-4);
1439
+
1280
1440
  scrollbar-width: thin;
1281
- scrollbar-color: rgba(0, 212, 255, 0.18) transparent;
1441
+ scrollbar-color: var(--sf-cyan-18) transparent;
1282
1442
  }
1283
1443
  .symframe-substrate::-webkit-scrollbar {
1284
1444
  width: 3px;
1285
1445
  }
1286
1446
  .symframe-substrate::-webkit-scrollbar-thumb {
1287
- background: rgba(0, 212, 255, 0.18);
1288
- border-radius: 2px;
1447
+ background: var(--sf-cyan-18);
1448
+ border-radius: var(--sf-radius-2);
1289
1449
  }
1290
1450
 
1291
1451
  /* Substrate entry — decay-driven visual. Custom properties are written
@@ -1308,17 +1468,20 @@ body {
1308
1468
  opacity: 1;
1309
1469
  filter: none;
1310
1470
  transform: none;
1311
- border-color: rgba(0, 212, 255, 0.32);
1312
- box-shadow: 0 0 12px rgba(0, 212, 255, 0.08);
1471
+ border-color: var(--sf-cyan-32);
1472
+ box-shadow: 0 0 12px var(--sf-cyan-08);
1313
1473
  }
1314
1474
  .substrate-live-dot {
1315
1475
  display: inline-block;
1316
1476
  width: 6px;
1317
1477
  height: 6px;
1318
- border-radius: 50%;
1478
+ border-radius: var(--sf-radius-pill);
1479
+
1319
1480
  background: var(--accent-cyan);
1320
- margin-right: 6px;
1321
- animation: pulse 1.2s ease-in-out infinite;
1481
+ margin-right: var(--sf-pad-6);
1482
+
1483
+ animation: pulse var(--sf-time-pulse) ease-in-out infinite;
1484
+
1322
1485
  flex-shrink: 0;
1323
1486
  }
1324
1487
 
@@ -1329,13 +1492,15 @@ body {
1329
1492
  max-height: 2px;
1330
1493
  padding: 0;
1331
1494
  border-width: 0;
1332
- border-top: 1px solid rgba(0, 212, 255, 0.06);
1495
+ border-top: 1px solid var(--sf-cyan-06);
1333
1496
  overflow: hidden;
1334
1497
  }
1335
1498
  .substrate-entry.substrate-texture:hover {
1336
- max-height: 200px;
1337
- padding: 6px 8px;
1338
- border: 1px solid rgba(0, 212, 255, 0.18);
1499
+ max-height: var(--sf-bound-list);
1500
+
1501
+ padding: var(--sf-pad-6) var(--sf-pad-8);
1502
+
1503
+ border: 1px solid var(--sf-cyan-18);
1339
1504
  opacity: 0.7;
1340
1505
  filter: none;
1341
1506
  }
@@ -1356,7 +1521,8 @@ body {
1356
1521
  flex-direction: column;
1357
1522
  align-items: center;
1358
1523
  justify-content: center;
1359
- gap: 10px;
1524
+ gap: var(--sf-pad-10);
1525
+
1360
1526
  padding: 40px 0;
1361
1527
  margin: auto;
1362
1528
  opacity: 0.85;
@@ -1364,17 +1530,15 @@ body {
1364
1530
  .substrate-quiet-dot {
1365
1531
  width: 14px;
1366
1532
  height: 14px;
1367
- border-radius: 50%;
1368
- background: radial-gradient(
1369
- circle at center,
1370
- rgba(0, 212, 255, 0.45) 0%,
1371
- rgba(0, 212, 255, 0) 70%
1372
- );
1373
- animation: quiet-pulse 3.2s ease-in-out infinite;
1533
+ border-radius: var(--sf-radius-pill);
1534
+
1535
+ background: radial-gradient(circle at center, var(--sf-cyan-45) 0%, rgba(0, 212, 255, 0) 70%);
1536
+ animation: quiet-pulse var(--sf-time-pulse-quiet) ease-in-out infinite;
1374
1537
  }
1375
1538
  .substrate-quiet-label {
1376
1539
  font-family: var(--font-mono);
1377
- font-size: 9px;
1540
+ font-size: var(--sf-text-9);
1541
+
1378
1542
  letter-spacing: 0.18em;
1379
1543
  text-transform: uppercase;
1380
1544
  color: var(--text-dim);
@@ -1397,7 +1561,8 @@ body {
1397
1561
  informative; the panel stays still. */
1398
1562
  @media (prefers-reduced-motion: reduce) {
1399
1563
  .substrate-entry {
1400
- transition: opacity 0.2s ease;
1564
+ transition: opacity var(--sf-time-quick) ease;
1565
+
1401
1566
  filter: none !important;
1402
1567
  transform: none !important;
1403
1568
  }
@@ -1417,22 +1582,24 @@ body {
1417
1582
  the substrate breathe through. The backdrop-filter blurs whatever
1418
1583
  substrate texture is behind, so even at moderate transparency the
1419
1584
  card body stays crisp. */
1420
- background: rgba(10, 16, 26, 0.62);
1585
+ background: var(--sf-surface-card);
1421
1586
  backdrop-filter: blur(10px) saturate(140%);
1422
1587
  -webkit-backdrop-filter: blur(10px) saturate(140%);
1423
- border: 1px solid rgba(0, 212, 255, 0.12);
1424
- border-radius: 10px;
1425
- padding: 10px 12px;
1588
+ border: 1px solid var(--sf-cyan-12);
1589
+ border-radius: var(--sf-radius-10);
1590
+
1591
+ padding: var(--sf-pad-10) var(--sf-pad-12);
1592
+
1426
1593
  box-shadow:
1427
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1428
- 0 4px 12px rgba(0, 0, 0, 0.25);
1594
+ inset 0 1px 0 var(--sf-white-04),
1595
+ 0 4px 12px var(--sf-black-25);
1429
1596
  }
1430
1597
  .symframe .symframe-card::before,
1431
1598
  .symframe .symframe-card::after {
1432
1599
  display: none;
1433
1600
  }
1434
1601
  .symframe .symframe-card:hover {
1435
- border-color: rgba(0, 212, 255, 0.18);
1602
+ border-color: var(--sf-cyan-18);
1436
1603
  }
1437
1604
 
1438
1605
  /* Phase 2: dynamic-card sub-elements (only present on cards added via
@@ -1441,17 +1608,19 @@ body {
1441
1608
  display: flex;
1442
1609
  align-items: center;
1443
1610
  justify-content: space-between;
1444
- gap: 8px;
1611
+ gap: var(--sf-pad-8);
1445
1612
  }
1446
1613
  .symframe-card-dismiss {
1447
1614
  background: transparent;
1448
1615
  border: none;
1449
1616
  color: var(--text-dim);
1450
- font-size: 16px;
1617
+ font-size: var(--sf-text-16);
1618
+
1451
1619
  line-height: 1;
1452
1620
  width: 18px;
1453
1621
  height: 18px;
1454
- border-radius: 4px;
1622
+ border-radius: var(--sf-radius-4);
1623
+
1455
1624
  cursor: pointer;
1456
1625
  opacity: 0.6;
1457
1626
  transition:
@@ -1466,7 +1635,7 @@ body {
1466
1635
  .symframe-card-dismiss:hover {
1467
1636
  opacity: 1;
1468
1637
  color: var(--accent-cyan);
1469
- background: rgba(0, 212, 255, 0.08);
1638
+ background: var(--sf-cyan-08);
1470
1639
  }
1471
1640
 
1472
1641
  /* Stage C: pin glyph — replaces dismiss button on pinned cards. Click
@@ -1477,11 +1646,13 @@ body {
1477
1646
  background: transparent;
1478
1647
  border: none;
1479
1648
  color: var(--accent-cyan);
1480
- font-size: 13px;
1649
+ font-size: var(--sf-text-13);
1650
+
1481
1651
  line-height: 1;
1482
1652
  width: 18px;
1483
1653
  height: 18px;
1484
- border-radius: 4px;
1654
+ border-radius: var(--sf-radius-4);
1655
+
1485
1656
  cursor: pointer;
1486
1657
  opacity: 0.8;
1487
1658
  padding: 0;
@@ -1494,33 +1665,33 @@ body {
1494
1665
  }
1495
1666
  .symframe-card-pin:hover {
1496
1667
  opacity: 1;
1497
- background: rgba(0, 212, 255, 0.08);
1668
+ background: var(--sf-cyan-08);
1498
1669
  }
1499
1670
 
1500
1671
  /* Stage C: dwell pulse — 600ms cyan border + glow then return. */
1501
1672
  .symframe-card.symframe-dwelling {
1502
- animation: symframe-dwell 600ms ease-out;
1673
+ animation: symframe-dwell var(--sf-time-600ms) ease-out;
1503
1674
  }
1504
1675
  @keyframes symframe-dwell {
1505
1676
  0% {
1506
1677
  border-color: var(--accent-cyan);
1507
1678
  box-shadow:
1508
- 0 0 0 0 rgba(0, 212, 255, 0.55),
1509
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1510
- 0 4px 12px rgba(0, 0, 0, 0.25);
1679
+ 0 0 0 0 var(--sf-cyan-55),
1680
+ inset 0 1px 0 var(--sf-white-04),
1681
+ 0 4px 12px var(--sf-black-25);
1511
1682
  }
1512
1683
  60% {
1513
- border-color: rgba(0, 212, 255, 0.6);
1684
+ border-color: var(--sf-cyan-60);
1514
1685
  box-shadow:
1515
1686
  0 0 0 6px rgba(0, 212, 255, 0),
1516
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1517
- 0 4px 12px rgba(0, 0, 0, 0.25);
1687
+ inset 0 1px 0 var(--sf-white-04),
1688
+ 0 4px 12px var(--sf-black-25);
1518
1689
  }
1519
1690
  100% {
1520
- border-color: rgba(0, 212, 255, 0.12);
1691
+ border-color: var(--sf-cyan-12);
1521
1692
  box-shadow:
1522
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1523
- 0 4px 12px rgba(0, 0, 0, 0.25);
1693
+ inset 0 1px 0 var(--sf-white-04),
1694
+ 0 4px 12px var(--sf-black-25);
1524
1695
  }
1525
1696
  }
1526
1697
 
@@ -1529,10 +1700,10 @@ body {
1529
1700
  on transitionend or after a 900ms fail-safe timeout. */
1530
1701
  .symframe-card.symframe-releasing {
1531
1702
  transition:
1532
- opacity 800ms cubic-bezier(0.4, 0, 0.6, 1),
1533
- transform 800ms cubic-bezier(0.4, 0, 0.6, 1),
1534
- max-height 800ms cubic-bezier(0.4, 0, 0.6, 1),
1535
- margin 800ms ease;
1703
+ opacity var(--sf-time-800ms) cubic-bezier(0.4, 0, 0.6, 1),
1704
+ transform var(--sf-time-800ms) cubic-bezier(0.4, 0, 0.6, 1),
1705
+ max-height var(--sf-time-800ms) cubic-bezier(0.4, 0, 0.6, 1),
1706
+ margin var(--sf-time-800ms) ease;
1536
1707
  opacity: 0;
1537
1708
  transform: scale(0.92);
1538
1709
  max-height: 0;
@@ -1549,7 +1720,7 @@ body {
1549
1720
  border-color: var(--accent-cyan);
1550
1721
  }
1551
1722
  .symframe-card.symframe-releasing {
1552
- transition: opacity 200ms ease;
1723
+ transition: opacity var(--sf-time-200ms) ease;
1553
1724
  transform: none;
1554
1725
  max-height: none;
1555
1726
  }
@@ -1564,12 +1735,15 @@ body {
1564
1735
  Click [+ Add] → menu with "Spawn subagent" / "Add scheduled task". */
1565
1736
  .symframe-awaiting {
1566
1737
  position: relative;
1567
- border-top: 1px solid rgba(0, 212, 255, 0.12);
1568
- margin-top: 8px;
1569
- padding: 8px 6px 4px;
1738
+ border-top: 1px solid var(--sf-cyan-12);
1739
+ margin-top: var(--sf-pad-8);
1740
+
1741
+ padding: var(--sf-pad-8) var(--sf-pad-6) var(--sf-pad-4);
1742
+
1570
1743
  display: flex;
1571
1744
  flex-direction: column;
1572
- gap: 4px;
1745
+ gap: var(--sf-pad-4);
1746
+
1573
1747
  /* Stage C.4: cap the AWAITING footer so it can't claim more than ~40%
1574
1748
  of the column height even if the user has many cron jobs. The
1575
1749
  list inside still scrolls (max-height: 200px on .awaiting-list)
@@ -1584,19 +1758,22 @@ body {
1584
1758
  .awaiting-header {
1585
1759
  display: flex;
1586
1760
  align-items: baseline;
1587
- gap: 8px;
1588
- padding: 0 4px 4px;
1761
+ gap: var(--sf-pad-8);
1762
+
1763
+ padding: 0 var(--sf-pad-4) var(--sf-pad-4);
1589
1764
  }
1590
1765
  .awaiting-title {
1591
1766
  font-family: var(--font-mono);
1592
- font-size: 10px;
1767
+ font-size: var(--sf-text-10);
1768
+
1593
1769
  font-weight: 600;
1594
1770
  letter-spacing: 0.14em;
1595
1771
  color: var(--accent-cyan);
1596
1772
  }
1597
1773
  .awaiting-count {
1598
1774
  font-family: var(--font-mono);
1599
- font-size: 9px;
1775
+ font-size: var(--sf-text-9);
1776
+
1600
1777
  letter-spacing: 0.04em;
1601
1778
  color: var(--text-dim);
1602
1779
  opacity: 0.6;
@@ -1605,38 +1782,44 @@ body {
1605
1782
  .awaiting-list {
1606
1783
  display: flex;
1607
1784
  flex-direction: column;
1608
- gap: 2px;
1609
- max-height: 200px;
1785
+ gap: var(--sf-pad-2);
1786
+
1787
+ max-height: var(--sf-bound-list);
1788
+
1610
1789
  overflow-y: auto;
1611
1790
  scrollbar-width: thin;
1612
- scrollbar-color: rgba(0, 212, 255, 0.18) transparent;
1791
+ scrollbar-color: var(--sf-cyan-18) transparent;
1613
1792
  }
1614
1793
  .awaiting-list::-webkit-scrollbar {
1615
1794
  width: 3px;
1616
1795
  }
1617
1796
  .awaiting-list::-webkit-scrollbar-thumb {
1618
- background: rgba(0, 212, 255, 0.18);
1619
- border-radius: 2px;
1797
+ background: var(--sf-cyan-18);
1798
+ border-radius: var(--sf-radius-2);
1620
1799
  }
1621
1800
  .awaiting-item {
1622
1801
  display: grid;
1623
1802
  grid-template-columns: 18px 1fr auto;
1624
1803
  align-items: center;
1625
- gap: 6px;
1626
- padding: 5px 8px;
1627
- border-radius: 6px;
1628
- background: rgba(255, 255, 255, 0.02);
1804
+ gap: var(--sf-pad-6);
1805
+
1806
+ padding: var(--sf-pad-5) var(--sf-pad-8);
1807
+
1808
+ border-radius: var(--sf-radius-6);
1809
+
1810
+ background: var(--sf-white-02);
1629
1811
  border: 1px solid transparent;
1630
1812
  font-family: var(--font-mono);
1631
- font-size: 10px;
1813
+ font-size: var(--sf-text-10);
1814
+
1632
1815
  cursor: pointer;
1633
1816
  transition:
1634
1817
  background 0.15s ease,
1635
1818
  border-color 0.15s ease;
1636
1819
  }
1637
1820
  .awaiting-item:hover {
1638
- background: rgba(0, 212, 255, 0.06);
1639
- border-color: rgba(0, 212, 255, 0.15);
1821
+ background: var(--sf-cyan-06);
1822
+ border-color: var(--sf-cyan-15);
1640
1823
  }
1641
1824
  .awaiting-item-disabled {
1642
1825
  opacity: 0.45;
@@ -1647,7 +1830,8 @@ body {
1647
1830
  display: inline-flex;
1648
1831
  align-items: center;
1649
1832
  justify-content: center;
1650
- font-size: 11px;
1833
+ font-size: var(--sf-text-11);
1834
+
1651
1835
  line-height: 1;
1652
1836
  }
1653
1837
  .awaiting-glyph-subagent {
@@ -1669,7 +1853,8 @@ body {
1669
1853
  .awaiting-meta {
1670
1854
  color: var(--text-dim);
1671
1855
  opacity: 0.75;
1672
- font-size: 9px;
1856
+ font-size: var(--sf-text-9);
1857
+
1673
1858
  letter-spacing: 0.04em;
1674
1859
  text-transform: lowercase;
1675
1860
  white-space: nowrap;
@@ -1678,10 +1863,12 @@ body {
1678
1863
  /* Empty-state placeholder when no subagents and no schedules exist. */
1679
1864
  .awaiting-empty {
1680
1865
  font-family: var(--font-mono);
1681
- font-size: 10px;
1866
+ font-size: var(--sf-text-10);
1867
+
1682
1868
  color: var(--text-dim);
1683
1869
  opacity: 0.55;
1684
- padding: 8px 10px;
1870
+ padding: var(--sf-pad-8) var(--sf-pad-10);
1871
+
1685
1872
  text-align: center;
1686
1873
  font-style: italic;
1687
1874
  }
@@ -1690,16 +1877,21 @@ body {
1690
1877
  .awaiting-add-btn {
1691
1878
  display: inline-flex;
1692
1879
  align-items: center;
1693
- gap: 6px;
1694
- margin-top: 4px;
1880
+ gap: var(--sf-pad-6);
1881
+
1882
+ margin-top: var(--sf-pad-4);
1883
+
1695
1884
  align-self: flex-start;
1696
- padding: 4px 10px;
1885
+ padding: var(--sf-pad-4) var(--sf-pad-10);
1886
+
1697
1887
  background: transparent;
1698
- border: 1px dashed rgba(0, 212, 255, 0.25);
1699
- border-radius: 6px;
1888
+ border: 1px dashed var(--sf-cyan-25);
1889
+ border-radius: var(--sf-radius-6);
1890
+
1700
1891
  color: var(--text-dim);
1701
1892
  font-family: var(--font-mono);
1702
- font-size: 10px;
1893
+ font-size: var(--sf-text-10);
1894
+
1703
1895
  letter-spacing: 0.04em;
1704
1896
  cursor: pointer;
1705
1897
  transition:
@@ -1710,7 +1902,7 @@ body {
1710
1902
  .awaiting-add-btn:hover {
1711
1903
  color: var(--accent-cyan);
1712
1904
  border-color: var(--accent-cyan);
1713
- background: rgba(0, 212, 255, 0.04);
1905
+ background: var(--sf-cyan-04);
1714
1906
  }
1715
1907
  .awaiting-add-btn svg {
1716
1908
  width: 12px;
@@ -1720,36 +1912,44 @@ body {
1720
1912
  position: absolute;
1721
1913
  left: 10px;
1722
1914
  bottom: 100%;
1723
- margin-bottom: 6px;
1724
- background: rgba(10, 16, 26, 0.95);
1915
+ margin-bottom: var(--sf-pad-6);
1916
+
1917
+ background: var(--sf-surface-menu);
1725
1918
  backdrop-filter: blur(12px) saturate(140%);
1726
1919
  -webkit-backdrop-filter: blur(12px) saturate(140%);
1727
- border: 1px solid rgba(0, 212, 255, 0.2);
1728
- border-radius: 8px;
1729
- padding: 4px;
1920
+ border: 1px solid var(--sf-cyan-20);
1921
+ border-radius: var(--sf-radius-8);
1922
+
1923
+ padding: var(--sf-pad-4);
1924
+
1730
1925
  display: flex;
1731
1926
  flex-direction: column;
1732
- gap: 2px;
1927
+ gap: var(--sf-pad-2);
1928
+
1733
1929
  min-width: 180px;
1734
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
1930
+ box-shadow: 0 8px 24px var(--sf-black-40);
1735
1931
  z-index: 20;
1736
1932
  }
1737
1933
  .awaiting-add-item {
1738
1934
  display: flex;
1739
1935
  align-items: center;
1740
- gap: 8px;
1741
- padding: 6px 10px;
1936
+ gap: var(--sf-pad-8);
1937
+
1938
+ padding: var(--sf-pad-6) var(--sf-pad-10);
1939
+
1742
1940
  background: transparent;
1743
1941
  border: none;
1744
- border-radius: 5px;
1942
+ border-radius: var(--sf-radius-5);
1943
+
1745
1944
  color: var(--text);
1746
1945
  font-family: var(--font-mono);
1747
- font-size: 11px;
1946
+ font-size: var(--sf-text-11);
1947
+
1748
1948
  cursor: pointer;
1749
1949
  text-align: left;
1750
1950
  }
1751
1951
  .awaiting-add-item:hover {
1752
- background: rgba(0, 212, 255, 0.08);
1952
+ background: var(--sf-cyan-08);
1753
1953
  color: var(--accent-cyan);
1754
1954
  }
1755
1955
  .awaiting-add-glyph {
@@ -1760,49 +1960,58 @@ body {
1760
1960
 
1761
1961
  .symframe-card-body {
1762
1962
  font-family: var(--font-mono);
1763
- font-size: 11px;
1963
+ font-size: var(--sf-text-11);
1964
+
1764
1965
  line-height: 1.5;
1765
1966
  color: var(--text);
1766
- margin-top: 8px;
1967
+ margin-top: var(--sf-pad-8);
1968
+
1767
1969
  white-space: pre-wrap;
1768
1970
  word-break: break-word;
1769
- max-height: 320px;
1971
+ max-height: var(--sf-bound-body);
1972
+
1770
1973
  overflow-y: auto;
1771
1974
  }
1772
1975
  .symframe-card-actions {
1773
1976
  display: flex;
1774
- gap: 6px;
1775
- margin-top: 10px;
1776
- padding-top: 8px;
1777
- border-top: 1px solid rgba(255, 255, 255, 0.05);
1977
+ gap: var(--sf-pad-6);
1978
+
1979
+ margin-top: var(--sf-pad-10);
1980
+
1981
+ padding-top: var(--sf-pad-8);
1982
+
1983
+ border-top: 1px solid var(--sf-white-05);
1778
1984
  flex-wrap: wrap;
1779
1985
  }
1780
1986
  .symframe-card-action {
1781
1987
  flex: 1 1 auto;
1782
1988
  min-width: 60px;
1783
- padding: 6px 10px;
1989
+ padding: var(--sf-pad-6) var(--sf-pad-10);
1990
+
1784
1991
  border: 1px solid var(--glass-border);
1785
- border-radius: 5px;
1786
- background: rgba(255, 255, 255, 0.03);
1992
+ border-radius: var(--sf-radius-5);
1993
+
1994
+ background: var(--sf-white-03);
1787
1995
  color: var(--text-dim);
1788
1996
  font-family: var(--font-mono);
1789
- font-size: 10px;
1997
+ font-size: var(--sf-text-10);
1998
+
1790
1999
  letter-spacing: 0.04em;
1791
2000
  cursor: pointer;
1792
- transition: all 0.15s ease;
2001
+ transition: all var(--sf-time-fast) ease;
1793
2002
  }
1794
2003
  .symframe-card-action:hover {
1795
2004
  border-color: var(--accent-cyan);
1796
2005
  color: var(--text);
1797
2006
  }
1798
2007
  .symframe-card-action-primary {
1799
- background: rgba(0, 212, 255, 0.08);
2008
+ background: var(--sf-cyan-08);
1800
2009
  border-color: var(--accent-cyan);
1801
2010
  color: var(--accent-cyan);
1802
2011
  }
1803
2012
  .symframe-card-action-primary:hover {
1804
- background: rgba(0, 212, 255, 0.14);
1805
- box-shadow: 0 0 8px rgba(0, 212, 255, 0.18);
2013
+ background: var(--sf-cyan-14);
2014
+ box-shadow: 0 0 8px var(--sf-cyan-18);
1806
2015
  }
1807
2016
 
1808
2017
  /* ── Stage D.1 (3.5.27): intent-aware visual treatment ──────────── */
@@ -1826,14 +2035,17 @@ body {
1826
2035
  position: absolute;
1827
2036
  top: 0;
1828
2037
  left: 0;
1829
- padding: 2px 8px 2px 6px;
2038
+ padding: var(--sf-pad-2) var(--sf-pad-8) var(--sf-pad-2) var(--sf-pad-6);
2039
+
1830
2040
  font-family: var(--font-mono);
1831
- font-size: 8px;
2041
+ font-size: var(--sf-text-8);
2042
+
1832
2043
  font-weight: 700;
1833
2044
  letter-spacing: 0.14em;
1834
2045
  text-transform: uppercase;
1835
- background: rgba(0, 0, 0, 0.55);
1836
- border-radius: 10px 0 6px 0;
2046
+ background: var(--sf-black-55);
2047
+ border-radius: var(--sf-radius-10) 0 var(--sf-radius-6) 0;
2048
+
1837
2049
  border-right: 1px solid currentColor;
1838
2050
  border-bottom: 1px solid currentColor;
1839
2051
  pointer-events: none;
@@ -1849,9 +2061,9 @@ body {
1849
2061
  /* holding — cyan; working memory */
1850
2062
  .symframe-card-dynamic[data-intent="holding"] {
1851
2063
  box-shadow:
1852
- inset 3px 0 0 0 rgba(0, 212, 255, 0.65),
1853
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1854
- 0 4px 12px rgba(0, 0, 0, 0.25);
2064
+ inset 3px 0 0 0 var(--sf-cyan-65),
2065
+ inset 0 1px 0 var(--sf-white-04),
2066
+ 0 4px 12px var(--sf-black-25);
1855
2067
  }
1856
2068
  .symframe-card-dynamic[data-intent="holding"]::before {
1857
2069
  color: var(--accent-cyan);
@@ -1861,8 +2073,8 @@ body {
1861
2073
  .symframe-card-dynamic[data-intent="weighing"] {
1862
2074
  box-shadow:
1863
2075
  inset 3px 0 0 0 #f5b73a,
1864
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1865
- 0 4px 12px rgba(0, 0, 0, 0.25);
2076
+ inset 0 1px 0 var(--sf-white-04),
2077
+ 0 4px 12px var(--sf-black-25);
1866
2078
  }
1867
2079
  .symframe-card-dynamic[data-intent="weighing"]::before {
1868
2080
  color: #f5b73a;
@@ -1870,22 +2082,22 @@ body {
1870
2082
 
1871
2083
  /* producing — green; actively drafting, slow pulse on the stripe */
1872
2084
  .symframe-card-dynamic[data-intent="producing"] {
1873
- animation: intent-producing-pulse 2.6s ease-in-out infinite;
2085
+ animation: intent-producing-pulse var(--sf-time-pulse-prod) ease-in-out infinite;
1874
2086
  }
1875
2087
  @keyframes intent-producing-pulse {
1876
2088
  0%,
1877
2089
  100% {
1878
2090
  box-shadow:
1879
- inset 3px 0 0 0 rgba(52, 211, 153, 0.55),
1880
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1881
- 0 4px 12px rgba(0, 0, 0, 0.25);
2091
+ inset 3px 0 0 0 var(--sf-green-55),
2092
+ inset 0 1px 0 var(--sf-white-04),
2093
+ 0 4px 12px var(--sf-black-25);
1882
2094
  }
1883
2095
  50% {
1884
2096
  box-shadow:
1885
- inset 3px 0 0 0 rgba(52, 211, 153, 1),
1886
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1887
- 0 4px 12px rgba(0, 0, 0, 0.25),
1888
- 0 0 14px rgba(52, 211, 153, 0.2);
2097
+ inset 3px 0 0 0 var(--sf-green-100),
2098
+ inset 0 1px 0 var(--sf-white-04),
2099
+ 0 4px 12px var(--sf-black-25),
2100
+ 0 0 14px var(--sf-green-20);
1889
2101
  }
1890
2102
  }
1891
2103
  .symframe-card-dynamic[data-intent="producing"]::before {
@@ -1897,8 +2109,8 @@ body {
1897
2109
  .symframe-card-dynamic[data-intent="drafted"] {
1898
2110
  box-shadow:
1899
2111
  inset 3px 0 0 0 #8b5cf6,
1900
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1901
- 0 4px 12px rgba(0, 0, 0, 0.25);
2112
+ inset 0 1px 0 var(--sf-white-04),
2113
+ 0 4px 12px var(--sf-black-25);
1902
2114
  }
1903
2115
  .symframe-card-dynamic[data-intent="drafted"]::before {
1904
2116
  color: #8b5cf6;
@@ -1906,30 +2118,30 @@ body {
1906
2118
  /* Emphasize action buttons on drafted cards — these cards exist to
1907
2119
  be acted on (Send / Copy / Open). Make the buttons more clickable. */
1908
2120
  .symframe-card-dynamic[data-intent="drafted"] .symframe-card-action {
1909
- border-color: rgba(139, 92, 246, 0.55);
2121
+ border-color: var(--sf-violet-55);
1910
2122
  color: var(--text);
1911
2123
  font-weight: 600;
1912
2124
  }
1913
2125
  .symframe-card-dynamic[data-intent="drafted"] .symframe-card-action:hover {
1914
- background: rgba(139, 92, 246, 0.12);
2126
+ background: var(--sf-violet-12);
1915
2127
  border-color: #8b5cf6;
1916
2128
  }
1917
2129
  .symframe-card-dynamic[data-intent="drafted"] .symframe-card-action-primary {
1918
- background: rgba(139, 92, 246, 0.22);
2130
+ background: var(--sf-violet-22);
1919
2131
  border-color: #8b5cf6;
1920
2132
  color: var(--text);
1921
2133
  }
1922
2134
  .symframe-card-dynamic[data-intent="drafted"] .symframe-card-action-primary:hover {
1923
- background: rgba(139, 92, 246, 0.32);
1924
- box-shadow: 0 0 10px rgba(139, 92, 246, 0.25);
2135
+ background: var(--sf-violet-32);
2136
+ box-shadow: 0 0 10px var(--sf-violet-25);
1925
2137
  }
1926
2138
 
1927
2139
  /* reference — muted gray; passive read-only context */
1928
2140
  .symframe-card-dynamic[data-intent="reference"] {
1929
2141
  box-shadow:
1930
2142
  inset 3px 0 0 0 rgba(255, 255, 255, 0.22),
1931
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1932
- 0 4px 12px rgba(0, 0, 0, 0.25);
2143
+ inset 0 1px 0 var(--sf-white-04),
2144
+ 0 4px 12px var(--sf-black-25);
1933
2145
  opacity: 0.88;
1934
2146
  filter: saturate(0.75);
1935
2147
  }
@@ -1943,13 +2155,13 @@ body {
1943
2155
  miscategorization. */
1944
2156
  .symframe-card-dynamic[data-intent="awaiting"] {
1945
2157
  box-shadow:
1946
- inset 3px 0 0 0 rgba(244, 114, 182, 0.55),
1947
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1948
- 0 4px 12px rgba(0, 0, 0, 0.25);
2158
+ inset 3px 0 0 0 var(--sf-pink-55),
2159
+ inset 0 1px 0 var(--sf-white-04),
2160
+ 0 4px 12px var(--sf-black-25);
1949
2161
  }
1950
2162
  .symframe-card-dynamic[data-intent="awaiting"]::before {
1951
2163
  content: "awaiting → footer";
1952
- color: rgba(244, 114, 182, 0.85);
2164
+ color: var(--sf-pink-85);
1953
2165
  }
1954
2166
 
1955
2167
  /* Reduced-motion: skip the producing pulse but keep the static
@@ -1958,9 +2170,9 @@ body {
1958
2170
  .symframe-card-dynamic[data-intent="producing"] {
1959
2171
  animation: none;
1960
2172
  box-shadow:
1961
- inset 3px 0 0 0 rgba(52, 211, 153, 0.75),
1962
- inset 0 1px 0 rgba(255, 255, 255, 0.04),
1963
- 0 4px 12px rgba(0, 0, 0, 0.25);
2173
+ inset 3px 0 0 0 var(--sf-green-75),
2174
+ inset 0 1px 0 var(--sf-white-04),
2175
+ 0 4px 12px var(--sf-black-25);
1964
2176
  }
1965
2177
  }
1966
2178
 
@@ -1973,54 +2185,64 @@ body {
1973
2185
  .symframe-body-markdown h2,
1974
2186
  .symframe-body-markdown h3,
1975
2187
  .symframe-body-markdown h4 {
1976
- font-size: 12px;
2188
+ font-size: var(--sf-text-12);
2189
+
1977
2190
  font-weight: 600;
1978
- margin: 8px 0 4px;
2191
+ margin: var(--sf-pad-8) 0 var(--sf-pad-4);
2192
+
1979
2193
  color: var(--text);
1980
2194
  }
1981
2195
  .symframe-body-markdown p {
1982
- margin: 4px 0;
2196
+ margin: var(--sf-pad-4) 0;
1983
2197
  }
1984
2198
  .symframe-body-markdown ul,
1985
2199
  .symframe-body-markdown ol {
1986
2200
  padding-left: 18px;
1987
- margin: 4px 0;
2201
+ margin: var(--sf-pad-4) 0;
1988
2202
  }
1989
2203
  .symframe-body-markdown code {
1990
2204
  font-family: var(--font-mono);
1991
- font-size: 10px;
1992
- padding: 1px 4px;
1993
- background: rgba(255, 255, 255, 0.04);
1994
- border-radius: 3px;
2205
+ font-size: var(--sf-text-10);
2206
+
2207
+ padding: 1px var(--sf-pad-4);
2208
+
2209
+ background: var(--sf-white-04);
2210
+ border-radius: var(--sf-radius-3);
1995
2211
  }
1996
2212
  .symframe-body-markdown pre {
1997
- background: rgba(0, 0, 0, 0.25);
1998
- border: 1px solid rgba(255, 255, 255, 0.05);
1999
- border-radius: 5px;
2000
- padding: 8px;
2213
+ background: var(--sf-black-25);
2214
+ border: 1px solid var(--sf-white-05);
2215
+ border-radius: var(--sf-radius-5);
2216
+
2217
+ padding: var(--sf-pad-8);
2218
+
2001
2219
  overflow-x: auto;
2002
- margin: 6px 0;
2220
+ margin: var(--sf-pad-6) 0;
2003
2221
  }
2004
2222
  .symframe-body-markdown pre code {
2005
2223
  background: transparent;
2006
2224
  padding: 0;
2007
- font-size: 10px;
2225
+ font-size: var(--sf-text-10);
2008
2226
  }
2009
2227
 
2010
2228
  /* Code body — pre/code wrapper with hljs theme-friendly chrome. */
2011
2229
  .symframe-body-code {
2012
- background: rgba(0, 0, 0, 0.3);
2013
- border: 1px solid rgba(255, 255, 255, 0.06);
2014
- border-radius: 5px;
2015
- padding: 8px 10px;
2230
+ background: var(--sf-black-30);
2231
+ border: 1px solid var(--sf-white-06);
2232
+ border-radius: var(--sf-radius-5);
2233
+
2234
+ padding: var(--sf-pad-8) var(--sf-pad-10);
2235
+
2016
2236
  margin: 0;
2017
2237
  overflow-x: auto;
2018
- max-height: 320px;
2238
+ max-height: var(--sf-bound-body);
2239
+
2019
2240
  overflow-y: auto;
2020
2241
  }
2021
2242
  .symframe-body-code code {
2022
2243
  font-family: var(--font-mono);
2023
- font-size: 10px;
2244
+ font-size: var(--sf-text-10);
2245
+
2024
2246
  line-height: 1.45;
2025
2247
  color: var(--text);
2026
2248
  background: transparent;
@@ -2030,28 +2252,33 @@ body {
2030
2252
  .symframe-body-email {
2031
2253
  display: flex;
2032
2254
  flex-direction: column;
2033
- gap: 4px;
2255
+ gap: var(--sf-pad-4);
2034
2256
  }
2035
2257
  .symframe-email-row {
2036
2258
  display: flex;
2037
- gap: 6px;
2259
+ gap: var(--sf-pad-6);
2260
+
2038
2261
  font-family: var(--font-mono);
2039
- font-size: 10px;
2262
+ font-size: var(--sf-text-10);
2263
+
2040
2264
  letter-spacing: 0.02em;
2041
- padding: 2px 0;
2042
- border-bottom: 1px dashed rgba(255, 255, 255, 0.05);
2265
+ padding: var(--sf-pad-2) 0;
2266
+
2267
+ border-bottom: 1px dashed var(--sf-white-05);
2043
2268
  }
2044
2269
  .symframe-email-row:last-of-type {
2045
- border-bottom: 1px solid rgba(255, 255, 255, 0.08);
2046
- margin-bottom: 4px;
2047
- padding-bottom: 4px;
2270
+ border-bottom: 1px solid var(--sf-white-08);
2271
+ margin-bottom: var(--sf-pad-4);
2272
+
2273
+ padding-bottom: var(--sf-pad-4);
2048
2274
  }
2049
2275
  .symframe-email-label {
2050
2276
  flex: 0 0 auto;
2051
2277
  color: var(--text-dim);
2052
2278
  text-transform: uppercase;
2053
2279
  letter-spacing: 0.06em;
2054
- font-size: 9px;
2280
+ font-size: var(--sf-text-9);
2281
+
2055
2282
  min-width: 48px;
2056
2283
  opacity: 0.7;
2057
2284
  }
@@ -2061,26 +2288,29 @@ body {
2061
2288
  }
2062
2289
  .symframe-email-body {
2063
2290
  font-family: var(--font-mono);
2064
- font-size: 11px;
2291
+ font-size: var(--sf-text-11);
2292
+
2065
2293
  line-height: 1.5;
2066
2294
  color: var(--text);
2067
2295
  white-space: pre-wrap;
2068
2296
  word-break: break-word;
2069
- margin-top: 4px;
2297
+ margin-top: var(--sf-pad-4);
2070
2298
  }
2071
2299
 
2072
2300
  /* PDF embed */
2073
2301
  .symframe-body-pdf {
2074
2302
  display: flex;
2075
2303
  flex-direction: column;
2076
- gap: 6px;
2304
+ gap: var(--sf-pad-6);
2077
2305
  }
2078
2306
  .symframe-pdf-iframe {
2079
2307
  width: 100%;
2080
- height: 280px;
2081
- border: 1px solid rgba(255, 255, 255, 0.08);
2082
- border-radius: 5px;
2083
- background: rgba(0, 0, 0, 0.2);
2308
+ height: var(--sf-bound-media);
2309
+
2310
+ border: 1px solid var(--sf-white-08);
2311
+ border-radius: var(--sf-radius-5);
2312
+
2313
+ background: var(--sf-black-20);
2084
2314
  }
2085
2315
 
2086
2316
  /* Audio + video shared chrome */
@@ -2088,23 +2318,26 @@ body {
2088
2318
  .symframe-body-video {
2089
2319
  display: flex;
2090
2320
  flex-direction: column;
2091
- gap: 6px;
2321
+ gap: var(--sf-pad-6);
2092
2322
  }
2093
2323
  .symframe-audio,
2094
2324
  .symframe-video {
2095
2325
  width: 100%;
2096
- border-radius: 5px;
2097
- background: rgba(0, 0, 0, 0.2);
2326
+ border-radius: var(--sf-radius-5);
2327
+
2328
+ background: var(--sf-black-20);
2098
2329
  }
2099
2330
  .symframe-video {
2100
- max-height: 280px;
2331
+ max-height: var(--sf-bound-media);
2332
+
2101
2333
  object-fit: contain;
2102
2334
  }
2103
2335
 
2104
2336
  /* Empty-media placeholder when url is missing */
2105
2337
  .symframe-body-empty {
2106
2338
  font-family: var(--font-mono);
2107
- font-size: 10px;
2339
+ font-size: var(--sf-text-10);
2340
+
2108
2341
  color: var(--text-dim);
2109
2342
  opacity: 0.6;
2110
2343
  font-style: italic;
@@ -2113,15 +2346,19 @@ body {
2113
2346
  /* Download link — used by pdf/audio/video renderers */
2114
2347
  .symframe-download {
2115
2348
  display: inline-block;
2116
- padding: 4px 8px;
2349
+ padding: var(--sf-pad-4) var(--sf-pad-8);
2350
+
2117
2351
  border: 1px solid var(--glass-border);
2118
- border-radius: 4px;
2352
+ border-radius: var(--sf-radius-4);
2353
+
2119
2354
  font-family: var(--font-mono);
2120
- font-size: 10px;
2355
+ font-size: var(--sf-text-10);
2356
+
2121
2357
  letter-spacing: 0.04em;
2122
2358
  color: var(--text-dim);
2123
2359
  text-decoration: none;
2124
- transition: all 0.15s ease;
2360
+ transition: all var(--sf-time-fast) ease;
2361
+
2125
2362
  align-self: flex-start;
2126
2363
  }
2127
2364
  .symframe-download:hover {
@@ -6703,17 +6940,20 @@ body {
6703
6940
  display: inline-block;
6704
6941
  width: 6px;
6705
6942
  height: 6px;
6706
- border-radius: 50%;
6943
+ border-radius: var(--sf-radius-pill);
6944
+
6707
6945
  background: var(--accent-cyan);
6708
- margin-left: 6px;
6946
+ margin-left: var(--sf-pad-6);
6947
+
6709
6948
  vertical-align: middle;
6710
6949
  opacity: 0;
6711
- transition: opacity 0.3s ease;
6950
+ transition: opacity var(--sf-time-slow) ease;
6951
+
6712
6952
  flex-shrink: 0;
6713
6953
  }
6714
6954
  .reasoning-live-dot.active {
6715
6955
  opacity: 1;
6716
- animation: pulse 1.2s ease-in-out infinite;
6956
+ animation: pulse var(--sf-time-pulse) ease-in-out infinite;
6717
6957
  }
6718
6958
 
6719
6959
  /* The .reasoning-panel / .reasoning-feed / .reasoning-empty* rules were
@@ -6726,18 +6966,20 @@ body {
6726
6966
  .reasoning-run-sep {
6727
6967
  display: flex;
6728
6968
  align-items: center;
6729
- gap: 8px;
6730
- margin: 4px 0 2px;
6969
+ gap: var(--sf-pad-8);
6970
+
6971
+ margin: var(--sf-pad-4) 0 var(--sf-pad-2);
6731
6972
  }
6732
6973
  .reasoning-run-sep::before,
6733
6974
  .reasoning-run-sep::after {
6734
6975
  content: "";
6735
6976
  flex: 1;
6736
6977
  height: 1px;
6737
- background: rgba(255, 255, 255, 0.06);
6978
+ background: var(--sf-white-06);
6738
6979
  }
6739
6980
  .reasoning-run-sep-label {
6740
- font-size: 9px;
6981
+ font-size: var(--sf-text-9);
6982
+
6741
6983
  font-family: var(--font-mono);
6742
6984
  font-weight: 600;
6743
6985
  letter-spacing: 0.1em;
@@ -6749,59 +6991,66 @@ body {
6749
6991
  .reasoning-entry {
6750
6992
  display: flex;
6751
6993
  flex-direction: column;
6752
- gap: 4px;
6753
- padding: 6px 8px;
6754
- background: rgba(255, 255, 255, 0.02);
6755
- border: 1px solid rgba(255, 255, 255, 0.05);
6756
- border-radius: 8px;
6757
- transition: border-color 0.2s;
6994
+ gap: var(--sf-pad-4);
6995
+
6996
+ padding: var(--sf-pad-6) var(--sf-pad-8);
6997
+
6998
+ background: var(--sf-white-02);
6999
+ border: 1px solid var(--sf-white-05);
7000
+ border-radius: var(--sf-radius-8);
7001
+
7002
+ transition: border-color var(--sf-time-quick);
6758
7003
  }
6759
7004
  .reasoning-entry:hover {
6760
- border-color: rgba(255, 255, 255, 0.09);
7005
+ border-color: var(--sf-white-09);
6761
7006
  }
6762
7007
 
6763
7008
  /* Entry header row: badge + label */
6764
7009
  .reasoning-entry-header {
6765
7010
  display: flex;
6766
7011
  align-items: center;
6767
- gap: 6px;
7012
+ gap: var(--sf-pad-6);
6768
7013
  }
6769
7014
  .reasoning-entry-badge {
6770
- font-size: 9px;
7015
+ font-size: var(--sf-text-9);
7016
+
6771
7017
  font-family: var(--font-mono);
6772
7018
  font-weight: 700;
6773
7019
  letter-spacing: 0.1em;
6774
- padding: 1px 5px;
6775
- border-radius: 4px;
7020
+ padding: 1px var(--sf-pad-5);
7021
+
7022
+ border-radius: var(--sf-radius-4);
7023
+
6776
7024
  flex-shrink: 0;
6777
7025
  }
6778
7026
  /* Thinking badge — cyan tint */
6779
7027
  .reasoning-entry-badge.badge-think {
6780
- background: rgba(0, 212, 255, 0.1);
7028
+ background: var(--sf-cyan-10);
6781
7029
  color: var(--accent-cyan);
6782
- border: 1px solid rgba(0, 212, 255, 0.18);
7030
+ border: 1px solid var(--sf-cyan-18);
6783
7031
  }
6784
7032
  /* Tool call badge — purple tint */
6785
7033
  .reasoning-entry-badge.badge-tool {
6786
- background: rgba(139, 92, 246, 0.12);
7034
+ background: var(--sf-violet-12);
6787
7035
  color: var(--accent-purple);
6788
- border: 1px solid rgba(139, 92, 246, 0.2);
7036
+ border: 1px solid var(--sf-violet-20);
6789
7037
  }
6790
7038
  /* Tool result badge — green tint */
6791
7039
  .reasoning-entry-badge.badge-result {
6792
- background: rgba(52, 211, 153, 0.1);
7040
+ background: var(--sf-green-10);
6793
7041
  color: var(--accent-green);
6794
- border: 1px solid rgba(52, 211, 153, 0.18);
7042
+ border: 1px solid var(--sf-green-18);
6795
7043
  }
6796
7044
  /* Narration badge — dim white tint */
6797
7045
  .reasoning-entry-badge.badge-narration {
6798
- background: rgba(255, 255, 255, 0.06);
7046
+ background: var(--sf-white-06);
6799
7047
  color: var(--text-muted);
6800
- border: 1px solid rgba(255, 255, 255, 0.1);
7048
+ border: 1px solid var(--sf-white-10);
6801
7049
  }
6802
7050
 
6803
7051
  .reasoning-entry-name {
6804
- font-size: 11px;
7052
+ font-size: var(--sf-text-11);
7053
+
6805
7054
  font-family: var(--font-mono);
6806
7055
  color: var(--text-muted);
6807
7056
  white-space: nowrap;
@@ -6812,48 +7061,55 @@ body {
6812
7061
 
6813
7062
  /* Thinking body */
6814
7063
  .reasoning-think-body {
6815
- font-size: 10px;
7064
+ font-size: var(--sf-text-10);
7065
+
6816
7066
  font-family: var(--font-mono);
6817
7067
  color: var(--text-muted);
6818
7068
  line-height: 1.55;
6819
7069
  white-space: pre-wrap;
6820
7070
  word-break: break-word;
6821
- max-height: 120px;
7071
+ max-height: var(--sf-bound-detail);
7072
+
6822
7073
  overflow-y: auto;
6823
- padding: 4px 2px 0;
7074
+ padding: var(--sf-pad-4) var(--sf-pad-2) 0;
7075
+
6824
7076
  opacity: 0.75;
6825
7077
  scrollbar-width: thin;
6826
- scrollbar-color: rgba(0, 212, 255, 0.15) transparent;
7078
+ scrollbar-color: var(--sf-cyan-15) transparent;
6827
7079
  }
6828
7080
  .reasoning-think-body::-webkit-scrollbar {
6829
7081
  width: 2px;
6830
7082
  }
6831
7083
  .reasoning-think-body::-webkit-scrollbar-thumb {
6832
- background: rgba(0, 212, 255, 0.15);
6833
- border-radius: 2px;
7084
+ background: var(--sf-cyan-15);
7085
+ border-radius: var(--sf-radius-2);
6834
7086
  }
6835
7087
 
6836
7088
  /* Tool detail — compact JSON preview, collapsible */
6837
7089
  .reasoning-tool-preview {
6838
- font-size: 10px;
7090
+ font-size: var(--sf-text-10);
7091
+
6839
7092
  font-family: var(--font-mono);
6840
7093
  color: var(--text-muted);
6841
7094
  opacity: 0.65;
6842
7095
  white-space: nowrap;
6843
7096
  overflow: hidden;
6844
7097
  text-overflow: ellipsis;
6845
- padding: 2px 0 0;
7098
+ padding: var(--sf-pad-2) 0 0;
6846
7099
  }
6847
7100
  .reasoning-tool-detail {
6848
7101
  display: none;
6849
- font-size: 10px;
7102
+ font-size: var(--sf-text-10);
7103
+
6850
7104
  font-family: var(--font-mono);
6851
7105
  color: var(--text-muted);
6852
7106
  white-space: pre-wrap;
6853
7107
  word-break: break-all;
6854
- padding: 4px 2px 0;
7108
+ padding: var(--sf-pad-4) var(--sf-pad-2) 0;
7109
+
6855
7110
  opacity: 0.65;
6856
- max-height: 100px;
7111
+ max-height: var(--sf-bound-tool);
7112
+
6857
7113
  overflow-y: auto;
6858
7114
  }
6859
7115
  .reasoning-entry.expanded .reasoning-tool-detail {
@@ -6865,10 +7121,10 @@ body {
6865
7121
 
6866
7122
  /* Result row */
6867
7123
  .reasoning-result-meta {
6868
- font-size: 10px;
7124
+ font-size: var(--sf-text-10);
6869
7125
  font-family: var(--font-mono);
6870
7126
  color: var(--text-dim);
6871
- padding: 2px 0 0;
7127
+ padding: var(--sf-pad-2) 0 0;
6872
7128
  }
6873
7129
 
6874
7130
  /* ── Lazy-load sentinel ──────────────────────────────────────────── */