<!-- Generated by tools/build_system.py from design-tokens/tokens.css and the data in that script. Do not edit by hand. -->

# CNO design tokens and component specs

Source of truth for building in the Canada's National Observer style. Developer system: /admin/system/

# Design tokens

Named values for the CNO interface, extracted from the saved nationalobserver.com pages. Use the token, never the raw value.

## Colour

| Colour | Token | Hex / value | RGB | Use |
| --- | --- | --- | --- | --- |
| Text | `--color-text` | `#000000` | R0 G0 B0 | body text (--cno-base-font-color), table cells, headings |
| Text on dark | `--color-text-on-dark` | `#ffffff` | R255 G255 B255 | text and icons on the black sidebar and on filled buttons |
| Text muted | `--color-text-muted` | `#666666` | R102 G102 B102 | labels, captions (--cno-gray-500) |
| Text disabled | `--color-text-disabled` | `#999999` | R153 G153 B153 | disabled text (--cno-gray-700) |
| Primary | `--color-primary` | `#003f74` | R0 G63 B116 | links in the admin, active states, focus (--cno-blue-dark) |
| Primary hover | `--color-primary-hover` | `#3ba5d1` | R59 G165 B209 | link and button hover (--cno-blue, the site's link colour) |
| Link | `--color-link` | `#3ba5d1` | R59 G165 B209 | links on the public site (a { color: var(--cno-blue) }) |
| Accent | `--color-accent` | `#fe3b1f` | R254 G59 B31 | Subscribe orange: the active-item bar and the one call to action (--cno-subscribe-orange) |
| Brand red | `--color-brand-red` | `#ff3a1e` | R255 G58 B30 | red of the CNO logo mark (--cno-red-300) |
| Ink | `--color-ink` | `#000000` | R0 G0 B0 | sidebar, header and footer-dark surfaces (--cno-black) |
| Ink soft | `--color-ink-soft` | `#222222` | R34 G34 B34 | hover on black surfaces (--cno-gray-100) |
| Surface | `--color-surface` | `#ffffff` | R255 G255 B255 | cards, menus, main area (--cno-white) |
| Page bg | `--color-page-bg` | `#f9f9f9` | R249 G249 B249 | code boxes, dev box, page tint (--cno-gray-1200) |
| Surface alt | `--color-surface-alt` | `#f2f2f2` | R242 G242 B242 | footer background (--cno-gray-1100) |
| Border | `--color-border` | `#dddddd` | R221 G221 B221 | section header rule (--cno-gray-950) |
| Border light | `--color-border-light` | `#e2e2e2` | R226 G226 B226 | table row dividers (--cno-gray-1000) |
| Border strong | `--color-border-strong` | `#cccccc` | R204 G204 B204 | input borders (--cno-gray-900) |
| Hover | `--color-hover` | `rgba(0, 0, 0, 0.04)` |  | round icon button hover |
| Focus visible | `--color-focus-visible` | `rgba(0, 0, 0, 0.12)` |  | keyboard focus fill on rows |
| Icon muted | `--color-icon-muted` | `#757575` | R117 G117 B117 | icons (--cno-gray-600) |
| Backdrop | `--color-backdrop` | `rgba(0, 0, 0, 0.8)` |  | behind a dialog (--cno-modal-background-color) |
| Link underline | `--color-link-underline` | `rgba(0, 63, 116, 0.4)` |  | underline on admin links |
| Disabled bg | `--color-disabled-bg` | `#e2e2e2` | R226 G226 B226 | disabled button fill (--cno-gray-1000) |
| Disabled text | `--color-disabled-text` | `#999999` | R153 G153 B153 | disabled button text (--cno-gray-700) |
| Success | `--color-success` | `#0db500` | R13 G181 B0 | success (--cno-green) |
| Success bg | `--color-success-bg` | `#d4f4d4` | R212 G244 B212 | success fill (--cno-green-light) |
| Success text | `--color-success-text` | `#054f00` | R5 G79 B0 | success text (--cno-green-dark) |
| Danger | `--color-danger` | `#ff0c00` | R255 G12 B0 | error (--cno-red) |
| Danger bg | `--color-danger-bg` | `#ffcecc` | R255 G206 B204 | error fill (--cno-red-light) |
| Danger text | `--color-danger-text` | `#990700` | R153 G7 B0 | error text (--cno-red-dark) |
| Warning | `--color-warning` | `#ffad02` | R255 G173 B2 | warning (--cno-yellow-dark) |
| Warning bg | `--color-warning-bg` | `#fdca40` | R253 G202 B64 | highlight fill (--cno-gold) |

## Typography

Sans `ProximaNova, "Helvetica Neue", Helvetica, Arial, "Nimbus Sans L", sans-serif`; serif `"Noto Serif", Georgia, Times, "Times New Roman", serif`.

| Token | Size / line height | Weight | Use |
| --- | --- | --- | --- |
| `--font-size-display` | 54px / 60px | 800 | Page title on wide screens |
| `--font-size-title` | 32px / 36px | 800 | Page title |
| `--font-size-h2` | 32px / 40.8px | 800 | Section heading |
| `--font-size-lg` | 18px / 24px | 400 | Site base text, large buttons |
| `--font-size-md` | 16px / 24px | 400 | Admin body text, medium and small buttons |
| `--font-size-table` | 15px / 22px | 400 | Table body |
| `--font-size-nav` | 14px / 20px | 700 | Sidebar items (uppercase) |
| `--font-size-thead` | 13px / 20px | 800 | Table head (uppercase) |
| `--font-size-caption` | 13px / 18px | 400 | Code badges, captions |

## Shape and elevation

| Token | Value | Use |
| --- | --- | --- |
| `--radius-sm` | 4px | Cards, inputs, code boxes |
| `--radius-btn-sm` | 15px | Small pill button |
| `--radius-btn-md` | 20px | Medium pill button |
| `--radius-btn-lg` | 24px | Large pill button |
| `--radius-round` | 50% | Icon buttons, dots |
| `--shadow-1` | 0 1px 2px rgba(0, 0, 0, 0.12) | Resting card (admin only; the site uses almost none) |
| `--shadow-8` | 0 6px 16px rgba(0, 0, 0, 0.16) | Menus and hovered tiles |
| `--shadow-24` | 0 16px 40px rgba(0, 0, 0, 0.3) | Dialogs |

## All tokens

Generated from `tokens.css`, so it is always complete.

| Token | Value | Use | Source |
| --- | --- | --- | --- |
| `--color-text` | `#000000` | body text (--cno-base-font-color), table cells, headings | nationalobserver.com CSS |
| `--color-text-on-dark` | `#ffffff` | text and icons on the black sidebar and on filled buttons | nationalobserver.com CSS |
| `--color-text-muted` | `#666666` | labels, captions (--cno-gray-500) | nationalobserver.com CSS |
| `--color-text-disabled` | `#999999` | disabled text (--cno-gray-700) | nationalobserver.com CSS |
| `--color-primary` | `#003f74` | links in the admin, active states, focus (--cno-blue-dark) | nationalobserver.com CSS |
| `--color-primary-hover` | `#3ba5d1` | link and button hover (--cno-blue, the site's link colour) | nationalobserver.com CSS |
| `--color-link` | `#3ba5d1` | links on the public site (a { color: var(--cno-blue) }) | nationalobserver.com CSS |
| `--color-accent` | `#fe3b1f` | Subscribe orange: the active-item bar and the one call to action (--cno-subscribe-orange) | nationalobserver.com CSS |
| `--color-brand-red` | `#ff3a1e` | red of the CNO logo mark (--cno-red-300) | nationalobserver.com CSS |
| `--color-ink` | `#000000` | sidebar, header and footer-dark surfaces (--cno-black) | nationalobserver.com CSS |
| `--color-ink-soft` | `#222222` | hover on black surfaces (--cno-gray-100) | nationalobserver.com CSS |
| `--color-surface` | `#ffffff` | cards, menus, main area (--cno-white) | nationalobserver.com CSS |
| `--color-page-bg` | `#f9f9f9` | code boxes, dev box, page tint (--cno-gray-1200) | nationalobserver.com CSS |
| `--color-surface-alt` | `#f2f2f2` | footer background (--cno-gray-1100) | nationalobserver.com CSS |
| `--color-border` | `#dddddd` | section header rule (--cno-gray-950) | nationalobserver.com CSS |
| `--color-border-light` | `#e2e2e2` | table row dividers (--cno-gray-1000) | nationalobserver.com CSS |
| `--color-border-strong` | `#cccccc` | input borders (--cno-gray-900) | nationalobserver.com CSS |
| `--color-hover` | `rgba(0, 0, 0, 0.04)` | round icon button hover | Ours (admin tool) |
| `--color-focus-visible` | `rgba(0, 0, 0, 0.12)` | keyboard focus fill on rows | Ours (admin tool) |
| `--color-icon-muted` | `#757575` | icons (--cno-gray-600) | nationalobserver.com CSS |
| `--color-backdrop` | `rgba(0, 0, 0, 0.8)` | behind a dialog (--cno-modal-background-color) | nationalobserver.com CSS |
| `--color-link-underline` | `rgba(0, 63, 116, 0.4)` | underline on admin links | Ours (admin tool) |
| `--color-disabled-bg` | `#e2e2e2` | disabled button fill (--cno-gray-1000) | nationalobserver.com CSS |
| `--color-disabled-text` | `#999999` | disabled button text (--cno-gray-700) | nationalobserver.com CSS |
| `--color-success` | `#0db500` | success (--cno-green) | nationalobserver.com CSS |
| `--color-success-bg` | `#d4f4d4` | success fill (--cno-green-light) | nationalobserver.com CSS |
| `--color-success-text` | `#054f00` | success text (--cno-green-dark) | nationalobserver.com CSS |
| `--color-danger` | `#ff0c00` | error (--cno-red) | nationalobserver.com CSS |
| `--color-danger-bg` | `#ffcecc` | error fill (--cno-red-light) | nationalobserver.com CSS |
| `--color-danger-text` | `#990700` | error text (--cno-red-dark) | nationalobserver.com CSS |
| `--color-warning` | `#ffad02` | warning (--cno-yellow-dark) | nationalobserver.com CSS |
| `--color-warning-bg` | `#fdca40` | highlight fill (--cno-gold) | nationalobserver.com CSS |
| `--font-family` | `ProximaNova, "Helvetica Neue", Helvetica, Arial, "Nimbus Sans L", sans-serif` | --cno-base-font-family: the UI typeface | nationalobserver.com CSS |
| `--font-family-serif` | `"Noto Serif", Georgia, Times, "Times New Roman", serif` | --cno-serif-font-family: article body and pull quotes | nationalobserver.com CSS |
| `--letter-spacing` | `0` | the site sets none | nationalobserver.com CSS |
| `--font-size-title` | `32px` | h1 at the smallest breakpoint (2rem) | nationalobserver.com CSS |
| `--line-height-title` | `36px` | h1 (2.25rem) | nationalobserver.com CSS |
| `--font-weight-title` | `800` | h1 | nationalobserver.com CSS |
| `--font-size-display` | `54px` | h1 at the widest breakpoint (3.375rem) | nationalobserver.com CSS |
| `--line-height-display` | `60px` | h1 at the widest breakpoint (3.75rem) | nationalobserver.com CSS |
| `--font-size-h2` | `32px` | h2 (2rem) | nationalobserver.com CSS |
| `--line-height-h2` | `40.8px` | h2 (2.55rem) | nationalobserver.com CSS |
| `--font-size-lg` | `18px` | base text (--cno-base-font-size) and large buttons | nationalobserver.com CSS |
| `--line-height-lg` | `24px` | base line height (--cno-base-line-height) | nationalobserver.com CSS |
| `--font-size-md` | `16px` | admin body text, medium and small buttons (1rem) | nationalobserver.com CSS |
| `--line-height-md` | `24px` | admin body line height | Ours (admin tool) |
| `--font-size-table` | `15px` | table body in the admin (dense, between 14 and 16) | Ours (admin tool) |
| `--line-height-table` | `22px` | table body | Ours (admin tool) |
| `--font-size-nav` | `14px` | sidebar items, uppercase 700 | Ours (admin tool) |
| `--line-height-nav` | `20px` | sidebar items | Ours (admin tool) |
| `--font-size-thead` | `13px` | table head, 800 | Ours (admin tool) |
| `--line-height-thead` | `20px` | table head | Ours (admin tool) |
| `--font-size-caption` | `13px` | code badges, captions | Ours (admin tool) |
| `--line-height-caption` | `18px` | captions | Ours (admin tool) |
| `--font-weight-regular` | `400` | body | nationalobserver.com CSS |
| `--font-weight-semibold` | `600` | subheads | nationalobserver.com CSS |
| `--font-weight-bold` | `700` | buttons, nav | nationalobserver.com CSS |
| `--font-weight-thead` | `800` | headings (extrabold file) | nationalobserver.com CSS |
| `--radius-sm` | `4px` | cards, inputs, code (--cno-border-radius) | nationalobserver.com CSS |
| `--radius-btn-sm` | `15px` | small pill button (.9375rem) | nationalobserver.com CSS |
| `--radius-btn-md` | `20px` | medium pill button (1.25rem) | nationalobserver.com CSS |
| `--radius-btn-lg` | `24px` | large pill button (1.5rem) | nationalobserver.com CSS |
| `--radius-round` | `50%` | icon buttons, dots | Ours (admin tool) |
| `--space-1` | `4px` | Tailwind 1 | nationalobserver.com CSS |
| `--space-2` | `8px` | Tailwind 2 | nationalobserver.com CSS |
| `--space-3` | `12px` | Tailwind 3 | nationalobserver.com CSS |
| `--space-4` | `16px` | Tailwind 4 | nationalobserver.com CSS |
| `--space-5` | `20px` | Tailwind 5 (footer side padding) | nationalobserver.com CSS |
| `--space-6` | `24px` | Tailwind 6 (paragraph margin 1.5rem) | nationalobserver.com CSS |
| `--space-8` | `32px` | Tailwind 8 | nationalobserver.com CSS |
| `--space-10` | `40px` | Tailwind 10 | nationalobserver.com CSS |
| `--page-padding` | `40px` | main area padding | Ours (admin tool) |
| `--card-padding` | `24px` | card padding | Ours (admin tool) |
| `--shadow-1` | `0 1px 2px rgba(0, 0, 0, 0.12)` | the site uses almost no shadows; resting card (admin only) | Ours (admin tool) |
| `--shadow-8` | `0 6px 16px rgba(0, 0, 0, 0.16)` | menus and hovered tiles | Ours (admin tool) |
| `--shadow-24` | `0 16px 40px rgba(0, 0, 0, 0.3)` | dialogs | Ours (admin tool) |
| `--duration-hover` | `150ms` | --cno-transition-speed-default: colour and background fades | nationalobserver.com CSS |
| `--duration-menu-item` | `150ms` | same as hover | nationalobserver.com CSS |
| `--ease-standard` | `ease-in-out` | transition timing on links and buttons | nationalobserver.com CSS |
| `--transition-focus` | `150ms ease-in-out` | focus and underline transitions | nationalobserver.com CSS |
| `--sidebar-width` | `240px` | admin left nav | Ours (admin tool) |
| `--content-max-width` | `1290px` | --cno-main-content-max-width-wide (80.625rem) | nationalobserver.com CSS |
| `--article-max-width` | `790px` | article column (max-w-search_result) | nationalobserver.com CSS |
| `--nav-indicator-height` | `4px` | active item bar | Ours (admin tool) |
| `--header-height` | `200px` | site header, collapsed (12.5rem) | nationalobserver.com CSS |
| `--footer-padding` | `20px` | footer side padding (px-5) | nationalobserver.com CSS |

## CSS

```css
/* CNO design tokens: extracted from the saved nationalobserver.com pages (the --cno-* custom properties and the compiled Tailwind/Drupal CSS).
   One token per line with its use as the trailing comment: the docs, tokens.json and the skill are generated from this file.
   Source tag at the start of each comment:
     [css]  the value is written literally in the saved nationalobserver.com CSS (:root --cno-* or a component rule)
     [ours] defined by us for the admin tool, not taken from the site */
:root {
  /* Color: text */
  --color-text: #000000;                     /* [css] body text (--cno-base-font-color), table cells, headings */
  --color-text-on-dark: #ffffff;             /* [css] text and icons on the black sidebar and on filled buttons */
  --color-text-muted: #666666;               /* [css] labels, captions (--cno-gray-500) */
  --color-text-disabled: #999999;            /* [css] disabled text (--cno-gray-700) */

  /* Color: brand and neutrals */
  --color-primary: #003f74;                  /* [css] links in the admin, active states, focus (--cno-blue-dark) */
  --color-primary-hover: #3ba5d1;            /* [css] link and button hover (--cno-blue, the site's link colour) */
  --color-link: #3ba5d1;                     /* [css] links on the public site (a { color: var(--cno-blue) }) */
  --color-accent: #fe3b1f;                   /* [css] Subscribe orange: the active-item bar and the one call to action (--cno-subscribe-orange) */
  --color-brand-red: #ff3a1e;                /* [css] red of the CNO logo mark (--cno-red-300) */
  --color-ink: #000000;                      /* [css] sidebar, header and footer-dark surfaces (--cno-black) */
  --color-ink-soft: #222222;                 /* [css] hover on black surfaces (--cno-gray-100) */
  --color-surface: #ffffff;                  /* [css] cards, menus, main area (--cno-white) */
  --color-page-bg: #f9f9f9;                  /* [css] code boxes, dev box, page tint (--cno-gray-1200) */
  --color-surface-alt: #f2f2f2;              /* [css] footer background (--cno-gray-1100) */
  --color-border: #dddddd;                   /* [css] section header rule (--cno-gray-950) */
  --color-border-light: #e2e2e2;             /* [css] table row dividers (--cno-gray-1000) */
  --color-border-strong: #cccccc;            /* [css] input borders (--cno-gray-900) */
  --color-hover: rgba(0, 0, 0, 0.04);        /* [ours] round icon button hover */
  --color-focus-visible: rgba(0, 0, 0, 0.12); /* [ours] keyboard focus fill on rows */
  --color-icon-muted: #757575;               /* [css] icons (--cno-gray-600) */
  --color-backdrop: rgba(0, 0, 0, 0.8);      /* [css] behind a dialog (--cno-modal-background-color) */
  --color-link-underline: rgba(0, 63, 116, 0.4); /* [ours] underline on admin links */
  --color-disabled-bg: #e2e2e2;              /* [css] disabled button fill (--cno-gray-1000) */
  --color-disabled-text: #999999;            /* [css] disabled button text (--cno-gray-700) */

  /* Color: status */
  --color-success: #0db500;                  /* [css] success (--cno-green) */
  --color-success-bg: #d4f4d4;               /* [css] success fill (--cno-green-light) */
  --color-success-text: #054f00;             /* [css] success text (--cno-green-dark) */
  --color-danger: #ff0c00;                   /* [css] error (--cno-red) */
  --color-danger-bg: #ffcecc;                /* [css] error fill (--cno-red-light) */
  --color-danger-text: #990700;              /* [css] error text (--cno-red-dark) */
  --color-warning: #ffad02;                  /* [css] warning (--cno-yellow-dark) */
  --color-warning-bg: #fdca40;               /* [css] highlight fill (--cno-gold) */

  /* Typography */
  --font-family: ProximaNova, "Helvetica Neue", Helvetica, Arial, "Nimbus Sans L", sans-serif; /* [css] --cno-base-font-family: the UI typeface */
  --font-family-serif: "Noto Serif", Georgia, Times, "Times New Roman", serif; /* [css] --cno-serif-font-family: article body and pull quotes */
  --letter-spacing: 0;                       /* [css] the site sets none */
  --font-size-title: 32px;                   /* [css] h1 at the smallest breakpoint (2rem) */
  --line-height-title: 36px;                 /* [css] h1 (2.25rem) */
  --font-weight-title: 800;                  /* [css] h1 */
  --font-size-display: 54px;                 /* [css] h1 at the widest breakpoint (3.375rem) */
  --line-height-display: 60px;               /* [css] h1 at the widest breakpoint (3.75rem) */
  --font-size-h2: 32px;                      /* [css] h2 (2rem) */
  --line-height-h2: 40.8px;                  /* [css] h2 (2.55rem) */
  --font-size-lg: 18px;                      /* [css] base text (--cno-base-font-size) and large buttons */
  --line-height-lg: 24px;                    /* [css] base line height (--cno-base-line-height) */
  --font-size-md: 16px;                      /* [css] admin body text, medium and small buttons (1rem) */
  --line-height-md: 24px;                    /* [ours] admin body line height */
  --font-size-table: 15px;                   /* [ours] table body in the admin (dense, between 14 and 16) */
  --line-height-table: 22px;                 /* [ours] table body */
  --font-size-nav: 14px;                     /* [ours] sidebar items, uppercase 700 */
  --line-height-nav: 20px;                   /* [ours] sidebar items */
  --font-size-thead: 13px;                   /* [ours] table head, 800 */
  --line-height-thead: 20px;                 /* [ours] table head */
  --font-size-caption: 13px;                 /* [ours] code badges, captions */
  --line-height-caption: 18px;               /* [ours] captions */
  --font-weight-regular: 400;                /* [css] body */
  --font-weight-semibold: 600;               /* [css] subheads */
  --font-weight-bold: 700;                   /* [css] buttons, nav */
  --font-weight-thead: 800;                  /* [css] headings (extrabold file) */

  /* Radius */
  --radius-sm: 4px;                          /* [css] cards, inputs, code (--cno-border-radius) */
  --radius-btn-sm: 15px;                     /* [css] small pill button (.9375rem) */
  --radius-btn-md: 20px;                     /* [css] medium pill button (1.25rem) */
  --radius-btn-lg: 24px;                     /* [css] large pill button (1.5rem) */
  --radius-round: 50%;                       /* [ours] icon buttons, dots */

  /* Spacing */
  --space-1: 4px;                            /* [css] Tailwind 1 */
  --space-2: 8px;                            /* [css] Tailwind 2 */
  --space-3: 12px;                           /* [css] Tailwind 3 */
  --space-4: 16px;                           /* [css] Tailwind 4 */
  --space-5: 20px;                           /* [css] Tailwind 5 (footer side padding) */
  --space-6: 24px;                           /* [css] Tailwind 6 (paragraph margin 1.5rem) */
  --space-8: 32px;                           /* [css] Tailwind 8 */
  --space-10: 40px;                          /* [css] Tailwind 10 */
  --page-padding: 40px;                      /* [ours] main area padding */
  --card-padding: 24px;                      /* [ours] card padding */

  /* Elevation */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.12); /* [ours] the site uses almost no shadows; resting card (admin only) */
  --shadow-8: 0 6px 16px rgba(0, 0, 0, 0.16); /* [ours] menus and hovered tiles */
  --shadow-24: 0 16px 40px rgba(0, 0, 0, 0.3); /* [ours] dialogs */

  /* Motion */
  --duration-hover: 150ms;                   /* [css] --cno-transition-speed-default: colour and background fades */
  --duration-menu-item: 150ms;               /* [css] same as hover */
  --ease-standard: ease-in-out;              /* [css] transition timing on links and buttons */
  --transition-focus: 150ms ease-in-out;     /* [css] focus and underline transitions */

  /* Layout */
  --sidebar-width: 240px;                    /* [ours] admin left nav */
  --content-max-width: 1290px;               /* [css] --cno-main-content-max-width-wide (80.625rem) */
  --article-max-width: 790px;                /* [css] article column (max-w-search_result) */
  --nav-indicator-height: 4px;               /* [ours] active item bar */
  --header-height: 200px;                    /* [css] site header, collapsed (12.5rem) */
  --footer-padding: 20px;                    /* [css] footer side padding (px-5) */
}
```


# Components

Specs for the CNO admin components. Each lists the values; build with the tokens in `design-tokens.md`.

## Admin shell

Black left nav with the white CNO logo, the uppercase section links and a content area. Collapses to a top bar below 720px.

| Property | Value |
| --- | --- |
| Sidebar | fill var(--color-ink), width var(--sidebar-width), sticky full height; logo 160px wide, padding 24px |
| Item | var(--font-size-nav) / 700 uppercase, padding 12px 24px, hover white at 12%, 150ms |
| Active item | white at 18% fill and a 4px bar (var(--nav-indicator-height)) in var(--color-accent) |
| Main | padding var(--page-padding); on the white pages the main area is var(--color-surface) |
| Mobile | at 720px the sidebar becomes a 64px top bar; the arrow button opens the menu |

```css
.side{width:var(--sidebar-width);background:var(--color-ink);color:var(--color-text-on-dark)}
.side nav a{padding:12px 24px;font:700 var(--font-size-nav)/var(--line-height-nav) var(--font-family);text-transform:uppercase}
.side nav a[aria-current=page]{box-shadow:inset var(--nav-indicator-height) 0 0 var(--color-accent)}
```

## Page title and section rule

The site's heading style: extra bold, with a hairline rule under the title and under each section header.

| Property | Value |
| --- | --- |
| Title | var(--font-size-title) / var(--line-height-title), weight 800; var(--font-size-display) from the wide breakpoint on the site |
| Rule | 1px solid var(--color-border) with 12px padding above it (the site's front-page section headers use border-bottom gray-950) |
| Lead | sans (var(--font-family)) at var(--font-size-md); the admin uses no serif |

```css
h1{font:800 var(--font-size-title)/var(--line-height-title) var(--font-family);padding-bottom:12px;border-bottom:1px solid var(--color-border)}
```

## Buttons

The site's pill buttons (.cno-button): bold 16px text on a fully rounded fill. Subscribe orange is the one loud button.

| Property | Value |
| --- | --- |
| Large | height 44px, padding 0 28px, 18px / 700, radius var(--radius-btn-lg) |
| Medium | height 40px, padding 0 24px, 16px / 700, radius var(--radius-btn-md) |
| Small | height 32px, padding 0 20px, 16px / 700, radius var(--radius-btn-sm) |
| Fill | Subscribe: var(--color-accent) (public site only). The admin has no filled buttons: its actions are icon links (next component) |
| Motion | color and background fade 150ms ease-in-out (var(--transition-focus)) |
| Disabled | var(--color-disabled-bg) fill, var(--color-disabled-text) text |

```css
.cno-button{display:inline-block;height:40px;padding:0 24px;border:0;border-radius:var(--radius-btn-md);
  background:var(--color-accent);color:#fff;font:700 var(--font-size-md)/40px var(--font-family);
  transition:background-color var(--duration-hover) var(--ease-standard)}
.cno-button:hover{background:var(--color-ink)}
```

## Icon link

The admin's quiet action: a text link with a 18px icon, no fill or border. Used for Open the page, Copy link, Back to all pages and Open developer spec.

| Property | Value |
| --- | --- |
| Text | var(--font-size-md) / 600, var(--color-primary), no underline at rest |
| Icon | 18px Material icon in currentColor, 4px from the text; leading for navigation back / open, trailing for forward |
| Hover | var(--color-primary-hover) with a 2px-offset underline, 150ms |
| Focus | 2px outline var(--color-primary) |
| Where | cno-admin/admin/admin.css (.ilink) |

```css
.ilink{display:inline-flex;align-items:center;gap:var(--space-1);color:var(--color-primary);font:600 var(--font-size-md)/var(--line-height-md) var(--font-family)}
.ilink svg{width:18px;height:18px;fill:currentColor}
.ilink:hover{color:var(--color-primary-hover);text-decoration:underline;text-underline-offset:2px}
```

## Links

Public links are light blue and darken on hover; the admin tables use the dark blue with a faint underline.

| Property | Value |
| --- | --- |
| Site link | var(--color-link), no underline, hover var(--color-primary), 150ms (a{color:var(--cno-blue)}) |
| Admin link | var(--color-primary), underline var(--color-link-underline), full colour underline on hover |

```css
a{color:var(--color-link);text-decoration:none;transition:color var(--duration-hover) var(--ease-standard)}
a:hover{color:var(--color-primary)}
```

## Card and tiles

Flat white card with a hairline border. The admin home tiles lift to elevation 8 on hover.

| Property | Value |
| --- | --- |
| Card | var(--color-surface), 1px var(--color-border-light) border, radius var(--radius-sm), padding var(--card-padding) |
| Tile title | var(--font-size-lg) / 700 in var(--color-primary), hover var(--color-primary-hover) |
| Hover | var(--shadow-8), 150ms |

```css
.card{background:var(--color-surface);border:1px solid var(--color-border-light);border-radius:var(--radius-sm);padding:var(--card-padding)}
```

## List table with developer row

The Public page list: one row per page, a twisty that opens a dark-on-grey developer box with the files, tokens, AI files and skill, and an inline code viewer.

| Property | Value |
| --- | --- |
| Head cell | var(--font-size-thead) / 800 uppercase, 1px var(--color-border-light) rule |
| Body cell | var(--font-size-table), padding 8px, 51px rows |
| Twisty | 40px round button, Material ChevronRight 24px, turns 90deg while open (150ms) |
| Developer box | var(--color-page-bg), 1px var(--color-border), radius var(--radius-sm), padding 16px |
| Code viewer | opens inside the box: header with file name, copy and close; 12px monospace; max height 360px |

```css
table{border-collapse:collapse;width:100%}
th{font:800 var(--font-size-thead)/var(--line-height-thead) var(--font-family);text-transform:uppercase}
td{padding:8px;font-size:var(--font-size-table);border-bottom:1px solid var(--color-border-light)}
```

## Status chips

Small pill labels for state. Colour is the meaning; light fill with dark text.

| Property | Value |
| --- | --- |
| Shape | height 24px, padding 0 12px, radius var(--radius-btn-sm), 13px / 700 |
| Success | var(--color-success-bg) fill, var(--color-success-text) text |
| Warning | var(--color-warning-bg) fill, var(--color-ink) text |
| Error | var(--color-danger-bg) fill, var(--color-danger-text) text |

```css
.chip{display:inline-flex;align-items:center;height:24px;padding:0 12px;border-radius:var(--radius-btn-sm);font:700 13px var(--font-family)}
.chip--ok{background:var(--color-success-bg);color:var(--color-success-text)}
```

## Gift pill (share full article)

The site's small outlined pill button with a gift icon. It opens the Gift Articles popover. Shown only on paywalled articles to subscribers.

| Property | Value |
| --- | --- |
| Size | height 2rem, padding 0 1rem 0 .75rem, radius .9375rem (the site's .cno-button--small), gap .5rem; icon 1.125rem in currentColor |
| Text | ProximaNova 700, 1rem / 2rem, colour var(--cno-gray-100), no wrap |
| Border and fill | 1px solid var(--cno-gray-100), transparent; hover and open fill var(--cno-gray-1100) |
| Motion | color and background-color 150ms ease-in-out (var(--cno-transition-speed-default)) |
| Focus | 2px outline var(--cno-blue-dark), offset 2px |
| Phones | below 640px the label is hidden and the pill becomes a 1.875rem round icon button |
| Visibility | only when the article is paywalled and the viewer is a subscriber |
| Where | cno-article-share/share.css (.cno-pill) and share.js |

```css
.cno-pill{display:inline-flex;align-items:center;gap:.5rem;height:2rem;padding:0 1rem 0 .75rem;border:1px solid var(--cno-gray-100);
  border-radius:.9375rem;background:transparent;color:var(--cno-gray-100);font:700 1rem/2rem var(--cno-base-font-family);
  transition:color var(--cno-transition-speed-default) ease-in-out,background-color var(--cno-transition-speed-default) ease-in-out}
.cno-pill:hover,.cno-pill[aria-expanded=true]{background:var(--cno-gray-1100)}
```

## Share icon and popover

One round share icon replaces the icon row (option A). Hover or tap opens a popover with the share options. The gift pill opens the same popover with the gift URL.

| Property | Value |
| --- | --- |
| Icon button | 1.875rem round, fill var(--cno-gray-900), icon 1rem in var(--cno-gray-100) (the same disc as .social-link in .share-links--gray-black); hover and open fill var(--cno-gray-800) |
| Popover box | white, 1px solid var(--cno-gray-950), radius var(--cno-border-radius), padding 1rem 1.25rem .5rem, width 18rem (max 100vw - 2.5rem), shadow 0 .25rem .75rem rgba(0,0,0,.12) (the one shadow; the site has none), z-index 40 |
| Position | 0.625rem below the button, left-aligned; shifted left to stay 12px inside the viewport; a .75rem caret follows the button centre |
| Title and text | title ProximaNova 800 1rem / 1.5rem; text 400 1rem / 1.5rem in var(--cno-gray-500), .75rem below |
| Rows | flex, gap .75rem, padding .5rem 0, 600 1rem / 1.5rem, separated by 1px var(--cno-gray-1000); hover text var(--cno-blue-dark); 1.875rem grey disc icon (var(--cno-gray-900) fill, .9rem icon) |
| Open / close | hover (desktop) opens after 120ms and closes 250ms after leaving unless pinned by a click; click or tap toggles; Esc and outside click close; one open at a time |
| Phones | below 640px the share icon calls navigator.share({title, url}) and falls back to this popover |
| Where | cno-article-share/share.css (.cno-iconbtn, .cno-pop) and share.js |

```css
.cno-pop{position:absolute;top:calc(100% + .625rem);left:0;z-index:40;width:18rem;max-width:calc(100vw - 2.5rem);
  padding:1rem 1.25rem .5rem;background:var(--cno-white);border:1px solid var(--cno-gray-950);
  border-radius:var(--cno-border-radius);box-shadow:0 .25rem .75rem rgba(0,0,0,.12)}
.cno-pop__row{display:flex;align-items:center;gap:.75rem;padding:.5rem 0;font:600 1rem/1.5rem var(--cno-base-font-family)}
```

## Toast

Short confirmation, used for Link copied.

| Property | Value |
| --- | --- |
| Box | fixed, centred, 1.5rem from the bottom, padding .5rem 1.25rem, radius 1.25rem, fill var(--cno-gray-100), white text 700 1rem / 1.5rem |
| Motion | fades and rises 1rem over var(--cno-transition-speed-default); visible for 1.8s; role=status, aria-live=polite |

```css
.cno-toast{position:fixed;left:50%;bottom:1.5rem;padding:.5rem 1.25rem;border-radius:1.25rem;background:var(--cno-gray-100);color:var(--cno-white);font:700 1rem/1.5rem var(--cno-base-font-family)}
```

## Footer

The site footer is a light grey band (gray-1100) with generous padding.

| Property | Value |
| --- | --- |
| Bar | var(--color-surface-alt), padding 60px var(--footer-padding) 120px on the site |
| Text | var(--font-size-md) |

```css
footer{background:var(--color-surface-alt);padding:60px var(--footer-padding) 120px}
```
