@nomideusz/svelte-calendar 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,7 +34,7 @@ Requirements:
34
34
  ]);
35
35
  </script>
36
36
 
37
- <Calendar {adapter} />
37
+ <Calendar {adapter} view="week-planner" />
38
38
  ```
39
39
 
40
40
  That's it — 8 built-in views, auto-coloring, drag-and-drop with live previews, all out of the box. The default `auto` theme probes your page's background, accent color and fonts, so the calendar adapts to any design.
@@ -151,7 +151,7 @@ When the calendar's **container** is narrower than 768px, it swaps to touch-firs
151
151
 
152
152
  ```svelte
153
153
  <!-- Auto-detect (default) — switches at a 768px container width -->
154
- <Calendar {adapter} />
154
+ <Calendar {adapter} view="week-planner" />
155
155
 
156
156
  <!-- Force mobile layout -->
157
157
  <Calendar {adapter} mobile={true} />
@@ -564,7 +564,7 @@ For fixed repeating events (class timetables, office hours):
564
564
  ]);
565
565
  </script>
566
566
 
567
- <Calendar {adapter} />
567
+ <Calendar {adapter} view="week-planner" />
568
568
  ```
569
569
 
570
570
  <details>
@@ -479,6 +479,34 @@ const dateLabel = $derived.by(() => {
479
479
  year: "numeric"
480
480
  });
481
481
  });
482
+ // ── Period title (the built-in header's big line) ──
483
+ // Names the month the user is looking at: "October 2026"; a week across two
484
+ // months reads "Oct – Nov 2026"; a day gives its date. `dateLabel` keeps the
485
+ // exact range for the header snippet and the screen-reader status line.
486
+ const periodTitle = $derived.by(() => {
487
+ if (!showDates) return "";
488
+ const loc = locale ?? getDefaultLocale();
489
+ if (viewState.mode === "day") {
490
+ return viewState.focusDate.toLocaleDateString(loc, {
491
+ weekday: useMobile ? "short" : "long",
492
+ month: "long",
493
+ day: "numeric",
494
+ year: "numeric"
495
+ });
496
+ }
497
+ const s = viewState.mode === "week" ? viewState.range.start : viewState.focusDate;
498
+ const e = viewState.mode === "week" ? new Date(viewState.range.end.getTime() - 1) : s;
499
+ if (s.getMonth() === e.getMonth() && s.getFullYear() === e.getFullYear()) {
500
+ return s.toLocaleDateString(loc, {
501
+ month: "long",
502
+ year: "numeric"
503
+ });
504
+ }
505
+ return new Intl.DateTimeFormat(loc, {
506
+ month: "short",
507
+ year: "numeric"
508
+ }).formatRange(s, e).replace(/[  ]/g, " ");
509
+ });
482
510
  // Which modes are available?
483
511
  const modes = $derived.by(() => {
484
512
  const g = new Set(desktopViews.map((v) => v.mode));
@@ -623,70 +651,50 @@ const navCtx = $derived({
623
651
  {#if headerSnippet}
624
652
  {@render headerSnippet(headerCtx)}
625
653
 
626
- <!-- ─── Mobile header (flow layout, no absolute) ─── -->
627
- {:else if useMobile && (showNavigation || (showModePills && modes.length > 1) || dateLabel)}
628
- {@const titleBelow = stackHeader && !!dateLabel}
629
- <div class="cal-m-hd" class:cal-m-hd--stack={stackHeader} class:cal-m-hd--titled={titleBelow}>
630
- <div class="cal-m-left">
631
- {#if showModePills && modes.length > 1}
632
- <div class="cal-m-pills" role="radiogroup" aria-label={L.viewMode}>
633
- {#each modes as g (g)}
634
- <button
635
- type="button"
636
- class="cal-m-pill"
637
- class:cal-m-pill--active={viewState.mode === g}
638
- role="radio"
639
- aria-checked={viewState.mode === g}
640
- onclick={() => switchMode(g)}
641
- >
642
- {g === 'day' ? L.day : g === 'week' ? L.week : L.month}
643
- </button>
644
- {/each}
645
- </div>
646
- {/if}
647
- </div>
648
-
649
- {#if !titleBelow}
650
- <span class="cal-m-title" role="status" aria-live="polite" aria-atomic="true">{dateLabel}</span>
654
+ <!-- ─── Built-in header: the period as the title, then view switch, then Today ‹ › ─── -->
655
+ {:else if showNavigation || (showModePills && modes.length > 1) || dateLabel}
656
+ <div class="cal-hd" class:cal-hd--mobile={useMobile} class:cal-hd--stack={stackHeader}>
657
+ <!-- The visible title names the month; the status line announces the exact range -->
658
+ <span class="cal-hd-title" aria-hidden="true">{periodTitle}</span>
659
+ <span class="cal-sr" role="status" aria-live="polite" aria-atomic="true">{dateLabel}</span>
660
+ {#if showModePills && !useMobile && labelsForMode.length > 1}
661
+ <!-- View-type switcher (e.g. Planner ↔ Agenda) for the current mode -->
662
+ <div class="cal-pills cal-pills--labels" role="radiogroup" aria-label={L.viewMode}>
663
+ {#each labelsForMode as label (label)}
664
+ <button
665
+ type="button"
666
+ class="cal-pill"
667
+ class:cal-pill--active={activeView?.label === label}
668
+ role="radio"
669
+ aria-checked={activeView?.label === label}
670
+ onclick={() => switchLabel(label)}
671
+ >
672
+ {viewLabel(label)}
673
+ </button>
674
+ {/each}
675
+ </div>
651
676
  {/if}
652
-
653
- <div class="cal-m-right">
677
+ {#if showModePills && modes.length > 1}
678
+ <div class="cal-pills" role="radiogroup" aria-label={L.viewMode}>
679
+ {#each modes as g (g)}
680
+ <button
681
+ type="button"
682
+ class="cal-pill"
683
+ class:cal-pill--active={viewState.mode === g}
684
+ role="radio"
685
+ aria-checked={viewState.mode === g}
686
+ onclick={() => switchMode(g)}
687
+ >
688
+ {g === 'day' ? L.day : g === 'week' ? L.week : L.month}
689
+ </button>
690
+ {/each}
691
+ </div>
692
+ {/if}
693
+ <div class="cal-hd-nav">
654
694
  {#if navigationSnippet}
655
695
  {@render navigationSnippet(navCtx)}
656
696
  {:else if showNavigation}
657
697
  <!-- Always rendered (disabled on today) so navigating never shifts layout -->
658
- <button
659
- type="button"
660
- class="cal-m-today"
661
- onclick={() => viewState.goToday()}
662
- disabled={viewIncludesToday}
663
- title={L.goToToday}
664
- >
665
- {L.today}
666
- </button>
667
- <button type="button" class="cal-m-nav" onclick={() => viewState.prev()} aria-label={viewState.mode === 'day' ? L.previousDay : viewState.mode === 'month' ? L.previousMonth : L.previousWeek}>
668
- <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" width="16" height="16" aria-hidden="true"><path d="M10 3 5 8l5 5"/></svg>
669
- </button>
670
- <button type="button" class="cal-m-nav" onclick={() => viewState.next()} aria-label={viewState.mode === 'day' ? L.nextDay : viewState.mode === 'month' ? L.nextMonth : L.nextWeek}>
671
- <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" width="16" height="16" aria-hidden="true"><path d="M6 3l5 5-5 5"/></svg>
672
- </button>
673
- {/if}
674
- </div>
675
- </div>
676
- {#if titleBelow}
677
- <div class="cal-m-titlebar">
678
- <span class="cal-m-title" role="status" aria-live="polite" aria-atomic="true">{dateLabel}</span>
679
- </div>
680
- {/if}
681
-
682
- <!-- ─── Desktop header ─── -->
683
- {:else if showNavigation || (showModePills && modes.length > 1) || dateLabel}
684
- <div class="cal-hd">
685
- <div class="cal-hd-side">
686
- {#if navigationSnippet}
687
- {@render navigationSnippet(navCtx)}
688
- {:else if showNavigation}
689
- <!-- Always rendered (disabled on today) so navigating never shifts the centered title -->
690
698
  <button
691
699
  type="button"
692
700
  class="cal-hd-today"
@@ -704,42 +712,6 @@ const navCtx = $derived({
704
712
  </button>
705
713
  {/if}
706
714
  </div>
707
- <span class="cal-hd-title" role="status" aria-live="polite" aria-atomic="true">{dateLabel}</span>
708
- <div class="cal-hd-side cal-hd-side--end">
709
- {#if showModePills && labelsForMode.length > 1}
710
- <!-- View-type switcher (e.g. Planner ↔ Agenda) for the current mode -->
711
- <div class="cal-pills cal-pills--labels" role="radiogroup" aria-label={L.viewMode}>
712
- {#each labelsForMode as label (label)}
713
- <button
714
- type="button"
715
- class="cal-pill"
716
- class:cal-pill--active={activeView?.label === label}
717
- role="radio"
718
- aria-checked={activeView?.label === label}
719
- onclick={() => switchLabel(label)}
720
- >
721
- {viewLabel(label)}
722
- </button>
723
- {/each}
724
- </div>
725
- {/if}
726
- {#if showModePills && modes.length > 1}
727
- <div class="cal-pills" role="radiogroup" aria-label={L.viewMode}>
728
- {#each modes as g (g)}
729
- <button
730
- type="button"
731
- class="cal-pill"
732
- class:cal-pill--active={viewState.mode === g}
733
- role="radio"
734
- aria-checked={viewState.mode === g}
735
- onclick={() => switchMode(g)}
736
- >
737
- {g === 'day' ? L.day : g === 'week' ? L.week : L.month}
738
- </button>
739
- {/each}
740
- </div>
741
- {/if}
742
- </div>
743
715
  </div>
744
716
  {/if}
745
717
 
@@ -792,118 +764,186 @@ const navCtx = $derived({
792
764
  }
793
765
 
794
766
 
795
- /* ── Desktop header ── */
767
+ /* ── Header: the period set large as the page's title, the view switch as
768
+ plain text, Today ‹ › in 2px ink frames, one rule to the grid. ── */
796
769
  .cal-hd {
770
+ /* Controls take a small corner that follows the calendar's own radius */
771
+ --cal-ctl-r: clamp(4px, calc(var(--cal-r, 0px) / 2), 8px);
772
+ --cal-ctl-h: 36px;
797
773
  display: flex;
798
774
  flex-wrap: wrap;
799
775
  align-items: center;
800
- gap: 8px;
801
- padding: 6px 10px;
802
- min-height: 44px;
803
- box-sizing: border-box;
776
+ gap: 10px 24px;
777
+ padding: 14px 16px 12px;
804
778
  border-bottom: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
805
779
  flex-shrink: 0;
806
- }
807
-
808
- .cal-hd-side {
809
- display: flex;
810
- align-items: center;
811
- gap: 4px;
812
- flex: 1;
813
- min-width: 0;
814
- }
815
-
816
- .cal-hd-side--end {
817
- justify-content: flex-end;
780
+ box-sizing: border-box;
781
+ font-family: var(--dt-sans, system-ui, sans-serif);
782
+ color: var(--dt-text, rgba(0, 0, 0, 0.87));
818
783
  }
819
784
 
820
785
  .cal-hd-title {
821
- font: 500 16px/1.2 var(--dt-sans, system-ui, sans-serif);
786
+ flex: 1 1 auto;
787
+ min-width: 0;
788
+ font: 400 32px/1.1 var(--dt-sans, system-ui, sans-serif);
789
+ font-stretch: 90%;
822
790
  font-variant-numeric: tabular-nums;
823
- letter-spacing: -0.01em;
824
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
791
+ letter-spacing: -0.02em;
825
792
  white-space: nowrap;
826
793
  overflow: hidden;
827
794
  text-overflow: ellipsis;
828
795
  }
829
796
 
830
- .cal-hd-btn {
831
- display: flex;
832
- align-items: center;
833
- justify-content: center;
834
- width: 28px;
835
- height: 28px;
836
- border: none;
837
- background: transparent;
838
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
839
- border-radius: 0;
840
- cursor: pointer;
841
- transition: background 120ms, color 120ms;
797
+ .cal-sr {
798
+ position: absolute;
799
+ width: 1px;
800
+ height: 1px;
801
+ margin: -1px;
802
+ padding: 0;
803
+ overflow: hidden;
804
+ clip-path: inset(50%);
805
+ white-space: nowrap;
806
+ border: 0;
842
807
  }
843
808
 
844
- .cal-hd-btn:hover {
845
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
846
- background: color-mix(in srgb, var(--dt-text, rgba(0, 0, 0, 0.87)) 8%, transparent);
809
+ .cal-hd-nav {
810
+ display: flex;
811
+ align-items: center;
812
+ gap: 8px;
847
813
  }
848
-
849
- .cal-hd-btn:focus-visible,
850
- .cal-hd-today:focus-visible,
851
- .cal-pill:focus-visible {
852
- outline: 2px solid color-mix(in srgb, var(--dt-accent, #2563eb) 55%, transparent);
853
- outline-offset: 2px;
814
+ .cal-hd-nav:empty {
815
+ display: none;
854
816
  }
855
817
 
856
- .cal-hd-today {
857
- font: 500 12px/1 var(--dt-sans, system-ui, sans-serif);
858
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
818
+ .cal-hd-today,
819
+ .cal-hd-btn {
820
+ box-sizing: border-box;
821
+ height: var(--cal-ctl-h);
822
+ border: 2px solid var(--dt-text, rgba(0, 0, 0, 0.87));
823
+ border-radius: var(--cal-ctl-r);
859
824
  background: transparent;
860
- border: 1px solid var(--dt-border-day, var(--dt-border, rgba(0, 0, 0, 0.14)));
861
- padding: 7px 10px;
862
- border-radius: 0;
825
+ color: var(--dt-text, rgba(0, 0, 0, 0.87));
863
826
  cursor: pointer;
827
+ transition: background-color 120ms, opacity 120ms;
828
+ -webkit-tap-highlight-color: transparent;
829
+ }
830
+ .cal-hd-today {
831
+ padding: 0 14px;
832
+ font: 400 15px/1 var(--dt-sans, system-ui, sans-serif);
864
833
  white-space: nowrap;
865
- margin-right: 2px;
866
- transition: background 120ms, color 120ms, border-color 120ms;
867
834
  }
868
-
869
- .cal-hd-today:hover:not(:disabled) {
870
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
871
- border-color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
835
+ .cal-hd-btn {
836
+ display: grid;
837
+ place-items: center;
838
+ width: var(--cal-ctl-h);
839
+ padding: 0;
840
+ }
841
+ /* The chevrons point along the reading direction */
842
+ .cal-hd-btn:dir(rtl) svg {
843
+ transform: scaleX(-1);
872
844
  }
845
+ .cal-hd-today:hover:not(:disabled),
846
+ .cal-hd-btn:hover {
847
+ background: var(--dt-hover, color-mix(in srgb, currentColor 6%, transparent));
848
+ }
849
+ .cal-hd-today:active:not(:disabled),
850
+ .cal-hd-btn:active {
851
+ background: color-mix(in srgb, var(--dt-text, #000) 12%, transparent);
852
+ }
853
+ /* Today is already in view: the frame stays, quietly */
873
854
  .cal-hd-today:disabled {
874
- opacity: 0.45;
855
+ opacity: 0.4;
875
856
  cursor: default;
876
857
  }
877
858
 
878
- /* View switch: plain text tabs; the chosen one carries an ink rule. */
859
+ .cal-hd-today:focus-visible,
860
+ .cal-hd-btn:focus-visible,
861
+ .cal-pill:focus-visible {
862
+ outline: 2px solid var(--dt-text, rgba(0, 0, 0, 0.87));
863
+ outline-offset: 2px;
864
+ }
865
+
866
+ /* View switch: plain text; the chosen one is ink over a 2px ink rule.
867
+ The accent keeps its three jobs. */
879
868
  .cal-pills {
880
869
  display: flex;
881
- gap: 2px;
870
+ gap: 16px;
882
871
  flex-shrink: 0;
883
872
  }
884
-
873
+ /* A hairline between the view-type and the day/week/month rows */
874
+ .cal-pills--labels + .cal-pills {
875
+ align-self: stretch;
876
+ align-items: center;
877
+ padding-inline-start: 24px;
878
+ border-inline-start: 1px solid var(--dt-border, rgba(0, 0, 0, 0.12));
879
+ }
885
880
  .cal-pill {
886
881
  border: none;
887
882
  background: transparent;
888
883
  color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
889
884
  cursor: pointer;
890
- font: 500 13px/1 var(--dt-sans, system-ui, sans-serif);
891
- padding: 8px 8px 7px;
885
+ font: 400 15px/1 var(--dt-sans, system-ui, sans-serif);
886
+ min-height: var(--cal-ctl-h);
887
+ /* 4px of air for the focus ring, given back so the row keeps its rhythm */
888
+ padding: 0 4px;
889
+ margin: 0 -4px;
892
890
  border-radius: 0;
893
- box-shadow: inset 0 -2px 0 transparent;
894
- transition: box-shadow 100ms, color 100ms;
891
+ white-space: nowrap;
892
+ text-decoration: underline 2px transparent;
893
+ text-underline-offset: 7px;
894
+ transition: color 120ms, text-decoration-color 120ms;
895
+ -webkit-tap-highlight-color: transparent;
895
896
  }
896
-
897
- /* :not(--active) — the hover rule otherwise outranks the active color,
898
- and iOS keeps :hover stuck after a tap (dark text on the accent). */
897
+ /* :not(--active) — iOS keeps :hover stuck after a tap */
899
898
  .cal-pill:hover:not(.cal-pill--active) {
900
899
  color: var(--dt-text, rgba(0, 0, 0, 0.87));
900
+ text-decoration-color: var(--dt-border-day, var(--dt-border, rgba(0, 0, 0, 0.3)));
901
901
  }
902
-
903
- /* Selected = ink text over an ink rule; the accent keeps its three jobs. */
904
902
  .cal-pill--active {
905
903
  color: var(--dt-text, rgba(0, 0, 0, 0.87));
906
- box-shadow: inset 0 -2px 0 var(--dt-text, rgba(0, 0, 0, 0.87));
904
+ text-decoration-color: currentColor;
905
+ }
906
+
907
+ /* Compact (mobile) header: same drawing, smaller title, tighter gaps */
908
+ .cal-hd--mobile {
909
+ --cal-ctl-h: 40px;
910
+ gap: 8px 12px;
911
+ padding: 10px 8px 8px;
912
+ }
913
+ .cal-hd--mobile .cal-hd-title {
914
+ font-size: 22px;
915
+ }
916
+ .cal-hd--mobile .cal-pills {
917
+ gap: 12px;
918
+ }
919
+ .cal-hd--mobile .cal-pill {
920
+ font-size: 14px;
921
+ }
922
+ .cal-hd--mobile .cal-hd-today {
923
+ padding: 0 10px;
924
+ font-size: 14px;
925
+ }
926
+ .cal-hd--mobile .cal-hd-nav {
927
+ gap: 6px;
928
+ margin-inline-start: auto;
929
+ }
930
+ /* Narrow containers: the title takes its own row above the controls */
931
+ .cal-hd--stack .cal-hd-title:not(:empty) {
932
+ flex-basis: 100%;
933
+ }
934
+
935
+ @media (pointer: coarse) {
936
+ .cal-hd {
937
+ --cal-ctl-h: 44px;
938
+ }
939
+ }
940
+
941
+ @media (prefers-reduced-motion: reduce) {
942
+ .cal-hd-today,
943
+ .cal-hd-btn,
944
+ .cal-pill {
945
+ transition: none;
946
+ }
907
947
  }
908
948
 
909
949
  .cal-body {
@@ -952,138 +992,4 @@ const navCtx = $derived({
952
992
  }
953
993
  }
954
994
 
955
- /* ── Mobile header (flow layout) ── */
956
- .cal-m-hd {
957
- display: flex;
958
- align-items: center;
959
- gap: 4px;
960
- padding: 8px 8px 6px;
961
- border-bottom: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
962
- flex-shrink: 0;
963
- min-height: 44px;
964
- }
965
-
966
- /* Narrow containers: the date label moves to its own row (.cal-m-titlebar),
967
- so the controls row spreads pills and nav to the edges. */
968
- .cal-m-hd--stack {
969
- justify-content: space-between;
970
- }
971
- .cal-m-hd--titled {
972
- border-bottom: none;
973
- padding-bottom: 2px;
974
- }
975
- .cal-m-titlebar {
976
- display: flex;
977
- justify-content: center;
978
- padding: 0 8px 8px;
979
- border-bottom: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
980
- flex-shrink: 0;
981
- }
982
- .cal-m-titlebar .cal-m-title {
983
- flex: 0 1 auto;
984
- }
985
-
986
- .cal-m-left,
987
- .cal-m-right {
988
- display: flex;
989
- align-items: center;
990
- gap: 2px;
991
- flex-shrink: 0;
992
- }
993
-
994
- .cal-m-right {
995
- justify-content: flex-end;
996
- }
997
-
998
- .cal-m-nav {
999
- display: flex;
1000
- align-items: center;
1001
- justify-content: center;
1002
- width: 40px;
1003
- height: 40px;
1004
- border: none;
1005
- background: transparent;
1006
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1007
- border-radius: 50%;
1008
- cursor: pointer;
1009
- transition: background 120ms, color 120ms;
1010
- -webkit-tap-highlight-color: transparent;
1011
- flex-shrink: 0;
1012
- }
1013
- .cal-m-nav:hover {
1014
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1015
- background: color-mix(in srgb, var(--dt-text, rgba(0, 0, 0, 0.87)) 8%, transparent);
1016
- }
1017
- .cal-m-nav:active {
1018
- background: var(--dt-accent-dim, rgba(37, 99, 235, 0.12));
1019
- }
1020
- .cal-m-nav:focus-visible {
1021
- outline: 2px solid color-mix(in srgb, var(--dt-accent, #2563eb) 55%, transparent);
1022
- outline-offset: 2px;
1023
- }
1024
-
1025
- .cal-m-pills {
1026
- display: flex;
1027
- gap: 2px;
1028
- flex-shrink: 0;
1029
- }
1030
- .cal-m-pill {
1031
- border: none;
1032
- background: transparent;
1033
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1034
- cursor: pointer;
1035
- font: 500 13px / 1 var(--dt-sans, system-ui, sans-serif);
1036
- padding: 11px 10px 9px;
1037
- border-radius: 0;
1038
- box-shadow: inset 0 -2px 0 transparent;
1039
- transition: box-shadow 100ms, color 100ms;
1040
- -webkit-tap-highlight-color: transparent;
1041
- }
1042
- .cal-m-pill:hover:not(.cal-m-pill--active) {
1043
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1044
- }
1045
- .cal-m-pill--active {
1046
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1047
- box-shadow: inset 0 -2px 0 var(--dt-text, rgba(0, 0, 0, 0.87));
1048
- }
1049
-
1050
- .cal-m-title {
1051
- flex: 1;
1052
- text-align: center;
1053
- font: 600 14px / 1.2 var(--dt-sans, system-ui, sans-serif);
1054
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1055
- white-space: nowrap;
1056
- overflow: hidden;
1057
- text-overflow: ellipsis;
1058
- min-width: 0;
1059
- }
1060
-
1061
- .cal-m-today {
1062
- font: 600 13px / 1 var(--dt-sans, system-ui, sans-serif);
1063
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1064
- background: transparent;
1065
- border: 1px solid var(--dt-border-day, rgba(0, 0, 0, 0.12));
1066
- min-height: 40px;
1067
- padding: 5px 12px;
1068
- border-radius: 0;
1069
- cursor: pointer;
1070
- white-space: nowrap;
1071
- transition: background 120ms, color 120ms;
1072
- -webkit-tap-highlight-color: transparent;
1073
- flex-shrink: 0;
1074
- }
1075
- .cal-m-today:hover:not(:disabled) {
1076
- border-color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1077
- }
1078
- .cal-m-today:active:not(:disabled) {
1079
- background: color-mix(in srgb, var(--dt-text, #000) 8%, transparent);
1080
- }
1081
- .cal-m-today:disabled {
1082
- opacity: 0.45;
1083
- cursor: default;
1084
- }
1085
- .cal-m-today:focus-visible {
1086
- outline: 2px solid var(--dt-text, rgba(0, 0, 0, 0.87));
1087
- outline-offset: 2px;
1088
- }
1089
995
  </style>
@@ -35,11 +35,11 @@ export declare const auto = "";
35
35
  */
36
36
  export declare const neutral = "\n\t--dt-stage-bg: #efebe9;\n\t--dt-bg: #efebe9;\n\t--dt-surface: #f4f1ee;\n\t--dt-border: rgba(15, 15, 15, 0.3);\n\t--dt-border-day: rgba(15, 15, 15, 0.6);\n\t--dt-text: #0f0f0f;\n\t--dt-text-2: rgba(15, 15, 15, 0.66);\n\t--dt-text-3: rgba(15, 15, 15, 0.54);\n\t--dt-accent: var(--asini-accent, #1d4fd7);\n\t--dt-accent-dim: color-mix(in srgb, var(--dt-accent) 12%, transparent);\n\t--dt-glow: color-mix(in srgb, var(--dt-accent) 25%, transparent);\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(15, 15, 15, 0.18);\n\t--dt-weekend-bg: rgba(15, 15, 15, 0.035);\n\t--dt-hover: rgba(15, 15, 15, 0.05);\n\t--dt-event: var(--dt-text);\n\t--dt-paper: none;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n";
37
37
  /** Midnight Industrial — dark charcoal + red accent, tech monitoring */
38
- export declare const midnight = "\n\t--dt-stage-bg: #080a0f;\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.55);\n\t--dt-text-3: rgba(100, 116, 139, 0.55);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-weekend-bg: rgba(148, 163, 184, 0.03);\n\t--dt-hover: rgba(148, 163, 184, 0.06);\n\t--dt-event: var(--dt-text);\n\t--dt-paper: none;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n";
38
+ export declare const midnight = "\n\t--dt-stage-bg: #080a0f;\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.75);\n\t--dt-text-3: rgba(148, 163, 184, 0.65);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-weekend-bg: rgba(148, 163, 184, 0.03);\n\t--dt-hover: rgba(148, 163, 184, 0.06);\n\t--dt-event: var(--dt-text);\n\t--dt-paper: none;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n";
39
39
  /** All available presets keyed by name */
40
40
  export declare const presets: {
41
41
  readonly auto: "";
42
42
  readonly neutral: "\n\t--dt-stage-bg: #efebe9;\n\t--dt-bg: #efebe9;\n\t--dt-surface: #f4f1ee;\n\t--dt-border: rgba(15, 15, 15, 0.3);\n\t--dt-border-day: rgba(15, 15, 15, 0.6);\n\t--dt-text: #0f0f0f;\n\t--dt-text-2: rgba(15, 15, 15, 0.66);\n\t--dt-text-3: rgba(15, 15, 15, 0.54);\n\t--dt-accent: var(--asini-accent, #1d4fd7);\n\t--dt-accent-dim: color-mix(in srgb, var(--dt-accent) 12%, transparent);\n\t--dt-glow: color-mix(in srgb, var(--dt-accent) 25%, transparent);\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(15, 15, 15, 0.18);\n\t--dt-weekend-bg: rgba(15, 15, 15, 0.035);\n\t--dt-hover: rgba(15, 15, 15, 0.05);\n\t--dt-event: var(--dt-text);\n\t--dt-paper: none;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n";
43
- readonly midnight: "\n\t--dt-stage-bg: #080a0f;\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.55);\n\t--dt-text-3: rgba(100, 116, 139, 0.55);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-weekend-bg: rgba(148, 163, 184, 0.03);\n\t--dt-hover: rgba(148, 163, 184, 0.06);\n\t--dt-event: var(--dt-text);\n\t--dt-paper: none;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n";
43
+ readonly midnight: "\n\t--dt-stage-bg: #080a0f;\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.75);\n\t--dt-text-3: rgba(148, 163, 184, 0.65);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-weekend-bg: rgba(148, 163, 184, 0.03);\n\t--dt-hover: rgba(148, 163, 184, 0.06);\n\t--dt-event: var(--dt-text);\n\t--dt-paper: none;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n";
44
44
  };
45
45
  export type PresetName = keyof typeof presets;
@@ -62,8 +62,8 @@ export const midnight = `
62
62
  --dt-border: rgba(148, 163, 184, 0.07);
63
63
  --dt-border-day: rgba(148, 163, 184, 0.14);
64
64
  --dt-text: rgba(226, 232, 240, 0.85);
65
- --dt-text-2: rgba(148, 163, 184, 0.55);
66
- --dt-text-3: rgba(100, 116, 139, 0.55);
65
+ --dt-text-2: rgba(148, 163, 184, 0.75);
66
+ --dt-text-3: rgba(148, 163, 184, 0.65);
67
67
  --dt-accent: #ef4444;
68
68
  --dt-accent-dim: rgba(239, 68, 68, 0.18);
69
69
  --dt-glow: rgba(239, 68, 68, 0.35);