margo-ui 1.2.3 → 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.
Files changed (53) hide show
  1. package/README.md +20 -4
  2. package/package.json +11 -1
  3. package/src/components/button/button.tsx +4 -4
  4. package/src/components/button/style.ts +3 -3
  5. package/src/components/button/type.ts +3 -3
  6. package/src/components/button_micro/button_micro.tsx +37 -0
  7. package/src/components/button_micro/style.ts +6 -0
  8. package/src/components/button_micro/type.ts +10 -0
  9. package/src/components/dialog/dialog.tsx +25 -0
  10. package/src/components/dialog/style.ts +6 -0
  11. package/src/components/dialog/type.ts +8 -0
  12. package/src/components/header/header.tsx +36 -0
  13. package/src/components/header/style.ts +8 -0
  14. package/src/components/header/type.ts +20 -0
  15. package/src/components/item/item.tsx +57 -0
  16. package/src/components/item/style.ts +13 -0
  17. package/src/components/item/type.ts +20 -0
  18. package/src/components/layer/layer.css +51 -0
  19. package/src/components/layer/layer.tsx +44 -0
  20. package/src/components/layer/style.ts +2 -0
  21. package/src/components/layer/type.ts +8 -0
  22. package/src/components/navigation_bar/navigation_bar.css +21 -0
  23. package/src/components/navigation_bar/navigation_bar.tsx +70 -0
  24. package/src/components/navigation_bar/style.ts +6 -0
  25. package/src/components/navigation_bar/type.ts +9 -0
  26. package/src/components/progress_bar/progress_bar.css +4 -7
  27. package/src/components/progress_bar/progress_bar.tsx +7 -4
  28. package/src/components/progress_bar/style.ts +2 -0
  29. package/src/components/progress_bar/type.ts +1 -0
  30. package/src/components/sheet/sheet.css +41 -0
  31. package/src/components/sheet/sheet.tsx +32 -0
  32. package/src/components/sheet/style.ts +14 -0
  33. package/src/components/sheet/type.ts +14 -0
  34. package/src/components/snippet/highlight.ts +83 -0
  35. package/src/components/snippet/snippet.tsx +63 -0
  36. package/src/components/snippet/style.ts +25 -0
  37. package/src/components/snippet/type.ts +26 -0
  38. package/src/components/table/style.ts +13 -0
  39. package/src/components/table/table.tsx +60 -0
  40. package/src/components/table/type.ts +14 -0
  41. package/src/components/tooltip/tooltip.tsx +7 -7
  42. package/src/components/tooltip/type.ts +2 -2
  43. package/src/css/grid.css +20 -0
  44. package/src/css/theme.css +8 -0
  45. package/src/css/variables.css +41 -3
  46. package/src/hoc/background_glow/background_glow.css +19 -9
  47. package/src/hoc/background_glow/background_glow.tsx +11 -4
  48. package/src/hoc/background_glow/style.ts +0 -8
  49. package/src/hoc/background_glow/type.ts +5 -4
  50. package/src/hoc/mask_gradient_x/mask_gradient_x.css +17 -0
  51. package/src/hoc/mask_gradient_x/mask_gradient_x.tsx +22 -0
  52. package/src/hoc/mask_gradient_x/type.ts +15 -0
  53. package/src/index.ts +33 -1
@@ -1,7 +1,7 @@
1
1
  import { Tag } from "react-renderable";
2
2
 
3
3
  import { cn } from "../../utils/cn/cn.js";
4
- import { progressBarBaseClassName } from "./style.js";
4
+ import { progressBarDefaultFill, progressBarBaseClassName } from "./style.js";
5
5
 
6
6
  import type { CSSProperties, ElementType } from "react";
7
7
  import type { ProgressBarProps } from "./type.js";
@@ -10,6 +10,7 @@ import "./progress_bar.css";
10
10
 
11
11
  export const ProgressBar = <T extends ElementType = "div">({
12
12
  animate = true,
13
+ fill = progressBarDefaultFill,
13
14
  mode = "indeterminate",
14
15
  style,
15
16
  value = 0,
@@ -26,9 +27,11 @@ export const ProgressBar = <T extends ElementType = "div">({
26
27
  aria-valuemin={isDeterminate ? 0 : undefined}
27
28
  aria-valuemax={isDeterminate ? 100 : undefined}
28
29
  aria-valuenow={isDeterminate ? progress : undefined}
29
- data-mode={mode}
30
- data-animate={animate}
31
- style={{ ...style, "--margo-progress-bar-value": `${progress}%` } as CSSProperties}
30
+ data-margo-mode={mode}
31
+ data-margo-animate={animate}
32
+ style={
33
+ { ...style, "--margo-progress-bar-fill": fill, "--margo-progress-bar-value": `${progress}%` } as CSSProperties
34
+ }
32
35
  className={cn(progressBarBaseClassName, className)}
33
36
  />
34
37
  );
@@ -1 +1,3 @@
1
+ export const progressBarDefaultFill = "linear-gradient(to right, var(--margo-color-primary-darken), var(--margo-color-primary))";
2
+
1
3
  export const progressBarBaseClassName = "margo-progress-bar relative h-0.5 overflow-hidden";
@@ -5,6 +5,7 @@ export type ProgressBarMode = "determinate" | "indeterminate";
5
5
 
6
6
  export type ProgressBarOwnProps = {
7
7
  animate?: boolean;
8
+ fill?: string;
8
9
  mode?: ProgressBarMode;
9
10
  value?: number;
10
11
  };
@@ -0,0 +1,41 @@
1
+ .margo-sheet {
2
+ transition: translate var(--margo-layer-duration) var(--margo-layer-easing);
3
+ }
4
+
5
+ .margo-sheet[data-margo-side="start"] {
6
+ translate: -100% 0;
7
+ }
8
+
9
+ .margo-sheet[data-margo-side="end"] {
10
+ translate: 100% 0;
11
+ }
12
+
13
+ .margo-sheet[data-margo-side="top"] {
14
+ translate: 0 -100%;
15
+ }
16
+
17
+ .margo-sheet[data-margo-side="bottom"] {
18
+ translate: 0 100%;
19
+ }
20
+
21
+ dialog[open] .margo-sheet {
22
+ translate: 0 0;
23
+ }
24
+
25
+ @starting-style {
26
+ dialog[open] .margo-sheet[data-margo-side="start"] {
27
+ translate: -100% 0;
28
+ }
29
+
30
+ dialog[open] .margo-sheet[data-margo-side="end"] {
31
+ translate: 100% 0;
32
+ }
33
+
34
+ dialog[open] .margo-sheet[data-margo-side="top"] {
35
+ translate: 0 -100%;
36
+ }
37
+
38
+ dialog[open] .margo-sheet[data-margo-side="bottom"] {
39
+ translate: 0 100%;
40
+ }
41
+ }
@@ -0,0 +1,32 @@
1
+ import { Tag } from "react-renderable";
2
+
3
+ import { cn } from "../../utils/cn/cn.js";
4
+ import { sheetBaseClassName, sheetBodyClassName, sheetFooterClassName, sheetSideClassName } from "./style.js";
5
+
6
+ import type { ElementType } from "react";
7
+ import type { SheetBodyProps, SheetFooterProps, SheetProps } from "./type.js";
8
+
9
+ import "./sheet.css";
10
+
11
+ export const Sheet = <T extends ElementType = "div">({ side = "end", className, children, ...rest }: SheetProps<T>) => (
12
+ <Tag
13
+ {...Tag.forward<T>(rest)}
14
+ data-margo-side={side}
15
+ data-margo-travel={true}
16
+ className={cn(sheetBaseClassName, sheetSideClassName[side], className)}
17
+ >
18
+ {children}
19
+ </Tag>
20
+ );
21
+
22
+ Sheet.Body = <T extends ElementType = "div">({ className, children, ...rest }: SheetBodyProps<T>) => (
23
+ <Tag {...Tag.forward<T>(rest)} className={cn(sheetBodyClassName, className)}>
24
+ {children}
25
+ </Tag>
26
+ );
27
+
28
+ Sheet.Footer = <T extends ElementType = "div">({ className, children, ...rest }: SheetFooterProps<T>) => (
29
+ <Tag {...Tag.forward<T>(rest)} className={cn(sheetFooterClassName, className)}>
30
+ {children}
31
+ </Tag>
32
+ );
@@ -0,0 +1,14 @@
1
+ import type { SheetSide } from "./type.js";
2
+
3
+ export const sheetBaseClassName = "margo-sheet flex flex-col overflow-hidden border-border bg-main text-on-main";
4
+
5
+ export const sheetSideClassName: Record<SheetSide, string> = {
6
+ start: "h-full w-[85%] max-w-[26rem] justify-self-start self-stretch border-r-2",
7
+ end: "h-full w-[85%] max-w-[26rem] justify-self-end self-stretch border-l-2",
8
+ top: "h-auto max-h-[40%] w-full self-start justify-self-stretch border-b-2",
9
+ bottom: "h-auto max-h-[40%] w-full self-end justify-self-stretch border-t-2",
10
+ };
11
+
12
+ export const sheetBodyClassName = "min-h-0 flex-1 overflow-y-auto px-5 py-4 text-sm";
13
+
14
+ export const sheetFooterClassName = "flex items-center justify-end gap-2 border-t-2 border-border px-5 py-4";
@@ -0,0 +1,14 @@
1
+ import type { TagProps } from "react-renderable";
2
+ import type { ElementType } from "react";
3
+
4
+ export type SheetSide = "start" | "end" | "top" | "bottom";
5
+
6
+ export type SheetOwnProps = {
7
+ side?: SheetSide;
8
+ };
9
+
10
+ export type SheetProps<T extends ElementType = "div"> = TagProps<T, SheetOwnProps>;
11
+
12
+ export type SheetBodyProps<T extends ElementType = "div"> = TagProps<T>;
13
+
14
+ export type SheetFooterProps<T extends ElementType = "div"> = TagProps<T>;
@@ -0,0 +1,83 @@
1
+ import type { SnippetToken, SnippetTokenType } from "./type.js";
2
+
3
+ const KEYWORDS = [
4
+ "as",
5
+ "async",
6
+ "await",
7
+ "break",
8
+ "case",
9
+ "catch",
10
+ "class",
11
+ "const",
12
+ "continue",
13
+ "default",
14
+ "delete",
15
+ "do",
16
+ "else",
17
+ "export",
18
+ "extends",
19
+ "false",
20
+ "for",
21
+ "from",
22
+ "function",
23
+ "if",
24
+ "implements",
25
+ "import",
26
+ "in",
27
+ "instanceof",
28
+ "interface",
29
+ "let",
30
+ "new",
31
+ "null",
32
+ "of",
33
+ "readonly",
34
+ "return",
35
+ "satisfies",
36
+ "switch",
37
+ "this",
38
+ "throw",
39
+ "true",
40
+ "try",
41
+ "type",
42
+ "typeof",
43
+ "undefined",
44
+ "var",
45
+ "void",
46
+ "while",
47
+ "yield",
48
+ ];
49
+
50
+ const PATTERNS: readonly { type: SnippetTokenType; source: string }[] = [
51
+ { type: "comment", source: "\\/\\/[^\\n]*|\\/\\*[\\s\\S]*?\\*\\/" },
52
+ { type: "string", source: "\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|`(?:[^`\\\\]|\\\\.)*`" },
53
+ { type: "tag", source: "<\\/?[A-Za-z][\\w.$]*" },
54
+ { type: "keyword", source: `\\b(?:${KEYWORDS.join("|")})\\b` },
55
+ { type: "number", source: "\\b\\d+(?:\\.\\d+)?\\b" },
56
+ { type: "attr", source: "\\b[A-Za-z_$][\\w$]*(?=\\s*[=:](?!=))" },
57
+ { type: "fn", source: "\\b[A-Za-z_$][\\w$]*(?=\\s*\\()" },
58
+ { type: "type", source: "\\b[A-Z][\\w$]*\\b" },
59
+ { type: "punct", source: "[{}()\\[\\]<>=;,.:!?|&+\\-*/]" },
60
+ ];
61
+
62
+ const TOKENIZER = new RegExp(PATTERNS.map((pattern) => `(${pattern.source})`).join("|"), "g");
63
+
64
+ export const snippetHighlight = (code: string): SnippetToken[] => {
65
+ const tokens: SnippetToken[] = [];
66
+ let cursor = 0;
67
+ let match: RegExpExecArray | null;
68
+
69
+ TOKENIZER.lastIndex = 0;
70
+
71
+ while ((match = TOKENIZER.exec(code)) !== null) {
72
+ if (match.index > cursor) tokens.push({ type: "plain", value: code.slice(cursor, match.index) });
73
+
74
+ const groupIndex = PATTERNS.findIndex((_, index) => match![index + 1] !== undefined);
75
+
76
+ tokens.push({ type: PATTERNS[groupIndex].type, value: match[0] });
77
+ cursor = match.index + match[0].length;
78
+ }
79
+
80
+ if (cursor < code.length) tokens.push({ type: "plain", value: code.slice(cursor) });
81
+
82
+ return tokens;
83
+ };
@@ -0,0 +1,63 @@
1
+ import { useState } from "react";
2
+
3
+ import { MdCheck, MdContentCopy } from "react-icons/md";
4
+
5
+ import { Guard, List, Swap, Tag } from "react-renderable";
6
+
7
+ import { cn } from "../../utils/cn/cn.js";
8
+ import { Button } from "../button/button.js";
9
+ import { snippetHighlight } from "./highlight.js";
10
+ import {
11
+ snippetBarClassName,
12
+ snippetBaseClassName,
13
+ snippetCodeClassName,
14
+ snippetCopyClassName,
15
+ snippetTitleClassName,
16
+ snippetTokenClassName,
17
+ } from "./style.js";
18
+
19
+ import type { ElementType } from "react";
20
+ import type { SnippetProps } from "./type.js";
21
+
22
+ export const Snippet = <T extends ElementType = "div">({ snippet, title, className, ...rest }: SnippetProps<T>) => {
23
+ const [isCopied, setIsCopied] = useState(false);
24
+ const source = snippet.trim();
25
+
26
+ const handleCopy = async () => {
27
+ await navigator.clipboard.writeText(source);
28
+ setIsCopied(true);
29
+ window.setTimeout(() => setIsCopied(false), 1500);
30
+ };
31
+
32
+ return (
33
+ <Tag {...Tag.forward<T>(rest)} className={cn(snippetBaseClassName, className)}>
34
+ <div className={snippetBarClassName}>
35
+ <Guard guardIf={!title} shouldHide>
36
+ <span className={snippetTitleClassName}>{title}</span>
37
+ </Guard>
38
+ <Button onClickBlur={handleCopy} aria-label="copy" aria-pressed={isCopied} className={snippetCopyClassName}>
39
+ <Button.Icon
40
+ icon={
41
+ <Swap.Boolean
42
+ swapOn={isCopied}
43
+ components={[<MdContentCopy className="text-sm" />, <MdCheck className="text-sm" />]}
44
+ />
45
+ }
46
+ />
47
+ </Button>
48
+ </div>
49
+ <pre className={snippetCodeClassName}>
50
+ <code>
51
+ <List
52
+ array={snippetHighlight(source)}
53
+ itemExtractor={({ row, index }) => (
54
+ <span key={index} className={snippetTokenClassName[row.type]}>
55
+ {row.value}
56
+ </span>
57
+ )}
58
+ />
59
+ </code>
60
+ </pre>
61
+ </Tag>
62
+ );
63
+ };
@@ -0,0 +1,25 @@
1
+ import type { SnippetTokenType } from "./type.js";
2
+
3
+ export const snippetBaseClassName = "overflow-hidden rounded-lg border-2 border-border bg-(--margo-code-surface)";
4
+
5
+ export const snippetBarClassName =
6
+ "flex items-center justify-between gap-4 border-b-2 border-border bg-(--margo-code-bar) px-3 py-2";
7
+
8
+ export const snippetTitleClassName = "text-mc uppercase tracking-widest text-medium";
9
+
10
+ export const snippetCopyClassName = "ml-auto bg-neutral/60";
11
+
12
+ export const snippetCodeClassName = "overflow-x-auto p-4 text-xs leading-relaxed";
13
+
14
+ export const snippetTokenClassName: Record<SnippetTokenType, string> = {
15
+ plain: "text-(--margo-code-plain)",
16
+ comment: "text-(--margo-code-comment) italic",
17
+ string: "text-(--margo-code-string)",
18
+ keyword: "text-(--margo-code-keyword)",
19
+ number: "text-(--margo-code-number)",
20
+ tag: "text-(--margo-code-tag)",
21
+ attr: "text-(--margo-code-attr)",
22
+ fn: "text-(--margo-code-fn)",
23
+ type: "text-(--margo-code-type)",
24
+ punct: "text-(--margo-code-punct)",
25
+ };
@@ -0,0 +1,26 @@
1
+ import type { TagProps } from "react-renderable";
2
+ import type { ElementType } from "react";
3
+
4
+ export type SnippetTokenType =
5
+ | "plain"
6
+ | "comment"
7
+ | "string"
8
+ | "keyword"
9
+ | "number"
10
+ | "tag"
11
+ | "attr"
12
+ | "fn"
13
+ | "type"
14
+ | "punct";
15
+
16
+ export type SnippetToken = {
17
+ type: SnippetTokenType;
18
+ value: string;
19
+ };
20
+
21
+ export type SnippetOwnProps = {
22
+ snippet: string;
23
+ title?: string;
24
+ };
25
+
26
+ export type SnippetProps<T extends ElementType = "div"> = TagProps<T, SnippetOwnProps>;
@@ -0,0 +1,13 @@
1
+ export const tableWrapperClassName = "w-full overflow-x-auto rounded-lg border-2 border-border";
2
+
3
+ export const tableBaseClassName = "w-full border-collapse text-xs text-on-main";
4
+
5
+ export const tableHeadClassName = "border-b-2 border-border bg-neutral/40 text-left";
6
+
7
+ export const tableBodyClassName = "align-top";
8
+
9
+ export const tableRowClassName = "border-b-2 border-border last:border-b-0";
10
+
11
+ export const tableHeadCellClassName = "px-3 py-2 font-medium whitespace-nowrap";
12
+
13
+ export const tableCellClassName = "px-3 py-2 align-top whitespace-nowrap";
@@ -0,0 +1,60 @@
1
+ import { Tag } from "react-renderable";
2
+
3
+ import { cn } from "../../utils/cn/cn.js";
4
+ import {
5
+ tableBaseClassName,
6
+ tableBodyClassName,
7
+ tableCellClassName,
8
+ tableHeadCellClassName,
9
+ tableHeadClassName,
10
+ tableRowClassName,
11
+ tableWrapperClassName,
12
+ } from "./style.js";
13
+
14
+ import type { ElementType } from "react";
15
+ import type {
16
+ TableBodyProps,
17
+ TableCellProps,
18
+ TableHeadCellProps,
19
+ TableHeadProps,
20
+ TableProps,
21
+ TableRowProps,
22
+ } from "./type.js";
23
+
24
+ export const Table = <T extends ElementType = "table">({ className, children, ...rest }: TableProps<T>) => (
25
+ <div className={tableWrapperClassName}>
26
+ <Tag {...Tag.forward<T>(rest, "table")} className={cn(tableBaseClassName, className)}>
27
+ {children}
28
+ </Tag>
29
+ </div>
30
+ );
31
+
32
+ Table.Head = <T extends ElementType = "thead">({ className, children, ...rest }: TableHeadProps<T>) => (
33
+ <Tag {...Tag.forward<T>(rest, "thead")} className={cn(tableHeadClassName, className)}>
34
+ {children}
35
+ </Tag>
36
+ );
37
+
38
+ Table.Body = <T extends ElementType = "tbody">({ className, children, ...rest }: TableBodyProps<T>) => (
39
+ <Tag {...Tag.forward<T>(rest, "tbody")} className={cn(tableBodyClassName, className)}>
40
+ {children}
41
+ </Tag>
42
+ );
43
+
44
+ Table.Row = <T extends ElementType = "tr">({ className, children, ...rest }: TableRowProps<T>) => (
45
+ <Tag {...Tag.forward<T>(rest, "tr")} className={cn(tableRowClassName, className)}>
46
+ {children}
47
+ </Tag>
48
+ );
49
+
50
+ Table.HeadCell = <T extends ElementType = "th">({ className, children, ...rest }: TableHeadCellProps<T>) => (
51
+ <Tag {...Tag.forward<T>(rest, "th")} className={cn(tableHeadCellClassName, className)}>
52
+ {children}
53
+ </Tag>
54
+ );
55
+
56
+ Table.Cell = <T extends ElementType = "td">({ className, children, ...rest }: TableCellProps<T>) => (
57
+ <Tag {...Tag.forward<T>(rest, "td")} className={cn(tableCellClassName, className)}>
58
+ {children}
59
+ </Tag>
60
+ );
@@ -0,0 +1,14 @@
1
+ import type { TagProps } from "react-renderable";
2
+ import type { ElementType } from "react";
3
+
4
+ export type TableProps<T extends ElementType = "table"> = TagProps<T>;
5
+
6
+ export type TableHeadProps<T extends ElementType = "thead"> = TagProps<T>;
7
+
8
+ export type TableBodyProps<T extends ElementType = "tbody"> = TagProps<T>;
9
+
10
+ export type TableRowProps<T extends ElementType = "tr"> = TagProps<T>;
11
+
12
+ export type TableHeadCellProps<T extends ElementType = "th"> = TagProps<T>;
13
+
14
+ export type TableCellProps<T extends ElementType = "td"> = TagProps<T>;
@@ -15,19 +15,19 @@ import type { ElementType, ReactNode } from "react";
15
15
  import type { TooltipProps } from "./type.js";
16
16
 
17
17
  export const Tooltip = <T extends ElementType = "div">({
18
- ariaLabel,
18
+ label,
19
19
  children,
20
20
  className,
21
21
  id,
22
- placeholder,
22
+ content,
23
23
  position = "down",
24
24
  ...rest
25
25
  }: TooltipProps<T>) => {
26
- const placeholderRef = useRef<ReactNode>(null);
26
+ const contentRef = useRef<ReactNode>(null);
27
27
 
28
- const isFilled = placeholder !== null && placeholder !== undefined;
28
+ const isFilled = content !== null && content !== undefined;
29
29
 
30
- if (isFilled) placeholderRef.current = placeholder;
30
+ if (isFilled) contentRef.current = content;
31
31
 
32
32
  return (
33
33
  <Tag {...Tag.forward<T>(rest)} className={cn(tooltipAnchorClassName, className)}>
@@ -35,7 +35,7 @@ export const Tooltip = <T extends ElementType = "div">({
35
35
  <span
36
36
  id={id}
37
37
  role="tooltip"
38
- aria-label={isFilled ? undefined : ariaLabel}
38
+ aria-label={isFilled ? undefined : label}
39
39
  className={cn(
40
40
  tooltipBubbleClassName,
41
41
  tooltipTransitionClassName,
@@ -43,7 +43,7 @@ export const Tooltip = <T extends ElementType = "div">({
43
43
  tooltipPositionClassName[position],
44
44
  )}
45
45
  >
46
- {placeholderRef.current}
46
+ {contentRef.current}
47
47
  </span>
48
48
  </Tag>
49
49
  );
@@ -4,9 +4,9 @@ import type { ElementType, ReactNode } from "react";
4
4
  export type TooltipPosition = "up" | "down" | "left" | "right";
5
5
 
6
6
  export type TooltipOwnProps = {
7
- ariaLabel?: string;
7
+ label?: string;
8
8
  id?: string;
9
- placeholder?: ReactNode;
9
+ content?: ReactNode;
10
10
  position?: TooltipPosition;
11
11
  children?: ReactNode;
12
12
  };
package/src/css/grid.css CHANGED
@@ -88,6 +88,26 @@
88
88
  margin-inline: calc(var(--margo-grid-bleed) * -1);
89
89
  }
90
90
 
91
+ /*
92
+ * Bleed padding: the exact counterpart of the bleed margins above. An element
93
+ * that bled off an edge gets its content back on the grid by padding it by the
94
+ * same distance, so the background reaches the viewport while the text stays
95
+ * aligned with the columns.
96
+ *
97
+ * Use on: a bled sidebar, band or bar whose children must keep the alignment.
98
+ */
99
+ @utility margo-pl-bleed {
100
+ padding-inline-start: var(--margo-grid-bleed);
101
+ }
102
+
103
+ @utility margo-pr-bleed {
104
+ padding-inline-end: var(--margo-grid-bleed);
105
+ }
106
+
107
+ @utility margo-px-bleed {
108
+ padding-inline: var(--margo-grid-bleed);
109
+ }
110
+
91
111
  /*
92
112
  * Back to the centered content area (all 12 columns), dropping any bleed.
93
113
  * Use to reset an element that a variant put on `full` at another breakpoint.
package/src/css/theme.css CHANGED
@@ -26,8 +26,16 @@
26
26
  /* Shadows */
27
27
  --shadow-card: var(--margo-shadow-card);
28
28
  --shadow-button: var(--margo-shadow-button);
29
+ --shadow-item: var(--margo-shadow-item);
29
30
  --shadow-chip: var(--margo-shadow-chip);
30
31
 
32
+ /* Durations */
33
+ --duration-layer: var(--margo-layer-duration);
34
+ --ease-layer: var(--margo-layer-easing);
35
+
36
+ /* Layers */
37
+ --z-index-layer: var(--margo-layer-z-index);
38
+
31
39
  /* Border widths */
32
40
  --border-width-2: var(--margo-border-width-2);
33
41
 
@@ -31,6 +31,10 @@
31
31
 
32
32
  --margo-border-width-2: 1.5px;
33
33
 
34
+ --margo-layer-duration: 750ms;
35
+ --margo-layer-easing: cubic-bezier(0.32, 0.72, 0, 1);
36
+ --margo-layer-z-index: 100;
37
+
34
38
  --margo-grid-max-width: 80rem;
35
39
  --margo-grid-padding: 1rem;
36
40
  --margo-grid-gutter-x: 2rem;
@@ -43,17 +47,31 @@
43
47
 
44
48
  --margo-color-neutral: #ffffff;
45
49
  --margo-color-on-neutral: #000000;
46
- --margo-color-main: #f6f6f6;
50
+ --margo-color-main: #e7e7e7;
47
51
  --margo-color-on-main: #151515;
48
52
  --margo-color-primary: #57e550;
49
53
  --margo-color-primary-darken: #45b93f;
50
54
  --margo-color-secondary: #d3d3d3;
51
- --margo-color-medium: #7e7e7e;
52
- --margo-color-border: #cfcfcf;
55
+ --margo-color-medium: #858585;
56
+ --margo-color-border: #cecece;
53
57
 
54
58
  --margo-shadow-card: 0 8px 6px -4px rgb(220, 220, 220, 0.5);
55
59
  --margo-shadow-button: 0px 2px 3px -1px rgb(220, 220, 220, 0.6);
60
+ --margo-shadow-item: 0px 2px 3px -1px rgb(220, 220, 220, 0.6);
56
61
  --margo-shadow-chip: 0 1px 3px -1px rgb(0, 0, 0, 0.6);
62
+
63
+ --margo-code-surface: #fbfbfb;
64
+ --margo-code-bar: #f1f1f1;
65
+ --margo-code-plain: #24292f;
66
+ --margo-code-comment: #8b949e;
67
+ --margo-code-string: #0a7d3f;
68
+ --margo-code-keyword: #a5309a;
69
+ --margo-code-number: #b3510f;
70
+ --margo-code-tag: #1f6fd6;
71
+ --margo-code-attr: #7a5cd6;
72
+ --margo-code-fn: #0f7c93;
73
+ --margo-code-type: #1f6fd6;
74
+ --margo-code-punct: #6e7781;
57
75
  }
58
76
 
59
77
  .dark {
@@ -71,5 +89,25 @@
71
89
 
72
90
  --margo-shadow-card: 0 4px 12px -4px rgb(0, 0, 0, 0.5);
73
91
  --margo-shadow-button: 0 2px 6px -2px rgb(0, 0, 0, 0.5);
92
+ --margo-shadow-item: 0 2px 6px -2px rgb(0, 0, 0, 0.5);
74
93
  --margo-shadow-chip: 0 1px 3px -1px rgb(0, 0, 0, 0.5);
94
+
95
+ --margo-code-surface: #0d0d0d;
96
+ --margo-code-bar: #161616;
97
+ --margo-code-plain: #e6e6e6;
98
+ --margo-code-comment: #6b6b6b;
99
+ --margo-code-string: #7ee787;
100
+ --margo-code-keyword: #ff7bd5;
101
+ --margo-code-number: #ffab70;
102
+ --margo-code-tag: #79c0ff;
103
+ --margo-code-attr: #c3a6ff;
104
+ --margo-code-fn: #56d4dd;
105
+ --margo-code-type: #79c0ff;
106
+ --margo-code-punct: #8b949e;
107
+ }
108
+
109
+ @media (prefers-reduced-motion: reduce) {
110
+ :root {
111
+ --margo-layer-duration: 1ms;
112
+ }
75
113
  }
@@ -7,26 +7,36 @@
7
7
  opacity: 0;
8
8
  border-radius: inherit;
9
9
  background: radial-gradient(
10
- var(--margo-background-glow-size) circle at var(--margo-background-glow-x, 50%) var(--margo-background-glow-y, 50%),
10
+ var(--margo-background-glow-size, 480px) circle at var(--margo-background-glow-x, 50%) var(--margo-background-glow-y, 50%),
11
11
  var(--color-primary),
12
12
  transparent 70%
13
13
  );
14
14
  transition: opacity 300ms ease-out;
15
15
  }
16
16
 
17
+ .margo-background-glow::after {
18
+ content: "";
19
+ position: absolute;
20
+ inset: 0;
21
+ z-index: -1;
22
+ pointer-events: none;
23
+ opacity: 0;
24
+ border-radius: inherit;
25
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
26
+ background-size: var(--margo-background-glow-noise-tile, 120px);
27
+ mix-blend-mode: overlay;
28
+ transition: opacity 300ms ease-out;
29
+ }
30
+
17
31
  .margo-background-glow:hover::before,
18
32
  .margo-background-glow:focus-within::before {
19
33
  opacity: var(--margo-background-glow-opacity, 0.1);
20
34
  }
21
35
 
22
- .margo-background-glow--size-sm {
23
- --margo-background-glow-size: 200px;
36
+ .margo-background-glow:hover::after,
37
+ .margo-background-glow:focus-within::after {
38
+ opacity: var(--margo-background-glow-noise-opacity, 0.04);
24
39
  }
25
40
 
26
- .margo-background-glow--size-md {
27
- --margo-background-glow-size: 320px;
28
- }
29
41
 
30
- .margo-background-glow--size-lg {
31
- --margo-background-glow-size: 480px;
32
- }
42
+