Qubik's Site

Writing Content

Pages are plain Markdown files under src/ (VitePress's srcDir). This page covers what you can put in them: the page types the theme recognizes, the Markdown syntax it adds on top of VitePress, and how to drop Vue components into a page.

The demo page src/markdown-examples.md shows every feature below as input beside output — keep it open in the dev server while you read this.

Field-by-field frontmatter types and defaults live in configuration/frontmatter.md.

Page types

The theme classifies every page from its location and renders a dedicated layout for it. You never wire this up — you just put the file in the right place:

Put the file atIt becomesYou get
src/index.md with home: truehomeThe welcome card from themeConfig.home
src/<anything>.mdnormalPlain article chrome — title, content, footer
src/posts/<post>.mdpostByline, taxonomy, cover, license and comment cards
src/series/<slug>/<part>.mdseries articleThe same, under a series banner
src/posts.md, archives.md, categories.md, tags.md, series.mdlistingWhatever listing component you place in it
not-foundThe 404 page, client-rendered

Two frontmatter escape hatches exist for the rare case where the path lies: pageType forces a type outright, and article: false drops a post to a plain page. The reasoning behind the layout is in design/content-architecture.md.

Frontmatter you'll use constantly

yaml
yaml
---
title: Hello, Terminal          # or a per-language map
description: A first look.      # summary in listings + meta description
date: 2026-07-28                # posts: publish date and listing order
tags: [theme, color]            # posts: taxonomy (plain names)
categories: Guides
cover: /images/hello.svg        # posts: card panel + article hero
order: -1                       # explorer/series ordering, smaller sorts higher
showInExplorer: false           # hide from the tree (still reachable by URL)
---

Standard Markdown

Headings, paragraphs, emphasis, blockquotes, lists, rules, links, tables, images, and inline code are all styled to the design language across the three color modes. Two behaviors worth knowing:

  • Heading anchors. Every heading gets a # control that appears on hover (always visible on touch). Clicking it copies that heading's absolute URL and confirms with a transient toast.
  • Reading measure. Body text is capped at a comfortable measure and stays neutral — the main color is reserved for emphasis (links, bold, headings, inline code). This is a binding rule, not a preference: design/color-system.md.

Code blocks

Fenced blocks are highlighted by Shiki with the Oxocarbon palettes and follow the active color mode. Each renders as a card with a title bar carrying the language and a [copy] control:

md
md
```js
export default { name: 'VitePressThemeTerminal' }
```

Add a file name in square brackets after the language and it appears in the title bar before the language:

md
md
```scss [main.scss]
body { color: var(--ct-main); }
```

Callouts

Eight container types, each with a colored left bar and an icon:

md
md
::: tip
Everything after the type is the body.
:::

::: warning Custom title
The rest of the line becomes the title.
:::

::: details
Collapsible — click the title to expand.
:::
TypeNotes
info / notenote is a style alias with its own title
tip
warning
danger / cautioncaution is a style alias with its own title
important
detailsCollapsible, with an animated chevron

Default titles are localized automatically; a custom title (anything after the type on the opening line) is used verbatim and may contain inline Markdown.

Pull quotes

For a line worth setting apart, the quote container frames it with corner marks in the shape of the Chinese brackets and , drawn in the main color — opener at the upper-left, closer at the lower-right:

md
md
::: quote
Hello, World!
:::

The container takes any Markdown, so a longer quotation and its attribution fit too. Nothing is configurable: the marks are drawn by the theme (with borders — they are not text, so they need no CJK font and never end up in a copied selection), the quotation is set bold, and the frame shrink-wraps it and centers in the column — a short line keeps the marks right beside it, a long one fills the column as usual.

Use the plain > blockquote for a quotation in the flow of your text, and ::: quote when the quotation is the point.

Markdown extensions

Enabled site-wide, no configuration needed:

FeatureSyntax
Emoji:tada:
SubscriptH~2~O
Superscript29^th^
Inserted text++inserted++
Marked text==highlighted==
FootnotesText[^1][^1]: The note.
Definition listsTerm / : definition
Abbreviations*[HTML]: HyperText Markup Language

Math

Two renderers, both typeset in IBM Plex Math, with no collision between them.

LaTeX uses the familiar delimiters and is rendered at build time to MathML:

md
md
Inline $E = mc^2$ and a display block:

$$
\frac{1}{2} \sum_{i=1}^{n} x_i
$$

Typst uses its own container and inline form:

md
md
::: typst
1/2 < floor("mod"(floor(y/17) dot 2^(-17 floor(x)), 2))
:::

Inline: :typst[e^(i pi) + 1 = 0]

Typst is compiled in the browser. Malformed input shows a visible error beside the kept source rather than a blank space, and with JavaScript off the raw source stays readable. The $ delimiters always mean LaTeX — $$…$$ never routes to Typst.

Images and galleries

Every image in the content area joins one click-to-enlarge gallery automatically. An image wrapped in a link keeps its link instead, and a single image opts out with data-no-lightbox:

md
md
![A terminal session](/images/demo-terminal-1.svg)

<img src="/images/logo.svg" alt="Logo" data-no-lightbox>

For a swipeable deck, nest slide containers inside a swiper container — note the outer fence needs more colons than the inner ones:

md
md
:::: swiper
::: swiper-slide-no-shadow
![First](/images/demo-terminal-1.svg)
:::
::: swiper-slide-no-shadow
![Second](/images/demo-terminal-2.svg)
:::
::::

Decks get prev/next chevrons outside the images and support mouse and touch swipes.

Per-language page bodies

A page can carry several language versions of its body; the reader's language switch swaps them in place, with no URL change:

md
md
::: lang en
English body…
:::

::: lang zh-Hans
中文正文…
:::

Content outside any ::: lang block always shows, so shared code samples and images need not be duplicated. Details in internationalization.md.

Vue components in Markdown

VitePress lets any page use Vue. The theme adds an @ alias pointing at .vitepress/theme, so imports stay short:

md
md
<script setup lang="ts">
import Card from '@/components/Card.vue'
</script>

<Card
  :show-prompt="true"
  :prompt="{ command: 'card', args: '~/notes' }"
>
  <p>Any content can live in a card.</p>
</Card>

Card is the theme's reusable floating window. Its prompt object takes a required command plus optional host, path, and args; omitted values default to the configured site name (or the normalized site title) and the current page path. The prompt is off unless show-prompt is set.

The listing components (PostsIndex, ArchivesList, CategoriesIndex, TagsIndex, TermPosts, SeriesIndex, SeriesArticles) and FriendLinks are registered globally — place them without importing. For pages that are mostly components rather than prose, author a view instead: customization.md.

READ~/docs/guide/writing-content
TOPdark