diff --git a/docs/learn/module-11-conceptual-specifications/lesson-04-spacing-objects.md b/docs/learn/module-11-conceptual-specifications/lesson-04-spacing-objects.md new file mode 100644 index 000000000..929700271 --- /dev/null +++ b/docs/learn/module-11-conceptual-specifications/lesson-04-spacing-objects.md @@ -0,0 +1,192 @@ +# Module 11: Conceptual Specifications + +## Lesson 4: Spacing as First-Class Objects + +**The invisible layer that holds everything together** + +--- + +## The Gap Is Not Empty + +Look at a well-designed page. Between the header and the hero. Between the cards in a grid. Between a heading and the paragraph below it. + +That space is not "nothing." It's a design decision. + +In WDS, **spacing is a first-class object** — it has an ID, a type, and a value, just like a button or a card. + +--- + +## Why Spacing Gets an ID + +Without IDs, spacing conversations sound like this: + +> "Add more space between the trust section and the seasons section" + +With IDs, they sound like this: + +> "Change `hem-v-space-3xl` to `space-4xl`" + +The second version is precise, traceable, and can be found in the design system. The first version requires the developer to figure out which space you mean. + +--- + +## The Naming Convention + +``` +{page}-{v|h}-{type}-{size} +``` + +| Part | Meaning | Examples | +|------|---------|---------| +| `{page}` | Which page | `hem`, `nyheter`, `om-oss` | +| `{v\|h}` | Direction | `v` = vertical, `h` = horizontal | +| `{type}` | What kind | `space`, `separator`, `line` | +| `{size}` | Token value | `zero`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `flex` | + +**The ID describes WHAT the spacing IS, not what it sits between.** + +### Examples + +```markdown +#### ↕ `hem-v-space-zero` — header and service menu form one continuous nav unit +#### ↕ `hem-v-separator-2xl` — gray line, space-2xl above and below +#### ↕ `hem-v-space-3xl` — major section boundary between seasons and footer +``` + +--- + +## Zero Spacing Is a Decision + +When two objects touch with no gap, that's a deliberate design choice: + +```markdown +#### ↕ `hem-v-space-zero` — hero sits flush below navigation, background color shift provides visual separation +``` + +If you don't document this, a future developer might "fix" it by adding spacing. Zero spacing says: "This is intentional. Don't add a gap." + +--- + +## How Spacing Appears in Page Specs + +Between each section, an explicit spacing object: + +``` +┌──────────────────────────┐ +│ Site Header │ +├──────────────────────────┤ +│ ↕ hem-v-space-zero │ ← spacing object +├──────────────────────────┤ +│ Service Menu │ +├──────────────────────────┤ +│ ↕ hem-v-space-zero │ ← spacing object +├──────────────────────────┤ +│ Hero Section │ +├──────────────────────────┤ +│ ↕ hem-v-space-zero │ ← spacing object (bg color shift) +├──────────────────────────┤ +│ About Section │ +├──────────────────────────┤ +│ ↕ hem-v-separator-2xl │ ← gray line with equal spacing +├──────────────────────────┤ +│ Trust Cards │ +├──────────────────────────┤ +│ ↕ hem-v-space-3xl │ ← major boundary +├──────────────────────────┤ +│ Season Cards │ +└──────────────────────────┘ +``` + +--- + +## Group-Level vs. Individual Spacing + +When all items in a grid share the same spacing, define it **on the container**: + +```markdown +| Grid gap | h-space-lg / v-space-lg (24px) | +``` + +Don't create separate spacing objects between card 1 and card 2, card 2 and card 3. The grid gap handles it. + +Individual spacing objects are for **between sections** and **non-uniform gaps**. + +--- + +## Internal Spacing + +Spacing inside a component (image-to-heading, heading-to-teaser inside a card) is NOT specified upfront. It's added only when the designer explicitly requests it during visual review. + +```markdown + +``` + +This follows the emergent principle: don't design what hasn't been needed yet. + +--- + +## Spacing in the Design System + +Spacing objects go to the design system **immediately on first use** — unlike regular objects which extract on second use. + +Why? Because spacing is relational. When you decide that a heading needs `space-xl` above a card grid, that's a universal design principle, not a page-specific detail. + +The design system organizes patterns by spacing value: + +```markdown +### v-space-3xl +| Above | Below | Why | +|-------|-------|-----| +| `trust-section` | `seasons-section` | Major section boundary | +| `seasons-section` | `site-footer` | Major section boundary | + +### v-space-zero +| Above | Below | Why | +|-------|-------|-----| +| `site-header` | `service-menu` | One continuous nav unit | +| `service-menu` | `hero` | Flush below navigation | +``` + +As more pages are designed, each spacing value accumulates more situations. The pattern table grows from real decisions. + +--- + +## How Many Spacing Objects Per Page? + +On a typical homepage with 8 sections: + +- **6 spacing objects** between sections +- **4 sections** with internal spacing properties (padding, grid gap) +- **10 total** spacing declarations + +That's lean. One or two per section boundary. Not dozens. + +--- + +## The Communication Pattern + +Always use token names when discussing spacing: + +``` +BAD: "Add 48 pixels above the footer" +GOOD: "Change hem-v-space-3xl to space-4xl above the footer" +``` + +This builds a shared vocabulary. Over time, the designer and developer both think in tokens. + +--- + +## What's Next + +In the next module, you'll learn how patterns emerge across pages and when to extract them into reusable components. + +--- + +**[Continue to Lesson 5: Typography Tokens →](lesson-05-typography-tokens.md)** + +--- + +[← Back to Lesson 3](lesson-03-element-state-specifications.md) | [Back to Module Overview](module-11-conceptual-specifications-overview.md) + +*Part of Module 11: Conceptual Specifications* diff --git a/docs/learn/module-11-conceptual-specifications/lesson-05-typography-tokens.md b/docs/learn/module-11-conceptual-specifications/lesson-05-typography-tokens.md new file mode 100644 index 000000000..32cc34c97 --- /dev/null +++ b/docs/learn/module-11-conceptual-specifications/lesson-05-typography-tokens.md @@ -0,0 +1,157 @@ +# Module 11: Conceptual Specifications + +## Lesson 5: Typography Tokens — Size Is Not Structure + +**Decoupling visual size from semantic meaning** + +--- + +## The Problem + +Most design systems conflate two things: + +- **Visual size** — how big text looks +- **Semantic level** — what the text means (H1, H2, H3, p) + +This creates rigid rules like "H1 is always 48px" or "H2 is always 32px." But reality doesn't work that way. + +A landing page H1 might be a serif display font at 56px italic. +An admin page H1 might be clean sans-serif at 20px medium. +A sidebar H2 might be 14px. + +The semantic level is for accessibility and SEO. The visual token is for hierarchy. + +--- + +## The WDS Approach + +Two independent systems: + +### Heading Scale (Visual Size) + +| Token | Size | Weight | Example Use | +|-------|------|--------|-------------| +| `heading-xxs` | 14px | 700 | Smallest sub-headers | +| `heading-xs` | 16px | 700 | Minor headings, labels | +| `heading-sm` | 18px | 700 | Card sub-headings | +| `heading-md` | 20px | 800 | Card headings | +| `heading-lg` | 24px | 800 | Section sub-headers | +| `heading-xl` | 30px | 900 | Section headers | +| `heading-2xl` | 36px | 900 | Major section headers | +| `heading-3xl` | 44px | 900 | Hero headings (tablet) | +| `heading-4xl` | 56px | 900 | Hero headings (desktop) | + +### Semantic Level (Document Structure) + +`

`, `

`, `

`, `

` — these define the document outline for accessibility and SEO. + +### How They Combine + +```html +

+ Our Services +

+``` + +This `

` is `heading-lg` on mobile, `heading-xl` on tablet, `heading-2xl` on desktop. The semantic level stays H2 on all devices. The visual size adapts. + +--- + +## The Responsive Scaling Rule + +Step up one token size per breakpoint: + +``` +Mobile: heading-lg (24px) +Tablet: heading-xl (30px) +Desktop: heading-2xl (36px) +``` + +In code: +```html +

+``` + +In specifications: +```markdown +| Visual size | heading-lg / heading-xl / heading-2xl | +``` + +Always use token names — never arbitrary pixel values per breakpoint. + +--- + +## Body Type Scale + +The same principle applies to body text: + +| Token | Size | Weight | Usage | +|-------|------|--------|-------| +| `text-body` | 16px | 400 | Body text | +| `text-body-small` | 14px | 400 | Captions, metadata | +| `text-body-large` | 18px | 400 | Lead paragraphs | +| `text-label` | 14px | 600 | Labels, badges | +| `text-phone` | 24px | 700 | Phone number CTA | + +--- + +## Why Tokens Beat Pixel Values + +### 1. Single Point of Change + +Bump `heading-xl` from 30px to 32px and every section header on the site adjusts. No hunting through files. + +### 2. Shared Vocabulary + +"Change the heading from `heading-lg` to `heading-xl`" is precise. "Make it bigger" is not. + +### 3. Consistent Hierarchy + +Tokens enforce a scale. You can't accidentally use 31px when the scale goes 30, 36, 44. + +### 4. Responsive by Default + +Each token has responsive variants built in. No reinventing breakpoint behavior per element. + +--- + +## When Tokens Emerge + +Don't create the full type scale before building any pages. + +Build pages first. Notice that you keep using the same sizes. Extract the scale from real usage. + +On the Kalla project, the heading scale emerged after the homepage was built and refined through browser review. The same heading sizes appeared 3+ times in different sections — that's when they became tokens. + +--- + +## Specifying Typography in Page Specs + +```markdown +### Section Heading + +**OBJECT ID:** `hem-trust-heading` +**DS TYPE:** `section-heading` + +| Property | Value | +|----------|-------| +| Tag | h2 | +| Visual size | heading-xl / heading-xl / heading-2xl | +| Font family | font-headline (Inter) | +| Font weight | 900 | +| Color | text-primary (#141414) | +``` + +Notice: the semantic tag (`h2`) and the visual size (`heading-xl`) are independent. The same component template can be used for an H2 on one page and an H3 on another. + +--- + +## What's Next + +You now understand the three invisible specification layers: spacing objects (Lesson 4), typography tokens (this lesson), and the dual-ID system that connects them to the design system (Module 12). + +--- + +[← Back to Lesson 4](lesson-04-spacing-objects.md) | [Back to Module Overview](module-11-conceptual-specifications-overview.md) + +*Part of Module 11: Conceptual Specifications* diff --git a/docs/learn/module-11-conceptual-specifications/module-11-conceptual-specifications-overview.md b/docs/learn/module-11-conceptual-specifications/module-11-conceptual-specifications-overview.md index 119b3d100..6cbe30b66 100644 --- a/docs/learn/module-11-conceptual-specifications/module-11-conceptual-specifications-overview.md +++ b/docs/learn/module-11-conceptual-specifications/module-11-conceptual-specifications-overview.md @@ -99,16 +99,40 @@ Specifications use consistent terminology: ## IDs Are the Key -Every object gets a unique ID: +Every object has two IDs: + +1. **Instance ID** — unique on the page: `hem-trust-cards:pos-1` +2. **DS Type** — defined in the design system: `article-card` + +The Instance ID tells you WHERE this specific object is. The DS Type tells you WHAT kind of object it is. + +```markdown +### Trust Card 1 + +**OBJECT ID:** `hem-trust-cards:pos-1` +**DS TYPE:** `article-card` +``` + +### Positional IDs for Lists + +When a page has multiple instances of the same component, use positional identifiers: ``` -Page: P01-signup-page -Section: P01-S01-hero-section -Widget: P01-S02-W01-signup-form -Card: P01-S03-C01-feature-card -Element: P01-S02-W01-E01-email-field +hem-trust-cards:pos-1 +hem-trust-cards:pos-2 +hem-trust-cards:pos-3 ``` +Child elements use colon-separated hierarchy: + +``` +hem-trust-cards:pos-1:image +hem-trust-cards:pos-1:heading +hem-trust-cards:pos-1:teaser +``` + +Use positional IDs (`pos-1`, `pos-2`) instead of semantic names when content order can change dynamically. + **Why IDs matter:** 1. **Traceability** — From spec → code → test @@ -117,6 +141,7 @@ Element: P01-S02-W01-E01-email-field 4. **Accessibility** — Reference specific elements for ARIA 5. **Analytics** — Track interactions precisely 6. **Testing** — Target elements for automation +7. **Design System** — Link page instances to reusable types **Without IDs, specifications are just documentation. With IDs, they're implementation maps.** @@ -410,6 +435,12 @@ Deep dive on specifying sections (placement, responsive behavior) and widgets (r **Lesson 3: Element & State Specifications** Complete element specifications with all states, exact content, ARIA attributes, edge cases, and translations +**Lesson 4: Spacing as First-Class Objects** +Every gap between sections gets an ID, a type, and a value — the invisible layer that holds everything together + +**Lesson 5: Typography Tokens — Size Is Not Structure** +Decouple visual size from semantic meaning. An H2 can be `heading-xl` on the homepage and `heading-sm` in a sidebar. + **Tutorial: Specify Your Pages** Hands-on practice with Freya creating complete specifications @@ -440,6 +471,12 @@ Deep dive on Layers 2 & 3 of the hierarchy ### [Lesson 3: Element & State Specifications](lesson-03-element-state-specifications.md) Deep dive on Layers 4 & 5 — Complete implementation details +### [Lesson 4: Spacing as First-Class Objects](lesson-04-spacing-objects.md) +The invisible layer — every gap gets an ID, a type, and a value + +### [Lesson 5: Typography Tokens — Size Is Not Structure](lesson-05-typography-tokens.md) +Decouple visual size from semantic meaning + --- ## Tutorial diff --git a/docs/learn/module-11-conceptual-specifications/tutorial-11.md b/docs/learn/module-11-conceptual-specifications/tutorial-11.md index b1c7b5a8a..ac4987d39 100644 --- a/docs/learn/module-11-conceptual-specifications/tutorial-11.md +++ b/docs/learn/module-11-conceptual-specifications/tutorial-11.md @@ -344,7 +344,44 @@ Summary: --- -## Step 8: Review Complete Specification (5 min) +## Step 8: Add Spacing Objects (5 min) + +### Freya guides the invisible layer: + +> "Now let's specify the spacing between sections. Every gap needs an ID." + +**You work through the page sections:** + +```markdown +## Spacing Objects + +#### ↕ `signup-v-space-zero` — header sits flush against form section +#### ↕ `signup-v-space-xl` — comfortable gap between form and trust section +#### ↕ `signup-v-space-lg` — standard gap between trust section and footer +``` + +**Freya reminds:** +> "Zero spacing is a design decision too — document it so nobody 'fixes' it later." + +### Typography tokens: + +> "Let's also specify the heading sizes using tokens, not pixels." + +```markdown +### Headline +| Property | Value | +|----------|-------| +| Tag | h1 | +| Visual size | heading-xl / heading-2xl / heading-3xl | +| Font weight | 900 | +``` + +**Freya explains:** +> "The semantic tag (h1) and the visual size (heading-xl) are independent. The h1 tells screen readers this is the page title. The token controls how big it looks." + +--- + +## Step 9: Review Complete Specification (5 min) ### Freya presents the full document: @@ -370,7 +407,7 @@ If yes, you're done. If not, identify what's missing. --- -## Step 9: Save and Organize (2 min) +## Step 10: Save and Organize (2 min) ### Save the specification: diff --git a/docs/learn/module-12-functional-components/lesson-01-patterns-emerge.md b/docs/learn/module-12-functional-components/lesson-01-patterns-emerge.md index 7b1212dde..4f8123989 100644 --- a/docs/learn/module-12-functional-components/lesson-01-patterns-emerge.md +++ b/docs/learn/module-12-functional-components/lesson-01-patterns-emerge.md @@ -48,11 +48,27 @@ Shared vocabulary with developers. ## When to Extract -Not everything should be a component. Look for: +Not everything should be a component. And **objects and spacing have different extraction timing:** + +### Objects: Extract on Second Use + +The first time a button or card appears, it's a one-off — it stays inline in the page spec. The second time the same pattern appears (same states, same behavior), it's a real pattern. Extract it to the design system. + +First use = one-off. Second use = pattern. Extract. + +### Spacing: Extract Immediately + +Spacing extracts on **first use** — no waiting for a second occurrence. + +Why? Because spacing is relational. When you decide that a heading needs `space-xl` above a card grid, that's a universal design principle — not a page-specific detail. It applies everywhere that pair of object types appears. + +### The Decision Checklist + +For objects, look for: **Appears more than once** -Once is an instance. Twice or more is a pattern worth considering. +Once is an instance. Twice or more is a pattern worth extracting. **Consistent behavior**