Skip to content

Components

Typography

Variants

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Body Large

Body

Overline

Caption
html
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<p class="large">Body Large</p>
<p>Body</p>
<p class="overline">Overline</p>
<caption>
  Caption
</caption>

Heading group

Zero or more p elements

Followed by one h* element

Followed by zero or more p elements

html
<hgroup>
  <p>Zero or more p elements</p>
  <h2>Followed by one h* element</h2>
  <p>Followed by zero or more p elements</p>
</hgroup>

Inline text elements

ResultCode
Abbr.<abbr>
Definition<dfn>
Bold<strong>, <b>
Italic<i>, <em>, <cite>
Deleted<del>
Inserted<ins>
Ctrl + S<kbd>
Highlighted<mark>
Strikethrough<s>
Small<small>
Text Sub<sub>
Text Sup<sup>
Underline<u>

Blockquote

"Occupy your mind, don't stay home. Talk to all your friends, but don't look at your phone”
— Marika Hackman, No Caffeine
html
<blockquote>
  "Occupy your mind, don't stay home. Talk to all your friends, but don't look at your phone”
  <footer>
    — Marika Hackman, <cite>No Caffeine</cite>
  </footer>
</blockquote>

Browser compatibility

Installation

css
@layer components.base {
  /* Base typography */
  :where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) {
    color: var(--text-color-1);
    font-weight: 700;
    text-wrap: pretty;
  }

  :where(h1, .h1) {
    font-size: var(--font-size-h1, var(--font-size-7));
    letter-spacing: -0.02em;
    line-height: 1.15;
  }

  :where(h2, .h2) {
    font-size: var(--font-size-h2, var(--font-size-5, 2rem));
    letter-spacing: -0.02em;
    line-height: 1.2;
  }

  :where(h3, .h3) {
    font-size: var(--font-size-h3, var(--font-size-4, 1.5rem));
    letter-spacing: -0.01em;
    line-height: 1.167;
  }

  :where(h4, .h4) {
    font-size: var(--font-size-h4, var(--font-size-3, 1.25rem));
    letter-spacing: -0.01em;
    line-height: 1.235;
  }

  :where(h5, .h5) {
    font-size: var(--font-size-h5, var(--font-size-2, 1.1rem));
    line-height: 1.334;
  }

  :where(h6, .h6) {
    font-size: var(--font-size-h6, var(--font-size-1, 1rem));
    line-height: 1;
  }

  :where(hgroup) {
    & > :where(p, .p) {
      margin: 0;
    }

    & > :where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) {
      margin-block-end: 0.4em;
    }

    /* The second p element */
    & > :where(p, .p):last-of-type:last-child:not(:first-child) {
      color: oklch(from currentColor l c h / 75%);
      font-size: var(--font-size-lg);
      line-height: 1.6;
    }
  }

  /** Overline */
  :where(.overline, hgroup > :where(p, .p):first-of-type:first-child) {
    color: light-dark(
      oklch(from var(--text-color-2) calc(l * 1.25) c h),
      oklch(from var(--text-color-2) calc(l * 0.75) c h)
    );
    font-size: var(--font-size-xs);
    font-weight: 500;
    letter-spacing: 0.06em;
    line-height: 2.5;
    text-transform: uppercase;
  }

  :where(p, .p) {
    text-wrap: pretty;

    &.small {
      font-size: var(--font-size-md);
    }
    &.large {
      font-size: var(--font-size-lg);
    }
  }

  /* Inline text elements */
  :where(ins, u, abbr, dfn) {
    text-decoration: underline;
    text-underline-offset: 1px;

    @supports (-moz-appearance: none) {
      text-underline-offset: 2px;
    }
  }

  :where(abbr, dfn) {
    font-style: normal;
    text-decoration: var(--color-9) underline dotted;

    &[title] {
      cursor: help;
      text-underline-offset: 1px;
    }

    @supports (-moz-appearance: none) {
      text-underline-offset: 2px;
    }
  }

  :where(sup) {
    font-size: 0.5em;
  }

  :where(del, ins) {
    color: var(--color-9);
  }

  :where(small) {
    font-size: max(0.5em, var(--font-size-0, 0.75rem));
    max-inline-size: var(--size-content-1);
  }

  :where(cite) {
    font-style: italic;
  }

  /* Blockquote */
  :where(blockquote) {
    border-inline-start-width: var(--border-size-3);
    display: grid;
    gap: var(--size-3);
    padding-block: var(--size-3);
    padding-inline: var(--size-4);

    :first-child {
      margin-block-start: 0;
    }

    :last-child {
      margin-block-end: 0;
    }

    footer {
      color: var(--text-color-2);
    }
  }

  /* Code */
  :where(pre) {
    border-radius: 0.375rem;
    direction: ltr;
    font-size: 0.875rem;
    line-height: 1.7142857;
    margin-block: 1.7142857em;
    max-inline-size: max-content;
    min-inline-size: 0;
    padding-block: 0.8571429em;
    padding-inline: 1.1428571em;
    white-space: pre;
    writing-mode: lr;
  }

  :where(code, kbd, samp, pre) {
    font-family: var(--font-mono);
  }

  :where(code) {
    background-color: oklch(00 0 0 /18%);
    border-radius: var(--border-size-3);
    font-size: 0.9em;
    padding: 0.2ex 0.5ex;
  }

  :where(kbd, var) {
    background-color: var(--text-color-2);
    border-color: var(--text-color-2);
    border-radius: var(--border-radius, var(--radius-2));
    border-width: var(--border-size-1);
    color: var(--text-color-2-contrast);
    padding: calc(var(--size-1) / 2) var(--size-1);
  }

  :where(:not(pre) code, kbd) {
    word-break: break-word;
  }

  :where(:not(pre) code) {
    border-radius: var(--border-radius, var(--radius-2));
    padding: var(--size-1) var(--size-2);
    writing-mode: lr;
  }

  :where(mark) {
    border-radius: var(--border-radius, 0);
    padding: calc(var(--size-1) / 2) var(--size-1);
    vertical-align: baseline;
  }

  /* Misc */
  :where(dt) {
    font-weight: 700;
  }

  :where(figure) {
    & > :where(figcaption) {
      font-size: var(--font-size-1, 1rem);
      text-wrap: balance;
    }
  }
}