Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,23 @@ The styling of this website is happening in a number of different places. Some o

The front page includes a number of detailed styling, these are all located in [styles-frontpage.scss](styles-frontpage.scss). They are all wrapped in `#FrontPage` ID so they shouldn't affect anything not located in the front page.

The sidebar for the [Get Started](start/) section has a unique style, and that is specified in the [start/styles.css](start/styles.css) file, that is loaded into each of these pages with either `css: styles.css` or `css: ../styles.css`.
The sidebar for the [Get Started](start/) section has a unique style, and that is specified in the [start/styles.css](start/styles.css) file, that is loaded into each of these pages with either `css: styles.css` or `css: ../styles.css`.

### Color palette

The site uses an accessible cranberry color family (base `#BA355F`) documented by the Posit creative team against WCAG 2.2 AA. The full seven-step ramp (three light tints, the base, three dark shades) plus shared surfaces, inks, and code colors live in [`_cranberry.scss`](_cranberry.scss) as SCSS variables (`$cranberry-light-1` … `$cranberry-dark-3`, `$surface-light`/`$surface-dark`, `$ink`/`$ink-inverse`, `$theme-blue`/`$theme-blue-dark`). Both the light and dark themes layer this partial so the ramp is defined once.

**Sass layering gotcha:** Quarto emits `scss:defaults` from *later-listed* theme files first, so `_cranberry.scss` must come **after** the files that consume its variables (it is listed last in each theme list). Conversely, `scss:rules` cascade in listing order.

### Light and dark themes

The `theme:` key (under `format: html:` in [_quarto.yml](_quarto.yml) — the light/dark mapping form is only honored there, not at the top level) defines both a light and a dark theme, so Quarto injects a light/dark toggle in the navbar. `respect-user-color-scheme: true` makes the initial choice follow the reader's OS/browser preference, falling back to light.

- **Light** layers `[cosmo, styles.scss, styles-frontpage.scss, _cranberry.scss]`.
- **Dark** layers `[cosmo, styles-dark.scss, styles.scss, styles-frontpage.scss, _cranberry.scss]`. The dark surface derives from the existing tidymodels ink (`#1A162D`).

Dark-specific overrides live in [`styles-dark.scss`](styles-dark.scss). Note the ordering: `styles-dark.scss` is listed *before* `styles.scss` so its `scss:defaults` (Bootstrap variables like `$body-bg`, `$link-color`, `$code-color`) win; its `scss:rules` are scoped under `.quarto-dark` so they win on specificity rather than source order. The default code blue (`#4758AB`) fails contrast on the dark surface, so dark mode uses `#919BCD` instead.

Plain CSS files that aren't run through Sass ([`find/listing-cards.css`](find/listing-cards.css) and [`start/styles.css`](start/styles.css)) carry their own `.quarto-dark { … }` override blocks with the ramp values inlined as literals.

**Page-level theme overrides** must also use the mapping form. For example `learn/models/parsnip-predictions/index.qmd` sets `theme: {light: [style.scss], dark: [style.scss]}`; a bare list there fails to merge with the site's light/dark themes.
30 changes: 30 additions & 0 deletions _cranberry.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*-- scss:defaults --*/

// Tidymodels cranberry color family & accessibility guidance.
// Prepared by the Posit creative team. Seven-step accessible family keyed to the
// base cranberry #BA355F, mirroring the tint structure of the Posit brand
// guidelines. WCAG 2.2 AA contrast is documented against the site's light
// surface (#FFFFFF) and the dark surface (#1A162D, the existing tidymodels ink).
//
// This partial only defines shared color variables; it is layered into both the
// light and dark themes so the ramp is defined once.

// The family ------------------------------------------------------------------
// Value on #FFFFFF on #1A162D
$cranberry-light-1: #ECC6D2; // 1.55:1 fills only 11.34:1 AAA
$cranberry-light-2: #DB96AC; // 2.34:1 fills only 7.50:1 AAA
$cranberry-light-3: #CB6585; // 3.66:1 Large / UI 4.80:1 AA
$cranberry-base: #BA355F; // 5.58:1 AA 3.14:1 Large / UI
$cranberry-dark-1: #8B2847; // 8.43:1 AAA 2.08:1 fills only
$cranberry-dark-2: #631D33; // 11.97:1 AAA 1.47:1 fills only
$cranberry-dark-3: #3A111F; // 16.41:1 AAA 1.07:1 fills only

// Surfaces & neutrals ---------------------------------------------------------
$surface-light: #FFFFFF;
$surface-dark: #1A162D; // existing tidymodels ink
$ink: #1A162D; // body text on light (17.55:1 AAA)
$ink-inverse: #DDDDDD; // body text on dark (12.92:1 AAA)

// Code color — default fails on dark (2.72:1); use the dark-safe variant there.
$theme-blue: #4758AB;
$theme-blue-dark: #919BCD; // 6.50:1 AA on #1A162D
23 changes: 18 additions & 5 deletions _quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,23 @@ format:
include-after-body: html/plausible.html
code-link: true
css: fonts/fonts.css
respect-user-color-scheme: true
grid:
body-width: 840px

theme:
- cosmo
- styles.scss
- styles-frontpage.scss
# _cranberry.scss defines the shared color ramp. Quarto emits `scss:defaults`
# from later-listed files first, so it must come after the files that use it.
theme:
light:
- cosmo
- styles.scss
- styles-frontpage.scss
- _cranberry.scss
dark:
# styles-dark.scss is listed before styles.scss so its `scss:defaults`
# overrides win; its `scss:rules` are scoped under `.quarto-dark` so they
# win on specificity rather than source order.
- cosmo
- styles-dark.scss
- styles.scss
- styles-frontpage.scss
- _cranberry.scss
11 changes: 11 additions & 0 deletions find/listing-cards.css
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,14 @@
.parsnip-card-meta-2 { grid-template-columns: 1fr; }
.listing-filter-summary { padding: 0.5rem 0.7rem; }
}

/* Dark theme — this is plain CSS (not run through Sass), so the cranberry ramp
values from _cranberry.scss are inlined here as literals. */
.quarto-dark .listing-filter-summary,
.quarto-dark .listing-filter-panel {
background: #241f3a;
border-color: rgba(221, 221, 221, 0.25);
}
.quarto-dark .parsnip-card + .parsnip-card { border-top-color: rgba(221, 221, 221, 0.15); }
.quarto-dark .parsnip-card-meta { color: #b3b0bd; }
.quarto-dark .parsnip-card-meta code { background: rgba(236, 198, 210, 0.08); }
5 changes: 4 additions & 1 deletion learn/models/parsnip-predictions/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ toc: true
toc-depth: 3
format:
html:
theme: ["style.scss"]
# Mapping shape (not a bare list) so it merges into the site's light/dark themes.
theme:
light: ["style.scss"]
dark: ["style.scss"]
r-packages:
- tidymodels
- agua
Expand Down
13 changes: 12 additions & 1 deletion start/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,16 @@ div.sidebar-item-container {
counter-increment: section;
content: counter(section, decimal) "";
padding-right: 0.5em;
color: #CA225E; /* $theme-cranberry */
color: #BA355F; /* $theme-cranberry */
}

/* Dark theme — plain CSS, so cranberry ramp values are inlined as literals. */
.quarto-dark .sidebar-menu-container {
border-right-color: rgba(221, 221, 221, 0.2);
}
.quarto-dark div.sidebar-item-container {
color: rgba(221, 221, 221, 0.6);
}
.quarto-dark .sidebar-item:not(:first-child)::before {
color: #CB6585; /* cranberry-light-3, 4.80:1 on dark */
}
106 changes: 106 additions & 0 deletions styles-dark.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*-- scss:defaults --*/

// Dark theme overrides. The shared cranberry ramp is defined in _cranberry.scss
// (layered ahead of this file). Surface derives from the existing tidymodels
// ink (#1A162D) so the color family stays intact. Contrast ratios are against
// that dark surface. See Tidymodels-ColorGuidance-Accessibility-2025.

$body-bg: $surface-dark; // #1A162D
$body-color: $ink-inverse; // #DDDDDD, 12.92:1 AAA
$link-color: $cranberry-light-3; // #CB6585, 4.80:1 AA
$link-hover-color:$cranberry-light-2; // #DB96AC, 7.50:1 AAA
$code-color: $theme-blue-dark; // #919BCD, 6.50:1 AA (default blue fails at 2.72:1)
$navbar-bg: $surface-dark;

/*-- scss:rules --*/

// Overrides for surfaces hardcoded to light in styles.scss / styles-frontpage.scss.
// Scoped under .quarto-dark so they win on specificity regardless of source order.
.quarto-dark {

h2 {
color: $ink-inverse;
}

// code chunks + inline code — dark translucent tint instead of the light grey
div.sourceCode,
p code:not(.sourceCode),
li code:not(.sourceCode),
td code:not(.sourceCode),
#session-info div pre code {
background-color: rgba($cranberry-light-1, 0.08);
border-color: rgba($cranberry-light-1, 0.12);
}

#session-info div pre code {
color: $ink-inverse;
}

// output tables — flip the odd (white) rows and bottom border to dark surface
.cell-output-display table {
thead {
background-color: rgba($cranberry-base, 0.25);
}

tbody {
tr:nth-of-type(even) > * {
background-color: rgba($cranberry-light-1, 0.08);
--bs-table-accent-bg: rgba($cranberry-light-1, 0.08);
}

tr:nth-of-type(odd) > * {
background-color: $surface-dark;
--bs-table-accent-bg: $surface-dark;
}

tr:last-of-type {
border-bottom-color: rgba($ink-inverse, 0.2);
}
}
}

// sidebar resource stickies
.section.resources .event a {
color: $ink-inverse;

&:hover {
color: $cranberry-light-3;
}
}

// Front page — bands and the event card hardcode light surfaces in
// styles-frontpage.scss. Override them here and drop the decorative
// tidy-back-*.svg backgrounds (light-canvas illustrations with white
// strokes that clash on the dark surface).
#FrontPage {

.event {
background-color: rgba($cranberry-light-1, 0.06);
border-color: rgba($cranberry-light-1, 0.15);
color: $ink-inverse;
}

.band.first .bandContent,
.band.third .bandContent {
background-color: transparent;
background-image: none;
}

.band.second {
background-color: $surface-dark;
border-top-color: rgba($ink-inverse, 0.15);
border-bottom-color: rgba($ink-inverse, 0.15);

.bandContent {
background-color: transparent;
background-image: none;
color: $ink-inverse;
}
}

.band.first,
.band.third {
background-color: $surface-dark;
}
}
}
26 changes: 17 additions & 9 deletions styles.scss
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
/*-- scss:defaults --*/
$theme-cranberry: #CA225E;
$theme-blue: #4758AB;
$theme-white: #FFFFFF;
// Color ramp ($cranberry-*, $theme-blue, $surface-*, $ink*) is defined in
// _cranberry.scss, layered ahead of this file in _quarto.yml.
$theme-cranberry: $cranberry-base; // #BA355F
$theme-white: $surface-light;
$theme-grey: #DDDDDD;
$theme-black: #1a162d;
$theme-black: $ink; // #1a162d
$theme-code-bg: rgba(233,236,239,.3);

// Suppress cosmo's default Source Sans Pro Google Fonts import — we use Lato.
$web-font-path: "";

// Colors ----------------------------------------------------------------------
$link-color: $theme-cranberry;
$link-color: $cranberry-base;
$link-hover-color: $cranberry-dark-1; // 8.43:1 AAA on white

// Fonts -----------------------------------------------------------------------
$font-family-sans-serif: 'Lato', sans-serif;
Expand All @@ -26,7 +28,7 @@ $code-color: $theme-blue;
$navbar-bg: $theme-white;

$footer-bg: rgba($theme-cranberry, 0.2);
$footer-fg: darken($theme-cranberry, 12%);
$footer-fg: $cranberry-dark-1; // 8.43:1 AAA on white

/*-- scss:rules --*/

Expand All @@ -40,6 +42,12 @@ a {
text-decoration: none;
}

// Accessible keyboard focus indicator (≥3:1, per the cranberry guidance).
:focus-visible {
outline: 2px solid $cranberry-base;
outline-offset: 2px;
}

// Inline SVG icons — used in place of Font Awesome / Bootstrap Icons to keep
// the front page from loading their CSS and woff2 font files. Currently used by:
// * fa-flag-checkered + fa-lightbulb in index.qmd (FA Free 6 Solid)
Expand Down Expand Up @@ -228,7 +236,7 @@ p code:not(.sourceCode), li code:not(.sourceCode), td code:not(.sourceCode) {

thead {
font-weight: 600;
background-color: rgba($theme-cranberry, 0.15);
background-color: $cranberry-light-1; // L1 fill, ≥12:1 with ink text

tr th {
padding: 15px 13px;
Expand All @@ -242,8 +250,8 @@ p code:not(.sourceCode), li code:not(.sourceCode), td code:not(.sourceCode) {

tbody {
tr:nth-of-type(even) > * {
background-color: rgba($theme-cranberry, 0.03);
--bs-table-accent-bg: rgba($theme-cranberry, 0.03);
background-color: rgba($cranberry-light-1, 0.25);
--bs-table-accent-bg: rgba($cranberry-light-1, 0.25);
}

tr:nth-of-type(odd) > * {
Expand Down