@codecavepro/brand 2.2.0 → 2.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 (24) hide show
  1. package/README.md +46 -34
  2. package/dist/src/{components/common → common}/ArticlePreview.vue +1 -1
  3. package/dist/src/{components/common → common}/Checkbox.vue +2 -2
  4. package/dist/src/common/HeaderBrows.vue +12 -0
  5. package/dist/src/{components/common → common}/InputText.vue +1 -1
  6. package/dist/src/{components/common → common}/Review.vue +2 -2
  7. package/dist/src/{components/common → common}/forms/ContactUsForm.vue +4 -4
  8. package/dist/src/{components/common → common}/forms/ResearchForm.vue +1 -1
  9. package/dist/src/{components/header → header}/mobile-menu.vue +2 -2
  10. package/dist/src/{components/homepage → homepage}/technologies.vue +2 -2
  11. package/dist/theme.css +1 -1
  12. package/dist/tokens.css +1 -1
  13. package/package.json +2 -2
  14. /package/dist/src/{components/common → common}/BrandNav.vue +0 -0
  15. /package/dist/src/{components/common → common}/Button.vue +0 -0
  16. /package/dist/src/{components/common → common}/GlowButton.vue +0 -0
  17. /package/dist/src/{components/common → common}/Radio.vue +0 -0
  18. /package/dist/src/{components/common → common}/TextField.vue +0 -0
  19. /package/dist/src/{components/common → common}/effects/TypingEffect.vue +0 -0
  20. /package/dist/src/{components/common → common}/images/LazyImage.vue +0 -0
  21. /package/dist/src/{components/footer → footer}/link-group.vue +0 -0
  22. /package/dist/src/{components/header → header}/services-list.vue +0 -0
  23. /package/dist/src/{components/homepage → homepage}/technology-card.vue +0 -0
  24. /package/dist/src/{components/project → project}/pain-points-item.vue +0 -0
package/README.md CHANGED
@@ -6,10 +6,10 @@ wrapper layer.
6
6
 
7
7
  Link one stylesheet and the whole system is live on `:root`.
8
8
 
9
- > **Status: stable.** The token *values* mirror what
10
- > [codecave.pro](https://codecave.pro) ships, and the package *layout* — export paths,
9
+ > **Status: stable.** The token _values_ mirror what
10
+ > [codecave.pro](https://codecave.pro) ships, and the package _layout_ — export paths,
11
11
  > module shape — is settled under semver: an export will not move or disappear outside a
12
- > major bump. Token *values* can change in a minor or patch release, because they track a
12
+ > major bump. Token _values_ can change in a minor or patch release, because they track a
13
13
  > living design system; pin an exact version if you need them frozen.
14
14
 
15
15
  ## Install
@@ -48,7 +48,7 @@ redesign turns into a find-and-replace across your codebase.
48
48
  `@codecavepro/brand/css` is the design system **whole**: the tokens, ten `@font-face`
49
49
  rules, base rules for `html`, `body`, `h1`–`h6` and `a`, two layout primitives and
50
50
  around sixty component classes. That is what you want for a page that should look like
51
- CODECAVE. It is *not* what you want in an app that already has a base layer — dropping
51
+ CODECAVE. It is _not_ what you want in an app that already has a base layer — dropping
52
52
  it in restyles every heading and link you have.
53
53
 
54
54
  For that case there is a second stylesheet holding the custom properties and nothing
@@ -60,7 +60,7 @@ else:
60
60
 
61
61
  Same 103 properties on `:root`, same values, zero rules. Nothing it declares can change
62
62
  how a single existing element renders — a `var()` only takes effect where you write
63
- one. Fonts come with it only as a *name*: `--font-sans` says Satoshi, and declaring the
63
+ one. Fonts come with it only as a _name_: `--font-sans` says Satoshi, and declaring the
64
64
  faces stays your call (see below).
65
65
 
66
66
  Use it to end a duplicated palette without signing up for a redesign in the same commit.
@@ -70,7 +70,7 @@ Use it to end a duplicated palette without signing up for a redesign in the same
70
70
  The same file is served, byte for byte, from the published design system:
71
71
 
72
72
  ```html
73
- <link rel="stylesheet" href="https://brand.codecave.pro/colors_and_type.css">
73
+ <link rel="stylesheet" href="https://brand.codecave.pro/colors_and_type.css" />
74
74
  ```
75
75
 
76
76
  The package build asserts that identity, so the file in your `node_modules` and the
@@ -81,17 +81,17 @@ file at that URL are provably the same bytes.
81
81
  `@codecavepro/brand/css` declares ten `@font-face` rules for **Satoshi**, but **no font
82
82
  binaries are included** — that is a licensing question, not an oversight. Until you
83
83
  supply the files, the faces 404 and the browser falls back down the stack
84
- (`-apple-system`, `Segoe UI`, Roboto, …). Tokens, colours and the type *scale* are all
84
+ (`-apple-system`, `Segoe UI`, Roboto, …). Tokens, colours and the type _scale_ are all
85
85
  correct regardless; only the typeface is missing.
86
86
 
87
87
  The two stylesheets expect the files in **different places**, because one is meant to be
88
88
  dropped into a project on its own:
89
89
 
90
- | Import | `@font-face` URLs | Put the `.woff2`/`.woff` files at |
91
- |---|---|---|
92
- | `@codecavepro/brand/css` | `./fonts/Satoshi-*.woff2` | a `fonts/` directory **beside** the stylesheet |
93
- | `@codecavepro/brand/fonts.css` | `./Satoshi-*.woff2` | **beside** the stylesheet itself |
94
- | `@codecavepro/brand/tokens.css` | *none — it declares no faces* | wherever your own `@font-face` rules point |
90
+ | Import | `@font-face` URLs | Put the `.woff2`/`.woff` files at |
91
+ | ------------------------------- | ----------------------------- | ---------------------------------------------- |
92
+ | `@codecavepro/brand/css` | `./fonts/Satoshi-*.woff2` | a `fonts/` directory **beside** the stylesheet |
93
+ | `@codecavepro/brand/fonts.css` | `./Satoshi-*.woff2` | **beside** the stylesheet itself |
94
+ | `@codecavepro/brand/tokens.css` | _none — it declares no faces_ | wherever your own `@font-face` rules point |
95
95
 
96
96
  Get the cuts from [Fontshare](https://www.fontshare.com/fonts/satoshi) — 300, 400, 500,
97
97
  700 and 900, each upright and italic, which is the ten faces these stylesheets declare.
@@ -100,7 +100,7 @@ synthesize; the design system documents why in
100
100
  [DESIGN.md §10.3](https://github.com/CodeCavePro/brand/blob/development/docs/DESIGN.md#103-synthesized-vs-real-font-weights).
101
101
 
102
102
  **Do not use the `stylesheet.css` that comes in the Fontshare download.** It declares
103
- Bold and Black *both* as `font-weight: bold`, and their italics likewise, so four cuts
103
+ Bold and Black _both_ as `font-weight: bold`, and their italics likewise, so four cuts
104
104
  collide into two slots and whichever is declared last silently wins — your `900` text
105
105
  renders Bold, or your `700` renders Black, with nothing to indicate which. Take the
106
106
  binaries from that download and the declarations from here.
@@ -111,13 +111,19 @@ For consumers that cannot read a stylesheet — design tooling, canvas/WebGL ren
111
111
  PDF and email builders, native apps:
112
112
 
113
113
  ```ts
114
- import { color, radius, fontSize, spacing, gradientBrand } from '@codecavepro/brand';
115
-
116
- color.action; // '#5F20FE'
114
+ import {
115
+ color,
116
+ radius,
117
+ fontSize,
118
+ spacing,
119
+ gradientBrand,
120
+ } from "@codecavepro/brand";
121
+
122
+ color.action; // '#5F20FE'
117
123
  color.surfaceSecondary; // '#0F0F15'
118
- radius.card; // '1.5rem'
119
- fontSize.headingLg; // { size: '3.5rem', lineHeight: '130%' }
120
- fontSize.body; // { size: '1rem', lineHeight: '1.5rem' }
124
+ radius.card; // '1.5rem'
125
+ fontSize.headingLg; // { size: '3.5rem', lineHeight: '130%' }
126
+ fontSize.body; // { size: '1rem', lineHeight: '1.5rem' }
121
127
  spacing.sectionPaddingTop; // '12.5rem'
122
128
  ```
123
129
 
@@ -131,14 +137,14 @@ Everything is `as const`, so the values are literal types, and the key unions ar
131
137
  exported for building your own maps:
132
138
 
133
139
  ```ts
134
- import type { SemanticColor, Radius, FontSizeStep } from '@codecavepro/brand';
140
+ import type { SemanticColor, Radius, FontSizeStep } from "@codecavepro/brand";
135
141
  ```
136
142
 
137
- | Module | Exports |
138
- |---|---|
139
- | colour | `brand`, `gray`, `accent`, `technologyGradient`, `error`, `color`, `gradientBrand` |
140
- | layout | `radius`, `gutter`, `spacing`, `shadow`, `maxWidthDesktop`, `breakpointSm` |
141
- | typography | `fontFamily`, `fontSize`, `fontWeight`, `eyebrow` |
143
+ | Module | Exports |
144
+ | ---------- | ---------------------------------------------------------------------------------- |
145
+ | colour | `brand`, `gray`, `accent`, `technologyGradient`, `error`, `color`, `gradientBrand` |
146
+ | layout | `radius`, `gutter`, `spacing`, `shadow`, `maxWidthDesktop`, `breakpointSm` |
147
+ | typography | `fontFamily`, `fontSize`, `fontWeight`, `eyebrow` |
142
148
 
143
149
  Two things to know about it:
144
150
 
@@ -149,7 +155,7 @@ Two things to know about it:
149
155
 
150
156
  ## The components
151
157
 
152
- 19 components and 13 icons — the buttons, the form controls and the forms
158
+ 20 components and 13 icons — the buttons, the form controls and the forms
153
159
  themselves, the nav bar, the footer link group, the article and technology
154
160
  cards, the review card and the typing effect codecave.pro renders — ship as
155
161
  **source**, byte-for-byte the files the site builds from. Not a reimplementation
@@ -168,8 +174,11 @@ the rest could follow.
168
174
 
169
175
  ```vue
170
176
  <BrandNav
171
- :left="[{ name: &apos;Workflow&apos;, href: &apos;/workflow&apos; }, { name: &apos;Services&apos;, slot: &apos;services&apos; }]"
172
- :right="[{ name: &apos;Insights&apos;, href: &apos;/insights&apos; }]"
177
+ :left="[
178
+ { name: 'Workflow', href: '/workflow' },
179
+ { name: 'Services', slot: 'services' },
180
+ ]"
181
+ :right="[{ name: 'Insights', href: '/insights' }]"
173
182
  :logo="wordmarkUrl"
174
183
  current="Workflow"
175
184
  >
@@ -184,9 +193,9 @@ resolve through your own asset pipeline.
184
193
 
185
194
  ```vue
186
195
  <script setup lang="ts">
187
- import Button from '@codecavepro/brand/components/common/Button.vue';
188
- import TextField from '@codecavepro/brand/components/common/TextField.vue';
189
- import CloudIcon from '@codecavepro/brand/assets/icons/cloud-icon.vue';
196
+ import Button from "@codecavepro/brand/components/common/Button.vue";
197
+ import TextField from "@codecavepro/brand/components/common/TextField.vue";
198
+ import CloudIcon from "@codecavepro/brand/assets/icons/cloud-icon.vue";
190
199
  </script>
191
200
 
192
201
  <template>
@@ -212,7 +221,7 @@ components; leave one out and only those are affected — `gsap` by `GlowButton.
212
221
  Every colour, radius and control height in these components is a token — but they reach
213
222
  most of them through **Tailwind utility classes** (`bg-surface-primary`,
214
223
  `text-heading-md`, `rounded-custom`), and a utility class exists only if Tailwind knows
215
- the name. `tokens.css` gives you the *values*; `theme.css` gives Tailwind the names, so
224
+ the name. `tokens.css` gives you the _values_; `theme.css` gives Tailwind the names, so
216
225
  you need both:
217
226
 
218
227
  ```css
@@ -271,7 +280,10 @@ three that show images take an optional resolver and default to leaving the URL
271
280
  <Review :item="testimonial" />
272
281
 
273
282
  <!-- URLs relative to your own media host -->
274
- <Review :item="testimonial" :resolve-image="(u) => `https://cdn.example.com/${u}`" />
283
+ <Review
284
+ :item="testimonial"
285
+ :resolve-image="(u) => `https://cdn.example.com/${u}`"
286
+ />
275
287
  ```
276
288
 
277
289
  Their props are declared as the fields each one reads — `item.photo.url`,
@@ -306,7 +318,7 @@ the rules, the reasoning, the anti-patterns — is documented separately:
306
318
  It authors nothing. Every byte is copied, extracted or compiled out of `docs/` in the
307
319
  repository above: `css` and `fonts.css` are copied verbatim, `tokens.css` is extracted
308
320
  from the same file `css` is copied from, `theme.css` is extracted from the capture of
309
- codecave.pro's `global.css`, and the typed module is compiled from `docs/tokens/*.ts`.
321
+ codecave.pro's `global.css`, and the typed module is compiled from `src/tokens/*.ts`.
310
322
  A name that `theme.css` and `tokens.css` both give a literal value must agree, and the
311
323
  build fails if it does not — otherwise one of the two would be dead and nobody would
312
324
  see it. `docs/` stays the single origin, and CI asserts on every push that
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { formattedDate } from "../../helpers/date-formatter.ts";
2
+ import { formattedDate } from "../helpers/date-formatter.ts";
3
3
 
4
4
  /* The fields this component actually reads, instead of the generated Strapi
5
5
  * `Article`. TypeScript is structural, so a real Article still satisfies this
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { computed } from "vue";
3
- import AsteriskIcon from "../../assets/icons/asterisk-icon.vue";
3
+ import AsteriskIcon from "../assets/icons/asterisk-icon.vue";
4
4
 
5
5
  const props = withDefaults(
6
6
  defineProps<{
@@ -101,7 +101,7 @@ input::before {
101
101
  content: '';
102
102
  transform: scale(0);
103
103
  transition: var(--duration-control) transform ease-in-out;
104
- background-image: url("../../assets/images/checked-icon.svg");
104
+ background-image: url("../assets/images/checked-icon.svg");
105
105
  background-repeat: no-repeat;
106
106
  background-position: center center;
107
107
  }
@@ -0,0 +1,12 @@
1
+ <template>
2
+ <div class="flex flex-col md:flex-row gap-4 md:gap-6 text-lg md:text-xl">
3
+ <div class="space-x-1">
4
+ <span class="font-bold text-body-primary">15+</span>
5
+ <span class="text-body-secondary">Years of experience</span>
6
+ </div>
7
+ <div class="space-x-1">
8
+ <span class="font-bold text-body-primary">4.7</span>
9
+ <span class="text-body-secondary">Average rating</span>
10
+ </div>
11
+ </div>
12
+ </template>
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import AsteriskIcon from "../../assets/icons/asterisk-icon.vue";
2
+ import AsteriskIcon from "../assets/icons/asterisk-icon.vue";
3
3
 
4
4
  defineProps<{
5
5
  id: string
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
- import LinkedinIcon from "../../assets/icons/linkedin-icon.vue";
3
- import VerifiedIcon from "../../assets/icons/verified-icon.vue";
2
+ import LinkedinIcon from "../assets/icons/linkedin-icon.vue";
3
+ import VerifiedIcon from "../assets/icons/verified-icon.vue";
4
4
  import LazyImage from "./images/LazyImage.vue"
5
5
 
6
6
  /* See ArticlePreview.vue: the fields read here, not the generated Strapi
@@ -5,16 +5,16 @@ import Checkbox from "../Checkbox.vue";
5
5
  import Radio from "../Radio.vue";
6
6
  import TextField from "../TextField.vue";
7
7
  import { computed, ref, watch } from "vue";
8
- import SuccessIcon from "../../../assets/icons/success-icon.vue";
9
- import CloseIcon from "../../../assets/icons/close-icon.vue";
8
+ import SuccessIcon from "../../assets/icons/success-icon.vue";
9
+ import CloseIcon from "../../assets/icons/close-icon.vue";
10
10
  import gsap from "gsap";
11
11
  import type {
12
12
  ContactFormDefinition,
13
13
  ContactFormValues,
14
14
  CrmSubmitResult,
15
15
  ICrmFormClient,
16
- } from "../../../lib/crm/types";
17
- import { isCorrectEmailFormat, isCorrectLinkedInFormat } from "../../../helpers/form-validator.ts";
16
+ } from "../../lib/crm/types";
17
+ import { isCorrectEmailFormat, isCorrectLinkedInFormat } from "../../helpers/form-validator.ts";
18
18
 
19
19
  /* This component knows nothing about HubSpot, or about any other CRM. It is
20
20
  * handed the labels to render and something that can accept a submission; who
@@ -2,7 +2,7 @@
2
2
  import { ref } from 'vue'
3
3
  import InputText from '../InputText.vue'
4
4
  import Button from '../Button.vue'
5
- import { isCorrectEmailFormat } from "../../../helpers/form-validator.ts";
5
+ import { isCorrectEmailFormat } from "../../helpers/form-validator.ts";
6
6
 
7
7
  const email = ref('')
8
8
 
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  import Button from "../common/Button.vue";
3
- import Shevron from "../../assets/icons/shevron.vue";
3
+ import Shevron from "../assets/icons/shevron.vue";
4
4
  import { computed, onUnmounted, ref, watch } from "vue";
5
- import BackIcon from "../../assets/icons/back-icon.vue";
5
+ import BackIcon from "../assets/icons/back-icon.vue";
6
6
  import ServicesList from "./services-list.vue";
7
7
 
8
8
  /* Everything this drawer used to read out of menu.ts, paths.ts and the site's
@@ -2,11 +2,11 @@
2
2
  import { computed, ref } from "vue";
3
3
  import { Carousel, type CarouselConfig, Slide } from "vue3-carousel";
4
4
  import "vue3-carousel/carousel.css";
5
- import { BREAKPOINTS } from "../../helpers/breakpoints.ts";
5
+ import { BREAKPOINTS } from "../helpers/breakpoints.ts";
6
6
  import GlowButton from "../common/GlowButton.vue";
7
7
  import TypingEffect from "../common/effects/TypingEffect.vue";
8
8
  import TechnologyCard from "./technology-card.vue";
9
- import { carouselGestureLocker } from "../../helpers/carousel-gesture-locker.ts";
9
+ import { carouselGestureLocker } from "../helpers/carousel-gesture-locker.ts";
10
10
 
11
11
  /* See ArticlePreview.vue: the fields read here, not the generated Strapi
12
12
  * `Technology`, which a caller may still pass unchanged. This component
package/dist/theme.css CHANGED
@@ -1,7 +1,7 @@
1
1
  /* ==========================================================================
2
2
  * CODECAVE Tailwind theme — @codecavepro/brand/theme.css
3
3
  * --------------------------------------------------------------------------
4
- * GENERATED from docs/theme.css — do not edit.
4
+ * GENERATED from src/styles/theme.css — do not edit.
5
5
  *
6
6
  * Declares the names Tailwind needs in order to emit CODECAVE utility
7
7
  * classes: bg-surface-primary, text-heading-lg, rounded-card and the rest.
package/dist/tokens.css CHANGED
@@ -1,7 +1,7 @@
1
1
  /* ==========================================================================
2
2
  * CODECAVE design tokens — @codecavepro/brand/tokens.css
3
3
  * --------------------------------------------------------------------------
4
- * GENERATED from docs/colors_and_type.css — do not edit.
4
+ * GENERATED from src/styles/colors_and_type.css — do not edit.
5
5
  *
6
6
  * The custom properties and nothing else: no @font-face, no rules for html,
7
7
  * body, headings or links, no layout primitives, no components. Import this
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codecavepro/brand",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "CODECAVE design system — colour, typography and layout tokens as CSS custom properties and as a typed module.",
5
5
  "license": "Unlicense",
6
6
  "type": "module",
@@ -28,7 +28,7 @@
28
28
  "./tokens.css": "./dist/tokens.css",
29
29
  "./theme.css": "./dist/theme.css",
30
30
  "./fonts.css": "./dist/fonts.css",
31
- "./components/*": "./dist/src/components/*",
31
+ "./components/*": "./dist/src/*",
32
32
  "./assets/*": "./dist/src/assets/*",
33
33
  "./helpers/*": "./dist/src/helpers/*",
34
34
  "./lib/*": "./dist/src/lib/*",