● Zion Boggan
repos/Docket/components/ui.tsx
zionboggan.com ↗
137 lines · tsx
History for this file →
1
import { clsx } from "@/lib/cx";
2
 
3
export function Card({
4
  as: Tag = "div",
5
  className,
6
  hover = false,
7
  children,
8
  ...rest
9
}: {
10
  as?: React.ElementType;
11
  className?: string;
12
  hover?: boolean;
13
  children: React.ReactNode;
14
  [key: string]: unknown;
15
}) {
16
  return (
17
    <Tag
18
      className={clsx(
19
        "rounded-[3px] border border-line bg-surface",
20
        hover && "transition-colors hover:bg-graphite",
21
        className
22
      )}
23
      {...rest}
24
    >
25
      {children}
26
    </Tag>
27
  );
28
}
29
 
30
export function SectionHeader({
31
  eyebrow,
32
  title,
33
  description,
34
  className,
35
}: {
36
  eyebrow?: string;
37
  title?: React.ReactNode;
38
  description?: React.ReactNode;
39
  className?: string;
40
}) {
41
  return (
42
    <div className={clsx("mb-6", className)}>
43
      {eyebrow ? <p className="label mb-2">{eyebrow}</p> : null}
44
      {title ? (
45
        <h2
46
          className="display text-paper"
47
          style={{ fontSize: "clamp(1.25rem, 4vw, 1.875rem)" }}
48
        >
49
          {title}
50
        </h2>
51
      ) : null}
52
      {description ? (
53
        <p className="prose-lead mt-3 max-w-2xl text-ash">{description}</p>
54
      ) : null}
55
    </div>
56
  );
57
}
58
 
59
export function PageHeader({
60
  eyebrow,
61
  title,
62
  lead,
63
}: {
64
  eyebrow: string;
65
  title: string;
66
  lead?: string;
67
}) {
68
  return (
69
    <header
70
      style={{
71
        borderBottom: "1px solid var(--dk-line)",
72
        paddingBottom: "clamp(28px, 5vw, 48px)",
73
        marginBottom: "clamp(28px, 5vw, 48px)",
74
      }}
75
    >
76
      {}
77
      <p
78
        className="label"
79
        style={{
80
          color: "var(--dk-signal)",
81
          marginBottom: "20px",
82
          display: "flex",
83
          alignItems: "center",
84
          gap: "8px",
85
          fontSize: "12px",
86
          letterSpacing: "0.14em",
87
        }}
88
      >
89
        <span
90
          aria-hidden="true"
91
          style={{
92
            width: "5px",
93
            height: "5px",
94
            borderRadius: "50%",
95
            background: "var(--dk-signal)",
96
            display: "inline-block",
97
            flexShrink: 0,
98
          }}
99
        />
100
        {eyebrow}
101
      </p>
102
      {}
103
      <h1
104
        className="font-display text-paper"
105
        style={{
106
          fontSize: "clamp(2rem, 7vw, 3.75rem)",
107
          fontWeight: 900,
108
          lineHeight: 1.0,
109
          letterSpacing: "-0.01em",
110
          wordSpacing: "0.06em",
111
          textTransform: "uppercase",
112
          maxWidth: "18ch",
113
          marginBottom: lead ? "24px" : 0,
114
          overflowWrap: "anywhere",
115
          hyphens: "auto",
116
        }}
117
      >
118
        {title}
119
      </h1>
120
      {}
121
      {lead ? (
122
        <p
123
          className="font-prose"
124
          style={{
125
            fontStyle: "italic",
126
            fontSize: "clamp(1rem, 1.8vw, 1.125rem)",
127
            lineHeight: 1.55,
128
            color: "var(--dk-ash)",
129
            maxWidth: "52ch",
130
          }}
131
        >
132
          {lead}
133
        </p>
134
      ) : null}
135
    </header>
136
  );
137
}