From e97f148ef605a614588b02e5af93cff47a238adb Mon Sep 17 00:00:00 2001 From: Sam Rolfe Date: Wed, 26 Aug 2026 13:18:50 +1000 Subject: [PATCH] Initial commit: TooraSt-wikijs --- DESIGN.md | 270 ++++++++++++++++++++++++++++++ create-toora-pages.py | 173 ++++++++++++++++++++ toora-global.css | 373 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 816 insertions(+) create mode 100644 DESIGN.md create mode 100644 create-toora-pages.py create mode 100644 toora-global.css diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..5445ac7 --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,270 @@ +--- +version: alpha +name: Vodafone-design-analysis +description: An inspired interpretation of Vodafone's design language — a telecom super-brand whose web surface alternates between editorial photography hero bands with massive uppercase display headlines and clean white content bands, anchored by the company's signature scarlet red CTA and the proprietary Vodafone display sans set at impossibly heavy 800 weight. + +colors: + primary: "#e60000" + on-primary: "#ffffff" + ink: "#25282b" + body: "#7e7e7e" + mute: "#bebebe" + canvas: "#ffffff" + canvas-soft: "#f2f2f2" + on-dark: "#ffffff" + +typography: + display-hero: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 144px + fontWeight: 800 + lineHeight: 114px + letterSpacing: -1px + display-xxl: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 126px + fontWeight: 800 + lineHeight: 113px + letterSpacing: -1px + display-xl: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 90px + fontWeight: 800 + lineHeight: 84px + display-lg: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 48px + fontWeight: 300 + lineHeight: 52px + display-md: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 40px + fontWeight: 300 + lineHeight: 44px + display-sm: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 32px + fontWeight: 700 + lineHeight: 40px + display-xs: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 24px + fontWeight: 700 + lineHeight: 24px + eyebrow-uppercase: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 16px + fontWeight: 800 + lineHeight: 24px + body-lg: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 22px + fontWeight: 400 + lineHeight: 24px + body-md: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 18px + fontWeight: 400 + lineHeight: 28px + body-md-strong: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 18px + fontWeight: 600 + lineHeight: 28px + body-sm: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 16px + fontWeight: 400 + lineHeight: 20px + body-sm-strong: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 16px + fontWeight: 700 + lineHeight: 22px + caption: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 14px + fontWeight: 400 + lineHeight: 16px + caption-strong: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 14px + fontWeight: 700 + lineHeight: 21px + caption-uppercase: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 12px + fontWeight: 600 + lineHeight: 16px + letterSpacing: 0.5691px + button-md: + fontFamily: Vodafone, Vodafone Rg, Helvetica Neue, Arial, sans-serif + fontSize: 18px + fontWeight: 400 + lineHeight: 28px + +rounded: + none: 0px + xs: 1px + sm: 6px + card: 6px + pill-md: 32px + pill-lg: 60px + full: 9999px + +spacing: + xxs: 2px + xs: 4px + sm: 8px + md: 12px + lg: 16px + xl: 20px + 2xl: 24px + 3xl: 32px + +components: + nav-bar: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-dark}" + typography: "{typography.body-sm}" + padding: "{spacing.lg} {spacing.3xl}" + nav-link: + textColor: "{colors.on-dark}" + typography: "{typography.body-sm}" + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + borderColor: "{colors.primary}" + typography: "{typography.button-md}" + rounded: "{rounded.pill-lg}" + padding: "{spacing.md} {spacing.2xl}" + button-outline-red: + backgroundColor: "{colors.canvas}" + textColor: "{colors.primary}" + borderColor: "{colors.primary}" + typography: "{typography.button-md}" + rounded: "{rounded.pill-lg}" + padding: "{spacing.md} {spacing.2xl}" + button-outline-dark: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + borderColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.pill-lg}" + padding: "{spacing.md} {spacing.2xl}" + button-icon-circular: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + borderColor: "{colors.canvas}" + rounded: "{rounded.full}" + text-input: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + borderColor: "{colors.ink}" + typography: "{typography.body-sm}" + rounded: "{rounded.sm}" + padding: "{spacing.md} {spacing.lg}" + badge-chip: + backgroundColor: "{colors.canvas-soft}" + textColor: "{colors.ink}" + typography: "{typography.caption-strong}" + rounded: "{rounded.pill-md}" + padding: "{spacing.xs} {spacing.md}" + card-content: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + card-hero: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.display-sm}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + hero-band-dark: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-dark}" + typography: "{typography.display-hero}" + padding: "{spacing.3xl} {spacing.3xl}" + hero-band-red: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.display-xl}" + padding: "{spacing.3xl} {spacing.3xl}" + content-band-light: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.display-md}" + padding: "{spacing.3xl} {spacing.3xl}" + speechmark-logo-orb: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + rounded: "{rounded.sm}" + divider-on-dark: + borderColor: "{colors.on-dark}" + footer: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-dark}" + typography: "{typography.body-sm}" + padding: "{spacing.3xl} {spacing.3xl}" + + ex-pricing-tier: + description: "Default tier card. Mirrors card-content chrome with canvas-soft surface and a hairline border." + backgroundColor: "{colors.canvas-soft}" + textColor: "{colors.ink}" + borderColor: "{colors.mute}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + ex-pricing-tier-featured: + description: "Featured tier — polarity-flipped to ink with white text and white pill CTA inside." + backgroundColor: "{colors.ink}" + textColor: "{colors.on-primary}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + ex-product-selector: + description: "Tariff-tier picker — repurposed as the brand's plan selector with badge-chip chips inside the frame." + backgroundColor: "{colors.canvas-soft}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + ex-cart-drawer: + description: "Subscription summary — line items per tariff add-on, light hairline dividers." + backgroundColor: "{colors.canvas}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + item-divider: "{colors.mute}" + ex-app-shell-row: + description: "Sidebar nav row. Active state uses brand primary as a left-edge indicator bar." + backgroundColor: "{colors.canvas}" + activeIndicator: "{colors.primary}" + rounded: "{rounded.sm}" + padding: "{spacing.md} {spacing.lg}" + ex-data-table-cell: + description: "Default data-table cell chrome. Header uses caption-uppercase mono-style eyebrow; body uses body-sm." + headerBackground: "{colors.canvas-soft}" + headerTypography: "{typography.caption-uppercase}" + bodyTypography: "{typography.body-sm}" + cellPadding: "{spacing.md} {spacing.lg}" + rowBorder: "{colors.mute}" + ex-auth-form-card: + description: "Sign-in / sign-up card. Mirrors card-content chrome with text-input primitives inside." + backgroundColor: "{colors.canvas-soft}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + ex-modal-card: + description: "Modal dialog surface — same chrome as card-content; brand uses scrim, not card shadow." + backgroundColor: "{colors.canvas}" + rounded: "{rounded.card}" + padding: "{spacing.lg}" + ex-empty-state-card: + description: "Empty-state illustration frame on canvas-soft with generous interior padding." + backgroundColor: "{colors.canvas-soft}" + rounded: "{rounded.card}" + padding: "{spacing.3xl}" + captionTypography: "{typography.body-md}" + ex-toast: + description: "Toast notification surface — card-content shape with caption-strong body." + backgroundColor: "{colors.canvas}" + rounded: "{rounded.sm}" + padding: "{spacing.md} {spacing.lg}" + typography: "{typography.body-sm}" diff --git a/create-toora-pages.py b/create-toora-pages.py new file mode 100644 index 0000000..8773051 --- /dev/null +++ b/create-toora-pages.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 +"""Create Toora pages in Wiki.js via GraphQL API.""" +import json, sys + +JWT = sys.argv[1] if len(sys.argv) > 1 else "" + +pages = [ + { + "title": "Toora Home", + "path": "home", + "tags": ["home", "toora"], + "desc": "Household knowledge base home", + "content": ( + '
' + '
Household Knowledge Base
' + '

TOORA

' + '

Everything about our home — how things work, what we use, and how to fix it.

' + '
' + '
' + '' + '
' + '
📺 Entertainment
TV, streaming, music, and internet services for the home.
' + '
💡 Lights
Lighting controls, switches, and smart bulbs.
' + '
🍳 Kitchen
Composting system, appliances, and kitchen setup.
' + '
🌱 Garden
BBQ, fires, and outdoor living.
' + '
🐾 Pets
Dogs and fish — care routines and setups.
' + '
🧺 Laundry
Washer and drier — usage and maintenance.
' + '
' + ) + }, + { + "title": "Entertainment", + "path": "entertainment", + "tags": ["entertainment", "tv", "music", "internet"], + "desc": "TV, streaming, music and internet", + "content": ( + '
' + '
Section
' + '

ENTERTAINMENT

' + '

TV and streaming setup, music systems, and home internet.

' + '
' + '
' + '' + '
' + '
📺 TV & Streaming
Television setup, streaming services, subscriptions, and devices.
' + '
🎵 Music
Music systems, speakers, playlists, and audio setup.
' + '
🌐 Internet
Home internet, WiFi, router, and network services.
' + '
' + ) + }, + { + "title": "Lights", + "path": "lights", + "tags": ["lights", "switches"], + "desc": "Lighting controls and switches", + "content": ( + '
' + '
Section
' + '

LIGHTS

' + '

Lighting around the home — controls, switches, and smart options.

' + '
' + '
' + '' + '
' + '
🎛 Controlling
Smart controls, dimmers, timers, and automation.
' + '
🔘 Switches
Wall switches, smart switches, and wiring notes.
' + '
' + ) + }, + { + "title": "Kitchen", + "path": "kitchen", + "tags": ["kitchen", "compost", "appliances"], + "desc": "Composting and kitchen appliances", + "content": ( + '
' + '
Section
' + '

KITCHEN

' + '

Compost system and kitchen appliances.

' + '
' + '
' + '' + '
' + '
🌿 Compost
Composting system, what goes in, and maintenance.
' + '
🔌 Appliances
Kitchen appliances, usage, and care.
' + '
' + ) + }, + { + "title": "Garden", + "path": "garden", + "tags": ["garden", "bbq", "fires"], + "desc": "Outdoor living — BBQ and fires", + "content": ( + '
' + '
Section
' + '

GARDEN

' + '

Outdoor living — BBQ, fires, and garden setup.

' + '
' + '
' + '' + '
' + '
🍖 BBQ
BBQ setup, care, and usage.
' + '
🔥 Fires
Fire pits and outdoor heating.
' + '
' + ) + }, + { + "title": "Pets", + "path": "pets", + "tags": ["pets", "dogs", "fish"], + "desc": "Pet care — dogs and fish", + "content": ( + '
' + '
Section
' + '

PETS

' + '

Our pets and how we care for them.

' + '
' + '
' + '' + '
' + '
🐕 Dogs
Dog care, feeding, and routines.
' + '
🐟 Fish
Fish tank setup, feeding, and maintenance.
' + '
' + ) + }, + { + "title": "Laundry", + "path": "laundry", + "tags": ["laundry", "washer", "drier"], + "desc": "Washer and drier notes", + "content": ( + '
' + '
Section
' + '

LAUNDRY

' + '

Laundry appliances — washer and drier.

' + '
' + '
' + '' + '
' + '
🌀 Washer
Washing machine usage, programs, and maintenance.
' + '
🌬 Drier
Drier usage, settings, and lint care.
' + '
' + ) + } +] + +mutations = [] +for idx, p in enumerate(pages): + content_escaped = p['content'].replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n') + tag_str = json.dumps(p['tags']) + mutation = f''' p{idx}: pages {{ + create( + title: "{p['title']}" + path: "{p['path']}" + content: "{content_escaped}" + editor: "wysiwyg" + isPublished: true + isPrivate: false + locale: "en" + tags: {tag_str} + description: "{p['desc']}" + ) {{ + page {{ id path title }} + responseResult {{ succeeded message }} + }} + }}''' + mutations.append(mutation) + +query = 'mutation {\n' + '\n'.join(mutations) + '\n}' +payload = {"query": query} +print(json.dumps(payload)) +PYEOF \ No newline at end of file diff --git a/toora-global.css b/toora-global.css new file mode 100644 index 0000000..55e9500 --- /dev/null +++ b/toora-global.css @@ -0,0 +1,373 @@ +/* ════════════════════════════════════════ + TOORA Wiki Global Stylesheet + Vodafone-inspired design language + ════════════════════════════════════════ */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;800&display=swap'); + +/* ═══ DESIGN TOKENS ═══ */ +:root { + /* Colors */ + --primary: #e60000; + --on-primary: #ffffff; + --ink: #25282b; + --body: #7e7e7e; + --mute: #bebebe; + --canvas: #ffffff; + --canvas-soft: #f2f2f2; + --on-dark: #ffffff; + + /* Typography */ + --font-display: 'Inter', 'Vodafone', 'Helvetica Neue', Arial, sans-serif; + + /* Radius */ + --radius-none: 0px; + --radius-card: 6px; + --radius-pill-md: 32px; + --radius-pill-lg: 60px; + --radius-full: 9999px; + + /* Spacing */ + --space-xs: 4px; + --space-sm: 8px; + --space-md: 12px; + --space-lg: 16px; + --space-xl: 20px; + --space-2xl: 24px; + --space-3xl: 32px; +} + +/* ═══ RESET ═══ */ +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; + box-shadow: none !important; +} + +html { + background: var(--canvas); + color: var(--ink); + font-family: var(--font-display); + font-size: 16px; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +body { + background: var(--canvas); + color: var(--ink); + min-height: 100vh; +} + +/* ═══ TYPOGRAPHY ═══ */ +.display-hero { + font-size: clamp(64px, 10vw, 144px); + font-weight: 800; + line-height: 0.8; + letter-spacing: -1px; + text-transform: uppercase; + color: var(--ink); +} +.display-xxl { + font-size: clamp(56px, 8vw, 126px); + font-weight: 800; + line-height: 0.9; + letter-spacing: -1px; + text-transform: uppercase; + color: var(--ink); +} +.display-xl { + font-size: clamp(48px, 7vw, 90px); + font-weight: 800; + line-height: 0.94; + text-transform: uppercase; + color: var(--ink); +} +.display-lg { + font-size: 48px; + font-weight: 300; + line-height: 1.08; + color: var(--ink); +} +.display-md { + font-size: 40px; + font-weight: 300; + line-height: 1.1; + color: var(--ink); +} +.display-sm { + font-size: 32px; + font-weight: 700; + line-height: 1.25; + color: var(--ink); +} +.display-xs { + font-size: 24px; + font-weight: 700; + line-height: 1; + color: var(--ink); +} +.eyebrow { + font-size: 16px; + font-weight: 800; + text-transform: uppercase; + line-height: 1.5; + color: var(--primary); + letter-spacing: 0.5px; +} +.body-lg { + font-size: 22px; + font-weight: 400; + line-height: 1.4; + color: var(--ink); +} +.body-md { + font-size: 18px; + font-weight: 400; + line-height: 1.55; + color: var(--ink); +} +.body-sm { + font-size: 16px; + font-weight: 400; + line-height: 1.4; + color: var(--body); +} +.caption-uppercase { + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.57px; + color: var(--body); +} + +/* ═══ BUTTONS — Vodafone pill system ═══ */ +.btn, .vf-btn { + display: inline-flex; + align-items: center; + justify-content: center; + font-family: var(--font-display); + font-size: 18px; + font-weight: 400; + line-height: 1; + border-radius: var(--radius-pill-lg); + padding: var(--space-md) var(--space-2xl); + cursor: pointer; + text-decoration: none; + border: 1px solid; + transition: opacity 0.2s ease, transform 0.2s ease; + white-space: nowrap; +} +.btn:hover, .vf-btn:hover { opacity: 0.85; } +.btn:active, .vf-btn:active { transform: scale(0.98); } + +.vf-btn-primary { + background: var(--primary); + color: var(--on-primary); + border-color: var(--primary); +} +.vf-btn-outline-red { + background: var(--canvas); + color: var(--primary); + border-color: var(--primary); +} +.vf-btn-outline-dark { + background: var(--canvas); + color: var(--ink); + border-color: var(--ink); +} + +/* ═══ BADGES / CHIPS ═══ */ +.vf-badge { + display: inline-block; + background: var(--canvas-soft); + color: var(--ink); + font-family: var(--font-display); + font-size: 14px; + font-weight: 700; + border-radius: var(--radius-pill-md); + padding: var(--space-xs) var(--space-md); + line-height: 1.5; +} + +/* ═══ CARDS — 6px radius ═══ */ +.vf-card { + background: var(--canvas); + color: var(--ink); + border-radius: var(--radius-card); + padding: var(--space-lg); + border: 1px solid var(--mute); + transition: border-color 0.2s ease; +} +.vf-card:hover { border-color: var(--ink); } +.vf-card-soft { + background: var(--canvas-soft); + border: 1px solid var(--mute); +} +.vf-card-title { + font-size: 32px; + font-weight: 700; + line-height: 1.25; + color: var(--ink); + margin-bottom: var(--space-sm); +} +.vf-card-desc { + font-size: 16px; + font-weight: 400; + line-height: 1.4; + color: var(--body); +} + +/* ═══ HERO BANDS ═══ */ +.vf-hero-dark { + background: var(--ink); + color: var(--on-dark); + padding: var(--space-3xl); +} +.vf-hero-dark .display-hero, +.vf-hero-dark .display-xxl, +.vf-hero-dark .display-xl { color: var(--on-dark); } +.vf-hero-dark .eyebrow { color: var(--primary); } +.vf-hero-dark .body-lg { color: var(--on-dark); } + +.vf-hero-red { + background: var(--primary); + color: var(--on-primary); + padding: var(--space-3xl); +} +.vf-hero-red .display-hero, +.vf-hero-red .display-xxl, +.vf-hero-red .display-xl { color: var(--on-primary); } + +.vf-band-light { + background: var(--canvas); + color: var(--ink); + padding: var(--space-3xl); +} + +/* ═══ NAV BAR ═══ */ +.vf-nav { + background: var(--ink); + color: var(--on-dark); + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--space-lg) var(--space-3xl); + position: sticky; + top: 0; + z-index: 100; +} +.vf-nav .vf-nav-brand { + font-family: var(--font-display); + font-size: 24px; + font-weight: 800; + color: var(--on-dark); + text-transform: uppercase; + letter-spacing: 0.5px; + text-decoration: none; +} +.vf-nav .vf-nav-brand .speechmark { + display: inline-block; + background: var(--primary); + color: var(--on-primary); + border-radius: var(--radius-card); + width: 32px; + height: 32px; + text-align: center; + line-height: 32px; + font-size: 20px; + margin-right: 8px; + font-weight: 800; +} +.vf-nav .vf-nav-links { + display: flex; + gap: var(--space-2xl); + list-style: none; + margin: 0; + padding: 0; +} +.vf-nav .vf-nav-links a { + font-family: var(--font-display); + font-size: 16px; + font-weight: 400; + color: var(--on-dark); + text-decoration: none; + opacity: 0.85; + transition: opacity 0.2s; +} +.vf-nav .vf-nav-links a:hover { opacity: 1; } + +/* ═══ GRIDS ═══ */ +.vf-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: var(--space-lg); +} +.vf-grid-3 { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--space-lg); +} + +/* ═══ SECTION LABEL ═══ */ +.vf-section-label { + font-size: 16px; + font-weight: 800; + text-transform: uppercase; + color: var(--primary); + margin-bottom: var(--space-xl); + display: block; +} + +/* ═══ FOOTER ═══ */ +.vf-footer { + background: var(--ink); + color: var(--on-dark); + padding: var(--space-3xl); + text-align: center; + font-size: 14px; + opacity: 0.85; +} + +/* ═══ WIKI.JS OVERRIDES ═══ */ +body, .content, .page-content, .main-panel { + background: var(--canvas) !important; + color: var(--ink) !important; +} +h1, h2, h3, h4, h5, h6 { + color: var(--ink) !important; + font-family: var(--font-display) !important; +} +a { + color: var(--primary) !important; +} +.wiki-logo img, .navbar-brand img, [class*="logo"] img { + display: none !important; +} +.wiki-logo:after, .navbar-brand:after { + content: "TOORA"; + font-family: 'Inter', 'Helvetica Neue', Arial, sans-serif; + font-size: 20px; + font-weight: 800; + letter-spacing: 0.5px; + text-transform: uppercase; + color: #ffffff; + white-space: nowrap; +} +.navbar, .navbar-default, .navbar-primary { + background: var(--ink) !important; + border-bottom: none !important; + box-shadow: none !important; +} + +/* ═══ RESPONSIVE ═══ */ +@media (max-width: 1024px) { + .vf-grid-3 { grid-template-columns: 1fr 1fr; } +} +@media (max-width: 768px) { + .vf-grid, .vf-grid-3 { grid-template-columns: 1fr; } + .vf-nav .vf-nav-links { display: none; } + .display-lg { font-size: 36px; } + .display-md { font-size: 32px; } + .display-sm { font-size: 28px; } +}