# Design System Tutorial

## Overview

This tutorial walks you through a 5-layer design system architecture. Each layer has a clear, single responsibility — and together they form a scalable, maintainable component library that can evolve over time.

The stack uses **MUI** as the base component library with **Emotion** as the styling engine (via MUI), and **CVA** (Class Variance Authority) for managing variant classes.

Here's the big picture before we dive in:

```plaintext
Layer 1: Primitives       → Unbranded MUI re-exports
Layer 2: DS Theme         → Tokens, fonts, and the styling engine
Layer 3: DS Components    → Branded, variant-aware components
Layer 4: DS Labs          → Composed, nearly-mature components
Layer 5: Product Kit      → Product-specific one-offs
```

We'll use the **Button** component as the running example throughout.

* * *

## Layer 1 — Primitives

**What it does:** Re-exports MUI components as "primitives." This layer acts as a swap point — if you ever migrate from MUI to another library, you only need to change things here.

**Where it lives:** `src/primitives/`

### Step 1.1 — Re-export the MUI component

Create a file like `src/primitives/index.ts` and re-export the MUI Button under a `Primitive` suffix:

```plaintext
export {
  Button as ButtonPrimitive,
  buttonClasses as buttonClassesPrimitive,
} from '@mui/material'
```

> **Why the** `Primitive` suffix? It signals to consumers that this is a raw, unstyled base — not the finished design system component. It also avoids naming collisions further up the stack.

> **A note on "unstyled":** Ideally, primitives would be completely unstyled and expose individual parts as `data-slot` attributes. MUI's `@mui/base` package is heading in that direction, but MUI itself hasn't fully adopted it yet. For now, we re-export the styled MUI component and override its styles in Layer 3. When MUI adopts `base-ui`, update this layer to use those instead.

That's all Layer 1 needs to do. ✅ A layer of re-exports of MUI.

### **Bonus:**

**Note:** The two exported identities, Button and buttonClasses, the Button is supposed to be unstyled derivative of pure logical implementation, that encapsulated behaviour differences for example: A is rendered as submit button within form, that is default browser thingy. These encapsulations are to make sure we have slimmest possible implementation of button.

Also note the the buttonClasses is a slot identifier, a Button has per the most design systems has three slots, a left icon, a child or label, a right icon; these are just plain slots. If I had to make a rough skeleton then that would look like inside of MUI:

```typescript
// mui/src/material/button.tsx
<button data-slot="button-root" className={buttonClasses.root}> // not quite this is <ButtonBase>
  <span data-slot="left-icon" className={buttonClasses.leftIcon}>
  {props.leftIcon}
  </span>
  <span data-slot="text-label" className={buttonClasses.label}>
  {props.children}
  </span>
  <span data-slot="right-icon" className={buttonClasses.rightIcon}>
  {props.rightIcon}
  </span>
</button>
```

**Note:** There is a variant of Button called Split Button:

![](https://cdn.hashnode.com/uploads/covers/61fff2693a8a6e5fe1197aef/a4c497d4-dd01-4a30-b1a2-63cbba776e21.png align="left")

This cannot be achieved by the Button shown above, so mui has something called ButtonBase, which is just plain old button.

```javascript
const ButtonBase = (props) => <button {…props}>{props.children}</button>
```

What I want you to notice is how MUI is focusing on creating a component, starting from ButtonBase to Button, a layer building upon previous one, a layer by layer approach.

*   Each layer exposes a atomic value, and solves one thing
    
*   Each layers builds upon the previous and adds more functionality
    
*   This is what composition means.
    

**Important Conversations:**

* * *

## Layer 2 — DS Theme

**What it does:** Defines design tokens (colors, spacing, typography) and exposes the styling engine used across the system.

**Where it lives:** `src/themes/`

### Step 2.1 — Understand the token hierarchy

Tokens are split into two levels:

| Level | File | Contents |
| --- | --- | --- |
| `l0-tokens.css` | `__shared/light/` | Global primitives (raw values like `#1A73E8`) |
| `l1-tokens.css` | `<product>/light/` or `<product>/dark/` | Semantic aliases (e.g. `--color-surface-accent`) |

**Layer 0 Tokens:** This is layer of color pallet, a layer of spacing, a layer of all possible combination of colors that our org will ever support, a spacing token (padding, margin) that our org, and all of its different products will ever support.

**Layer 1 Tokens:** This is layer of that remains constant, and is referred directly inside the component. The button bg color is referring a surface color, that surface color definition lives inside of the layer 1 tokens.

![shapes at 26-06-28 17.53.30.png](https://cdn.hashnode.com/uploads/covers/61fff2693a8a6e5fe1197aef/f445f0b9-8ec2-429a-b549-e5405d59f1e8.png align="center")

**Important rule:** Figma designs must always reference `l1` tokens, never `l0` directly. `l0` is the raw palette; `l1` is what components consume.

### Step 2.2 — Set up a product theme

Each product (e.g. Google Photos, Google Calendar) gets its own theme folder:

```plaintext
src/themes/styled/
  __shared/
    light/
      l0-tokens.css        ← raw palette
      font.css             ← font palette (woff font files)

  google-photos/           ← product theme
    light/                 ← color-scheme
      l1-tokens.css        ← semantic tokens (light mode)
    dark/
      l1-tokens.css        ← semantic tokens (dark mode)
    font.css
    main.css               ← entry point

  google-calendar/
    light/
      l1-tokens.css
```

You should notice how the `__shared` dir is list of all shared value, these are L0 token space, the woff font files, and default fonting, etc.

Notice the `google-photos` dir it is called the product, per product of the organisation the tokens may vary so these files are required, they may ref to shared set of tokens or create their own token set.

Only thing that should remain constant is component token `--button-bg-color` to `--surface-0` mapping, the --surface-0 can maps itself to #FFC0CB or #0000FF. We don't care as long as button keep on mapping to a name called surface-0, out component will keep on working in any product and any color scheme.

```plaintext
google-photos: it is indicative of a product theme
google-photos/light: it is indicative of light color-scheme of theme of the google-photos product
```

The `main.css` entry point for a product simply imports everything it needs:

```plaintext
/* google-photos/main.css */
@import "../__shared/light/l0-tokens.css";
@import "./light/l1-tokens.css";
@import "./font.css";
```

Notice in our case we are re-exporting the l0, font and adding our tokens.

### Step 2.3 — Re-export the styling engine

Expose the styled utility from this layer so everything above it uses a consistent import:

```plaintext
// src/themes/index.ts
export { styled } from '@mui/system'

// BUT in our case it is
export { styledPrimitve as styled } from '../primitives'
```

> **Note on MUI theme conflicts:** You may find that MUI's built-in theme object conflicts with your custom tokens.
> 
> A pragmatic workaround is to attach your tokens to a `resolveTheme` property on the MUI theme object, leaving MUI's own theme untouched. It's not elegant, but it's safe until your design system matures.
> 
> And we have limited tokens, we currently have 14 font-size :sus: tokens so

* * *

## Layer 3 — Design system Components

**What it does:** This is where your actual branded components live. It binds tokens to components, manages variants, and exposes a strict public API.

**Where it lives:** `src/design-system/`

This layer has three parts, built in order:

1.  The styled internal component
    
2.  The public class map and variant config
    
3.  The exported component
    

* * *

### Step 3.1 — Define your class map

Before writing any styles, define a `buttonClasses` object. This is the single source of truth for every CSS class name the button uses:

```plaintext
export const buttonClasses = {
  root: 'ui-button',
  variant: {
    primary:   'ui-button--v-primary',
    secondary: 'ui-button--v-secondary',
    outlined:  'ui-button--v-outlined',
    text:      'ui-button--v-text',
    negative:  'ui-button--v-negative',
    hyperlink: 'ui-button--v-hyperlink',
  } as const,
  size: {
    xs: 'ui-button--s-xs',
    sm: 'ui-button--s-sm',
    md: 'ui-button--s-md',
    lg: 'ui-button--s-lg',
  } as const,
  isActive:  'ui-button--active',
  fullWidth: 'ui-button--full-width',
  disabled: 'ui-button--disabled'
}
```

> **Why a class map?** It keeps class names in one place and makes refactoring safe. The styled component reads from this object — no magic strings scattered across your codebase.

**Bonus:**

You should use this whenever you want to alter the CSS of the component, there is a example ahead.

* * *

### Step 3.2 — Write the styled internal component

Import your primitive and the `styled` function from the theme layer, then build `StyledButtonInternal`:

```typescript
import { ButtonPrimitive } from '../../primitives'
import { styled } from '../../ds-theme'

// This layer adds our google-photos product tokens on the primtive button
// making sure the component is aware of the product-styling
const StyledButtonInternal = styled(ButtonPrimitive)(({ theme }) => {
  // Notice: `resolveTheme`, is where our product theme lives
  // We aren't touching anything outside of resolveTheme
  const { colors, spacing, stroke } = theme.resolveTheme

  return {
    // Notice the stling order
    // ─── 1. CSS Custom Properties (Tokens) ───────────────────────────────
    // Define all tunable values as CSS variables.
    // These are overridden by variant classes below.

    // Notice how the component tokens maps to specific tokens,
    // As long as this mapping doesn't change the component can adapt
    // to any product and color scheme
    '--btn-bg':             colors.surface.accent.default,
    '--btn-bg-hover':       colors.surface.accent.hover,
    '--btn-bg-active':      colors.surface.accent.active,
    '--btn-bg-disabled':    colors.surface.accent.disable,

    '--btn-color':          colors.type[0],
    '--btn-color-hover':    'var(--btn-color)',
    '--btn-color-active':   'var(--btn-color)',
    '--btn-color-disabled': colors.type.accentDisable,

    '--btn-border-width':   '0px',
    '--btn-border-color':   colors.type[2],

    // Default (md) size tokens

    // Hardcoded? Well there is not really a good way to handle such tokens, I'm still searching for something
    '--btn-height':    '32px',
    '--btn-min-width': '60px',
    '--btn-py':        spacing[8],
    '--btn-px':        spacing[12],
    '--btn-radius':    spacing[6],
    '--btn-icon-size': 'calc(var(--ui-base-size) * 4)',

    // ─── 2. Base Styles ───────────────────────────────────────────────────
    display:        'inline-flex',
    alignItems:     'center',
    justifyContent: 'center',
    cursor:         'pointer',
    userSelect:     'none',
    textTransform:  'none',
    letterSpacing:  'normal',
    height:         'var(--btn-custom-height, var(--btn-height))',
    minWidth:       'var(--btn-custom-min-width, var(--btn-min-width))',
    padding:        'var(--btn-custom-py, var(--btn-py)) var(--btn-custom-px, var(--btn-px))',
    borderRadius:   'var(--btn-custom-radius, var(--btn-radius))',
    borderStyle:    'solid',
    borderWidth:    'var(--btn-border-width)',
    borderColor:    'var(--btn-custom-border-color, var(--btn-border-color))',
    backgroundColor:'var(--btn-custom-bg, var(--btn-bg))',
    color:          'var(--btn-color)',

    // ─── 3. Interaction States ────────────────────────────────────────────
    '&:focus-visible': {
      outline:       `2px solid ${colors.edge.accent.focus}`,
      outlineOffset: spacing[2],
    },
    '&:hover:not(:disabled)': {
      backgroundColor: 'var(--btn-custom-bg-hover, var(--btn-bg-hover))',
      color:           'var(--btn-color-hover)',
      borderColor:     'var(--btn-custom-border-color-hover, var(--btn-border-color-hover))',
    },
    '&:active:not(:disabled)': {
      backgroundColor: 'var(--btn-custom-bg-active, var(--btn-bg-active))',
    },
    '&:disabled': {
      pointerEvents:   'none',
      backgroundColor: 'var(--btn-bg-disabled)',
      color:           'var(--btn-color-disabled)',
    },

    // ─── 4. Variant Classes ───────────────────────────────────────────────
    // Each variant just overrides the CSS variables defined in section 1.
    [`&.${buttonClasses.variant.secondary}`]: {
      '--btn-bg':       colors.surface[3],
      '--btn-bg-hover': colors.edge[5],
    },
    
    // states concerned to this variant

    [`&:hover.${buttonClasses.variant.secondary}`]: {
      '--btn-bg':       colors.surface[3],
      '--btn-bg-hover': colors.edge[5],
    },
    

    [`&.${buttonClasses.variant.outlined}`]: {
      '--btn-bg':           'transparent',
      '--btn-color':        colors.type[2],
      '--btn-border-width': stroke[3],
      '--btn-border-color': colors.edge[6],
    },
    [`&.${buttonClasses.variant.text}`]: {
      '--btn-bg':       'transparent',
      '--btn-bg-hover': colors.surface.clear.hover,
      '--btn-color':    colors.type[2],
    },

    // Size classes
    [`&.${buttonClasses.size.sm}`]: {
      '--btn-height':    '28px',
      '--btn-py':        spacing[6],
      '--btn-px':        spacing[12],
      '--btn-radius':    spacing[4],
      '--btn-icon-size': 'calc(var(--ui-base-size) * 3)',
    },
    [`&.${buttonClasses.size.lg}`]: {
      '--btn-height':    '36px',
      '--btn-py':        spacing[8],
      '--btn-px':        spacing[16],
    },
  }
})
```

> **Key pattern — CSS variables as a theming layer:** All colors, sizes, and spacing are set as CSS custom properties first (section 1), then consumed via `var(--btn-*)` in base styles (section 2). Variant classes simply reassign those variables. This means state, hover, and active styles all update automatically when a variant changes the variable — you never need to re-declare `&:hover` inside each variant.

> **Style ordering matters:** Always follow this order: `tokens → base styles → interaction states → variants → compound variants → variant-specific states`.

* * *

### Step 3.3 — Wire up variants with CVA

Use CVA to compute the right class names from props:

```plaintext
import { cva, GetVariantProps } from '../../theme'



// Always create the default variant props, it is a life-saver
const getDefaultVariantProps = (props?: Partial<ButtonVariantProps>): ButtonVariantProps => ({
  variant: props?.variant || 'primary',
  size: props?.size || 'md',
  isActive: props?.isActive || false,
  fullWidth: props?.fullWidth || false,
  disabled: props?.disabled || false
});


const buttonVariants = cva(buttonClasses.root, {
  variants: {
    variant:   buttonClasses.variant,
    size:      buttonClasses.size,
    isActive:  { true: buttonClasses.isActive,  false: '' },
    fullWidth: { true: buttonClasses.fullWidth, false: '' },
    disabled:  { true: buttonClasses.disabled, false: ''}
  },
  defaultVariants: getDefaultVariantProps(),
})

type ButtonVariantProps = GetVariantProps<typeof buttonVariants>;
```

* * *

### Step 3.4 — Build the styled wrapper

`StyledButton` is a public, escapable component. It accepts `className`, `sx`, and `style` — useful for teams who need to adapt the button without forking it:

```plaintext
import React, { useMemo } from 'react'
import { clsx } from '../../theme'

export type StyleButtonVariantProps = ButtonVariantProps;
export type StyledButtonProps = 
Omit<
  StyledButtonInternalProps, 
  keyof ButtonVariantProps 
  | '...other-styling-mui-props'
> & StyleButtonVariantProps


// Do note that this layer is expensive, both cva and the StyledButtonInternal
// Thus memoise always, may help sometimes
export const StyledButton = React.memo((props) => {
  const { size, variant, isActive, fullWidth, className, ...otherProps } = 
  getDefaultVariantProps(props)

  const classes = useMemo(
    () => buttonVariants({ size, variant, isActive, fullWidth }),
    [size, variant, isActive, fullWidth]
  )

  // Note: I could have just written  <StyledButtonInternal className={clsx(classes, className)}
  // Why did I pulled the value outside of the render?

  // I did this to hint the react-compiler that the jsx is dependent on this value,
  // see if you can memoise this value internally, react-compiler?

  // Compiler tmrw may become much more smart where it binds to vars directly, if the var
  // identity or value changed it may re-render as an effect to the change
  // Pulling it outside of the jsx, make sure that there is not computation inside of jsx-render
  // itself, thus if there is not computation within the render step then the render can be
  // cached and memoised

  const className = clsx(classes, className)
  
  return (
    <StyledButtonInternal
      className={className}
      {...otherProps}
    />
  )
})
```

> `StyledButton` is exported so that teams can extend or restyle the button with `styled(StyledButton)`, `sx`, or extra `className` props. **It's the escape hatch.**
> 
> **NOTE: Using StyledButton is discouraged, and should not be allowed until absolutely necessary.**

* * *

### Step 3.5 — Build the strict public component

The final `Button` component is what most product code should import. It deliberately removes styling escape hatches — all visual variations must come through supported props (variants):

```plaintext
const Button = (
  props: Omit<StyledButtonProps, 'className' | 'sx' | 'style'>
) => {
  // Any component-specific logic lives here
  const handleClick = (event) => {
    props.onClick?.(event)
  }

  return <StyledButton {...props} onClick={handleClick} />
}

export { Button }
```

> **Why remove** `className`, `sx`, and `style`? Because the point of a design system is consistency. If every team can arbitrarily style the button, you don't have a design system — you have a starting point. The strict API enforces that all design decisions go through the variant system, which can be reviewed, documented, and updated centrally.

* * *

### What Layer 3 exports

| Export | Who uses it |
| --- | --- |
| `Button` | Product teams (primary import) |
| `StyledButton` | Teams that need to extend the button |
| `buttonClasses` | Styling and testing utilities |

**Note:**

StyledButton is exported from `button/index.ts` but not `design-system/index.ts`

We should create a eslint plugin that throws a warning on nested import `import { StyledButton } from design-system/button` this will throw a warning, and AI will comment this on the PR, making sure that the breach is known to reviewer, the escape hatch is caught and reasoned about and well thought of.

* * *

## Layer 4 — DS Labs

**What it does:** Houses composed components that are nearly ready for the design system but haven't stabilized yet. Think of it as a staging area.

**Who maintains it:** The pod (product team), not the DS with final authoritative authority being DS team.

**Where it lives:** `src/ds-labs/`

### Step 4.1 — Compose from DS components

DS Labs components are built by composing Layer 3 (design-system) components and not primitive component or `StyledButton` kind of component.

Here's an example: an **EditableText** field that shows static text until the user clicks an edit icon:

```plaintext
// Notice: this is import from 'ds/index.ts'
// This cannot be 'ds/button'

// If there is such a import it means that is not ready to be merged into ds-core
// Ideally that belongs to next layer, product-ui-kit

import { TextInput, Typography } from '../../ds'
import { EditIcon } from '../../ds-icons'
import { useState } from 'react'

function EditableTextInput({ value, onChange }) {
  const [isEditable, setIsEditable] = useState(false)

  return isEditable
    ? <TextInput value={value} onChange={onChange} onBlur={() => setIsEditable(false)} autoFocus />
    : (
      <Typography>
        {value}
        <EditIcon onClick={() => setIsEditable(true)} />
      </Typography>
    )
}
```

**When does a Labs component graduate to DS?**

When it has:

*   Stabilized API (no breaking changes expected)
    
*   Consistent usage patterns across at least two products
    
*   Coverage by the DS team's review process
    

It should only use `ds` imports not nested `ds/button` that is something unstable, either we will add such a support in the component i.e `StyledBox` will support one more variant, so that the `Button` can be used directly.

Sometimes we override StyledBox but didn't needed the tokens that it had to offer, in those cases it is fine to have directly used

and styled it via a data-slot.

* * *

## Layer 5 — Product Kit

**What it does:** Holds UI components that are specific to a single product and have no realistic path to becoming shared. These will exist in product code and not design-sytem code.

**Where it lives:** `google-photos/ui-kit/scaleble-container`, `google-calendar/ui-kit/calendar-cell`

**Examples of things that belong here:**

*   A dashboard widget specific to one app's data model
    
*   A branded onboarding flow that only makes sense in one product
    
*   One-off promotional banners or campaign UI
    
*   Some A/B testing UI component
    
*   Something related to product identity
    

**Rule of thumb:** If you can imagine another product needing it, it might belong in DS Labs. If you genuinely can't, it lives in your product code.

For example:

ScalableBox

```plaintext
const ScalableBox = () => {
 
  return <div data-slot="scalable-container">
    <div data-slot="left-edge"></div>
    <div data-slot="right-edge"></div>
    <div data-slot="top-edge"></div>
    <div data-slot="bottom-edge"></div>
  </div>

}
```

We wanted to create a simple container whoes edges can be dragged so as to increase the width and height of the container.

1.  Ask yourself is it being used by my product or multiple products?
    
2.  Ask yourself is there any pre-requisite component required to build this?
    

If the answer to first \[1\] question is Yes, you may want to concern the designers and DS team. For visualisation of component, its API etc.

If the answer to second \[2\] question is Yes, you may want to see list of existing components, the new components that is required to be built for example drag handler, you may need to go through the MUI docs id there is such a component existing? Depending on these answers you may want to to then see if the design team gave you specification for the components, ask them those specification first that is a doc for each required component. It is mandatory toh have these docs attached with the Figma desgin. Once you have it you should follow the step from the primitive layer to all the way to lab layer.

Please note there no really good answer where this component should go or how it should be prepared etc, but you should try you best to use existing components.

* * *

## Summary

| Layer | Name | Responsibility | Consumers |
| --- | --- | --- | --- |
| 1 | Primitives | Raw MUI re-exports, swap point for future library changes | Layer 3 |
| 2 | DS Theme | Tokens (`l0`/`l1`) and the `styled` engine | Layer 3 |
| 3 | DS Components | Branded, variant-driven components with strict APIs | Everyone |
| 4 | DS Labs | Composed, near-mature components under pod ownership | Products |
| 5 | Product Kit | Product-specific UI with no sharing intent | One product |

* * *

## Quick Reference: Adding a New Variant

Say you need a new `ghost` variant on Button. Here's exactly what to touch:

1.  `buttonClasses` — add `ghost: 'ui-button--v-ghost'` to the `variant` map.
    
2.  `StyledButtonInternal` — add a `[&.${buttonClasses.variant.ghost}]` block that sets the CSS variables.
    
3.  `buttonVariants` (CVA) — it picks up the new key automatically from `buttonClasses.variant`.
    
4.  `Button` props type — if you're using a strict union type for `variant`, add `'ghost'` to it.
    
5.  Any request that deserves living in DS-lab or product-kit and is built on composition. It composes a component like `button`
    
    **BUT** in respect to this component of ds-lab or the product-kit, the nested component needs some special styling, such a styling won't ever be present on the component when being though in isolation.
    
    The Button has padding left and right that is dependent on the size of the button, example it can be `8px` when the size is `sm`, and `14px` when the size is `lg`. The component wont't ever have a padding of 4px when the size is `sm`
    
    Your first reaction could be adding one more variant `xs` but ask yourself what are chances of this being used everywhere in the App, if the chances are high then the component can be modified to add such a variant in size. BUT, that is unlikely to be the case as the component that came up with initial doc never thought of this use-case.
    
    **BUT**, a requirement has been proposed.
    
    Button in the App navigation can have a custom height it can be smaller (height = 20px ) and just the padding is `4px`.
    
    Something that is outside of the variants, be caution at this point of time, you have to pushback on this, heavily.
    
    Openly tag your lead and designer who gave it to you and the design lead, asking for a explanation why is is required.
    
    **Please note this has to be in public channel and documented.**
    
    You are not going to add a variant until it really makes sense.
    
    For example:
    
    The Button having soft edges like being pill shaped or increased border radius or just being flat, is valid requirement it is entirely new paradigm of variant.
    
    This variant can be added with values like full (pill), sm (4px may be), none (0px).
    
    ```plaintext
    round: {
      none: 'ui-btn--round-flat',
      full: 'ui-btn--round-full',
      sm: 'ui-btn--round-sm', 
    }
    ```
    
    This is valid requirement it is all new variant of a button
    
    **BUT,** having `0px` padding or custom padding on the button of size `sm` is weird?
    
    When the size `sm` has internally defined a fixed padding why we want to modify that? Why is there a requirement to modify it?
    
    Push hard on this, belive me designer don't know what they need, or they are just slacking off or they are not ready to do some Math to adjust padding and are not ready to do the hard work.
    
    We cannot let their requirement spoil our code.
    
    So please ask and get this in written.
    
    If found that you are doing things blindly without questioning or involving higher stake holder, with excuse that you did this in order to meet deadlines.
    
    **Please Please Note** You will be held responsible along with everyone involved from product, designer, dev, lead.
    
    If such a instance happens and come to notice, **Please note you will be tagged and highlighed in public channel.**
    
    **And even your component as whole may be deleted from the code**, we won't care about how and what imapct will it have on your code, it explodes your code, product, fine!! We will do it anyways.
    
    Only case it is valid when design team give in writing
    
    When this component is ment to be a component in isolation i.e it has been thought and designed in isolation by just inheriting on existing design and freely modifying to suit the use case. This component itself will become a use-case.
    
    Example: A product checkout page is way different than the rest of its pages, may have different font family, or different but bold styles, trying to grab attentions. Form component in that case is valid ask as it itself is becoming a use-case.
    
    I'm stressing this again and again, and literally mean every word because I want you to feel bad about it as an engineer. Please not this is something you should feel bad about, something you should not encourage, something you should have bold stance against.
