🚧 Working on theming

This commit is contained in:
Manuel Cillero 2023-11-01 19:40:37 +01:00
parent 63299dc3e0
commit a6b6130f4f
15 changed files with 436 additions and 207 deletions

View file

@ -18,7 +18,7 @@ impl ModuleTrait for Bootsier {
} }
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
service_for_static_files!(scfg, "/bootsier", bootsier); service_for_static_files!(scfg, bootsier => "/bootsier");
} }
} }
@ -47,36 +47,23 @@ impl ThemeTrait for Bootsier {
"side-menu", "side-menu",
"content" "content"
] { ] {
@if let Some(content) = page.prepare_region(region) { (self.prepare_region(page, region))
#(region) class="region" { (content) }
}
} }
} }
}, },
_ => { _ => html! {
let header = page.prepare_region("header"); body class=[page.body_classes().get()] {
let nav_branding = page.prepare_region("nav_branding"); (self.prepare_region(page, "header"))
let nav_main = page.prepare_region("nav_main"); (self.prepare_region(page, "nav_branding"))
let nav_additional = page.prepare_region("nav_additional"); (self.prepare_region(page, "nav_main"))
let breadcrumb = page.prepare_region("breadcrumb"); (self.prepare_region(page, "nav_additional"))
let content = page.prepare_region("content"); (self.prepare_region(page, "breadcrumb"))
let sidebar_first = page.prepare_region("sidebar_first"); (self.prepare_region(page, "content"))
let sidebar_second = page.prepare_region("sidebar_second"); (self.prepare_region(page, "sidebar_first"))
let footer = page.prepare_region("footer"); (self.prepare_region(page, "sidebar_second"))
html! { (self.prepare_region(page, "footer"))
body class=[page.body_classes().get()] {
(header.unwrap_or_default())
(nav_branding.unwrap_or_default())
(nav_main.unwrap_or_default())
(nav_additional.unwrap_or_default())
(breadcrumb.unwrap_or_default())
(content.unwrap_or_default())
(sidebar_first.unwrap_or_default())
(sidebar_second.unwrap_or_default())
(footer.unwrap_or_default())
}
} }
} },
} }
} }
@ -92,7 +79,52 @@ impl ThemeTrait for Bootsier {
.with_version("5.1.3") .with_version("5.1.3")
.with_weight(-99), .with_weight(-99),
)) ))
.alter_context(ContextOp::AddBaseAssets); .alter_context(ContextOp::AddBaseAssets)
.alter_context(ContextOp::AddStyleSheet(
StyleSheet::at("/bootsier/css/styles.css")
.with_version("0.0.1"),
));
}
#[rustfmt::skip]
fn before_prepare_component(
&self,
component: &mut dyn ComponentTrait,
_cx: &mut Context,
) {
match component.handle() {
COMPONENT_BASE_HEADING => {
let h = component_as_mut::<Heading>(component);
let original = h.display().to_string();
h.alter_classes(
ClassesOp::SetDefault,
match h.display() {
HeadingDisplay::ExtraLarge => "display-1",
HeadingDisplay::XxLarge => "display-2",
HeadingDisplay::XLarge => "display-3",
HeadingDisplay::Large => "display-4",
HeadingDisplay::Medium => "display-5",
_ => original.as_str(),
},
);
}
COMPONENT_BASE_PARAGRAPH => {
let p = component_as_mut::<Paragraph>(component);
let original = p.font_size().to_string();
p.alter_classes(
ClassesOp::SetDefault,
match p.font_size() {
FontSize::ExtraLarge => "fs-1",
FontSize::XxLarge => "fs-2",
FontSize::XLarge => "fs-3",
FontSize::Large => "fs-4",
FontSize::Medium => "fs-5",
_ => original.as_str(),
},
);
}
_ => {}
}
} }
fn render_component(&self, component: &dyn ComponentTrait, cx: &mut Context) -> Option<Markup> { fn render_component(&self, component: &dyn ComponentTrait, cx: &mut Context) -> Option<Markup> {

View file

@ -0,0 +1,7 @@
/* OVERRIDE COMPONENT STYLES */
/* Heading component */
.pt-heading__subtitle {
margin-top: calc(-1 * var(--pt-gap-0-5));
}

View file

@ -16,7 +16,7 @@ impl ModuleTrait for Bulmix {
} }
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
service_for_static_files!(scfg, "/bulmix", bulmix); service_for_static_files!(scfg, bulmix => "/bulmix");
} }
} }
@ -50,32 +50,30 @@ impl ThemeTrait for Bulmix {
} }
COMPONENT_BASE_HEADING => { COMPONENT_BASE_HEADING => {
let h = component_as_mut::<Heading>(component); let h = component_as_mut::<Heading>(component);
h.alter_classes( match h.display() {
ClassesOp::SetDefault, HeadingDisplay::Subtitle => h.alter_classes(
match h.display() { ClassesOp::SetDefault, "subtitle"
HeadingDisplay::XxLarge => "title is-1", ),
HeadingDisplay::Large => "title is-2", _ => h.alter_classes(
HeadingDisplay::Medium => "title is-3", ClassesOp::AddDefault, "title"
HeadingDisplay::Small => "title is-4", ),
HeadingDisplay::XxSmall => "title is-5", };
HeadingDisplay::Normal => "title",
HeadingDisplay::Subtitle => "subtitle",
},
);
} }
COMPONENT_BASE_PARAGRAPH => { COMPONENT_BASE_PARAGRAPH => {
let p = component_as_mut::<Paragraph>(component); let p = component_as_mut::<Paragraph>(component);
let original = concat_string!("block ", p.font_size().to_string());
p.alter_classes( p.alter_classes(
ClassesOp::SetDefault, ClassesOp::SetDefault,
match p.display() { match p.font_size() {
ParagraphDisplay::XxLarge => "is-size-2", FontSize::ExtraLarge => "block is-size-1",
ParagraphDisplay::Large => "is-size-3", FontSize::XxLarge => "block is-size-2",
ParagraphDisplay::Medium => "is-size-4", FontSize::XLarge => "block is-size-3",
ParagraphDisplay::Small => "is-size-5", FontSize::Large => "block is-size-4",
ParagraphDisplay::XxSmall => "is-size-6", FontSize::Medium => "block is-size-5",
ParagraphDisplay::Normal => "", _ => original.as_str(),
}, },
); );
} }
_ => {} _ => {}
} }
@ -84,14 +82,18 @@ impl ThemeTrait for Bulmix {
fn render_component( fn render_component(
&self, &self,
component: &dyn ComponentTrait, component: &dyn ComponentTrait,
_cx: &mut Context, cx: &mut Context,
) -> Option<Markup> { ) -> Option<Markup> {
match component.handle() { match component.handle() {
COMPONENT_BASE_ICON => { COMPONENT_BASE_ICON => {
let icon = component_as_ref::<Icon>(component); let icon = component_as_ref::<Icon>(component);
if icon.icon_name().is_empty() {
return None
};
cx.set_param::<bool>(PARAM_BASE_INCLUDE_ICONS, true);
Some(html! { Some(html! {
span class="icon" { span class="icon" {
i class=[icon.classes().get()] {}; i class=[icon.classes().get()] {}
} }
}) })
} }

View file

@ -22,7 +22,7 @@ impl ModuleTrait for HomeDemo {
} }
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
service_for_static_files!(scfg, "/homedemo", homedemo); service_for_static_files!(scfg, homedemo => "/homedemo");
scfg.route("/", service::web::get().to(demo)); scfg.route("/", service::web::get().to(demo));
} }
} }
@ -62,7 +62,7 @@ fn hello_world() -> Wrapper {
&config::SETTINGS.app.name, &config::SETTINGS.app.name,
), ),
)) ))
.with_display(ParagraphDisplay::Small), .with_font_size(FontSize::Medium),
) )
.add_component(Paragraph::translated( .add_component(Paragraph::translated(
L10n::t("hello_powered", &LOCALES_HOMEDEMO).with_arg( L10n::t("hello_powered", &LOCALES_HOMEDEMO).with_arg(
@ -114,7 +114,7 @@ fn welcome() -> Wrapper {
) )
.add_component( .add_component(
Paragraph::translated(L10n::t("welcome_text1", &LOCALES_HOMEDEMO)) Paragraph::translated(L10n::t("welcome_text1", &LOCALES_HOMEDEMO))
.with_display(ParagraphDisplay::Small), .with_font_size(FontSize::Medium),
) )
.add_component(Paragraph::translated(L10n::t( .add_component(Paragraph::translated(L10n::t(
"welcome_text2", "welcome_text2",
@ -138,7 +138,7 @@ fn about_pagetop() -> Wrapper {
.add_component(Heading::h2(L10n::t("pagetop_title", &LOCALES_HOMEDEMO))) .add_component(Heading::h2(L10n::t("pagetop_title", &LOCALES_HOMEDEMO)))
.add_component( .add_component(
Paragraph::translated(L10n::t("pagetop_text1", &LOCALES_HOMEDEMO)) Paragraph::translated(L10n::t("pagetop_text1", &LOCALES_HOMEDEMO))
.with_display(ParagraphDisplay::Small), .with_font_size(FontSize::Medium),
) )
.add_component(Paragraph::translated(L10n::t( .add_component(Paragraph::translated(L10n::t(
"pagetop_text2", "pagetop_text2",
@ -174,7 +174,7 @@ fn promo_pagetop() -> Wrapper {
), ),
), ),
) )
.with_display(ParagraphDisplay::Small), .with_font_size(FontSize::Medium),
), ),
) )
.add_item( .add_item(
@ -205,7 +205,7 @@ fn reporting_issues() -> Wrapper {
))) )))
.add_component( .add_component(
Paragraph::translated(L10n::t("report_problems_text1", &LOCALES_HOMEDEMO)) Paragraph::translated(L10n::t("report_problems_text1", &LOCALES_HOMEDEMO))
.with_display(ParagraphDisplay::Small), .with_font_size(FontSize::Medium),
) )
.add_component(Paragraph::translated(L10n::t( .add_component(Paragraph::translated(L10n::t(
"report_problems_text2", "report_problems_text2",

View file

@ -1,5 +1,5 @@
body.default-homepage span.app-name { body.default-homepage span.app-name {
font-weight: bold; font-weight: 400;
color: inherit; color: inherit;
} }

View file

@ -49,6 +49,8 @@ pub(crate) fn add_base_assets(cx: &mut Context) {
)); ));
} }
// *************************************************************************************************
#[rustfmt::skip] #[rustfmt::skip]
#[derive(Default)] #[derive(Default)]
pub enum BreakPoint { pub enum BreakPoint {
@ -79,6 +81,43 @@ impl ToString for BreakPoint {
} }
} }
// *************************************************************************************************
#[derive(Default)]
pub enum FontSize {
ExtraLarge,
XxLarge,
XLarge,
Large,
Medium,
#[default]
Normal,
Small,
XSmall,
XxSmall,
ExtraSmall,
}
#[rustfmt::skip]
impl ToString for FontSize {
fn to_string(&self) -> String {
match self {
FontSize::ExtraLarge => "pt-fs__x3l".to_string(),
FontSize::XxLarge => "pt-fs__x2l".to_string(),
FontSize::XLarge => "pt-fs__xl".to_string(),
FontSize::Large => "pt-fs__l".to_string(),
FontSize::Medium => "pt-fs__m".to_string(),
FontSize::Normal => "".to_string(),
FontSize::Small => "pt-fs__s".to_string(),
FontSize::XSmall => "pt-fs__xs".to_string(),
FontSize::XxSmall => "pt-fs__x2s".to_string(),
FontSize::ExtraSmall => "pt-fs__x3s".to_string(),
}
}
}
// *************************************************************************************************
mod html; mod html;
pub use html::{Html, COMPONENT_BASE_HTML}; pub use html::{Html, COMPONENT_BASE_HTML};
@ -95,7 +134,7 @@ pub use icon::{Icon, COMPONENT_BASE_ICON};
mod heading; mod heading;
pub use heading::{Heading, HeadingDisplay, HeadingType, COMPONENT_BASE_HEADING}; pub use heading::{Heading, HeadingDisplay, HeadingType, COMPONENT_BASE_HEADING};
mod paragraph; mod paragraph;
pub use paragraph::{Paragraph, ParagraphDisplay, COMPONENT_BASE_PARAGRAPH}; pub use paragraph::{Paragraph, COMPONENT_BASE_PARAGRAPH};
mod anchor; mod anchor;
pub use anchor::{Anchor, AnchorTarget, AnchorType, COMPONENT_BASE_ANCHOR}; pub use anchor::{Anchor, AnchorTarget, AnchorType, COMPONENT_BASE_ANCHOR};
mod image; mod image;

View file

@ -15,16 +15,31 @@ pub enum HeadingType {
#[derive(Default)] #[derive(Default)]
pub enum HeadingDisplay { pub enum HeadingDisplay {
#[default] ExtraLarge,
Normal,
XxLarge, XxLarge,
XLarge,
Large, Large,
Medium, Medium,
Small, #[default]
XxSmall, Normal,
Subtitle, Subtitle,
} }
#[rustfmt::skip]
impl ToString for HeadingDisplay {
fn to_string(&self) -> String {
match self {
HeadingDisplay::ExtraLarge => "pt-heading__title-x3l".to_string(),
HeadingDisplay::XxLarge => "pt-heading__title-x2l".to_string(),
HeadingDisplay::XLarge => "pt-heading__title-xl".to_string(),
HeadingDisplay::Large => "pt-heading__title-l".to_string(),
HeadingDisplay::Medium => "pt-heading__title-m".to_string(),
HeadingDisplay::Normal => "".to_string(),
HeadingDisplay::Subtitle => "pt-heading__subtitle".to_string(),
}
}
}
#[rustfmt::skip] #[rustfmt::skip]
#[derive(Default)] #[derive(Default)]
pub struct Heading { pub struct Heading {
@ -35,7 +50,6 @@ pub struct Heading {
heading_type: HeadingType, heading_type: HeadingType,
text : OptionTranslated, text : OptionTranslated,
display : HeadingDisplay, display : HeadingDisplay,
template : String,
} }
impl ComponentTrait for Heading { impl ComponentTrait for Heading {
@ -151,28 +165,14 @@ impl Heading {
#[rustfmt::skip] #[rustfmt::skip]
#[fn_builder] #[fn_builder]
pub fn alter_display(&mut self, display: HeadingDisplay) -> &mut Self { pub fn alter_display(&mut self, display: HeadingDisplay) -> &mut Self {
self.alter_classes( self.classes.alter_value(
ClassesOp::SetDefault, ClassesOp::Replace(self.display.to_string()),
match display { display.to_string(),
HeadingDisplay::XxLarge => "display-2",
HeadingDisplay::Large => "display-3",
HeadingDisplay::Medium => "display-4",
HeadingDisplay::Small => "display-5",
HeadingDisplay::XxSmall => "display-6",
HeadingDisplay::Normal => "",
HeadingDisplay::Subtitle => "",
},
); );
self.display = display; self.display = display;
self self
} }
#[fn_builder]
pub fn alter_template(&mut self, template: &str) -> &mut Self {
self.template = template.to_owned();
self
}
// Paragraph GETTERS. // Paragraph GETTERS.
pub fn classes(&self) -> &OptionClasses { pub fn classes(&self) -> &OptionClasses {
@ -190,8 +190,4 @@ impl Heading {
pub fn display(&self) -> &HeadingDisplay { pub fn display(&self) -> &HeadingDisplay {
&self.display &self.display
} }
pub fn template(&self) -> &str {
self.template.as_str()
}
} }

View file

@ -29,8 +29,10 @@ impl ComponentTrait for Icon {
} }
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
if self.icon_name().is_empty() {
return PrepareMarkup::None
}
cx.set_param::<bool>(PARAM_BASE_INCLUDE_ICONS, true); cx.set_param::<bool>(PARAM_BASE_INCLUDE_ICONS, true);
PrepareMarkup::With(html! { i class=[self.classes().get()] {} }) PrepareMarkup::With(html! { i class=[self.classes().get()] {} })
} }
} }

View file

@ -2,17 +2,6 @@ use crate::prelude::*;
new_handle!(COMPONENT_BASE_PARAGRAPH); new_handle!(COMPONENT_BASE_PARAGRAPH);
#[derive(Default)]
pub enum ParagraphDisplay {
#[default]
Normal,
XxLarge,
Large,
Medium,
Small,
XxSmall,
}
#[rustfmt::skip] #[rustfmt::skip]
#[derive(Default)] #[derive(Default)]
pub struct Paragraph { pub struct Paragraph {
@ -21,8 +10,7 @@ pub struct Paragraph {
id : OptionId, id : OptionId,
classes : OptionClasses, classes : OptionClasses,
stuff : ArcComponents, stuff : ArcComponents,
display : ParagraphDisplay, font_size : FontSize,
template : String,
} }
impl ComponentTrait for Paragraph { impl ComponentTrait for Paragraph {
@ -112,25 +100,12 @@ impl Paragraph {
#[rustfmt::skip] #[rustfmt::skip]
#[fn_builder] #[fn_builder]
pub fn alter_display(&mut self, display: ParagraphDisplay) -> &mut Self { pub fn alter_font_size(&mut self, font_size: FontSize) -> &mut Self {
self.alter_classes( self.classes.alter_value(
ClassesOp::SetDefault, ClassesOp::Replace(self.font_size.to_string()),
match display { font_size.to_string(),
ParagraphDisplay::XxLarge => "fs-2",
ParagraphDisplay::Large => "fs-3",
ParagraphDisplay::Medium => "fs-4",
ParagraphDisplay::Small => "fs-5",
ParagraphDisplay::XxSmall => "fs-6",
ParagraphDisplay::Normal => "",
},
); );
self.display = display; self.font_size = font_size;
self
}
#[fn_builder]
pub fn alter_template(&mut self, template: &str) -> &mut Self {
self.template = template.to_owned();
self self
} }
@ -144,11 +119,7 @@ impl Paragraph {
&self.stuff &self.stuff
} }
pub fn display(&self) -> &ParagraphDisplay { pub fn font_size(&self) -> &FontSize {
&self.display &self.font_size
}
pub fn template(&self) -> &str {
self.template.as_str()
} }
} }

View file

@ -1,6 +1,6 @@
use crate::core::component::{ComponentTrait, Context}; use crate::core::component::{ComponentTrait, Context};
use crate::core::module::ModuleTrait; use crate::core::module::ModuleTrait;
use crate::html::{html, Favicon, Markup}; use crate::html::{html, Favicon, Markup, OptionId};
use crate::locale::L10n; use crate::locale::L10n;
use crate::response::page::Page; use crate::response::page::Page;
use crate::{concat_string, config}; use crate::{concat_string, config};
@ -20,16 +20,27 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
] ]
} }
fn prepare_region(&self, page: &mut Page, region: &str) -> Markup {
let render_region = page.components_in(region).prepare(page.context());
if render_region.is_empty() {
html! {}
} else {
let id = OptionId::with(region).get().unwrap();
let id_inner = concat_string!(id, "__inner");
html! {
div id=(id) class="pt-region" {
div id=(id_inner) class="pt-region__inner" {
(render_region)
}
}
}
}
}
#[allow(unused_variables)] #[allow(unused_variables)]
fn before_prepare_body(&self, page: &mut Page) {} fn before_prepare_body(&self, page: &mut Page) {}
fn prepare_body(&self, page: &mut Page) -> Markup { fn prepare_body(&self, page: &mut Page) -> Markup {
let header = page.prepare_region("header");
let pagetop = page.prepare_region("pagetop");
let content = page.prepare_region("content");
let sidebar = page.prepare_region("sidebar");
let footer = page.prepare_region("footer");
let skip_to = concat_string!("#", page.skip_to().get().unwrap_or("content".to_owned())); let skip_to = concat_string!("#", page.skip_to().get().unwrap_or("content".to_owned()));
html! { html! {
@ -41,11 +52,15 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
} }
div class="pt-body__wrapper" { div class="pt-body__wrapper" {
div class="pt-body__regions" { div class="pt-body__regions" {
(header.unwrap_or_default()) (self.prepare_region(page, "header"))
(pagetop.unwrap_or_default()) (self.prepare_region(page, "pagetop"))
(content.unwrap_or_default()) div class="pt-content" {
(sidebar.unwrap_or_default()) div class="pt-content__wrapper" {
(footer.unwrap_or_default()) (self.prepare_region(page, "content"))
(self.prepare_region(page, "sidebar"))
}
}
(self.prepare_region(page, "footer"))
} }
} }
} }

View file

@ -72,7 +72,7 @@ impl OptionClasses {
} }
ClassesOp::Replace(classes_to_replace) => { ClassesOp::Replace(classes_to_replace) => {
let mut pos = self.0.len(); let mut pos = self.0.len();
let mut class_type = ClassType::User; let mut class_type = ClassType::Default;
let replace: Vec<&str> = classes_to_replace.split_ascii_whitespace().collect(); let replace: Vec<&str> = classes_to_replace.split_ascii_whitespace().collect();
for class in replace { for class in replace {
if let Some(replace_pos) = self.0.iter().position(|(c, _)| c.eq(class)) { if let Some(replace_pos) = self.0.iter().position(|(c, _)| c.eq(class)) {

View file

@ -1,5 +1,5 @@
use crate::base::action::page::{run_actions_after_prepare_body, run_actions_before_prepare_body}; use crate::base::action::page::{run_actions_after_prepare_body, run_actions_before_prepare_body};
use crate::core::component::{ArcComponent, ComponentTrait}; use crate::core::component::{ArcComponent, ArcComponents as RegionComponents, ComponentTrait};
use crate::core::component::{Context, ContextOp}; use crate::core::component::{Context, ContextOp};
use crate::core::theme::ComponentsRegions; use crate::core::theme::ComponentsRegions;
use crate::html::{html, Markup, DOCTYPE}; use crate::html::{html, Markup, DOCTYPE};
@ -21,8 +21,8 @@ pub struct Page {
favicon : Option<Favicon>, favicon : Option<Favicon>,
context : Context, context : Context,
body_classes: OptionClasses, body_classes: OptionClasses,
regions : ComponentsRegions,
skip_to : OptionId, skip_to : OptionId,
regions : ComponentsRegions,
template : String, template : String,
} }
@ -37,8 +37,8 @@ impl Page {
favicon : None, favicon : None,
context : Context::new(request), context : Context::new(request),
body_classes: OptionClasses::new(), body_classes: OptionClasses::new(),
regions : ComponentsRegions::new(),
skip_to : OptionId::new(), skip_to : OptionId::new(),
regions : ComponentsRegions::new(),
template : "default".to_owned(), template : "default".to_owned(),
} }
} }
@ -88,14 +88,14 @@ impl Page {
} }
#[fn_builder] #[fn_builder]
pub fn alter_in(&mut self, region: &'static str, component: impl ComponentTrait) -> &mut Self { pub fn alter_skip_to(&mut self, id: impl Into<String>) -> &mut Self {
self.regions.add_in(region, ArcComponent::with(component)); self.skip_to.alter_value(id);
self self
} }
#[fn_builder] #[fn_builder]
pub fn alter_skip_to(&mut self, id: impl Into<String>) -> &mut Self { pub fn alter_in(&mut self, region: &'static str, component: impl ComponentTrait) -> &mut Self {
self.skip_to.alter_value(id); self.regions.add_in(region, ArcComponent::with(component));
self self
} }
@ -139,6 +139,10 @@ impl Page {
&self.skip_to &self.skip_to
} }
pub fn components_in(&self, region: &str) -> RegionComponents {
self.regions.get_components(self.context.theme(), region)
}
pub fn template(&self) -> &str { pub fn template(&self) -> &str {
self.template.as_str() self.template.as_str()
} }
@ -178,20 +182,4 @@ impl Page {
} }
}) })
} }
pub fn prepare_region(&mut self, region: &str) -> Option<Markup> {
let render = self
.regions
.get_components(self.context.theme(), region)
.prepare(self.context());
if render.is_empty() {
None
} else {
Some(html! {
div id=[OptionId::with(region).get()] class="region" {
(render)
}
})
}
}
} }

View file

@ -5,40 +5,87 @@ html {
body { body {
margin: 0; margin: 0;
font-family: var(--pt-font-family); font-family: var(--pt-font-family);
font-size: var(--pt-font-size-base); font-size: var(--pt-fs--base);
font-weight: var(--pt-font-weight); font-weight: var(--pt-fw--base);
line-height: var(--pt-line-height-base); line-height: var(--pt-lh--base);
color: var(--pt-color); color: var(--pt-color);
background-color: var(--pt-color--bg); background-color: var(--pt-color--bg);
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
} }
.pt-body__skip { /* TYPOGRAPHY */
display: flex;
justify-content: center; h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: var(--pt-gap-0-9);
font-weight: var(--pt-fw--bold);
line-height: var(--pt-lh--header);
} }
.pt-body__skip a { h1 {
display: block; font-size: var(--pt-fs--x3l);
padding: var(--pt-gap-0-5) var(--pt-gap-1-5);
color: var(--pt-color--white);
background-color: var(--pt-color--gray-5);
text-decoration: none;
outline: 0;
position: absolute;
transform: translateY(-100%);
transition: all 0.3s ease-in-out;
z-index: 9999;
} }
.pt-body__skip a:after { h2 {
content: "\0020 ➔"; font-size: var(--pt-fs--x2l);
} }
.pt-body__skip a:focus { h3 {
transform: translateY(0%); font-size: var(--pt-fs--xl);
}
h4 {
font-size: var(--pt-fs--l);
}
h5 {
font-size: var(--pt-fs--m);
}
h6 {
font-size: var(--pt-fs--base);
}
/* LG - Applies <= 992px */
@media screen and (max-width: 62em) {
h1 {
font-size: calc(var(--pt-fs--l) + 1.25vw);
}
h2 {
font-size: calc(var(--pt-fs--l) + 0.6vw);
}
h3 {
font-size: calc(var(--pt-fs--m) + 0.6vw);
}
h4 {
font-size: calc(var(--pt-fs--m) + 0.3vw);
}
} }
.pt-body__wrapper { p {
margin-top: 0;
margin-bottom: var(--pt-gap-0-9);
}
/* LAYOUT */
#header__inner,
.pt-content__wrapper,
#footer__inner {
width: 100%; width: 100%;
max-width: var(--pt-max-width); max-width: var(--pt-max-width);
margin: 0 auto; margin: 0 auto;
} }
#header {
background: var(--pt-color--white);
}
.pt-content__wrapper {
background: var(--pt-color--white);
}
#footer {
background: linear-gradient(180deg, var(--pt-color--gray-5) 0%, var(--pt-color--gray-10) 100%);
}
#footer__inner {
color: var(--pt-color--gray-65);
background: var(--pt-color--gray-20);
padding: var(--pt-gap-3) 0 var(--pt-gap-12);
}
#footer__inner a {
color: var(--pt-color--white);
}

View file

@ -1,3 +1,122 @@
/* SKIP TO MAIN CONTENT */
.pt-body__skip {
display: flex;
justify-content: center;
}
.pt-body__skip a {
display: block;
padding: var(--pt-gap-0-5) var(--pt-gap-1-5);
color: var(--pt-color--white);
background-color: var(--pt-color--gray-5);
text-decoration: none;
outline: 0;
position: absolute;
transform: translateY(-100%);
transition: all 0.3s ease-in-out;
z-index: 9999;
}
.pt-body__skip a:after {
content: "\0020 ➔";
}
.pt-body__skip a:focus {
transform: translateY(0%);
}
/* TYPOGRAPHY */
.pt-fs__x3l {
font-size: var(--pt-fs--x3l) !important;
}
.pt-fs__x2l {
font-size: var(--pt-fs--x2l) !important;
}
.pt-fs__xl {
font-size: var(--pt-fs--xl) !important;
}
.pt-fs__l {
font-size: var(--pt-fs--l) !important;
}
.pt-fs__m {
font-size: var(--pt-fs--m) !important;
}
.pt-fs__s {
font-size: var(--pt-fs--s) !important;
}
.pt-fs__xs {
font-size: var(--pt-fs--xs) !important;
}
.pt-fs__x2s {
font-size: var(--pt-fs--x2s) !important;
}
.pt-fs__x3s {
font-size: var(--pt-fs--x3s) !important;
}
/* LG - Applies <= 992px */
@media screen and (max-width: 62em) {
.pt-fs__x3l {
font-size: calc(var(--pt-fs--l) + 1.25vw) !important;
}
.pt-fs__x2l {
font-size: calc(var(--pt-fs--l) + 0.6vw) !important;
}
.pt-fs__xl {
font-size: calc(var(--pt-fs--m) + 0.6vw) !important;
}
.pt-fs__l {
font-size: calc(var(--pt-fs--m) + 0.3vw) !important;
}
}
/* COMPONENT STYLES */
/* Heading component */
.pt-heading__title-x3l,
.pt-heading__title-x2l,
.pt-heading__title-xl,
.pt-heading__title-l,
.pt-heading__title-m,
.pt-heading__subtitle {
font-weight: var(--pt-fw--light);
}
.pt-heading__title-x3l {
font-size: calc(var(--pt-fs--x3l) * 2);
}
.pt-heading__title-x2l {
font-size: calc(var(--pt-fs--x3l) * 1.8);
}
.pt-heading__title-xl {
font-size: calc(var(--pt-fs--x3l) * 1.6);
}
.pt-heading__title-l {
font-size: calc(var(--pt-fs--x3l) * 1.4);
}
.pt-heading__title-m {
font-size: calc(var(--pt-fs--x3l) * 1.2);
}
.pt-heading__subtitle {
margin-top: calc(-1 * var(--pt-gap-0-75));
}
/* LG - Applies <= 992px */
@media screen and (max-width: 62em) {
.pt-heading__title-x3l {
font-size: calc((var(--pt-fs--x3l) / 1.5) + 4.5vw);
}
.pt-heading__title-x2l {
font-size: calc((var(--pt-fs--x3l) / 1.6) + 3.9vw);
}
.pt-heading__title-xl {
font-size: calc((var(--pt-fs--x3l) / 1.6) + 3.3vw);
}
.pt-heading__title-l {
font-size: calc((var(--pt-fs--x3l) / 1.7) + 2.7vw);
}
.pt-heading__title-m {
font-size: calc((var(--pt-fs--x3l) / 1.7) + 2.1vw);
}
}
/* Image component */ /* Image component */
.pt-img__fluid { .pt-img__fluid {
@ -14,10 +133,10 @@
} }
.pt-branding__name { .pt-branding__name {
letter-spacing: 0.02em; letter-spacing: 0.02em;
font-size: var(--pt-font-size-xl); font-size: var(--pt-fs--l);
} }
.pt-branding__slogan { .pt-branding__slogan {
font-size: var(--pt-font-size-l); font-size: var(--pt-fs--m);
} }
/* SM - Applies <= 568px */ /* SM - Applies <= 568px */
@ -29,7 +148,7 @@
/* LG - Applies <= 992px */ /* LG - Applies <= 992px */
@media (max-width: 62em) { @media (max-width: 62em) {
.pt-branding__slogan { .pt-branding__slogan {
font-size: var(--pt-font-size-l); font-size: var(--pt-fs--base);
} }
} }

View file

@ -3,15 +3,26 @@
--pt-font-serif: "Lora","georgia",serif; --pt-font-serif: "Lora","georgia",serif;
--pt-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; --pt-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
--pt-font-family: var(--pt-font-sans); --pt-font-family: var(--pt-font-sans);
--pt-font-size-base: 1rem;
--pt-font-size-xxl: 1.875rem; /* Font size */
--pt-font-size-xl: 1.375rem; --pt-fs--x3l: 2.5rem;
--pt-font-size-l: 1.125rem; --pt-fs--x2l: 2rem;
--pt-font-size-s: 0.875rem; --pt-fs--xl: 1.75rem;
--pt-font-size-xs: 0.8125rem; --pt-fs--l: 1.5rem;
--pt-font-size-xxs: 0.75rem; --pt-fs--m: 1.25rem;
--pt-font-weight: 400; --pt-fs--base: 1rem;
--pt-line-height-base: 1.5; --pt-fs--s: 0.875rem;
--pt-fs--xs: 0.75rem;
--pt-fs--x2s: 0.5625rem;
--pt-fs--x3s: 0.375rem;
/* Font weight */
--pt-fw--light: 300;
--pt-fw--base: 400;
--pt-fw--bold: 500;
/* Line height */
--pt-lh--base: 1.5;
--pt-lh--header: 1.2;
--pt-max-width: 90rem; --pt-max-width: 90rem;
/* /*
--pt-color-rgb: 33,37,41; --pt-color-rgb: 33,37,41;
@ -71,13 +82,11 @@
} }
*/ */
:root { :root {
/*
--pt-gap-0-25: calc(0.25 * var(--pt-gap)); --pt-gap-0-25: calc(0.25 * var(--pt-gap));
*/
--pt-gap-0-5: calc(0.5 * var(--pt-gap)); --pt-gap-0-5: calc(0.5 * var(--pt-gap));
--pt-gap-0-75: calc(0.75 * var(--pt-gap)); --pt-gap-0-75: calc(0.75 * var(--pt-gap));
--pt-gap-0-9: calc(0.9 * var(--pt-gap));
--pt-gap-1-5: calc(1.5 * var(--pt-gap)); --pt-gap-1-5: calc(1.5 * var(--pt-gap));
/*
--pt-gap-2: calc(2 * var(--pt-gap)); --pt-gap-2: calc(2 * var(--pt-gap));
--pt-gap-2-5: calc(2.5 * var(--pt-gap)); --pt-gap-2-5: calc(2.5 * var(--pt-gap));
--pt-gap-3: calc(3 * var(--pt-gap)); --pt-gap-3: calc(3 * var(--pt-gap));
@ -90,7 +99,15 @@
--pt-gap-10: calc(10 * var(--pt-gap)); --pt-gap-10: calc(10 * var(--pt-gap));
--pt-gap-11: calc(11 * var(--pt-gap)); --pt-gap-11: calc(11 * var(--pt-gap));
--pt-gap-12: calc(12 * var(--pt-gap)); --pt-gap-12: calc(12 * var(--pt-gap));
*/
--pt-color--primary-hue: 202;
--pt-color--primary-saturation: 79%;
--pt-color--primary-lightness: 50;
--pt-color--primary-30: hsl(var(--pt-color--primary-hue),var(--pt-color--primary-saturation),calc(1% * (var(--pt-color--primary-lightness) - (0.36 * var(--pt-color--primary-lightness)))));
--pt-color--primary-40: hsl(var(--pt-color--primary-hue),var(--pt-color--primary-saturation),calc(1% * (var(--pt-color--primary-lightness) - (0.24 * var(--pt-color--primary-lightness)))));
--pt-color--primary-50: hsl(var(--pt-color--primary-hue),var(--pt-color--primary-saturation),calc(1% * var(--pt-color--primary-lightness)));
--pt-color--primary-60: hsl(var(--pt-color--primary-hue),var(--pt-color--primary-saturation),calc(1% * (var(--pt-color--primary-lightness) + (0.24 * (100 - var(--pt-color--primary-lightness))))));
--pt-color--primary-80: hsl(var(--pt-color--primary-hue),var(--pt-color--primary-saturation),calc(1% * (var(--pt-color--primary-lightness) + (0.85 * (100 - var(--pt-color--primary-lightness))))));
--pt-color--gray-hue: 201; --pt-color--gray-hue: 201;
--pt-color--gray-saturation: 15%; --pt-color--gray-saturation: 15%;
@ -106,23 +123,17 @@
--pt-color--gray-100: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),97%); --pt-color--gray-100: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),97%);
--pt-color--white: #fff; --pt-color--white: #fff;
--pt-color--bg: var(--pt-color--white); --pt-color--bg: #fafafa;
--pt-color: #212529; --pt-color: #212529;
/* /*
--color--primary-hue: 202;
--color--primary-saturation: 79%;
--color--primary-lightness: 50;
--color--primary-30: hsl(var(--color--primary-hue),var(--color--primary-saturation),calc(1% * (var(--color--primary-lightness) - (0.36 * var(--color--primary-lightness)))));
--color--primary-40: hsl(var(--color--primary-hue),var(--color--primary-saturation),calc(1% * (var(--color--primary-lightness) - (0.24 * var(--color--primary-lightness)))));
--color--primary-50: hsl(var(--color--primary-hue),var(--color--primary-saturation),calc(1% * var(--color--primary-lightness)));
--color--primary-60: hsl(var(--color--primary-hue),var(--color--primary-saturation),calc(1% * (var(--color--primary-lightness) + (0.24 * (100 - var(--color--primary-lightness))))));
--color--primary-80: hsl(var(--color--primary-hue),var(--color--primary-saturation),calc(1% * (var(--color--primary-lightness) + (0.85 * (100 - var(--color--primary-lightness))))));
--color-text-neutral-soft: var(--color--gray-45); --color-text-neutral-soft: var(--color--gray-45);
--color-text-neutral-medium: var(--color--gray-20); --color-text-neutral-medium: var(--color--gray-20);
--color-text-neutral-loud: var(--color--gray-5); --color-text-neutral-loud: var(--color--gray-5);
--color-text-primary-medium: var(--color--primary-40); --color-text-primary-medium: var(--pt-color--primary-40);
--color-text-primary-loud: var(--color--primary-30); --color-text-primary-loud: var(--pt-color--primary-30);
--color--black: #000; --color--black: #000;
*/ */
/* /*