Skip to content
Merged
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
171 changes: 171 additions & 0 deletions .agent/working-memory/plan-ui-refactor-docsy-theme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Plan: Docsy UI Refactor and Color System Refresh

**Date:** 2026-04-15
**Site:** Open Modeling Foundation Hugo + Docsy gateway
**Primary style files:**
- `assets/scss/_variables_project.scss`
- `assets/scss/_styles_project.scss`
- `assets/scss/_sidebar-tree-with-links.scss`

---

## Goal

Refactor the visual system so the site reads as a modern scientific/editorial platform with stronger brand consistency, improved accessibility, and clearer hierarchy across homepage, docs pages, and resource content.

## Non-goals

- No information architecture changes (menus/routes/content structure stay as-is).
- No JavaScript framework migration.
- No component rewrite outside existing Docsy/Hugo templates unless required for styling hooks.

---

## Proposed visual direction

**Theme concept:** Scientific Editorial

- Trust-first dark blue primary foundation
- Crisp teal for links and interactive affordances
- Warm amber accent reserved for key actions/highlights
- Light neutral surfaces for long-form readability
- Distinctive serif/sans pairing for stronger voice and scanability

### Candidate palette (recommended)

- `--omf-primary`: `#0F2742`
- `--omf-secondary`: `#0E7490`
- `--omf-accent`: `#F59E0B`
- `--omf-surface-1`: `#F7FAFC`
- `--omf-surface-2`: `#EAF1F6`
- `--omf-text`: `#1F2937`
- `--omf-text-muted`: `#4B5563`
- `--omf-border`: `#CBD5E1`

Map these to Bootstrap/Docsy Sass variables (`$primary`, `$secondary`, `$light`, `$dark`, `$link-color`, etc.) in `_variables_project.scss`.

---

## Work plan

### Phase 1: Foundations (variables + typography)

1. Replace ad-hoc colors with a coherent tokenized palette in `_variables_project.scss`.
2. Define heading/body font stacks with non-generic defaults.
3. Normalize link contrast and states (default/hover/focus/visited where applicable).
4. Keep navbar/footer colors aligned with the new tokens.

**Deliverable:** Stable theme primitives with no page-level regressions.

### Phase 2: Global components

1. Refine card visual language (radius, border, depth, hover).
2. Improve sidebar readability and active states.
3. Standardize focus-visible styles across nav, content links, buttons.
4. Harmonize spacing rhythm for headings, paragraphs, and section blocks.

**Deliverable:** Consistent interaction and hierarchy across standard Docsy layouts.

### Phase 3: Homepage and hero polish

1. Increase narrative hierarchy in hero section typography.
2. Improve section separation using controlled background contrast.
3. Tune icon block spacing and heading weights.
4. Introduce subtle motion only where it reinforces orientation.

**Deliverable:** Distinct, intentional landing experience without visual noise.

### Phase 4: Resource/doc page refinement

1. Ensure resource-heavy pages (including awesome list) inherit the new system cleanly.
2. Recheck long-form content readability (line length, heading rhythm, lists).
3. Tighten metadata/callout card styling for consistency.

**Deliverable:** High readability and cohesive branding in content-dense pages.

---

## Implementation details

### Files likely to edit

- `assets/scss/_variables_project.scss`
- Color and typography tokens
- Bootstrap variable overrides
- `assets/scss/_styles_project.scss`
- Footer, cards, sidebar active indicators, docs content rhythm
- Homepage block enhancements
- Awesome list style alignment
- `content/en/_index.html` (optional/minimal)
- Minor semantic wrappers or utility classes for layout hooks

### Guardrails

- Preserve existing URL structure and menu behavior.
- Preserve Docsy compatibility and upgradeability.
- Avoid introducing heavy custom JS.
- Keep animation subtle and accessible (reduced-motion friendly).

---

## Accessibility and quality criteria

1. Contrast:
- Body text and interactive text must meet WCAG 2.2 AA.
2. Keyboard:
- All interactive elements show visible focus indicators.
3. Readability:
- Paragraph line length targets ~60-80 characters where practical.
4. Motion:
- Respect `prefers-reduced-motion`.
5. Regression:
- No broken layouts at mobile, tablet, and desktop breakpoints.

---

## Validation plan

Run in containerized environment:

1. `docker compose run --rm --no-deps --entrypoint sh hugo -c '.github/scripts/build-site.sh'`
2. Spot-check representative pages in `public/`:
- home
- one standards page
- one working-group page
- resources index
- awesome-list page
3. HTML parse check for touched rendered pages using `xmllint --html --noout`.
4. Visual regression check by comparing before/after screenshots for key templates.

---

## Risks and mitigations

- **Risk:** New palette reduces contrast in existing components.
- **Mitigation:** Run targeted contrast checks before finalizing tokens.

- **Risk:** Docsy defaults conflict with custom overrides.
- **Mitigation:** Keep overrides scoped and rely on variable-level changes first.

- **Risk:** Typography choice increases layout shift/perf cost.
- **Mitigation:** Use performant font loading strategy and fallback stacks.

---

## Suggested execution order

1. Palette + link/focus tokens
2. Sidebar + card system
3. Homepage polish
4. Resource and awesome-list final pass
5. Build, validate, and document changes

---

## Definition of done

- Unified color system implemented and documented.
- Sidebar, cards, and content typography visibly improved and consistent.
- Homepage visual hierarchy is stronger and more intentional.
- Awesome-list and other long-form pages match the new design language.
- Container build passes and HTML parse checks pass for touched pages.
12 changes: 11 additions & 1 deletion .agent/working-memory/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@

- awesome-modeling-practices embed plan is ready: `.agent/working-memory/plan-awesome-list.md`.
- navigation/resources refactor issue plan is ready: `.agent/working-memory/plan-navigation-resources-refactor.md`.
- Next step on request: implement the planned integration.
- UI refactor plan artifact is ready: `.agent/working-memory/plan-ui-refactor-docsy-theme.md`.
- Next step on request: complete visual QA pass for key pages and tune any contrast/spacing edge cases.

## Notes by date (newest first)

### 2026-04-15

- Resumed UI theme refactor handoff and implemented Phase 1 + Phase 2 baseline in SCSS:
- `assets/scss/_variables_project.scss`: tokenized Scientific Editorial palette, typography stacks, Bootstrap variable remap, focus ring tuning, reduced-motion handling.
- `assets/scss/_styles_project.scss`: global readability/focus updates, navbar/section backgrounds, footer restyle, card and sidebar interaction polish, awesome-list alignment.
- `assets/scss/_sidebar-tree-with-links.scss`: page-meta link contrast, hover/focus states, and typography weight adjustments.
- Validation run completed with containerized workflow: `make render` succeeded on 2026-04-15 22:45 UTC.
- Build warning observed (pre-existing): Hugo deprecation for `.Site.AllPages` in theme/template code, unrelated to this SCSS refactor.

### 2026-03-31

- `Makefile` maintenance completed: fixed `make shell`, refactored shared Docker Compose flags, removed global `.NOTPARALLEL`, and simplified `clean` with a merged `find`.
Expand Down
139 changes: 139 additions & 0 deletions .github/scripts/download-fonts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/usr/bin/env bash
set -euo pipefail

IFS=$'\n\t'

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "${script_dir}/../.." && pwd)"
cd "$repo_root"

fonts_root="static/fonts"
tmpdir="$(mktemp -d)"

cleanup() {
rm -rf "$tmpdir"
}
trap cleanup EXIT

mkdir -p "$fonts_root"

declare -a FONT_SPECS=()

font_spec() {
FONT_SPECS+=("${1}|${2}|${3}|${4}|${5}")
}

download() {
local url="$1"
local out="$2"

curl \
--fail \
--location \
--silent \
--show-error \
--proto '=https' \
--tlsv1.2 \
"$url" \
-o "$out"
}

verify_integrity() {
local package_spec="$1"
local tarball="$2"
local expected_integrity expected_b64 actual_b64

expected_integrity="$(npm view "$package_spec" dist.integrity --json | tr -d '"')"
if [[ -z "$expected_integrity" || "$expected_integrity" == "null" ]]; then
echo "Missing dist.integrity for $package_spec" >&2
exit 1
fi

case "$expected_integrity" in
sha512-*) expected_b64="${expected_integrity#sha512-}" ;;
*)
echo "Unexpected integrity format for $package_spec: $expected_integrity" >&2
exit 1
;;
esac

actual_b64="$(openssl dgst -sha512 -binary "$tarball" | openssl base64 -A)"

if [[ "$actual_b64" != "$expected_b64" ]]; then
echo "Integrity mismatch for $package_spec" >&2
echo "expected: $expected_integrity" >&2
echo "actual: sha512-$actual_b64" >&2
exit 1
fi
}

copy_license() {
local package_dir="$1"
local dest_dir="$2"

for candidate in LICENSE OFL.txt LICENSE.txt LICENSE.md; do
if [[ -f "$package_dir/$candidate" ]]; then
install -m 0644 "$package_dir/$candidate" "$dest_dir/OFL.txt"
return
fi
done

echo "No license file found in $package_dir" >&2
exit 1
}

install_family() {
local display_name="$1"
local family_slug="$2"
local package="$3"
local version="$4"
local files_csv="$5"

local package_spec="${package}@${version}"
local tarball_url tarball unpack dest_dir

tarball_url="$(npm view "$package_spec" dist.tarball --json | tr -d '"')"
tarball="$tmpdir/${family_slug}.tgz"
unpack="$tmpdir/${family_slug}"
dest_dir="$fonts_root/$family_slug"

mkdir -p "$dest_dir" "$unpack"
download "$tarball_url" "$tarball"
verify_integrity "$package_spec" "$tarball"
tar -xzf "$tarball" -C "$unpack"

local file
IFS=',' read -r -a files <<< "$files_csv"
for file in "${files[@]}"; do
install -m 0644 "$unpack/package/files/$file" "$dest_dir/"
done

copy_license "$unpack/package" "$dest_dir"
echo "Installed $display_name $version"
}

source "$script_dir/fonts.env"

for spec in "${FONT_SPECS[@]}"; do
IFS='|' read -r display_name family_slug package version files_csv <<< "$spec"
install_family "$display_name" "$family_slug" "$package" "$version" "$files_csv"
done

{
echo "This directory contains self-hosted WOFF2 fonts used by the site."
echo
echo "Families:"
for spec in "${FONT_SPECS[@]}"; do
IFS='|' read -r display_name family_slug package version files_csv <<< "$spec"
echo "- ${display_name} (${version})"
done
echo
echo "Each family directory includes its upstream license file as OFL.txt."
} > "$fonts_root/README.md"

ls -lh \
"$fonts_root/public-sans" \
"$fonts_root/source-serif-4" \
"$fonts_root/ibm-plex-mono"

echo "Font files and license files downloaded and installed successfully."
8 changes: 8 additions & 0 deletions .github/scripts/fonts.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
font_spec "Public Sans" "public-sans" "@fontsource/public-sans" "5.2.7" \
"public-sans-latin-300-normal.woff2,public-sans-latin-400-normal.woff2,public-sans-latin-600-normal.woff2"

font_spec "Source Serif 4" "source-serif-4" "@fontsource/source-serif-4" "5.2.9" \
"source-serif-4-latin-400-normal.woff2,source-serif-4-latin-600-normal.woff2,source-serif-4-latin-700-normal.woff2"

font_spec "IBM Plex Mono" "ibm-plex-mono" "@fontsource/ibm-plex-mono" "5.2.7" \
"ibm-plex-mono-latin-400-normal.woff2,ibm-plex-mono-latin-500-normal.woff2,ibm-plex-mono-latin-600-normal.woff2"
17 changes: 14 additions & 3 deletions assets/scss/_sidebar-tree-with-links.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@
.td-page-meta {
a {
display: block;
font-weight: $font-weight-light;
padding-bottom: .25rem;
font-weight: $font-weight-medium;
font-weight: 600;
padding-bottom: 0.25rem;
color: var(--omf-text-muted);
text-decoration-thickness: 0.06em;
text-underline-offset: 0.14em;
border-radius: 0.25rem;
transition: background-color 0.2s ease, color 0.2s ease;
}

a:hover,
a:focus-visible {
color: $primary;
background-color: rgba($secondary, 0.1);
text-decoration-color: rgba($secondary, 0.72);
}
}
}
Loading
Loading