@tfrc/marketing 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # @tfrc/marketing
2
+
3
+ The marketing dialect of the company's visual language. Marketing pages,
4
+ case studies, careers. Persuades a stranger once; desktop-first; motion is
5
+ generous because motion sells here.
6
+
7
+ **This package is not the website.** It is one of two dialects — the other
8
+ is `@tfrc/product` — and thefullremotecompany.com is a separate repository
9
+ that *installs* this one (`decisions/0007.md`). Building that site? Read
10
+ `CONSUMING.md` at the repo root, not this file. Renamed from `@tfrc/web`
11
+ for exactly this reason; see `decisions/0008.md`.
12
+
13
+ ~14 components. None of them have a product equivalent — a hero, a CTA
14
+ band, and a stat strip mean nothing inside a finance app, which is exactly
15
+ why they live here and not in `@tfrc/foundation`.
16
+
17
+ Never imports from `@tfrc/product`. If you need something from there, it
18
+ belongs in `@tfrc/foundation` instead — see `decisions/0001.md`.
19
+
20
+ ## Files
21
+
22
+ - `src/tokens.css` — the semantic layer. Same token names as `@tfrc/product`,
23
+ different values (`CONTRACT.md` in the foundation package documents which
24
+ names are required).
25
+ - `src/components.css` — button, card, stats, CTA band.
26
+ - `src/index.css` — entry point; import order is foundation → tokens →
27
+ components.
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@tfrc/marketing",
3
+ "version": "1.0.0",
4
+ "license": "MIT",
5
+ "description": "The marketing dialect of the visual language — corporate site, campaigns, careers. Expressive, desktop-first, ~14 components. Never imports from @tfrc/product.",
6
+ "keywords": ["design-system", "design-tokens", "css", "tailwind", "marketing"],
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/the-full-remote-company/design-system.git",
10
+ "directory": "packages/marketing"
11
+ },
12
+ "homepage": "https://github.com/the-full-remote-company/design-system/tree/main/packages/marketing#readme",
13
+ "bugs": "https://github.com/the-full-remote-company/design-system/issues",
14
+ "main": "src/index.css",
15
+ "exports": {
16
+ ".": "./src/index.css"
17
+ },
18
+ "files": ["src", "README.md"],
19
+ "dependencies": {
20
+ "@tfrc/foundation": "1.0.0"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public",
24
+ "registry": "https://registry.npmjs.org"
25
+ }
26
+ }
@@ -0,0 +1,101 @@
1
+ /* ==========================================================================
2
+ @tfrc/marketing — components
3
+ Reference only tokens defined in tokens.css. Zero raw color literals.
4
+ See AGENTS.md rule 2.
5
+ ========================================================================== */
6
+
7
+ h1, h2, h3 {
8
+ font-family: var(--font-display);
9
+ font-weight: 800;
10
+ margin: 0;
11
+ letter-spacing: -0.032em;
12
+ line-height: 1.02;
13
+ }
14
+
15
+ .wrap {
16
+ max-width: 1240px;
17
+ margin: 0 auto;
18
+ padding: 0 var(--gutter);
19
+ }
20
+
21
+ /* ---- Button — same API/class names as @tfrc/product, different values ---- */
22
+ .btn {
23
+ display: inline-flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ gap: 0.5rem;
27
+ height: var(--control-h);
28
+ padding: 0 1.5rem;
29
+ border: 1px solid transparent;
30
+ border-radius: var(--radius-sm);
31
+ font-family: inherit;
32
+ font-size: 0.9375rem;
33
+ font-weight: 600;
34
+ cursor: pointer;
35
+ text-decoration: none;
36
+ transition: background var(--duration-fast) var(--ease-quint),
37
+ color var(--duration-fast) var(--ease-quint),
38
+ border-color var(--duration-fast) var(--ease-quint),
39
+ transform var(--duration-fast) var(--ease-quint);
40
+ }
41
+ .btn:hover { transform: translateY(-1px); }
42
+ .btn--primary { background: var(--color-accent); color: var(--color-accent-fg); }
43
+ .btn--primary:hover { background: var(--color-accent-hover); }
44
+ .btn--secondary {
45
+ background: var(--color-surface-raised);
46
+ border-color: var(--color-border-strong);
47
+ color: var(--color-text-primary);
48
+ }
49
+ .btn--secondary:hover { background: var(--color-surface-sunken); }
50
+ .btn--onDark {
51
+ background: transparent;
52
+ border-color: var(--ramp-neutral-700);
53
+ color: var(--color-text-inverse);
54
+ }
55
+ .btn--onDark:hover { border-color: var(--gold); color: var(--gold); }
56
+
57
+ /* ---- Card — web only, no app equivalent ---- */
58
+ .card {
59
+ background: var(--color-surface-raised);
60
+ border: 1px solid var(--color-border-subtle);
61
+ border-radius: var(--radius-lg);
62
+ padding: 1.75rem;
63
+ transition: transform var(--duration-base) var(--ease-quint),
64
+ box-shadow var(--duration-base) var(--ease-quint),
65
+ border-color var(--duration-base) var(--ease-quint);
66
+ }
67
+ .card--interactive:hover {
68
+ transform: translateY(-4px);
69
+ box-shadow: var(--shadow-lg);
70
+ border-color: var(--color-border-strong);
71
+ }
72
+
73
+ /* ---- Stat strip — layout primitive, no app equivalent ---- */
74
+ .stats {
75
+ display: grid;
76
+ gap: 1px;
77
+ background: var(--color-border-subtle);
78
+ border-top: 1px solid var(--color-border-subtle);
79
+ border-bottom: 1px solid var(--color-border-subtle);
80
+ grid-template-columns: repeat(2, 1fr);
81
+ }
82
+ @media (min-width: 760px) { .stats { grid-template-columns: repeat(4, 1fr); } }
83
+ .stat { background: var(--color-surface); padding: 2rem var(--gutter); }
84
+ .stat__n {
85
+ font-family: var(--font-display);
86
+ font-size: 2.5rem;
87
+ font-weight: 800;
88
+ letter-spacing: -0.035em;
89
+ line-height: 1;
90
+ }
91
+ .stat__l { font-size: 0.8125rem; color: var(--color-text-secondary); margin-top: 0.5rem; }
92
+
93
+ /* ---- CTA band — full-bleed accent, no app equivalent.
94
+ Inside a product this density of persuasion would be an interruption;
95
+ on a marketing page it is the entire point. ---- */
96
+ .cta {
97
+ background: var(--color-accent);
98
+ color: #fff;
99
+ border-radius: var(--radius-xl);
100
+ padding: clamp(2.5rem, 6vw, 4.5rem);
101
+ }
package/src/index.css ADDED
@@ -0,0 +1,10 @@
1
+ /* ==========================================================================
2
+ @tfrc/marketing — entry point
3
+ Import order matters: foundation (ramps + reset) -> tokens (semantic
4
+ layer) -> components. Never import anything from @tfrc/product — see
5
+ AGENTS.md rule 3 and scripts/lint-boundaries.js.
6
+ ========================================================================== */
7
+
8
+ @import "@tfrc/foundation";
9
+ @import "./tokens.css";
10
+ @import "./components.css";
package/src/tokens.css ADDED
@@ -0,0 +1,76 @@
1
+ /* ==========================================================================
2
+ @tfrc/marketing — semantic tokens
3
+ Same token NAMES as @tfrc/product (see CONTRACT.md). Values diverge on
4
+ purpose — this file is self-contained per decisions/0004.md and does
5
+ not import anything from @tfrc/product.
6
+ ========================================================================== */
7
+
8
+ :root {
9
+ --color-surface: oklch(0.988 0.003 270);
10
+ --color-surface-raised: oklch(1 0 0);
11
+ --color-surface-sunken: oklch(0.962 0.006 270);
12
+ --color-surface-inverse: var(--ramp-neutral-950);
13
+
14
+ --color-border-subtle: oklch(0.912 0.010 270);
15
+ --color-border-strong: oklch(0.808 0.016 270);
16
+
17
+ --color-text-primary: var(--ramp-neutral-900);
18
+ --color-text-secondary: var(--ramp-neutral-600);
19
+ --color-text-muted: var(--ramp-neutral-400);
20
+ --color-text-inverse: oklch(0.980 0.004 270);
21
+
22
+ --color-accent: var(--ramp-brand-600);
23
+ --color-accent-hover: var(--ramp-brand-700);
24
+ --color-accent-fg: #fff;
25
+ --color-accent-bg: var(--ramp-brand-100);
26
+ --color-accent-bg-fg: var(--ramp-brand-800);
27
+
28
+ --color-focus: oklch(0.560 0.150 235);
29
+
30
+ --color-info-bg: oklch(0.940 0.032 235);
31
+ --color-info-fg: oklch(0.360 0.070 237);
32
+ --color-info-line: oklch(0.560 0.150 235);
33
+
34
+ --color-danger-solid: oklch(0.615 0.205 25);
35
+ --color-danger-bg: oklch(0.940 0.035 25);
36
+ --color-danger-fg: oklch(0.475 0.170 25);
37
+ --color-danger-line: oklch(0.615 0.205 25);
38
+
39
+ --color-success-bg: oklch(0.940 0.040 150);
40
+ --color-success-fg: oklch(0.455 0.090 150);
41
+ --color-success-line: oklch(0.590 0.110 150);
42
+
43
+ /* NOTE: --color-gain / --color-loss are intentionally NOT defined here.
44
+ @tfrc/marketing must never reference them. See decisions/0002.md and
45
+ scripts/lint-boundaries.js, which checks this mechanically. */
46
+
47
+ --gold: var(--ramp-support-500);
48
+
49
+ /* ---- corporate-only scale: this is most of the divergence ---- */
50
+ --font-display: "Bricolage Grotesque", "Segoe UI", system-ui, sans-serif;
51
+ --font-sans: "Instrument Sans", system-ui, sans-serif;
52
+ --font-mono: "JetBrains Mono", ui-monospace, monospace;
53
+
54
+ --step-hero: clamp(2.75rem, 7.5vw, 6rem); /* app tops out at 1.75rem */
55
+ --step-xl: clamp(2rem, 4vw, 3.25rem);
56
+ --step-lg: 1.5rem;
57
+ --step-body: 1.0625rem; /* app body is 0.9375rem */
58
+ --step-sm: 0.875rem;
59
+ --step-xs: 0.6875rem;
60
+
61
+ --radius-sm: 0.375rem;
62
+ --radius-md: 0.625rem;
63
+ --radius-lg: 1rem;
64
+ --radius-xl: 1.5rem; /* app caps at 0.75rem */
65
+
66
+ --control-h: 3rem;
67
+ --gutter: clamp(1.25rem, 5vw, 4rem);
68
+ --section-y: clamp(4rem, 10vw, 8rem);
69
+
70
+ --duration-fast: 160ms;
71
+ --duration-base: 320ms;
72
+ --duration-slow: 640ms; /* app never exceeds 200ms */
73
+
74
+ --shadow-sm: 0 1px 3px oklch(0 0 0 / 0.07);
75
+ --shadow-lg: 0 24px 60px oklch(0 0 0 / 0.13), 0 4px 12px oklch(0 0 0 / 0.06);
76
+ }