Canada's National Observer
CNO Developer System
Section 05 — Components

Components

The components of the CNO admin as live specimens with their spec and starter CSS. The specimens are built from the tokens.

Admin shellshell

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


SystemPublic
PropertyValue
Sidebarfill var(--color-ink), width var(--sidebar-width), sticky full height; logo 160px wide, padding 24px
Itemvar(--font-size-nav) / 700 uppercase, padding 12px 24px, hover white at 12%, 150ms
Active itemwhite at 18% fill and a 4px bar (var(--nav-indicator-height)) in var(--color-accent)
Mainpadding var(--page-padding); on the white pages the main area is var(--color-surface)
Mobileat 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 ruletitle

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

Public

PropertyValue
Titlevar(--font-size-title) / var(--line-height-title), weight 800; var(--font-size-display) from the wide breakpoint on the site
Rule1px solid var(--color-border) with 12px padding above it (the site's front-page section headers use border-bottom gray-950)
Leadsans (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)}
Buttonsbuttons

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

LargeMediumSmallAdminDisabled
PropertyValue
Largeheight 44px, padding 0 28px, 18px / 700, radius var(--radius-btn-lg)
Mediumheight 40px, padding 0 24px, 16px / 700, radius var(--radius-btn-md)
Smallheight 32px, padding 0 20px, 16px / 700, radius var(--radius-btn-sm)
FillSubscribe: var(--color-accent) (public site only). The admin has no filled buttons: its actions are icon links (next component)
Motioncolor and background fade 150ms ease-in-out (var(--transition-focus))
Disabledvar(--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)}
Card and tilescard

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

SystemType, colour, components, tokens, AI files./admin/system
PropertyValue
Cardvar(--color-surface), 1px var(--color-border-light) border, radius var(--radius-sm), padding var(--card-padding)
Tile titlevar(--font-size-lg) / 700 in var(--color-primary), hover var(--color-primary-hover)
Hovervar(--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 rowtable

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.

PageFile
▸Searchsearch-2.html
PropertyValue
Head cellvar(--font-size-thead) / 800 uppercase, 1px var(--color-border-light) rule
Body cellvar(--font-size-table), padding 8px, 51px rows
Twisty40px round button, Material ChevronRight 24px, turns 90deg while open (150ms)
Developer boxvar(--color-page-bg), 1px var(--color-border), radius var(--radius-sm), padding 16px
Code vieweropens 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 chipsstatus

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

LiveDraftError
PropertyValue
Shapeheight 24px, padding 0 12px, radius var(--radius-btn-sm), 13px / 700
Successvar(--color-success-bg) fill, var(--color-success-text) text
Warningvar(--color-warning-bg) fill, var(--color-ink) text
Errorvar(--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)share-gift

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

Share full article
PropertyValue
Sizeheight 2rem, padding 0 1rem 0 .75rem, radius .9375rem (the site's .cno-button--small), gap .5rem; icon 1.125rem in currentColor
TextProximaNova 700, 1rem / 2rem, colour var(--cno-gray-100), no wrap
Border and fill1px solid var(--cno-gray-100), transparent; hover and open fill var(--cno-gray-1100)
Motioncolor and background-color 150ms ease-in-out (var(--cno-transition-speed-default))
Focus2px outline var(--cno-blue-dark), offset 2px
Phonesbelow 640px the label is hidden and the pill becomes a 1.875rem round icon button
Visibilityonly when the article is paywalled and the viewer is a subscriber
Wherecno-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 popovershare-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.

Share Options

Share a link that only subscribers can access.

  • Copy link
  • Email
  • Bluesky
  • LinkedIn
  • Reddit
PropertyValue
Icon button1.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 boxwhite, 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
Position0.625rem below the button, left-aligned; shifted left to stay 12px inside the viewport; a .75rem caret follows the button centre
Title and texttitle ProximaNova 800 1rem / 1.5rem; text 400 1rem / 1.5rem in var(--cno-gray-500), .75rem below
Rowsflex, 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 / closehover (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
Phonesbelow 640px the share icon calls navigator.share({title, url}) and falls back to this popover
Wherecno-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)}
Toasttoast

Short confirmation, used for Link copied.

Link copied
PropertyValue
Boxfixed, centred, 1.5rem from the bottom, padding .5rem 1.25rem, radius 1.25rem, fill var(--cno-gray-100), white text 700 1rem / 1.5rem
Motionfades 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)}