@nomideusz/svelte-calendar 1.0.1 → 1.1.1

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.
@@ -21,7 +21,7 @@ import { createClock } from "../../core/clock.svelte.js";
21
21
  import { fitParts } from "../../text-fit.js";
22
22
  import { HOUR_MS, sod, addDaysMs, diffDays } from "../../core/time.js";
23
23
  import { startOfWeek as sowFn, isAllDay, segmentForDay } from "../../core/time.js";
24
- import { fmtH, fmtTime, fmtDuration, weekdayShort, weekdayLong } from "../../core/locale.js";
24
+ import { fmtHParts, fmtTime, fmtDuration, weekdayShort, weekdayLong } from "../../core/locale.js";
25
25
  let { mode = "week", mondayStart = true, locale, height = 520, events = [], style = "", focusDate, oneventclick, oneventcreate, onexternaldrop, selectedEventId = null, readOnly = false, visibleHours } = $props();
26
26
  // ── Context ────────────────────────────────────────
27
27
  const ctx = useCalendarContext();
@@ -78,8 +78,8 @@ function inAllDayStrip(ev) {
78
78
  return isAllDay(ev) || ev.end.getTime() >= addDaysMs(ev.start.getTime(), 1);
79
79
  }
80
80
  // ── Config ─────────────────────────────────────────
81
- const HOUR_H = 48;
82
- const GUTTER_W = 48;
81
+ const HOUR_H = 64;
82
+ const GUTTER_W = 60;
83
83
  const MIN_COL_W = $derived(ctx.minColumnWidth);
84
84
  const ALLDAY_MAX = 3;
85
85
  const startHour = $derived(visibleHours?.[0] ?? 0);
@@ -802,14 +802,14 @@ function onWindowKeydown(e) {
802
802
  onpointerenter={() => oneventhover?.(seg.ev)}
803
803
  >
804
804
  {#if !seg.isStart}
805
- <span class="tw-ad-cont" aria-hidden="true">◂</span>
805
+ <span class="tw-ad-cont" aria-hidden="true"><svg viewBox="0 0 8 8" width="8" height="8"><path d="M5.5 1.5 2.5 4l3 2.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" /></svg></span>
806
806
  {/if}
807
807
  <span class="tw-ad-title">{seg.ev.title}</span>
808
808
  {#if seg.totalDays > 1}
809
809
  <span class="tw-ad-span" aria-hidden="true">{seg.dayIndex}/{seg.totalDays}</span>
810
810
  {/if}
811
811
  {#if !seg.isEnd && seg.totalDays > 1}
812
- <span class="tw-ad-arrow" aria-hidden="true">▸</span>
812
+ <span class="tw-ad-arrow" aria-hidden="true"><svg viewBox="0 0 8 8" width="8" height="8"><path d="M2.5 1.5 5.5 4l-3 2.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" /></svg></span>
813
813
  {/if}
814
814
  </button>
815
815
  {/snippet}
@@ -887,7 +887,12 @@ function onWindowKeydown(e) {
887
887
  <div class="tw-gutter" style:width="{GUTTER_W}px" aria-hidden="true">
888
888
  {#each { length: hourCount } as _, i}
889
889
  {#if i > 0}
890
- <span class="tw-gutter-lb" style:top="{i * HOUR_H}px">{fmtH(startHour + i, locale)}</span>
890
+ {@const [hNum, hSuf] = fmtHParts(startHour + i, locale)}
891
+ <!-- an hour the now plate would half-cover gives way to it -->
892
+ <span
893
+ class="tw-gutter-lb"
894
+ class:tw-gutter-lb--under={nowY !== null && weekHasToday && Math.abs(i * HOUR_H - nowY) < 18}
895
+ style:top="{i * HOUR_H}px">{hNum}<small>{hSuf}</small></span>
891
896
  {/if}
892
897
  {/each}
893
898
  {#if axisGhost}
@@ -918,6 +923,10 @@ function onWindowKeydown(e) {
918
923
  <div class="tw-line" style:top="{i * HOUR_H}px"></div>
919
924
  <div class="tw-line tw-line--half" style:top="{i * HOUR_H + HOUR_H / 2}px"></div>
920
925
  {/each}
926
+ {#if nowY !== null && weekHasToday}
927
+ <!-- now, ruled across the whole week; today's column draws it solid -->
928
+ <div class="tw-now-week" style:top="{nowY}px"></div>
929
+ {/if}
921
930
  </div>
922
931
 
923
932
  {#each dayCols as day (day.ms)}
@@ -976,7 +985,7 @@ function onWindowKeydown(e) {
976
985
  style:height="{p.height}px"
977
986
  style:left="calc({(p.col / p.totalCols) * 100}% + 1px)"
978
987
  style:width="calc({100 / p.totalCols}% - {p.totalCols > 1 ? 3 : 8}px)"
979
- style:--ev-color={p.ev.color ?? 'var(--dt-accent)'}
988
+ style:--ev-color={p.ev.color ?? 'var(--dt-event, var(--dt-accent))'}
980
989
  role="button"
981
990
  tabindex="0"
982
991
  title={p.ev.title}
@@ -990,7 +999,7 @@ function onWindowKeydown(e) {
990
999
  <div class="tw-ev-body">
991
1000
  <EventContent event={p.ev}>
992
1001
  {@const parts = blockParts(p.ev, p.height)}
993
- <span class="tw-ev-time">{fmtTime(p.ev.start, locale)} – {fmtTime(p.ev.end, locale)}</span>
1002
+ <span class="tw-ev-time">{fmtTime(p.ev.start, locale)}<span class="tw-ev-end">{` – ${fmtTime(p.ev.end, locale)}`}</span></span>
994
1003
  <span class="tw-ev-title">{p.ev.title}</span>
995
1004
  {#if parts.room}
996
1005
  <span class="tw-ev-loc">{p.ev.location}</span>
@@ -1072,7 +1081,7 @@ function onWindowKeydown(e) {
1072
1081
  overflow: hidden;
1073
1082
  user-select: none;
1074
1083
  font-variant-numeric: tabular-nums;
1075
- background: var(--dt-bg, #ffffff);
1084
+ background: var(--dt-paper, none), var(--dt-bg, #ffffff);
1076
1085
  -webkit-tap-highlight-color: transparent;
1077
1086
  }
1078
1087
  .tw--auto { overflow: visible; }
@@ -1110,7 +1119,7 @@ function onWindowKeydown(e) {
1110
1119
  position: sticky;
1111
1120
  top: 0;
1112
1121
  z-index: 30;
1113
- background: var(--dt-bg, #ffffff);
1122
+ background: var(--dt-paper, none), var(--dt-bg, #ffffff);
1114
1123
  border-bottom: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
1115
1124
  }
1116
1125
 
@@ -1124,7 +1133,7 @@ function onWindowKeydown(e) {
1124
1133
  position: sticky;
1125
1134
  left: 0;
1126
1135
  z-index: 2;
1127
- background: var(--dt-bg, #ffffff);
1136
+ background: var(--dt-paper, none), var(--dt-bg, #ffffff);
1128
1137
  }
1129
1138
 
1130
1139
  .tw-hd {
@@ -1133,36 +1142,34 @@ function onWindowKeydown(e) {
1133
1142
  display: flex;
1134
1143
  flex-direction: column;
1135
1144
  align-items: center;
1136
- gap: 2px;
1137
- padding: 8px 4px 6px;
1145
+ gap: 4px;
1146
+ padding: 14px 4px 12px;
1138
1147
  border-left: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
1139
1148
  }
1140
1149
 
1141
1150
  .tw-hd-wd {
1142
- font: 500 10px/1 var(--dt-sans, system-ui, sans-serif);
1143
- letter-spacing: 0.06em;
1151
+ font: 500 12px/1 var(--dt-sans, system-ui, sans-serif);
1152
+ letter-spacing: 0.08em;
1144
1153
  text-transform: uppercase;
1145
- color: var(--dt-text-3, rgba(0, 0, 0, 0.38));
1154
+ color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1146
1155
  }
1147
1156
  .tw-hd--today .tw-hd-wd {
1148
1157
  color: var(--dt-accent, #2563eb);
1149
- font-weight: 600;
1150
1158
  }
1151
1159
 
1160
+ /* The day number is the typography of the grid: large, regular weight. */
1152
1161
  .tw-hd-num {
1153
1162
  display: inline-flex;
1154
1163
  align-items: center;
1155
1164
  justify-content: center;
1156
- min-width: 26px;
1157
- height: 26px;
1158
- border-radius: 50%;
1159
- font: 600 14px/1 var(--dt-sans, system-ui, sans-serif);
1165
+ font: 400 40px/1 var(--dt-sans, system-ui, sans-serif);
1166
+ font-stretch: 90%;
1167
+ letter-spacing: -0.02em;
1160
1168
  color: var(--dt-text, rgba(0, 0, 0, 0.87));
1161
1169
  }
1170
+ /* Today: the numeral in the accent, nothing else. */
1162
1171
  .tw-hd-num--today {
1163
- background: var(--dt-accent, #2563eb);
1164
- color: var(--dt-accent-fg, var(--dt-btn-text, #ffffff));
1165
- font-weight: 700;
1172
+ color: var(--dt-accent, #2563eb);
1166
1173
  }
1167
1174
 
1168
1175
  .tw-hd-custom {
@@ -1178,14 +1185,17 @@ function onWindowKeydown(e) {
1178
1185
 
1179
1186
  .tw-ad-gutter {
1180
1187
  flex-shrink: 0;
1188
+ /* The padding sits inside the gutter's width, so the all-day cells
1189
+ start where the day columns and headers start. */
1190
+ box-sizing: border-box;
1181
1191
  position: sticky;
1182
1192
  left: 0;
1183
1193
  z-index: 2;
1184
- background: var(--dt-bg, #ffffff);
1194
+ background: var(--dt-paper, none), var(--dt-bg, #ffffff);
1185
1195
  display: flex;
1186
1196
  align-items: flex-start;
1187
1197
  justify-content: flex-end;
1188
- padding: 4px 6px 4px 0;
1198
+ padding: 6px 8px 6px 0;
1189
1199
  }
1190
1200
  .tw-ad-gutter-lb {
1191
1201
  font: 500 10px/1.2 var(--dt-sans, system-ui, sans-serif);
@@ -1199,7 +1209,7 @@ function onWindowKeydown(e) {
1199
1209
  display: flex;
1200
1210
  flex-direction: column;
1201
1211
  gap: 2px;
1202
- padding: 3px 3px 4px;
1212
+ padding: 4px 0 5px;
1203
1213
  border-left: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
1204
1214
  }
1205
1215
  .tw-ad-cell--today { background: var(--dt-today-bg, rgba(37, 99, 235, 0.04)); }
@@ -1208,42 +1218,46 @@ function onWindowKeydown(e) {
1208
1218
  appearance: none;
1209
1219
  display: flex;
1210
1220
  align-items: center;
1211
- gap: 3px;
1212
- padding: 2px 6px;
1213
- min-height: 18px;
1221
+ gap: 4px;
1222
+ padding: 0 10px;
1223
+ min-height: 36px;
1214
1224
  border: none;
1215
- border-radius: 3px;
1216
- background: color-mix(in srgb, var(--ev-color) 22%, var(--dt-surface, var(--dt-bg, #ffffff)));
1217
- border-left: 2.5px solid var(--ev-color);
1225
+ border-radius: 0;
1226
+ /* The paper's grain runs through the band (multiply keeps the colour). */
1227
+ background: var(--dt-paper, none) var(--ev-color);
1228
+ background-blend-mode: multiply;
1229
+ color: var(--dt-btn-text, #fff);
1218
1230
  cursor: pointer;
1219
1231
  overflow: hidden;
1220
1232
  text-align: left;
1221
- transition: background 0.12s;
1233
+ transition: filter 0.12s;
1222
1234
  -webkit-tap-highlight-color: transparent;
1223
1235
  }
1224
1236
  .tw-ad:hover {
1225
- background: color-mix(in srgb, var(--ev-color) 32%, var(--dt-surface, var(--dt-bg, #ffffff)));
1237
+ filter: brightness(1.08);
1226
1238
  }
1239
+ /* A span continues across its days as one band: no edge between segments. */
1227
1240
  .tw-ad--mid,
1228
1241
  .tw-ad--end:not(.tw-ad--start) {
1229
- border-left: 1px dashed color-mix(in srgb, var(--ev-color) 40%, transparent);
1230
- border-radius: 0 3px 3px 0;
1242
+ margin-left: -1px;
1231
1243
  }
1232
1244
  .tw-ad--selected {
1233
- box-shadow: 0 0 0 1.5px var(--ev-color);
1245
+ box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff);
1234
1246
  }
1235
1247
  .tw-ad--cancelled .tw-ad-title {
1236
1248
  text-decoration: line-through;
1237
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1249
+ }
1250
+ .tw-ad--cancelled {
1251
+ background: color-mix(in srgb, var(--ev-color) 55%, var(--dt-bg, #fff));
1238
1252
  }
1239
1253
  .tw-ad:focus-visible {
1240
1254
  outline: none;
1241
- box-shadow: 0 0 0 2px var(--dt-accent, #2563eb);
1255
+ box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff), 0 0 0 2px var(--dt-accent, #2563eb);
1242
1256
  }
1243
1257
 
1244
1258
  .tw-ad-title {
1245
- font: 500 11px/1.2 var(--dt-sans, system-ui, sans-serif);
1246
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1259
+ font: 500 13.5px/1.2 var(--dt-sans, system-ui, sans-serif);
1260
+ color: inherit;
1247
1261
  white-space: nowrap;
1248
1262
  overflow: hidden;
1249
1263
  text-overflow: ellipsis;
@@ -1251,16 +1265,29 @@ function onWindowKeydown(e) {
1251
1265
  min-width: 0;
1252
1266
  }
1253
1267
  .tw-ad-span {
1254
- font: 400 10px/1 var(--dt-sans, system-ui, sans-serif);
1255
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1268
+ font: 400 11px/1 var(--dt-sans, system-ui, sans-serif);
1269
+ font-variant-numeric: tabular-nums;
1270
+ color: inherit;
1271
+ opacity: 0.75;
1256
1272
  flex-shrink: 0;
1257
1273
  }
1274
+ .tw-ad--mid .tw-ad-title,
1275
+ .tw-ad--end:not(.tw-ad--start) .tw-ad-title {
1276
+ visibility: hidden;
1277
+ }
1278
+ .tw-ad-gutter + .tw-ad-cell .tw-ad-title {
1279
+ visibility: visible;
1280
+ }
1281
+ .tw-ad-span,
1258
1282
  .tw-ad-cont,
1259
1283
  .tw-ad-arrow {
1260
- font-size: 10px;
1261
- color: var(--ev-color);
1284
+ display: none;
1285
+ }
1286
+ .tw-ad-arrow {
1287
+ display: none;
1288
+ color: inherit;
1289
+ opacity: 0.75;
1262
1290
  flex-shrink: 0;
1263
- line-height: 1;
1264
1291
  }
1265
1292
  .tw-ad-arrow { margin-left: auto; }
1266
1293
 
@@ -1295,18 +1322,46 @@ function onWindowKeydown(e) {
1295
1322
  position: sticky;
1296
1323
  left: 0;
1297
1324
  z-index: 20;
1298
- background: var(--dt-bg, #ffffff);
1325
+ background: var(--dt-paper, none), var(--dt-bg, #ffffff);
1299
1326
  border-right: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
1300
1327
  }
1301
1328
 
1329
+ /* Timetable hour: the numeral carries the rank, the suffix sits raised
1330
+ and small beside it. */
1302
1331
  .tw-gutter-lb {
1303
1332
  position: absolute;
1304
- right: 6px;
1333
+ left: 6px;
1334
+ right: 0;
1305
1335
  transform: translateY(-50%);
1306
- font: 500 11px/1 var(--dt-mono, ui-monospace, monospace);
1307
- color: var(--dt-text-3, rgba(0, 0, 0, 0.38));
1336
+ display: flex;
1337
+ align-items: flex-start;
1338
+ gap: 2px;
1339
+ font: 400 26px/1 var(--dt-sans, system-ui, sans-serif);
1340
+ font-stretch: 85%;
1341
+ font-variant-numeric: tabular-nums;
1342
+ letter-spacing: -0.02em;
1343
+ color: var(--dt-text, rgba(0, 0, 0, 0.87));
1308
1344
  white-space: nowrap;
1309
1345
  }
1346
+ .tw-gutter-lb::after {
1347
+ content: '';
1348
+ flex: 1;
1349
+ min-width: 6px;
1350
+ height: 1px;
1351
+ margin-left: 5px;
1352
+ align-self: center;
1353
+ background: var(--dt-border-day, rgba(0, 0, 0, 0.3));
1354
+ }
1355
+ .tw-gutter-lb--under {
1356
+ visibility: hidden;
1357
+ }
1358
+ .tw-gutter-lb small {
1359
+ font-size: 10px;
1360
+ font-weight: 500;
1361
+ line-height: 1;
1362
+ letter-spacing: 0;
1363
+ color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1364
+ }
1310
1365
 
1311
1366
  /* The clock beside the now line, and the drag's edges while it lasts —
1312
1367
  both sit on the surface so they cover the hour label beneath. */
@@ -1315,18 +1370,19 @@ function onWindowKeydown(e) {
1315
1370
  position: absolute;
1316
1371
  right: 3px;
1317
1372
  transform: translateY(-50%);
1318
- padding: 1px 3px;
1319
- border-radius: 3px;
1373
+ padding: 2px 4px;
1374
+ border-radius: 0;
1320
1375
  background: var(--dt-surface, var(--dt-bg, #fff));
1321
- font: 600 10px/1.2 var(--dt-mono, ui-monospace, monospace);
1376
+ font: 500 11px/1.2 var(--dt-sans, system-ui, sans-serif);
1377
+ font-variant-numeric: tabular-nums;
1322
1378
  color: var(--dt-accent, #2563eb);
1323
1379
  white-space: nowrap;
1324
1380
  z-index: 2;
1325
1381
  }
1382
+ /* The clock is a reversed plate on the accent, like a board's live time. */
1326
1383
  .tw-gutter-now {
1327
- opacity: 0.75;
1328
- transform: translateY(-50%);
1329
- z-index: 2;
1384
+ background: var(--dt-accent, #2563eb);
1385
+ color: var(--dt-btn-text, #ffffff);
1330
1386
  }
1331
1387
 
1332
1388
  /* ─── Columns wrapper ────────────────────────────── */
@@ -1353,6 +1409,15 @@ function onWindowKeydown(e) {
1353
1409
  background: var(--dt-border, rgba(0, 0, 0, 0.08));
1354
1410
  }
1355
1411
  .tw-line--half { opacity: 0.4; }
1412
+ .tw-now-week {
1413
+ position: absolute;
1414
+ left: 0;
1415
+ right: 0;
1416
+ height: 0;
1417
+ border-top: 2px solid var(--dt-accent, #2563eb);
1418
+ opacity: 0.85;
1419
+ transform: translateY(-1px);
1420
+ }
1356
1421
 
1357
1422
  /* ─── Day column ─────────────────────────────────── */
1358
1423
  .tw-col {
@@ -1372,7 +1437,7 @@ function onWindowKeydown(e) {
1372
1437
  }
1373
1438
  /* What has already happened steps back; a cancelled block keeps its own look. */
1374
1439
  .tw-ev--past:not(.tw-ev--cancelled) {
1375
- opacity: 0.6;
1440
+ opacity: 0.78;
1376
1441
  }
1377
1442
  .tw-col--weekend:not(.tw-col--today):not(.tw-col--past) {
1378
1443
  background: var(--dt-weekend-bg, rgba(0, 0, 0, 0.012));
@@ -1421,8 +1486,7 @@ function onWindowKeydown(e) {
1421
1486
  left: 0;
1422
1487
  right: 0;
1423
1488
  height: 0;
1424
- border-top: 1px dotted var(--dt-accent, #2563eb);
1425
- opacity: 0.7;
1489
+ border-top: 2px solid var(--dt-accent, #2563eb);
1426
1490
  z-index: 12;
1427
1491
  pointer-events: none;
1428
1492
  transform: translateY(-1px);
@@ -1430,7 +1494,7 @@ function onWindowKeydown(e) {
1430
1494
  .tw-now-dot {
1431
1495
  position: absolute;
1432
1496
  left: -4px;
1433
- top: -3px;
1497
+ top: -5px;
1434
1498
  width: 8px;
1435
1499
  height: 8px;
1436
1500
  border-radius: 50%;
@@ -1441,8 +1505,8 @@ function onWindowKeydown(e) {
1441
1505
  .tw-ev {
1442
1506
  position: absolute;
1443
1507
  z-index: 6;
1444
- border-radius: 5px;
1445
- background: color-mix(in srgb, var(--ev-color) 14%, var(--dt-surface, var(--dt-bg, #ffffff)));
1508
+ border-radius: 0;
1509
+ background: transparent;
1446
1510
  display: flex;
1447
1511
  align-items: stretch;
1448
1512
  overflow: hidden;
@@ -1455,7 +1519,7 @@ function onWindowKeydown(e) {
1455
1519
  -webkit-tap-highlight-color: transparent;
1456
1520
  }
1457
1521
  .tw-ev:hover {
1458
- background: color-mix(in srgb, var(--ev-color) 24%, var(--dt-surface, var(--dt-bg, #ffffff)));
1522
+ background: var(--dt-hover, rgba(0, 0, 0, 0.04));
1459
1523
  z-index: 8;
1460
1524
  }
1461
1525
  /* Short blocks keep duration-proportional height, but get a 44px
@@ -1471,12 +1535,11 @@ function onWindowKeydown(e) {
1471
1535
  height: 44px;
1472
1536
  }
1473
1537
  .tw-ev--selected {
1474
- box-shadow: 0 0 0 2px var(--ev-color),
1475
- 0 2px 12px color-mix(in srgb, var(--ev-color) 25%, transparent);
1538
+ box-shadow: inset 0 0 0 1px var(--ev-color);
1476
1539
  z-index: 9;
1477
1540
  }
1478
1541
  .tw-ev--current {
1479
- background: color-mix(in srgb, var(--ev-color) 22%, var(--dt-surface, var(--dt-bg, #ffffff)));
1542
+ background: var(--dt-accent-dim, rgba(37, 99, 235, 0.12));
1480
1543
  }
1481
1544
  .tw-ev--resizing {
1482
1545
  z-index: 50;
@@ -1491,40 +1554,39 @@ function onWindowKeydown(e) {
1491
1554
  }
1492
1555
  /* Status treatments: token-level dims + a non-opacity signal
1493
1556
  (strikethrough / border style) — consistent with the other views. */
1494
- .tw-ev--cancelled {
1495
- background: color-mix(in srgb, var(--ev-color) 5%, var(--dt-surface, var(--dt-bg, #ffffff)));
1496
- }
1557
+ /* Printed states: a cancelled class is struck through and stays on the
1558
+ grid; a tentative one is set in grey with a dashed bar. */
1497
1559
  .tw-ev--cancelled .tw-ev-title {
1498
1560
  text-decoration: line-through;
1499
1561
  color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1500
1562
  }
1501
1563
  .tw-ev--cancelled .tw-ev-stripe { opacity: 0.45; /* decorative bar only */ }
1502
- .tw-ev--tentative {
1503
- background: color-mix(in srgb, var(--ev-color) 6%, var(--dt-surface, var(--dt-bg, #ffffff)));
1504
- border: 1px dashed color-mix(in srgb, var(--ev-color) 45%, transparent);
1505
- }
1506
- .tw-ev--full {
1507
- background: color-mix(in srgb, var(--ev-color) 6%, var(--dt-surface, var(--dt-bg, #ffffff)));
1508
- border: 1px solid color-mix(in srgb, var(--ev-color) 30%, transparent);
1564
+ .tw-ev--tentative .tw-ev-title,
1565
+ .tw-ev--full .tw-ev-title {
1566
+ color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1509
1567
  }
1510
- .tw-ev--full .tw-ev-title { color: var(--dt-text-2, rgba(0, 0, 0, 0.54)); }
1511
- .tw-ev--limited {
1512
- background: color-mix(in srgb, var(--ev-color) 8%, var(--dt-surface, var(--dt-bg, #ffffff)));
1513
- border: 1px dashed color-mix(in srgb, var(--ev-color) 45%, transparent);
1568
+ .tw-ev--tentative .tw-ev-stripe,
1569
+ .tw-ev--limited .tw-ev-stripe {
1570
+ background: repeating-linear-gradient(
1571
+ 180deg,
1572
+ var(--ev-color) 0 4px,
1573
+ transparent 4px 7px
1574
+ );
1514
1575
  }
1576
+ .tw-ev--full .tw-ev-stripe { opacity: 0.45; }
1515
1577
  .tw-ev--readonly { cursor: default; }
1516
1578
 
1517
1579
  .tw-ev-stripe {
1518
1580
  width: 3px;
1519
1581
  background: var(--ev-color);
1520
1582
  flex-shrink: 0;
1521
- border-radius: 5px 0 0 5px;
1522
1583
  }
1523
1584
 
1524
1585
  .tw-ev-body {
1586
+ container: tw-ev / inline-size;
1525
1587
  flex: 1;
1526
1588
  min-width: 0;
1527
- padding: 3px 6px;
1589
+ padding: 3px 7px;
1528
1590
  display: flex;
1529
1591
  flex-direction: column;
1530
1592
  gap: 1px;
@@ -1539,16 +1601,24 @@ function onWindowKeydown(e) {
1539
1601
  padding-bottom: 1px;
1540
1602
  }
1541
1603
 
1604
+ /* Title first, time under it; both one size, rank by weight and ink. */
1542
1605
  .tw-ev-time {
1543
- font: 400 11px/1.1 var(--dt-mono, ui-monospace, monospace);
1544
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1606
+ order: 1;
1607
+ font: 400 14px/1.2 var(--dt-sans, system-ui, sans-serif);
1608
+ font-variant-numeric: tabular-nums;
1609
+ color: var(--dt-text, rgba(0, 0, 0, 0.87));
1545
1610
  white-space: nowrap;
1546
1611
  flex-shrink: 0;
1547
1612
  }
1548
1613
  .tw-ev--compact .tw-ev-time { order: 0; }
1614
+ /* A narrow overlap column keeps the start time whole and drops the end. */
1615
+ @container tw-ev (max-width: 104px) {
1616
+ .tw-ev-end { display: none; }
1617
+ }
1549
1618
 
1550
1619
  .tw-ev-title {
1551
- font: 600 12px/1.2 var(--dt-sans, system-ui, sans-serif);
1620
+ order: 0;
1621
+ font: 500 15px/1.25 var(--dt-sans, system-ui, sans-serif);
1552
1622
  color: var(--dt-text, rgba(0, 0, 0, 0.87));
1553
1623
  white-space: nowrap;
1554
1624
  overflow: hidden;
@@ -1556,8 +1626,9 @@ function onWindowKeydown(e) {
1556
1626
  }
1557
1627
 
1558
1628
  .tw-ev-loc {
1559
- font: 400 10px/1.2 var(--dt-sans, system-ui, sans-serif);
1560
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1629
+ order: 2;
1630
+ font: 400 12.5px/1.2 var(--dt-sans, system-ui, sans-serif);
1631
+ color: var(--dt-text, rgba(0, 0, 0, 0.87));
1561
1632
  white-space: nowrap;
1562
1633
  overflow: hidden;
1563
1634
  text-overflow: ellipsis;
@@ -1641,8 +1712,8 @@ function onWindowKeydown(e) {
1641
1712
  left: 1px;
1642
1713
  right: 3px;
1643
1714
  z-index: 40;
1644
- border-radius: 5px;
1645
- background: color-mix(in srgb, var(--ev-color) 22%, var(--dt-surface, var(--dt-bg, #ffffff)));
1715
+ border-radius: 0;
1716
+ background: color-mix(in srgb, var(--ev-color) 12%, var(--dt-surface, var(--dt-bg, #ffffff)));
1646
1717
  outline: 1px solid color-mix(in srgb, var(--ev-color) 45%, transparent);
1647
1718
  box-shadow: 0 6px 18px color-mix(in srgb, var(--ev-color) 24%, rgba(0, 0, 0, 0.22));
1648
1719
  display: flex;
@@ -1660,7 +1731,8 @@ function onWindowKeydown(e) {
1660
1731
  box-shadow: none;
1661
1732
  }
1662
1733
  .tw-ghost-time {
1663
- font: 600 11px/1.1 var(--dt-mono, ui-monospace, monospace);
1734
+ font: 700 12px/1.15 var(--dt-sans, system-ui, sans-serif);
1735
+ font-variant-numeric: tabular-nums;
1664
1736
  color: var(--ev-color, var(--dt-accent, #2563eb));
1665
1737
  white-space: nowrap;
1666
1738
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomideusz/svelte-calendar",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "A themeable Svelte 5 calendar: day, week, scrolling-week and month views, agenda lists, touch-first mobile layouts, drag-and-drop, timezones, a headless API and an embeddable web component.",
5
5
  "type": "module",
6
6
  "sideEffects": [