@danieldeusing/design 0.1.4 → 0.1.6
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/dist/danieldeusing-design.css +372 -1
- package/dist/danieldeusing-design.min.css +2 -2
- package/package.json +1 -1
- package/runtime/index.js +1 -0
- package/runtime/terminal.js +22 -0
- package/runtime/tooltip.js +54 -0
- package/src/index.css +5 -2
- package/src/print.css +351 -0
- package/src/tailwind.css +2 -0
- package/src/tooltip.css +16 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! danieldeusing-design v0.1.
|
|
1
|
+
/*! danieldeusing-design v0.1.6 | MIT | https://github.com/danieldeusing/danieldeusing-design */
|
|
2
2
|
/* ===== reset.css ===== */
|
|
3
3
|
/*
|
|
4
4
|
* danieldeusing-design — minimal reset.
|
|
@@ -742,3 +742,374 @@ footer.status .dropdown summary, footer.status .anim-toggle { padding: 0.55rem 0
|
|
|
742
742
|
font: inherit; cursor: pointer;
|
|
743
743
|
}
|
|
744
744
|
}
|
|
745
|
+
|
|
746
|
+
/* ===== tooltip.css ===== */
|
|
747
|
+
/*
|
|
748
|
+
* tooltip.css — styles for the [data-tip] tooltip system (runtime/tooltip.js).
|
|
749
|
+
* The panel is a body-level singleton with position:fixed — it can never be
|
|
750
|
+
* clipped by overflow containers and always sits on top.
|
|
751
|
+
*/
|
|
752
|
+
[data-tip] { cursor: help; }
|
|
753
|
+
span[data-tip], th[data-tip] { border-bottom: 1px dotted var(--muted-foreground); }
|
|
754
|
+
|
|
755
|
+
#ddtip {
|
|
756
|
+
position: fixed; z-index: 9999; display: none; max-width: 340px;
|
|
757
|
+
background: var(--background); color: var(--foreground);
|
|
758
|
+
border: 1px solid var(--muted-foreground); border-radius: 4px;
|
|
759
|
+
padding: 7px 10px; font-size: 0.72rem; line-height: 1.45; font-weight: 400;
|
|
760
|
+
text-align: left; white-space: normal; pointer-events: none;
|
|
761
|
+
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/* ===== print.css ===== */
|
|
765
|
+
/*
|
|
766
|
+
* danieldeusing-design — print layer.
|
|
767
|
+
*
|
|
768
|
+
* Paper is a different device, not a narrow screen. This layer strips the parts
|
|
769
|
+
* of the terminal look that only exist to sell "a CRT is running" — scanlines,
|
|
770
|
+
* phosphor glow, sticky chrome, the reveal animation — and lays the content out
|
|
771
|
+
* as a document: black on white, 12px body text, sane page breaks.
|
|
772
|
+
*
|
|
773
|
+
* Load LAST (index.css imports it after every other layer) so its token
|
|
774
|
+
* overrides win on source order without needing !important on each one.
|
|
775
|
+
*
|
|
776
|
+
* Three things here are load-bearing and easy to lose in a refactor:
|
|
777
|
+
*
|
|
778
|
+
* 1. The terminal reveal is forced open. runtime/terminal.js only reveals a
|
|
779
|
+
* [data-term-out] once its section scrolls into view, so a long page that
|
|
780
|
+
* is printed straight after load has most of its content sitting at
|
|
781
|
+
* visibility:hidden. Printing it would silently produce blank pages — the
|
|
782
|
+
* reader only finds out on paper. Everything is forced visible here
|
|
783
|
+
* regardless of animation state.
|
|
784
|
+
* 2. `zoom` is reset. Pages that use the resolution-independent zoom trick
|
|
785
|
+
* (html.style.zoom = innerWidth / 1920) carry that multiplier into the
|
|
786
|
+
* print box, which is what makes a printout come out oversized.
|
|
787
|
+
* 3. Mermaid bakes the ACTIVE theme's colours into the SVG at render time, so
|
|
788
|
+
* a diagram rendered under `green`/`mono` is dark-on-dark on paper no
|
|
789
|
+
* matter what the page tokens say. The SVG parts are repainted below.
|
|
790
|
+
*/
|
|
791
|
+
|
|
792
|
+
@media print {
|
|
793
|
+
@page {
|
|
794
|
+
margin: 14mm 12mm;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/* ── ink-frugal palette, whatever theme is on screen ────────────────────
|
|
798
|
+
`html[data-theme]` matches the specificity of the themed token blocks in
|
|
799
|
+
tokens.css and comes later in the bundle, so it wins for every theme. */
|
|
800
|
+
:root,
|
|
801
|
+
html,
|
|
802
|
+
html[data-theme] {
|
|
803
|
+
--background: #ffffff;
|
|
804
|
+
--foreground: #111111;
|
|
805
|
+
--card: #ffffff;
|
|
806
|
+
--card-foreground: #111111;
|
|
807
|
+
--popover: #ffffff;
|
|
808
|
+
--popover-foreground: #111111;
|
|
809
|
+
--primary: #000000;
|
|
810
|
+
--primary-foreground: #ffffff;
|
|
811
|
+
--secondary: #ffffff;
|
|
812
|
+
--secondary-foreground: #111111;
|
|
813
|
+
--muted: #ffffff;
|
|
814
|
+
--muted-foreground: #444444;
|
|
815
|
+
--accent: #000000;
|
|
816
|
+
--accent-foreground: #ffffff;
|
|
817
|
+
--destructive: #7a1c1c;
|
|
818
|
+
--border: #9a9a9a;
|
|
819
|
+
--input: #9a9a9a;
|
|
820
|
+
--ring: #000000;
|
|
821
|
+
--glow: transparent;
|
|
822
|
+
--glow-soft: transparent;
|
|
823
|
+
--scanline-opacity: 0;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/* ── document metrics ──────────────────────────────────────────────────
|
|
827
|
+
The rem baseline is pinned so the design's rem scale lands where it was
|
|
828
|
+
drawn, and the body size is stated in px so it is 12px on paper whatever
|
|
829
|
+
the browser's default font size is. `zoom` is a screen-only device. */
|
|
830
|
+
html {
|
|
831
|
+
zoom: 1 !important;
|
|
832
|
+
font-size: 16px;
|
|
833
|
+
scroll-behavior: auto;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
body {
|
|
837
|
+
background: #ffffff;
|
|
838
|
+
color: var(--foreground);
|
|
839
|
+
font-size: 12px;
|
|
840
|
+
line-height: 1.45;
|
|
841
|
+
overflow: visible;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/* CRT scanline overlay: a fixed, full-viewport gradient — on paper it is a
|
|
845
|
+
grey wash over the page. */
|
|
846
|
+
body::after {
|
|
847
|
+
display: none !important;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/* ── nothing animates on paper ─────────────────────────────────────────
|
|
851
|
+
Also the mechanism that un-hides the terminal reveal: the keyframes use
|
|
852
|
+
`both`, so killing the animation restores the element's own opacity. */
|
|
853
|
+
*,
|
|
854
|
+
*::before,
|
|
855
|
+
*::after {
|
|
856
|
+
animation: none !important;
|
|
857
|
+
transition: none !important;
|
|
858
|
+
text-shadow: none !important;
|
|
859
|
+
box-shadow: none !important;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/* ── the reveal must never decide what lands on paper ──────────────────
|
|
863
|
+
See note 1 at the top of this file. */
|
|
864
|
+
html.term-anim [data-term] [data-term-out],
|
|
865
|
+
html.term-anim [data-term] [data-term-out]:not(.term-show),
|
|
866
|
+
html.term-anim [data-term] [data-term-out] > * {
|
|
867
|
+
visibility: visible !important;
|
|
868
|
+
opacity: 1 !important;
|
|
869
|
+
}
|
|
870
|
+
html.term-anim [data-term] .prompt:not(.term-live) {
|
|
871
|
+
color: var(--muted-foreground) !important;
|
|
872
|
+
}
|
|
873
|
+
html.term-anim [data-term] .prompt:not(.term-live)::before {
|
|
874
|
+
color: var(--primary) !important;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/* ── screen-only chrome ────────────────────────────────────────────────
|
|
878
|
+
.toc is the "On this page" navigator: a screen affordance with no meaning
|
|
879
|
+
on paper, and the first thing that makes a printout look broken. */
|
|
880
|
+
header.bar,
|
|
881
|
+
footer.status,
|
|
882
|
+
.site-nav,
|
|
883
|
+
.nav-burger,
|
|
884
|
+
.mobile-nav,
|
|
885
|
+
.mobile-footer,
|
|
886
|
+
.skip-link,
|
|
887
|
+
.dropdown,
|
|
888
|
+
.dropdown-panel,
|
|
889
|
+
.anim-toggle,
|
|
890
|
+
.cursor-block,
|
|
891
|
+
.term-caret,
|
|
892
|
+
.ascii-rule,
|
|
893
|
+
.toc,
|
|
894
|
+
#ddtip {
|
|
895
|
+
display: none !important;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
[data-tip] {
|
|
899
|
+
cursor: auto;
|
|
900
|
+
}
|
|
901
|
+
span[data-tip],
|
|
902
|
+
th[data-tip] {
|
|
903
|
+
border-bottom: 0;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/* ── layout: the page is the column ────────────────────────────────────
|
|
907
|
+
.wrap/.layout/.content are the documentation-template vocabulary shipped
|
|
908
|
+
in templates/documentation.html. */
|
|
909
|
+
.wrap {
|
|
910
|
+
max-width: none !important;
|
|
911
|
+
margin: 0 !important;
|
|
912
|
+
padding: 0 !important;
|
|
913
|
+
}
|
|
914
|
+
.layout {
|
|
915
|
+
display: block !important;
|
|
916
|
+
}
|
|
917
|
+
.content {
|
|
918
|
+
min-width: 0;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/* ── heading hierarchy against a 12px body ─────────────────────────────
|
|
922
|
+
24 / 18 / 16 / 14 px. !important because page-level rules give these
|
|
923
|
+
classes a higher specificity than a bare element selector. */
|
|
924
|
+
h1,
|
|
925
|
+
.title {
|
|
926
|
+
font-size: 1.5rem !important;
|
|
927
|
+
}
|
|
928
|
+
h2 {
|
|
929
|
+
font-size: 1.15rem !important;
|
|
930
|
+
}
|
|
931
|
+
h3,
|
|
932
|
+
.sub {
|
|
933
|
+
font-size: 1rem !important;
|
|
934
|
+
}
|
|
935
|
+
h4 {
|
|
936
|
+
font-size: 0.9rem !important;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.prompt {
|
|
940
|
+
font-size: 0.7rem;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/* ── page breaks ───────────────────────────────────────────────────────
|
|
944
|
+
A heading (or a `$ command` section header) must never be the last thing
|
|
945
|
+
on a page. Tables break between rows and repeat their header; everything
|
|
946
|
+
that reads as one unit stays together. */
|
|
947
|
+
h1,
|
|
948
|
+
h2,
|
|
949
|
+
h3,
|
|
950
|
+
h4,
|
|
951
|
+
.prompt,
|
|
952
|
+
.toc-label {
|
|
953
|
+
break-after: avoid-page;
|
|
954
|
+
break-inside: avoid;
|
|
955
|
+
}
|
|
956
|
+
p,
|
|
957
|
+
li,
|
|
958
|
+
blockquote {
|
|
959
|
+
orphans: 3;
|
|
960
|
+
widows: 3;
|
|
961
|
+
}
|
|
962
|
+
pre,
|
|
963
|
+
figure,
|
|
964
|
+
blockquote,
|
|
965
|
+
tr,
|
|
966
|
+
img,
|
|
967
|
+
.eli5,
|
|
968
|
+
.card-terminal {
|
|
969
|
+
break-inside: avoid;
|
|
970
|
+
}
|
|
971
|
+
/* NOT svg. A mermaid flowchart is routinely taller than a printed page;
|
|
972
|
+
`break-inside: avoid` on the SVG pushes it past the page boundary while its
|
|
973
|
+
wrapper stays behind, which prints an entire page as an empty bordered box.
|
|
974
|
+
Let the SVG break where the wrapper breaks. */
|
|
975
|
+
svg {
|
|
976
|
+
break-inside: auto;
|
|
977
|
+
}
|
|
978
|
+
thead {
|
|
979
|
+
display: table-header-group;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
/* ── nothing scrolls on paper ──────────────────────────────────────────
|
|
983
|
+
An overflow-x container has no scrollbar in print: whatever sits past the
|
|
984
|
+
right edge is simply gone. Let it wrap instead. */
|
|
985
|
+
.table-scroll,
|
|
986
|
+
pre,
|
|
987
|
+
.diagram {
|
|
988
|
+
overflow: visible !important;
|
|
989
|
+
max-width: 100% !important;
|
|
990
|
+
}
|
|
991
|
+
pre {
|
|
992
|
+
white-space: pre-wrap !important;
|
|
993
|
+
overflow-wrap: anywhere;
|
|
994
|
+
font-size: 0.75rem !important;
|
|
995
|
+
background: transparent !important;
|
|
996
|
+
}
|
|
997
|
+
pre.mermaid[data-processed] {
|
|
998
|
+
white-space: normal !important;
|
|
999
|
+
}
|
|
1000
|
+
code {
|
|
1001
|
+
background: transparent !important;
|
|
1002
|
+
overflow-wrap: anywhere;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
table {
|
|
1006
|
+
width: 100% !important;
|
|
1007
|
+
table-layout: auto;
|
|
1008
|
+
border-collapse: collapse;
|
|
1009
|
+
font-size: 0.75rem !important;
|
|
1010
|
+
}
|
|
1011
|
+
/* `overflow-wrap: break-word` and NOT `anywhere`: `anywhere` also shrinks a
|
|
1012
|
+
cell's min-content width to one character, and the auto table layout then
|
|
1013
|
+
collapses a short column to nothing ("Orchestrator" set as "Orche/strat/or"
|
|
1014
|
+
down a 6-character column). Only the elements that actually hold
|
|
1015
|
+
unbreakable strings — paths, URLs, identifiers — get to break anywhere. */
|
|
1016
|
+
th,
|
|
1017
|
+
td {
|
|
1018
|
+
overflow-wrap: break-word;
|
|
1019
|
+
white-space: normal !important;
|
|
1020
|
+
}
|
|
1021
|
+
td code,
|
|
1022
|
+
th code,
|
|
1023
|
+
td a,
|
|
1024
|
+
th a {
|
|
1025
|
+
overflow-wrap: anywhere;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/* ── links read as text ────────────────────────────────────────────────
|
|
1029
|
+
The URL is deliberately NOT printed after the link. These are internal
|
|
1030
|
+
documents whose links are mostly in-page anchors and hosts already named
|
|
1031
|
+
in the prose; appending every href would add noise and pages without
|
|
1032
|
+
adding information. To turn it on, add:
|
|
1033
|
+
a[href^="http"]::after { content: " (" attr(href) ")"; } */
|
|
1034
|
+
a {
|
|
1035
|
+
color: inherit;
|
|
1036
|
+
text-decoration: underline;
|
|
1037
|
+
text-underline-offset: 2px;
|
|
1038
|
+
}
|
|
1039
|
+
a.card-terminal,
|
|
1040
|
+
a[class*="card"] {
|
|
1041
|
+
text-decoration: none;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.glow,
|
|
1045
|
+
.glow-lg {
|
|
1046
|
+
color: inherit;
|
|
1047
|
+
}
|
|
1048
|
+
.btn-terminal {
|
|
1049
|
+
border: 1px solid var(--border);
|
|
1050
|
+
background: transparent;
|
|
1051
|
+
color: var(--foreground);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/* ── mermaid diagrams ──────────────────────────────────────────────────
|
|
1055
|
+
See note 3 at the top of this file: the palette is baked into the SVG at
|
|
1056
|
+
render time, so a diagram rendered under a dark theme prints as dark
|
|
1057
|
+
boxes with invisible labels. Repaint the standard mermaid parts. */
|
|
1058
|
+
/* Every diagram is scaled to fit ONE page. Not cosmetic: Chromium will not
|
|
1059
|
+
start an over-tall diagram in the space left on the current page, so an
|
|
1060
|
+
uncapped flowchart (they run to 2500px in a narrow column) prints a blank
|
|
1061
|
+
page, then an empty bordered box, then the diagram — six such pages in the
|
|
1062
|
+
executor design doc alone. `width/height: auto` with both max-* set is what
|
|
1063
|
+
makes the browser scale it proportionally instead of squashing it.
|
|
1064
|
+
A diagram that ends up too small to read is a diagram that is too tall for
|
|
1065
|
+
paper: split it, or lay it out left-to-right. */
|
|
1066
|
+
.mermaid svg {
|
|
1067
|
+
display: block;
|
|
1068
|
+
margin-inline: auto;
|
|
1069
|
+
width: auto !important;
|
|
1070
|
+
height: auto !important;
|
|
1071
|
+
max-width: 100% !important;
|
|
1072
|
+
max-height: 235mm !important;
|
|
1073
|
+
}
|
|
1074
|
+
.mermaid svg .node rect,
|
|
1075
|
+
.mermaid svg .node polygon,
|
|
1076
|
+
.mermaid svg .node circle,
|
|
1077
|
+
.mermaid svg .node path,
|
|
1078
|
+
.mermaid svg .label-container,
|
|
1079
|
+
.mermaid svg .cluster rect,
|
|
1080
|
+
.mermaid svg .actor,
|
|
1081
|
+
.mermaid svg .note {
|
|
1082
|
+
fill: #ffffff !important;
|
|
1083
|
+
stroke: #333333 !important;
|
|
1084
|
+
}
|
|
1085
|
+
.mermaid svg .edgePath path,
|
|
1086
|
+
.mermaid svg .flowchart-link,
|
|
1087
|
+
.mermaid svg line,
|
|
1088
|
+
.mermaid svg .messageLine0,
|
|
1089
|
+
.mermaid svg .messageLine1 {
|
|
1090
|
+
stroke: #333333 !important;
|
|
1091
|
+
}
|
|
1092
|
+
.mermaid svg .arrowheadPath,
|
|
1093
|
+
.mermaid svg marker path,
|
|
1094
|
+
.mermaid svg marker polygon {
|
|
1095
|
+
fill: #333333 !important;
|
|
1096
|
+
stroke: #333333 !important;
|
|
1097
|
+
}
|
|
1098
|
+
.mermaid svg text,
|
|
1099
|
+
.mermaid svg .nodeLabel,
|
|
1100
|
+
.mermaid svg .edgeLabel,
|
|
1101
|
+
.mermaid svg .cluster-label,
|
|
1102
|
+
.mermaid svg .messageText,
|
|
1103
|
+
.mermaid svg foreignObject div,
|
|
1104
|
+
.mermaid svg foreignObject span,
|
|
1105
|
+
.mermaid svg p {
|
|
1106
|
+
fill: #111111 !important;
|
|
1107
|
+
color: #111111 !important;
|
|
1108
|
+
background: transparent !important;
|
|
1109
|
+
}
|
|
1110
|
+
.mermaid svg .edgeLabel rect,
|
|
1111
|
+
.mermaid svg .edgeLabel foreignObject > div {
|
|
1112
|
+
fill: #ffffff !important;
|
|
1113
|
+
background: #ffffff !important;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! danieldeusing-design v0.1.
|
|
2
|
-
*,*::before,*::after{box-sizing: border-box}*{margin: 0}html{-webkit-text-size-adjust: 100%;text-size-adjust: 100%;tab-size: 4}body{min-height: 100vh;min-height: 100dvh;line-height: 1.5}img,picture,video,canvas,svg{display: block;max-width: 100%}input,button,textarea,select{font: inherit;color: inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap: break-word}ul,ol{list-style: none;padding: 0}a{color: inherit;text-decoration: none}table{border-collapse: collapse}:root{--background: #f5efe2;--foreground: #43352a;--card: #efe7d4;--card-foreground: #43352a;--popover: #efe7d4;--popover-foreground: #43352a;--primary: #8a4516;--primary-foreground: #f8f3e8;--secondary: #ece3cf;--secondary-foreground: #43352a;--muted: #ece3cf;--muted-foreground: #71614e;--accent: #8a4516;--accent-foreground: #f8f3e8;--destructive: #a02c2c;--border: #d9cdb6;--input: #d9cdb6;--ring: #8a4516;--glow: rgba(160,82,45,0.1);--glow-soft: rgba(160,82,45,0.05);--scanline-opacity: 0.15;--radius: 0rem;--font-mono: "JetBrains Mono Variable","JetBrains Mono","Menlo",monospace}html[data-theme="green"]{--background: #020604;--foreground: #4fdd7d;--card: #04110a;--card-foreground: #4fdd7d;--popover: #04110a;--popover-foreground: #4fdd7d;--primary: #33ff66;--primary-foreground: #02160a;--secondary: #071509;--secondary-foreground: #4fdd7d;--muted: #071509;--muted-foreground: #3da45e;--accent: #33ff66;--accent-foreground: #02160a;--destructive: #ff5c5c;--border: #1c4a2c;--input: #1c4a2c;--ring: #33ff66;--glow: rgba(51,255,102,0.35);--glow-soft: rgba(51,255,102,0.12);--scanline-opacity: 0.5}html[data-theme="mono"]{--background: #050505;--foreground: #d4d4d4;--card: #0d0d0d;--card-foreground: #d4d4d4;--popover: #0d0d0d;--popover-foreground: #d4d4d4;--primary: #ffffff;--primary-foreground: #050505;--secondary: #111111;--secondary-foreground: #d4d4d4;--muted: #111111;--muted-foreground: #8a8a8a;--accent: #ffffff;--accent-foreground: #050505;--destructive: #ff5c5c;--border: #333333;--input: #333333;--ring: #ffffff;--glow: rgba(255,255,255,0.25);--glow-soft: rgba(255,255,255,0.08);--scanline-opacity: 0.45}html[data-theme="paper"]{--background: #fafafa;--foreground: #1f1f1f;--card: #f1f1f1;--card-foreground: #1f1f1f;--popover: #f1f1f1;--popover-foreground: #1f1f1f;--primary: #000000;--primary-foreground: #fafafa;--secondary: #efefef;--secondary-foreground: #1f1f1f;--muted: #efefef;--muted-foreground: #595959;--accent: #000000;--accent-foreground: #fafafa;--destructive: #b3261e;--border: #d4d4d4;--input: #d4d4d4;--ring: #000000;--glow: rgba(0,0,0,0.06);--glow-soft: rgba(0,0,0,0.04);--scanline-opacity: 0.12}html{scroll-behavior: smooth}*,*::before,*::after{border-color: var(--border)}:focus-visible{outline: 2px solid var(--ring);outline-offset: 2px}body{background: var(--background);color: var(--foreground);font-family: var(--font-mono);font-size: 0.75rem;line-height: 1.5;overflow-x: hidden;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}button:not(:disabled),summary,[role="button"]{cursor: pointer}body::after{content: "";position: fixed;inset: 0;z-index: 40;pointer-events: none;background: repeating-linear-gradient( 0deg,rgba(0,0,0,0.25) 0px,rgba(0,0,0,0.25) 1px,transparent 1px,transparent 3px );opacity: var(--scanline-opacity)}::selection{background: var(--primary);color: var(--primary-foreground)}.glow{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.glow-lg{color: var(--primary);text-shadow: 0 0 12px var(--glow)}.prompt{font-size: 0.75rem;font-weight: 700;color: var(--muted-foreground)}.prompt::before{content: "$ ";color: var(--primary)}.comment::before{content: "# ";color: var(--border)}.cursor-block{display: inline-block;width: 0.55em;height: 1em;margin-left: 8px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em);animation: ddd-blink 1.1s step-end infinite}@keyframes ddd-blink{50%{opacity: 0}}.btn-terminal{display: inline-block;background: var(--primary);color: var(--primary-foreground);font-weight: 700;padding: 12px 24px;box-shadow: 0 0 16px var(--glow);transition: box-shadow 0.15s ease,transform 0.15s ease}.btn-terminal::before{content: "> "}.btn-terminal:hover{box-shadow: 0 0 28px var(--glow);transform: translateY(-2px)}.link-quiet{color: var(--muted-foreground);text-decoration: underline;text-underline-offset: 4px;transition: color 0.15s ease}.link-quiet:hover{color: var(--primary)}.anim-toggle{display: inline-flex;align-items: center;gap: 6px;font: inherit;color: var(--muted-foreground);background: none;border: 0;cursor: pointer;transition: color 0.15s ease}.anim-toggle:hover{color: var(--primary)}.anim-toggle[aria-pressed="true"] [data-anim-box]{color: var(--primary)}.dd-dot{display: inline-block;width: 11px;height: 11px;flex: none;border-radius: 50%;background: currentColor}.dd-flag{display: inline-block;width: 15px;height: 10px;flex: none;border: 1px solid var(--border);background-size: cover;background-repeat: no-repeat}.dd-flag-de{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='4' fill='%23262626'/><rect y='4' width='18' height='4' fill='%23c83232'/><rect y='8' width='18' height='4' fill='%23e8be32'/></svg>")}.dd-flag-en{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%23b22234'/><rect y='4' width='18' height='4' fill='%23ececec'/><rect width='8' height='6' fill='%233c3b6e'/></svg>")}.dd-flag-pt{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%231c9148'/><polygon points='9,1.5 15.5,6 9,10.5 2.5,6' fill='%23e8c832'/><rect x='8' y='5' width='2' height='2' fill='%232c3f87'/></svg>")}.dd-flag-es{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='6' height='12' fill='%2315734c'/><rect x='6' width='6' height='12' fill='%23ececec'/><rect x='12' width='6' height='12' fill='%23bf2233'/><rect x='8' y='5' width='2' height='2' fill='%237a5c3a'/></svg>")}.ascii-rule{margin: 1rem 0;border: 0;color: var(--border);line-height: 1;white-space: nowrap;overflow: hidden;user-select: none}.ascii-rule::before{content: "────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"}.card-terminal{background: var(--card);border: 1px solid var(--border);transition: border-color 0.15s ease,box-shadow 0.15s ease}.card-terminal:hover{border-color: var(--primary);box-shadow: 0 0 20px var(--glow-soft)}.dropdown{position: relative}.dropdown>summary{display: inline-flex;align-items: center;gap: 6px;cursor: pointer;user-select: none;list-style: none;color: var(--muted-foreground);transition: color 0.15s ease}.dropdown>summary::-webkit-details-marker{display: none}.dropdown>summary:hover,.dropdown[open]>summary{color: var(--primary)}.dropdown-panel{position: absolute;right: 0;bottom: calc(100% + 12px);z-index: 50;min-width: 128px;margin: 0;padding: 4px 0;list-style: none;background: var(--card);border: 1px solid var(--border);border-radius: 0;box-shadow: 0 0 20px var(--glow-soft)}.dropdown-panel--down{top: calc(100% + 8px);bottom: auto;left: 0;right: auto}.dropdown-item{display: flex;align-items: center;gap: 8px;width: 100%;padding: 5px 14px;text-align: left;font: inherit;line-height: 1.5;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;white-space: nowrap;transition: color 0.15s ease}.dropdown-item:hover{color: var(--primary);background: var(--muted)}.dropdown-item[aria-current="true"],html:not([data-theme]) .dropdown-item[data-theme-value="warm"],html[data-theme="green"] .dropdown-item[data-theme-value="green"],html[data-theme="mono"] .dropdown-item[data-theme-value="mono"],html[data-theme="paper"] .dropdown-item[data-theme-value="paper"],html[data-theme="warm"] .dropdown-item[data-theme-value="warm"]{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.eli5{margin: 1.25em 0;padding: 0.7em 1em;color: var(--foreground);background: color-mix(in srgb,var(--primary) 7%,var(--card));border: 1px solid var(--border);border-left: 3px solid var(--primary);border-radius: var(--radius);font-size: 0.92em;line-height: 1.6}.eli5::before{content: "ELI5";display: inline-flex;align-items: center;justify-content: center;margin-right: 0.6em;vertical-align: 0.08em;font-family: var(--font-mono);font-size: 0.72em;font-weight: 700;line-height: 1;letter-spacing: 0.04em;padding: 0.34em 0.6em;border-radius: 5px;background: #b42318;color: #fff}.eli5-term{font-weight: 700;color: var(--primary)}html.anim-off *,html.anim-off *::before,html.anim-off *::after{animation: none !important}html.anim-off .cursor-block{display: none}@media (prefers-reduced-motion: no-preference){html.term-anim [data-term] .prompt:not(.term-live),html.term-anim [data-term] .prompt:not(.term-live)::before{color: transparent}html.term-anim [data-term] [data-term-out]:not(.term-show){visibility: hidden}html.term-anim [data-term] [data-term-out].term-show{animation: ddd-term-output 0.2s steps(3,end) both}@keyframes ddd-term-output{from{opacity: 0}}html.term-anim [data-term] [data-term-out].term-show>*{animation: ddd-term-output 0.25s steps(3,end) both}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(2){animation-delay: 0.09s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(3){animation-delay: 0.18s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(4){animation-delay: 0.27s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(5){animation-delay: 0.36s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(6){animation-delay: 0.45s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(7){animation-delay: 0.54s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(8){animation-delay: 0.63s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(9){animation-delay: 0.72s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(10){animation-delay: 0.81s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(n + 11){animation-delay: 0.9s}.term-caret{display: inline-block;width: 0.55em;height: 1em;margin-left: 2px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em)}}.skip-link{position: absolute;left: -999px;top: 0;z-index: 100;background: var(--card);border: 1px solid var(--primary);padding: 0.5rem 1rem;color: var(--primary)}.skip-link:focus{left: 0.5rem;top: 0.5rem}.visually-hidden{position: absolute;width: 1px;height: 1px;overflow: hidden;clip: rect(0 0 0 0);white-space: nowrap}header.bar{position: sticky;top: 0;z-index: 30;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.6rem 1.25rem;border-bottom: 1px solid var(--border);background: var(--card)}header.bar .brand{display: inline-flex;align-items: center;font-weight: 700;font-size: 1rem}header.bar .brand,header.bar .brand a{color: inherit;text-decoration: none}header.bar .dropdown summary{padding: 0.6rem 0.4rem}.bar-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}footer.status{position: fixed;inset-inline: 0;bottom: 0;z-index: 50;min-height: 2rem;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.35rem 1.25rem;border-top: 1px solid var(--border);background: var(--card);font-size: 0.7rem}footer.status .dropdown summary,footer.status .anim-toggle{padding: 0.55rem 0.4rem}.status-left{color: var(--muted-foreground);min-width: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.status-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}.sep{width: 1px;height: 0.9rem;background: var(--border)}.doc-link{color: var(--muted-foreground);text-decoration: none;transition: color 0.15s ease}.doc-link:hover{color: var(--primary)}.ls-row{display: flex;align-items: baseline;gap: 0.9rem}.ls-perm{color: var(--muted-foreground);font-size: 0.72rem;letter-spacing: 0}.ls-row--sub .ls-name{padding-left: 1rem}.ls-panel{min-width: 17rem;left: auto !important;right: 0}#nav{position: relative}.nav-burger{display: none;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;padding: 0.55rem;margin: -0.3rem -0.3rem -0.3rem 0}.nav-burger:hover{color: var(--primary)}.mobile-nav{display: none;list-style: none;margin: 0;padding: 0}.mobile-footer{display: none}@media (max-width: 48rem){.nav-burger{display: inline-flex;align-items: center}.site-nav{display: none;position: absolute;top: 100%;left: 0;right: 0;z-index: 40;background: var(--card);border-bottom: 1px solid var(--border);padding: 0.4rem 1.25rem 0.9rem;max-height: calc(100vh - 6rem);overflow-y: auto}.site-nav.open{display: block}.site-nav>.dropdown{display: none}.mobile-nav{display: flex;flex-direction: column}.mobile-nav .mobile-item{display: flex;align-items: baseline;gap: 0.9rem;padding: 0.65rem 0;text-decoration: none;color: var(--foreground);font-size: 0.9rem;border-bottom: 1px solid var(--border)}.mobile-nav li:last-child .mobile-item{border-bottom: 0}.mobile-nav .mobile-item:active .ls-name,.mobile-nav .mobile-item:hover .ls-name{color: var(--primary)}footer.status{display: none}.mobile-footer{display: flex;flex-direction: column;gap: 0.55rem;margin-top: 0.8rem;border-top: 1px solid var(--border);padding-top: 0.8rem;font-size: 0.85rem}.mobile-footer .doc-link{padding: 0.2rem 0}.mobile-footer .mobile-theme summary{list-style: none;display: flex;align-items: center;gap: 0.5rem;color: var(--muted-foreground);cursor: pointer;padding: 0.2rem 0}.mobile-footer .mobile-theme summary::-webkit-details-marker{display: none}.mobile-footer .mf-chev{margin-left: auto;opacity: 0.7}.mobile-footer .mf-panel{display: flex;flex-direction: column;margin-top: 0.3rem}.mobile-footer .mf-panel .dropdown-item{text-align: left;padding: 0.4rem 0.6rem}.mobile-footer .anim-toggle{display: inline-flex;gap: 0.5rem;align-items: center;background: none;border: 0;padding: 0.2rem 0;color: var(--muted-foreground);font: inherit;cursor: pointer}}
|
|
1
|
+
/*! danieldeusing-design v0.1.6 | MIT | https://github.com/danieldeusing/danieldeusing-design */
|
|
2
|
+
*,*::before,*::after{box-sizing: border-box}*{margin: 0}html{-webkit-text-size-adjust: 100%;text-size-adjust: 100%;tab-size: 4}body{min-height: 100vh;min-height: 100dvh;line-height: 1.5}img,picture,video,canvas,svg{display: block;max-width: 100%}input,button,textarea,select{font: inherit;color: inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap: break-word}ul,ol{list-style: none;padding: 0}a{color: inherit;text-decoration: none}table{border-collapse: collapse}:root{--background: #f5efe2;--foreground: #43352a;--card: #efe7d4;--card-foreground: #43352a;--popover: #efe7d4;--popover-foreground: #43352a;--primary: #8a4516;--primary-foreground: #f8f3e8;--secondary: #ece3cf;--secondary-foreground: #43352a;--muted: #ece3cf;--muted-foreground: #71614e;--accent: #8a4516;--accent-foreground: #f8f3e8;--destructive: #a02c2c;--border: #d9cdb6;--input: #d9cdb6;--ring: #8a4516;--glow: rgba(160,82,45,0.1);--glow-soft: rgba(160,82,45,0.05);--scanline-opacity: 0.15;--radius: 0rem;--font-mono: "JetBrains Mono Variable","JetBrains Mono","Menlo",monospace}html[data-theme="green"]{--background: #020604;--foreground: #4fdd7d;--card: #04110a;--card-foreground: #4fdd7d;--popover: #04110a;--popover-foreground: #4fdd7d;--primary: #33ff66;--primary-foreground: #02160a;--secondary: #071509;--secondary-foreground: #4fdd7d;--muted: #071509;--muted-foreground: #3da45e;--accent: #33ff66;--accent-foreground: #02160a;--destructive: #ff5c5c;--border: #1c4a2c;--input: #1c4a2c;--ring: #33ff66;--glow: rgba(51,255,102,0.35);--glow-soft: rgba(51,255,102,0.12);--scanline-opacity: 0.5}html[data-theme="mono"]{--background: #050505;--foreground: #d4d4d4;--card: #0d0d0d;--card-foreground: #d4d4d4;--popover: #0d0d0d;--popover-foreground: #d4d4d4;--primary: #ffffff;--primary-foreground: #050505;--secondary: #111111;--secondary-foreground: #d4d4d4;--muted: #111111;--muted-foreground: #8a8a8a;--accent: #ffffff;--accent-foreground: #050505;--destructive: #ff5c5c;--border: #333333;--input: #333333;--ring: #ffffff;--glow: rgba(255,255,255,0.25);--glow-soft: rgba(255,255,255,0.08);--scanline-opacity: 0.45}html[data-theme="paper"]{--background: #fafafa;--foreground: #1f1f1f;--card: #f1f1f1;--card-foreground: #1f1f1f;--popover: #f1f1f1;--popover-foreground: #1f1f1f;--primary: #000000;--primary-foreground: #fafafa;--secondary: #efefef;--secondary-foreground: #1f1f1f;--muted: #efefef;--muted-foreground: #595959;--accent: #000000;--accent-foreground: #fafafa;--destructive: #b3261e;--border: #d4d4d4;--input: #d4d4d4;--ring: #000000;--glow: rgba(0,0,0,0.06);--glow-soft: rgba(0,0,0,0.04);--scanline-opacity: 0.12}html{scroll-behavior: smooth}*,*::before,*::after{border-color: var(--border)}:focus-visible{outline: 2px solid var(--ring);outline-offset: 2px}body{background: var(--background);color: var(--foreground);font-family: var(--font-mono);font-size: 0.75rem;line-height: 1.5;overflow-x: hidden;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}button:not(:disabled),summary,[role="button"]{cursor: pointer}body::after{content: "";position: fixed;inset: 0;z-index: 40;pointer-events: none;background: repeating-linear-gradient( 0deg,rgba(0,0,0,0.25) 0px,rgba(0,0,0,0.25) 1px,transparent 1px,transparent 3px );opacity: var(--scanline-opacity)}::selection{background: var(--primary);color: var(--primary-foreground)}.glow{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.glow-lg{color: var(--primary);text-shadow: 0 0 12px var(--glow)}.prompt{font-size: 0.75rem;font-weight: 700;color: var(--muted-foreground)}.prompt::before{content: "$ ";color: var(--primary)}.comment::before{content: "# ";color: var(--border)}.cursor-block{display: inline-block;width: 0.55em;height: 1em;margin-left: 8px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em);animation: ddd-blink 1.1s step-end infinite}@keyframes ddd-blink{50%{opacity: 0}}.btn-terminal{display: inline-block;background: var(--primary);color: var(--primary-foreground);font-weight: 700;padding: 12px 24px;box-shadow: 0 0 16px var(--glow);transition: box-shadow 0.15s ease,transform 0.15s ease}.btn-terminal::before{content: "> "}.btn-terminal:hover{box-shadow: 0 0 28px var(--glow);transform: translateY(-2px)}.link-quiet{color: var(--muted-foreground);text-decoration: underline;text-underline-offset: 4px;transition: color 0.15s ease}.link-quiet:hover{color: var(--primary)}.anim-toggle{display: inline-flex;align-items: center;gap: 6px;font: inherit;color: var(--muted-foreground);background: none;border: 0;cursor: pointer;transition: color 0.15s ease}.anim-toggle:hover{color: var(--primary)}.anim-toggle[aria-pressed="true"] [data-anim-box]{color: var(--primary)}.dd-dot{display: inline-block;width: 11px;height: 11px;flex: none;border-radius: 50%;background: currentColor}.dd-flag{display: inline-block;width: 15px;height: 10px;flex: none;border: 1px solid var(--border);background-size: cover;background-repeat: no-repeat}.dd-flag-de{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='4' fill='%23262626'/><rect y='4' width='18' height='4' fill='%23c83232'/><rect y='8' width='18' height='4' fill='%23e8be32'/></svg>")}.dd-flag-en{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%23b22234'/><rect y='4' width='18' height='4' fill='%23ececec'/><rect width='8' height='6' fill='%233c3b6e'/></svg>")}.dd-flag-pt{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%231c9148'/><polygon points='9,1.5 15.5,6 9,10.5 2.5,6' fill='%23e8c832'/><rect x='8' y='5' width='2' height='2' fill='%232c3f87'/></svg>")}.dd-flag-es{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='6' height='12' fill='%2315734c'/><rect x='6' width='6' height='12' fill='%23ececec'/><rect x='12' width='6' height='12' fill='%23bf2233'/><rect x='8' y='5' width='2' height='2' fill='%237a5c3a'/></svg>")}.ascii-rule{margin: 1rem 0;border: 0;color: var(--border);line-height: 1;white-space: nowrap;overflow: hidden;user-select: none}.ascii-rule::before{content: "────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"}.card-terminal{background: var(--card);border: 1px solid var(--border);transition: border-color 0.15s ease,box-shadow 0.15s ease}.card-terminal:hover{border-color: var(--primary);box-shadow: 0 0 20px var(--glow-soft)}.dropdown{position: relative}.dropdown>summary{display: inline-flex;align-items: center;gap: 6px;cursor: pointer;user-select: none;list-style: none;color: var(--muted-foreground);transition: color 0.15s ease}.dropdown>summary::-webkit-details-marker{display: none}.dropdown>summary:hover,.dropdown[open]>summary{color: var(--primary)}.dropdown-panel{position: absolute;right: 0;bottom: calc(100% + 12px);z-index: 50;min-width: 128px;margin: 0;padding: 4px 0;list-style: none;background: var(--card);border: 1px solid var(--border);border-radius: 0;box-shadow: 0 0 20px var(--glow-soft)}.dropdown-panel--down{top: calc(100% + 8px);bottom: auto;left: 0;right: auto}.dropdown-item{display: flex;align-items: center;gap: 8px;width: 100%;padding: 5px 14px;text-align: left;font: inherit;line-height: 1.5;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;white-space: nowrap;transition: color 0.15s ease}.dropdown-item:hover{color: var(--primary);background: var(--muted)}.dropdown-item[aria-current="true"],html:not([data-theme]) .dropdown-item[data-theme-value="warm"],html[data-theme="green"] .dropdown-item[data-theme-value="green"],html[data-theme="mono"] .dropdown-item[data-theme-value="mono"],html[data-theme="paper"] .dropdown-item[data-theme-value="paper"],html[data-theme="warm"] .dropdown-item[data-theme-value="warm"]{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.eli5{margin: 1.25em 0;padding: 0.7em 1em;color: var(--foreground);background: color-mix(in srgb,var(--primary) 7%,var(--card));border: 1px solid var(--border);border-left: 3px solid var(--primary);border-radius: var(--radius);font-size: 0.92em;line-height: 1.6}.eli5::before{content: "ELI5";display: inline-flex;align-items: center;justify-content: center;margin-right: 0.6em;vertical-align: 0.08em;font-family: var(--font-mono);font-size: 0.72em;font-weight: 700;line-height: 1;letter-spacing: 0.04em;padding: 0.34em 0.6em;border-radius: 5px;background: #b42318;color: #fff}.eli5-term{font-weight: 700;color: var(--primary)}html.anim-off *,html.anim-off *::before,html.anim-off *::after{animation: none !important}html.anim-off .cursor-block{display: none}@media (prefers-reduced-motion: no-preference){html.term-anim [data-term] .prompt:not(.term-live),html.term-anim [data-term] .prompt:not(.term-live)::before{color: transparent}html.term-anim [data-term] [data-term-out]:not(.term-show){visibility: hidden}html.term-anim [data-term] [data-term-out].term-show{animation: ddd-term-output 0.2s steps(3,end) both}@keyframes ddd-term-output{from{opacity: 0}}html.term-anim [data-term] [data-term-out].term-show>*{animation: ddd-term-output 0.25s steps(3,end) both}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(2){animation-delay: 0.09s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(3){animation-delay: 0.18s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(4){animation-delay: 0.27s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(5){animation-delay: 0.36s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(6){animation-delay: 0.45s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(7){animation-delay: 0.54s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(8){animation-delay: 0.63s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(9){animation-delay: 0.72s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(10){animation-delay: 0.81s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(n + 11){animation-delay: 0.9s}.term-caret{display: inline-block;width: 0.55em;height: 1em;margin-left: 2px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em)}}.skip-link{position: absolute;left: -999px;top: 0;z-index: 100;background: var(--card);border: 1px solid var(--primary);padding: 0.5rem 1rem;color: var(--primary)}.skip-link:focus{left: 0.5rem;top: 0.5rem}.visually-hidden{position: absolute;width: 1px;height: 1px;overflow: hidden;clip: rect(0 0 0 0);white-space: nowrap}header.bar{position: sticky;top: 0;z-index: 30;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.6rem 1.25rem;border-bottom: 1px solid var(--border);background: var(--card)}header.bar .brand{display: inline-flex;align-items: center;font-weight: 700;font-size: 1rem}header.bar .brand,header.bar .brand a{color: inherit;text-decoration: none}header.bar .dropdown summary{padding: 0.6rem 0.4rem}.bar-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}footer.status{position: fixed;inset-inline: 0;bottom: 0;z-index: 50;min-height: 2rem;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.35rem 1.25rem;border-top: 1px solid var(--border);background: var(--card);font-size: 0.7rem}footer.status .dropdown summary,footer.status .anim-toggle{padding: 0.55rem 0.4rem}.status-left{color: var(--muted-foreground);min-width: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.status-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}.sep{width: 1px;height: 0.9rem;background: var(--border)}.doc-link{color: var(--muted-foreground);text-decoration: none;transition: color 0.15s ease}.doc-link:hover{color: var(--primary)}.ls-row{display: flex;align-items: baseline;gap: 0.9rem}.ls-perm{color: var(--muted-foreground);font-size: 0.72rem;letter-spacing: 0}.ls-row--sub .ls-name{padding-left: 1rem}.ls-panel{min-width: 17rem;left: auto !important;right: 0}#nav{position: relative}.nav-burger{display: none;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;padding: 0.55rem;margin: -0.3rem -0.3rem -0.3rem 0}.nav-burger:hover{color: var(--primary)}.mobile-nav{display: none;list-style: none;margin: 0;padding: 0}.mobile-footer{display: none}@media (max-width: 48rem){.nav-burger{display: inline-flex;align-items: center}.site-nav{display: none;position: absolute;top: 100%;left: 0;right: 0;z-index: 40;background: var(--card);border-bottom: 1px solid var(--border);padding: 0.4rem 1.25rem 0.9rem;max-height: calc(100vh - 6rem);overflow-y: auto}.site-nav.open{display: block}.site-nav>.dropdown{display: none}.mobile-nav{display: flex;flex-direction: column}.mobile-nav .mobile-item{display: flex;align-items: baseline;gap: 0.9rem;padding: 0.65rem 0;text-decoration: none;color: var(--foreground);font-size: 0.9rem;border-bottom: 1px solid var(--border)}.mobile-nav li:last-child .mobile-item{border-bottom: 0}.mobile-nav .mobile-item:active .ls-name,.mobile-nav .mobile-item:hover .ls-name{color: var(--primary)}footer.status{display: none}.mobile-footer{display: flex;flex-direction: column;gap: 0.55rem;margin-top: 0.8rem;border-top: 1px solid var(--border);padding-top: 0.8rem;font-size: 0.85rem}.mobile-footer .doc-link{padding: 0.2rem 0}.mobile-footer .mobile-theme summary{list-style: none;display: flex;align-items: center;gap: 0.5rem;color: var(--muted-foreground);cursor: pointer;padding: 0.2rem 0}.mobile-footer .mobile-theme summary::-webkit-details-marker{display: none}.mobile-footer .mf-chev{margin-left: auto;opacity: 0.7}.mobile-footer .mf-panel{display: flex;flex-direction: column;margin-top: 0.3rem}.mobile-footer .mf-panel .dropdown-item{text-align: left;padding: 0.4rem 0.6rem}.mobile-footer .anim-toggle{display: inline-flex;gap: 0.5rem;align-items: center;background: none;border: 0;padding: 0.2rem 0;color: var(--muted-foreground);font: inherit;cursor: pointer}}[data-tip]{cursor: help}span[data-tip],th[data-tip]{border-bottom: 1px dotted var(--muted-foreground)}#ddtip{position: fixed;z-index: 9999;display: none;max-width: 340px;background: var(--background);color: var(--foreground);border: 1px solid var(--muted-foreground);border-radius: 4px;padding: 7px 10px;font-size: 0.72rem;line-height: 1.45;font-weight: 400;text-align: left;white-space: normal;pointer-events: none;box-shadow: 0 4px 14px rgba(0,0,0,0.25)}@media print{@page{margin: 14mm 12mm}:root,html,html[data-theme]{--background: #ffffff;--foreground: #111111;--card: #ffffff;--card-foreground: #111111;--popover: #ffffff;--popover-foreground: #111111;--primary: #000000;--primary-foreground: #ffffff;--secondary: #ffffff;--secondary-foreground: #111111;--muted: #ffffff;--muted-foreground: #444444;--accent: #000000;--accent-foreground: #ffffff;--destructive: #7a1c1c;--border: #9a9a9a;--input: #9a9a9a;--ring: #000000;--glow: transparent;--glow-soft: transparent;--scanline-opacity: 0}html{zoom: 1 !important;font-size: 16px;scroll-behavior: auto}body{background: #ffffff;color: var(--foreground);font-size: 12px;line-height: 1.45;overflow: visible}body::after{display: none !important}*,*::before,*::after{animation: none !important;transition: none !important;text-shadow: none !important;box-shadow: none !important}html.term-anim [data-term] [data-term-out],html.term-anim [data-term] [data-term-out]:not(.term-show),html.term-anim [data-term] [data-term-out]>*{visibility: visible !important;opacity: 1 !important}html.term-anim [data-term] .prompt:not(.term-live){color: var(--muted-foreground) !important}html.term-anim [data-term] .prompt:not(.term-live)::before{color: var(--primary) !important}header.bar,footer.status,.site-nav,.nav-burger,.mobile-nav,.mobile-footer,.skip-link,.dropdown,.dropdown-panel,.anim-toggle,.cursor-block,.term-caret,.ascii-rule,.toc,#ddtip{display: none !important}[data-tip]{cursor: auto}span[data-tip],th[data-tip]{border-bottom: 0}.wrap{max-width: none !important;margin: 0 !important;padding: 0 !important}.layout{display: block !important}.content{min-width: 0}h1,.title{font-size: 1.5rem !important}h2{font-size: 1.15rem !important}h3,.sub{font-size: 1rem !important}h4{font-size: 0.9rem !important}.prompt{font-size: 0.7rem}h1,h2,h3,h4,.prompt,.toc-label{break-after: avoid-page;break-inside: avoid}p,li,blockquote{orphans: 3;widows: 3}pre,figure,blockquote,tr,img,.eli5,.card-terminal{break-inside: avoid}svg{break-inside: auto}thead{display: table-header-group}.table-scroll,pre,.diagram{overflow: visible !important;max-width: 100% !important}pre{white-space: pre-wrap !important;overflow-wrap: anywhere;font-size: 0.75rem !important;background: transparent !important}pre.mermaid[data-processed]{white-space: normal !important}code{background: transparent !important;overflow-wrap: anywhere}table{width: 100% !important;table-layout: auto;border-collapse: collapse;font-size: 0.75rem !important}th,td{overflow-wrap: break-word;white-space: normal !important}td code,th code,td a,th a{overflow-wrap: anywhere}a{color: inherit;text-decoration: underline;text-underline-offset: 2px}a.card-terminal,a[class*="card"]{text-decoration: none}.glow,.glow-lg{color: inherit}.btn-terminal{border: 1px solid var(--border);background: transparent;color: var(--foreground)}.mermaid svg{display: block;margin-inline: auto;width: auto !important;height: auto !important;max-width: 100% !important;max-height: 235mm !important}.mermaid svg .node rect,.mermaid svg .node polygon,.mermaid svg .node circle,.mermaid svg .node path,.mermaid svg .label-container,.mermaid svg .cluster rect,.mermaid svg .actor,.mermaid svg .note{fill: #ffffff !important;stroke: #333333 !important}.mermaid svg .edgePath path,.mermaid svg .flowchart-link,.mermaid svg line,.mermaid svg .messageLine0,.mermaid svg .messageLine1{stroke: #333333 !important}.mermaid svg .arrowheadPath,.mermaid svg marker path,.mermaid svg marker polygon{fill: #333333 !important;stroke: #333333 !important}.mermaid svg text,.mermaid svg .nodeLabel,.mermaid svg .edgeLabel,.mermaid svg .cluster-label,.mermaid svg .messageText,.mermaid svg foreignObject div,.mermaid svg foreignObject span,.mermaid svg p{fill: #111111 !important;color: #111111 !important;background: transparent !important}.mermaid svg .edgeLabel rect,.mermaid svg .edgeLabel foreignObject>div{fill: #ffffff !important;background: #ffffff !important}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danieldeusing/design",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "The danieldeusing terminal design system \u2014 framework-agnostic CSS tokens, components, and a vanilla-JS runtime for the CRT/JetBrains-Mono look used across danieldeusing.de, seedr, and briefs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/runtime/index.js
CHANGED
package/runtime/terminal.js
CHANGED
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
* After the initial on-screen sections finish, it sets window.termContentDone
|
|
20
20
|
* and dispatches a "term:contentdone" event — a hook for chaining a follow-up
|
|
21
21
|
* animation (e.g. a nav that "runs" once the page has finished printing).
|
|
22
|
+
*
|
|
23
|
+
* On `beforeprint` the whole session is fast-forwarded, so a page printed while
|
|
24
|
+
* it is still typing prints complete. src/print.css covers the CSS half of this
|
|
25
|
+
* (nothing stays hidden); only the truncated prompt text needs JS.
|
|
22
26
|
*/
|
|
23
27
|
|
|
24
28
|
export function initTerminal() {
|
|
@@ -103,7 +107,25 @@ export function initTerminal() {
|
|
|
103
107
|
sequence = sequence.then(() => playSection(section));
|
|
104
108
|
};
|
|
105
109
|
|
|
110
|
+
// Printing must never show a half-typed page. src/print.css forces the
|
|
111
|
+
// revealed state for everything CSS can reach, but a prompt caught mid-type
|
|
112
|
+
// has been truncated in the DOM — no stylesheet can put those characters
|
|
113
|
+
// back. Snapshot the text up front and restore it synchronously when the
|
|
114
|
+
// browser announces a print.
|
|
115
|
+
const finishForPrint = () => {
|
|
116
|
+
document.querySelectorAll("[data-term] .prompt").forEach((prompt) => {
|
|
117
|
+
if (prompt.dataset.termText !== undefined) prompt.textContent = prompt.dataset.termText;
|
|
118
|
+
prompt.classList.add("term-live");
|
|
119
|
+
});
|
|
120
|
+
document.querySelectorAll("[data-term] [data-term-out]").forEach((chunk) => chunk.classList.add("term-show"));
|
|
121
|
+
};
|
|
122
|
+
|
|
106
123
|
const start = () => {
|
|
124
|
+
document.querySelectorAll("[data-term] .prompt").forEach((prompt) => {
|
|
125
|
+
prompt.dataset.termText = (prompt.textContent || "").trim();
|
|
126
|
+
});
|
|
127
|
+
window.addEventListener("beforeprint", finishForPrint);
|
|
128
|
+
|
|
107
129
|
const observer = new IntersectionObserver(
|
|
108
130
|
(entries) => {
|
|
109
131
|
entries.forEach((entry) => {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* tooltip.js — viewport-clamped hover/focus tooltips for `[data-tip]`.
|
|
3
|
+
*
|
|
4
|
+
* Markup contract:
|
|
5
|
+
* <span data-tip="Explanation shown on hover">metric</span>
|
|
6
|
+
*
|
|
7
|
+
* One singleton panel (`#ddtip`, styled in src/tooltip.css) is appended to
|
|
8
|
+
* <body> and positioned with `position: fixed`, so it escapes every overflow/
|
|
9
|
+
* clip context and always renders on top. Placement prefers below the anchor,
|
|
10
|
+
* flips above when there is no room, and clamps horizontally to the viewport —
|
|
11
|
+
* a tooltip must never be cut off. Event delegation means dynamically rendered
|
|
12
|
+
* [data-tip] nodes just work.
|
|
13
|
+
*/
|
|
14
|
+
export function initTooltips() {
|
|
15
|
+
if (document.getElementById("ddtip")) return;
|
|
16
|
+
const tip = document.createElement("div");
|
|
17
|
+
tip.id = "ddtip";
|
|
18
|
+
tip.setAttribute("role", "tooltip");
|
|
19
|
+
document.body.appendChild(tip);
|
|
20
|
+
|
|
21
|
+
let anchor = null;
|
|
22
|
+
function show(el) {
|
|
23
|
+
anchor = el;
|
|
24
|
+
tip.textContent = el.getAttribute("data-tip");
|
|
25
|
+
tip.style.display = "block";
|
|
26
|
+
tip.style.left = "0px";
|
|
27
|
+
tip.style.top = "0px";
|
|
28
|
+
const margin = 8;
|
|
29
|
+
const r = el.getBoundingClientRect();
|
|
30
|
+
const t = tip.getBoundingClientRect();
|
|
31
|
+
const x = Math.min(Math.max(r.left, margin), window.innerWidth - t.width - margin);
|
|
32
|
+
let y = r.bottom + 6;
|
|
33
|
+
if (y + t.height > window.innerHeight - margin) y = r.top - t.height - 6;
|
|
34
|
+
if (y < margin) y = margin;
|
|
35
|
+
tip.style.left = x + "px";
|
|
36
|
+
tip.style.top = y + "px";
|
|
37
|
+
}
|
|
38
|
+
function hide() {
|
|
39
|
+
anchor = null;
|
|
40
|
+
tip.style.display = "none";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
document.addEventListener("mouseover", (event) => {
|
|
44
|
+
const el = event.target.closest("[data-tip]");
|
|
45
|
+
if (el) show(el);
|
|
46
|
+
else if (anchor) hide();
|
|
47
|
+
});
|
|
48
|
+
document.addEventListener("focusin", (event) => {
|
|
49
|
+
const el = event.target.closest("[data-tip]");
|
|
50
|
+
if (el) show(el);
|
|
51
|
+
});
|
|
52
|
+
document.addEventListener("focusout", hide);
|
|
53
|
+
document.addEventListener("scroll", () => anchor && show(anchor), true);
|
|
54
|
+
}
|
package/src/index.css
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The no-Tailwind entry point. Import this one file and you get the full
|
|
5
5
|
* terminal theme: a minimal reset, the four-theme token set, the document base,
|
|
6
|
-
*
|
|
7
|
-
* Tauri webview — anywhere CSS @import is understood, with no
|
|
6
|
+
* every component primitive, and the print layer. Works in plain HTML, React,
|
|
7
|
+
* Angular, Vue, a Tauri webview — anywhere CSS @import is understood, with no
|
|
8
|
+
* build step.
|
|
8
9
|
*
|
|
9
10
|
* import "@danieldeusing/design"; // package "." export
|
|
10
11
|
* <link rel="stylesheet" href=".../dist/danieldeusing-design.css"> // CDN
|
|
@@ -18,3 +19,5 @@
|
|
|
18
19
|
@import "./base.css";
|
|
19
20
|
@import "./components.css";
|
|
20
21
|
@import "./chrome.css";
|
|
22
|
+
@import "./tooltip.css";
|
|
23
|
+
@import "./print.css";
|
package/src/print.css
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* danieldeusing-design — print layer.
|
|
3
|
+
*
|
|
4
|
+
* Paper is a different device, not a narrow screen. This layer strips the parts
|
|
5
|
+
* of the terminal look that only exist to sell "a CRT is running" — scanlines,
|
|
6
|
+
* phosphor glow, sticky chrome, the reveal animation — and lays the content out
|
|
7
|
+
* as a document: black on white, 12px body text, sane page breaks.
|
|
8
|
+
*
|
|
9
|
+
* Load LAST (index.css imports it after every other layer) so its token
|
|
10
|
+
* overrides win on source order without needing !important on each one.
|
|
11
|
+
*
|
|
12
|
+
* Three things here are load-bearing and easy to lose in a refactor:
|
|
13
|
+
*
|
|
14
|
+
* 1. The terminal reveal is forced open. runtime/terminal.js only reveals a
|
|
15
|
+
* [data-term-out] once its section scrolls into view, so a long page that
|
|
16
|
+
* is printed straight after load has most of its content sitting at
|
|
17
|
+
* visibility:hidden. Printing it would silently produce blank pages — the
|
|
18
|
+
* reader only finds out on paper. Everything is forced visible here
|
|
19
|
+
* regardless of animation state.
|
|
20
|
+
* 2. `zoom` is reset. Pages that use the resolution-independent zoom trick
|
|
21
|
+
* (html.style.zoom = innerWidth / 1920) carry that multiplier into the
|
|
22
|
+
* print box, which is what makes a printout come out oversized.
|
|
23
|
+
* 3. Mermaid bakes the ACTIVE theme's colours into the SVG at render time, so
|
|
24
|
+
* a diagram rendered under `green`/`mono` is dark-on-dark on paper no
|
|
25
|
+
* matter what the page tokens say. The SVG parts are repainted below.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
@media print {
|
|
29
|
+
@page {
|
|
30
|
+
margin: 14mm 12mm;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* ── ink-frugal palette, whatever theme is on screen ────────────────────
|
|
34
|
+
`html[data-theme]` matches the specificity of the themed token blocks in
|
|
35
|
+
tokens.css and comes later in the bundle, so it wins for every theme. */
|
|
36
|
+
:root,
|
|
37
|
+
html,
|
|
38
|
+
html[data-theme] {
|
|
39
|
+
--background: #ffffff;
|
|
40
|
+
--foreground: #111111;
|
|
41
|
+
--card: #ffffff;
|
|
42
|
+
--card-foreground: #111111;
|
|
43
|
+
--popover: #ffffff;
|
|
44
|
+
--popover-foreground: #111111;
|
|
45
|
+
--primary: #000000;
|
|
46
|
+
--primary-foreground: #ffffff;
|
|
47
|
+
--secondary: #ffffff;
|
|
48
|
+
--secondary-foreground: #111111;
|
|
49
|
+
--muted: #ffffff;
|
|
50
|
+
--muted-foreground: #444444;
|
|
51
|
+
--accent: #000000;
|
|
52
|
+
--accent-foreground: #ffffff;
|
|
53
|
+
--destructive: #7a1c1c;
|
|
54
|
+
--border: #9a9a9a;
|
|
55
|
+
--input: #9a9a9a;
|
|
56
|
+
--ring: #000000;
|
|
57
|
+
--glow: transparent;
|
|
58
|
+
--glow-soft: transparent;
|
|
59
|
+
--scanline-opacity: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* ── document metrics ──────────────────────────────────────────────────
|
|
63
|
+
The rem baseline is pinned so the design's rem scale lands where it was
|
|
64
|
+
drawn, and the body size is stated in px so it is 12px on paper whatever
|
|
65
|
+
the browser's default font size is. `zoom` is a screen-only device. */
|
|
66
|
+
html {
|
|
67
|
+
zoom: 1 !important;
|
|
68
|
+
font-size: 16px;
|
|
69
|
+
scroll-behavior: auto;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
body {
|
|
73
|
+
background: #ffffff;
|
|
74
|
+
color: var(--foreground);
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
line-height: 1.45;
|
|
77
|
+
overflow: visible;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* CRT scanline overlay: a fixed, full-viewport gradient — on paper it is a
|
|
81
|
+
grey wash over the page. */
|
|
82
|
+
body::after {
|
|
83
|
+
display: none !important;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* ── nothing animates on paper ─────────────────────────────────────────
|
|
87
|
+
Also the mechanism that un-hides the terminal reveal: the keyframes use
|
|
88
|
+
`both`, so killing the animation restores the element's own opacity. */
|
|
89
|
+
*,
|
|
90
|
+
*::before,
|
|
91
|
+
*::after {
|
|
92
|
+
animation: none !important;
|
|
93
|
+
transition: none !important;
|
|
94
|
+
text-shadow: none !important;
|
|
95
|
+
box-shadow: none !important;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* ── the reveal must never decide what lands on paper ──────────────────
|
|
99
|
+
See note 1 at the top of this file. */
|
|
100
|
+
html.term-anim [data-term] [data-term-out],
|
|
101
|
+
html.term-anim [data-term] [data-term-out]:not(.term-show),
|
|
102
|
+
html.term-anim [data-term] [data-term-out] > * {
|
|
103
|
+
visibility: visible !important;
|
|
104
|
+
opacity: 1 !important;
|
|
105
|
+
}
|
|
106
|
+
html.term-anim [data-term] .prompt:not(.term-live) {
|
|
107
|
+
color: var(--muted-foreground) !important;
|
|
108
|
+
}
|
|
109
|
+
html.term-anim [data-term] .prompt:not(.term-live)::before {
|
|
110
|
+
color: var(--primary) !important;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* ── screen-only chrome ────────────────────────────────────────────────
|
|
114
|
+
.toc is the "On this page" navigator: a screen affordance with no meaning
|
|
115
|
+
on paper, and the first thing that makes a printout look broken. */
|
|
116
|
+
header.bar,
|
|
117
|
+
footer.status,
|
|
118
|
+
.site-nav,
|
|
119
|
+
.nav-burger,
|
|
120
|
+
.mobile-nav,
|
|
121
|
+
.mobile-footer,
|
|
122
|
+
.skip-link,
|
|
123
|
+
.dropdown,
|
|
124
|
+
.dropdown-panel,
|
|
125
|
+
.anim-toggle,
|
|
126
|
+
.cursor-block,
|
|
127
|
+
.term-caret,
|
|
128
|
+
.ascii-rule,
|
|
129
|
+
.toc,
|
|
130
|
+
#ddtip {
|
|
131
|
+
display: none !important;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
[data-tip] {
|
|
135
|
+
cursor: auto;
|
|
136
|
+
}
|
|
137
|
+
span[data-tip],
|
|
138
|
+
th[data-tip] {
|
|
139
|
+
border-bottom: 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ── layout: the page is the column ────────────────────────────────────
|
|
143
|
+
.wrap/.layout/.content are the documentation-template vocabulary shipped
|
|
144
|
+
in templates/documentation.html. */
|
|
145
|
+
.wrap {
|
|
146
|
+
max-width: none !important;
|
|
147
|
+
margin: 0 !important;
|
|
148
|
+
padding: 0 !important;
|
|
149
|
+
}
|
|
150
|
+
.layout {
|
|
151
|
+
display: block !important;
|
|
152
|
+
}
|
|
153
|
+
.content {
|
|
154
|
+
min-width: 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* ── heading hierarchy against a 12px body ─────────────────────────────
|
|
158
|
+
24 / 18 / 16 / 14 px. !important because page-level rules give these
|
|
159
|
+
classes a higher specificity than a bare element selector. */
|
|
160
|
+
h1,
|
|
161
|
+
.title {
|
|
162
|
+
font-size: 1.5rem !important;
|
|
163
|
+
}
|
|
164
|
+
h2 {
|
|
165
|
+
font-size: 1.15rem !important;
|
|
166
|
+
}
|
|
167
|
+
h3,
|
|
168
|
+
.sub {
|
|
169
|
+
font-size: 1rem !important;
|
|
170
|
+
}
|
|
171
|
+
h4 {
|
|
172
|
+
font-size: 0.9rem !important;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.prompt {
|
|
176
|
+
font-size: 0.7rem;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* ── page breaks ───────────────────────────────────────────────────────
|
|
180
|
+
A heading (or a `$ command` section header) must never be the last thing
|
|
181
|
+
on a page. Tables break between rows and repeat their header; everything
|
|
182
|
+
that reads as one unit stays together. */
|
|
183
|
+
h1,
|
|
184
|
+
h2,
|
|
185
|
+
h3,
|
|
186
|
+
h4,
|
|
187
|
+
.prompt,
|
|
188
|
+
.toc-label {
|
|
189
|
+
break-after: avoid-page;
|
|
190
|
+
break-inside: avoid;
|
|
191
|
+
}
|
|
192
|
+
p,
|
|
193
|
+
li,
|
|
194
|
+
blockquote {
|
|
195
|
+
orphans: 3;
|
|
196
|
+
widows: 3;
|
|
197
|
+
}
|
|
198
|
+
pre,
|
|
199
|
+
figure,
|
|
200
|
+
blockquote,
|
|
201
|
+
tr,
|
|
202
|
+
img,
|
|
203
|
+
.eli5,
|
|
204
|
+
.card-terminal {
|
|
205
|
+
break-inside: avoid;
|
|
206
|
+
}
|
|
207
|
+
/* NOT svg. A mermaid flowchart is routinely taller than a printed page;
|
|
208
|
+
`break-inside: avoid` on the SVG pushes it past the page boundary while its
|
|
209
|
+
wrapper stays behind, which prints an entire page as an empty bordered box.
|
|
210
|
+
Let the SVG break where the wrapper breaks. */
|
|
211
|
+
svg {
|
|
212
|
+
break-inside: auto;
|
|
213
|
+
}
|
|
214
|
+
thead {
|
|
215
|
+
display: table-header-group;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* ── nothing scrolls on paper ──────────────────────────────────────────
|
|
219
|
+
An overflow-x container has no scrollbar in print: whatever sits past the
|
|
220
|
+
right edge is simply gone. Let it wrap instead. */
|
|
221
|
+
.table-scroll,
|
|
222
|
+
pre,
|
|
223
|
+
.diagram {
|
|
224
|
+
overflow: visible !important;
|
|
225
|
+
max-width: 100% !important;
|
|
226
|
+
}
|
|
227
|
+
pre {
|
|
228
|
+
white-space: pre-wrap !important;
|
|
229
|
+
overflow-wrap: anywhere;
|
|
230
|
+
font-size: 0.75rem !important;
|
|
231
|
+
background: transparent !important;
|
|
232
|
+
}
|
|
233
|
+
pre.mermaid[data-processed] {
|
|
234
|
+
white-space: normal !important;
|
|
235
|
+
}
|
|
236
|
+
code {
|
|
237
|
+
background: transparent !important;
|
|
238
|
+
overflow-wrap: anywhere;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
table {
|
|
242
|
+
width: 100% !important;
|
|
243
|
+
table-layout: auto;
|
|
244
|
+
border-collapse: collapse;
|
|
245
|
+
font-size: 0.75rem !important;
|
|
246
|
+
}
|
|
247
|
+
/* `overflow-wrap: break-word` and NOT `anywhere`: `anywhere` also shrinks a
|
|
248
|
+
cell's min-content width to one character, and the auto table layout then
|
|
249
|
+
collapses a short column to nothing ("Orchestrator" set as "Orche/strat/or"
|
|
250
|
+
down a 6-character column). Only the elements that actually hold
|
|
251
|
+
unbreakable strings — paths, URLs, identifiers — get to break anywhere. */
|
|
252
|
+
th,
|
|
253
|
+
td {
|
|
254
|
+
overflow-wrap: break-word;
|
|
255
|
+
white-space: normal !important;
|
|
256
|
+
}
|
|
257
|
+
td code,
|
|
258
|
+
th code,
|
|
259
|
+
td a,
|
|
260
|
+
th a {
|
|
261
|
+
overflow-wrap: anywhere;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* ── links read as text ────────────────────────────────────────────────
|
|
265
|
+
The URL is deliberately NOT printed after the link. These are internal
|
|
266
|
+
documents whose links are mostly in-page anchors and hosts already named
|
|
267
|
+
in the prose; appending every href would add noise and pages without
|
|
268
|
+
adding information. To turn it on, add:
|
|
269
|
+
a[href^="http"]::after { content: " (" attr(href) ")"; } */
|
|
270
|
+
a {
|
|
271
|
+
color: inherit;
|
|
272
|
+
text-decoration: underline;
|
|
273
|
+
text-underline-offset: 2px;
|
|
274
|
+
}
|
|
275
|
+
a.card-terminal,
|
|
276
|
+
a[class*="card"] {
|
|
277
|
+
text-decoration: none;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.glow,
|
|
281
|
+
.glow-lg {
|
|
282
|
+
color: inherit;
|
|
283
|
+
}
|
|
284
|
+
.btn-terminal {
|
|
285
|
+
border: 1px solid var(--border);
|
|
286
|
+
background: transparent;
|
|
287
|
+
color: var(--foreground);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* ── mermaid diagrams ──────────────────────────────────────────────────
|
|
291
|
+
See note 3 at the top of this file: the palette is baked into the SVG at
|
|
292
|
+
render time, so a diagram rendered under a dark theme prints as dark
|
|
293
|
+
boxes with invisible labels. Repaint the standard mermaid parts. */
|
|
294
|
+
/* Every diagram is scaled to fit ONE page. Not cosmetic: Chromium will not
|
|
295
|
+
start an over-tall diagram in the space left on the current page, so an
|
|
296
|
+
uncapped flowchart (they run to 2500px in a narrow column) prints a blank
|
|
297
|
+
page, then an empty bordered box, then the diagram — six such pages in the
|
|
298
|
+
executor design doc alone. `width/height: auto` with both max-* set is what
|
|
299
|
+
makes the browser scale it proportionally instead of squashing it.
|
|
300
|
+
A diagram that ends up too small to read is a diagram that is too tall for
|
|
301
|
+
paper: split it, or lay it out left-to-right. */
|
|
302
|
+
.mermaid svg {
|
|
303
|
+
display: block;
|
|
304
|
+
margin-inline: auto;
|
|
305
|
+
width: auto !important;
|
|
306
|
+
height: auto !important;
|
|
307
|
+
max-width: 100% !important;
|
|
308
|
+
max-height: 235mm !important;
|
|
309
|
+
}
|
|
310
|
+
.mermaid svg .node rect,
|
|
311
|
+
.mermaid svg .node polygon,
|
|
312
|
+
.mermaid svg .node circle,
|
|
313
|
+
.mermaid svg .node path,
|
|
314
|
+
.mermaid svg .label-container,
|
|
315
|
+
.mermaid svg .cluster rect,
|
|
316
|
+
.mermaid svg .actor,
|
|
317
|
+
.mermaid svg .note {
|
|
318
|
+
fill: #ffffff !important;
|
|
319
|
+
stroke: #333333 !important;
|
|
320
|
+
}
|
|
321
|
+
.mermaid svg .edgePath path,
|
|
322
|
+
.mermaid svg .flowchart-link,
|
|
323
|
+
.mermaid svg line,
|
|
324
|
+
.mermaid svg .messageLine0,
|
|
325
|
+
.mermaid svg .messageLine1 {
|
|
326
|
+
stroke: #333333 !important;
|
|
327
|
+
}
|
|
328
|
+
.mermaid svg .arrowheadPath,
|
|
329
|
+
.mermaid svg marker path,
|
|
330
|
+
.mermaid svg marker polygon {
|
|
331
|
+
fill: #333333 !important;
|
|
332
|
+
stroke: #333333 !important;
|
|
333
|
+
}
|
|
334
|
+
.mermaid svg text,
|
|
335
|
+
.mermaid svg .nodeLabel,
|
|
336
|
+
.mermaid svg .edgeLabel,
|
|
337
|
+
.mermaid svg .cluster-label,
|
|
338
|
+
.mermaid svg .messageText,
|
|
339
|
+
.mermaid svg foreignObject div,
|
|
340
|
+
.mermaid svg foreignObject span,
|
|
341
|
+
.mermaid svg p {
|
|
342
|
+
fill: #111111 !important;
|
|
343
|
+
color: #111111 !important;
|
|
344
|
+
background: transparent !important;
|
|
345
|
+
}
|
|
346
|
+
.mermaid svg .edgeLabel rect,
|
|
347
|
+
.mermaid svg .edgeLabel foreignObject > div {
|
|
348
|
+
fill: #ffffff !important;
|
|
349
|
+
background: #ffffff !important;
|
|
350
|
+
}
|
|
351
|
+
}
|
package/src/tailwind.css
CHANGED
package/src/tooltip.css
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* tooltip.css — styles for the [data-tip] tooltip system (runtime/tooltip.js).
|
|
3
|
+
* The panel is a body-level singleton with position:fixed — it can never be
|
|
4
|
+
* clipped by overflow containers and always sits on top.
|
|
5
|
+
*/
|
|
6
|
+
[data-tip] { cursor: help; }
|
|
7
|
+
span[data-tip], th[data-tip] { border-bottom: 1px dotted var(--muted-foreground); }
|
|
8
|
+
|
|
9
|
+
#ddtip {
|
|
10
|
+
position: fixed; z-index: 9999; display: none; max-width: 340px;
|
|
11
|
+
background: var(--background); color: var(--foreground);
|
|
12
|
+
border: 1px solid var(--muted-foreground); border-radius: 4px;
|
|
13
|
+
padding: 7px 10px; font-size: 0.72rem; line-height: 1.45; font-weight: 400;
|
|
14
|
+
text-align: left; white-space: normal; pointer-events: none;
|
|
15
|
+
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
|
|
16
|
+
}
|